2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Create and register network interface.
35 -------- ---------- ----------------------------------------------
38 #include "rt_config.h"
39 #include <linux/pci.h>
43 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
44 rt2860_interrupt(int irq, void *dev_instance);
46 rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
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);
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 //
77 #define INT_RX RT2860_INT_RX_DONE
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 //
90 /***************************************************************************
92 * Interface-depended memory allocation/Free related procedures.
93 * Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
95 **************************************************************************/
96 // Function for TxDesc Memory allocation.
97 void RTMP_AllocateTxDescMemory(
102 OUT PVOID *VirtualAddress,
103 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
105 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
107 *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
112 // Function for MgmtDesc Memory allocation.
113 void RTMP_AllocateMgmtDescMemory(
114 IN PRTMP_ADAPTER pAd,
117 OUT PVOID *VirtualAddress,
118 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
120 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
122 *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
127 // Function for RxDesc Memory allocation.
128 void RTMP_AllocateRxDescMemory(
129 IN PRTMP_ADAPTER pAd,
132 OUT PVOID *VirtualAddress,
133 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
135 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
137 *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
142 // Function for free allocated Desc Memory.
143 void RTMP_FreeDescMemory(
144 IN PRTMP_ADAPTER pAd,
146 IN PVOID VirtualAddress,
147 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
149 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
151 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
155 // Function for TxData DMA Memory allocation.
156 void RTMP_AllocateFirstTxBuffer(
157 IN PRTMP_ADAPTER pAd,
161 OUT PVOID *VirtualAddress,
162 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
164 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
166 *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
170 void RTMP_FreeFirstTxBuffer(
171 IN PRTMP_ADAPTER pAd,
174 IN PVOID VirtualAddress,
175 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
177 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
179 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
184 * FUNCTION: Allocate a common buffer for DMA
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
192 void RTMP_AllocateSharedMemory(
193 IN PRTMP_ADAPTER pAd,
196 OUT PVOID *VirtualAddress,
197 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
199 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
201 *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
206 * FUNCTION: Allocate a packet buffer for DMA
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
214 * Cached is ignored: always cached memory
216 PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
217 IN PRTMP_ADAPTER pAd,
220 OUT PVOID *VirtualAddress,
221 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
225 pkt = dev_alloc_skb(Length);
228 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
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);
237 *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
240 *VirtualAddress = (PVOID) NULL;
241 *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
244 return (PNDIS_PACKET) pkt;
248 VOID Invalid_Remaining_Packet(
249 IN PRTMP_ADAPTER pAd,
250 IN ULONG VirtualAddress)
252 NDIS_PHYSICAL_ADDRESS PhysicalAddress;
254 PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
258 int RtmpOSIRQRequest(IN struct net_device *net_dev)
260 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
265 if (pAd->infType != RTMP_DEV_INF_RBUS)
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));
271 printk("RT2860: request_irq ERROR(%d)\n", retval);
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)))
278 if ((retval = request_irq(net_dev->irq,rt2860_interrupt, SA_INTERRUPT, net_dev->name ,net_dev)))
281 printk("RT2860: request_irq ERROR(%d)\n", retval);
290 int RtmpOSIRQRelease(IN struct net_device *net_dev)
292 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
295 if (pAd->infType != RTMP_DEV_INF_RBUS)
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);
301 free_irq(pObj->pci_dev->irq, (net_dev));
302 RTMP_MSI_DISABLE(pAd);
306 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
307 synchronize_irq(net_dev->irq);
309 free_irq(net_dev->irq, (net_dev));
316 NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd)
320 pObj = (POS_COOKIE) pAd->OS_Cookie;
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);
332 return NDIS_STATUS_SUCCESS;
336 void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd)
340 pObj = (POS_COOKIE) pAd->OS_Cookie;
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);
354 NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd)
358 return NDIS_STATUS_SUCCESS;
363 ========================================================================
365 Close kernel threads.
368 *pAd the raxx interface data pointer
374 ========================================================================
376 VOID RtmpMgmtTaskExit(
377 IN RTMP_ADAPTER *pAd)
385 static inline void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
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))
393 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable
396 // DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
399 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
403 static inline void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
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
413 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
418 /***************************************************************************
420 * tasklet related procedures.
422 **************************************************************************/
423 static void mgmt_dma_done_tasklet(unsigned long data)
426 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
427 INT_SOURCE_CSR_STRUC IntSource;
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))
435 pObj = (POS_COOKIE) pAd->OS_Cookie;
437 // printk("mgmt_dma_done_process\n");
439 IntSource.field.MgmtDmaDone = 1;
440 pAd->int_pending &= ~INT_MGMT_DLY;
442 RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
444 // if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
446 RTMP_INT_LOCK(&pAd->irq_lock, flags);
448 * double check to avoid lose of interrupts
450 if (pAd->int_pending & INT_MGMT_DLY)
452 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
453 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
457 /* enable TxDataInt again */
458 rt2860_int_enable(pAd, INT_MGMT_DLY);
459 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
463 static void rx_done_tasklet(unsigned long data)
466 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
467 BOOLEAN bReschedule = 0;
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))
475 #ifdef UAPSD_AP_SUPPORT
476 UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TASKLET);
477 #endif // UAPSD_AP_SUPPORT //
479 pObj = (POS_COOKIE) pAd->OS_Cookie;
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 //
487 #ifdef UAPSD_AP_SUPPORT
488 UAPSD_TIMING_RECORD_STOP();
489 #endif // UAPSD_AP_SUPPORT //
491 RTMP_INT_LOCK(&pAd->irq_lock, flags);
493 * double check to avoid rotting packet
495 if (pAd->int_pending & INT_RX || bReschedule)
497 tasklet_hi_schedule(&pObj->rx_done_task);
498 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
502 /* enable RxINT again */
503 rt2860_int_enable(pAd, INT_RX);
504 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
509 void fifo_statistic_full_tasklet(unsigned long data)
512 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
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))
520 pObj = (POS_COOKIE) pAd->OS_Cookie;
522 pAd->int_pending &= ~(FifoStaFullInt);
523 NICUpdateFifoStaCounters(pAd);
525 RTMP_INT_LOCK(&pAd->irq_lock, flags);
527 * double check to avoid rotting packet
529 if (pAd->int_pending & FifoStaFullInt)
531 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
532 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
536 /* enable RxINT again */
538 rt2860_int_enable(pAd, FifoStaFullInt);
539 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
546 static void ac3_dma_done_tasklet(unsigned long data)
549 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
550 INT_SOURCE_CSR_STRUC IntSource;
552 BOOLEAN bReschedule = 0;
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))
559 pObj = (POS_COOKIE) pAd->OS_Cookie;
561 // printk("ac0_dma_done_process\n");
563 IntSource.field.Ac3DmaDone = 1;
564 pAd->int_pending &= ~INT_AC3_DLY;
566 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
568 RTMP_INT_LOCK(&pAd->irq_lock, flags);
570 * double check to avoid lose of interrupts
572 if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
574 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
575 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
579 /* enable TxDataInt again */
580 rt2860_int_enable(pAd, INT_AC3_DLY);
581 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
585 static void ac2_dma_done_tasklet(unsigned long data)
588 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
589 INT_SOURCE_CSR_STRUC IntSource;
591 BOOLEAN bReschedule = 0;
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))
598 pObj = (POS_COOKIE) pAd->OS_Cookie;
601 IntSource.field.Ac2DmaDone = 1;
602 pAd->int_pending &= ~INT_AC2_DLY;
604 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
606 RTMP_INT_LOCK(&pAd->irq_lock, flags);
609 * double check to avoid lose of interrupts
611 if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
613 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
614 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
618 /* enable TxDataInt again */
619 rt2860_int_enable(pAd, INT_AC2_DLY);
620 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
624 static void ac1_dma_done_tasklet(unsigned long data)
627 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
628 INT_SOURCE_CSR_STRUC IntSource;
630 BOOLEAN bReschedule = 0;
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))
637 pObj = (POS_COOKIE) pAd->OS_Cookie;
639 // printk("ac0_dma_done_process\n");
641 IntSource.field.Ac1DmaDone = 1;
642 pAd->int_pending &= ~INT_AC1_DLY;
644 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
646 RTMP_INT_LOCK(&pAd->irq_lock, flags);
648 * double check to avoid lose of interrupts
650 if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
652 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
653 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
657 /* enable TxDataInt again */
658 rt2860_int_enable(pAd, INT_AC1_DLY);
659 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
663 static void ac0_dma_done_tasklet(unsigned long data)
666 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
667 INT_SOURCE_CSR_STRUC IntSource;
669 BOOLEAN bReschedule = 0;
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))
676 pObj = (POS_COOKIE) pAd->OS_Cookie;
678 // printk("ac0_dma_done_process\n");
680 IntSource.field.Ac0DmaDone = 1;
681 pAd->int_pending &= ~INT_AC0_DLY;
683 // RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
684 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
686 RTMP_INT_LOCK(&pAd->irq_lock, flags);
688 * double check to avoid lose of interrupts
690 if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
692 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
693 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
697 /* enable TxDataInt again */
698 rt2860_int_enable(pAd, INT_AC0_DLY);
699 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
705 /***************************************************************************
707 * interrupt handler related procedures.
709 **************************************************************************/
713 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
714 rt2860_interrupt(int irq, void *dev_instance)
716 rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
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;
724 pObj = (POS_COOKIE) pAd->OS_Cookie;
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 */
734 // Inital the Interrupt source.
736 IntSource.word = 0x00000000L;
737 // McuIntSource.word = 0x00000000L;
740 // Get the interrupt sources & saved to local variable
742 //RTMP_IO_READ32(pAd, where, &McuIntSource.word);
743 //RTMP_IO_WRITE32(pAd, , McuIntSource.word);
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.
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))
756 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
757 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
760 // DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n"));
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));
767 // Do nothing if Reset in progress
768 if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |fRTMP_ADAPTER_HALT_IN_PROGRESS)))
770 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
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
788 pAd->bPCIclkOff = FALSE;
790 // If required spinlock, each interrupt service routine has to acquire
791 // and release itself.
794 // Do nothing if NIC doesn't exist
795 if (IntSource.word == 0xffffffff)
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)
805 if (IntSource.word & TxCoherent)
807 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
808 RTMPHandleRxCoherentInterrupt(pAd);
811 if (IntSource.word & RxCoherent)
813 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
814 RTMPHandleRxCoherentInterrupt(pAd);
817 if (IntSource.word & FifoStaFullInt)
819 if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
821 /* mask FifoStaFullInt */
822 rt2860_int_disable(pAd, FifoStaFullInt);
823 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
825 pAd->int_pending |= FifoStaFullInt;
828 if (IntSource.word & INT_MGMT_DLY)
830 if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
832 rt2860_int_disable(pAd, INT_MGMT_DLY);
833 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
835 pAd->int_pending |= INT_MGMT_DLY ;
838 if (IntSource.word & INT_RX)
840 if ((pAd->int_disable_mask & INT_RX) == 0)
844 rt2860_int_disable(pAd, INT_RX);
845 tasklet_hi_schedule(&pObj->rx_done_task);
847 pAd->int_pending |= INT_RX;
851 if (IntSource.word & INT_AC3_DLY)
854 if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
857 rt2860_int_disable(pAd, INT_AC3_DLY);
858 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
860 pAd->int_pending |= INT_AC3_DLY;
863 if (IntSource.word & INT_AC2_DLY)
866 if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
869 rt2860_int_disable(pAd, INT_AC2_DLY);
870 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
872 pAd->int_pending |= INT_AC2_DLY;
875 if (IntSource.word & INT_AC1_DLY)
878 pAd->int_pending |= INT_AC1_DLY;
880 if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
883 rt2860_int_disable(pAd, INT_AC1_DLY);
884 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
889 if (IntSource.word & INT_AC0_DLY)
893 if (IntSource.word & 0x2) {
895 RTMP_IO_READ32(pAd, DELAY_INT_CFG, ®);
896 printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
899 pAd->int_pending |= INT_AC0_DLY;
901 if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
904 rt2860_int_disable(pAd, INT_AC0_DLY);
905 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
911 if (IntSource.word & PreTBTTInt)
913 RTMPHandlePreTBTTInterrupt(pAd);
916 if (IntSource.word & TBTTInt)
918 RTMPHandleTBTTInterrupt(pAd);
924 #ifdef CONFIG_STA_SUPPORT
925 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
927 if (IntSource.word & AutoWakeupInt)
928 RTMPHandleTwakeupInterrupt(pAd);
930 #endif // CONFIG_STA_SUPPORT //
932 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
939 * invaild or writeback cache
940 * and convert virtual address to physical address
942 dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
948 ------ Porting Information ------
950 mgmt packets => sd_idx = 0
951 SwIdx: pAd->MgmtRing.TxCpuIdx
952 pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
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;
963 pAd = (PRTMP_ADAPTER)handle;
964 pObj = (POS_COOKIE)pAd->OS_Cookie;
969 pTxBlk = (PTX_BLK)ptr;
970 return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
974 return pci_map_single(pObj->pci_dev, ptr, size, direction);
979 void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
984 pAd=(PRTMP_ADAPTER)handle;
985 pObj = (POS_COOKIE)pAd->OS_Cookie;
987 pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);