From 2238b42bb8f682b8f5998b15f56899ac1269618e Mon Sep 17 00:00:00 2001 From: weiliu Date: Thu, 28 Jan 2021 14:15:29 +0100 Subject: [PATCH] improve csma state machine, force ch_idle high after decode, log cw and num_slot_random in the last attempt --- doc/README.md | 10 ++++++++ driver/sdr.c | 59 +++++++++++++++++++++++++++++++++++++++--------- driver/xpu/xpu.c | 5 ++-- openwifi-hw | 2 +- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/doc/README.md b/doc/README.md index 183c258..c5bb416 100644 --- a/doc/README.md +++ b/doc/README.md @@ -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 diff --git a/driver/sdr.c b/driver/sdr.c index 7aec770..3af3637 100644 --- a/driver/sdr.c +++ b/driver/sdr.c @@ -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 ®_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: diff --git a/driver/xpu/xpu.c b/driver/xpu/xpu.c index aae78a3..9de00d4 100644 --- a/driver/xpu/xpu.c +++ b/driver/xpu/xpu.c @@ -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); diff --git a/openwifi-hw b/openwifi-hw index d1a28d0..5871295 160000 --- a/openwifi-hw +++ b/openwifi-hw @@ -1 +1 @@ -Subproject commit d1a28d0e337db53e5f7cfcd548c80df9d61ccc1b +Subproject commit 5871295ebbbc6d1373c2b3ddee567d1c73c4156d