aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c23
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c54
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c23
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h16
5 files changed, 94 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 5fe985cd3dfd..8205d3e4ab66 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -104,14 +104,14 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
104 clear_bit(wil_status_irqen, &wil->status); 104 clear_bit(wil_status_irqen, &wil->status);
105} 105}
106 106
107static void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 107void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
108{ 108{
109 iowrite32(WIL6210_IMC_TX, wil->csr + 109 iowrite32(WIL6210_IMC_TX, wil->csr +
110 HOSTADDR(RGF_DMA_EP_TX_ICR) + 110 HOSTADDR(RGF_DMA_EP_TX_ICR) +
111 offsetof(struct RGF_ICR, IMC)); 111 offsetof(struct RGF_ICR, IMC));
112} 112}
113 113
114static void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 114void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
115{ 115{
116 iowrite32(WIL6210_IMC_RX, wil->csr + 116 iowrite32(WIL6210_IMC_RX, wil->csr +
117 HOSTADDR(RGF_DMA_EP_RX_ICR) + 117 HOSTADDR(RGF_DMA_EP_RX_ICR) +
@@ -182,13 +182,14 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
182 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { 182 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
183 wil_dbg_irq(wil, "RX done\n"); 183 wil_dbg_irq(wil, "RX done\n");
184 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; 184 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
185 wil_rx_handle(wil); 185 wil_dbg_txrx(wil, "NAPI schedule\n");
186 napi_schedule(&wil->napi_rx);
186 } 187 }
187 188
188 if (isr) 189 if (isr)
189 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 190 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
190 191
191 wil6210_unmask_irq_rx(wil); 192 /* Rx IRQ will be enabled when NAPI processing finished */
192 193
193 return IRQ_HANDLED; 194 return IRQ_HANDLED;
194} 195}
@@ -211,23 +212,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
211 wil6210_mask_irq_tx(wil); 212 wil6210_mask_irq_tx(wil);
212 213
213 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 214 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
214 uint i;
215 wil_dbg_irq(wil, "TX done\n"); 215 wil_dbg_irq(wil, "TX done\n");
216 napi_schedule(&wil->napi_tx);
216 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 217 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
217 for (i = 0; i < 24; i++) { 218 /* clear also all VRING interrupts */
218 u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); 219 isr &= ~(BIT(25) - 1UL);
219 if (isr & mask) {
220 isr &= ~mask;
221 wil_dbg_irq(wil, "TX done(%i)\n", i);
222 wil_tx_complete(wil, i);
223 }
224 }
225 } 220 }
226 221
227 if (isr) 222 if (isr)
228 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 223 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
229 224
230 wil6210_unmask_irq_tx(wil); 225 /* Tx IRQ will be enabled when NAPI processing finished */
231 226
232 return IRQ_HANDLED; 227 return IRQ_HANDLED;
233} 228}
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index a0478e2f6868..ea49c8a18e15 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -365,6 +365,9 @@ static int __wil_up(struct wil6210_priv *wil)
365 /* Rx VRING. After MAC and beacon */ 365 /* Rx VRING. After MAC and beacon */
366 wil_rx_init(wil); 366 wil_rx_init(wil);
367 367
368 napi_enable(&wil->napi_rx);
369 napi_enable(&wil->napi_tx);
370
368 return 0; 371 return 0;
369} 372}
370 373
@@ -381,6 +384,9 @@ int wil_up(struct wil6210_priv *wil)
381 384
382static int __wil_down(struct wil6210_priv *wil) 385static int __wil_down(struct wil6210_priv *wil)
383{ 386{
387 napi_disable(&wil->napi_rx);
388 napi_disable(&wil->napi_tx);
389
384 if (wil->scan_request) { 390 if (wil->scan_request) {
385 cfg80211_scan_done(wil->scan_request, true); 391 cfg80211_scan_done(wil->scan_request, true);
386 wil->scan_request = NULL; 392 wil->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 098a8ec6b841..29dd1e58cb17 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -40,6 +40,55 @@ static const struct net_device_ops wil_netdev_ops = {
40 .ndo_validate_addr = eth_validate_addr, 40 .ndo_validate_addr = eth_validate_addr,
41}; 41};
42 42
43static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
44{
45 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
46 napi_rx);
47 int quota = budget;
48 int done;
49
50 wil_rx_handle(wil, &quota);
51 done = budget - quota;
52
53 if (done <= 1) { /* burst ends - only one packet processed */
54 napi_complete(napi);
55 wil6210_unmask_irq_rx(wil);
56 wil_dbg_txrx(wil, "NAPI RX complete\n");
57 }
58
59 wil_dbg_txrx(wil, "NAPI RX poll(%d) done %d\n", budget, done);
60
61 return done;
62}
63
64static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
65{
66 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
67 napi_tx);
68 int tx_done = 0;
69 uint i;
70
71 /* always process ALL Tx complete, regardless budget - it is fast */
72 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
73 struct vring *vring = &wil->vring_tx[i];
74
75 if (!vring->va)
76 continue;
77
78 tx_done += wil_tx_complete(wil, i);
79 }
80
81 if (tx_done <= 1) { /* burst ends - only one packet processed */
82 napi_complete(napi);
83 wil6210_unmask_irq_tx(wil);
84 wil_dbg_txrx(wil, "NAPI TX complete\n");
85 }
86
87 wil_dbg_txrx(wil, "NAPI TX poll(%d) done %d\n", budget, tx_done);
88
89 return min(tx_done, budget);
90}
91
43void *wil_if_alloc(struct device *dev, void __iomem *csr) 92void *wil_if_alloc(struct device *dev, void __iomem *csr)
44{ 93{
45 struct net_device *ndev; 94 struct net_device *ndev;
@@ -81,6 +130,11 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
81 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 130 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
82 wdev->netdev = ndev; 131 wdev->netdev = ndev;
83 132
133 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
134 WIL6210_NAPI_BUDGET);
135 netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
136 WIL6210_NAPI_BUDGET);
137
84 wil_link_off(wil); 138 wil_link_off(wil);
85 139
86 return wil; 140 return wil;
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index dc183d573c08..bab50117383a 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -440,6 +440,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
440 440
441/* 441/*
442 * Pass Rx packet to the netif. Update statistics. 442 * Pass Rx packet to the netif. Update statistics.
443 * Called in softirq context (NAPI poll).
443 */ 444 */
444static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 445static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
445{ 446{
@@ -448,10 +449,7 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
448 449
449 skb_orphan(skb); 450 skb_orphan(skb);
450 451
451 if (in_interrupt()) 452 rc = netif_receive_skb(skb);
452 rc = netif_rx(skb);
453 else
454 rc = netif_rx_ni(skb);
455 453
456 if (likely(rc == NET_RX_SUCCESS)) { 454 if (likely(rc == NET_RX_SUCCESS)) {
457 ndev->stats.rx_packets++; 455 ndev->stats.rx_packets++;
@@ -465,9 +463,9 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
465/** 463/**
466 * Proceed all completed skb's from Rx VRING 464 * Proceed all completed skb's from Rx VRING
467 * 465 *
468 * Safe to call from IRQ 466 * Safe to call from NAPI poll, i.e. softirq with interrupts enabled
469 */ 467 */
470void wil_rx_handle(struct wil6210_priv *wil) 468void wil_rx_handle(struct wil6210_priv *wil, int *quota)
471{ 469{
472 struct net_device *ndev = wil_to_ndev(wil); 470 struct net_device *ndev = wil_to_ndev(wil);
473 struct vring *v = &wil->vring_rx; 471 struct vring *v = &wil->vring_rx;
@@ -478,7 +476,8 @@ void wil_rx_handle(struct wil6210_priv *wil)
478 return; 476 return;
479 } 477 }
480 wil_dbg_txrx(wil, "%s()\n", __func__); 478 wil_dbg_txrx(wil, "%s()\n", __func__);
481 while (NULL != (skb = wil_vring_reap_rx(wil, v))) { 479 while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
480 (*quota)--;
482 481
483 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 482 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
484 skb->dev = ndev; 483 skb->dev = ndev;
@@ -788,17 +787,20 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
788/** 787/**
789 * Clean up transmitted skb's from the Tx VRING 788 * Clean up transmitted skb's from the Tx VRING
790 * 789 *
790 * Return number of descriptors cleared
791 *
791 * Safe to call from IRQ 792 * Safe to call from IRQ
792 */ 793 */
793void wil_tx_complete(struct wil6210_priv *wil, int ringid) 794int wil_tx_complete(struct wil6210_priv *wil, int ringid)
794{ 795{
795 struct net_device *ndev = wil_to_ndev(wil); 796 struct net_device *ndev = wil_to_ndev(wil);
796 struct device *dev = wil_to_dev(wil); 797 struct device *dev = wil_to_dev(wil);
797 struct vring *vring = &wil->vring_tx[ringid]; 798 struct vring *vring = &wil->vring_tx[ringid];
799 int done = 0;
798 800
799 if (!vring->va) { 801 if (!vring->va) {
800 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 802 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
801 return; 803 return 0;
802 } 804 }
803 805
804 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); 806 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
@@ -847,7 +849,10 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
847 d->dma.length = 0; 849 d->dma.length = 0;
848 d->dma.status = TX_DMA_STATUS_DU; 850 d->dma.status = TX_DMA_STATUS_DU;
849 vring->swtail = wil_vring_next_tail(vring); 851 vring->swtail = wil_vring_next_tail(vring);
852 done++;
850 } 853 }
851 if (wil_vring_avail_tx(vring) > vring->size/4) 854 if (wil_vring_avail_tx(vring) > vring->size/4)
852 netif_tx_wake_all_queues(wil_to_ndev(wil)); 855 netif_tx_wake_all_queues(wil_to_ndev(wil));
856
857 return done;
853} 858}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 484446e66c5a..2e3c26e1c975 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -34,9 +34,11 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
34 34
35#define WIL6210_MEM_SIZE (2*1024*1024UL) 35#define WIL6210_MEM_SIZE (2*1024*1024UL)
36 36
37#define WIL6210_RX_RING_SIZE (128) 37#define WIL6210_RX_RING_SIZE (128)
38#define WIL6210_TX_RING_SIZE (128) 38#define WIL6210_TX_RING_SIZE (128)
39#define WIL6210_MAX_TX_RINGS (24) 39#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
40#define WIL6210_MAX_CID (8) /* HW limit */
41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
40 42
41/* Hardware definitions begin */ 43/* Hardware definitions begin */
42 44
@@ -239,6 +241,8 @@ struct wil6210_priv {
239 * - consumed in thread by wmi_event_worker 241 * - consumed in thread by wmi_event_worker
240 */ 242 */
241 spinlock_t wmi_ev_lock; 243 spinlock_t wmi_ev_lock;
244 struct napi_struct napi_rx;
245 struct napi_struct napi_tx;
242 /* DMA related */ 246 /* DMA related */
243 struct vring vring_rx; 247 struct vring vring_rx;
244 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 248 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -360,10 +364,12 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
360void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 364void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
361 365
362netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 366netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
363void wil_tx_complete(struct wil6210_priv *wil, int ringid); 367int wil_tx_complete(struct wil6210_priv *wil, int ringid);
368void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
364 369
365/* RX API */ 370/* RX API */
366void wil_rx_handle(struct wil6210_priv *wil); 371void wil_rx_handle(struct wil6210_priv *wil, int *quota);
372void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
367 373
368int wil_iftype_nl2wmi(enum nl80211_iftype type); 374int wil_iftype_nl2wmi(enum nl80211_iftype type);
369 375