Merge branch 'misc-3.2' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
[pandora-kernel.git] / drivers / net / wireless / ath / ath5k / qcu.c
1 /*
2  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  *
17  */
18
19 /********************************************\
20 Queue Control Unit, DFS Control Unit Functions
21 \********************************************/
22
23 #include "ath5k.h"
24 #include "reg.h"
25 #include "debug.h"
26
27
28 /******************\
29 * Helper functions *
30 \******************/
31
32 /*
33  * Get number of pending frames
34  * for a specific queue [5211+]
35  */
36 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
37 {
38         u32 pending;
39         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
40
41         /* Return if queue is declared inactive */
42         if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
43                 return false;
44
45         /* XXX: How about AR5K_CFG_TXCNT ? */
46         if (ah->ah_version == AR5K_AR5210)
47                 return false;
48
49         pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
50         pending &= AR5K_QCU_STS_FRMPENDCNT;
51
52         /* It's possible to have no frames pending even if TXE
53          * is set. To indicate that q has not stopped return
54          * true */
55         if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
56                 return true;
57
58         return pending;
59 }
60
61 /*
62  * Set a transmit queue inactive
63  */
64 void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
65 {
66         if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
67                 return;
68
69         /* This queue will be skipped in further operations */
70         ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
71         /*For SIMR setup*/
72         AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
73 }
74
75 /*
76  * Make sure cw is a power of 2 minus 1 and smaller than 1024
77  */
78 static u16 ath5k_cw_validate(u16 cw_req)
79 {
80         u32 cw = 1;
81         cw_req = min(cw_req, (u16)1023);
82
83         while (cw < cw_req)
84                 cw = (cw << 1) | 1;
85
86         return cw;
87 }
88
89 /*
90  * Get properties for a transmit queue
91  */
92 int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
93                 struct ath5k_txq_info *queue_info)
94 {
95         memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
96         return 0;
97 }
98
99 /*
100  * Set properties for a transmit queue
101  */
102 int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
103                                 const struct ath5k_txq_info *qinfo)
104 {
105         struct ath5k_txq_info *qi;
106
107         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
108
109         qi = &ah->ah_txq[queue];
110
111         if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE)
112                 return -EIO;
113
114         /* copy and validate values */
115         qi->tqi_type = qinfo->tqi_type;
116         qi->tqi_subtype = qinfo->tqi_subtype;
117         qi->tqi_flags = qinfo->tqi_flags;
118         /*
119          * According to the docs: Although the AIFS field is 8 bit wide,
120          * the maximum supported value is 0xFC. Setting it higher than that
121          * will cause the DCU to hang.
122          */
123         qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC);
124         qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min);
125         qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max);
126         qi->tqi_cbr_period = qinfo->tqi_cbr_period;
127         qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit;
128         qi->tqi_burst_time = qinfo->tqi_burst_time;
129         qi->tqi_ready_time = qinfo->tqi_ready_time;
130
131         /*XXX: Is this supported on 5210 ?*/
132         /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/
133         if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA &&
134                 ((qinfo->tqi_subtype == AR5K_WME_AC_VI) ||
135                  (qinfo->tqi_subtype == AR5K_WME_AC_VO))) ||
136              qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD)
137                 qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
138
139         return 0;
140 }
141
142 /*
143  * Initialize a transmit queue
144  */
145 int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
146                 struct ath5k_txq_info *queue_info)
147 {
148         unsigned int queue;
149         int ret;
150
151         /*
152          * Get queue by type
153          */
154         /* 5210 only has 2 queues */
155         if (ah->ah_capabilities.cap_queues.q_tx_num == 2) {
156                 switch (queue_type) {
157                 case AR5K_TX_QUEUE_DATA:
158                         queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
159                         break;
160                 case AR5K_TX_QUEUE_BEACON:
161                 case AR5K_TX_QUEUE_CAB:
162                         queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
163                         break;
164                 default:
165                         return -EINVAL;
166                 }
167         } else {
168                 switch (queue_type) {
169                 case AR5K_TX_QUEUE_DATA:
170                         for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
171                                 ah->ah_txq[queue].tqi_type !=
172                                 AR5K_TX_QUEUE_INACTIVE; queue++) {
173
174                                 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
175                                         return -EINVAL;
176                         }
177                         break;
178                 case AR5K_TX_QUEUE_UAPSD:
179                         queue = AR5K_TX_QUEUE_ID_UAPSD;
180                         break;
181                 case AR5K_TX_QUEUE_BEACON:
182                         queue = AR5K_TX_QUEUE_ID_BEACON;
183                         break;
184                 case AR5K_TX_QUEUE_CAB:
185                         queue = AR5K_TX_QUEUE_ID_CAB;
186                         break;
187                 default:
188                         return -EINVAL;
189                 }
190         }
191
192         /*
193          * Setup internal queue structure
194          */
195         memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
196         ah->ah_txq[queue].tqi_type = queue_type;
197
198         if (queue_info != NULL) {
199                 queue_info->tqi_type = queue_type;
200                 ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
201                 if (ret)
202                         return ret;
203         }
204
205         /*
206          * We use ah_txq_status to hold a temp value for
207          * the Secondary interrupt mask registers on 5211+
208          * check out ath5k_hw_reset_tx_queue
209          */
210         AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
211
212         return queue;
213 }
214
215
216 /*******************************\
217 * Single QCU/DCU initialization *
218 \*******************************/
219
220 /*
221  * Set tx retry limits on DCU
222  */
223 void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,
224                                   unsigned int queue)
225 {
226         /* Single data queue on AR5210 */
227         if (ah->ah_version == AR5K_AR5210) {
228                 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
229
230                 if (queue > 0)
231                         return;
232
233                 ath5k_hw_reg_write(ah,
234                         (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
235                         | AR5K_REG_SM(ah->ah_retry_long,
236                                       AR5K_NODCU_RETRY_LMT_SLG_RETRY)
237                         | AR5K_REG_SM(ah->ah_retry_short,
238                                       AR5K_NODCU_RETRY_LMT_SSH_RETRY)
239                         | AR5K_REG_SM(ah->ah_retry_long,
240                                       AR5K_NODCU_RETRY_LMT_LG_RETRY)
241                         | AR5K_REG_SM(ah->ah_retry_short,
242                                       AR5K_NODCU_RETRY_LMT_SH_RETRY),
243                         AR5K_NODCU_RETRY_LMT);
244         /* DCU on AR5211+ */
245         } else {
246                 ath5k_hw_reg_write(ah,
247                         AR5K_REG_SM(ah->ah_retry_long,
248                                     AR5K_DCU_RETRY_LMT_RTS)
249                         | AR5K_REG_SM(ah->ah_retry_long,
250                                       AR5K_DCU_RETRY_LMT_STA_RTS)
251                         | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short),
252                                       AR5K_DCU_RETRY_LMT_STA_DATA),
253                         AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
254         }
255 }
256
257 /**
258  * ath5k_hw_reset_tx_queue - Initialize a single hw queue
259  *
260  * @ah The &struct ath5k_hw
261  * @queue The hw queue number
262  *
263  * Set DFS properties for the given transmit queue on DCU
264  * and configures all queue-specific parameters.
265  */
266 int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
267 {
268         struct ath5k_txq_info *tq = &ah->ah_txq[queue];
269
270         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
271
272         tq = &ah->ah_txq[queue];
273
274         /* Skip if queue inactive or if we are on AR5210
275          * that doesn't have QCU/DCU */
276         if ((ah->ah_version == AR5K_AR5210) ||
277         (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))
278                 return 0;
279
280         /*
281          * Set contention window (cw_min/cw_max)
282          * and arbitrated interframe space (aifs)...
283          */
284         ath5k_hw_reg_write(ah,
285                 AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
286                 AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
287                 AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),
288                 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
289
290         /*
291          * Set tx retry limits for this queue
292          */
293         ath5k_hw_set_tx_retry_limits(ah, queue);
294
295
296         /*
297          * Set misc registers
298          */
299
300         /* Enable DCU to wait for next fragment from QCU */
301         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
302                                 AR5K_DCU_MISC_FRAG_WAIT);
303
304         /* On Maui and Spirit use the global seqnum on DCU */
305         if (ah->ah_mac_version < AR5K_SREV_AR5211)
306                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
307                                         AR5K_DCU_MISC_SEQNUM_CTL);
308
309         /* Constant bit rate period */
310         if (tq->tqi_cbr_period) {
311                 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
312                                         AR5K_QCU_CBRCFG_INTVAL) |
313                                         AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
314                                         AR5K_QCU_CBRCFG_ORN_THRES),
315                                         AR5K_QUEUE_CBRCFG(queue));
316
317                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
318                                         AR5K_QCU_MISC_FRSHED_CBR);
319
320                 if (tq->tqi_cbr_overflow_limit)
321                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
322                                         AR5K_QCU_MISC_CBR_THRES_ENABLE);
323         }
324
325         /* Ready time interval */
326         if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))
327                 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
328                                         AR5K_QCU_RDYTIMECFG_INTVAL) |
329                                         AR5K_QCU_RDYTIMECFG_ENABLE,
330                                         AR5K_QUEUE_RDYTIMECFG(queue));
331
332         if (tq->tqi_burst_time) {
333                 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
334                                         AR5K_DCU_CHAN_TIME_DUR) |
335                                         AR5K_DCU_CHAN_TIME_ENABLE,
336                                         AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
337
338                 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
339                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
340                                         AR5K_QCU_MISC_RDY_VEOL_POLICY);
341         }
342
343         /* Enable/disable Post frame backoff */
344         if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
345                 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
346                                         AR5K_QUEUE_DFS_MISC(queue));
347
348         /* Enable/disable fragmentation burst backoff */
349         if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
350                 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
351                                         AR5K_QUEUE_DFS_MISC(queue));
352
353         /*
354          * Set registers by queue type
355          */
356         switch (tq->tqi_type) {
357         case AR5K_TX_QUEUE_BEACON:
358                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
359                                 AR5K_QCU_MISC_FRSHED_DBA_GT |
360                                 AR5K_QCU_MISC_CBREXP_BCN_DIS |
361                                 AR5K_QCU_MISC_BCN_ENABLE);
362
363                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
364                                 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
365                                 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
366                                 AR5K_DCU_MISC_ARBLOCK_IGNORE |
367                                 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
368                                 AR5K_DCU_MISC_BCN_ENABLE);
369                 break;
370
371         case AR5K_TX_QUEUE_CAB:
372                 /* XXX: use BCN_SENT_GT, if we can figure out how */
373                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
374                                         AR5K_QCU_MISC_FRSHED_DBA_GT |
375                                         AR5K_QCU_MISC_CBREXP_DIS |
376                                         AR5K_QCU_MISC_CBREXP_BCN_DIS);
377
378                 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -
379                                         (AR5K_TUNE_SW_BEACON_RESP -
380                                         AR5K_TUNE_DMA_BEACON_RESP) -
381                                 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
382                                         AR5K_QCU_RDYTIMECFG_ENABLE,
383                                         AR5K_QUEUE_RDYTIMECFG(queue));
384
385                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
386                                         (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
387                                         AR5K_DCU_MISC_ARBLOCK_CTL_S));
388                 break;
389
390         case AR5K_TX_QUEUE_UAPSD:
391                 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
392                                         AR5K_QCU_MISC_CBREXP_DIS);
393                 break;
394
395         case AR5K_TX_QUEUE_DATA:
396         default:
397                         break;
398         }
399
400         /* TODO: Handle frame compression */
401
402         /*
403          * Enable interrupts for this tx queue
404          * in the secondary interrupt mask registers
405          */
406         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
407                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
408
409         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
410                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
411
412         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
413                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
414
415         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
416                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
417
418         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
419                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
420
421         if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
422                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
423
424         if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
425                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
426
427         if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
428                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
429
430         if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
431                 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
432
433         /* Update secondary interrupt mask registers */
434
435         /* Filter out inactive queues */
436         ah->ah_txq_imr_txok &= ah->ah_txq_status;
437         ah->ah_txq_imr_txerr &= ah->ah_txq_status;
438         ah->ah_txq_imr_txurn &= ah->ah_txq_status;
439         ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
440         ah->ah_txq_imr_txeol &= ah->ah_txq_status;
441         ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
442         ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
443         ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
444         ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
445
446         ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
447                                         AR5K_SIMR0_QCU_TXOK) |
448                                         AR5K_REG_SM(ah->ah_txq_imr_txdesc,
449                                         AR5K_SIMR0_QCU_TXDESC),
450                                         AR5K_SIMR0);
451
452         ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
453                                         AR5K_SIMR1_QCU_TXERR) |
454                                         AR5K_REG_SM(ah->ah_txq_imr_txeol,
455                                         AR5K_SIMR1_QCU_TXEOL),
456                                         AR5K_SIMR1);
457
458         /* Update SIMR2 but don't overwrite rest simr2 settings */
459         AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
460         AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
461                                 AR5K_REG_SM(ah->ah_txq_imr_txurn,
462                                 AR5K_SIMR2_QCU_TXURN));
463
464         ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
465                                 AR5K_SIMR3_QCBRORN) |
466                                 AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
467                                 AR5K_SIMR3_QCBRURN),
468                                 AR5K_SIMR3);
469
470         ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
471                                 AR5K_SIMR4_QTRIG), AR5K_SIMR4);
472
473         /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
474         ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
475                                 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
476
477         /* No queue has TXNOFRM enabled, disable the interrupt
478          * by setting AR5K_TXNOFRM to zero */
479         if (ah->ah_txq_imr_nofrm == 0)
480                 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
481
482         /* Set QCU mask for this DCU to save power */
483         AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
484
485         return 0;
486 }
487
488
489 /**************************\
490 * Global QCU/DCU functions *
491 \**************************/
492
493 /**
494  * ath5k_hw_set_ifs_intervals  - Set global inter-frame spaces on DCU
495  *
496  * @ah The &struct ath5k_hw
497  * @slot_time Slot time in us
498  *
499  * Sets the global IFS intervals on DCU (also works on AR5210) for
500  * the given slot time and the current bwmode.
501  */
502 int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
503 {
504         struct ieee80211_channel *channel = ah->ah_current_channel;
505         struct ieee80211_rate *rate;
506         u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
507         u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
508
509         if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
510                 return -EINVAL;
511
512         sifs = ath5k_hw_get_default_sifs(ah);
513         sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
514
515         /* EIFS
516          * Txtime of ack at lowest rate + SIFS + DIFS
517          * (DIFS = SIFS + 2 * Slot time)
518          *
519          * Note: HAL has some predefined values for EIFS
520          * Turbo:   (37 + 2 * 6)
521          * Default: (74 + 2 * 9)
522          * Half:    (149 + 2 * 13)
523          * Quarter: (298 + 2 * 21)
524          *
525          * (74 + 2 * 6) for AR5210 default and turbo !
526          *
527          * According to the formula we have
528          * ack_tx_time = 25 for turbo and
529          * ack_tx_time = 42.5 * clock multiplier
530          * for default/half/quarter.
531          *
532          * This can't be right, 42 is what we would get
533          * from ath5k_hw_get_frame_dur_for_bwmode or
534          * ieee80211_generic_frame_duration for zero frame
535          * length and without SIFS !
536          *
537          * Also we have different lowest rate for 802.11a
538          */
539         if (channel->band == IEEE80211_BAND_5GHZ)
540                 rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
541         else
542                 rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
543
544         ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
545
546         /* ack_tx_time includes an SIFS already */
547         eifs = ack_tx_time + sifs + 2 * slot_time;
548         eifs_clock = ath5k_hw_htoclock(ah, eifs);
549
550         /* Set IFS settings on AR5210 */
551         if (ah->ah_version == AR5K_AR5210) {
552                 u32 pifs, pifs_clock, difs, difs_clock;
553
554                 /* Set slot time */
555                 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
556
557                 /* Set EIFS */
558                 eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);
559
560                 /* PIFS = Slot time + SIFS */
561                 pifs = slot_time + sifs;
562                 pifs_clock = ath5k_hw_htoclock(ah, pifs);
563                 pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);
564
565                 /* DIFS = SIFS + 2 * Slot time */
566                 difs = sifs + 2 * slot_time;
567                 difs_clock = ath5k_hw_htoclock(ah, difs);
568
569                 /* Set SIFS/DIFS */
570                 ath5k_hw_reg_write(ah, (difs_clock <<
571                                 AR5K_IFS0_DIFS_S) | sifs_clock,
572                                 AR5K_IFS0);
573
574                 /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */
575                 ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |
576                                 (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),
577                                 AR5K_IFS1);
578
579                 return 0;
580         }
581
582         /* Set IFS slot time */
583         ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
584
585         /* Set EIFS interval */
586         ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);
587
588         /* Set SIFS interval in usecs */
589         AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
590                                 AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,
591                                 sifs);
592
593         /* Set SIFS interval in clock cycles */
594         ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);
595
596         return 0;
597 }
598
599
600 int ath5k_hw_init_queues(struct ath5k_hw *ah)
601 {
602         int i, ret;
603
604         /* TODO: HW Compression support for data queues */
605         /* TODO: Burst prefetch for data queues */
606
607         /*
608          * Reset queues and start beacon timers at the end of the reset routine
609          * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
610          * Note: If we want we can assign multiple qcus on one dcu.
611          */
612         if (ah->ah_version != AR5K_AR5210)
613                 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
614                         ret = ath5k_hw_reset_tx_queue(ah, i);
615                         if (ret) {
616                                 ATH5K_ERR(ah,
617                                         "failed to reset TX queue #%d\n", i);
618                                 return ret;
619                         }
620                 }
621         else
622                 /* No QCU/DCU on AR5210, just set tx
623                  * retry limits. We set IFS parameters
624                  * on ath5k_hw_set_ifs_intervals */
625                 ath5k_hw_set_tx_retry_limits(ah, 0);
626
627         /* Set the turbo flag when operating on 40MHz */
628         if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
629                 AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,
630                                 AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);
631
632         /* If we didn't set IFS timings through
633          * ath5k_hw_set_coverage_class make sure
634          * we set them here */
635         if (!ah->ah_coverage_class) {
636                 unsigned int slot_time = ath5k_hw_get_default_slottime(ah);
637                 ath5k_hw_set_ifs_intervals(ah, slot_time);
638         }
639
640         return 0;
641 }