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