root/drivers/net/wireless/ath/ath5k/desc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ath5k_hw_setup_2word_tx_desc
  2. ath5k_hw_setup_4word_tx_desc
  3. ath5k_hw_setup_mrr_tx_desc
  4. ath5k_hw_proc_2word_tx_status
  5. ath5k_hw_proc_4word_tx_status
  6. ath5k_hw_setup_rx_desc
  7. ath5k_hw_proc_5210_rx_status
  8. ath5k_hw_proc_5212_rx_status
  9. ath5k_hw_init_desc_functions

   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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  25 
  26 #include "ath5k.h"
  27 #include "reg.h"
  28 #include "debug.h"
  29 
  30 
  31 /**
  32  * DOC: Hardware descriptor functions
  33  *
  34  * Here we handle the processing of the low-level hw descriptors
  35  * that hw reads and writes via DMA for each TX and RX attempt (that means
  36  * we can also have descriptors for failed TX/RX tries). We have two kind of
  37  * descriptors for RX and TX, control descriptors tell the hw how to send or
  38  * receive a packet where to read/write it from/to etc and status descriptors
  39  * that contain information about how the packet was sent or received (errors
  40  * included).
  41  *
  42  * Descriptor format is not exactly the same for each MAC chip version so we
  43  * have function pointers on &struct ath5k_hw we initialize at runtime based on
  44  * 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 descriptor
  54  * @ah: The &struct ath5k_hw
  55  * @desc: The &struct ath5k_desc
  56  * @pkt_len: Frame length in bytes
  57  * @hdr_len: Header length in bytes (only used on AR5210)
  58  * @padsize: Any padding we've added to the frame length
  59  * @type: One of enum ath5k_pkt_type
  60  * @tx_power: Tx power in 0.5dB steps
  61  * @tx_rate0: HW idx for transmission rate
  62  * @tx_tries0: Max number of retransmissions
  63  * @key_index: Index on key table to use for encryption
  64  * @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 rate
  67  * @rtscts_duration: What to put on duration field on the header of RTS/CTS
  68  *
  69  * Internal function to initialize a 2-Word TX control descriptor
  70  * found on AR5210 and AR5211 MACs chips.
  71  *
  72  * Returns 0 on success or -EINVAL on false input
  73  */
  74 static int
  75 ath5k_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 input
  95          * - Zero retries don't make sense.
  96          * - A zero rate will put the HW into a mode where it continuously sends
  97          *   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_FLAGS
 194 #undef _TX_FLAGS_5211
 195 
 196         /*
 197          * WEP crap
 198          */
 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 descriptor
 220  * @ah: The &struct ath5k_hw
 221  * @desc: The &struct ath5k_desc
 222  * @pkt_len: Frame length in bytes
 223  * @hdr_len: Header length in bytes (only used on AR5210)
 224  * @padsize: Any padding we've added to the frame length
 225  * @type: One of enum ath5k_pkt_type
 226  * @tx_power: Tx power in 0.5dB steps
 227  * @tx_rate0: HW idx for transmission rate
 228  * @tx_tries0: Max number of retransmissions
 229  * @key_index: Index on key table to use for encryption
 230  * @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 rate
 233  * @rtscts_duration: What to put on duration field on the header of RTS/CTS
 234  *
 235  * Internal function to initialize a 4-Word TX control descriptor
 236  * found on AR5212 and later MACs chips.
 237  *
 238  * Returns 0 on success or -EINVAL on false input
 239  */
 240 static int
 241 ath5k_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 on
 258          * uncached memory
 259          */
 260         u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
 261 
 262         tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
 263 
 264         /*
 265          * Validate input
 266          * - Zero retries don't make sense.
 267          * - A zero rate will put the HW into a mode where it continuously sends
 268          *   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_FLAGS
 331 
 332         /*
 333          * WEP crap
 334          */
 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/CTS
 343          */
 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 descriptor
 363  * @ah: The &struct ath5k_hw
 364  * @desc: The &struct ath5k_desc
 365  * @tx_rate1: HW idx for rate used on transmission series 1
 366  * @tx_tries1: Max number of retransmissions for transmission series 1
 367  * @tx_rate2: HW idx for rate used on transmission series 2
 368  * @tx_tries2: Max number of retransmissions for transmission series 2
 369  * @tx_rate3: HW idx for rate used on transmission series 3
 370  * @tx_tries3: Max number of retransmissions for transmission series 3
 371  *
 372  * Multi rate retry (MRR) tx control descriptors are available only on AR5212
 373  * 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 input
 377  */
 378 int
 379 ath5k_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 where
 394          * it continuously sends noise on the channel, so it is important to
 395          * 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_TRIES
 423 
 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/1
 437  * @ah: The &struct ath5k_hw
 438  * @desc: The &struct ath5k_desc
 439  * @ts: The &struct ath5k_tx_status
 440  */
 441 static int
 442 ath5k_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 status
 456          */
 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 5212
 489  * @ah: The &struct ath5k_hw
 490  * @desc: The &struct ath5k_desc
 491  * @ts: The &struct ath5k_tx_status
 492  */
 493 static int
 494 ath5k_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 status
 513          */
 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 descriptor
 553  * @ah: The &struct ath5k_hw
 554  * @desc: The &struct ath5k_desc
 555  * @size: RX buffer length in bytes
 556  * @flags: One of AR5K_RXDESC_* flags
 557  */
 558 int
 559 ath5k_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 descriptor
 569          * If we don't clean the status descriptor,
 570          * while scanning we get too many results,
 571          * most of them virtual, after some secs
 572          * 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/1
 590  * @ah: The &struct ath5k_hw
 591  * @desc: The &struct ath5k_desc
 592  * @rs: The &struct ath5k_rx_status
 593  *
 594  * Internal function used to process an RX status descriptor
 595  * on AR5210/5211 MAC.
 596  *
 597  * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e
 598  * frame yet.
 599  */
 600 static int
 601 ath5k_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 status
 618          */
 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 the
 629          * 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         else
 639                 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 status
 645          */
 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         else
 650                 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
 651 
 652         /*
 653          * Receive/descriptor errors
 654          */
 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 5212
 684  * @ah: The &struct ath5k_hw
 685  * @desc: The &struct ath5k_desc
 686  * @rs: The &struct ath5k_rx_status
 687  *
 688  * Internal function used to process an RX status descriptor
 689  * on AR5212 and later MAC.
 690  *
 691  * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e
 692  * frame yet.
 693  */
 694 static int
 695 ath5k_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 status
 714          */
 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 status
 728          */
 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         else
 733                 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
 734 
 735         /*
 736          * Receive/descriptor errors
 737          */
 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 ah
 766  * @ah: The &struct ath5k_hw
 767  *
 768  * Maps the internal descriptor functions to the function pointers on ah, used
 769  * from above. This is used as an abstraction layer to handle the various chips
 770  * the same way.
 771  */
 772 int
 773 ath5k_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         } else
 784                 return -ENOTSUPP;
 785         return 0;
 786 }

/* [<][>][^][v][top][bottom][index][help] */