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