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