787 lines · c
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 any7 * purpose with or without fee is hereby granted, provided that the above8 * copyright notice and this permission notice appear in all copies.9 *10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17 *18 */19 20/******************************\21 Hardware Descriptor Functions22\******************************/23 24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt25 26#include "ath5k.h"27#include "reg.h"28#include "debug.h"29 30 31/**32 * DOC: Hardware descriptor functions33 *34 * Here we handle the processing of the low-level hw descriptors35 * that hw reads and writes via DMA for each TX and RX attempt (that means36 * we can also have descriptors for failed TX/RX tries). We have two kind of37 * descriptors for RX and TX, control descriptors tell the hw how to send or38 * receive a packet where to read/write it from/to etc and status descriptors39 * that contain information about how the packet was sent or received (errors40 * included).41 *42 * Descriptor format is not exactly the same for each MAC chip version so we43 * have function pointers on &struct ath5k_hw we initialize at runtime based on44 * the chip used.45 */46 47 48/************************\49* TX Control descriptors *50\************************/51 52/**53 * ath5k_hw_setup_2word_tx_desc() - Initialize a 2-word tx control descriptor54 * @ah: The &struct ath5k_hw55 * @desc: The &struct ath5k_desc56 * @pkt_len: Frame length in bytes57 * @hdr_len: Header length in bytes (only used on AR5210)58 * @padsize: Any padding we've added to the frame length59 * @type: One of enum ath5k_pkt_type60 * @tx_power: Tx power in 0.5dB steps61 * @tx_rate0: HW idx for transmission rate62 * @tx_tries0: Max number of retransmissions63 * @key_index: Index on key table to use for encryption64 * @antenna_mode: Which antenna to use (0 for auto)65 * @flags: One of AR5K_TXDESC_* flags (desc.h)66 * @rtscts_rate: HW idx for RTS/CTS transmission rate67 * @rtscts_duration: What to put on duration field on the header of RTS/CTS68 *69 * Internal function to initialize a 2-Word TX control descriptor70 * found on AR5210 and AR5211 MACs chips.71 *72 * Returns 0 on success or -EINVAL on false input73 */74static int75ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah,76 struct ath5k_desc *desc,77 unsigned int pkt_len, unsigned int hdr_len,78 int padsize,79 enum ath5k_pkt_type type,80 unsigned int tx_power,81 unsigned int tx_rate0, unsigned int tx_tries0,82 unsigned int key_index,83 unsigned int antenna_mode,84 unsigned int flags,85 unsigned int rtscts_rate, unsigned int rtscts_duration)86{87 u32 frame_type;88 struct ath5k_hw_2w_tx_ctl *tx_ctl;89 unsigned int frame_len;90 91 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;92 93 /*94 * Validate input95 * - Zero retries don't make sense.96 * - A zero rate will put the HW into a mode where it continuously sends97 * noise on the channel, so it is important to avoid this.98 */99 if (unlikely(tx_tries0 == 0)) {100 ATH5K_ERR(ah, "zero retries\n");101 WARN_ON(1);102 return -EINVAL;103 }104 if (unlikely(tx_rate0 == 0)) {105 ATH5K_ERR(ah, "zero rate\n");106 WARN_ON(1);107 return -EINVAL;108 }109 110 /* Clear descriptor */111 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));112 113 /* Setup control descriptor */114 115 /* Verify and set frame length */116 117 /* remove padding we might have added before */118 frame_len = pkt_len - padsize + FCS_LEN;119 120 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)121 return -EINVAL;122 123 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;124 125 /* Verify and set buffer length */126 127 /* NB: beacon's BufLen must be a multiple of 4 bytes */128 if (type == AR5K_PKT_TYPE_BEACON)129 pkt_len = roundup(pkt_len, 4);130 131 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)132 return -EINVAL;133 134 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;135 136 /*137 * Verify and set header length (only 5210)138 */139 if (ah->ah_version == AR5K_AR5210) {140 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)141 return -EINVAL;142 tx_ctl->tx_control_0 |=143 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);144 }145 146 /*Differences between 5210-5211*/147 if (ah->ah_version == AR5K_AR5210) {148 switch (type) {149 case AR5K_PKT_TYPE_BEACON:150 case AR5K_PKT_TYPE_PROBE_RESP:151 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;152 break;153 case AR5K_PKT_TYPE_PIFS:154 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;155 break;156 default:157 frame_type = type;158 break;159 }160 161 tx_ctl->tx_control_0 |=162 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |163 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);164 165 } else {166 tx_ctl->tx_control_0 |=167 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |168 AR5K_REG_SM(antenna_mode,169 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);170 tx_ctl->tx_control_1 |=171 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);172 }173 174#define _TX_FLAGS(_c, _flag) \175 if (flags & AR5K_TXDESC_##_flag) { \176 tx_ctl->tx_control_##_c |= \177 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \178 }179#define _TX_FLAGS_5211(_c, _flag) \180 if (flags & AR5K_TXDESC_##_flag) { \181 tx_ctl->tx_control_##_c |= \182 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \183 }184 _TX_FLAGS(0, CLRDMASK);185 _TX_FLAGS(0, INTREQ);186 _TX_FLAGS(0, RTSENA);187 188 if (ah->ah_version == AR5K_AR5211) {189 _TX_FLAGS_5211(0, VEOL);190 _TX_FLAGS_5211(1, NOACK);191 }192 193#undef _TX_FLAGS194#undef _TX_FLAGS_5211195 196 /*197 * WEP crap198 */199 if (key_index != AR5K_TXKEYIX_INVALID) {200 tx_ctl->tx_control_0 |=201 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;202 tx_ctl->tx_control_1 |=203 AR5K_REG_SM(key_index,204 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);205 }206 207 /*208 * RTS/CTS Duration [5210 ?]209 */210 if ((ah->ah_version == AR5K_AR5210) &&211 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))212 tx_ctl->tx_control_1 |= rtscts_duration &213 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;214 215 return 0;216}217 218/**219 * ath5k_hw_setup_4word_tx_desc() - Initialize a 4-word tx control descriptor220 * @ah: The &struct ath5k_hw221 * @desc: The &struct ath5k_desc222 * @pkt_len: Frame length in bytes223 * @hdr_len: Header length in bytes (only used on AR5210)224 * @padsize: Any padding we've added to the frame length225 * @type: One of enum ath5k_pkt_type226 * @tx_power: Tx power in 0.5dB steps227 * @tx_rate0: HW idx for transmission rate228 * @tx_tries0: Max number of retransmissions229 * @key_index: Index on key table to use for encryption230 * @antenna_mode: Which antenna to use (0 for auto)231 * @flags: One of AR5K_TXDESC_* flags (desc.h)232 * @rtscts_rate: HW idx for RTS/CTS transmission rate233 * @rtscts_duration: What to put on duration field on the header of RTS/CTS234 *235 * Internal function to initialize a 4-Word TX control descriptor236 * found on AR5212 and later MACs chips.237 *238 * Returns 0 on success or -EINVAL on false input239 */240static int241ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,242 struct ath5k_desc *desc,243 unsigned int pkt_len, unsigned int hdr_len,244 int padsize,245 enum ath5k_pkt_type type,246 unsigned int tx_power,247 unsigned int tx_rate0, unsigned int tx_tries0,248 unsigned int key_index,249 unsigned int antenna_mode,250 unsigned int flags,251 unsigned int rtscts_rate, unsigned int rtscts_duration)252{253 struct ath5k_hw_4w_tx_ctl *tx_ctl;254 unsigned int frame_len;255 256 /*257 * Use local variables for these to reduce load/store access on258 * uncached memory259 */260 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;261 262 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;263 264 /*265 * Validate input266 * - Zero retries don't make sense.267 * - A zero rate will put the HW into a mode where it continuously sends268 * noise on the channel, so it is important to avoid this.269 */270 if (unlikely(tx_tries0 == 0)) {271 ATH5K_ERR(ah, "zero retries\n");272 WARN_ON(1);273 return -EINVAL;274 }275 if (unlikely(tx_rate0 == 0)) {276 ATH5K_ERR(ah, "zero rate\n");277 WARN_ON(1);278 return -EINVAL;279 }280 281 tx_power += ah->ah_txpower.txp_offset;282 if (tx_power > AR5K_TUNE_MAX_TXPOWER)283 tx_power = AR5K_TUNE_MAX_TXPOWER;284 285 /* Clear descriptor status area */286 memset(&desc->ud.ds_tx5212.tx_stat, 0,287 sizeof(desc->ud.ds_tx5212.tx_stat));288 289 /* Setup control descriptor */290 291 /* Verify and set frame length */292 293 /* remove padding we might have added before */294 frame_len = pkt_len - padsize + FCS_LEN;295 296 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)297 return -EINVAL;298 299 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;300 301 /* Verify and set buffer length */302 303 /* NB: beacon's BufLen must be a multiple of 4 bytes */304 if (type == AR5K_PKT_TYPE_BEACON)305 pkt_len = roundup(pkt_len, 4);306 307 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)308 return -EINVAL;309 310 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;311 312 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |313 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);314 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);315 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);316 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;317 318#define _TX_FLAGS(_c, _flag) \319 if (flags & AR5K_TXDESC_##_flag) { \320 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \321 }322 323 _TX_FLAGS(0, CLRDMASK);324 _TX_FLAGS(0, VEOL);325 _TX_FLAGS(0, INTREQ);326 _TX_FLAGS(0, RTSENA);327 _TX_FLAGS(0, CTSENA);328 _TX_FLAGS(1, NOACK);329 330#undef _TX_FLAGS331 332 /*333 * WEP crap334 */335 if (key_index != AR5K_TXKEYIX_INVALID) {336 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;337 txctl1 |= AR5K_REG_SM(key_index,338 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);339 }340 341 /*342 * RTS/CTS343 */344 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {345 if ((flags & AR5K_TXDESC_RTSENA) &&346 (flags & AR5K_TXDESC_CTSENA))347 return -EINVAL;348 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;349 txctl3 |= AR5K_REG_SM(rtscts_rate,350 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);351 }352 353 tx_ctl->tx_control_0 = txctl0;354 tx_ctl->tx_control_1 = txctl1;355 tx_ctl->tx_control_2 = txctl2;356 tx_ctl->tx_control_3 = txctl3;357 358 return 0;359}360 361/**362 * ath5k_hw_setup_mrr_tx_desc() - Initialize an MRR tx control descriptor363 * @ah: The &struct ath5k_hw364 * @desc: The &struct ath5k_desc365 * @tx_rate1: HW idx for rate used on transmission series 1366 * @tx_tries1: Max number of retransmissions for transmission series 1367 * @tx_rate2: HW idx for rate used on transmission series 2368 * @tx_tries2: Max number of retransmissions for transmission series 2369 * @tx_rate3: HW idx for rate used on transmission series 3370 * @tx_tries3: Max number of retransmissions for transmission series 3371 *372 * Multi rate retry (MRR) tx control descriptors are available only on AR5212373 * MACs, they are part of the normal 4-word tx control descriptor (see above)374 * but we handle them through a separate function for better abstraction.375 *376 * Returns 0 on success or -EINVAL on invalid input377 */378int379ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah,380 struct ath5k_desc *desc,381 u_int tx_rate1, u_int tx_tries1,382 u_int tx_rate2, u_int tx_tries2,383 u_int tx_rate3, u_int tx_tries3)384{385 struct ath5k_hw_4w_tx_ctl *tx_ctl;386 387 /* no mrr support for cards older than 5212 */388 if (ah->ah_version < AR5K_AR5212)389 return 0;390 391 /*392 * Rates can be 0 as long as the retry count is 0 too.393 * A zero rate and nonzero retry count will put the HW into a mode where394 * it continuously sends noise on the channel, so it is important to395 * avoid this.396 */397 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||398 (tx_rate2 == 0 && tx_tries2 != 0) ||399 (tx_rate3 == 0 && tx_tries3 != 0))) {400 ATH5K_ERR(ah, "zero rate\n");401 WARN_ON(1);402 return -EINVAL;403 }404 405 if (ah->ah_version == AR5K_AR5212) {406 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;407 408#define _XTX_TRIES(_n) \409 if (tx_tries##_n) { \410 tx_ctl->tx_control_2 |= \411 AR5K_REG_SM(tx_tries##_n, \412 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \413 tx_ctl->tx_control_3 |= \414 AR5K_REG_SM(tx_rate##_n, \415 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \416 }417 418 _XTX_TRIES(1);419 _XTX_TRIES(2);420 _XTX_TRIES(3);421 422#undef _XTX_TRIES423 424 return 1;425 }426 427 return 0;428}429 430 431/***********************\432* TX Status descriptors *433\***********************/434 435/**436 * ath5k_hw_proc_2word_tx_status() - Process a tx status descriptor on 5210/1437 * @ah: The &struct ath5k_hw438 * @desc: The &struct ath5k_desc439 * @ts: The &struct ath5k_tx_status440 */441static int442ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,443 struct ath5k_desc *desc,444 struct ath5k_tx_status *ts)445{446 struct ath5k_hw_tx_status *tx_status;447 448 tx_status = &desc->ud.ds_tx5210.tx_stat;449 450 /* No frame has been send or error */451 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))452 return -EINPROGRESS;453 454 /*455 * Get descriptor status456 */457 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,458 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);459 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,460 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);461 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,462 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);463 /*TODO: ts->ts_virtcol + test*/464 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,465 AR5K_DESC_TX_STATUS1_SEQ_NUM);466 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,467 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);468 ts->ts_antenna = 1;469 ts->ts_status = 0;470 ts->ts_final_idx = 0;471 472 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {473 if (tx_status->tx_status_0 &474 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)475 ts->ts_status |= AR5K_TXERR_XRETRY;476 477 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)478 ts->ts_status |= AR5K_TXERR_FIFO;479 480 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)481 ts->ts_status |= AR5K_TXERR_FILT;482 }483 484 return 0;485}486 487/**488 * ath5k_hw_proc_4word_tx_status() - Process a tx status descriptor on 5212489 * @ah: The &struct ath5k_hw490 * @desc: The &struct ath5k_desc491 * @ts: The &struct ath5k_tx_status492 */493static int494ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,495 struct ath5k_desc *desc,496 struct ath5k_tx_status *ts)497{498 struct ath5k_hw_tx_status *tx_status;499 u32 txstat0, txstat1;500 501 tx_status = &desc->ud.ds_tx5212.tx_stat;502 503 txstat1 = READ_ONCE(tx_status->tx_status_1);504 505 /* No frame has been send or error */506 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))507 return -EINPROGRESS;508 509 txstat0 = READ_ONCE(tx_status->tx_status_0);510 511 /*512 * Get descriptor status513 */514 ts->ts_tstamp = AR5K_REG_MS(txstat0,515 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);516 ts->ts_shortretry = AR5K_REG_MS(txstat0,517 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);518 ts->ts_final_retry = AR5K_REG_MS(txstat0,519 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);520 ts->ts_seqnum = AR5K_REG_MS(txstat1,521 AR5K_DESC_TX_STATUS1_SEQ_NUM);522 ts->ts_rssi = AR5K_REG_MS(txstat1,523 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);524 ts->ts_antenna = (txstat1 &525 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;526 ts->ts_status = 0;527 528 ts->ts_final_idx = AR5K_REG_MS(txstat1,529 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);530 531 /* TX error */532 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {533 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)534 ts->ts_status |= AR5K_TXERR_XRETRY;535 536 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)537 ts->ts_status |= AR5K_TXERR_FIFO;538 539 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)540 ts->ts_status |= AR5K_TXERR_FILT;541 }542 543 return 0;544}545 546 547/****************\548* RX Descriptors *549\****************/550 551/**552 * ath5k_hw_setup_rx_desc() - Initialize an rx control descriptor553 * @ah: The &struct ath5k_hw554 * @desc: The &struct ath5k_desc555 * @size: RX buffer length in bytes556 * @flags: One of AR5K_RXDESC_* flags557 */558int559ath5k_hw_setup_rx_desc(struct ath5k_hw *ah,560 struct ath5k_desc *desc,561 u32 size, unsigned int flags)562{563 struct ath5k_hw_rx_ctl *rx_ctl;564 565 rx_ctl = &desc->ud.ds_rx.rx_ctl;566 567 /*568 * Clear the descriptor569 * If we don't clean the status descriptor,570 * while scanning we get too many results,571 * most of them virtual, after some secs572 * of scanning system hangs. M.F.573 */574 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));575 576 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN))577 return -EINVAL;578 579 /* Setup descriptor */580 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;581 582 if (flags & AR5K_RXDESC_INTREQ)583 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;584 585 return 0;586}587 588/**589 * ath5k_hw_proc_5210_rx_status() - Process the rx status descriptor on 5210/1590 * @ah: The &struct ath5k_hw591 * @desc: The &struct ath5k_desc592 * @rs: The &struct ath5k_rx_status593 *594 * Internal function used to process an RX status descriptor595 * on AR5210/5211 MAC.596 *597 * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e598 * frame yet.599 */600static int601ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,602 struct ath5k_desc *desc,603 struct ath5k_rx_status *rs)604{605 struct ath5k_hw_rx_status *rx_status;606 607 rx_status = &desc->ud.ds_rx.rx_stat;608 609 /* No frame received / not ready */610 if (unlikely(!(rx_status->rx_status_1 &611 AR5K_5210_RX_DESC_STATUS1_DONE)))612 return -EINPROGRESS;613 614 memset(rs, 0, sizeof(struct ath5k_rx_status));615 616 /*617 * Frame receive status618 */619 rs->rs_datalen = rx_status->rx_status_0 &620 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;621 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,622 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);623 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,624 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);625 rs->rs_more = !!(rx_status->rx_status_0 &626 AR5K_5210_RX_DESC_STATUS0_MORE);627 /* TODO: this timestamp is 13 bit, later on we assume 15 bit!628 * also the HAL code for 5210 says the timestamp is bits [10..22] of the629 * TSF, and extends the timestamp here to 15 bit.630 * we need to check on 5210...631 */632 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,633 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);634 635 if (ah->ah_version == AR5K_AR5211)636 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,637 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211);638 else639 rs->rs_antenna = (rx_status->rx_status_0 &640 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210)641 ? 2 : 1;642 643 /*644 * Key table status645 */646 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)647 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,648 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);649 else650 rs->rs_keyix = AR5K_RXKEYIX_INVALID;651 652 /*653 * Receive/descriptor errors654 */655 if (!(rx_status->rx_status_1 &656 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {657 if (rx_status->rx_status_1 &658 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)659 rs->rs_status |= AR5K_RXERR_CRC;660 661 /* only on 5210 */662 if ((ah->ah_version == AR5K_AR5210) &&663 (rx_status->rx_status_1 &664 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))665 rs->rs_status |= AR5K_RXERR_FIFO;666 667 if (rx_status->rx_status_1 &668 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {669 rs->rs_status |= AR5K_RXERR_PHY;670 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,671 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);672 }673 674 if (rx_status->rx_status_1 &675 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)676 rs->rs_status |= AR5K_RXERR_DECRYPT;677 }678 679 return 0;680}681 682/**683 * ath5k_hw_proc_5212_rx_status() - Process the rx status descriptor on 5212684 * @ah: The &struct ath5k_hw685 * @desc: The &struct ath5k_desc686 * @rs: The &struct ath5k_rx_status687 *688 * Internal function used to process an RX status descriptor689 * on AR5212 and later MAC.690 *691 * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e692 * frame yet.693 */694static int695ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,696 struct ath5k_desc *desc,697 struct ath5k_rx_status *rs)698{699 struct ath5k_hw_rx_status *rx_status;700 u32 rxstat0, rxstat1;701 702 rx_status = &desc->ud.ds_rx.rx_stat;703 rxstat1 = READ_ONCE(rx_status->rx_status_1);704 705 /* No frame received / not ready */706 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))707 return -EINPROGRESS;708 709 memset(rs, 0, sizeof(struct ath5k_rx_status));710 rxstat0 = READ_ONCE(rx_status->rx_status_0);711 712 /*713 * Frame receive status714 */715 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;716 rs->rs_rssi = AR5K_REG_MS(rxstat0,717 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);718 rs->rs_rate = AR5K_REG_MS(rxstat0,719 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);720 rs->rs_antenna = AR5K_REG_MS(rxstat0,721 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);722 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);723 rs->rs_tstamp = AR5K_REG_MS(rxstat1,724 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);725 726 /*727 * Key table status728 */729 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)730 rs->rs_keyix = AR5K_REG_MS(rxstat1,731 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);732 else733 rs->rs_keyix = AR5K_RXKEYIX_INVALID;734 735 /*736 * Receive/descriptor errors737 */738 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {739 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)740 rs->rs_status |= AR5K_RXERR_CRC;741 742 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {743 rs->rs_status |= AR5K_RXERR_PHY;744 rs->rs_phyerr = AR5K_REG_MS(rxstat1,745 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);746 if (!ah->ah_capabilities.cap_has_phyerr_counters)747 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);748 }749 750 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)751 rs->rs_status |= AR5K_RXERR_DECRYPT;752 753 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)754 rs->rs_status |= AR5K_RXERR_MIC;755 }756 return 0;757}758 759 760/********\761* Attach *762\********/763 764/**765 * ath5k_hw_init_desc_functions() - Init function pointers inside ah766 * @ah: The &struct ath5k_hw767 *768 * Maps the internal descriptor functions to the function pointers on ah, used769 * from above. This is used as an abstraction layer to handle the various chips770 * the same way.771 */772int773ath5k_hw_init_desc_functions(struct ath5k_hw *ah)774{775 if (ah->ah_version == AR5K_AR5212) {776 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;777 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;778 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;779 } else if (ah->ah_version <= AR5K_AR5211) {780 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;781 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;782 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;783 } else784 return -ENOTSUPP;785 return 0;786}787