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