Merge branch 'batman-adv/next' of git://git.open-mesh.org/linux-merge
[cascardo/linux.git] / drivers / net / wireless / ath / ath5k / desc.c
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  */
36 static int
37 ath5k_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  */
178 static 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  */
298 int
299 ath5k_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  */
356 static 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  */
405 static 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  */
466 int 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  */
497 static 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  */
580 static 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  */
652 int 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 }