diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/desc.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/desc.c | 199 |
1 files changed, 90 insertions, 109 deletions
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 43244382f213..f82383b3ed30 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -26,9 +26,10 @@ | |||
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "base.h" | 27 | #include "base.h" |
28 | 28 | ||
29 | /* | 29 | |
30 | * TX Descriptors | 30 | /************************\ |
31 | */ | 31 | * TX Control descriptors * |
32 | \************************/ | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Initialize the 2-word tx control descriptor on 5210/5211 | 35 | * Initialize the 2-word tx control descriptor on 5210/5211 |
@@ -50,7 +51,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
50 | /* | 51 | /* |
51 | * Validate input | 52 | * Validate input |
52 | * - Zero retries don't make sense. | 53 | * - Zero retries don't make sense. |
53 | * - A zero rate will put the HW into a mode where it continously sends | 54 | * - A zero rate will put the HW into a mode where it continuously sends |
54 | * noise on the channel, so it is important to avoid this. | 55 | * noise on the channel, so it is important to avoid this. |
55 | */ | 56 | */ |
56 | if (unlikely(tx_tries0 == 0)) { | 57 | if (unlikely(tx_tries0 == 0)) { |
@@ -106,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
106 | case AR5K_PKT_TYPE_BEACON: | 107 | case AR5K_PKT_TYPE_BEACON: |
107 | case AR5K_PKT_TYPE_PROBE_RESP: | 108 | case AR5K_PKT_TYPE_PROBE_RESP: |
108 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; | 109 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; |
110 | break; | ||
109 | case AR5K_PKT_TYPE_PIFS: | 111 | case AR5K_PKT_TYPE_PIFS: |
110 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; | 112 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; |
113 | break; | ||
111 | default: | 114 | default: |
112 | frame_type = type; | 115 | frame_type = type; |
116 | break; | ||
113 | } | 117 | } |
114 | 118 | ||
115 | tx_ctl->tx_control_0 |= | 119 | tx_ctl->tx_control_0 |= |
@@ -184,12 +188,18 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
184 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 188 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
185 | unsigned int frame_len; | 189 | unsigned int frame_len; |
186 | 190 | ||
191 | /* | ||
192 | * Use local variables for these to reduce load/store access on | ||
193 | * uncached memory | ||
194 | */ | ||
195 | u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; | ||
196 | |||
187 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 197 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
188 | 198 | ||
189 | /* | 199 | /* |
190 | * Validate input | 200 | * Validate input |
191 | * - Zero retries don't make sense. | 201 | * - Zero retries don't make sense. |
192 | * - A zero rate will put the HW into a mode where it continously sends | 202 | * - A zero rate will put the HW into a mode where it continuously sends |
193 | * noise on the channel, so it is important to avoid this. | 203 | * noise on the channel, so it is important to avoid this. |
194 | */ | 204 | */ |
195 | if (unlikely(tx_tries0 == 0)) { | 205 | if (unlikely(tx_tries0 == 0)) { |
@@ -207,8 +217,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
207 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) | 217 | if (tx_power > AR5K_TUNE_MAX_TXPOWER) |
208 | tx_power = AR5K_TUNE_MAX_TXPOWER; | 218 | tx_power = AR5K_TUNE_MAX_TXPOWER; |
209 | 219 | ||
210 | /* Clear descriptor */ | 220 | /* Clear descriptor status area */ |
211 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | 221 | memset(&desc->ud.ds_tx5212.tx_stat, 0, |
222 | sizeof(desc->ud.ds_tx5212.tx_stat)); | ||
212 | 223 | ||
213 | /* Setup control descriptor */ | 224 | /* Setup control descriptor */ |
214 | 225 | ||
@@ -220,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
220 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 231 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
221 | return -EINVAL; | 232 | return -EINVAL; |
222 | 233 | ||
223 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | 234 | txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; |
224 | 235 | ||
225 | /* Verify and set buffer length */ | 236 | /* Verify and set buffer length */ |
226 | 237 | ||
@@ -231,21 +242,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
231 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | 242 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) |
232 | return -EINVAL; | 243 | return -EINVAL; |
233 | 244 | ||
234 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | 245 | txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; |
235 | 246 | ||
236 | tx_ctl->tx_control_0 |= | 247 | txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | |
237 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | 248 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
238 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 249 | txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
239 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 250 | txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
240 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 251 | txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
241 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, | ||
242 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
243 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
244 | 252 | ||
245 | #define _TX_FLAGS(_c, _flag) \ | 253 | #define _TX_FLAGS(_c, _flag) \ |
246 | if (flags & AR5K_TXDESC_##_flag) { \ | 254 | if (flags & AR5K_TXDESC_##_flag) { \ |
247 | tx_ctl->tx_control_##_c |= \ | 255 | txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ |
248 | AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ | ||
249 | } | 256 | } |
250 | 257 | ||
251 | _TX_FLAGS(0, CLRDMASK); | 258 | _TX_FLAGS(0, CLRDMASK); |
@@ -261,8 +268,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
261 | * WEP crap | 268 | * WEP crap |
262 | */ | 269 | */ |
263 | if (key_index != AR5K_TXKEYIX_INVALID) { | 270 | if (key_index != AR5K_TXKEYIX_INVALID) { |
264 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | 271 | txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; |
265 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | 272 | txctl1 |= AR5K_REG_SM(key_index, |
266 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); | 273 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); |
267 | } | 274 | } |
268 | 275 | ||
@@ -273,12 +280,16 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
273 | if ((flags & AR5K_TXDESC_RTSENA) && | 280 | if ((flags & AR5K_TXDESC_RTSENA) && |
274 | (flags & AR5K_TXDESC_CTSENA)) | 281 | (flags & AR5K_TXDESC_CTSENA)) |
275 | return -EINVAL; | 282 | return -EINVAL; |
276 | tx_ctl->tx_control_2 |= rtscts_duration & | 283 | txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; |
277 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | 284 | txctl3 |= AR5K_REG_SM(rtscts_rate, |
278 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
279 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | 285 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); |
280 | } | 286 | } |
281 | 287 | ||
288 | tx_ctl->tx_control_0 = txctl0; | ||
289 | tx_ctl->tx_control_1 = txctl1; | ||
290 | tx_ctl->tx_control_2 = txctl2; | ||
291 | tx_ctl->tx_control_3 = txctl3; | ||
292 | |||
282 | return 0; | 293 | return 0; |
283 | } | 294 | } |
284 | 295 | ||
@@ -299,7 +310,7 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
299 | /* | 310 | /* |
300 | * Rates can be 0 as long as the retry count is 0 too. | 311 | * Rates can be 0 as long as the retry count is 0 too. |
301 | * A zero rate and nonzero retry count will put the HW into a mode where | 312 | * A zero rate and nonzero retry count will put the HW into a mode where |
302 | * it continously sends noise on the channel, so it is important to | 313 | * it continuously sends noise on the channel, so it is important to |
303 | * avoid this. | 314 | * avoid this. |
304 | */ | 315 | */ |
305 | if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || | 316 | if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || |
@@ -335,8 +346,13 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
335 | return 0; | 346 | return 0; |
336 | } | 347 | } |
337 | 348 | ||
349 | |||
350 | /***********************\ | ||
351 | * TX Status descriptors * | ||
352 | \***********************/ | ||
353 | |||
338 | /* | 354 | /* |
339 | * Proccess the tx status descriptor on 5210/5211 | 355 | * Process the tx status descriptor on 5210/5211 |
340 | */ | 356 | */ |
341 | static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | 357 | static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, |
342 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | 358 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) |
@@ -358,7 +374,7 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
358 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 374 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
359 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 375 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, |
360 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 376 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
361 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 377 | ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, |
362 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 378 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
363 | /*TODO: ts->ts_virtcol + test*/ | 379 | /*TODO: ts->ts_virtcol + test*/ |
364 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 380 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, |
@@ -367,9 +383,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
367 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 383 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
368 | ts->ts_antenna = 1; | 384 | ts->ts_antenna = 1; |
369 | ts->ts_status = 0; | 385 | ts->ts_status = 0; |
370 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
371 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
372 | ts->ts_retry[0] = ts->ts_longretry; | ||
373 | ts->ts_final_idx = 0; | 386 | ts->ts_final_idx = 0; |
374 | 387 | ||
375 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 388 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
@@ -388,97 +401,65 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | |||
388 | } | 401 | } |
389 | 402 | ||
390 | /* | 403 | /* |
391 | * Proccess a tx status descriptor on 5212 | 404 | * Process a tx status descriptor on 5212 |
392 | */ | 405 | */ |
393 | static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | 406 | static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, |
394 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | 407 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) |
395 | { | 408 | { |
396 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | 409 | struct ath5k_hw_4w_tx_ctl *tx_ctl; |
397 | struct ath5k_hw_tx_status *tx_status; | 410 | struct ath5k_hw_tx_status *tx_status; |
411 | u32 txstat0, txstat1; | ||
398 | 412 | ||
399 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | 413 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; |
400 | tx_status = &desc->ud.ds_tx5212.tx_stat; | 414 | tx_status = &desc->ud.ds_tx5212.tx_stat; |
401 | 415 | ||
416 | txstat1 = ACCESS_ONCE(tx_status->tx_status_1); | ||
417 | |||
402 | /* No frame has been send or error */ | 418 | /* No frame has been send or error */ |
403 | if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) | 419 | if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) |
404 | return -EINPROGRESS; | 420 | return -EINPROGRESS; |
405 | 421 | ||
422 | txstat0 = ACCESS_ONCE(tx_status->tx_status_0); | ||
423 | |||
406 | /* | 424 | /* |
407 | * Get descriptor status | 425 | * Get descriptor status |
408 | */ | 426 | */ |
409 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | 427 | ts->ts_tstamp = AR5K_REG_MS(txstat0, |
410 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | 428 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); |
411 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | 429 | ts->ts_shortretry = AR5K_REG_MS(txstat0, |
412 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | 430 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); |
413 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | 431 | ts->ts_final_retry = AR5K_REG_MS(txstat0, |
414 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | 432 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); |
415 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | 433 | ts->ts_seqnum = AR5K_REG_MS(txstat1, |
416 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | 434 | AR5K_DESC_TX_STATUS1_SEQ_NUM); |
417 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | 435 | ts->ts_rssi = AR5K_REG_MS(txstat1, |
418 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | 436 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); |
419 | ts->ts_antenna = (tx_status->tx_status_1 & | 437 | ts->ts_antenna = (txstat1 & |
420 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; | 438 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; |
421 | ts->ts_status = 0; | 439 | ts->ts_status = 0; |
422 | 440 | ||
423 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, | 441 | ts->ts_final_idx = AR5K_REG_MS(txstat1, |
424 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); | 442 | AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); |
425 | 443 | ||
426 | /* The longretry counter has the number of un-acked retries | ||
427 | * for the final rate. To get the total number of retries | ||
428 | * we have to add the retry counters for the other rates | ||
429 | * as well | ||
430 | */ | ||
431 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
432 | switch (ts->ts_final_idx) { | ||
433 | case 3: | ||
434 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
435 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
436 | |||
437 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
438 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
439 | ts->ts_longretry += ts->ts_retry[2]; | ||
440 | /* fall through */ | ||
441 | case 2: | ||
442 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
443 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
444 | |||
445 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
446 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
447 | ts->ts_longretry += ts->ts_retry[1]; | ||
448 | /* fall through */ | ||
449 | case 1: | ||
450 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
451 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
452 | |||
453 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
454 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
455 | ts->ts_longretry += ts->ts_retry[0]; | ||
456 | /* fall through */ | ||
457 | case 0: | ||
458 | ts->ts_rate[0] = tx_ctl->tx_control_3 & | ||
459 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | /* TX error */ | 444 | /* TX error */ |
464 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | 445 | if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { |
465 | if (tx_status->tx_status_0 & | 446 | if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) |
466 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
467 | ts->ts_status |= AR5K_TXERR_XRETRY; | 447 | ts->ts_status |= AR5K_TXERR_XRETRY; |
468 | 448 | ||
469 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | 449 | if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) |
470 | ts->ts_status |= AR5K_TXERR_FIFO; | 450 | ts->ts_status |= AR5K_TXERR_FIFO; |
471 | 451 | ||
472 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | 452 | if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) |
473 | ts->ts_status |= AR5K_TXERR_FILT; | 453 | ts->ts_status |= AR5K_TXERR_FILT; |
474 | } | 454 | } |
475 | 455 | ||
476 | return 0; | 456 | return 0; |
477 | } | 457 | } |
478 | 458 | ||
479 | /* | 459 | |
480 | * RX Descriptors | 460 | /****************\ |
481 | */ | 461 | * RX Descriptors * |
462 | \****************/ | ||
482 | 463 | ||
483 | /* | 464 | /* |
484 | * Initialize an rx control descriptor | 465 | * Initialize an rx control descriptor |
@@ -512,7 +493,7 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
512 | } | 493 | } |
513 | 494 | ||
514 | /* | 495 | /* |
515 | * Proccess the rx status descriptor on 5210/5211 | 496 | * Process the rx status descriptor on 5210/5211 |
516 | */ | 497 | */ |
517 | static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | 498 | static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, |
518 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) | 499 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) |
@@ -595,44 +576,44 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
595 | } | 576 | } |
596 | 577 | ||
597 | /* | 578 | /* |
598 | * Proccess the rx status descriptor on 5212 | 579 | * Process the rx status descriptor on 5212 |
599 | */ | 580 | */ |
600 | static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | 581 | static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, |
601 | struct ath5k_desc *desc, | 582 | struct ath5k_desc *desc, |
602 | struct ath5k_rx_status *rs) | 583 | struct ath5k_rx_status *rs) |
603 | { | 584 | { |
604 | struct ath5k_hw_rx_status *rx_status; | 585 | struct ath5k_hw_rx_status *rx_status; |
586 | u32 rxstat0, rxstat1; | ||
605 | 587 | ||
606 | rx_status = &desc->ud.ds_rx.rx_stat; | 588 | rx_status = &desc->ud.ds_rx.rx_stat; |
589 | rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); | ||
607 | 590 | ||
608 | /* No frame received / not ready */ | 591 | /* No frame received / not ready */ |
609 | if (unlikely(!(rx_status->rx_status_1 & | 592 | if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) |
610 | AR5K_5212_RX_DESC_STATUS1_DONE))) | ||
611 | return -EINPROGRESS; | 593 | return -EINPROGRESS; |
612 | 594 | ||
613 | memset(rs, 0, sizeof(struct ath5k_rx_status)); | 595 | memset(rs, 0, sizeof(struct ath5k_rx_status)); |
596 | rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); | ||
614 | 597 | ||
615 | /* | 598 | /* |
616 | * Frame receive status | 599 | * Frame receive status |
617 | */ | 600 | */ |
618 | rs->rs_datalen = rx_status->rx_status_0 & | 601 | rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; |
619 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | 602 | rs->rs_rssi = AR5K_REG_MS(rxstat0, |
620 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
621 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 603 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
622 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 604 | rs->rs_rate = AR5K_REG_MS(rxstat0, |
623 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 605 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
624 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, | 606 | rs->rs_antenna = AR5K_REG_MS(rxstat0, |
625 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); | 607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
626 | rs->rs_more = !!(rx_status->rx_status_0 & | 608 | rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); |
627 | AR5K_5212_RX_DESC_STATUS0_MORE); | 609 | rs->rs_tstamp = AR5K_REG_MS(rxstat1, |
628 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
629 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 610 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
630 | 611 | ||
631 | /* | 612 | /* |
632 | * Key table status | 613 | * Key table status |
633 | */ | 614 | */ |
634 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | 615 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) |
635 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | 616 | rs->rs_keyix = AR5K_REG_MS(rxstat1, |
636 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | 617 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); |
637 | else | 618 | else |
638 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | 619 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; |
@@ -640,32 +621,32 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
640 | /* | 621 | /* |
641 | * Receive/descriptor errors | 622 | * Receive/descriptor errors |
642 | */ | 623 | */ |
643 | if (!(rx_status->rx_status_1 & | 624 | if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { |
644 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | 625 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) |
645 | if (rx_status->rx_status_1 & | ||
646 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
647 | rs->rs_status |= AR5K_RXERR_CRC; | 626 | rs->rs_status |= AR5K_RXERR_CRC; |
648 | 627 | ||
649 | if (rx_status->rx_status_1 & | 628 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { |
650 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
651 | rs->rs_status |= AR5K_RXERR_PHY; | 629 | rs->rs_status |= AR5K_RXERR_PHY; |
652 | rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, | 630 | rs->rs_phyerr = AR5K_REG_MS(rxstat1, |
653 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); | 631 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); |
654 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | 632 | if (!ah->ah_capabilities.cap_has_phyerr_counters) |
655 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); | 633 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); |
656 | } | 634 | } |
657 | 635 | ||
658 | if (rx_status->rx_status_1 & | 636 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) |
659 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
660 | rs->rs_status |= AR5K_RXERR_DECRYPT; | 637 | rs->rs_status |= AR5K_RXERR_DECRYPT; |
661 | 638 | ||
662 | if (rx_status->rx_status_1 & | 639 | if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) |
663 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
664 | rs->rs_status |= AR5K_RXERR_MIC; | 640 | rs->rs_status |= AR5K_RXERR_MIC; |
665 | } | 641 | } |
666 | return 0; | 642 | return 0; |
667 | } | 643 | } |
668 | 644 | ||
645 | |||
646 | /********\ | ||
647 | * Attach * | ||
648 | \********/ | ||
649 | |||
669 | /* | 650 | /* |
670 | * Init function pointers inside ath5k_hw struct | 651 | * Init function pointers inside ath5k_hw struct |
671 | */ | 652 | */ |