nomadik-gpio: allow sleep mode dir/pull to differ from normal mode
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2860 / rt_pci_rbus.c
blob3004be6da003085e2e6907e22bdaea57221b28d7
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
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. *
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 *************************************************************************
27 Module Name:
28 rt_pci_rbus.c
30 Abstract:
31 Create and register network interface.
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
38 #include "rt_config.h"
39 #include <linux/pci.h>
41 IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
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);
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 */
64 #define INT_RX RT2860_INT_RX_DONE
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
73 /***************************************************************************
75 * Interface-depended memory allocation/Free related procedures.
76 * Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
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)
87 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
89 *VirtualAddress =
90 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
91 PhysicalAddress);
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)
102 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
104 *VirtualAddress =
105 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
106 PhysicalAddress);
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)
117 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
119 *VirtualAddress =
120 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
121 PhysicalAddress);
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)
131 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
133 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
134 PhysicalAddress);
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)
145 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
147 *VirtualAddress =
148 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
149 PhysicalAddress);
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)
158 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
160 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
161 PhysicalAddress);
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
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)
179 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
181 *VirtualAddress =
182 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
183 PhysicalAddress);
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
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)
204 struct sk_buff *pkt;
206 pkt = dev_alloc_skb(Length);
208 if (pkt == NULL) {
209 DBGPRINT(RT_DEBUG_ERROR,
210 ("can't allocate rx %ld size packet\n", Length));
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;
224 return (void *)pkt;
227 void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress)
229 dma_addr_t PhysicalAddress;
231 PhysicalAddress =
232 PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600),
233 RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE);
236 int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
238 struct os_cookie *pObj;
240 pObj = (struct os_cookie *)pAd->OS_Cookie;
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);
257 return NDIS_STATUS_SUCCESS;
260 void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
262 struct os_cookie *pObj;
264 pObj = (struct os_cookie *)pAd->OS_Cookie;
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);
276 int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
279 return NDIS_STATUS_SUCCESS;
283 ========================================================================
284 Routine Description:
285 Close kernel threads.
287 Arguments:
288 *pAd the raxx interface data pointer
290 Return Value:
291 NONE
293 Note:
294 ========================================================================
296 void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
299 return;
302 static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode)
304 u32 regValue;
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)) */
310 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 1:enable */
312 /*else */
313 /* DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */
315 if (regValue != 0)
316 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
319 static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode)
321 u32 regValue;
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 */
327 if (regValue == 0) {
328 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
332 /***************************************************************************
334 * tasklet related procedures.
336 **************************************************************************/
337 static void mgmt_dma_done_tasklet(unsigned long data)
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;
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;
350 pObj = (struct os_cookie *)pAd->OS_Cookie;
352 /* printk("mgmt_dma_done_process\n"); */
353 IntSource.word = 0;
354 IntSource.field.MgmtDmaDone = 1;
355 pAd->int_pending &= ~INT_MGMT_DLY;
357 RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
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);
363 * double check to avoid lose of interrupts
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;
371 /* enable TxDataInt again */
372 rt2860_int_enable(pAd, INT_MGMT_DLY);
373 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
376 static void rx_done_tasklet(unsigned long data)
378 unsigned long flags;
379 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
380 BOOLEAN bReschedule = 0;
381 struct os_cookie *pObj;
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;
389 pObj = (struct os_cookie *)pAd->OS_Cookie;
391 pAd->int_pending &= ~(INT_RX);
392 bReschedule = STARxDoneInterruptHandle(pAd, 0);
394 RTMP_INT_LOCK(&pAd->irq_lock, flags);
396 * double check to avoid rotting packet
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;
404 /* enable Rxint again */
405 rt2860_int_enable(pAd, INT_RX);
406 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
410 void fifo_statistic_full_tasklet(unsigned long data)
412 unsigned long flags;
413 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
414 struct os_cookie *pObj;
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;
422 pObj = (struct os_cookie *)pAd->OS_Cookie;
424 pAd->int_pending &= ~(FifoStaFullInt);
425 NICUpdateFifoStaCounters(pAd);
427 RTMP_INT_LOCK(&pAd->irq_lock, flags);
429 * double check to avoid rotting packet
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;
437 /* enable Rxint again */
439 rt2860_int_enable(pAd, FifoStaFullInt);
440 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
444 static void ac3_dma_done_tasklet(unsigned long data)
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;
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;
458 pObj = (struct os_cookie *)pAd->OS_Cookie;
460 /* printk("ac0_dma_done_process\n"); */
461 IntSource.word = 0;
462 IntSource.field.Ac3DmaDone = 1;
463 pAd->int_pending &= ~INT_AC3_DLY;
465 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
467 RTMP_INT_LOCK(&pAd->irq_lock, flags);
469 * double check to avoid lose of interrupts
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;
477 /* enable TxDataInt again */
478 rt2860_int_enable(pAd, INT_AC3_DLY);
479 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
482 static void ac2_dma_done_tasklet(unsigned long data)
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;
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;
496 pObj = (struct os_cookie *)pAd->OS_Cookie;
498 IntSource.word = 0;
499 IntSource.field.Ac2DmaDone = 1;
500 pAd->int_pending &= ~INT_AC2_DLY;
502 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
504 RTMP_INT_LOCK(&pAd->irq_lock, flags);
507 * double check to avoid lose of interrupts
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;
515 /* enable TxDataInt again */
516 rt2860_int_enable(pAd, INT_AC2_DLY);
517 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
520 static void ac1_dma_done_tasklet(unsigned long data)
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;
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;
534 pObj = (struct os_cookie *)pAd->OS_Cookie;
536 /* printk("ac0_dma_done_process\n"); */
537 IntSource.word = 0;
538 IntSource.field.Ac1DmaDone = 1;
539 pAd->int_pending &= ~INT_AC1_DLY;
541 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
543 RTMP_INT_LOCK(&pAd->irq_lock, flags);
545 * double check to avoid lose of interrupts
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;
553 /* enable TxDataInt again */
554 rt2860_int_enable(pAd, INT_AC1_DLY);
555 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
558 static void ac0_dma_done_tasklet(unsigned long data)
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;
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;
572 pObj = (struct os_cookie *)pAd->OS_Cookie;
574 /* printk("ac0_dma_done_process\n"); */
575 IntSource.word = 0;
576 IntSource.field.Ac0DmaDone = 1;
577 pAd->int_pending &= ~INT_AC0_DLY;
579 /* RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */
580 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
582 RTMP_INT_LOCK(&pAd->irq_lock, flags);
584 * double check to avoid lose of interrupts
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;
592 /* enable TxDataInt again */
593 rt2860_int_enable(pAd, INT_AC0_DLY);
594 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
597 /***************************************************************************
599 * interrupt handler related procedures.
601 **************************************************************************/
602 int print_int_count;
604 IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
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;
611 GET_PAD_FROM_NET_DEV(pAd, net_dev);
613 pObj = (struct os_cookie *)pAd->OS_Cookie;
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 */
620 /* */
621 /* Inital the Interrupt source. */
622 /* */
623 IntSource.word = 0x00000000L;
624 /* McuIntSource.word = 0x00000000L; */
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); */
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)) */
643 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
644 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); /* write 1 to clear */
646 /* else */
647 /* DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */
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)); */
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;
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 /* */
667 #ifdef DBG
669 #endif
671 pAd->bPCIclkOff = FALSE;
673 /* If required spinlock, each interrupt service routine has to acquire */
674 /* and release itself. */
675 /* */
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;
685 if (IntSource.word & TxCoherent) {
686 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
687 RTMPHandleRxCoherentInterrupt(pAd);
690 if (IntSource.word & RxCoherent) {
691 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
692 RTMPHandleRxCoherentInterrupt(pAd);
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);
701 pAd->int_pending |= FifoStaFullInt;
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);
709 pAd->int_pending |= INT_MGMT_DLY;
712 if (IntSource.word & INT_RX) {
713 if ((pAd->int_disable_mask & INT_RX) == 0) {
715 /* mask Rxint */
716 rt2860_int_disable(pAd, INT_RX);
717 tasklet_hi_schedule(&pObj->rx_done_task);
719 pAd->int_pending |= INT_RX;
722 if (IntSource.word & INT_AC3_DLY) {
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);
729 pAd->int_pending |= INT_AC3_DLY;
732 if (IntSource.word & INT_AC2_DLY) {
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);
739 pAd->int_pending |= INT_AC2_DLY;
742 if (IntSource.word & INT_AC1_DLY) {
744 pAd->int_pending |= INT_AC1_DLY;
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);
754 if (IntSource.word & INT_AC0_DLY) {
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);
763 pAd->int_pending |= INT_AC0_DLY;
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);
773 if (IntSource.word & PreTBTTInt) {
774 RTMPHandlePreTBTTInterrupt(pAd);
777 if (IntSource.word & TBTTInt) {
778 RTMPHandleTBTTInterrupt(pAd);
782 if (IntSource.word & AutoWakeupInt)
783 RTMPHandleTwakeupInterrupt(pAd);
786 return IRQ_HANDLED;
790 * invaild or writeback cache
791 * and convert virtual address to physical address
793 dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
794 size_t size, int sd_idx, int direction)
796 struct os_cookie *pObj;
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;
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;
810 > For Rx Alloc:
811 sd_idx = -1
814 pObj = (struct os_cookie *)pAd->OS_Cookie;
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);
827 void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr,
828 size_t size, int direction)
830 struct os_cookie *pObj;
832 pObj = (struct os_cookie *)pAd->OS_Cookie;
834 pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);