mirror of
https://github.com/open-sdr/openwifi.git
synced 2024-12-23 15:32:41 +00:00
Fix the issue of iGent env related big ping delay:
1. The issue only happens at zcu102 side, when it is tested as AP together with zedboard 2. The issue does not happen when zcu102 is client and zedboard is AP 3. The issue (most likely) does not happen in places other than iGent (like Pablo home) 4. Sometimes it does happen at my home when I test zcu102 as AP together with COTS WiFi 5. Indeed seems like the environment related. Guess some quick small packets in the environment quickly flush/round-up/mess-up the rx dma cyclic buffer, and the rx interrupt internal static variable target_buf_idx_old loses track of the background automatic rx dma cyclic buffer 6. The fix is for all board types (zcu102, zedboard, 7035, etc) 7. The driver compiling make_all.sh script generates USE_NEW_RX_INTERRUPT macro to pre_def.h to enable the new code (while keeping the old code). You can use the script as before. 8. The logic of the fix is that exhaustive search all the rx dma cyclic buffer in rx interrupt to get packet to Linux in the first place.
This commit is contained in:
parent
f286042926
commit
109b1cfd3a
@ -39,10 +39,12 @@ if [ "$ARCH_OPTION" == "64" ]; then
|
||||
LINUX_KERNEL_SRC_DIR=$OPENWIFI_DIR/adi-linux-64/
|
||||
ARCH="arm64"
|
||||
CROSS_COMPILE="aarch64-linux-gnu-"
|
||||
echo "#define USE_NEW_RX_INTERRUPT 1" > pre_def.h
|
||||
else
|
||||
LINUX_KERNEL_SRC_DIR=$OPENWIFI_DIR/adi-linux/
|
||||
ARCH="arm"
|
||||
CROSS_COMPILE="arm-linux-gnueabihf-"
|
||||
echo "#define USE_NEW_RX_INTERRUPT 1" > pre_def.h
|
||||
fi
|
||||
|
||||
# check if user entered the right path to analog device linux
|
||||
|
31
driver/sdr.c
31
driver/sdr.c
@ -338,19 +338,29 @@ static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id)
|
||||
// u32 dma_driver_buf_idx_mod;
|
||||
u8 *pdata_tmp, fcs_ok;//, target_buf_idx;//, phy_rx_sn_hw;
|
||||
s8 signal;
|
||||
u16 rssi_val, addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0;
|
||||
u16 agc_status_and_pkt_exist_flag, rssi_val, addr1_high16=0, addr2_high16=0, addr3_high16=0, sc=0;
|
||||
bool content_ok = false, len_overflow = false;
|
||||
static u8 target_buf_idx_old = 0;
|
||||
|
||||
#ifdef USE_NEW_RX_INTERRUPT
|
||||
int i;
|
||||
spin_lock(&priv->lock);
|
||||
for (i=0; i<NUM_RX_BD; i++) {
|
||||
pdata_tmp = priv->rx_cyclic_buf + i*RX_BD_BUF_SIZE;
|
||||
agc_status_and_pkt_exist_flag = (*((u16*)(pdata_tmp+10))); //check rx_intf_pl_to_m_axis.v. FPGA TODO: add pkt exist 1bit flag next to gpio_status_lock_by_sig_valid
|
||||
if ( agc_status_and_pkt_exist_flag==0 ) // no packet in the buffer
|
||||
continue;
|
||||
#else
|
||||
static u8 target_buf_idx_old = 0;
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
while(1) { // loop all rx buffers that have new rx packets
|
||||
pdata_tmp = priv->rx_cyclic_buf + target_buf_idx_old*RX_BD_BUF_SIZE; // our header insertion is at the beginning
|
||||
agc_status_and_pkt_exist_flag = (*((u16*)(pdata_tmp+10)));
|
||||
if ( agc_status_and_pkt_exist_flag==0 ) // no packet in the buffer
|
||||
break;
|
||||
#endif
|
||||
|
||||
tsft_low = (*((u32*)(pdata_tmp+0 )));
|
||||
tsft_high = (*((u32*)(pdata_tmp+4 )));
|
||||
if ( tsft_low==0 && tsft_high==0 ) // no packet in the buffer
|
||||
break;
|
||||
|
||||
rssi_val = (*((u16*)(pdata_tmp+8 )));
|
||||
len = (*((u16*)(pdata_tmp+12)));
|
||||
|
||||
@ -410,7 +420,11 @@ static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id)
|
||||
printk("%s openwifi_rx_interrupt:%4dbytes ht%d %3dM FC%04x DI%04x addr1/2/3:%04x%08x/%04x%08x/%04x%08x SC%04x fcs%d buf_idx%d %ddBm\n", sdr_compatible_str,
|
||||
len, ht_flag, wifi_rate_table[rate_idx], hdr->frame_control, hdr->duration_id,
|
||||
reverse16(addr1_high16), reverse32(addr1_low32), reverse16(addr2_high16), reverse32(addr2_low32), reverse16(addr3_high16), reverse32(addr3_low32),
|
||||
#ifdef USE_NEW_RX_INTERRUPT
|
||||
sc, fcs_ok, i, signal);
|
||||
#else
|
||||
sc, fcs_ok, target_buf_idx_old, signal);
|
||||
#endif
|
||||
}
|
||||
|
||||
// priv->phy_rx_sn_hw_old = phy_rx_sn_hw;
|
||||
@ -442,10 +456,11 @@ static irqreturn_t openwifi_rx_interrupt(int irq, void *dev_id)
|
||||
} else
|
||||
printk("%s openwifi_rx_interrupt: WARNING dev_alloc_skb failed!\n", sdr_compatible_str);
|
||||
}
|
||||
(*((u32*)(pdata_tmp+0 ))) = 0;
|
||||
(*((u32*)(pdata_tmp+4 ))) = 0; // clear the tsft_low and tsft_high to indicate the packet has been processed
|
||||
(*((u16*)(pdata_tmp+10))) = 0; // clear the field (set by rx_intf_pl_to_m_axis.v) to indicate the packet has been processed
|
||||
loop_count++;
|
||||
#ifndef USE_NEW_RX_INTERRUPT
|
||||
target_buf_idx_old=((target_buf_idx_old+1)&(NUM_RX_BD-1));
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( loop_count!=1 && (priv->drv_rx_reg_val[DRV_RX_REG_IDX_PRINT_CFG]&1) )
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef OPENWIFI_SDR
|
||||
#define OPENWIFI_SDR
|
||||
|
||||
#include "pre_def.h"
|
||||
|
||||
// -------------------for leds--------------------------------
|
||||
struct gpio_led_data { //please always align with the leds-gpio.c in linux kernel
|
||||
struct led_classdev cdev;
|
||||
@ -90,7 +92,13 @@ union u16_byte2 {
|
||||
|
||||
#define RING_ROOM_THRESHOLD 4
|
||||
#define NUM_TX_BD 64 // !!! should align to the fifo size in tx_bit_intf.v
|
||||
|
||||
#ifdef USE_NEW_RX_INTERRUPT
|
||||
#define NUM_RX_BD 8
|
||||
#else
|
||||
#define NUM_RX_BD 16
|
||||
#endif
|
||||
|
||||
#define TX_BD_BUF_SIZE (8192)
|
||||
#define RX_BD_BUF_SIZE (8192)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user