]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wireless/ath5k/dma.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / ath5k / dma.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 * DMA and interrupt masking functions *
21 \*************************************/
22
23 /*
24  * dma.c - DMA and interrupt masking functions
25  *
26  * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
27  * handle queue setup for 5210 chipset (rest are handled on qcu.c).
28  * Also we setup interrupt mask register (IMR) and read the various iterrupt
29  * status registers (ISR).
30  *
31  * TODO: Handle SISR on 5211+ and introduce a function to return the queue
32  * number that resulted the interrupt.
33  */
34
35 #include "ath5k.h"
36 #include "reg.h"
37 #include "debug.h"
38 #include "base.h"
39
40 /*********\
41 * Receive *
42 \*********/
43
44 /**
45  * ath5k_hw_start_rx_dma - Start DMA receive
46  *
47  * @ah: The &struct ath5k_hw
48  */
49 void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
50 {
51         ATH5K_TRACE(ah->ah_sc);
52         ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
53         ath5k_hw_reg_read(ah, AR5K_CR);
54 }
55
56 /**
57  * ath5k_hw_stop_rx_dma - Stop DMA receive
58  *
59  * @ah: The &struct ath5k_hw
60  */
61 int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
62 {
63         unsigned int i;
64
65         ATH5K_TRACE(ah->ah_sc);
66         ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
67
68         /*
69          * It may take some time to disable the DMA receive unit
70          */
71         for (i = 1000; i > 0 &&
72                         (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
73                         i--)
74                 udelay(10);
75
76         return i ? 0 : -EBUSY;
77 }
78
79 /**
80  * ath5k_hw_get_rxdp - Get RX Descriptor's address
81  *
82  * @ah: The &struct ath5k_hw
83  *
84  * XXX: Is RXDP read and clear ?
85  */
86 u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
87 {
88         return ath5k_hw_reg_read(ah, AR5K_RXDP);
89 }
90
91 /**
92  * ath5k_hw_set_rxdp - Set RX Descriptor's address
93  *
94  * @ah: The &struct ath5k_hw
95  * @phys_addr: RX descriptor address
96  *
97  * XXX: Should we check if rx is enabled before setting rxdp ?
98  */
99 void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
100 {
101         ATH5K_TRACE(ah->ah_sc);
102
103         ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
104 }
105
106
107 /**********\
108 * Transmit *
109 \**********/
110
111 /**
112  * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
113  *
114  * @ah: The &struct ath5k_hw
115  * @queue: The hw queue number
116  *
117  * Start DMA transmit for a specific queue and since 5210 doesn't have
118  * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
119  * queue for normal data and one queue for beacons). For queue setup
120  * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
121  * of range or if queue is already disabled.
122  *
123  * NOTE: Must be called after setting up tx control descriptor for that
124  * queue (see below).
125  */
126 int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
127 {
128         u32 tx_queue;
129
130         ATH5K_TRACE(ah->ah_sc);
131         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
132
133         /* Return if queue is declared inactive */
134         if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
135                 return -EIO;
136
137         if (ah->ah_version == AR5K_AR5210) {
138                 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
139
140                 /*
141                  * Set the queue by type on 5210
142                  */
143                 switch (ah->ah_txq[queue].tqi_type) {
144                 case AR5K_TX_QUEUE_DATA:
145                         tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
146                         break;
147                 case AR5K_TX_QUEUE_BEACON:
148                         tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
149                         ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
150                                         AR5K_BSR);
151                         break;
152                 case AR5K_TX_QUEUE_CAB:
153                         tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
154                         ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
155                                 AR5K_BCR_BDMAE, AR5K_BSR);
156                         break;
157                 default:
158                         return -EINVAL;
159                 }
160                 /* Start queue */
161                 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
162                 ath5k_hw_reg_read(ah, AR5K_CR);
163         } else {
164                 /* Return if queue is disabled */
165                 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
166                         return -EIO;
167
168                 /* Start queue */
169                 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
170         }
171
172         return 0;
173 }
174
175 /**
176  * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
177  *
178  * @ah: The &struct ath5k_hw
179  * @queue: The hw queue number
180  *
181  * Stop DMA transmit on a specific hw queue and drain queue so we don't
182  * have any pending frames. Returns -EBUSY if we still have pending frames,
183  * -EINVAL if queue number is out of range.
184  *
185  */
186 int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
187 {
188         unsigned int i = 40;
189         u32 tx_queue, pending;
190
191         ATH5K_TRACE(ah->ah_sc);
192         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
193
194         /* Return if queue is declared inactive */
195         if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
196                 return -EIO;
197
198         if (ah->ah_version == AR5K_AR5210) {
199                 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
200
201                 /*
202                  * Set by queue type
203                  */
204                 switch (ah->ah_txq[queue].tqi_type) {
205                 case AR5K_TX_QUEUE_DATA:
206                         tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
207                         break;
208                 case AR5K_TX_QUEUE_BEACON:
209                 case AR5K_TX_QUEUE_CAB:
210                         /* XXX Fix me... */
211                         tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
212                         ath5k_hw_reg_write(ah, 0, AR5K_BSR);
213                         break;
214                 default:
215                         return -EINVAL;
216                 }
217
218                 /* Stop queue */
219                 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
220                 ath5k_hw_reg_read(ah, AR5K_CR);
221         } else {
222                 /*
223                  * Schedule TX disable and wait until queue is empty
224                  */
225                 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
226
227                 /*Check for pending frames*/
228                 do {
229                         pending = ath5k_hw_reg_read(ah,
230                                 AR5K_QUEUE_STATUS(queue)) &
231                                 AR5K_QCU_STS_FRMPENDCNT;
232                         udelay(100);
233                 } while (--i && pending);
234
235                 /* For 2413+ order PCU to drop packets using
236                  * QUIET mechanism */
237                 if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
238                 pending){
239                         /* Set periodicity and duration */
240                         ath5k_hw_reg_write(ah,
241                                 AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
242                                 AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
243                                 AR5K_QUIET_CTL2);
244
245                         /* Enable quiet period for current TSF */
246                         ath5k_hw_reg_write(ah,
247                                 AR5K_QUIET_CTL1_QT_EN |
248                                 AR5K_REG_SM(ath5k_hw_reg_read(ah,
249                                                 AR5K_TSF_L32_5211) >> 10,
250                                                 AR5K_QUIET_CTL1_NEXT_QT_TSF),
251                                 AR5K_QUIET_CTL1);
252
253                         /* Force channel idle high */
254                         AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
255                                         AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
256
257                         /* Wait a while and disable mechanism */
258                         udelay(200);
259                         AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
260                                                 AR5K_QUIET_CTL1_QT_EN);
261
262                         /* Re-check for pending frames */
263                         i = 40;
264                         do {
265                                 pending = ath5k_hw_reg_read(ah,
266                                         AR5K_QUEUE_STATUS(queue)) &
267                                         AR5K_QCU_STS_FRMPENDCNT;
268                                 udelay(100);
269                         } while (--i && pending);
270
271                         AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
272                                         AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
273                 }
274
275                 /* Clear register */
276                 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
277                 if (pending)
278                         return -EBUSY;
279         }
280
281         /* TODO: Check for success on 5210 else return error */
282         return 0;
283 }
284
285 /**
286  * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
287  *
288  * @ah: The &struct ath5k_hw
289  * @queue: The hw queue number
290  *
291  * Get TX descriptor's address for a specific queue. For 5210 we ignore
292  * the queue number and use tx queue type since we only have 2 queues.
293  * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
294  * For newer chips with QCU/DCU we just read the corresponding TXDP register.
295  *
296  * XXX: Is TXDP read and clear ?
297  */
298 u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
299 {
300         u16 tx_reg;
301
302         ATH5K_TRACE(ah->ah_sc);
303         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
304
305         /*
306          * Get the transmit queue descriptor pointer from the selected queue
307          */
308         /*5210 doesn't have QCU*/
309         if (ah->ah_version == AR5K_AR5210) {
310                 switch (ah->ah_txq[queue].tqi_type) {
311                 case AR5K_TX_QUEUE_DATA:
312                         tx_reg = AR5K_NOQCU_TXDP0;
313                         break;
314                 case AR5K_TX_QUEUE_BEACON:
315                 case AR5K_TX_QUEUE_CAB:
316                         tx_reg = AR5K_NOQCU_TXDP1;
317                         break;
318                 default:
319                         return 0xffffffff;
320                 }
321         } else {
322                 tx_reg = AR5K_QUEUE_TXDP(queue);
323         }
324
325         return ath5k_hw_reg_read(ah, tx_reg);
326 }
327
328 /**
329  * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
330  *
331  * @ah: The &struct ath5k_hw
332  * @queue: The hw queue number
333  *
334  * Set TX descriptor's address for a specific queue. For 5210 we ignore
335  * the queue number and we use tx queue type since we only have 2 queues
336  * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
337  * For newer chips with QCU/DCU we just set the corresponding TXDP register.
338  * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
339  * active.
340  */
341 int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
342 {
343         u16 tx_reg;
344
345         ATH5K_TRACE(ah->ah_sc);
346         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
347
348         /*
349          * Set the transmit queue descriptor pointer register by type
350          * on 5210
351          */
352         if (ah->ah_version == AR5K_AR5210) {
353                 switch (ah->ah_txq[queue].tqi_type) {
354                 case AR5K_TX_QUEUE_DATA:
355                         tx_reg = AR5K_NOQCU_TXDP0;
356                         break;
357                 case AR5K_TX_QUEUE_BEACON:
358                 case AR5K_TX_QUEUE_CAB:
359                         tx_reg = AR5K_NOQCU_TXDP1;
360                         break;
361                 default:
362                         return -EINVAL;
363                 }
364         } else {
365                 /*
366                  * Set the transmit queue descriptor pointer for
367                  * the selected queue on QCU for 5211+
368                  * (this won't work if the queue is still active)
369                  */
370                 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
371                         return -EIO;
372
373                 tx_reg = AR5K_QUEUE_TXDP(queue);
374         }
375
376         /* Set descriptor pointer */
377         ath5k_hw_reg_write(ah, phys_addr, tx_reg);
378
379         return 0;
380 }
381
382 /**
383  * ath5k_hw_update_tx_triglevel - Update tx trigger level
384  *
385  * @ah: The &struct ath5k_hw
386  * @increase: Flag to force increase of trigger level
387  *
388  * This function increases/decreases the tx trigger level for the tx fifo
389  * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
390  * the buffer and transmits it's data. Lowering this results sending small
391  * frames more quickly but can lead to tx underruns, raising it a lot can
392  * result other problems (i think bmiss is related). Right now we start with
393  * the lowest possible (64Bytes) and if we get tx underrun we increase it using
394  * the increase flag. Returns -EIO if we have have reached maximum/minimum.
395  *
396  * XXX: Link this with tx DMA size ?
397  * XXX: Use it to save interrupts ?
398  * TODO: Needs testing, i think it's related to bmiss...
399  */
400 int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
401 {
402         u32 trigger_level, imr;
403         int ret = -EIO;
404
405         ATH5K_TRACE(ah->ah_sc);
406
407         /*
408          * Disable interrupts by setting the mask
409          */
410         imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
411
412         trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
413                         AR5K_TXCFG_TXFULL);
414
415         if (!increase) {
416                 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
417                         goto done;
418         } else
419                 trigger_level +=
420                         ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
421
422         /*
423          * Update trigger level on success
424          */
425         if (ah->ah_version == AR5K_AR5210)
426                 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
427         else
428                 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
429                                 AR5K_TXCFG_TXFULL, trigger_level);
430
431         ret = 0;
432
433 done:
434         /*
435          * Restore interrupt mask
436          */
437         ath5k_hw_set_imr(ah, imr);
438
439         return ret;
440 }
441
442 /*******************\
443 * Interrupt masking *
444 \*******************/
445
446 /**
447  * ath5k_hw_is_intr_pending - Check if we have pending interrupts
448  *
449  * @ah: The &struct ath5k_hw
450  *
451  * Check if we have pending interrupts to process. Returns 1 if we
452  * have pending interrupts and 0 if we haven't.
453  */
454 bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
455 {
456         ATH5K_TRACE(ah->ah_sc);
457         return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
458 }
459
460 /**
461  * ath5k_hw_get_isr - Get interrupt status
462  *
463  * @ah: The @struct ath5k_hw
464  * @interrupt_mask: Driver's interrupt mask used to filter out
465  * interrupts in sw.
466  *
467  * This function is used inside our interrupt handler to determine the reason
468  * for the interrupt by reading Primary Interrupt Status Register. Returns an
469  * abstract interrupt status mask which is mostly ISR with some uncommon bits
470  * being mapped on some standard non hw-specific positions
471  * (check out &ath5k_int).
472  *
473  * NOTE: We use read-and-clear register, so after this function is called ISR
474  * is zeroed.
475  *
476  * XXX: Why filter interrupts in sw with interrupt_mask ? No benefit at all
477  * plus it can be misleading (one might thing that we save interrupts this way)
478  */
479 int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
480 {
481         u32 data;
482
483         ATH5K_TRACE(ah->ah_sc);
484
485         /*
486          * Read interrupt status from the Interrupt Status register
487          * on 5210
488          */
489         if (ah->ah_version == AR5K_AR5210) {
490                 data = ath5k_hw_reg_read(ah, AR5K_ISR);
491                 if (unlikely(data == AR5K_INT_NOCARD)) {
492                         *interrupt_mask = data;
493                         return -ENODEV;
494                 }
495         } else {
496                 /*
497                  * Read interrupt status from the Read-And-Clear
498                  * shadow register.
499                  * Note: PISR/SISR Not available on 5210
500                  */
501                 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
502         }
503
504         /*
505          * Get abstract interrupt mask (driver-compatible)
506          */
507         *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
508
509         if (unlikely(data == AR5K_INT_NOCARD))
510                 return -ENODEV;
511
512         if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
513                 *interrupt_mask |= AR5K_INT_RX;
514
515         if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
516                 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
517                 *interrupt_mask |= AR5K_INT_TX;
518
519         if (ah->ah_version != AR5K_AR5210) {
520                 /*HIU = Host Interface Unit (PCI etc)*/
521                 if (unlikely(data & (AR5K_ISR_HIUERR)))
522                         *interrupt_mask |= AR5K_INT_FATAL;
523
524                 /*Beacon Not Ready*/
525                 if (unlikely(data & (AR5K_ISR_BNR)))
526                         *interrupt_mask |= AR5K_INT_BNR;
527         }
528
529         /*
530          * XXX: BMISS interrupts may occur after association.
531          * I found this on 5210 code but it needs testing. If this is
532          * true we should disable them before assoc and re-enable them
533          * after a successfull assoc + some jiffies.
534          */
535 #if 0
536         interrupt_mask &= ~AR5K_INT_BMISS;
537 #endif
538
539         /*
540          * In case we didn't handle anything,
541          * print the register value.
542          */
543         if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
544                 ATH5K_PRINTF("0x%08x\n", data);
545
546         return 0;
547 }
548
549 /**
550  * ath5k_hw_set_imr - Set interrupt mask
551  *
552  * @ah: The &struct ath5k_hw
553  * @new_mask: The new interrupt mask to be set
554  *
555  * Set the interrupt mask in hw to save interrupts. We do that by mapping
556  * ath5k_int bits to hw-specific bits to remove abstraction and writing
557  * Interrupt Mask Register.
558  */
559 enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
560 {
561         enum ath5k_int old_mask, int_mask;
562
563         /*
564          * Disable card interrupts to prevent any race conditions
565          * (they will be re-enabled afterwards).
566          */
567         ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
568         ath5k_hw_reg_read(ah, AR5K_IER);
569
570         old_mask = ah->ah_imr;
571
572         /*
573          * Add additional, chipset-dependent interrupt mask flags
574          * and write them to the IMR (interrupt mask register).
575          */
576         int_mask = new_mask & AR5K_INT_COMMON;
577
578         if (new_mask & AR5K_INT_RX)
579                 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
580                         AR5K_IMR_RXDESC;
581
582         if (new_mask & AR5K_INT_TX)
583                 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
584                         AR5K_IMR_TXURN;
585
586         if (ah->ah_version != AR5K_AR5210) {
587                 if (new_mask & AR5K_INT_FATAL) {
588                         int_mask |= AR5K_IMR_HIUERR;
589                         AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
590                                         AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
591                 }
592         }
593
594         ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
595
596         /* Store new interrupt mask */
597         ah->ah_imr = new_mask;
598
599         /* ..re-enable interrupts */
600         ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
601         ath5k_hw_reg_read(ah, AR5K_IER);
602
603         return old_mask;
604 }
605