madwifi: don't poll the channel noise in a performance critical path
[openwrt.git] / package / madwifi / patches / 300-napi_polling.patch
1 Index: madwifi-ng-r2756-20071018/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2756-20071018.orig/ath/if_ath.c 2007-10-24 06:20:20.433853739 +0200
4 +++ madwifi-ng-r2756-20071018/ath/if_ath.c 2007-10-24 06:20:20.749871745 +0200
5 @@ -170,7 +170,7 @@
6 int, u_int64_t);
7 static void ath_setdefantenna(struct ath_softc *, u_int);
8 static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int);
9 -static void ath_rx_tasklet(TQUEUE_ARG);
10 +static int ath_rx_poll(struct net_device *dev, int *budget);
11 static int ath_hardstart(struct sk_buff *, struct net_device *);
12 static int ath_mgtstart(struct ieee80211com *, struct sk_buff *);
13 #ifdef ATH_SUPERG_COMP
14 @@ -445,7 +445,6 @@
15 ATH_TXBUF_LOCK_INIT(sc);
16 ATH_RXBUF_LOCK_INIT(sc);
17
18 - ATH_INIT_TQUEUE(&sc->sc_rxtq, ath_rx_tasklet, dev);
19 ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet, dev);
20 ATH_INIT_TQUEUE(&sc->sc_bmisstq, ath_bmiss_tasklet, dev);
21 ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet, dev);
22 @@ -696,6 +695,8 @@
23 dev->set_mac_address = ath_set_mac_address;
24 dev->change_mtu = ath_change_mtu;
25 dev->tx_queue_len = ATH_TXBUF - 1; /* 1 for mgmt frame */
26 + dev->poll = ath_rx_poll;
27 + dev->weight = 64;
28 #ifdef USE_HEADERLEN_RESV
29 dev->hard_header_len += sizeof(struct ieee80211_qosframe) +
30 sizeof(struct llc) +
31 @@ -1794,6 +1795,7 @@
32 (status & HAL_INT_RXPHY) ? " HAL_INT_RXPHY" : "",
33 (status & HAL_INT_SWBA) ? " HAL_INT_SWBA" : "");
34
35 + sc->sc_isr = status;
36 status &= sc->sc_imask; /* discard unasked for bits */
37 if (status & HAL_INT_FATAL) {
38 sc->sc_stats.ast_hardware++;
39 @@ -1831,7 +1833,14 @@
40 }
41 if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
42 ath_uapsd_processtriggers(sc);
43 - ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark);
44 + sc->sc_isr &= ~HAL_INT_RX;
45 + if (netif_rx_schedule_prep(dev)) {
46 +#ifndef ATH_PRECISE_TSF
47 + sc->sc_imask &= ~HAL_INT_RX;
48 + ath_hal_intrset(ah, sc->sc_imask);
49 +#endif
50 + __netif_rx_schedule(dev);
51 + }
52 }
53 if (status & HAL_INT_TX) {
54 #ifdef ATH_SUPERG_DYNTURBO
55 @@ -1857,6 +1866,11 @@
56 }
57 }
58 #endif
59 + /* disable transmit interrupt */
60 + sc->sc_isr &= ~HAL_INT_TX;
61 + ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
62 + sc->sc_imask &= ~HAL_INT_TX;
63 +
64 ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
65 }
66 if (status & HAL_INT_BMISS) {
67 @@ -3450,10 +3464,10 @@
68 *
69 * XXX Using in_softirq is not right since we might
70 * be called from other soft irq contexts than
71 - * ath_rx_tasklet.
72 + * ath_rx_poll
73 */
74 if (!in_softirq())
75 - tasklet_disable(&sc->sc_rxtq);
76 + netif_poll_disable(dev);
77 netif_stop_queue(dev);
78 }
79
80 @@ -3466,7 +3480,7 @@
81 DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
82 netif_start_queue(dev);
83 if (!in_softirq()) /* NB: see above */
84 - tasklet_enable(&sc->sc_rxtq);
85 + netif_poll_enable(dev);
86 }
87
88 /*
89 @@ -5707,13 +5721,12 @@
90 sc->sc_rxotherant = 0;
91 }
92
93 -static void
94 -ath_rx_tasklet(TQUEUE_ARG data)
95 +static int
96 +ath_rx_poll(struct net_device *dev, int *budget)
97 {
98 #define PA2DESC(_sc, _pa) \
99 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
100 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
101 - struct net_device *dev = (struct net_device *)data;
102 struct ath_buf *bf;
103 struct ath_softc *sc = dev->priv;
104 struct ieee80211com *ic = &sc->sc_ic;
105 @@ -5726,9 +5739,11 @@
106 int type;
107 u_int phyerr;
108 u_int64_t rs_tsf;
109 -
110 + u_int processed = 0, early_stop = 0;
111 + u_int rx_limit = dev->quota;
112
113 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__);
114 +process_rx_again:
115 do {
116 bf = STAILQ_FIRST(&sc->sc_rxbuf);
117 if (bf == NULL) { /* XXX ??? can this happen */
118 @@ -5752,6 +5767,13 @@
119 /* NB: never process the self-linked entry at the end */
120 break;
121 }
122 +
123 + processed++;
124 + if (rx_limit-- < 0) {
125 + early_stop = 1;
126 + break;
127 + }
128 +
129 skb = bf->bf_skb;
130 if (skb == NULL) { /* XXX ??? can this happen */
131 printk("%s: no skbuff (%s)\n", DEV_NAME(dev), __func__);
132 @@ -5796,6 +5818,7 @@
133 sc->sc_stats.ast_rx_phyerr++;
134 phyerr = rs->rs_phyerr & 0x1f;
135 sc->sc_stats.ast_rx_phy[phyerr]++;
136 + goto rx_next;
137 }
138 if (rs->rs_status & HAL_RXERR_DECRYPT) {
139 /*
140 @@ -6011,9 +6034,33 @@
141 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
142 ATH_RXBUF_UNLOCK_IRQ(sc);
143 } while (ath_rxbuf_init(sc, bf) == 0);
144 + if (!early_stop) {
145 + /* Check if more data is received while we were
146 + * processing the descriptor chain.
147 + */
148 +#ifndef ATH_PRECISE_TSF
149 + ATH_DISABLE_INTR();
150 + if (sc->sc_isr & HAL_INT_RX) {
151 + sc->sc_isr &= ~HAL_INT_RX;
152 + ATH_ENABLE_INTR();
153 + ath_uapsd_processtriggers(sc);
154 + goto process_rx_again;
155 + }
156 +#endif
157 + netif_rx_complete(dev);
158 +
159 +#ifndef ATH_PRECISE_TSF
160 + sc->sc_imask |= HAL_INT_RX;
161 + ath_hal_intrset(ah, sc->sc_imask);
162 + ATH_ENABLE_INTR();
163 +#endif
164 + }
165 +
166 + *budget -= processed;
167
168 /* rx signal state monitoring */
169 ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
170 + return early_stop;
171 #undef PA2DESC
172 }
173
174 @@ -7635,11 +7682,22 @@
175 struct net_device *dev = (struct net_device *)data;
176 struct ath_softc *sc = dev->priv;
177
178 +process_tx_again:
179 if (txqactive(sc->sc_ah, 0))
180 ath_tx_processq(sc, &sc->sc_txq[0]);
181 if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
182 ath_tx_processq(sc, sc->sc_cabq);
183
184 + ATH_DISABLE_INTR();
185 + if (sc->sc_isr & HAL_INT_TX) {
186 + sc->sc_isr &= ~HAL_INT_TX;
187 + ATH_ENABLE_INTR();
188 + goto process_tx_again;
189 + }
190 + sc->sc_imask |= HAL_INT_TX;
191 + ath_hal_intrset(sc->sc_ah, sc->sc_imask);
192 + ATH_ENABLE_INTR();
193 +
194 netif_wake_queue(dev);
195
196 if (sc->sc_softled)
197 @@ -7656,6 +7714,7 @@
198 struct net_device *dev = (struct net_device *)data;
199 struct ath_softc *sc = dev->priv;
200
201 +process_tx_again:
202 /*
203 * Process each active queue.
204 */
205 @@ -7676,6 +7735,16 @@
206 if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
207 ath_tx_processq(sc, sc->sc_uapsdq);
208
209 + ATH_DISABLE_INTR();
210 + if (sc->sc_isr & HAL_INT_TX) {
211 + sc->sc_isr &= ~HAL_INT_TX;
212 + ATH_ENABLE_INTR();
213 + goto process_tx_again;
214 + }
215 + sc->sc_imask |= HAL_INT_TX;
216 + ath_hal_intrset(sc->sc_ah, sc->sc_imask);
217 + ATH_ENABLE_INTR();
218 +
219 netif_wake_queue(dev);
220
221 if (sc->sc_softled)
222 @@ -7693,6 +7762,7 @@
223 unsigned int i;
224
225 /* Process each active queue. */
226 +process_tx_again:
227 for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
228 if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
229 ath_tx_processq(sc, &sc->sc_txq[i]);
230 @@ -7701,6 +7771,16 @@
231 ath_tx_processq(sc, sc->sc_xrtxq);
232 #endif
233
234 + ATH_DISABLE_INTR();
235 + if (sc->sc_isr & HAL_INT_TX) {
236 + sc->sc_isr &= ~HAL_INT_TX;
237 + ATH_ENABLE_INTR();
238 + goto process_tx_again;
239 + }
240 + sc->sc_imask |= HAL_INT_TX;
241 + ath_hal_intrset(sc->sc_ah, sc->sc_imask);
242 + ATH_ENABLE_INTR();
243 +
244 netif_wake_queue(dev);
245
246 if (sc->sc_softled)
247 @@ -7799,6 +7879,7 @@
248 ath_draintxq(struct ath_softc *sc)
249 {
250 struct ath_hal *ah = sc->sc_ah;
251 + int npend = 0;
252 unsigned int i;
253
254 /* XXX return value */
255 @@ -9336,9 +9417,9 @@
256 dev->mtu = mtu;
257 if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
258 /* NB: the rx buffers may need to be reallocated */
259 - tasklet_disable(&sc->sc_rxtq);
260 + netif_poll_disable(dev);
261 error = ath_reset(dev);
262 - tasklet_enable(&sc->sc_rxtq);
263 + netif_poll_enable(dev);
264 }
265 ATH_UNLOCK(sc);
266
267 Index: madwifi-ng-r2756-20071018/ath/if_athvar.h
268 ===================================================================
269 --- madwifi-ng-r2756-20071018.orig/ath/if_athvar.h 2007-10-24 06:20:19.789817035 +0200
270 +++ madwifi-ng-r2756-20071018/ath/if_athvar.h 2007-10-24 06:20:20.749871745 +0200
271 @@ -50,6 +50,10 @@
272 #include <asm/io.h>
273 #include <linux/list.h>
274
275 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
276 +#define irqs_disabled() 0
277 +#endif
278 +
279 /*
280 * Deduce if tasklets are available. If not then
281 * fall back to using the immediate work queue.
282 @@ -642,7 +646,6 @@
283 struct ath_buf *sc_rxbufcur; /* current rx buffer */
284 u_int32_t *sc_rxlink; /* link ptr in last RX desc */
285 spinlock_t sc_rxbuflock;
286 - struct ATH_TQ_STRUCT sc_rxtq; /* rx intr tasklet */
287 struct ATH_TQ_STRUCT sc_rxorntq; /* rxorn intr tasklet */
288 u_int8_t sc_defant; /* current default antenna */
289 u_int8_t sc_rxotherant; /* RXs on non-default antenna */
290 @@ -655,6 +658,7 @@
291 u_int sc_txintrperiod; /* tx interrupt batching */
292 struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
293 struct ath_txq *sc_ac2q[WME_NUM_AC]; /* WME AC -> h/w qnum */
294 + HAL_INT sc_isr; /* unmasked ISR state */
295 struct ATH_TQ_STRUCT sc_txtq; /* tx intr tasklet */
296 u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
297 struct ath_descdma sc_bdma; /* beacon descriptors */
298 @@ -727,6 +731,8 @@
299 #define ATH_TXBUF_LOCK_ASSERT(_sc) \
300 KASSERT(spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf not locked!"))
301
302 +#define ATH_DISABLE_INTR local_irq_disable
303 +#define ATH_ENABLE_INTR local_irq_enable
304
305 #define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock)
306 #define ATH_RXBUF_LOCK_DESTROY(_sc)
307 Index: madwifi-ng-r2756-20071018/net80211/ieee80211_input.c
308 ===================================================================
309 --- madwifi-ng-r2756-20071018.orig/net80211/ieee80211_input.c 2007-10-24 06:20:19.113778513 +0200
310 +++ madwifi-ng-r2756-20071018/net80211/ieee80211_input.c 2007-10-24 06:20:20.757872202 +0200
311 @@ -1128,8 +1128,9 @@
312 if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
313 /* attach vlan tag */
314 vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan);
315 - } else
316 - netif_rx(skb);
317 + } else {
318 + netif_receive_skb(skb);
319 + }
320 dev->last_rx = jiffies;
321 }
322 }
This page took 0.064678 seconds and 5 git commands to generate.