Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / rt2860 / rt_pci_rbus.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     rt_pci_rbus.c
29
30     Abstract:
31     Create and register network interface.
32
33     Revision History:
34     Who                 When            What
35     Justin P. Mattock   11/07/2010      Fix a typo
36     --------    ----------      ----------------------------------------------
37 */
38
39 #include "rt_config.h"
40 #include <linux/pci.h>
41
42 IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
43
44 static void rx_done_tasklet(unsigned long data);
45 static void mgmt_dma_done_tasklet(unsigned long data);
46 static void ac0_dma_done_tasklet(unsigned long data);
47 static void ac1_dma_done_tasklet(unsigned long data);
48 static void ac2_dma_done_tasklet(unsigned long data);
49 static void ac3_dma_done_tasklet(unsigned long data);
50 static void fifo_statistic_full_tasklet(unsigned long data);
51
52 /*---------------------------------------------------------------------*/
53 /* Symbol & Macro Definitions                                          */
54 /*---------------------------------------------------------------------*/
55 #define RT2860_INT_RX_DLY                               (1<<0)  /* bit 0 */
56 #define RT2860_INT_TX_DLY                               (1<<1)  /* bit 1 */
57 #define RT2860_INT_RX_DONE                              (1<<2)  /* bit 2 */
58 #define RT2860_INT_AC0_DMA_DONE                 (1<<3)  /* bit 3 */
59 #define RT2860_INT_AC1_DMA_DONE                 (1<<4)  /* bit 4 */
60 #define RT2860_INT_AC2_DMA_DONE                 (1<<5)  /* bit 5 */
61 #define RT2860_INT_AC3_DMA_DONE                 (1<<6)  /* bit 6 */
62 #define RT2860_INT_HCCA_DMA_DONE                (1<<7)  /* bit 7 */
63 #define RT2860_INT_MGMT_DONE                    (1<<8)  /* bit 8 */
64
65 #define INT_RX                  RT2860_INT_RX_DONE
66
67 #define INT_AC0_DLY             (RT2860_INT_AC0_DMA_DONE)       /*| RT2860_INT_TX_DLY) */
68 #define INT_AC1_DLY             (RT2860_INT_AC1_DMA_DONE)       /*| RT2860_INT_TX_DLY) */
69 #define INT_AC2_DLY             (RT2860_INT_AC2_DMA_DONE)       /*| RT2860_INT_TX_DLY) */
70 #define INT_AC3_DLY             (RT2860_INT_AC3_DMA_DONE)       /*| RT2860_INT_TX_DLY) */
71 #define INT_HCCA_DLY    (RT2860_INT_HCCA_DMA_DONE)      /*| RT2860_INT_TX_DLY) */
72 #define INT_MGMT_DLY    RT2860_INT_MGMT_DONE
73
74 /***************************************************************************
75   *
76   *     Interface-depended memory allocation/Free related procedures.
77   *             Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
78   *
79   **************************************************************************/
80 /* Function for TxDesc Memory allocation. */
81 void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
82                                u32 Index,
83                                unsigned long Length,
84                                IN BOOLEAN Cached,
85                                void **VirtualAddress,
86                                dma_addr_t *PhysicalAddress)
87 {
88         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
89
90         *VirtualAddress =
91             (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
92                                          PhysicalAddress);
93
94 }
95
96 /* Function for MgmtDesc Memory allocation. */
97 void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
98                                  unsigned long Length,
99                                  IN BOOLEAN Cached,
100                                  void **VirtualAddress,
101                                  dma_addr_t *PhysicalAddress)
102 {
103         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
104
105         *VirtualAddress =
106             (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
107                                          PhysicalAddress);
108
109 }
110
111 /* Function for RxDesc Memory allocation. */
112 void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
113                                unsigned long Length,
114                                IN BOOLEAN Cached,
115                                void **VirtualAddress,
116                                dma_addr_t *PhysicalAddress)
117 {
118         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
119
120         *VirtualAddress =
121             (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
122                                          PhysicalAddress);
123
124 }
125
126 /* Function for free allocated Desc Memory. */
127 void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
128                          unsigned long Length,
129                          void *VirtualAddress,
130                          dma_addr_t PhysicalAddress)
131 {
132         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
133
134         pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
135                             PhysicalAddress);
136 }
137
138 /* Function for TxData DMA Memory allocation. */
139 void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
140                                 u32 Index,
141                                 unsigned long Length,
142                                 IN BOOLEAN Cached,
143                                 void **VirtualAddress,
144                                 dma_addr_t *PhysicalAddress)
145 {
146         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
147
148         *VirtualAddress =
149             (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
150                                          PhysicalAddress);
151 }
152
153 void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
154                             unsigned long Length,
155                             IN BOOLEAN Cached,
156                             void *VirtualAddress,
157                             dma_addr_t PhysicalAddress)
158 {
159         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
160
161         pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
162                             PhysicalAddress);
163 }
164
165 /*
166  * FUNCTION: Allocate a common buffer for DMA
167  * ARGUMENTS:
168  *     AdapterHandle:  AdapterHandle
169  *     Length:  Number of bytes to allocate
170  *     Cached:  Whether or not the memory can be cached
171  *     VirtualAddress:  Pointer to memory is returned here
172  *     PhysicalAddress:  Physical address corresponding to virtual address
173  */
174 void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
175                                unsigned long Length,
176                                IN BOOLEAN Cached,
177                                void **VirtualAddress,
178                                dma_addr_t *PhysicalAddress)
179 {
180         struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
181
182         *VirtualAddress =
183             (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
184                                          PhysicalAddress);
185 }
186
187 /*
188  * FUNCTION: Allocate a packet buffer for DMA
189  * ARGUMENTS:
190  *     AdapterHandle:  AdapterHandle
191  *     Length:  Number of bytes to allocate
192  *     Cached:  Whether or not the memory can be cached
193  *     VirtualAddress:  Pointer to memory is returned here
194  *     PhysicalAddress:  Physical address corresponding to virtual address
195  * Notes:
196  *     Cached is ignored: always cached memory
197  */
198 void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
199                                          unsigned long Length,
200                                          IN BOOLEAN Cached,
201                                          void **VirtualAddress,
202                                          OUT dma_addr_t *
203                                          PhysicalAddress)
204 {
205         struct sk_buff *pkt;
206
207         pkt = dev_alloc_skb(Length);
208
209         if (pkt == NULL) {
210                 DBGPRINT(RT_DEBUG_ERROR,
211                          ("can't allocate rx %ld size packet\n", Length));
212         }
213
214         if (pkt) {
215                 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
216                 *VirtualAddress = (void *)pkt->data;
217                 *PhysicalAddress =
218                     PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1,
219                                    PCI_DMA_FROMDEVICE);
220         } else {
221                 *VirtualAddress = (void *)NULL;
222                 *PhysicalAddress = (dma_addr_t)NULL;
223         }
224
225         return (void *)pkt;
226 }
227
228 void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress)
229 {
230         dma_addr_t PhysicalAddress;
231
232         PhysicalAddress =
233             PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600),
234                            RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE);
235 }
236
237 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
238 {
239         struct os_cookie *pObj;
240
241         pObj = (struct os_cookie *)pAd->OS_Cookie;
242
243         tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
244         tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet,
245                      (unsigned long)pAd);
246         tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet,
247                      (unsigned long)pAd);
248         tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet,
249                      (unsigned long)pAd);
250         tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet,
251                      (unsigned long)pAd);
252         tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet,
253                      (unsigned long)pAd);
254         tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
255         tasklet_init(&pObj->fifo_statistic_full_task,
256                      fifo_statistic_full_tasklet, (unsigned long)pAd);
257
258         return NDIS_STATUS_SUCCESS;
259 }
260
261 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
262 {
263         struct os_cookie *pObj;
264
265         pObj = (struct os_cookie *)pAd->OS_Cookie;
266
267         tasklet_kill(&pObj->rx_done_task);
268         tasklet_kill(&pObj->mgmt_dma_done_task);
269         tasklet_kill(&pObj->ac0_dma_done_task);
270         tasklet_kill(&pObj->ac1_dma_done_task);
271         tasklet_kill(&pObj->ac2_dma_done_task);
272         tasklet_kill(&pObj->ac3_dma_done_task);
273         tasklet_kill(&pObj->tbtt_task);
274         tasklet_kill(&pObj->fifo_statistic_full_task);
275 }
276
277 int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
278 {
279
280         return NDIS_STATUS_SUCCESS;
281 }
282
283 /*
284 ========================================================================
285 Routine Description:
286     Close kernel threads.
287
288 Arguments:
289         *pAd                            the raxx interface data pointer
290
291 Return Value:
292     NONE
293
294 Note:
295 ========================================================================
296 */
297 void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
298 {
299
300         return;
301 }
302
303 static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode)
304 {
305         u32 regValue;
306
307         pAd->int_disable_mask &= ~(mode);
308         regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
309         /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
310         {
311                 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);   /* 1:enable */
312         }
313         /*else */
314         /*      DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */
315
316         if (regValue != 0)
317                 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
318 }
319
320 static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode)
321 {
322         u32 regValue;
323
324         pAd->int_disable_mask |= mode;
325         regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
326         RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);   /* 0: disable */
327
328         if (regValue == 0) {
329                 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
330         }
331 }
332
333 /***************************************************************************
334   *
335   *     tasklet related procedures.
336   *
337   **************************************************************************/
338 static void mgmt_dma_done_tasklet(unsigned long data)
339 {
340         unsigned long flags;
341         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
342         INT_SOURCE_CSR_STRUC IntSource;
343         struct os_cookie *pObj;
344
345         /* Do nothing if the driver is starting halt state. */
346         /* This might happen when timer already been fired before cancel timer with mlmehalt */
347         if (RTMP_TEST_FLAG
348             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
349                 return;
350
351         pObj = (struct os_cookie *)pAd->OS_Cookie;
352
353 /*      printk("mgmt_dma_done_process\n"); */
354         IntSource.word = 0;
355         IntSource.field.MgmtDmaDone = 1;
356         pAd->int_pending &= ~INT_MGMT_DLY;
357
358         RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
359
360         /* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */
361         /* bug report output */
362         RTMP_INT_LOCK(&pAd->irq_lock, flags);
363         /*
364          * double check to avoid lose of interrupts
365          */
366         if (pAd->int_pending & INT_MGMT_DLY) {
367                 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
368                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
369                 return;
370         }
371
372         /* enable TxDataInt again */
373         rt2860_int_enable(pAd, INT_MGMT_DLY);
374         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
375 }
376
377 static void rx_done_tasklet(unsigned long data)
378 {
379         unsigned long flags;
380         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
381         BOOLEAN bReschedule = 0;
382         struct os_cookie *pObj;
383
384         /* Do nothing if the driver is starting halt state. */
385         /* This might happen when timer already been fired before cancel timer with mlmehalt */
386         if (RTMP_TEST_FLAG
387             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
388                 return;
389
390         pObj = (struct os_cookie *)pAd->OS_Cookie;
391
392         pAd->int_pending &= ~(INT_RX);
393         bReschedule = STARxDoneInterruptHandle(pAd, 0);
394
395         RTMP_INT_LOCK(&pAd->irq_lock, flags);
396         /*
397          * double check to avoid rotting packet
398          */
399         if (pAd->int_pending & INT_RX || bReschedule) {
400                 tasklet_hi_schedule(&pObj->rx_done_task);
401                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
402                 return;
403         }
404
405         /* enable Rxint again */
406         rt2860_int_enable(pAd, INT_RX);
407         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
408
409 }
410
411 void fifo_statistic_full_tasklet(unsigned long data)
412 {
413         unsigned long flags;
414         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
415         struct os_cookie *pObj;
416
417         /* Do nothing if the driver is starting halt state. */
418         /* This might happen when timer already been fired before cancel timer with mlmehalt */
419         if (RTMP_TEST_FLAG
420             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
421                 return;
422
423         pObj = (struct os_cookie *)pAd->OS_Cookie;
424
425         pAd->int_pending &= ~(FifoStaFullInt);
426         NICUpdateFifoStaCounters(pAd);
427
428         RTMP_INT_LOCK(&pAd->irq_lock, flags);
429         /*
430          * double check to avoid rotting packet
431          */
432         if (pAd->int_pending & FifoStaFullInt) {
433                 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
434                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
435                 return;
436         }
437
438         /* enable Rxint again */
439
440         rt2860_int_enable(pAd, FifoStaFullInt);
441         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
442
443 }
444
445 static void ac3_dma_done_tasklet(unsigned long data)
446 {
447         unsigned long flags;
448         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
449         INT_SOURCE_CSR_STRUC IntSource;
450         struct os_cookie *pObj;
451         BOOLEAN bReschedule = 0;
452
453         /* Do nothing if the driver is starting halt state. */
454         /* This might happen when timer already been fired before cancel timer with mlmehalt */
455         if (RTMP_TEST_FLAG
456             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
457                 return;
458
459         pObj = (struct os_cookie *)pAd->OS_Cookie;
460
461 /*      printk("ac0_dma_done_process\n"); */
462         IntSource.word = 0;
463         IntSource.field.Ac3DmaDone = 1;
464         pAd->int_pending &= ~INT_AC3_DLY;
465
466         bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
467
468         RTMP_INT_LOCK(&pAd->irq_lock, flags);
469         /*
470          * double check to avoid lose of interrupts
471          */
472         if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) {
473                 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
474                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
475                 return;
476         }
477
478         /* enable TxDataInt again */
479         rt2860_int_enable(pAd, INT_AC3_DLY);
480         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
481 }
482
483 static void ac2_dma_done_tasklet(unsigned long data)
484 {
485         unsigned long flags;
486         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
487         INT_SOURCE_CSR_STRUC IntSource;
488         struct os_cookie *pObj;
489         BOOLEAN bReschedule = 0;
490
491         /* Do nothing if the driver is starting halt state. */
492         /* This might happen when timer already been fired before cancel timer with mlmehalt */
493         if (RTMP_TEST_FLAG
494             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
495                 return;
496
497         pObj = (struct os_cookie *)pAd->OS_Cookie;
498
499         IntSource.word = 0;
500         IntSource.field.Ac2DmaDone = 1;
501         pAd->int_pending &= ~INT_AC2_DLY;
502
503         bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
504
505         RTMP_INT_LOCK(&pAd->irq_lock, flags);
506
507         /*
508          * double check to avoid lose of interrupts
509          */
510         if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) {
511                 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
512                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
513                 return;
514         }
515
516         /* enable TxDataInt again */
517         rt2860_int_enable(pAd, INT_AC2_DLY);
518         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
519 }
520
521 static void ac1_dma_done_tasklet(unsigned long data)
522 {
523         unsigned long flags;
524         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
525         INT_SOURCE_CSR_STRUC IntSource;
526         struct os_cookie *pObj;
527         BOOLEAN bReschedule = 0;
528
529         /* Do nothing if the driver is starting halt state. */
530         /* This might happen when timer already been fired before cancel timer with mlmehalt */
531         if (RTMP_TEST_FLAG
532             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
533                 return;
534
535         pObj = (struct os_cookie *)pAd->OS_Cookie;
536
537 /*      printk("ac0_dma_done_process\n"); */
538         IntSource.word = 0;
539         IntSource.field.Ac1DmaDone = 1;
540         pAd->int_pending &= ~INT_AC1_DLY;
541
542         bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
543
544         RTMP_INT_LOCK(&pAd->irq_lock, flags);
545         /*
546          * double check to avoid lose of interrupts
547          */
548         if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) {
549                 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
550                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
551                 return;
552         }
553
554         /* enable TxDataInt again */
555         rt2860_int_enable(pAd, INT_AC1_DLY);
556         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
557 }
558
559 static void ac0_dma_done_tasklet(unsigned long data)
560 {
561         unsigned long flags;
562         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
563         INT_SOURCE_CSR_STRUC IntSource;
564         struct os_cookie *pObj;
565         BOOLEAN bReschedule = 0;
566
567         /* Do nothing if the driver is starting halt state. */
568         /* This might happen when timer already been fired before cancel timer with mlmehalt */
569         if (RTMP_TEST_FLAG
570             (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
571                 return;
572
573         pObj = (struct os_cookie *)pAd->OS_Cookie;
574
575 /*      printk("ac0_dma_done_process\n"); */
576         IntSource.word = 0;
577         IntSource.field.Ac0DmaDone = 1;
578         pAd->int_pending &= ~INT_AC0_DLY;
579
580 /*      RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */
581         bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
582
583         RTMP_INT_LOCK(&pAd->irq_lock, flags);
584         /*
585          * double check to avoid lose of interrupts
586          */
587         if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) {
588                 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
589                 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
590                 return;
591         }
592
593         /* enable TxDataInt again */
594         rt2860_int_enable(pAd, INT_AC0_DLY);
595         RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
596 }
597
598 /***************************************************************************
599   *
600   *     interrupt handler related procedures.
601   *
602   **************************************************************************/
603 int print_int_count;
604
605 IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
606 {
607         struct net_device *net_dev = (struct net_device *)dev_instance;
608         struct rt_rtmp_adapter *pAd = NULL;
609         INT_SOURCE_CSR_STRUC IntSource;
610         struct os_cookie *pObj;
611
612         GET_PAD_FROM_NET_DEV(pAd, net_dev);
613
614         pObj = (struct os_cookie *)pAd->OS_Cookie;
615
616         /* Note 03312008: we can not return here before
617            RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
618            RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
619            Or kernel will panic after ifconfig ra0 down sometimes */
620
621         /* */
622         /* Inital the Interrupt source. */
623         /* */
624         IntSource.word = 0x00000000L;
625 /*      McuIntSource.word = 0x00000000L; */
626
627         /* */
628         /* Get the interrupt sources & saved to local variable */
629         /* */
630         /*RTMP_IO_READ32(pAd, where, &McuIntSource.word); */
631         /*RTMP_IO_WRITE32(pAd, , McuIntSource.word); */
632
633         /* */
634         /* Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp */
635         /* And at the same time, clock maybe turned off that say there is no DMA service. */
636         /* when ASIC get to sleep. */
637         /* To prevent system hang on power saving. */
638         /* We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. */
639         /* */
640         /* RT2661 => when ASIC is sleeping, MAC register cannot be read and written. */
641         /* RT2860 => when ASIC is sleeping, MAC register can be read and written. */
642 /*      if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
643         {
644                 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
645                 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);   /* write 1 to clear */
646         }
647 /*      else */
648 /*              DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */
649
650 /*      RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear); */
651 /*      RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear); */
652 /*      DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n", */
653 /*                      IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear)); */
654
655         /* Do nothing if Reset in progress */
656         if (RTMP_TEST_FLAG
657             (pAd,
658              (fRTMP_ADAPTER_RESET_IN_PROGRESS |
659               fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
660                 return IRQ_HANDLED;
661         }
662         /* */
663         /* Handle interrupt, walk through all bits */
664         /* Should start from highest priority interrupt */
665         /* The priority can be adjust by altering processing if statement */
666         /* */
667
668 #ifdef DBG
669
670 #endif
671
672         pAd->bPCIclkOff = FALSE;
673
674         /* If required spinlock, each interrupt service routine has to acquire */
675         /* and release itself. */
676         /* */
677
678         /* Do nothing if NIC doesn't exist */
679         if (IntSource.word == 0xffffffff) {
680                 RTMP_SET_FLAG(pAd,
681                               (fRTMP_ADAPTER_NIC_NOT_EXIST |
682                                fRTMP_ADAPTER_HALT_IN_PROGRESS));
683                 return IRQ_HANDLED;
684         }
685
686         if (IntSource.word & TxCoherent) {
687                 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
688                 RTMPHandleRxCoherentInterrupt(pAd);
689         }
690
691         if (IntSource.word & RxCoherent) {
692                 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
693                 RTMPHandleRxCoherentInterrupt(pAd);
694         }
695
696         if (IntSource.word & FifoStaFullInt) {
697                 if ((pAd->int_disable_mask & FifoStaFullInt) == 0) {
698                         /* mask FifoStaFullInt */
699                         rt2860_int_disable(pAd, FifoStaFullInt);
700                         tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
701                 }
702                 pAd->int_pending |= FifoStaFullInt;
703         }
704
705         if (IntSource.word & INT_MGMT_DLY) {
706                 if ((pAd->int_disable_mask & INT_MGMT_DLY) == 0) {
707                         rt2860_int_disable(pAd, INT_MGMT_DLY);
708                         tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
709                 }
710                 pAd->int_pending |= INT_MGMT_DLY;
711         }
712
713         if (IntSource.word & INT_RX) {
714                 if ((pAd->int_disable_mask & INT_RX) == 0) {
715
716                         /* mask Rxint */
717                         rt2860_int_disable(pAd, INT_RX);
718                         tasklet_hi_schedule(&pObj->rx_done_task);
719                 }
720                 pAd->int_pending |= INT_RX;
721         }
722
723         if (IntSource.word & INT_AC3_DLY) {
724
725                 if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) {
726                         /* mask TxDataInt */
727                         rt2860_int_disable(pAd, INT_AC3_DLY);
728                         tasklet_hi_schedule(&pObj->ac3_dma_done_task);
729                 }
730                 pAd->int_pending |= INT_AC3_DLY;
731         }
732
733         if (IntSource.word & INT_AC2_DLY) {
734
735                 if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) {
736                         /* mask TxDataInt */
737                         rt2860_int_disable(pAd, INT_AC2_DLY);
738                         tasklet_hi_schedule(&pObj->ac2_dma_done_task);
739                 }
740                 pAd->int_pending |= INT_AC2_DLY;
741         }
742
743         if (IntSource.word & INT_AC1_DLY) {
744
745                 pAd->int_pending |= INT_AC1_DLY;
746
747                 if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) {
748                         /* mask TxDataInt */
749                         rt2860_int_disable(pAd, INT_AC1_DLY);
750                         tasklet_hi_schedule(&pObj->ac1_dma_done_task);
751                 }
752
753         }
754
755         if (IntSource.word & INT_AC0_DLY) {
756
757 /*
758                 if (IntSource.word & 0x2) {
759                         u32 reg;
760                         RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
761                         printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
762                 }
763 */
764                 pAd->int_pending |= INT_AC0_DLY;
765
766                 if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) {
767                         /* mask TxDataInt */
768                         rt2860_int_disable(pAd, INT_AC0_DLY);
769                         tasklet_hi_schedule(&pObj->ac0_dma_done_task);
770                 }
771
772         }
773
774         if (IntSource.word & PreTBTTInt) {
775                 RTMPHandlePreTBTTInterrupt(pAd);
776         }
777
778         if (IntSource.word & TBTTInt) {
779                 RTMPHandleTBTTInterrupt(pAd);
780         }
781
782         {
783                 if (IntSource.word & AutoWakeupInt)
784                         RTMPHandleTwakeupInterrupt(pAd);
785         }
786
787         return IRQ_HANDLED;
788 }
789
790 /*
791  * invalid or writeback cache
792  * and convert virtual address to physical address
793  */
794 dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
795                                 size_t size, int sd_idx, int direction)
796 {
797         struct os_cookie *pObj;
798
799         /*
800            ------ Porting Information ------
801            > For Tx Alloc:
802            mgmt packets => sd_idx = 0
803            SwIdx: pAd->MgmtRing.TxCpuIdx
804            pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
805
806            data packets => sd_idx = 1
807            TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
808            QueIdx: pTxBlk->QueIdx
809            pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
810
811            > For Rx Alloc:
812            sd_idx = -1
813          */
814
815         pObj = (struct os_cookie *)pAd->OS_Cookie;
816
817         if (sd_idx == 1) {
818                 struct rt_tx_blk *pTxBlk;
819                 pTxBlk = (struct rt_tx_blk *)ptr;
820                 return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData,
821                                       pTxBlk->SrcBufLen, direction);
822         } else {
823                 return pci_map_single(pObj->pci_dev, ptr, size, direction);
824         }
825
826 }
827
828 void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr,
829                             size_t size, int direction)
830 {
831         struct os_cookie *pObj;
832
833         pObj = (struct os_cookie *)pAd->OS_Cookie;
834
835         pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
836
837 }