diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-10-15 14:03:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-09 16:13:24 -0500 |
commit | e0e9bc82fb0813fd353b0abbba0f1d6a680cc77c (patch) | |
tree | d81c63dd8cb99cc29a6f53f5b5fca1eea860ddc8 /drivers | |
parent | 45684c75f9aa80eb477465bddcf79c9ad95206c7 (diff) |
ath9k_hw: optimize tx status descriptor processing
Disassembly shows, that at least on MIPS, the compiler generates a lot of
memory accesses to the same location in the descriptor field parsing.
Since it is operating on uncached memory, this can be quite expensive in
this hot path.
Change the code a bit to help the compiler optimize it properly, and get
rid of some unused fields in the ath_tx_status struct.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9002_mac.c | 81 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mac.c | 69 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.h | 3 |
3 files changed, 72 insertions, 81 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index f5ed73dac254..3b4c52c9181c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -208,77 +208,68 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
208 | struct ath_tx_status *ts) | 208 | struct ath_tx_status *ts) |
209 | { | 209 | { |
210 | struct ar5416_desc *ads = AR5416DESC(ds); | 210 | struct ar5416_desc *ads = AR5416DESC(ds); |
211 | u32 status; | ||
211 | 212 | ||
212 | if ((ads->ds_txstatus9 & AR_TxDone) == 0) | 213 | status = ACCESS_ONCE(ads->ds_txstatus9); |
214 | if ((status & AR_TxDone) == 0) | ||
213 | return -EINPROGRESS; | 215 | return -EINPROGRESS; |
214 | 216 | ||
215 | ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); | ||
216 | ts->ts_tstamp = ads->AR_SendTimestamp; | 217 | ts->ts_tstamp = ads->AR_SendTimestamp; |
217 | ts->ts_status = 0; | 218 | ts->ts_status = 0; |
218 | ts->ts_flags = 0; | 219 | ts->ts_flags = 0; |
219 | 220 | ||
220 | if (ads->ds_txstatus1 & AR_FrmXmitOK) | 221 | if (status & AR_TxOpExceeded) |
222 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
223 | ts->tid = MS(status, AR_TxTid); | ||
224 | ts->ts_rateindex = MS(status, AR_FinalTxIdx); | ||
225 | ts->ts_seqnum = MS(status, AR_SeqNum); | ||
226 | |||
227 | status = ACCESS_ONCE(ads->ds_txstatus0); | ||
228 | ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); | ||
229 | ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); | ||
230 | ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02); | ||
231 | if (status & AR_TxBaStatus) { | ||
232 | ts->ts_flags |= ATH9K_TX_BA; | ||
233 | ts->ba_low = ads->AR_BaBitmapLow; | ||
234 | ts->ba_high = ads->AR_BaBitmapHigh; | ||
235 | } | ||
236 | |||
237 | status = ACCESS_ONCE(ads->ds_txstatus1); | ||
238 | if (status & AR_FrmXmitOK) | ||
221 | ts->ts_status |= ATH9K_TX_ACKED; | 239 | ts->ts_status |= ATH9K_TX_ACKED; |
222 | if (ads->ds_txstatus1 & AR_ExcessiveRetries) | 240 | if (status & AR_ExcessiveRetries) |
223 | ts->ts_status |= ATH9K_TXERR_XRETRY; | 241 | ts->ts_status |= ATH9K_TXERR_XRETRY; |
224 | if (ads->ds_txstatus1 & AR_Filtered) | 242 | if (status & AR_Filtered) |
225 | ts->ts_status |= ATH9K_TXERR_FILT; | 243 | ts->ts_status |= ATH9K_TXERR_FILT; |
226 | if (ads->ds_txstatus1 & AR_FIFOUnderrun) { | 244 | if (status & AR_FIFOUnderrun) { |
227 | ts->ts_status |= ATH9K_TXERR_FIFO; | 245 | ts->ts_status |= ATH9K_TXERR_FIFO; |
228 | ath9k_hw_updatetxtriglevel(ah, true); | 246 | ath9k_hw_updatetxtriglevel(ah, true); |
229 | } | 247 | } |
230 | if (ads->ds_txstatus9 & AR_TxOpExceeded) | 248 | if (status & AR_TxTimerExpired) |
231 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
232 | if (ads->ds_txstatus1 & AR_TxTimerExpired) | ||
233 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | 249 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; |
234 | 250 | if (status & AR_DescCfgErr) | |
235 | if (ads->ds_txstatus1 & AR_DescCfgErr) | ||
236 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; | 251 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; |
237 | if (ads->ds_txstatus1 & AR_TxDataUnderrun) { | 252 | if (status & AR_TxDataUnderrun) { |
238 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; | 253 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; |
239 | ath9k_hw_updatetxtriglevel(ah, true); | 254 | ath9k_hw_updatetxtriglevel(ah, true); |
240 | } | 255 | } |
241 | if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { | 256 | if (status & AR_TxDelimUnderrun) { |
242 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | 257 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; |
243 | ath9k_hw_updatetxtriglevel(ah, true); | 258 | ath9k_hw_updatetxtriglevel(ah, true); |
244 | } | 259 | } |
245 | if (ads->ds_txstatus0 & AR_TxBaStatus) { | 260 | ts->ts_shortretry = MS(status, AR_RTSFailCnt); |
246 | ts->ts_flags |= ATH9K_TX_BA; | 261 | ts->ts_longretry = MS(status, AR_DataFailCnt); |
247 | ts->ba_low = ads->AR_BaBitmapLow; | 262 | ts->ts_virtcol = MS(status, AR_VirtRetryCnt); |
248 | ts->ba_high = ads->AR_BaBitmapHigh; | ||
249 | } | ||
250 | 263 | ||
251 | ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); | 264 | status = ACCESS_ONCE(ads->ds_txstatus5); |
252 | switch (ts->ts_rateindex) { | 265 | ts->ts_rssi = MS(status, AR_TxRSSICombined); |
253 | case 0: | 266 | ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10); |
254 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); | 267 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); |
255 | break; | 268 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); |
256 | case 1: | ||
257 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); | ||
258 | break; | ||
259 | case 2: | ||
260 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); | ||
261 | break; | ||
262 | case 3: | ||
263 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); | ||
264 | break; | ||
265 | } | ||
266 | 269 | ||
267 | ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); | ||
268 | ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); | ||
269 | ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); | ||
270 | ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); | ||
271 | ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); | ||
272 | ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); | ||
273 | ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); | ||
274 | ts->evm0 = ads->AR_TxEVM0; | 270 | ts->evm0 = ads->AR_TxEVM0; |
275 | ts->evm1 = ads->AR_TxEVM1; | 271 | ts->evm1 = ads->AR_TxEVM1; |
276 | ts->evm2 = ads->AR_TxEVM2; | 272 | ts->evm2 = ads->AR_TxEVM2; |
277 | ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); | ||
278 | ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); | ||
279 | ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); | ||
280 | ts->tid = MS(ads->ds_txstatus9, AR_TxTid); | ||
281 | ts->ts_antenna = 0; | ||
282 | 273 | ||
283 | return 0; | 274 | return 0; |
284 | } | 275 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 3b424ca1ba84..10c812e353a6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -237,10 +237,12 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
237 | struct ath_tx_status *ts) | 237 | struct ath_tx_status *ts) |
238 | { | 238 | { |
239 | struct ar9003_txs *ads; | 239 | struct ar9003_txs *ads; |
240 | u32 status; | ||
240 | 241 | ||
241 | ads = &ah->ts_ring[ah->ts_tail]; | 242 | ads = &ah->ts_ring[ah->ts_tail]; |
242 | 243 | ||
243 | if ((ads->status8 & AR_TxDone) == 0) | 244 | status = ACCESS_ONCE(ads->status8); |
245 | if ((status & AR_TxDone) == 0) | ||
244 | return -EINPROGRESS; | 246 | return -EINPROGRESS; |
245 | 247 | ||
246 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; | 248 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; |
@@ -253,57 +255,58 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
253 | return -EIO; | 255 | return -EIO; |
254 | } | 256 | } |
255 | 257 | ||
258 | if (status & AR_TxOpExceeded) | ||
259 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
260 | ts->ts_rateindex = MS(status, AR_FinalTxIdx); | ||
261 | ts->ts_seqnum = MS(status, AR_SeqNum); | ||
262 | ts->tid = MS(status, AR_TxTid); | ||
263 | |||
256 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | 264 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); |
257 | ts->desc_id = MS(ads->status1, AR_TxDescId); | 265 | ts->desc_id = MS(ads->status1, AR_TxDescId); |
258 | ts->ts_seqnum = MS(ads->status8, AR_SeqNum); | ||
259 | ts->ts_tstamp = ads->status4; | 266 | ts->ts_tstamp = ads->status4; |
260 | ts->ts_status = 0; | 267 | ts->ts_status = 0; |
261 | ts->ts_flags = 0; | 268 | ts->ts_flags = 0; |
262 | 269 | ||
263 | if (ads->status3 & AR_ExcessiveRetries) | 270 | status = ACCESS_ONCE(ads->status2); |
271 | ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); | ||
272 | ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); | ||
273 | ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02); | ||
274 | if (status & AR_TxBaStatus) { | ||
275 | ts->ts_flags |= ATH9K_TX_BA; | ||
276 | ts->ba_low = ads->status5; | ||
277 | ts->ba_high = ads->status6; | ||
278 | } | ||
279 | |||
280 | status = ACCESS_ONCE(ads->status3); | ||
281 | if (status & AR_ExcessiveRetries) | ||
264 | ts->ts_status |= ATH9K_TXERR_XRETRY; | 282 | ts->ts_status |= ATH9K_TXERR_XRETRY; |
265 | if (ads->status3 & AR_Filtered) | 283 | if (status & AR_Filtered) |
266 | ts->ts_status |= ATH9K_TXERR_FILT; | 284 | ts->ts_status |= ATH9K_TXERR_FILT; |
267 | if (ads->status3 & AR_FIFOUnderrun) { | 285 | if (status & AR_FIFOUnderrun) { |
268 | ts->ts_status |= ATH9K_TXERR_FIFO; | 286 | ts->ts_status |= ATH9K_TXERR_FIFO; |
269 | ath9k_hw_updatetxtriglevel(ah, true); | 287 | ath9k_hw_updatetxtriglevel(ah, true); |
270 | } | 288 | } |
271 | if (ads->status8 & AR_TxOpExceeded) | 289 | if (status & AR_TxTimerExpired) |
272 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
273 | if (ads->status3 & AR_TxTimerExpired) | ||
274 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | 290 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; |
275 | 291 | if (status & AR_DescCfgErr) | |
276 | if (ads->status3 & AR_DescCfgErr) | ||
277 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; | 292 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; |
278 | if (ads->status3 & AR_TxDataUnderrun) { | 293 | if (status & AR_TxDataUnderrun) { |
279 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; | 294 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; |
280 | ath9k_hw_updatetxtriglevel(ah, true); | 295 | ath9k_hw_updatetxtriglevel(ah, true); |
281 | } | 296 | } |
282 | if (ads->status3 & AR_TxDelimUnderrun) { | 297 | if (status & AR_TxDelimUnderrun) { |
283 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | 298 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; |
284 | ath9k_hw_updatetxtriglevel(ah, true); | 299 | ath9k_hw_updatetxtriglevel(ah, true); |
285 | } | 300 | } |
286 | if (ads->status2 & AR_TxBaStatus) { | 301 | ts->ts_shortretry = MS(status, AR_RTSFailCnt); |
287 | ts->ts_flags |= ATH9K_TX_BA; | 302 | ts->ts_longretry = MS(status, AR_DataFailCnt); |
288 | ts->ba_low = ads->status5; | 303 | ts->ts_virtcol = MS(status, AR_VirtRetryCnt); |
289 | ts->ba_high = ads->status6; | 304 | |
290 | } | 305 | status = ACCESS_ONCE(ads->status7); |
291 | 306 | ts->ts_rssi = MS(status, AR_TxRSSICombined); | |
292 | ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx); | 307 | ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10); |
293 | 308 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); | |
294 | ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined); | 309 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); |
295 | ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00); | ||
296 | ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01); | ||
297 | ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02); | ||
298 | ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10); | ||
299 | ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11); | ||
300 | ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12); | ||
301 | ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt); | ||
302 | ts->ts_longretry = MS(ads->status3, AR_DataFailCnt); | ||
303 | ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt); | ||
304 | ts->ts_antenna = 0; | ||
305 | |||
306 | ts->tid = MS(ads->status8, AR_TxTid); | ||
307 | 310 | ||
308 | memset(ads, 0, sizeof(*ads)); | 311 | memset(ads, 0, sizeof(*ads)); |
309 | 312 | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 538c676e799c..fdc25074ca1f 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -104,13 +104,11 @@ struct ath_tx_status { | |||
104 | u32 ts_tstamp; | 104 | u32 ts_tstamp; |
105 | u16 ts_seqnum; | 105 | u16 ts_seqnum; |
106 | u8 ts_status; | 106 | u8 ts_status; |
107 | u8 ts_ratecode; | ||
108 | u8 ts_rateindex; | 107 | u8 ts_rateindex; |
109 | int8_t ts_rssi; | 108 | int8_t ts_rssi; |
110 | u8 ts_shortretry; | 109 | u8 ts_shortretry; |
111 | u8 ts_longretry; | 110 | u8 ts_longretry; |
112 | u8 ts_virtcol; | 111 | u8 ts_virtcol; |
113 | u8 ts_antenna; | ||
114 | u8 ts_flags; | 112 | u8 ts_flags; |
115 | int8_t ts_rssi_ctl0; | 113 | int8_t ts_rssi_ctl0; |
116 | int8_t ts_rssi_ctl1; | 114 | int8_t ts_rssi_ctl1; |
@@ -121,7 +119,6 @@ struct ath_tx_status { | |||
121 | u8 qid; | 119 | u8 qid; |
122 | u16 desc_id; | 120 | u16 desc_id; |
123 | u8 tid; | 121 | u8 tid; |
124 | u8 pad[2]; | ||
125 | u32 ba_low; | 122 | u32 ba_low; |
126 | u32 ba_high; | 123 | u32 ba_high; |
127 | u32 evm0; | 124 | u32 evm0; |