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