0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0025
0026 #include "ath5k.h"
0027 #include "reg.h"
0028 #include "debug.h"
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 static int
0075 ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah,
0076 struct ath5k_desc *desc,
0077 unsigned int pkt_len, unsigned int hdr_len,
0078 int padsize,
0079 enum ath5k_pkt_type type,
0080 unsigned int tx_power,
0081 unsigned int tx_rate0, unsigned int tx_tries0,
0082 unsigned int key_index,
0083 unsigned int antenna_mode,
0084 unsigned int flags,
0085 unsigned int rtscts_rate, unsigned int rtscts_duration)
0086 {
0087 u32 frame_type;
0088 struct ath5k_hw_2w_tx_ctl *tx_ctl;
0089 unsigned int frame_len;
0090
0091 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
0092
0093
0094
0095
0096
0097
0098
0099 if (unlikely(tx_tries0 == 0)) {
0100 ATH5K_ERR(ah, "zero retries\n");
0101 WARN_ON(1);
0102 return -EINVAL;
0103 }
0104 if (unlikely(tx_rate0 == 0)) {
0105 ATH5K_ERR(ah, "zero rate\n");
0106 WARN_ON(1);
0107 return -EINVAL;
0108 }
0109
0110
0111 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
0112
0113
0114
0115
0116
0117
0118 frame_len = pkt_len - padsize + FCS_LEN;
0119
0120 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
0121 return -EINVAL;
0122
0123 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
0124
0125
0126
0127
0128 if (type == AR5K_PKT_TYPE_BEACON)
0129 pkt_len = roundup(pkt_len, 4);
0130
0131 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
0132 return -EINVAL;
0133
0134 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
0135
0136
0137
0138
0139 if (ah->ah_version == AR5K_AR5210) {
0140 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)
0141 return -EINVAL;
0142 tx_ctl->tx_control_0 |=
0143 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);
0144 }
0145
0146
0147 if (ah->ah_version == AR5K_AR5210) {
0148 switch (type) {
0149 case AR5K_PKT_TYPE_BEACON:
0150 case AR5K_PKT_TYPE_PROBE_RESP:
0151 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
0152 break;
0153 case AR5K_PKT_TYPE_PIFS:
0154 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
0155 break;
0156 default:
0157 frame_type = type;
0158 break;
0159 }
0160
0161 tx_ctl->tx_control_0 |=
0162 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |
0163 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
0164
0165 } else {
0166 tx_ctl->tx_control_0 |=
0167 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
0168 AR5K_REG_SM(antenna_mode,
0169 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
0170 tx_ctl->tx_control_1 |=
0171 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);
0172 }
0173
0174 #define _TX_FLAGS(_c, _flag) \
0175 if (flags & AR5K_TXDESC_##_flag) { \
0176 tx_ctl->tx_control_##_c |= \
0177 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \
0178 }
0179 #define _TX_FLAGS_5211(_c, _flag) \
0180 if (flags & AR5K_TXDESC_##_flag) { \
0181 tx_ctl->tx_control_##_c |= \
0182 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \
0183 }
0184 _TX_FLAGS(0, CLRDMASK);
0185 _TX_FLAGS(0, INTREQ);
0186 _TX_FLAGS(0, RTSENA);
0187
0188 if (ah->ah_version == AR5K_AR5211) {
0189 _TX_FLAGS_5211(0, VEOL);
0190 _TX_FLAGS_5211(1, NOACK);
0191 }
0192
0193 #undef _TX_FLAGS
0194 #undef _TX_FLAGS_5211
0195
0196
0197
0198
0199 if (key_index != AR5K_TXKEYIX_INVALID) {
0200 tx_ctl->tx_control_0 |=
0201 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
0202 tx_ctl->tx_control_1 |=
0203 AR5K_REG_SM(key_index,
0204 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);
0205 }
0206
0207
0208
0209
0210 if ((ah->ah_version == AR5K_AR5210) &&
0211 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
0212 tx_ctl->tx_control_1 |= rtscts_duration &
0213 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;
0214
0215 return 0;
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 static int
0241 ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
0242 struct ath5k_desc *desc,
0243 unsigned int pkt_len, unsigned int hdr_len,
0244 int padsize,
0245 enum ath5k_pkt_type type,
0246 unsigned int tx_power,
0247 unsigned int tx_rate0, unsigned int tx_tries0,
0248 unsigned int key_index,
0249 unsigned int antenna_mode,
0250 unsigned int flags,
0251 unsigned int rtscts_rate, unsigned int rtscts_duration)
0252 {
0253 struct ath5k_hw_4w_tx_ctl *tx_ctl;
0254 unsigned int frame_len;
0255
0256
0257
0258
0259
0260 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
0261
0262 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
0263
0264
0265
0266
0267
0268
0269
0270 if (unlikely(tx_tries0 == 0)) {
0271 ATH5K_ERR(ah, "zero retries\n");
0272 WARN_ON(1);
0273 return -EINVAL;
0274 }
0275 if (unlikely(tx_rate0 == 0)) {
0276 ATH5K_ERR(ah, "zero rate\n");
0277 WARN_ON(1);
0278 return -EINVAL;
0279 }
0280
0281 tx_power += ah->ah_txpower.txp_offset;
0282 if (tx_power > AR5K_TUNE_MAX_TXPOWER)
0283 tx_power = AR5K_TUNE_MAX_TXPOWER;
0284
0285
0286 memset(&desc->ud.ds_tx5212.tx_stat, 0,
0287 sizeof(desc->ud.ds_tx5212.tx_stat));
0288
0289
0290
0291
0292
0293
0294 frame_len = pkt_len - padsize + FCS_LEN;
0295
0296 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
0297 return -EINVAL;
0298
0299 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
0300
0301
0302
0303
0304 if (type == AR5K_PKT_TYPE_BEACON)
0305 pkt_len = roundup(pkt_len, 4);
0306
0307 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
0308 return -EINVAL;
0309
0310 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
0311
0312 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
0313 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
0314 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
0315 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
0316 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
0317
0318 #define _TX_FLAGS(_c, _flag) \
0319 if (flags & AR5K_TXDESC_##_flag) { \
0320 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
0321 }
0322
0323 _TX_FLAGS(0, CLRDMASK);
0324 _TX_FLAGS(0, VEOL);
0325 _TX_FLAGS(0, INTREQ);
0326 _TX_FLAGS(0, RTSENA);
0327 _TX_FLAGS(0, CTSENA);
0328 _TX_FLAGS(1, NOACK);
0329
0330 #undef _TX_FLAGS
0331
0332
0333
0334
0335 if (key_index != AR5K_TXKEYIX_INVALID) {
0336 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
0337 txctl1 |= AR5K_REG_SM(key_index,
0338 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
0339 }
0340
0341
0342
0343
0344 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
0345 if ((flags & AR5K_TXDESC_RTSENA) &&
0346 (flags & AR5K_TXDESC_CTSENA))
0347 return -EINVAL;
0348 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
0349 txctl3 |= AR5K_REG_SM(rtscts_rate,
0350 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
0351 }
0352
0353 tx_ctl->tx_control_0 = txctl0;
0354 tx_ctl->tx_control_1 = txctl1;
0355 tx_ctl->tx_control_2 = txctl2;
0356 tx_ctl->tx_control_3 = txctl3;
0357
0358 return 0;
0359 }
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 int
0379 ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah,
0380 struct ath5k_desc *desc,
0381 u_int tx_rate1, u_int tx_tries1,
0382 u_int tx_rate2, u_int tx_tries2,
0383 u_int tx_rate3, u_int tx_tries3)
0384 {
0385 struct ath5k_hw_4w_tx_ctl *tx_ctl;
0386
0387
0388 if (ah->ah_version < AR5K_AR5212)
0389 return 0;
0390
0391
0392
0393
0394
0395
0396
0397 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
0398 (tx_rate2 == 0 && tx_tries2 != 0) ||
0399 (tx_rate3 == 0 && tx_tries3 != 0))) {
0400 ATH5K_ERR(ah, "zero rate\n");
0401 WARN_ON(1);
0402 return -EINVAL;
0403 }
0404
0405 if (ah->ah_version == AR5K_AR5212) {
0406 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
0407
0408 #define _XTX_TRIES(_n) \
0409 if (tx_tries##_n) { \
0410 tx_ctl->tx_control_2 |= \
0411 AR5K_REG_SM(tx_tries##_n, \
0412 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
0413 tx_ctl->tx_control_3 |= \
0414 AR5K_REG_SM(tx_rate##_n, \
0415 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
0416 }
0417
0418 _XTX_TRIES(1);
0419 _XTX_TRIES(2);
0420 _XTX_TRIES(3);
0421
0422 #undef _XTX_TRIES
0423
0424 return 1;
0425 }
0426
0427 return 0;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441 static int
0442 ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
0443 struct ath5k_desc *desc,
0444 struct ath5k_tx_status *ts)
0445 {
0446 struct ath5k_hw_tx_status *tx_status;
0447
0448 tx_status = &desc->ud.ds_tx5210.tx_stat;
0449
0450
0451 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
0452 return -EINPROGRESS;
0453
0454
0455
0456
0457 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
0458 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
0459 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
0460 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
0461 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
0462 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
0463
0464 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
0465 AR5K_DESC_TX_STATUS1_SEQ_NUM);
0466 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
0467 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
0468 ts->ts_antenna = 1;
0469 ts->ts_status = 0;
0470 ts->ts_final_idx = 0;
0471
0472 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
0473 if (tx_status->tx_status_0 &
0474 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
0475 ts->ts_status |= AR5K_TXERR_XRETRY;
0476
0477 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
0478 ts->ts_status |= AR5K_TXERR_FIFO;
0479
0480 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
0481 ts->ts_status |= AR5K_TXERR_FILT;
0482 }
0483
0484 return 0;
0485 }
0486
0487
0488
0489
0490
0491
0492
0493 static int
0494 ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
0495 struct ath5k_desc *desc,
0496 struct ath5k_tx_status *ts)
0497 {
0498 struct ath5k_hw_tx_status *tx_status;
0499 u32 txstat0, txstat1;
0500
0501 tx_status = &desc->ud.ds_tx5212.tx_stat;
0502
0503 txstat1 = READ_ONCE(tx_status->tx_status_1);
0504
0505
0506 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
0507 return -EINPROGRESS;
0508
0509 txstat0 = READ_ONCE(tx_status->tx_status_0);
0510
0511
0512
0513
0514 ts->ts_tstamp = AR5K_REG_MS(txstat0,
0515 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
0516 ts->ts_shortretry = AR5K_REG_MS(txstat0,
0517 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
0518 ts->ts_final_retry = AR5K_REG_MS(txstat0,
0519 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
0520 ts->ts_seqnum = AR5K_REG_MS(txstat1,
0521 AR5K_DESC_TX_STATUS1_SEQ_NUM);
0522 ts->ts_rssi = AR5K_REG_MS(txstat1,
0523 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
0524 ts->ts_antenna = (txstat1 &
0525 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
0526 ts->ts_status = 0;
0527
0528 ts->ts_final_idx = AR5K_REG_MS(txstat1,
0529 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
0530
0531
0532 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
0533 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
0534 ts->ts_status |= AR5K_TXERR_XRETRY;
0535
0536 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
0537 ts->ts_status |= AR5K_TXERR_FIFO;
0538
0539 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
0540 ts->ts_status |= AR5K_TXERR_FILT;
0541 }
0542
0543 return 0;
0544 }
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 int
0559 ath5k_hw_setup_rx_desc(struct ath5k_hw *ah,
0560 struct ath5k_desc *desc,
0561 u32 size, unsigned int flags)
0562 {
0563 struct ath5k_hw_rx_ctl *rx_ctl;
0564
0565 rx_ctl = &desc->ud.ds_rx.rx_ctl;
0566
0567
0568
0569
0570
0571
0572
0573
0574 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
0575
0576 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN))
0577 return -EINVAL;
0578
0579
0580 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
0581
0582 if (flags & AR5K_RXDESC_INTREQ)
0583 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
0584
0585 return 0;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 static int
0601 ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
0602 struct ath5k_desc *desc,
0603 struct ath5k_rx_status *rs)
0604 {
0605 struct ath5k_hw_rx_status *rx_status;
0606
0607 rx_status = &desc->ud.ds_rx.rx_stat;
0608
0609
0610 if (unlikely(!(rx_status->rx_status_1 &
0611 AR5K_5210_RX_DESC_STATUS1_DONE)))
0612 return -EINPROGRESS;
0613
0614 memset(rs, 0, sizeof(struct ath5k_rx_status));
0615
0616
0617
0618
0619 rs->rs_datalen = rx_status->rx_status_0 &
0620 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
0621 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
0622 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
0623 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
0624 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
0625 rs->rs_more = !!(rx_status->rx_status_0 &
0626 AR5K_5210_RX_DESC_STATUS0_MORE);
0627
0628
0629
0630
0631
0632 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
0633 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
0634
0635 if (ah->ah_version == AR5K_AR5211)
0636 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
0637 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211);
0638 else
0639 rs->rs_antenna = (rx_status->rx_status_0 &
0640 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210)
0641 ? 2 : 1;
0642
0643
0644
0645
0646 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
0647 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
0648 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
0649 else
0650 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
0651
0652
0653
0654
0655 if (!(rx_status->rx_status_1 &
0656 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
0657 if (rx_status->rx_status_1 &
0658 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
0659 rs->rs_status |= AR5K_RXERR_CRC;
0660
0661
0662 if ((ah->ah_version == AR5K_AR5210) &&
0663 (rx_status->rx_status_1 &
0664 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))
0665 rs->rs_status |= AR5K_RXERR_FIFO;
0666
0667 if (rx_status->rx_status_1 &
0668 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
0669 rs->rs_status |= AR5K_RXERR_PHY;
0670 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
0671 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
0672 }
0673
0674 if (rx_status->rx_status_1 &
0675 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
0676 rs->rs_status |= AR5K_RXERR_DECRYPT;
0677 }
0678
0679 return 0;
0680 }
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 static int
0695 ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
0696 struct ath5k_desc *desc,
0697 struct ath5k_rx_status *rs)
0698 {
0699 struct ath5k_hw_rx_status *rx_status;
0700 u32 rxstat0, rxstat1;
0701
0702 rx_status = &desc->ud.ds_rx.rx_stat;
0703 rxstat1 = READ_ONCE(rx_status->rx_status_1);
0704
0705
0706 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
0707 return -EINPROGRESS;
0708
0709 memset(rs, 0, sizeof(struct ath5k_rx_status));
0710 rxstat0 = READ_ONCE(rx_status->rx_status_0);
0711
0712
0713
0714
0715 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
0716 rs->rs_rssi = AR5K_REG_MS(rxstat0,
0717 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
0718 rs->rs_rate = AR5K_REG_MS(rxstat0,
0719 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
0720 rs->rs_antenna = AR5K_REG_MS(rxstat0,
0721 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
0722 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
0723 rs->rs_tstamp = AR5K_REG_MS(rxstat1,
0724 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
0725
0726
0727
0728
0729 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
0730 rs->rs_keyix = AR5K_REG_MS(rxstat1,
0731 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
0732 else
0733 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
0734
0735
0736
0737
0738 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
0739 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
0740 rs->rs_status |= AR5K_RXERR_CRC;
0741
0742 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
0743 rs->rs_status |= AR5K_RXERR_PHY;
0744 rs->rs_phyerr = AR5K_REG_MS(rxstat1,
0745 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
0746 if (!ah->ah_capabilities.cap_has_phyerr_counters)
0747 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
0748 }
0749
0750 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
0751 rs->rs_status |= AR5K_RXERR_DECRYPT;
0752
0753 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
0754 rs->rs_status |= AR5K_RXERR_MIC;
0755 }
0756 return 0;
0757 }
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772 int
0773 ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
0774 {
0775 if (ah->ah_version == AR5K_AR5212) {
0776 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
0777 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
0778 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
0779 } else if (ah->ah_version <= AR5K_AR5211) {
0780 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
0781 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
0782 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
0783 } else
0784 return -ENOTSUPP;
0785 return 0;
0786 }