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