desc.c revision 8786123b51984c518436911048668f9673f30cdf
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#include "base.h" 28 29/* 30 * TX Descriptors 31 */ 32 33/* 34 * Initialize the 2-word tx control descriptor on 5210/5211 35 */ 36static int 37ath5k_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 continously sends 54 * noise on the channel, so it is important to avoid this. 55 */ 56 if (unlikely(tx_tries0 == 0)) { 57 ATH5K_ERR(ah->ah_sc, "zero retries\n"); 58 WARN_ON(1); 59 return -EINVAL; 60 } 61 if (unlikely(tx_rate0 == 0)) { 62 ATH5K_ERR(ah->ah_sc, "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 case AR5K_PKT_TYPE_PIFS: 110 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; 111 default: 112 frame_type = type; 113 } 114 115 tx_ctl->tx_control_0 |= 116 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) | 117 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 118 119 } else { 120 tx_ctl->tx_control_0 |= 121 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | 122 AR5K_REG_SM(antenna_mode, 123 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); 124 tx_ctl->tx_control_1 |= 125 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211); 126 } 127 128#define _TX_FLAGS(_c, _flag) \ 129 if (flags & AR5K_TXDESC_##_flag) { \ 130 tx_ctl->tx_control_##_c |= \ 131 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ 132 } 133#define _TX_FLAGS_5211(_c, _flag) \ 134 if (flags & AR5K_TXDESC_##_flag) { \ 135 tx_ctl->tx_control_##_c |= \ 136 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \ 137 } 138 _TX_FLAGS(0, CLRDMASK); 139 _TX_FLAGS(0, INTREQ); 140 _TX_FLAGS(0, RTSENA); 141 142 if (ah->ah_version == AR5K_AR5211) { 143 _TX_FLAGS_5211(0, VEOL); 144 _TX_FLAGS_5211(1, NOACK); 145 } 146 147#undef _TX_FLAGS 148#undef _TX_FLAGS_5211 149 150 /* 151 * WEP crap 152 */ 153 if (key_index != AR5K_TXKEYIX_INVALID) { 154 tx_ctl->tx_control_0 |= 155 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 156 tx_ctl->tx_control_1 |= 157 AR5K_REG_SM(key_index, 158 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX); 159 } 160 161 /* 162 * RTS/CTS Duration [5210 ?] 163 */ 164 if ((ah->ah_version == AR5K_AR5210) && 165 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) 166 tx_ctl->tx_control_1 |= rtscts_duration & 167 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210; 168 169 return 0; 170} 171 172/* 173 * Initialize the 4-word tx control descriptor on 5212 174 */ 175static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, 176 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, 177 int padsize, 178 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, 179 unsigned int tx_tries0, unsigned int key_index, 180 unsigned int antenna_mode, unsigned int flags, 181 unsigned int rtscts_rate, 182 unsigned int rtscts_duration) 183{ 184 struct ath5k_hw_4w_tx_ctl *tx_ctl; 185 unsigned int frame_len; 186 187 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 188 189 /* 190 * Validate input 191 * - Zero retries don't make sense. 192 * - A zero rate will put the HW into a mode where it continously sends 193 * noise on the channel, so it is important to avoid this. 194 */ 195 if (unlikely(tx_tries0 == 0)) { 196 ATH5K_ERR(ah->ah_sc, "zero retries\n"); 197 WARN_ON(1); 198 return -EINVAL; 199 } 200 if (unlikely(tx_rate0 == 0)) { 201 ATH5K_ERR(ah->ah_sc, "zero rate\n"); 202 WARN_ON(1); 203 return -EINVAL; 204 } 205 206 tx_power += ah->ah_txpower.txp_offset; 207 if (tx_power > AR5K_TUNE_MAX_TXPOWER) 208 tx_power = AR5K_TUNE_MAX_TXPOWER; 209 210 /* Clear descriptor */ 211 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); 212 213 /* Setup control descriptor */ 214 215 /* Verify and set frame length */ 216 217 /* remove padding we might have added before */ 218 frame_len = pkt_len - padsize + FCS_LEN; 219 220 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 221 return -EINVAL; 222 223 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; 224 225 /* Verify and set buffer length */ 226 227 /* NB: beacon's BufLen must be a multiple of 4 bytes */ 228 if (type == AR5K_PKT_TYPE_BEACON) 229 pkt_len = roundup(pkt_len, 4); 230 231 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) 232 return -EINVAL; 233 234 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; 235 236 tx_ctl->tx_control_0 |= 237 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | 238 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 239 tx_ctl->tx_control_1 |= AR5K_REG_SM(type, 240 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 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 245#define _TX_FLAGS(_c, _flag) \ 246 if (flags & AR5K_TXDESC_##_flag) { \ 247 tx_ctl->tx_control_##_c |= \ 248 AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ 249 } 250 251 _TX_FLAGS(0, CLRDMASK); 252 _TX_FLAGS(0, VEOL); 253 _TX_FLAGS(0, INTREQ); 254 _TX_FLAGS(0, RTSENA); 255 _TX_FLAGS(0, CTSENA); 256 _TX_FLAGS(1, NOACK); 257 258#undef _TX_FLAGS 259 260 /* 261 * WEP crap 262 */ 263 if (key_index != AR5K_TXKEYIX_INVALID) { 264 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 265 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, 266 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); 267 } 268 269 /* 270 * RTS/CTS 271 */ 272 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { 273 if ((flags & AR5K_TXDESC_RTSENA) && 274 (flags & AR5K_TXDESC_CTSENA)) 275 return -EINVAL; 276 tx_ctl->tx_control_2 |= rtscts_duration & 277 AR5K_4W_TX_DESC_CTL2_RTS_DURATION; 278 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, 279 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); 280 } 281 282 return 0; 283} 284 285/* 286 * Initialize a 4-word multi rate retry tx control descriptor on 5212 287 */ 288int 289ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 290 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, 291 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) 292{ 293 struct ath5k_hw_4w_tx_ctl *tx_ctl; 294 295 /* no mrr support for cards older than 5212 */ 296 if (ah->ah_version < AR5K_AR5212) 297 return 0; 298 299 /* 300 * 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 302 * it continously sends noise on the channel, so it is important to 303 * avoid this. 304 */ 305 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || 306 (tx_rate2 == 0 && tx_tries2 != 0) || 307 (tx_rate3 == 0 && tx_tries3 != 0))) { 308 ATH5K_ERR(ah->ah_sc, "zero rate\n"); 309 WARN_ON(1); 310 return -EINVAL; 311 } 312 313 if (ah->ah_version == AR5K_AR5212) { 314 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 315 316#define _XTX_TRIES(_n) \ 317 if (tx_tries##_n) { \ 318 tx_ctl->tx_control_2 |= \ 319 AR5K_REG_SM(tx_tries##_n, \ 320 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ 321 tx_ctl->tx_control_3 |= \ 322 AR5K_REG_SM(tx_rate##_n, \ 323 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ 324 } 325 326 _XTX_TRIES(1); 327 _XTX_TRIES(2); 328 _XTX_TRIES(3); 329 330#undef _XTX_TRIES 331 332 return 1; 333 } 334 335 return 0; 336} 337 338/* 339 * Proccess the tx status descriptor on 5210/5211 340 */ 341static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, 342 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 343{ 344 struct ath5k_hw_2w_tx_ctl *tx_ctl; 345 struct ath5k_hw_tx_status *tx_status; 346 347 tx_ctl = &desc->ud.ds_tx5210.tx_ctl; 348 tx_status = &desc->ud.ds_tx5210.tx_stat; 349 350 /* No frame has been send or error */ 351 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) 352 return -EINPROGRESS; 353 354 /* 355 * Get descriptor status 356 */ 357 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 358 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 359 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 360 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 361 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 362 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 363 /*TODO: ts->ts_virtcol + test*/ 364 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 365 AR5K_DESC_TX_STATUS1_SEQ_NUM); 366 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 367 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 368 ts->ts_antenna = 1; 369 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; 374 375 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 376 if (tx_status->tx_status_0 & 377 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 378 ts->ts_status |= AR5K_TXERR_XRETRY; 379 380 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 381 ts->ts_status |= AR5K_TXERR_FIFO; 382 383 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 384 ts->ts_status |= AR5K_TXERR_FILT; 385 } 386 387 return 0; 388} 389 390/* 391 * Proccess a tx status descriptor on 5212 392 */ 393static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, 394 struct ath5k_desc *desc, struct ath5k_tx_status *ts) 395{ 396 struct ath5k_hw_4w_tx_ctl *tx_ctl; 397 struct ath5k_hw_tx_status *tx_status; 398 399 tx_ctl = &desc->ud.ds_tx5212.tx_ctl; 400 tx_status = &desc->ud.ds_tx5212.tx_stat; 401 402 /* No frame has been send or error */ 403 if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) 404 return -EINPROGRESS; 405 406 /* 407 * Get descriptor status 408 */ 409 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 410 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 411 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 412 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 413 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 414 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 415 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 416 AR5K_DESC_TX_STATUS1_SEQ_NUM); 417 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 418 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 419 ts->ts_antenna = (tx_status->tx_status_1 & 420 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; 421 ts->ts_status = 0; 422 423 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, 424 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); 425 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 */ 464 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 465 if (tx_status->tx_status_0 & 466 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 467 ts->ts_status |= AR5K_TXERR_XRETRY; 468 469 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 470 ts->ts_status |= AR5K_TXERR_FIFO; 471 472 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 473 ts->ts_status |= AR5K_TXERR_FILT; 474 } 475 476 return 0; 477} 478 479/* 480 * RX Descriptors 481 */ 482 483/* 484 * Initialize an rx control descriptor 485 */ 486int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 487 u32 size, unsigned int flags) 488{ 489 struct ath5k_hw_rx_ctl *rx_ctl; 490 491 rx_ctl = &desc->ud.ds_rx.rx_ctl; 492 493 /* 494 * Clear the descriptor 495 * If we don't clean the status descriptor, 496 * while scanning we get too many results, 497 * most of them virtual, after some secs 498 * of scanning system hangs. M.F. 499 */ 500 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); 501 502 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN)) 503 return -EINVAL; 504 505 /* Setup descriptor */ 506 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; 507 508 if (flags & AR5K_RXDESC_INTREQ) 509 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; 510 511 return 0; 512} 513 514/* 515 * Proccess the rx status descriptor on 5210/5211 516 */ 517static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, 518 struct ath5k_desc *desc, struct ath5k_rx_status *rs) 519{ 520 struct ath5k_hw_rx_status *rx_status; 521 522 rx_status = &desc->ud.ds_rx.rx_stat; 523 524 /* No frame received / not ready */ 525 if (unlikely(!(rx_status->rx_status_1 & 526 AR5K_5210_RX_DESC_STATUS1_DONE))) 527 return -EINPROGRESS; 528 529 memset(rs, 0, sizeof(struct ath5k_rx_status)); 530 531 /* 532 * Frame receive status 533 */ 534 rs->rs_datalen = rx_status->rx_status_0 & 535 AR5K_5210_RX_DESC_STATUS0_DATA_LEN; 536 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, 537 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); 538 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 539 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); 540 rs->rs_more = !!(rx_status->rx_status_0 & 541 AR5K_5210_RX_DESC_STATUS0_MORE); 542 /* TODO: this timestamp is 13 bit, later on we assume 15 bit! 543 * also the HAL code for 5210 says the timestamp is bits [10..22] of the 544 * TSF, and extends the timestamp here to 15 bit. 545 * we need to check on 5210... 546 */ 547 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 548 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 549 550 if (ah->ah_version == AR5K_AR5211) 551 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, 552 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211); 553 else 554 rs->rs_antenna = (rx_status->rx_status_0 & 555 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) 556 ? 2 : 1; 557 558 /* 559 * Key table status 560 */ 561 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) 562 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 563 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); 564 else 565 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 566 567 /* 568 * Receive/descriptor errors 569 */ 570 if (!(rx_status->rx_status_1 & 571 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 572 if (rx_status->rx_status_1 & 573 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) 574 rs->rs_status |= AR5K_RXERR_CRC; 575 576 /* only on 5210 */ 577 if ((ah->ah_version == AR5K_AR5210) && 578 (rx_status->rx_status_1 & 579 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210)) 580 rs->rs_status |= AR5K_RXERR_FIFO; 581 582 if (rx_status->rx_status_1 & 583 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { 584 rs->rs_status |= AR5K_RXERR_PHY; 585 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, 586 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); 587 } 588 589 if (rx_status->rx_status_1 & 590 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 591 rs->rs_status |= AR5K_RXERR_DECRYPT; 592 } 593 594 return 0; 595} 596 597/* 598 * Proccess the rx status descriptor on 5212 599 */ 600static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, 601 struct ath5k_desc *desc, 602 struct ath5k_rx_status *rs) 603{ 604 struct ath5k_hw_rx_status *rx_status; 605 606 rx_status = &desc->ud.ds_rx.rx_stat; 607 608 /* No frame received / not ready */ 609 if (unlikely(!(rx_status->rx_status_1 & 610 AR5K_5212_RX_DESC_STATUS1_DONE))) 611 return -EINPROGRESS; 612 613 memset(rs, 0, sizeof(struct ath5k_rx_status)); 614 615 /* 616 * Frame receive status 617 */ 618 rs->rs_datalen = rx_status->rx_status_0 & 619 AR5K_5212_RX_DESC_STATUS0_DATA_LEN; 620 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, 621 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); 622 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 623 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); 624 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, 625 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); 626 rs->rs_more = !!(rx_status->rx_status_0 & 627 AR5K_5212_RX_DESC_STATUS0_MORE); 628 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 629 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 630 631 /* 632 * Key table status 633 */ 634 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) 635 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 636 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); 637 else 638 rs->rs_keyix = AR5K_RXKEYIX_INVALID; 639 640 /* 641 * Receive/descriptor errors 642 */ 643 if (!(rx_status->rx_status_1 & 644 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { 645 if (rx_status->rx_status_1 & 646 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) 647 rs->rs_status |= AR5K_RXERR_CRC; 648 649 if (rx_status->rx_status_1 & 650 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { 651 rs->rs_status |= AR5K_RXERR_PHY; 652 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, 653 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); 654 ath5k_ani_phy_error_report(ah, rs->rs_phyerr); 655 } 656 657 if (rx_status->rx_status_1 & 658 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 659 rs->rs_status |= AR5K_RXERR_DECRYPT; 660 661 if (rx_status->rx_status_1 & 662 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) 663 rs->rs_status |= AR5K_RXERR_MIC; 664 } 665 return 0; 666} 667 668/* 669 * Init function pointers inside ath5k_hw struct 670 */ 671int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) 672{ 673 if (ah->ah_version == AR5K_AR5212) { 674 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; 675 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; 676 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; 677 } else if (ah->ah_version <= AR5K_AR5211) { 678 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; 679 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; 680 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; 681 } else 682 return -ENOTSUPP; 683 return 0; 684} 685