Fix common misspellings
[deliverable/linux.git] / drivers / staging / rt2860 / rt_pci_rbus.c
CommitLineData
ca97b838
BZ
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:
6ccb5d7c
JM
34 Who When What
35 Justin P. Mattock 11/07/2010 Fix a typo
ca97b838
BZ
36 -------- ---------- ----------------------------------------------
37*/
38
39#include "rt_config.h"
40#include <linux/pci.h>
41
42IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
43
44static void rx_done_tasklet(unsigned long data);
45static void mgmt_dma_done_tasklet(unsigned long data);
46static void ac0_dma_done_tasklet(unsigned long data);
47static void ac1_dma_done_tasklet(unsigned long data);
48static void ac2_dma_done_tasklet(unsigned long data);
49static void ac3_dma_done_tasklet(unsigned long data);
50static void fifo_statistic_full_tasklet(unsigned long data);
51
ca97b838
BZ
52/*---------------------------------------------------------------------*/
53/* Symbol & Macro Definitions */
54/*---------------------------------------------------------------------*/
9f548a2a
BZ
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 */
ca97b838
BZ
64
65#define INT_RX RT2860_INT_RX_DONE
66
9f548a2a
BZ
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) */
ca97b838
BZ
72#define INT_MGMT_DLY RT2860_INT_MGMT_DONE
73
ca97b838
BZ
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 **************************************************************************/
9f548a2a 80/* Function for TxDesc Memory allocation. */
62eb734b 81void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
51126deb
BZ
82 u32 Index,
83 unsigned long Length,
66cd8d6e 84 IN BOOLEAN Cached,
015ffcbe 85 void **VirtualAddress,
8a10a546 86 dma_addr_t *PhysicalAddress)
ca97b838 87{
8a10a546 88 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 89
66cd8d6e 90 *VirtualAddress =
51126deb 91 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
66cd8d6e 92 PhysicalAddress);
ca97b838
BZ
93
94}
95
9f548a2a 96/* Function for MgmtDesc Memory allocation. */
62eb734b 97void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
51126deb 98 unsigned long Length,
66cd8d6e 99 IN BOOLEAN Cached,
015ffcbe 100 void **VirtualAddress,
8a10a546 101 dma_addr_t *PhysicalAddress)
ca97b838 102{
8a10a546 103 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 104
66cd8d6e 105 *VirtualAddress =
51126deb 106 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
66cd8d6e 107 PhysicalAddress);
ca97b838
BZ
108
109}
110
9f548a2a 111/* Function for RxDesc Memory allocation. */
62eb734b 112void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
51126deb 113 unsigned long Length,
66cd8d6e 114 IN BOOLEAN Cached,
015ffcbe 115 void **VirtualAddress,
8a10a546 116 dma_addr_t *PhysicalAddress)
ca97b838 117{
8a10a546 118 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 119
66cd8d6e 120 *VirtualAddress =
51126deb 121 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
66cd8d6e 122 PhysicalAddress);
ca97b838
BZ
123
124}
125
9f548a2a 126/* Function for free allocated Desc Memory. */
62eb734b 127void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
51126deb
BZ
128 unsigned long Length,
129 void *VirtualAddress,
8a10a546 130 dma_addr_t PhysicalAddress)
ca97b838 131{
8a10a546 132 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 133
66cd8d6e
BZ
134 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
135 PhysicalAddress);
ca97b838
BZ
136}
137
9f548a2a 138/* Function for TxData DMA Memory allocation. */
62eb734b 139void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
51126deb
BZ
140 u32 Index,
141 unsigned long Length,
66cd8d6e 142 IN BOOLEAN Cached,
015ffcbe 143 void **VirtualAddress,
8a10a546 144 dma_addr_t *PhysicalAddress)
ca97b838 145{
8a10a546 146 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 147
66cd8d6e 148 *VirtualAddress =
51126deb 149 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
66cd8d6e 150 PhysicalAddress);
ca97b838
BZ
151}
152
62eb734b 153void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
51126deb 154 unsigned long Length,
66cd8d6e 155 IN BOOLEAN Cached,
51126deb 156 void *VirtualAddress,
8a10a546 157 dma_addr_t PhysicalAddress)
ca97b838 158{
8a10a546 159 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 160
66cd8d6e
BZ
161 pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
162 PhysicalAddress);
ca97b838
BZ
163}
164
ca97b838
BZ
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 */
62eb734b 174void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
51126deb 175 unsigned long Length,
66cd8d6e 176 IN BOOLEAN Cached,
015ffcbe 177 void **VirtualAddress,
8a10a546 178 dma_addr_t *PhysicalAddress)
ca97b838 179{
8a10a546 180 struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 181
66cd8d6e 182 *VirtualAddress =
51126deb 183 (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
66cd8d6e 184 PhysicalAddress);
ca97b838
BZ
185}
186
ca97b838
BZ
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 */
62eb734b 198void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
51126deb 199 unsigned long Length,
66cd8d6e 200 IN BOOLEAN Cached,
015ffcbe 201 void **VirtualAddress,
8a10a546 202 OUT dma_addr_t *
66cd8d6e 203 PhysicalAddress)
ca97b838
BZ
204{
205 struct sk_buff *pkt;
206
207 pkt = dev_alloc_skb(Length);
208
209 if (pkt == NULL) {
66cd8d6e
BZ
210 DBGPRINT(RT_DEBUG_ERROR,
211 ("can't allocate rx %ld size packet\n", Length));
ca97b838
BZ
212 }
213
214 if (pkt) {
215 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
51126deb 216 *VirtualAddress = (void *)pkt->data;
66cd8d6e
BZ
217 *PhysicalAddress =
218 PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1,
219 PCI_DMA_FROMDEVICE);
ca97b838 220 } else {
51126deb 221 *VirtualAddress = (void *)NULL;
8a10a546 222 *PhysicalAddress = (dma_addr_t)NULL;
ca97b838
BZ
223 }
224
8a10a546 225 return (void *)pkt;
ca97b838
BZ
226}
227
62eb734b 228void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress)
ca97b838 229{
8a10a546 230 dma_addr_t PhysicalAddress;
ca97b838 231
66cd8d6e
BZ
232 PhysicalAddress =
233 PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600),
234 RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE);
ca97b838
BZ
235}
236
62eb734b 237int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
ca97b838 238{
8a10a546 239 struct os_cookie *pObj;
ca97b838 240
8a10a546 241 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
242
243 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
66cd8d6e
BZ
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);
ca97b838 254 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
66cd8d6e
BZ
255 tasklet_init(&pObj->fifo_statistic_full_task,
256 fifo_statistic_full_tasklet, (unsigned long)pAd);
ca97b838
BZ
257
258 return NDIS_STATUS_SUCCESS;
259}
260
62eb734b 261void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
ca97b838 262{
8a10a546 263 struct os_cookie *pObj;
ca97b838 264
8a10a546 265 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
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
62eb734b 277int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
ca97b838
BZ
278{
279
ca97b838
BZ
280 return NDIS_STATUS_SUCCESS;
281}
282
ca97b838
BZ
283/*
284========================================================================
285Routine Description:
286 Close kernel threads.
287
288Arguments:
289 *pAd the raxx interface data pointer
290
291Return Value:
292 NONE
293
294Note:
295========================================================================
296*/
62eb734b 297void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
ca97b838
BZ
298{
299
ca97b838
BZ
300 return;
301}
302
62eb734b 303static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode)
ca97b838
BZ
304{
305 u32 regValue;
306
307 pAd->int_disable_mask &= ~(mode);
308 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
9f548a2a 309 /*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
ca97b838 310 {
9f548a2a 311 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 1:enable */
ca97b838 312 }
9f548a2a
BZ
313 /*else */
314 /* DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */
ca97b838
BZ
315
316 if (regValue != 0)
317 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
318}
319
62eb734b 320static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode)
ca97b838
BZ
321{
322 u32 regValue;
323
324 pAd->int_disable_mask |= mode;
66cd8d6e 325 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
9f548a2a 326 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); /* 0: disable */
ca97b838 327
66cd8d6e 328 if (regValue == 0) {
ca97b838
BZ
329 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
330 }
331}
332
ca97b838
BZ
333/***************************************************************************
334 *
335 * tasklet related procedures.
336 *
337 **************************************************************************/
338static void mgmt_dma_done_tasklet(unsigned long data)
339{
340 unsigned long flags;
62eb734b 341 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 342 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 343 struct os_cookie *pObj;
ca97b838 344
9f548a2a
BZ
345 /* Do nothing if the driver is starting halt state. */
346 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
347 if (RTMP_TEST_FLAG
348 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
349 return;
350
8a10a546 351 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 352
9f548a2a 353/* printk("mgmt_dma_done_process\n"); */
ca97b838
BZ
354 IntSource.word = 0;
355 IntSource.field.MgmtDmaDone = 1;
356 pAd->int_pending &= ~INT_MGMT_DLY;
357
358 RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
359
6ccb5d7c 360 /* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */
9f548a2a 361 /* bug report output */
ca97b838
BZ
362 RTMP_INT_LOCK(&pAd->irq_lock, flags);
363 /*
364 * double check to avoid lose of interrupts
365 */
66cd8d6e 366 if (pAd->int_pending & INT_MGMT_DLY) {
ca97b838
BZ
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
ca97b838
BZ
377static void rx_done_tasklet(unsigned long data)
378{
379 unsigned long flags;
62eb734b 380 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 381 BOOLEAN bReschedule = 0;
8a10a546 382 struct os_cookie *pObj;
ca97b838 383
9f548a2a
BZ
384 /* Do nothing if the driver is starting halt state. */
385 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
386 if (RTMP_TEST_FLAG
387 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
388 return;
389
8a10a546 390 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
391
392 pAd->int_pending &= ~(INT_RX);
66cd8d6e 393 bReschedule = STARxDoneInterruptHandle(pAd, 0);
ca97b838
BZ
394
395 RTMP_INT_LOCK(&pAd->irq_lock, flags);
396 /*
397 * double check to avoid rotting packet
398 */
66cd8d6e 399 if (pAd->int_pending & INT_RX || bReschedule) {
ca97b838
BZ
400 tasklet_hi_schedule(&pObj->rx_done_task);
401 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
402 return;
403 }
404
51126deb 405 /* enable Rxint again */
ca97b838
BZ
406 rt2860_int_enable(pAd, INT_RX);
407 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
408
409}
410
ca97b838
BZ
411void fifo_statistic_full_tasklet(unsigned long data)
412{
413 unsigned long flags;
62eb734b 414 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
8a10a546 415 struct os_cookie *pObj;
ca97b838 416
9f548a2a
BZ
417 /* Do nothing if the driver is starting halt state. */
418 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
419 if (RTMP_TEST_FLAG
420 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
421 return;
422
8a10a546 423 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
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 */
66cd8d6e 432 if (pAd->int_pending & FifoStaFullInt) {
ca97b838
BZ
433 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
434 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
435 return;
436 }
437
51126deb 438 /* enable Rxint again */
ca97b838
BZ
439
440 rt2860_int_enable(pAd, FifoStaFullInt);
441 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
442
443}
444
445static void ac3_dma_done_tasklet(unsigned long data)
446{
447 unsigned long flags;
62eb734b 448 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 449 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 450 struct os_cookie *pObj;
ca97b838
BZ
451 BOOLEAN bReschedule = 0;
452
9f548a2a
BZ
453 /* Do nothing if the driver is starting halt state. */
454 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
455 if (RTMP_TEST_FLAG
456 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
457 return;
458
8a10a546 459 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 460
9f548a2a 461/* printk("ac0_dma_done_process\n"); */
ca97b838
BZ
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 */
66cd8d6e 472 if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) {
ca97b838
BZ
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
ca97b838
BZ
483static void ac2_dma_done_tasklet(unsigned long data)
484{
485 unsigned long flags;
62eb734b 486 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 487 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 488 struct os_cookie *pObj;
ca97b838
BZ
489 BOOLEAN bReschedule = 0;
490
9f548a2a
BZ
491 /* Do nothing if the driver is starting halt state. */
492 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
493 if (RTMP_TEST_FLAG
494 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
495 return;
496
8a10a546 497 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838
BZ
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 */
66cd8d6e 510 if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) {
ca97b838
BZ
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
ca97b838
BZ
521static void ac1_dma_done_tasklet(unsigned long data)
522{
523 unsigned long flags;
62eb734b 524 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 525 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 526 struct os_cookie *pObj;
ca97b838
BZ
527 BOOLEAN bReschedule = 0;
528
9f548a2a
BZ
529 /* Do nothing if the driver is starting halt state. */
530 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
531 if (RTMP_TEST_FLAG
532 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
533 return;
534
8a10a546 535 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 536
9f548a2a 537/* printk("ac0_dma_done_process\n"); */
ca97b838
BZ
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 */
66cd8d6e 548 if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) {
ca97b838
BZ
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
ca97b838
BZ
559static void ac0_dma_done_tasklet(unsigned long data)
560{
561 unsigned long flags;
62eb734b 562 struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
66cd8d6e 563 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 564 struct os_cookie *pObj;
ca97b838
BZ
565 BOOLEAN bReschedule = 0;
566
9f548a2a
BZ
567 /* Do nothing if the driver is starting halt state. */
568 /* This might happen when timer already been fired before cancel timer with mlmehalt */
66cd8d6e
BZ
569 if (RTMP_TEST_FLAG
570 (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
ca97b838
BZ
571 return;
572
8a10a546 573 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 574
9f548a2a 575/* printk("ac0_dma_done_process\n"); */
ca97b838
BZ
576 IntSource.word = 0;
577 IntSource.field.Ac0DmaDone = 1;
578 pAd->int_pending &= ~INT_AC0_DLY;
579
9f548a2a 580/* RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */
ca97b838
BZ
581 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
582
583 RTMP_INT_LOCK(&pAd->irq_lock, flags);
584 /*
585 * double check to avoid lose of interrupts
586 */
66cd8d6e 587 if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) {
ca97b838
BZ
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
ca97b838
BZ
598/***************************************************************************
599 *
600 * interrupt handler related procedures.
601 *
602 **************************************************************************/
603int print_int_count;
604
605IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
606{
66cd8d6e 607 struct net_device *net_dev = (struct net_device *)dev_instance;
62eb734b 608 struct rt_rtmp_adapter *pAd = NULL;
66cd8d6e 609 INT_SOURCE_CSR_STRUC IntSource;
8a10a546 610 struct os_cookie *pObj;
ca97b838
BZ
611
612 GET_PAD_FROM_NET_DEV(pAd, net_dev);
613
8a10a546 614 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 615
ca97b838 616 /* Note 03312008: we can not return here before
66cd8d6e
BZ
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 */
ca97b838 620
9f548a2a 621 /* */
25985edc 622 /* Initial the Interrupt source. */
9f548a2a 623 /* */
ca97b838 624 IntSource.word = 0x00000000L;
9f548a2a
BZ
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)) */
ca97b838
BZ
643 {
644 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
9f548a2a 645 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); /* write 1 to clear */
ca97b838 646 }
9f548a2a
BZ
647/* else */
648/* DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */
ca97b838 649
9f548a2a
BZ
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)); */
ca97b838 654
9f548a2a 655 /* Do nothing if Reset in progress */
66cd8d6e
BZ
656 if (RTMP_TEST_FLAG
657 (pAd,
658 (fRTMP_ADAPTER_RESET_IN_PROGRESS |
659 fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
660 return IRQ_HANDLED;
ca97b838 661 }
9f548a2a
BZ
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 /* */
ca97b838
BZ
667
668#ifdef DBG
669
670#endif
671
ca97b838
BZ
672 pAd->bPCIclkOff = FALSE;
673
9f548a2a
BZ
674 /* If required spinlock, each interrupt service routine has to acquire */
675 /* and release itself. */
676 /* */
ca97b838 677
9f548a2a 678 /* Do nothing if NIC doesn't exist */
66cd8d6e
BZ
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;
ca97b838
BZ
684 }
685
66cd8d6e 686 if (IntSource.word & TxCoherent) {
ca97b838
BZ
687 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
688 RTMPHandleRxCoherentInterrupt(pAd);
689 }
690
66cd8d6e 691 if (IntSource.word & RxCoherent) {
ca97b838
BZ
692 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
693 RTMPHandleRxCoherentInterrupt(pAd);
694 }
695
66cd8d6e
BZ
696 if (IntSource.word & FifoStaFullInt) {
697 if ((pAd->int_disable_mask & FifoStaFullInt) == 0) {
ca97b838
BZ
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
66cd8d6e
BZ
705 if (IntSource.word & INT_MGMT_DLY) {
706 if ((pAd->int_disable_mask & INT_MGMT_DLY) == 0) {
ca97b838
BZ
707 rt2860_int_disable(pAd, INT_MGMT_DLY);
708 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
709 }
66cd8d6e 710 pAd->int_pending |= INT_MGMT_DLY;
ca97b838
BZ
711 }
712
66cd8d6e
BZ
713 if (IntSource.word & INT_RX) {
714 if ((pAd->int_disable_mask & INT_RX) == 0) {
ca97b838 715
51126deb 716 /* mask Rxint */
ca97b838
BZ
717 rt2860_int_disable(pAd, INT_RX);
718 tasklet_hi_schedule(&pObj->rx_done_task);
719 }
720 pAd->int_pending |= INT_RX;
721 }
722
66cd8d6e 723 if (IntSource.word & INT_AC3_DLY) {
ca97b838 724
66cd8d6e 725 if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) {
ca97b838
BZ
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
66cd8d6e 733 if (IntSource.word & INT_AC2_DLY) {
ca97b838 734
66cd8d6e 735 if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) {
ca97b838
BZ
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
66cd8d6e 743 if (IntSource.word & INT_AC1_DLY) {
ca97b838
BZ
744
745 pAd->int_pending |= INT_AC1_DLY;
746
66cd8d6e 747 if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) {
ca97b838
BZ
748 /* mask TxDataInt */
749 rt2860_int_disable(pAd, INT_AC1_DLY);
750 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
751 }
752
753 }
754
66cd8d6e 755 if (IntSource.word & INT_AC0_DLY) {
ca97b838
BZ
756
757/*
758 if (IntSource.word & 0x2) {
759 u32 reg;
760 RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
761 printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
762 }
763*/
764 pAd->int_pending |= INT_AC0_DLY;
765
66cd8d6e 766 if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) {
ca97b838
BZ
767 /* mask TxDataInt */
768 rt2860_int_disable(pAd, INT_AC0_DLY);
769 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
770 }
771
772 }
773
66cd8d6e 774 if (IntSource.word & PreTBTTInt) {
ca97b838
BZ
775 RTMPHandlePreTBTTInterrupt(pAd);
776 }
777
66cd8d6e 778 if (IntSource.word & TBTTInt) {
ca97b838
BZ
779 RTMPHandleTBTTInterrupt(pAd);
780 }
781
782 {
783 if (IntSource.word & AutoWakeupInt)
784 RTMPHandleTwakeupInterrupt(pAd);
785 }
786
66cd8d6e 787 return IRQ_HANDLED;
ca97b838
BZ
788}
789
790/*
6ccb5d7c 791 * invalid or writeback cache
ca97b838
BZ
792 * and convert virtual address to physical address
793 */
9fd453c9
BH
794dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
795 size_t size, int sd_idx, int direction)
ca97b838 796{
8a10a546 797 struct os_cookie *pObj;
ca97b838
BZ
798
799 /*
66cd8d6e
BZ
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 */
ca97b838 814
8a10a546 815 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 816
66cd8d6e 817 if (sd_idx == 1) {
62eb734b
BZ
818 struct rt_tx_blk *pTxBlk;
819 pTxBlk = (struct rt_tx_blk *)ptr;
66cd8d6e
BZ
820 return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData,
821 pTxBlk->SrcBufLen, direction);
822 } else {
ca97b838
BZ
823 return pci_map_single(pObj->pci_dev, ptr, size, direction);
824 }
825
826}
827
9fd453c9
BH
828void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr,
829 size_t size, int direction)
ca97b838 830{
8a10a546 831 struct os_cookie *pObj;
ca97b838 832
8a10a546 833 pObj = (struct os_cookie *)pAd->OS_Cookie;
ca97b838 834
e44fd1cf 835 pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
ca97b838
BZ
836
837}
This page took 0.326549 seconds and 5 git commands to generate.