Loading drivers/net/wireless/ath/wil6210/debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,8 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil, seq_puts(s, "???\n"); } seq_printf(s, " desc_rdy_pol = %d\n", sring->desc_rdy_pol); seq_printf(s, " invalid_buff_id_cnt = %d\n", sring->invalid_buff_id_cnt); if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) { uint i; Loading drivers/net/wireless/ath/wil6210/interrupt.c +40 −25 Original line number Diff line number Diff line Loading @@ -285,21 +285,24 @@ void wil_configure_interrupt_moderation(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_rx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_rx(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: RX\n"); wil6210_unmask_irq_rx(wil); return IRQ_NONE; } wil6210_mask_irq_rx(wil); /* RX_DONE and RX_HTRSH interrupts are the same if interrupt * moderation is not used. Interrupt moderation may cause RX * buffer overflow while RX_DONE is delayed. The required Loading Loading @@ -344,21 +347,24 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_rx_edma(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_INT_GEN_RX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: RX\n"); wil6210_unmask_irq_rx_edma(wil); return IRQ_NONE; } wil6210_mask_irq_rx_edma(wil); if (likely(isr & BIT_RX_STATUS_IRQ)) { wil_dbg_irq(wil, "RX status ring\n"); isr &= ~BIT_RX_STATUS_IRQ; Loading Loading @@ -392,21 +398,24 @@ static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_tx_edma(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_INT_GEN_TX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: TX\n"); wil6210_unmask_irq_tx_edma(wil); return IRQ_NONE; } wil6210_mask_irq_tx_edma(wil); if (likely(isr & BIT_TX_STATUS_IRQ)) { wil_dbg_irq(wil, "TX status ring\n"); isr &= ~BIT_TX_STATUS_IRQ; Loading Loading @@ -435,21 +444,24 @@ static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_tx(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: TX\n"); wil6210_unmask_irq_tx(wil); return IRQ_NONE; } wil6210_mask_irq_tx(wil); if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) { wil_dbg_irq(wil, "TX done\n"); isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; Loading Loading @@ -521,7 +533,11 @@ static bool wil_validate_mbox_regs(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; wil6210_mask_irq_misc(wil, false); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + offsetof(struct RGF_ICR, ICR)); Loading @@ -530,11 +546,10 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (!isr) { wil_err(wil, "spurious IRQ: MISC\n"); wil6210_unmask_irq_misc(wil, false); return IRQ_NONE; } wil6210_mask_irq_misc(wil, false); if (isr & ISR_MISC_FW_ERROR) { u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr); u32 ucode_assert_code = Loading drivers/net/wireless/ath/wil6210/ioctl.c +19 −3 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) struct wil_memio io; void __iomem *a; bool need_copy = false; int rc; if (copy_from_user(&io, data, sizeof(io))) return -EFAULT; Loading @@ -72,6 +73,11 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) io.op); return -EINVAL; } rc = wil_mem_access_lock(wil); if (rc) return rc; /* operation */ switch (io.op & WIL_MMIO_OP_MASK) { case WIL_MMIO_READ: Loading @@ -86,9 +92,12 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) #endif default: wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op); wil_mem_access_unlock(wil); return -EINVAL; } wil_mem_access_unlock(wil); if (need_copy) { wil_dbg_ioctl(wil, "IO done: addr(0x%08x) val(0x%08x) op(0x%08x)\n", Loading Loading @@ -134,6 +143,12 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (!block) return -ENOMEM; rc = wil_mem_access_lock(wil); if (rc) { kfree(block); return rc; } /* operation */ switch (io.op & WIL_MMIO_OP_MASK) { case WIL_MMIO_READ: Loading @@ -142,7 +157,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (copy_to_user((void __user *)(uintptr_t)io.block, block, io.size)) { rc = -EFAULT; goto out_free; goto out_unlock; } break; #if defined(CONFIG_WIL6210_WRITE_IOCTL) Loading @@ -150,7 +165,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (copy_from_user(block, (void __user *)(uintptr_t)io.block, io.size)) { rc = -EFAULT; goto out_free; goto out_unlock; } wil_memcpy_toio_32(a, block, io.size); wmb(); /* make sure write propagated to HW */ Loading @@ -163,7 +178,8 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) break; } out_free: out_unlock: wil_mem_access_unlock(wil); kfree(block); return rc; } Loading drivers/net/wireless/ath/wil6210/main.c +0 −5 Original line number Diff line number Diff line Loading @@ -1560,11 +1560,6 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) if (wil->hw_version < HW_VER_TALYN_MB) { wil_s(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0); wil_w(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0); } else { wil_s(wil, RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, ICR), 0); wil_w(wil, RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, IMV), ~0); } /* clear PAL_UNIT_ICR (potential D0->D3 leftover) * In Talyn-MB host cannot access this register due to Loading drivers/net/wireless/ath/wil6210/txrx_edma.c +39 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define WIL_EDMA_MAX_DATA_OFFSET (2) /* RX buffer size must be aligned to 4 bytes */ #define WIL_EDMA_RX_BUF_LEN_DEFAULT (2048) #define MAX_INVALID_BUFF_ID_RETRY (3) static void wil_tx_desc_unmap_edma(struct device *dev, union wil_tx_desc *desc, Loading Loading @@ -302,7 +303,8 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, struct list_head *free = &wil->rx_buff_mgmt.free; int i; wil->rx_buff_mgmt.buff_arr = kcalloc(size, sizeof(struct wil_rx_buff), wil->rx_buff_mgmt.buff_arr = kcalloc(size + 1, sizeof(struct wil_rx_buff), GFP_KERNEL); if (!wil->rx_buff_mgmt.buff_arr) return -ENOMEM; Loading @@ -311,14 +313,16 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, INIT_LIST_HEAD(active); INIT_LIST_HEAD(free); /* Linkify the list */ /* Linkify the list. * buffer id 0 should not be used (marks invalid id). */ buff_arr = wil->rx_buff_mgmt.buff_arr; for (i = 0; i < size; i++) { for (i = 1; i <= size; i++) { list_add(&buff_arr[i].list, free); buff_arr[i].id = i; } wil->rx_buff_mgmt.size = size; wil->rx_buff_mgmt.size = size + 1; return 0; } Loading Loading @@ -882,26 +886,50 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, /* Extract the buffer ID from the status message */ buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); if (unlikely(!wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size))) { while (!buff_id) { struct wil_rx_status_extended *s; int invalid_buff_id_retry = 0; wil_dbg_txrx(wil, "buff_id is not updated yet by HW, (swhead 0x%x)\n", sring->swhead); if (++invalid_buff_id_retry > MAX_INVALID_BUFF_ID_RETRY) break; /* Read the status message again */ s = (struct wil_rx_status_extended *) (sring->va + (sring->elem_size * sring->swhead)); *(struct wil_rx_status_extended *)msg = *s; buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); } if (unlikely(!wil_val_in_range(buff_id, 1, wil->rx_buff_mgmt.size))) { wil_err(wil, "Corrupt buff_id=%d, sring->swhead=%d\n", buff_id, sring->swhead); wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_sring_advance_swhead(sring); /* Extract the SKB from the rx_buff management array */ skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; if (!skb) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); wil_rx_status_reset_buff_id(sring); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); memcpy(&pa, skb->cb, sizeof(pa)); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); dmalen = le16_to_cpu(wil_rx_status_get_length(msg)); Loading @@ -916,7 +944,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, sizeof(struct wil_rx_status_extended), false); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); eop = wil_rx_status_get_eop(msg); Loading Loading
drivers/net/wireless/ath/wil6210/debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,8 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil, seq_puts(s, "???\n"); } seq_printf(s, " desc_rdy_pol = %d\n", sring->desc_rdy_pol); seq_printf(s, " invalid_buff_id_cnt = %d\n", sring->invalid_buff_id_cnt); if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) { uint i; Loading
drivers/net/wireless/ath/wil6210/interrupt.c +40 −25 Original line number Diff line number Diff line Loading @@ -285,21 +285,24 @@ void wil_configure_interrupt_moderation(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_rx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_rx(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: RX\n"); wil6210_unmask_irq_rx(wil); return IRQ_NONE; } wil6210_mask_irq_rx(wil); /* RX_DONE and RX_HTRSH interrupts are the same if interrupt * moderation is not used. Interrupt moderation may cause RX * buffer overflow while RX_DONE is delayed. The required Loading Loading @@ -344,21 +347,24 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_rx_edma(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_INT_GEN_RX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_rx(isr); wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: RX\n"); wil6210_unmask_irq_rx_edma(wil); return IRQ_NONE; } wil6210_mask_irq_rx_edma(wil); if (likely(isr & BIT_RX_STATUS_IRQ)) { wil_dbg_irq(wil, "RX status ring\n"); isr &= ~BIT_RX_STATUS_IRQ; Loading Loading @@ -392,21 +398,24 @@ static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_tx_edma(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_INT_GEN_TX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err(wil, "spurious IRQ: TX\n"); wil6210_unmask_irq_tx_edma(wil); return IRQ_NONE; } wil6210_mask_irq_tx_edma(wil); if (likely(isr & BIT_TX_STATUS_IRQ)) { wil_dbg_irq(wil, "TX status ring\n"); isr &= ~BIT_TX_STATUS_IRQ; Loading Loading @@ -435,21 +444,24 @@ static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) static irqreturn_t wil6210_irq_tx(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; bool need_unmask = true; wil6210_mask_irq_tx(wil); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + offsetof(struct RGF_ICR, ICR)); bool need_unmask = true; trace_wil6210_irq_tx(isr); wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); if (unlikely(!isr)) { wil_err_ratelimited(wil, "spurious IRQ: TX\n"); wil6210_unmask_irq_tx(wil); return IRQ_NONE; } wil6210_mask_irq_tx(wil); if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) { wil_dbg_irq(wil, "TX done\n"); isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; Loading Loading @@ -521,7 +533,11 @@ static bool wil_validate_mbox_regs(struct wil6210_priv *wil) static irqreturn_t wil6210_irq_misc(int irq, void *cookie) { struct wil6210_priv *wil = cookie; u32 isr = wil_ioread32_and_clear(wil->csr + u32 isr; wil6210_mask_irq_misc(wil, false); isr = wil_ioread32_and_clear(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + offsetof(struct RGF_ICR, ICR)); Loading @@ -530,11 +546,10 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) if (!isr) { wil_err(wil, "spurious IRQ: MISC\n"); wil6210_unmask_irq_misc(wil, false); return IRQ_NONE; } wil6210_mask_irq_misc(wil, false); if (isr & ISR_MISC_FW_ERROR) { u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr); u32 ucode_assert_code = Loading
drivers/net/wireless/ath/wil6210/ioctl.c +19 −3 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) struct wil_memio io; void __iomem *a; bool need_copy = false; int rc; if (copy_from_user(&io, data, sizeof(io))) return -EFAULT; Loading @@ -72,6 +73,11 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) io.op); return -EINVAL; } rc = wil_mem_access_lock(wil); if (rc) return rc; /* operation */ switch (io.op & WIL_MMIO_OP_MASK) { case WIL_MMIO_READ: Loading @@ -86,9 +92,12 @@ static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) #endif default: wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op); wil_mem_access_unlock(wil); return -EINVAL; } wil_mem_access_unlock(wil); if (need_copy) { wil_dbg_ioctl(wil, "IO done: addr(0x%08x) val(0x%08x) op(0x%08x)\n", Loading Loading @@ -134,6 +143,12 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (!block) return -ENOMEM; rc = wil_mem_access_lock(wil); if (rc) { kfree(block); return rc; } /* operation */ switch (io.op & WIL_MMIO_OP_MASK) { case WIL_MMIO_READ: Loading @@ -142,7 +157,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (copy_to_user((void __user *)(uintptr_t)io.block, block, io.size)) { rc = -EFAULT; goto out_free; goto out_unlock; } break; #if defined(CONFIG_WIL6210_WRITE_IOCTL) Loading @@ -150,7 +165,7 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) if (copy_from_user(block, (void __user *)(uintptr_t)io.block, io.size)) { rc = -EFAULT; goto out_free; goto out_unlock; } wil_memcpy_toio_32(a, block, io.size); wmb(); /* make sure write propagated to HW */ Loading @@ -163,7 +178,8 @@ static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) break; } out_free: out_unlock: wil_mem_access_unlock(wil); kfree(block); return rc; } Loading
drivers/net/wireless/ath/wil6210/main.c +0 −5 Original line number Diff line number Diff line Loading @@ -1560,11 +1560,6 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) if (wil->hw_version < HW_VER_TALYN_MB) { wil_s(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0); wil_w(wil, RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0); } else { wil_s(wil, RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, ICR), 0); wil_w(wil, RGF_CAF_ICR_TALYN_MB + offsetof(struct RGF_ICR, IMV), ~0); } /* clear PAL_UNIT_ICR (potential D0->D3 leftover) * In Talyn-MB host cannot access this register due to Loading
drivers/net/wireless/ath/wil6210/txrx_edma.c +39 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define WIL_EDMA_MAX_DATA_OFFSET (2) /* RX buffer size must be aligned to 4 bytes */ #define WIL_EDMA_RX_BUF_LEN_DEFAULT (2048) #define MAX_INVALID_BUFF_ID_RETRY (3) static void wil_tx_desc_unmap_edma(struct device *dev, union wil_tx_desc *desc, Loading Loading @@ -302,7 +303,8 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, struct list_head *free = &wil->rx_buff_mgmt.free; int i; wil->rx_buff_mgmt.buff_arr = kcalloc(size, sizeof(struct wil_rx_buff), wil->rx_buff_mgmt.buff_arr = kcalloc(size + 1, sizeof(struct wil_rx_buff), GFP_KERNEL); if (!wil->rx_buff_mgmt.buff_arr) return -ENOMEM; Loading @@ -311,14 +313,16 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, INIT_LIST_HEAD(active); INIT_LIST_HEAD(free); /* Linkify the list */ /* Linkify the list. * buffer id 0 should not be used (marks invalid id). */ buff_arr = wil->rx_buff_mgmt.buff_arr; for (i = 0; i < size; i++) { for (i = 1; i <= size; i++) { list_add(&buff_arr[i].list, free); buff_arr[i].id = i; } wil->rx_buff_mgmt.size = size; wil->rx_buff_mgmt.size = size + 1; return 0; } Loading Loading @@ -882,26 +886,50 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, /* Extract the buffer ID from the status message */ buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); if (unlikely(!wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size))) { while (!buff_id) { struct wil_rx_status_extended *s; int invalid_buff_id_retry = 0; wil_dbg_txrx(wil, "buff_id is not updated yet by HW, (swhead 0x%x)\n", sring->swhead); if (++invalid_buff_id_retry > MAX_INVALID_BUFF_ID_RETRY) break; /* Read the status message again */ s = (struct wil_rx_status_extended *) (sring->va + (sring->elem_size * sring->swhead)); *(struct wil_rx_status_extended *)msg = *s; buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); } if (unlikely(!wil_val_in_range(buff_id, 1, wil->rx_buff_mgmt.size))) { wil_err(wil, "Corrupt buff_id=%d, sring->swhead=%d\n", buff_id, sring->swhead); wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_sring_advance_swhead(sring); /* Extract the SKB from the rx_buff management array */ skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; if (!skb) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); wil_rx_status_reset_buff_id(sring); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); memcpy(&pa, skb->cb, sizeof(pa)); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); dmalen = le16_to_cpu(wil_rx_status_get_length(msg)); Loading @@ -916,7 +944,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, sizeof(struct wil_rx_status_extended), false); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); eop = wil_rx_status_get_eop(msg); Loading