Staging: add rt2860 wireless driver
[deliverable/linux.git] / drivers / staging / rt2860 / 2860_main_dev.c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 2870_main_dev.c
29
30 Abstract:
31 Create and register network interface.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 */
37
38 #include "rt_config.h"
39
40
41 #ifdef MULTIPLE_CARD_SUPPORT
42 // record whether the card in the card list is used in the card file
43 extern UINT8 MC_CardUsed[];
44 #endif // MULTIPLE_CARD_SUPPORT //
45
46
47 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
48 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
49
50 static void rx_done_tasklet(unsigned long data);
51 static void mgmt_dma_done_tasklet(unsigned long data);
52 static void ac0_dma_done_tasklet(unsigned long data);
53 static void ac1_dma_done_tasklet(unsigned long data);
54 static void ac2_dma_done_tasklet(unsigned long data);
55 static void ac3_dma_done_tasklet(unsigned long data);
56 static void hcca_dma_done_tasklet(unsigned long data);
57 static void fifo_statistic_full_tasklet(unsigned long data);
58
59
60 /*---------------------------------------------------------------------*/
61 /* Symbol & Macro Definitions */
62 /*---------------------------------------------------------------------*/
63 #define RT2860_INT_RX_DLY (1<<0) // bit 0
64 #define RT2860_INT_TX_DLY (1<<1) // bit 1
65 #define RT2860_INT_RX_DONE (1<<2) // bit 2
66 #define RT2860_INT_AC0_DMA_DONE (1<<3) // bit 3
67 #define RT2860_INT_AC1_DMA_DONE (1<<4) // bit 4
68 #define RT2860_INT_AC2_DMA_DONE (1<<5) // bit 5
69 #define RT2860_INT_AC3_DMA_DONE (1<<6) // bit 6
70 #define RT2860_INT_HCCA_DMA_DONE (1<<7) // bit 7
71 #define RT2860_INT_MGMT_DONE (1<<8) // bit 8
72
73 #define INT_RX RT2860_INT_RX_DONE
74
75 #define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
76 #define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
77 #define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
78 #define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
79 #define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
80 #define INT_MGMT_DLY RT2860_INT_MGMT_DONE
81
82 /*---------------------------------------------------------------------*/
83 /* Prototypes of Functions Used */
84 /*---------------------------------------------------------------------*/
85 /* function declarations */
86 static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id *ent);
87 static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
88 static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent);
89 void init_thread_task(PRTMP_ADAPTER pAd);
90 static void __exit rt2860_cleanup_module(void);
91 static int __init rt2860_init_module(void);
92
93 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
94 #ifdef CONFIG_PM
95 static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
96 static int rt2860_resume(struct pci_dev *pci_dev);
97 #endif // CONFIG_PM //
98 #endif
99
100
101 //
102 // Ralink PCI device table, include all supported chipsets
103 //
104 static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
105 {
106 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, //RT28602.4G
107 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
108 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
109 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
110 {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
111 {0,} // terminate list
112 };
113
114 MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
115 #ifdef CONFIG_STA_SUPPORT
116 MODULE_LICENSE("GPL");
117 #ifdef MODULE_VERSION
118 MODULE_VERSION(STA_DRIVER_VERSION);
119 #endif
120 #endif // CONFIG_STA_SUPPORT //
121
122
123 //
124 // Our PCI driver structure
125 //
126 static struct pci_driver rt2860_driver =
127 {
128 name: "rt2860",
129 id_table: rt2860_pci_tbl,
130 probe: rt2860_init_one,
131 #if LINUX_VERSION_CODE >= 0x20412
132 remove: __devexit_p(rt2860_remove_one),
133 #else
134 remove: __devexit(rt2860_remove_one),
135 #endif
136
137 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
138 #ifdef CONFIG_PM
139 suspend: rt2860_suspend,
140 resume: rt2860_resume,
141 #endif
142 #endif
143 };
144
145
146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
147 #ifdef CONFIG_PM
148
149 VOID RT2860RejectPendingPackets(
150 IN PRTMP_ADAPTER pAd)
151 {
152 // clear PS packets
153 // clear TxSw packets
154 }
155
156 static int rt2860_suspend(
157 struct pci_dev *pci_dev,
158 pm_message_t state)
159 {
160 struct net_device *net_dev = pci_get_drvdata(pci_dev);
161 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
162 INT32 retval;
163
164
165 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
166
167 if (net_dev == NULL)
168 {
169 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
170 }
171 else
172 {
173 pAd = (PRTMP_ADAPTER)net_dev->priv;
174
175 /* we can not use IFF_UP because ra0 down but ra1 up */
176 /* and 1 suspend/resume function for 1 module, not for each interface */
177 /* so Linux will call suspend/resume function once */
178 if (VIRTUAL_IF_NUM(pAd) > 0)
179 {
180 // avoid users do suspend after interface is down
181
182 // stop interface
183 netif_carrier_off(net_dev);
184 netif_stop_queue(net_dev);
185
186 // mark device as removed from system and therefore no longer available
187 netif_device_detach(net_dev);
188
189 // mark halt flag
190 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
191 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
192
193 // take down the device
194 rt28xx_close((PNET_DEV)net_dev);
195
196 RT_MOD_DEC_USE_COUNT();
197 }
198 }
199
200 // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
201 // enable device to generate PME# when suspended
202 // pci_choose_state(): Choose the power state of a PCI device to be suspended
203 retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
204 // save the PCI configuration space of a device before suspending
205 pci_save_state(pci_dev);
206 // disable PCI device after use
207 pci_disable_device(pci_dev);
208
209 retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
210
211 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
212 return retval;
213 }
214
215 static int rt2860_resume(
216 struct pci_dev *pci_dev)
217 {
218 struct net_device *net_dev = pci_get_drvdata(pci_dev);
219 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
220 INT32 retval;
221
222
223 // set the power state of a PCI device
224 // PCI has 4 power states, DO (normal) ~ D3(less power)
225 // in include/linux/pci.h, you can find that
226 // #define PCI_D0 ((pci_power_t __force) 0)
227 // #define PCI_D1 ((pci_power_t __force) 1)
228 // #define PCI_D2 ((pci_power_t __force) 2)
229 // #define PCI_D3hot ((pci_power_t __force) 3)
230 // #define PCI_D3cold ((pci_power_t __force) 4)
231 // #define PCI_UNKNOWN ((pci_power_t __force) 5)
232 // #define PCI_POWER_ERROR ((pci_power_t __force) -1)
233 retval = pci_set_power_state(pci_dev, PCI_D0);
234
235 // restore the saved state of a PCI device
236 pci_restore_state(pci_dev);
237
238 // initialize device before it's used by a driver
239 if (pci_enable_device(pci_dev))
240 {
241 printk("pci enable fail!\n");
242 return 0;
243 }
244
245 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
246
247 if (net_dev == NULL)
248 {
249 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
250 }
251 else
252 pAd = (PRTMP_ADAPTER)net_dev->priv;
253
254 if (pAd != NULL)
255 {
256 /* we can not use IFF_UP because ra0 down but ra1 up */
257 /* and 1 suspend/resume function for 1 module, not for each interface */
258 /* so Linux will call suspend/resume function once */
259 if (VIRTUAL_IF_NUM(pAd) > 0)
260 {
261 // mark device as attached from system and restart if needed
262 netif_device_attach(net_dev);
263
264 if (rt28xx_open((PNET_DEV)net_dev) != 0)
265 {
266 // open fail
267 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
268 return 0;
269 }
270
271 // increase MODULE use count
272 RT_MOD_INC_USE_COUNT();
273
274 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
275 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
276
277 netif_start_queue(net_dev);
278 netif_carrier_on(net_dev);
279 netif_wake_queue(net_dev);
280 }
281 }
282
283 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
284 return 0;
285 }
286 #endif // CONFIG_PM //
287 #endif
288
289
290 static INT __init rt2860_init_module(VOID)
291 {
292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
293 return pci_register_driver(&rt2860_driver);
294 #else
295 return pci_module_init(&rt2860_driver);
296 #endif
297 }
298
299
300 //
301 // Driver module unload function
302 //
303 static VOID __exit rt2860_cleanup_module(VOID)
304 {
305 pci_unregister_driver(&rt2860_driver);
306 }
307
308 module_init(rt2860_init_module);
309 module_exit(rt2860_cleanup_module);
310
311
312 static INT __devinit rt2860_init_one (
313 IN struct pci_dev *pci_dev,
314 IN const struct pci_device_id *ent)
315 {
316 INT rc;
317
318 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n"));
319
320 // wake up and enable device
321 if (pci_enable_device (pci_dev))
322 {
323 rc = -EIO;
324 }
325 else
326 {
327 rc = rt2860_probe(pci_dev, ent);
328 }
329
330 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n"));
331 return rc;
332 }
333
334
335 static VOID __devexit rt2860_remove_one(
336 IN struct pci_dev *pci_dev)
337 {
338 struct net_device *net_dev = pci_get_drvdata(pci_dev);
339 RTMP_ADAPTER *pAd = net_dev->priv;
340
341 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
342
343 if (pAd != NULL)
344 {
345 #ifdef MULTIPLE_CARD_SUPPORT
346 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
347 MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
348 #endif // MULTIPLE_CARD_SUPPORT //
349
350
351
352
353 // Unregister network device
354 unregister_netdev(net_dev);
355
356 // Unmap CSR base address
357 iounmap((char *)(net_dev->base_addr));
358
359 RTMPFreeAdapter(pAd);
360
361 // release memory region
362 release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
363 }
364 else
365 {
366 // Unregister network device
367 unregister_netdev(net_dev);
368
369 // Unmap CSR base address
370 iounmap((char *)(net_dev->base_addr));
371
372 // release memory region
373 release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
374 }
375
376 // Free pre-allocated net_device memory
377 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
378 free_netdev(net_dev);
379 #else
380 kfree(net_dev);
381 #endif
382 }
383
384 //
385 // PCI device probe & initialization function
386 //
387 static INT __devinit rt2860_probe(
388 IN struct pci_dev *pci_dev,
389 IN const struct pci_device_id *ent)
390 {
391 PRTMP_ADAPTER pAd;
392 INT rv = 0;
393
394 rv = (INT)rt28xx_probe((void *)pci_dev, (void *)ent, 0, &pAd);
395 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
396 return rv;
397 }
398
399
400 void init_thread_task(IN PRTMP_ADAPTER pAd)
401 {
402 POS_COOKIE pObj;
403
404 pObj = (POS_COOKIE) pAd->OS_Cookie;
405
406 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
407 tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
408 tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
409 tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
410 tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
411 tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
412 tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);
413 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
414 tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
415 }
416
417 void kill_thread_task(IN PRTMP_ADAPTER pAd)
418 {
419 POS_COOKIE pObj;
420
421 pObj = (POS_COOKIE) pAd->OS_Cookie;
422
423 tasklet_kill(&pObj->rx_done_task);
424 tasklet_kill(&pObj->mgmt_dma_done_task);
425 tasklet_kill(&pObj->ac0_dma_done_task);
426 tasklet_kill(&pObj->ac1_dma_done_task);
427 tasklet_kill(&pObj->ac2_dma_done_task);
428 tasklet_kill(&pObj->ac3_dma_done_task);
429 tasklet_kill(&pObj->hcca_dma_done_task);
430 tasklet_kill(&pObj->tbtt_task);
431 tasklet_kill(&pObj->fifo_statistic_full_task);
432 }
433
434
435 static void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
436 {
437 u32 regValue;
438
439 pAd->int_disable_mask &= ~(mode);
440 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
441 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable
442
443 if (regValue != 0)
444 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
445 }
446
447
448 static void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
449 {
450 u32 regValue;
451
452 pAd->int_disable_mask |= mode;
453 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
454 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 0: disable
455
456 if (regValue == 0)
457 {
458 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
459 }
460 }
461
462 static void mgmt_dma_done_tasklet(unsigned long data)
463 {
464 unsigned long flags;
465 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
466 INT_SOURCE_CSR_STRUC IntSource;
467 POS_COOKIE pObj;
468
469 // Do nothing if the driver is starting halt state.
470 // This might happen when timer already been fired before cancel timer with mlmehalt
471 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
472 return;
473
474 pObj = (POS_COOKIE) pAd->OS_Cookie;
475
476 IntSource.word = 0;
477 IntSource.field.MgmtDmaDone = 1;
478 pAd->int_pending &= ~INT_MGMT_DLY;
479
480 RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
481
482 // if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
483 // bug report output
484 RTMP_INT_LOCK(&pAd->irq_lock, flags);
485 /*
486 * double check to avoid lose of interrupts
487 */
488 if (pAd->int_pending & INT_MGMT_DLY)
489 {
490 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
491 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
492 return;
493 }
494
495 /* enable TxDataInt again */
496 rt2860_int_enable(pAd, INT_MGMT_DLY);
497 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
498 }
499
500 static void rx_done_tasklet(unsigned long data)
501 {
502 unsigned long flags;
503 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
504 BOOLEAN bReschedule = 0;
505 POS_COOKIE pObj;
506
507 // Do nothing if the driver is starting halt state.
508 // This might happen when timer already been fired before cancel timer with mlmehalt
509 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
510 return;
511
512 pObj = (POS_COOKIE) pAd->OS_Cookie;
513
514 pAd->int_pending &= ~(INT_RX);
515 #ifdef CONFIG_STA_SUPPORT
516 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
517 bReschedule = STARxDoneInterruptHandle(pAd, 0);
518 #endif // CONFIG_STA_SUPPORT //
519
520 RTMP_INT_LOCK(&pAd->irq_lock, flags);
521 /*
522 * double check to avoid rotting packet
523 */
524 if (pAd->int_pending & INT_RX || bReschedule)
525 {
526 tasklet_hi_schedule(&pObj->rx_done_task);
527 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
528 return;
529 }
530
531 /* enable RxINT again */
532 rt2860_int_enable(pAd, INT_RX);
533 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
534
535 }
536
537 void fifo_statistic_full_tasklet(unsigned long data)
538 {
539 unsigned long flags;
540 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
541 POS_COOKIE pObj;
542
543 // Do nothing if the driver is starting halt state.
544 // This might happen when timer already been fired before cancel timer with mlmehalt
545 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
546 return;
547
548 pObj = (POS_COOKIE) pAd->OS_Cookie;
549
550 pAd->int_pending &= ~(FifoStaFullInt);
551 NICUpdateFifoStaCounters(pAd);
552
553 RTMP_INT_LOCK(&pAd->irq_lock, flags);
554 /*
555 * double check to avoid rotting packet
556 */
557 if (pAd->int_pending & FifoStaFullInt)
558 {
559 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
560 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
561 return;
562 }
563
564 /* enable RxINT again */
565
566 rt2860_int_enable(pAd, FifoStaFullInt);
567 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
568
569 }
570
571 static void hcca_dma_done_tasklet(unsigned long data)
572 {
573 unsigned long flags;
574 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
575 INT_SOURCE_CSR_STRUC IntSource;
576 POS_COOKIE pObj;
577
578 // Do nothing if the driver is starting halt state.
579 // This might happen when timer already been fired before cancel timer with mlmehalt
580 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
581 return;
582
583 pObj = (POS_COOKIE) pAd->OS_Cookie;
584
585
586 IntSource.word = 0;
587 IntSource.field.HccaDmaDone = 1;
588 pAd->int_pending &= ~INT_HCCA_DLY;
589
590 RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
591
592 RTMP_INT_LOCK(&pAd->irq_lock, flags);
593 /*
594 * double check to avoid lose of interrupts
595 */
596 if (pAd->int_pending & INT_HCCA_DLY)
597 {
598 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
599 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
600 return;
601 }
602
603 /* enable TxDataInt again */
604 rt2860_int_enable(pAd, INT_HCCA_DLY);
605 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
606 }
607
608 static void ac3_dma_done_tasklet(unsigned long data)
609 {
610 unsigned long flags;
611 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
612 INT_SOURCE_CSR_STRUC IntSource;
613 POS_COOKIE pObj;
614 BOOLEAN bReschedule = 0;
615
616 // Do nothing if the driver is starting halt state.
617 // This might happen when timer already been fired before cancel timer with mlmehalt
618 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
619 return;
620
621 pObj = (POS_COOKIE) pAd->OS_Cookie;
622
623 IntSource.word = 0;
624 IntSource.field.Ac3DmaDone = 1;
625 pAd->int_pending &= ~INT_AC3_DLY;
626
627 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
628
629 RTMP_INT_LOCK(&pAd->irq_lock, flags);
630 /*
631 * double check to avoid lose of interrupts
632 */
633 if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
634 {
635 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
636 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
637 return;
638 }
639
640 /* enable TxDataInt again */
641 rt2860_int_enable(pAd, INT_AC3_DLY);
642 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
643 }
644
645 static void ac2_dma_done_tasklet(unsigned long data)
646 {
647 unsigned long flags;
648 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
649 INT_SOURCE_CSR_STRUC IntSource;
650 POS_COOKIE pObj;
651 BOOLEAN bReschedule = 0;
652
653 // Do nothing if the driver is starting halt state.
654 // This might happen when timer already been fired before cancel timer with mlmehalt
655 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
656 return;
657
658 pObj = (POS_COOKIE) pAd->OS_Cookie;
659
660 IntSource.word = 0;
661 IntSource.field.Ac2DmaDone = 1;
662 pAd->int_pending &= ~INT_AC2_DLY;
663
664 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
665
666 RTMP_INT_LOCK(&pAd->irq_lock, flags);
667
668 /*
669 * double check to avoid lose of interrupts
670 */
671 if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
672 {
673 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
674 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
675 return;
676 }
677
678 /* enable TxDataInt again */
679 rt2860_int_enable(pAd, INT_AC2_DLY);
680 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
681 }
682
683 static void ac1_dma_done_tasklet(unsigned long data)
684 {
685 unsigned long flags;
686 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
687 INT_SOURCE_CSR_STRUC IntSource;
688 POS_COOKIE pObj;
689 BOOLEAN bReschedule = 0;
690
691 // Do nothing if the driver is starting halt state.
692 // This might happen when timer already been fired before cancel timer with mlmehalt
693 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
694 return;
695
696 pObj = (POS_COOKIE) pAd->OS_Cookie;
697
698 IntSource.word = 0;
699 IntSource.field.Ac1DmaDone = 1;
700 pAd->int_pending &= ~INT_AC1_DLY;
701
702 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
703
704 RTMP_INT_LOCK(&pAd->irq_lock, flags);
705 /*
706 * double check to avoid lose of interrupts
707 */
708 if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
709 {
710 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
711 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
712 return;
713 }
714
715 /* enable TxDataInt again */
716 rt2860_int_enable(pAd, INT_AC1_DLY);
717 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
718 }
719
720 static void ac0_dma_done_tasklet(unsigned long data)
721 {
722 unsigned long flags;
723 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
724 INT_SOURCE_CSR_STRUC IntSource;
725 POS_COOKIE pObj;
726 BOOLEAN bReschedule = 0;
727
728 // Do nothing if the driver is starting halt state.
729 // This might happen when timer already been fired before cancel timer with mlmehalt
730 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
731 return;
732
733 pObj = (POS_COOKIE) pAd->OS_Cookie;
734
735 IntSource.word = 0;
736 IntSource.field.Ac0DmaDone = 1;
737 pAd->int_pending &= ~INT_AC0_DLY;
738
739 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
740
741 RTMP_INT_LOCK(&pAd->irq_lock, flags);
742 /*
743 * double check to avoid lose of interrupts
744 */
745 if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
746 {
747 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
748 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
749 return;
750 }
751
752 /* enable TxDataInt again */
753 rt2860_int_enable(pAd, INT_AC0_DLY);
754 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
755 }
756
757
758 int print_int_count;
759
760 IRQ_HANDLE_TYPE
761 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
762 rt2860_interrupt(int irq, void *dev_instance)
763 #else
764 rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
765 #endif
766 {
767 struct net_device *net_dev = (struct net_device *) dev_instance;
768 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
769 INT_SOURCE_CSR_STRUC IntSource;
770 POS_COOKIE pObj;
771
772 pObj = (POS_COOKIE) pAd->OS_Cookie;
773
774
775 /* Note 03312008: we can not return here before
776 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
777 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
778 Or kernel will panic after ifconfig ra0 down sometimes */
779
780
781 //
782 // Inital the Interrupt source.
783 //
784 IntSource.word = 0x00000000L;
785 // McuIntSource.word = 0x00000000L;
786
787 //
788 // Get the interrupt sources & saved to local variable
789 //
790 //RTMP_IO_READ32(pAd, where, &McuIntSource.word);
791 //RTMP_IO_WRITE32(pAd, , McuIntSource.word);
792
793 //
794 // Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
795 // And at the same time, clock maybe turned off that say there is no DMA service.
796 // when ASIC get to sleep.
797 // To prevent system hang on power saving.
798 // We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
799 //
800 // RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
801 // RT2860 => when ASIC is sleeping, MAC register can be read and written.
802
803 {
804 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
805 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
806 }
807
808 // Do nothing if Reset in progress
809 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
810 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
811 {
812 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
813 return IRQ_HANDLED;
814 #else
815 return;
816 #endif
817 }
818
819 //
820 // Handle interrupt, walk through all bits
821 // Should start from highest priority interrupt
822 // The priority can be adjust by altering processing if statement
823 //
824
825 pAd->bPCIclkOff = FALSE;
826
827 // If required spinlock, each interrupt service routine has to acquire
828 // and release itself.
829 //
830
831 // Do nothing if NIC doesn't exist
832 if (IntSource.word == 0xffffffff)
833 {
834 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
835 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
836 return IRQ_HANDLED;
837 #else
838 return;
839 #endif
840 }
841
842 if (IntSource.word & TxCoherent)
843 {
844 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
845 RTMPHandleRxCoherentInterrupt(pAd);
846 }
847
848 if (IntSource.word & RxCoherent)
849 {
850 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
851 RTMPHandleRxCoherentInterrupt(pAd);
852 }
853
854 if (IntSource.word & FifoStaFullInt)
855 {
856 #if 1
857 if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
858 {
859 /* mask FifoStaFullInt */
860 rt2860_int_disable(pAd, FifoStaFullInt);
861 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
862 }
863 pAd->int_pending |= FifoStaFullInt;
864 #else
865 NICUpdateFifoStaCounters(pAd);
866 #endif
867 }
868
869 if (IntSource.word & INT_MGMT_DLY)
870 {
871 if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
872 {
873 rt2860_int_disable(pAd, INT_MGMT_DLY);
874 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
875 }
876 pAd->int_pending |= INT_MGMT_DLY ;
877 }
878
879 if (IntSource.word & INT_RX)
880 {
881 if ((pAd->int_disable_mask & INT_RX) == 0)
882 {
883 /* mask RxINT */
884 rt2860_int_disable(pAd, INT_RX);
885 tasklet_hi_schedule(&pObj->rx_done_task);
886 }
887 pAd->int_pending |= INT_RX;
888 }
889
890 if (IntSource.word & INT_HCCA_DLY)
891 {
892
893 if ((pAd->int_disable_mask & INT_HCCA_DLY) == 0)
894 {
895 /* mask TxDataInt */
896 rt2860_int_disable(pAd, INT_HCCA_DLY);
897 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
898 }
899 pAd->int_pending |= INT_HCCA_DLY;
900 }
901
902 if (IntSource.word & INT_AC3_DLY)
903 {
904
905 if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
906 {
907 /* mask TxDataInt */
908 rt2860_int_disable(pAd, INT_AC3_DLY);
909 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
910 }
911 pAd->int_pending |= INT_AC3_DLY;
912 }
913
914 if (IntSource.word & INT_AC2_DLY)
915 {
916
917 if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
918 {
919 /* mask TxDataInt */
920 rt2860_int_disable(pAd, INT_AC2_DLY);
921 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
922 }
923 pAd->int_pending |= INT_AC2_DLY;
924 }
925
926 if (IntSource.word & INT_AC1_DLY)
927 {
928
929 pAd->int_pending |= INT_AC1_DLY;
930
931 if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
932 {
933 /* mask TxDataInt */
934 rt2860_int_disable(pAd, INT_AC1_DLY);
935 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
936 }
937
938 }
939
940 if (IntSource.word & INT_AC0_DLY)
941 {
942 pAd->int_pending |= INT_AC0_DLY;
943
944 if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
945 {
946 /* mask TxDataInt */
947 rt2860_int_disable(pAd, INT_AC0_DLY);
948 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
949 }
950
951 }
952
953 if (IntSource.word & PreTBTTInt)
954 {
955 RTMPHandlePreTBTTInterrupt(pAd);
956 }
957
958 if (IntSource.word & TBTTInt)
959 {
960 RTMPHandleTBTTInterrupt(pAd);
961 }
962
963
964
965 #ifdef CONFIG_STA_SUPPORT
966 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
967 {
968 if (IntSource.word & AutoWakeupInt)
969 RTMPHandleTwakeupInterrupt(pAd);
970 }
971 #endif // CONFIG_STA_SUPPORT //
972
973 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
974 return IRQ_HANDLED;
975 #endif
976
977 }
978
979 /*
980 ========================================================================
981 Routine Description:
982 Check the chipset vendor/product ID.
983
984 Arguments:
985 _dev_p Point to the PCI or USB device
986
987 Return Value:
988 TRUE Check ok
989 FALSE Check fail
990
991 Note:
992 ========================================================================
993 */
994 BOOLEAN RT28XXChipsetCheck(
995 IN void *_dev_p)
996 {
997 /* always TRUE */
998 return TRUE;
999 }
1000
1001
1002 /*
1003 ========================================================================
1004 Routine Description:
1005 Init net device structure.
1006
1007 Arguments:
1008 _dev_p Point to the PCI or USB device
1009 *net_dev Point to the net device
1010 *pAd the raxx interface data pointer
1011
1012 Return Value:
1013 TRUE Init ok
1014 FALSE Init fail
1015
1016 Note:
1017 ========================================================================
1018 */
1019 BOOLEAN RT28XXNetDevInit(
1020 IN void *_dev_p,
1021 IN struct net_device *net_dev,
1022 IN RTMP_ADAPTER *pAd)
1023 {
1024 struct pci_dev *pci_dev = (struct pci_dev *)_dev_p;
1025 CHAR *print_name;
1026 ULONG csr_addr;
1027
1028
1029 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1030 print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
1031 #else
1032 print_name = pci_dev ? pci_dev->slot_name : "rt2860";
1033 #endif // LINUX_VERSION_CODE //
1034
1035 net_dev->base_addr = 0;
1036 net_dev->irq = 0;
1037
1038 if (pci_request_regions(pci_dev, print_name))
1039 goto err_out_free_netdev;
1040
1041 // interrupt IRQ number
1042 net_dev->irq = pci_dev->irq;
1043
1044 // map physical address to virtual address for accessing register
1045 csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0),
1046 pci_resource_len(pci_dev, 0));
1047
1048 if (!csr_addr)
1049 {
1050 DBGPRINT(RT_DEBUG_ERROR,
1051 ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
1052 print_name, (ULONG)pci_resource_len(pci_dev, 0),
1053 (ULONG)pci_resource_start(pci_dev, 0)));
1054 goto err_out_free_res;
1055 }
1056
1057 // Save CSR virtual address and irq to device structure
1058 net_dev->base_addr = csr_addr;
1059 pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr;
1060
1061 // Set DMA master
1062 pci_set_master(pci_dev);
1063
1064 net_dev->priv_flags = INT_MAIN;
1065
1066 DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",
1067 net_dev->name, (ULONG)pci_resource_start(pci_dev, 0),
1068 (ULONG)csr_addr, pci_dev->irq));
1069 return TRUE;
1070
1071
1072 /* --------------------------- ERROR HANDLE --------------------------- */
1073 err_out_free_res:
1074 pci_release_regions(pci_dev);
1075 err_out_free_netdev:
1076 /* free netdev in caller, not here */
1077 return FALSE;
1078 }
1079
1080
1081 /*
1082 ========================================================================
1083 Routine Description:
1084 Init net device structure.
1085
1086 Arguments:
1087 _dev_p Point to the PCI or USB device
1088 *pAd the raxx interface data pointer
1089
1090 Return Value:
1091 TRUE Config ok
1092 FALSE Config fail
1093
1094 Note:
1095 ========================================================================
1096 */
1097 BOOLEAN RT28XXProbePostConfig(
1098 IN void *_dev_p,
1099 IN RTMP_ADAPTER *pAd,
1100 IN INT32 argc)
1101 {
1102 /* no use */
1103 return TRUE;
1104 }
1105
1106
1107 /*
1108 ========================================================================
1109 Routine Description:
1110 Disable DMA.
1111
1112 Arguments:
1113 *pAd the raxx interface data pointer
1114
1115 Return Value:
1116 None
1117
1118 Note:
1119 ========================================================================
1120 */
1121 VOID RT28XXDMADisable(
1122 IN RTMP_ADAPTER *pAd)
1123 {
1124 WPDMA_GLO_CFG_STRUC GloCfg;
1125
1126
1127 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1128 GloCfg.word &= 0xff0;
1129 GloCfg.field.EnTXWriteBackDDONE =1;
1130 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1131 }
1132
1133
1134 /*
1135 ========================================================================
1136 Routine Description:
1137 Enable DMA.
1138
1139 Arguments:
1140 *pAd the raxx interface data pointer
1141
1142 Return Value:
1143 None
1144
1145 Note:
1146 ========================================================================
1147 */
1148 VOID RT28XXDMAEnable(
1149 IN RTMP_ADAPTER *pAd)
1150 {
1151 WPDMA_GLO_CFG_STRUC GloCfg;
1152 int i = 0;
1153
1154 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1155 do
1156 {
1157 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1158 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1159 break;
1160
1161 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1162 RTMPusecDelay(1000);
1163 i++;
1164 }while ( i <200);
1165
1166 RTMPusecDelay(50);
1167
1168 GloCfg.field.EnTXWriteBackDDONE = 1;
1169 GloCfg.field.WPDMABurstSIZE = 2;
1170 GloCfg.field.EnableRxDMA = 1;
1171 GloCfg.field.EnableTxDMA = 1;
1172
1173 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1174 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1175
1176 }
1177
1178 /*
1179 ========================================================================
1180 Routine Description:
1181 Write Beacon buffer to Asic.
1182
1183 Arguments:
1184 *pAd the raxx interface data pointer
1185
1186 Return Value:
1187 None
1188
1189 Note:
1190 ========================================================================
1191 */
1192 VOID RT28xx_UpdateBeaconToAsic(
1193 IN RTMP_ADAPTER *pAd,
1194 IN INT apidx,
1195 IN ULONG FrameLen,
1196 IN ULONG UpdatePos)
1197 {
1198 ULONG CapInfoPos = 0;
1199 UCHAR *ptr, *ptr_update, *ptr_capinfo;
1200 UINT i;
1201 BOOLEAN bBcnReq = FALSE;
1202 UCHAR bcn_idx = 0;
1203
1204 {
1205 DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __FUNCTION__));
1206 return;
1207 }
1208
1209 if (bBcnReq == FALSE)
1210 {
1211 /* when the ra interface is down, do not send its beacon frame */
1212 /* clear all zero */
1213 for(i=0; i<TXWI_SIZE; i+=4)
1214 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1215 }
1216 else
1217 {
1218 ptr = (PUCHAR)&pAd->BeaconTxWI;
1219 #ifdef RT_BIG_ENDIAN
1220 RTMPWIEndianChange(ptr, TYPE_TXWI);
1221 #endif
1222 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1223 {
1224 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1225 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
1226 ptr += 4;
1227 }
1228
1229 // Update CapabilityInfo in Beacon
1230 for (i = CapInfoPos; i < (CapInfoPos+2); i++)
1231 {
1232 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
1233 ptr_capinfo ++;
1234 }
1235
1236 if (FrameLen > UpdatePos)
1237 {
1238 for (i= UpdatePos; i< (FrameLen); i++)
1239 {
1240 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
1241 ptr_update ++;
1242 }
1243 }
1244
1245 }
1246
1247 }
1248
1249 #ifdef CONFIG_STA_SUPPORT
1250 VOID RTMPInitPCIeLinkCtrlValue(
1251 IN PRTMP_ADAPTER pAd)
1252 {
1253 }
1254
1255 VOID RTMPFindHostPCIDev(
1256 IN PRTMP_ADAPTER pAd)
1257 {
1258 }
1259
1260 /*
1261 ========================================================================
1262
1263 Routine Description:
1264
1265 Arguments:
1266 Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
1267 Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
1268
1269 ========================================================================
1270 */
1271 VOID RTMPPCIeLinkCtrlValueRestore(
1272 IN PRTMP_ADAPTER pAd,
1273 IN UCHAR Level)
1274 {
1275 }
1276
1277 /*
1278 ========================================================================
1279
1280 Routine Description:
1281
1282 Arguments:
1283 Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
1284 Because now frequently set our device to mode 1 or mode 3 will cause problem.
1285
1286 ========================================================================
1287 */
1288 VOID RTMPPCIeLinkCtrlSetting(
1289 IN PRTMP_ADAPTER pAd,
1290 IN USHORT Max)
1291 {
1292 }
1293 #endif // CONFIG_STA_SUPPORT //
1294
1295 VOID rt2860_stop(struct net_device *net_dev)
1296 {
1297 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
1298 if (net_dev == NULL)
1299 {
1300 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
1301 }
1302 else
1303 pAd = (PRTMP_ADAPTER)net_dev->priv;
1304
1305 if (pAd != NULL)
1306 {
1307 // stop interface
1308 netif_carrier_off(net_dev);
1309 netif_stop_queue(net_dev);
1310
1311 // mark device as removed from system and therefore no longer available
1312 netif_device_detach(net_dev);
1313
1314 // mark halt flag
1315 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
1316 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1317
1318 // take down the device
1319 rt28xx_close((PNET_DEV)net_dev);
1320 RT_MOD_DEC_USE_COUNT();
1321 }
1322 return;
1323 }
1324
1325 /*
1326 * invaild or writeback cache
1327 * and convert virtual address to physical address
1328 */
1329 dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
1330 {
1331 PRTMP_ADAPTER pAd;
1332 POS_COOKIE pObj;
1333
1334 /*
1335 ------ Porting Information ------
1336 > For Tx Alloc:
1337 mgmt packets => sd_idx = 0
1338 SwIdx: pAd->MgmtRing.TxCpuIdx
1339 pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
1340
1341 data packets => sd_idx = 1
1342 TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
1343 QueIdx: pTxBlk->QueIdx
1344 pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
1345
1346 > For Rx Alloc:
1347 sd_idx = -1
1348 */
1349
1350 pAd = (PRTMP_ADAPTER)handle;
1351 pObj = (POS_COOKIE)pAd->OS_Cookie;
1352
1353 if (sd_idx == 1)
1354 {
1355 PTX_BLK pTxBlk;
1356 pTxBlk = (PTX_BLK)ptr;
1357 return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
1358 }
1359 else
1360 {
1361 return pci_map_single(pObj->pci_dev, ptr, size, direction);
1362 }
1363
1364 }
1365
1366 void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
1367 {
1368 PRTMP_ADAPTER pAd;
1369 POS_COOKIE pObj;
1370
1371 pAd=(PRTMP_ADAPTER)handle;
1372 pObj = (POS_COOKIE)pAd->OS_Cookie;
1373
1374 pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
1375
1376 }
1377
This page took 0.059736 seconds and 6 git commands to generate.