improve csma state machine, force ch_idle high after decode, log cw and num_slot_random in the last attempt

This commit is contained in:
weiliu 2021-01-28 14:15:29 +01:00
parent 09316927a9
commit 2238b42bb8
4 changed files with 62 additions and 14 deletions

View File

@ -268,6 +268,16 @@ and use dmesg command in Linux to see those messages. openwifi driver prints nor
- q2: the packet goes to FPGA queue 2. (You can change the mapping between Linux priority and FPGA queue in sdr.c)
- wr4 rd3: the write/read index of buffer (shared buffer between the active openwifi_tx and background openwifi_tx_interrupt).
- tx interrupt printing example
```
sdr,sdr openwifi_tx_interrupt: tx_result 02 prio2 wr28 rd25 num_rand_slot 21 cw 6
```
- printing from sdr driver, openwifi_tx_interrupt function.
- tx_result: 5 bit, lower 4 bit tells how many tx attemps are made on this packet, and the 5th bit indicates no ack (1) or an ack (0) is received
- prio, wr, rd: these fileds can be interpreted the same way as the print in openwifi_tx function
- num_rand_slot: tells how many slots the CSMA/CA state machine waited until the packet is sent in the last tx attempt.
- cw: tells the exponent of the contention window. For this packet, the exponent 6 means the contention window size is 64. If the contention phase is never entered, the cw is set to 0.
- rx printing example
sdr,sdr openwifi_rx_interrupt: 28bytes 24M FC0108 DI002c addr1/2/3:66554433222a/b0481ada2ef2/66554433222a SC4760 fcs1 buf_idx13 -30dBm

View File

@ -124,7 +124,7 @@ static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
{
struct openwifi_priv *priv = dev->priv;
u32 actual_rx_lo = conf->chandef.chan->center_freq - priv->rx_freq_offset_to_lo_MHz + priv->drv_rx_reg_val[DRV_RX_REG_IDX_EXTRA_FO];
u32 actual_tx_lo;
u32 actual_tx_lo, reg_val;
bool change_flag = (actual_rx_lo != priv->actual_rx_lo);
if (change_flag) {
@ -150,7 +150,8 @@ static void ad9361_rf_set_channel(struct ieee80211_hw *dev,
}
// xpu_api->XPU_REG_LBT_TH_write((priv->rssi_correction-62)<<1); // -62dBm
xpu_api->XPU_REG_LBT_TH_write((priv->rssi_correction-62-16)<<1); // wei's magic value is 135, here is 134 @ ch 44
reg_val=xpu_api->XPU_REG_LBT_TH_read();
xpu_api->XPU_REG_LBT_TH_write( (reg_val & 0xFFFF0000) | ((priv->rssi_correction-62-16)<<1)); // wei's magic value is 135, here is 134 @ ch 44
if (actual_rx_lo < 2500) {
//priv->slot_time = 20; //20 is default slot time in ERP(OFDM)/11g 2.4G; short one is 9.
@ -442,7 +443,7 @@ static irqreturn_t openwifi_tx_interrupt(int irq, void *dev_id)
struct openwifi_ring *ring;
struct sk_buff *skb;
struct ieee80211_tx_info *info;
u32 reg_val, hw_queue_len, prio, queue_idx, dma_fifo_no_room_flag, cw, loop_count=0;//, i;
u32 reg_val, hw_queue_len, prio, queue_idx, dma_fifo_no_room_flag, num_slot_random, cw, loop_count=0;//, i;
u8 tx_result_report;
// u16 prio_rd_idx_store[64]={0};
@ -450,9 +451,15 @@ static irqreturn_t openwifi_tx_interrupt(int irq, void *dev_id)
while(1) { // loop all packets that have been sent by FPGA
reg_val = tx_intf_api->TX_INTF_REG_PKT_INFO_read();
if (reg_val!=0x7FFFFF) {
if (reg_val!=0xFFFFFFFF) {
prio = ((0x7FFFF & reg_val)>>(5+NUM_BIT_MAX_PHY_TX_SN+NUM_BIT_MAX_NUM_HW_QUEUE));
cw = (reg_val>>(2+5+NUM_BIT_MAX_PHY_TX_SN+NUM_BIT_MAX_NUM_HW_QUEUE));
cw = ((0xF0000000 & reg_val) >> 28);
num_slot_random = ((0xFF80000 &reg_val)>>(2+5+NUM_BIT_MAX_PHY_TX_SN+NUM_BIT_MAX_NUM_HW_QUEUE));
if(cw > 10) {
cw = 10 ;
num_slot_random += 512 ;
}
ring = &(priv->tx_ring[prio]);
ring->bd_rd_idx = ((reg_val>>5)&MAX_PHY_TX_SN);
skb = ring->bds[ring->bd_rd_idx].skb_linked;
@ -508,7 +515,7 @@ static irqreturn_t openwifi_tx_interrupt(int irq, void *dev_id)
if ( (tx_result_report&0x10) && ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&1) )
printk("%s openwifi_tx_interrupt: WARNING tx_result %02x prio%d wr%d rd%d\n", sdr_compatible_str, tx_result_report, prio, ring->bd_wr_idx, ring->bd_rd_idx);
if ( ((priv->drv_tx_reg_val[DRV_TX_REG_IDX_PRINT_CFG])&2) )
printk("%s openwifi_tx_interrupt: tx_result %02x prio%d wr%d rd%d cw %d\n", sdr_compatible_str, tx_result_report, prio, ring->bd_wr_idx, ring->bd_rd_idx, cw);
printk("%s openwifi_tx_interrupt: tx_result %02x prio%d wr%d rd%d num_rand_slot %d cw %d \n", sdr_compatible_str, tx_result_report, prio, ring->bd_wr_idx, ring->bd_rd_idx, num_slot_random,cw);
ieee80211_tx_status_irqsafe(dev, skb);
@ -991,15 +998,16 @@ static int openwifi_start(struct ieee80211_hw *dev)
openofdm_rx_api->OPENOFDM_RX_REG_POWER_THRES_write(0);
// rssi_half_db_th = 87<<1; // -62dBm // will settup in runtime in _rf_set_channel
// xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
reg=xpu_api->XPU_REG_LBT_TH_read();
xpu_api->XPU_REG_LBT_TH_write((reg & 0xFF00FFFF) | (75 << 16) ); // bit 23:16 of LBT TH reg is set to control the duration to force ch_idle after decoding a packet due to imperfection of agc and signals
// xpu_api->XPU_REG_CSMA_CFG_write(3); // cw_min -- already set in xpu.c
//xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((40)<<16)|0 );//high 16bit 5GHz; low 16 bit 2.4GHz (Attention, current tx core has around 1.19us starting delay that makes the ack fall behind 10us SIFS in 2.4GHz! Need to improve TX in 2.4GHz!)
//xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51)<<16)|0 );//now our tx send out I/Q immediately
xpu_api->XPU_REG_SEND_ACK_WAIT_TOP_write( ((51+23)<<16)|(0+23) );//we have more time when we use FIR in AD9361
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (((45+2+2)*10 + 15)<<16) | 10 );//2.4GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (((51+2+2)*10 + 15)<<16) | 10 );//5GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP0_write( (1<<31) | (((45+2+2)*10 + 15)<<16) | 10 );//2.4GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
xpu_api->XPU_REG_RECV_ACK_COUNT_TOP1_write( (1<<31) | (((51+2+2)*10 + 15)<<16) | 10 );//5GHz. extra 300 clocks are needed when rx core fall into fake ht detection phase (rx mcs 6M)
tx_intf_api->TX_INTF_REG_CTS_TOSELF_WAIT_SIFS_TOP_write( ((16*10)<<16)|(10*10) );//high 16bit 5GHz; low 16 bit 2.4GHz. counter speed 10MHz is assumed
@ -1381,14 +1389,42 @@ static void openwifi_bss_info_changed(struct ieee80211_hw *dev,
changed&BSS_CHANGED_BEACON_ENABLED,changed&BSS_CHANGED_BEACON);
}
}
// helper function
u32 log2val(u32 val){
u32 ret_val = 0 ;
while(val>1){
val = val >> 1 ;
ret_val ++ ;
}
return ret_val ;
}
static int openwifi_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
printk("%s openwifi_conf_tx: WARNING [queue %d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
printk("%s openwifi_conf_tx: WARNING [queue %d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d, aifs and txop ignored\n",
sdr_compatible_str,queue,params->aifs,params->cw_min,params->cw_max,params->txop);
u32 reg19_val, reg8_val, cw_min_exp, cw_max_exp;
reg19_val=xpu_api->XPU_REG_CSMA_CFG_read();
reg8_val=xpu_api->XPU_REG_LBT_TH_read();
cw_min_exp = (log2val(params->cw_min + 1) & 0x0F);
cw_max_exp = (log2val(params->cw_max + 1) & 0x0F);
switch(queue){
case 0: reg19_val = (reg19_val & 0xFFFFFF00) | cw_min_exp | (cw_max_exp << 4); break ;
case 1: reg19_val = (reg19_val & 0xFFFF00FF) | ((cw_min_exp | (cw_max_exp << 4)) << 8); break ;
case 2: reg19_val = (reg19_val & 0xFF00FFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 16); break ;
case 3: reg8_val = (reg8_val & 0x00FFFFFF) | ((cw_min_exp | (cw_max_exp << 4)) << 24); break ;
default: printk("%s openwifi_conf_tx: WARNING queue %d does not exist",sdr_compatible_str, queue); return(0);
}
reg19_val = reg19_val | 0x10000000 ; // enable dynamic contention window.
xpu_api->XPU_REG_LBT_TH_write(reg8_val);
xpu_api->XPU_REG_CSMA_CFG_write(reg19_val);
//printk("reg19 val target val %08x, reg8 target val %08x", reg19_val, reg8_val);
//reg19_val=xpu_api->XPU_REG_CSMA_CFG_read();
//reg8_val=xpu_api->XPU_REG_LBT_TH_read();
//printk("reg19 val read back %08x, reg8 read back %08x", reg19_val, reg8_val);
return(0);
}
}
static u64 openwifi_prepare_multicast(struct ieee80211_hw *dev,
struct netdev_hw_addr_list *mc_list)
@ -1624,6 +1660,7 @@ static int openwifi_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *
return -EINVAL;
tmp = nla_get_u32(tb[OPENWIFI_ATTR_RSSI_TH]);
printk("%s set RSSI_TH to %d\n", sdr_compatible_str, tmp);
tmp = (tmp | (xpu_api->XPU_REG_LBT_TH_read() & 0xFFFF0000));
xpu_api->XPU_REG_LBT_TH_write(tmp);
return 0;
case OPENWIFI_CMD_GET_RSSI_TH:

View File

@ -284,7 +284,7 @@ EXPORT_SYMBOL(xpu_api);
static inline u32 hw_init(enum xpu_mode mode){
int err=0, i, rssi_half_db_th, rssi_half_db_offset, agc_gain_delay;
u32 filter_flag = 0;
u32 filter_flag = 0, reg_val;
printk("%s hw_init mode %d\n", xpu_compatible_str, mode);
@ -395,7 +395,8 @@ static inline u32 hw_init(enum xpu_mode mode){
//rssi_half_db_th = 70<<1; // with splitter
rssi_half_db_th = 87<<1; // -62dBm
xpu_api->XPU_REG_LBT_TH_write(rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
reg_val=xpu_api->XPU_REG_LBT_TH_read();
xpu_api->XPU_REG_LBT_TH_write((reg_val & 0xFFFF0000) | rssi_half_db_th); // set IQ rssi th step .5dB to xxx and enable it
//xpu_api->XPU_REG_CSMA_DEBUG_write((1<<31)|(20<<24)|(4<<19)|(3<<14)|(10<<7)|(5));
xpu_api->XPU_REG_CSMA_DEBUG_write(0);

@ -1 +1 @@
Subproject commit d1a28d0e337db53e5f7cfcd548c80df9d61ccc1b
Subproject commit 5871295ebbbc6d1373c2b3ddee567d1c73c4156d