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