1 /* 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> 3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> 4 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20 /******************************\ 21 Hardware Descriptor Functions 22 \******************************/ 23 24 #include "ath5k.h" 25 #include "reg.h" 26 #include "debug.h" 27 28 29 /************************\ 30 * TX Control descriptors * 31 \************************/ 32 33 /* 34 * Initialize the 2-word tx control descriptor on 5210/5211 35 */ 36 static int 37 ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 38 unsigned int pkt_len, unsigned int hdr_len, int padsize, 39 enum ath5k_pkt_type type, 40 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, 41 unsigned int key_index, unsigned int antenna_mode, unsigned int flags, 42 unsigned int rtscts_rate, unsigned int rtscts_duration) 43 { 44 u32 frame_type; 45 struct ath5k_hw_2w_tx_ctl *tx_ctl; 46 unsigned int frame_len; 47 48 tx_ctl = &desc->ud.ds_tx5210.tx_ctl; 49 50 /* 51 * Validate input 52 * - Zero retries don't make sense. 53 * - 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 */ 56 if (unlikely(tx_tries0 == 0)) { 57 ATH5K_ERR(ah, "zero retries\n"); 58 WARN_ON(1); 59 return -EINVAL; 60 } 61 if (unlikely(tx_rate0 == 0)) { 62 ATH5K_ERR(ah, "zero rate\n"); 63 WARN_ON(1); 64 return -EINVAL; 65 } 66 67 /* Clear descriptor */ 68 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); 69 70 /* Setup control descriptor */ 71 72 /* Verify and set frame length */ 73 74 /* remove padding we might have added before */ 75 frame_len = pkt_len - padsize + FCS_LEN; 76 77 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) 78 return -EINVAL; 79 80 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; 81 82 /* Verify and set buffer length */ 83 84 /* NB: beacon's BufLen must be a multiple of 4 bytes */ 85 if (type == AR5K_PKT_TYPE_BEACON) 86 pkt_len = roundup(pkt_len, 4); 87 88 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) 89 return -EINVAL; 90 91 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; 92 93 /* 94 * Verify and set header length (only 5210) 95 */ 96 if (ah->ah_version == AR5K_AR5210) { 97 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210) 98 return -EINVAL; 99 tx_ctl->tx_control_0 |= 100 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210); 101 } 102 103 /*Differences between 5210-5211*/ 104 if (ah->ah_version == AR5K_AR5210) { 105 switch (type) { 106 case AR5K_PKT_TYPE_BEACON: 107 case AR5K_PKT_TYPE_PROBE_RESP: 108 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; 109 break; 110 case AR5K_PKT_TYPE_PIFS: 111 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; 112 break; 113 default: 114 frame_type = type; 115 break; 116 } 117 118 tx_ctl->tx_control_0 |= 119 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) | 120 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 121 122 } else { 123 tx_ctl->tx_control_0 |= 124 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | 125 AR5K_REG_SM(antenna_mode, 126 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); 127 tx_ctl->tx_control_1 |= 128 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211); 129 } 130 131 #define _TX_FLAGS(_c, _flag) \ 132 if (flags & AR5K_TXDESC_##_flag) { \ 133 tx_ctl->tx_control_##_c |= \ 134 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ 135 } 136 #define _TX_FLAGS_5211(_c, _flag) \ 137 if (flags & AR5K_TXDESC_##_flag) { \ 138 tx_ctl->tx_control_##_c |= \ 139 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \ 140 } 141 _TX_FLAGS(0, CLRDMASK); 142 _TX_FLAGS(0, INTREQ); 143 _TX_FLAGS(0, RTSENA); 144 145 if (ah->ah_version == AR5K_AR5211) { 146 _TX_FLAGS_5211(0, VEOL); 147 _TX_FLAGS_5211(1, NOACK); 148 } 149 150 #undef _TX_FLAGS 151 #undef _TX_FLAGS_5211 152 153 /* 154 * WEP crap 155 */ 156 if (key_index != AR5K_TXKEYIX_INVALID) { 157 tx_ctl->tx_control_0 |= 158 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 159 tx_ctl->tx_control_1 |= 160 AR5K_REG_SM(key_index, 161 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX); 162 } 163 164 /* 165 * RTS/CTS Duration [5210 ?] 166 */ 167 if ((ah->ah_version == AR5K_AR5210) && 168 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) 169 tx_ctl->tx_control_1 |= rtscts_duration & 170 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210; 171 172 return 0; 173 } 174 175 /* 176 * Initialize the 4-word tx control descriptor on 5212 177 */ 178 static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 179 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, 180 int padsize, 181 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, 182 unsigned int tx_tries0, unsigned int key_index, 183 unsigned int antenna_mode, unsigned int flags, 184 unsigned int rtscts_rate, 185 unsigned int rtscts_duration) 186 { 187 struct ath5k_hw_4w_tx_ctl *tx_ctl; 188 unsigned int frame_len; 189 190 /* 191 * Use local variables for these to reduce load/store access on 192 * uncached memory 193 */ 194 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; 195 196 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 197 198 /* 199 * Validate input 200 * - Zero retries don't make sense. 201 * - A zero rate will put the HW into a mode where it continuously sends 202 * noise on the channel, so it is important to avoid this. 203 */ 204 if (unlikely(tx_tries0 == 0)) { 205 ATH5K_ERR(ah, "zero retries\n"); 206 WARN_ON(1); 207 return -EINVAL; 208 } 209 if (unlikely(tx_rate0 == 0)) { 210 ATH5K_ERR(ah, "zero rate\n"); 211 WARN_ON(1); 212 return -EINVAL; 213 } 214 215 tx_power += ah->ah_txpower.txp_offset; 216 if (tx_power > AR5K_TUNE_MAX_TXPOWER) 217 tx_power = AR5K_TUNE_MAX_TXPOWER; 218 219 /* Clear descriptor status area */ 220 memset(&desc->ud.ds_tx5212.tx_stat, 0, 221 sizeof(desc->ud.ds_tx5212.tx_stat)); 222 223 /* Setup control descriptor */ 224 225 /* Verify and set frame length */ 226 227 /* remove padding we might have added before */ 228 frame_len = pkt_len - padsize + FCS_LEN; 229 230 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 231 return -EINVAL; 232 233 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; 234 235 /* Verify and set buffer length */ 236 237 /* NB: beacon's BufLen must be a multiple of 4 bytes */ 238 if (type == AR5K_PKT_TYPE_BEACON) 239 pkt_len = roundup(pkt_len, 4); 240 241 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) 242 return -EINVAL; 243 244 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; 245 246 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | 247 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 248 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 249 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); 250 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 251 252 #define _TX_FLAGS(_c, _flag) \ 253 if (flags & AR5K_TXDESC_##_flag) { \ 254 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ 255 } 256 257 _TX_FLAGS(0, CLRDMASK); 258 _TX_FLAGS(0, VEOL); 259 _TX_FLAGS(0, INTREQ); 260 _TX_FLAGS(0, RTSENA); 261 _TX_FLAGS(0, CTSENA); 262 _TX_FLAGS(1, NOACK); 263 264 #undef _TX_FLAGS 265 266 /* 267 * WEP crap 268 */ 269 if (key_index != AR5K_TXKEYIX_INVALID) { 270 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 271 txctl1 |= AR5K_REG_SM(key_index, 272 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); 273 } 274 275 /* 276 * RTS/CTS 277 */ 278 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { 279 if ((flags & AR5K_TXDESC_RTSENA) && 280 (flags & AR5K_TXDESC_CTSENA)) 281 return -EINVAL; 282 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; 283 txctl3 |= AR5K_REG_SM(rtscts_rate, 284 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); 285 } 286 287 tx_ctl->tx_control_0 = txctl0; 288 tx_ctl->tx_control_1 = txctl1; 289 tx_ctl->tx_control_2 = txctl2; 290 tx_ctl->tx_control_3 = txctl3; 291 292 return 0; 293 } 294 295 /* 296 * Initialize a 4-word multi rate retry tx control descriptor on 5212 297 */ 298 int 299 ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 300 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, 301 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) 302 { 303 struct ath5k_hw_4w_tx_ctl *tx_ctl; 304 305 /* no mrr support for cards older than 5212 */ 306 if (ah->ah_version < AR5K_AR5212) 307 return 0; 308 309 /* 310 * Rates can be 0 as long as the retry count is 0 too. 311 * A zero rate and nonzero retry count will put the HW into a mode where 312 * it continuously sends noise on the channel, so it is important to 313 * avoid this. 314 */ 315 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || 316 (tx_rate2 == 0 && tx_tries2 != 0) || 317 (tx_rate3 == 0 && tx_tries3 != 0))) { 318 ATH5K_ERR(ah, "zero rate\n"); 319 WARN_ON(1); 320 return -EINVAL; 321 } 322 323 if (ah->ah_version == AR5K_AR5212) { 324 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 325 326 #define _XTX_TRIES(_n) \ 327 if (tx_tries##_n) { \ 328 tx_ctl->tx_control_2 |= \ 329 AR5K_REG_SM(tx_tries##_n, \ 330 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ 331 tx_ctl->tx_control_3 |= \ 332 AR5K_REG_SM(tx_rate##_n, \ 333 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ 334 } 335 336 _XTX_TRIES(1); 337 _XTX_TRIES(2); 338 _XTX_TRIES(3); 339 340 #undef _XTX_TRIES 341 342 return 1; 343 } 344 345 return 0; 346 } 347 348 349 /***********************\ 350 * TX Status descriptors * 351 \***********************/ 352 353 /* 354 * Process the tx status descriptor on 5210/5211 355 */ 356 static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, 357 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 358 { 359 struct ath5k_hw_2w_tx_ctl *tx_ctl; 360 struct ath5k_hw_tx_status *tx_status; 361 362 tx_ctl = &desc->ud.ds_tx5210.tx_ctl; 363 tx_status = &desc->ud.ds_tx5210.tx_stat; 364 365 /* No frame has been send or error */ 366 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) 367 return -EINPROGRESS; 368 369 /* 370 * Get descriptor status 371 */ 372 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 373 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 374 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 375 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 376 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, 377 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 378 /*TODO: ts->ts_virtcol + test*/ 379 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 380 AR5K_DESC_TX_STATUS1_SEQ_NUM); 381 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 382 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 383 ts->ts_antenna = 1; 384 ts->ts_status = 0; 385 ts->ts_final_idx = 0; 386 387 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 388 if (tx_status->tx_status_0 & 389 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 390 ts->ts_status |= AR5K_TXERR_XRETRY; 391 392 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 393 ts->ts_status |= AR5K_TXERR_FIFO; 394 395 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 396 ts->ts_status |= AR5K_TXERR_FILT; 397 } 398 399 return 0; 400 } 401 402 /* 403 * Process a tx status descriptor on 5212 404 */ 405 static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, 406 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 407 { 408 struct ath5k_hw_4w_tx_ctl *tx_ctl; 409 struct ath5k_hw_tx_status *tx_status; 410 u32 txstat0, txstat1; 411 412 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 413 tx_status = &desc->ud.ds_tx5212.tx_stat; 414 415 txstat1 = ACCESS_ONCE(tx_status->tx_status_1); 416 417 /* No frame has been send or error */ 418 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) 419 return -EINPROGRESS; 420 421 txstat0 = ACCESS_ONCE(tx_status->tx_status_0); 422 423 /* 424 * Get descriptor status 425 */ 426 ts->ts_tstamp = AR5K_REG_MS(txstat0, 427 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 428 ts->ts_shortretry = AR5K_REG_MS(txstat0, 429 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 430 ts->ts_final_retry = AR5K_REG_MS(txstat0, 431 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 432 ts->ts_seqnum = AR5K_REG_MS(txstat1, 433 AR5K_DESC_TX_STATUS1_SEQ_NUM); 434 ts->ts_rssi = AR5K_REG_MS(txstat1, 435 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 436 ts->ts_antenna = (txstat1 & 437 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; 438 ts->ts_status = 0; 439 440 ts->ts_final_idx = AR5K_REG_MS(txstat1, 441 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); 442 443 /* TX error */ 444 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 445 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 446 ts->ts_status |= AR5K_TXERR_XRETRY; 447 448 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 449 ts->ts_status |= AR5K_TXERR_FIFO; 450 451 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) 452 ts->ts_status |= AR5K_TXERR_FILT; 453 } 454 455 return 0; 456 } 457 458 459 /****************\ 460 * RX Descriptors * 461 \****************/ 462 463 /* 464 * Initialize an rx control descriptor 465 */ 466 int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 467 u32 size, unsigned int flags) 468 { 469 struct ath5k_hw_rx_ctl *rx_ctl; 470 471 rx_ctl = &desc->ud.ds_rx.rx_ctl; 472 473 /* 474 * Clear the descriptor 475 * If we don't clean the status descriptor, 476 * while scanning we get too many results, 477 * most of them virtual, after some secs 478 * of scanning system hangs. M.F. 479 */ 480 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); 481 482 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN)) 483 return -EINVAL; 484 485 /* Setup descriptor */ 486 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; 487 488 if (flags & AR5K_RXDESC_INTREQ) 489 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; 490 491 return 0; 492 } 493 494 /* 495 * Process the rx status descriptor on 5210/5211 496 */ 497 static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, 498 struct ath5k_desc *desc, struct ath5k_rx_status *rs) 499 { 500 struct ath5k_hw_rx_status *rx_status; 501 502 rx_status = &desc->ud.ds_rx.rx_stat; 503 504 /* No frame received / not ready */ 505 if (unlikely(!(rx_status->rx_status_1 & 506 AR5K_5210_RX_DESC_STATUS1_DONE))) 507 return -EINPROGRESS; 508 509 memset(rs, 0, sizeof(struct ath5k_rx_status)); 510 511 /* 512 * Frame receive status 513 */ 514 rs->rs_datalen = rx_status->rx_status_0 & 515 AR5K_5210_RX_DESC_STATUS0_DATA_LEN; 516 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, 517 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); 518 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 519 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); 520 rs->rs_more = !!(rx_status->rx_status_0 & 521 AR5K_5210_RX_DESC_STATUS0_MORE); 522 /* TODO: this timestamp is 13 bit, later on we assume 15 bit! 523 * also the HAL code for 5210 says the timestamp is bits [10..22] of the 524 * TSF, and extends the timestamp here to 15 bit. 525 * we need to check on 5210... 526 */ 527 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 528 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 529 530 if (ah->ah_version == AR5K_AR5211) 531 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, 532 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211); 533 else 534 rs->rs_antenna = (rx_status->rx_status_0 & 535 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) 536 ? 2 : 1; 537 538 /* 539 * Key table status 540 */ 541 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) 542 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 543 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); 544 else 545 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 546 547 /* 548 * Receive/descriptor errors 549 */ 550 if (!(rx_status->rx_status_1 & 551 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 552 if (rx_status->rx_status_1 & 553 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) 554 rs->rs_status |= AR5K_RXERR_CRC; 555 556 /* only on 5210 */ 557 if ((ah->ah_version == AR5K_AR5210) && 558 (rx_status->rx_status_1 & 559 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210)) 560 rs->rs_status |= AR5K_RXERR_FIFO; 561 562 if (rx_status->rx_status_1 & 563 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { 564 rs->rs_status |= AR5K_RXERR_PHY; 565 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, 566 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); 567 } 568 569 if (rx_status->rx_status_1 & 570 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 571 rs->rs_status |= AR5K_RXERR_DECRYPT; 572 } 573 574 return 0; 575 } 576 577 /* 578 * Process the rx status descriptor on 5212 579 */ 580 static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, 581 struct ath5k_desc *desc, 582 struct ath5k_rx_status *rs) 583 { 584 struct ath5k_hw_rx_status *rx_status; 585 u32 rxstat0, rxstat1; 586 587 rx_status = &desc->ud.ds_rx.rx_stat; 588 rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); 589 590 /* No frame received / not ready */ 591 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) 592 return -EINPROGRESS; 593 594 memset(rs, 0, sizeof(struct ath5k_rx_status)); 595 rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); 596 597 /* 598 * Frame receive status 599 */ 600 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; 601 rs->rs_rssi = AR5K_REG_MS(rxstat0, 602 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); 603 rs->rs_rate = AR5K_REG_MS(rxstat0, 604 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); 605 rs->rs_antenna = AR5K_REG_MS(rxstat0, 606 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); 607 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); 608 rs->rs_tstamp = AR5K_REG_MS(rxstat1, 609 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 610 611 /* 612 * Key table status 613 */ 614 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) 615 rs->rs_keyix = AR5K_REG_MS(rxstat1, 616 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); 617 else 618 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 619 620 /* 621 * Receive/descriptor errors 622 */ 623 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 624 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) 625 rs->rs_status |= AR5K_RXERR_CRC; 626 627 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { 628 rs->rs_status |= AR5K_RXERR_PHY; 629 rs->rs_phyerr = AR5K_REG_MS(rxstat1, 630 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); 631 if (!ah->ah_capabilities.cap_has_phyerr_counters) 632 ath5k_ani_phy_error_report(ah, rs->rs_phyerr); 633 } 634 635 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 636 rs->rs_status |= AR5K_RXERR_DECRYPT; 637 638 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) 639 rs->rs_status |= AR5K_RXERR_MIC; 640 } 641 return 0; 642 } 643 644 645 /********\ 646 * Attach * 647 \********/ 648 649 /* 650 * Init function pointers inside ath5k_hw struct 651 */ 652 int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) 653 { 654 if (ah->ah_version == AR5K_AR5212) { 655 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 656 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; 657 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; 658 } else if (ah->ah_version <= AR5K_AR5211) { 659 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; 660 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; 661 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; 662 } else 663 return -ENOTSUPP; 664 return 0; 665 } 666