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