1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include "ath5k.h"
27#include "reg.h"
28#include "debug.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74static int
75ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah,
76 struct ath5k_desc *desc,
77 unsigned int pkt_len, unsigned int hdr_len,
78 int padsize,
79 enum ath5k_pkt_type type,
80 unsigned int tx_power,
81 unsigned int tx_rate0, unsigned int tx_tries0,
82 unsigned int key_index,
83 unsigned int antenna_mode,
84 unsigned int flags,
85 unsigned int rtscts_rate, unsigned int rtscts_duration)
86{
87 u32 frame_type;
88 struct ath5k_hw_2w_tx_ctl *tx_ctl;
89 unsigned int frame_len;
90
91 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
92
93
94
95
96
97
98
99 if (unlikely(tx_tries0 == 0)) {
100 ATH5K_ERR(ah, "zero retries\n");
101 WARN_ON(1);
102 return -EINVAL;
103 }
104 if (unlikely(tx_rate0 == 0)) {
105 ATH5K_ERR(ah, "zero rate\n");
106 WARN_ON(1);
107 return -EINVAL;
108 }
109
110
111 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
112
113
114
115
116
117
118 frame_len = pkt_len - padsize + FCS_LEN;
119
120 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
121 return -EINVAL;
122
123 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
124
125
126
127
128 if (type == AR5K_PKT_TYPE_BEACON)
129 pkt_len = roundup(pkt_len, 4);
130
131 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
132 return -EINVAL;
133
134 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
135
136
137
138
139 if (ah->ah_version == AR5K_AR5210) {
140 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)
141 return -EINVAL;
142 tx_ctl->tx_control_0 |=
143 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);
144 }
145
146
147 if (ah->ah_version == AR5K_AR5210) {
148 switch (type) {
149 case AR5K_PKT_TYPE_BEACON:
150 case AR5K_PKT_TYPE_PROBE_RESP:
151 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
152 break;
153 case AR5K_PKT_TYPE_PIFS:
154 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
155 break;
156 default:
157 frame_type = type;
158 break;
159 }
160
161 tx_ctl->tx_control_0 |=
162 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |
163 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
164
165 } else {
166 tx_ctl->tx_control_0 |=
167 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
168 AR5K_REG_SM(antenna_mode,
169 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
170 tx_ctl->tx_control_1 |=
171 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);
172 }
173
174#define _TX_FLAGS(_c, _flag) \
175 if (flags & AR5K_TXDESC_##_flag) { \
176 tx_ctl->tx_control_##_c |= \
177 AR5K_2W_TX_DESC_CTL##_c##_##_flag; \
178 }
179#define _TX_FLAGS_5211(_c, _flag) \
180 if (flags & AR5K_TXDESC_##_flag) { \
181 tx_ctl->tx_control_##_c |= \
182 AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \
183 }
184 _TX_FLAGS(0, CLRDMASK);
185 _TX_FLAGS(0, INTREQ);
186 _TX_FLAGS(0, RTSENA);
187
188 if (ah->ah_version == AR5K_AR5211) {
189 _TX_FLAGS_5211(0, VEOL);
190 _TX_FLAGS_5211(1, NOACK);
191 }
192
193#undef _TX_FLAGS
194#undef _TX_FLAGS_5211
195
196
197
198
199 if (key_index != AR5K_TXKEYIX_INVALID) {
200 tx_ctl->tx_control_0 |=
201 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
202 tx_ctl->tx_control_1 |=
203 AR5K_REG_SM(key_index,
204 AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);
205 }
206
207
208
209
210 if ((ah->ah_version == AR5K_AR5210) &&
211 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
212 tx_ctl->tx_control_1 |= rtscts_duration &
213 AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;
214
215 return 0;
216}
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240static int
241ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
242 struct ath5k_desc *desc,
243 unsigned int pkt_len, unsigned int hdr_len,
244 int padsize,
245 enum ath5k_pkt_type type,
246 unsigned int tx_power,
247 unsigned int tx_rate0, unsigned int tx_tries0,
248 unsigned int key_index,
249 unsigned int antenna_mode,
250 unsigned int flags,
251 unsigned int rtscts_rate, unsigned int rtscts_duration)
252{
253 struct ath5k_hw_4w_tx_ctl *tx_ctl;
254 unsigned int frame_len;
255
256
257
258
259
260 u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
261
262 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
263
264
265
266
267
268
269
270 if (unlikely(tx_tries0 == 0)) {
271 ATH5K_ERR(ah, "zero retries\n");
272 WARN_ON(1);
273 return -EINVAL;
274 }
275 if (unlikely(tx_rate0 == 0)) {
276 ATH5K_ERR(ah, "zero rate\n");
277 WARN_ON(1);
278 return -EINVAL;
279 }
280
281 tx_power += ah->ah_txpower.txp_offset;
282 if (tx_power > AR5K_TUNE_MAX_TXPOWER)
283 tx_power = AR5K_TUNE_MAX_TXPOWER;
284
285
286 memset(&desc->ud.ds_tx5212.tx_stat, 0,
287 sizeof(desc->ud.ds_tx5212.tx_stat));
288
289
290
291
292
293
294 frame_len = pkt_len - padsize + FCS_LEN;
295
296 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
297 return -EINVAL;
298
299 txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
300
301
302
303
304 if (type == AR5K_PKT_TYPE_BEACON)
305 pkt_len = roundup(pkt_len, 4);
306
307 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
308 return -EINVAL;
309
310 txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
311
312 txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
313 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
314 txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
315 txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
316 txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
317
318#define _TX_FLAGS(_c, _flag) \
319 if (flags & AR5K_TXDESC_##_flag) { \
320 txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \
321 }
322
323 _TX_FLAGS(0, CLRDMASK);
324 _TX_FLAGS(0, VEOL);
325 _TX_FLAGS(0, INTREQ);
326 _TX_FLAGS(0, RTSENA);
327 _TX_FLAGS(0, CTSENA);
328 _TX_FLAGS(1, NOACK);
329
330#undef _TX_FLAGS
331
332
333
334
335 if (key_index != AR5K_TXKEYIX_INVALID) {
336 txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
337 txctl1 |= AR5K_REG_SM(key_index,
338 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
339 }
340
341
342
343
344 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
345 if ((flags & AR5K_TXDESC_RTSENA) &&
346 (flags & AR5K_TXDESC_CTSENA))
347 return -EINVAL;
348 txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
349 txctl3 |= AR5K_REG_SM(rtscts_rate,
350 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
351 }
352
353 tx_ctl->tx_control_0 = txctl0;
354 tx_ctl->tx_control_1 = txctl1;
355 tx_ctl->tx_control_2 = txctl2;
356 tx_ctl->tx_control_3 = txctl3;
357
358 return 0;
359}
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378int
379ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah,
380 struct ath5k_desc *desc,
381 u_int tx_rate1, u_int tx_tries1,
382 u_int tx_rate2, u_int tx_tries2,
383 u_int tx_rate3, u_int tx_tries3)
384{
385 struct ath5k_hw_4w_tx_ctl *tx_ctl;
386
387
388 if (ah->ah_version < AR5K_AR5212)
389 return 0;
390
391
392
393
394
395
396
397 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
398 (tx_rate2 == 0 && tx_tries2 != 0) ||
399 (tx_rate3 == 0 && tx_tries3 != 0))) {
400 ATH5K_ERR(ah, "zero rate\n");
401 WARN_ON(1);
402 return -EINVAL;
403 }
404
405 if (ah->ah_version == AR5K_AR5212) {
406 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
407
408#define _XTX_TRIES(_n) \
409 if (tx_tries##_n) { \
410 tx_ctl->tx_control_2 |= \
411 AR5K_REG_SM(tx_tries##_n, \
412 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
413 tx_ctl->tx_control_3 |= \
414 AR5K_REG_SM(tx_rate##_n, \
415 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
416 }
417
418 _XTX_TRIES(1);
419 _XTX_TRIES(2);
420 _XTX_TRIES(3);
421
422#undef _XTX_TRIES
423
424 return 1;
425 }
426
427 return 0;
428}
429
430
431
432
433
434
435
436
437
438
439
440
441static int
442ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
443 struct ath5k_desc *desc,
444 struct ath5k_tx_status *ts)
445{
446 struct ath5k_hw_tx_status *tx_status;
447
448 tx_status = &desc->ud.ds_tx5210.tx_stat;
449
450
451 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
452 return -EINPROGRESS;
453
454
455
456
457 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
458 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
459 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
460 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
461 ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
462 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
463
464 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
465 AR5K_DESC_TX_STATUS1_SEQ_NUM);
466 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
467 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
468 ts->ts_antenna = 1;
469 ts->ts_status = 0;
470 ts->ts_final_idx = 0;
471
472 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
473 if (tx_status->tx_status_0 &
474 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
475 ts->ts_status |= AR5K_TXERR_XRETRY;
476
477 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
478 ts->ts_status |= AR5K_TXERR_FIFO;
479
480 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
481 ts->ts_status |= AR5K_TXERR_FILT;
482 }
483
484 return 0;
485}
486
487
488
489
490
491
492
493static int
494ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
495 struct ath5k_desc *desc,
496 struct ath5k_tx_status *ts)
497{
498 struct ath5k_hw_tx_status *tx_status;
499 u32 txstat0, txstat1;
500
501 tx_status = &desc->ud.ds_tx5212.tx_stat;
502
503 txstat1 = READ_ONCE(tx_status->tx_status_1);
504
505
506 if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
507 return -EINPROGRESS;
508
509 txstat0 = READ_ONCE(tx_status->tx_status_0);
510
511
512
513
514 ts->ts_tstamp = AR5K_REG_MS(txstat0,
515 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
516 ts->ts_shortretry = AR5K_REG_MS(txstat0,
517 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
518 ts->ts_final_retry = AR5K_REG_MS(txstat0,
519 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
520 ts->ts_seqnum = AR5K_REG_MS(txstat1,
521 AR5K_DESC_TX_STATUS1_SEQ_NUM);
522 ts->ts_rssi = AR5K_REG_MS(txstat1,
523 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
524 ts->ts_antenna = (txstat1 &
525 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
526 ts->ts_status = 0;
527
528 ts->ts_final_idx = AR5K_REG_MS(txstat1,
529 AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
530
531
532 if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
533 if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
534 ts->ts_status |= AR5K_TXERR_XRETRY;
535
536 if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
537 ts->ts_status |= AR5K_TXERR_FIFO;
538
539 if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
540 ts->ts_status |= AR5K_TXERR_FILT;
541 }
542
543 return 0;
544}
545
546
547
548
549
550
551
552
553
554
555
556
557
558int
559ath5k_hw_setup_rx_desc(struct ath5k_hw *ah,
560 struct ath5k_desc *desc,
561 u32 size, unsigned int flags)
562{
563 struct ath5k_hw_rx_ctl *rx_ctl;
564
565 rx_ctl = &desc->ud.ds_rx.rx_ctl;
566
567
568
569
570
571
572
573
574 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
575
576 if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN))
577 return -EINVAL;
578
579
580 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
581
582 if (flags & AR5K_RXDESC_INTREQ)
583 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
584
585 return 0;
586}
587
588
589
590
591
592
593
594
595
596
597
598
599
600static int
601ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
602 struct ath5k_desc *desc,
603 struct ath5k_rx_status *rs)
604{
605 struct ath5k_hw_rx_status *rx_status;
606
607 rx_status = &desc->ud.ds_rx.rx_stat;
608
609
610 if (unlikely(!(rx_status->rx_status_1 &
611 AR5K_5210_RX_DESC_STATUS1_DONE)))
612 return -EINPROGRESS;
613
614 memset(rs, 0, sizeof(struct ath5k_rx_status));
615
616
617
618
619 rs->rs_datalen = rx_status->rx_status_0 &
620 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
621 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
622 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
623 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
624 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
625 rs->rs_more = !!(rx_status->rx_status_0 &
626 AR5K_5210_RX_DESC_STATUS0_MORE);
627
628
629
630
631
632 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
633 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
634
635 if (ah->ah_version == AR5K_AR5211)
636 rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
637 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211);
638 else
639 rs->rs_antenna = (rx_status->rx_status_0 &
640 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210)
641 ? 2 : 1;
642
643
644
645
646 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
647 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
648 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
649 else
650 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
651
652
653
654
655 if (!(rx_status->rx_status_1 &
656 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
657 if (rx_status->rx_status_1 &
658 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
659 rs->rs_status |= AR5K_RXERR_CRC;
660
661
662 if ((ah->ah_version == AR5K_AR5210) &&
663 (rx_status->rx_status_1 &
664 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))
665 rs->rs_status |= AR5K_RXERR_FIFO;
666
667 if (rx_status->rx_status_1 &
668 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
669 rs->rs_status |= AR5K_RXERR_PHY;
670 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
671 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
672 }
673
674 if (rx_status->rx_status_1 &
675 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
676 rs->rs_status |= AR5K_RXERR_DECRYPT;
677 }
678
679 return 0;
680}
681
682
683
684
685
686
687
688
689
690
691
692
693
694static int
695ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
696 struct ath5k_desc *desc,
697 struct ath5k_rx_status *rs)
698{
699 struct ath5k_hw_rx_status *rx_status;
700 u32 rxstat0, rxstat1;
701
702 rx_status = &desc->ud.ds_rx.rx_stat;
703 rxstat1 = READ_ONCE(rx_status->rx_status_1);
704
705
706 if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
707 return -EINPROGRESS;
708
709 memset(rs, 0, sizeof(struct ath5k_rx_status));
710 rxstat0 = READ_ONCE(rx_status->rx_status_0);
711
712
713
714
715 rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
716 rs->rs_rssi = AR5K_REG_MS(rxstat0,
717 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
718 rs->rs_rate = AR5K_REG_MS(rxstat0,
719 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
720 rs->rs_antenna = AR5K_REG_MS(rxstat0,
721 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
722 rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
723 rs->rs_tstamp = AR5K_REG_MS(rxstat1,
724 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
725
726
727
728
729 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
730 rs->rs_keyix = AR5K_REG_MS(rxstat1,
731 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
732 else
733 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
734
735
736
737
738 if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
739 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
740 rs->rs_status |= AR5K_RXERR_CRC;
741
742 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
743 rs->rs_status |= AR5K_RXERR_PHY;
744 rs->rs_phyerr = AR5K_REG_MS(rxstat1,
745 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
746 if (!ah->ah_capabilities.cap_has_phyerr_counters)
747 ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
748 }
749
750 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
751 rs->rs_status |= AR5K_RXERR_DECRYPT;
752
753 if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
754 rs->rs_status |= AR5K_RXERR_MIC;
755 }
756 return 0;
757}
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772int
773ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
774{
775 if (ah->ah_version == AR5K_AR5212) {
776 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
777 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
778 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
779 } else if (ah->ah_version <= AR5K_AR5211) {
780 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
781 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
782 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
783 } else
784 return -ENOTSUPP;
785 return 0;
786}
787