blob: ff7f8338073671b34d73c771e8a96a646ef14249 [file] [log] [blame]
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001/*
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
43extern UINT8 MC_CardUsed[];
44#endif // MULTIPLE_CARD_SUPPORT //
45
46
47extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
48 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
49
50static void rx_done_tasklet(unsigned long data);
51static void mgmt_dma_done_tasklet(unsigned long data);
52static void ac0_dma_done_tasklet(unsigned long data);
53static void ac1_dma_done_tasklet(unsigned long data);
54static void ac2_dma_done_tasklet(unsigned long data);
55static void ac3_dma_done_tasklet(unsigned long data);
56static void hcca_dma_done_tasklet(unsigned long data);
57static 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 */
86static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id *ent);
87static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
88static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent);
89void init_thread_task(PRTMP_ADAPTER pAd);
90static void __exit rt2860_cleanup_module(void);
91static int __init rt2860_init_module(void);
92
Greg Kroah-Hartman91980992008-10-28 14:48:09 -070093#ifdef CONFIG_PM
94static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
95static int rt2860_resume(struct pci_dev *pci_dev);
96#endif // CONFIG_PM //
Greg Kroah-Hartman91980992008-10-28 14:48:09 -070097
98
99//
100// Ralink PCI device table, include all supported chipsets
101//
102static 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
112MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
113#ifdef CONFIG_STA_SUPPORT
114MODULE_LICENSE("GPL");
115#ifdef MODULE_VERSION
116MODULE_VERSION(STA_DRIVER_VERSION);
117#endif
118#endif // CONFIG_STA_SUPPORT //
119
120
121//
122// Our PCI driver structure
123//
124static struct pci_driver rt2860_driver =
125{
126 name: "rt2860",
127 id_table: rt2860_pci_tbl,
128 probe: rt2860_init_one,
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700129 remove: __devexit_p(rt2860_remove_one),
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700130
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700131#ifdef CONFIG_PM
132 suspend: rt2860_suspend,
133 resume: rt2860_resume,
134#endif
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700135};
136
137
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700138#ifdef CONFIG_PM
139
140VOID RT2860RejectPendingPackets(
141 IN PRTMP_ADAPTER pAd)
142{
143 // clear PS packets
144 // clear TxSw packets
145}
146
147static 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 {
Greg Kroah-Hartman739b7972009-01-05 14:19:51 -0800164 pAd = net_dev->ml_priv;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700165
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
206static 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
Greg Kroah-Hartman739b7972009-01-05 14:19:51 -0800243 pAd = net_dev->ml_priv;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700244
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 //
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700278
279
280static INT __init rt2860_init_module(VOID)
281{
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700282 return pci_register_driver(&rt2860_driver);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700283}
284
285
286//
287// Driver module unload function
288//
289static VOID __exit rt2860_cleanup_module(VOID)
290{
291 pci_unregister_driver(&rt2860_driver);
292}
293
294module_init(rt2860_init_module);
295module_exit(rt2860_cleanup_module);
296
297
298static 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
321static VOID __devexit rt2860_remove_one(
322 IN struct pci_dev *pci_dev)
323{
324 struct net_device *net_dev = pci_get_drvdata(pci_dev);
Greg Kroah-Hartman739b7972009-01-05 14:19:51 -0800325 RTMP_ADAPTER *pAd = net_dev->ml_priv;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700326
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
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700363 free_netdev(net_dev);
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700364}
365
366//
367// PCI device probe & initialization function
368//
369static 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
382void 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
399void 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
417static 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
430static 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
444static 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
482static 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
519void 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
553static 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
590static 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
627static 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
665static 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
702static 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
740int print_int_count;
741
742IRQ_HANDLE_TYPE
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700743rt2860_interrupt(int irq, void *dev_instance)
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700744{
745 struct net_device *net_dev = (struct net_device *) dev_instance;
Greg Kroah-Hartman739b7972009-01-05 14:19:51 -0800746 PRTMP_ADAPTER pAd = net_dev->ml_priv;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700747 INT_SOURCE_CSR_STRUC IntSource;
748 POS_COOKIE pObj;
Adam McDanieled291e82009-02-23 08:01:07 -0700749 BOOLEAN bOldValue;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700750
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
Adam McDanieled291e82009-02-23 08:01:07 -0700782 bOldValue = pAd->bPCIclkOff;
783 pAd->bPCIclkOff = FALSE;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700784 {
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 }
Adam McDanieled291e82009-02-23 08:01:07 -0700788 pAd->bPCIclkOff = bOldValue;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700789
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 {
Pekka Enberg7f20a182009-01-13 20:51:11 +0200794 return IRQ_HANDLED;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700795 }
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
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700803 // 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);
Adam McDanieled291e82009-02-23 08:01:07 -0700811 printk("snowpin - IntSource.word == 0xffffffff\n");
Pekka Enberg7f20a182009-01-13 20:51:11 +0200812 return IRQ_HANDLED;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700813 }
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
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700946 return IRQ_HANDLED;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700947}
948
949/*
950========================================================================
951Routine Description:
952 Check the chipset vendor/product ID.
953
954Arguments:
955 _dev_p Point to the PCI or USB device
956
957Return Value:
958 TRUE Check ok
959 FALSE Check fail
960
961Note:
962========================================================================
963*/
964BOOLEAN RT28XXChipsetCheck(
965 IN void *_dev_p)
966{
967 /* always TRUE */
968 return TRUE;
969}
970
971
972/*
973========================================================================
974Routine Description:
975 Init net device structure.
976
977Arguments:
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
982Return Value:
983 TRUE Init ok
984 FALSE Init fail
985
986Note:
987========================================================================
988*/
989BOOLEAN 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;
Greg Kroah-Hartman26f0bcd2008-11-13 15:37:21 -0800995 const CHAR *print_name;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -0700996 ULONG csr_addr;
997
998
Pekka Enberg7f20a182009-01-13 20:51:11 +0200999 print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001000
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 --------------------------- */
1039err_out_free_res:
1040 pci_release_regions(pci_dev);
1041err_out_free_netdev:
1042 /* free netdev in caller, not here */
1043 return FALSE;
1044}
1045
1046
1047/*
1048========================================================================
1049Routine Description:
1050 Init net device structure.
1051
1052Arguments:
1053 _dev_p Point to the PCI or USB device
1054 *pAd the raxx interface data pointer
1055
1056Return Value:
1057 TRUE Config ok
1058 FALSE Config fail
1059
1060Note:
1061========================================================================
1062*/
1063BOOLEAN 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========================================================================
1075Routine Description:
1076 Disable DMA.
1077
1078Arguments:
1079 *pAd the raxx interface data pointer
1080
1081Return Value:
1082 None
1083
1084Note:
1085========================================================================
1086*/
1087VOID 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========================================================================
1102Routine Description:
1103 Enable DMA.
1104
1105Arguments:
1106 *pAd the raxx interface data pointer
1107
1108Return Value:
1109 None
1110
1111Note:
1112========================================================================
1113*/
1114VOID 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========================================================================
1146Routine Description:
1147 Write Beacon buffer to Asic.
1148
1149Arguments:
1150 *pAd the raxx interface data pointer
1151
1152Return Value:
1153 None
1154
1155Note:
1156========================================================================
1157*/
1158VOID 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 {
Harvey Harrisond599edc2009-01-07 14:31:57 -08001171 DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__));
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001172 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
1216VOID RTMPInitPCIeLinkCtrlValue(
1217 IN PRTMP_ADAPTER pAd)
1218{
1219}
1220
1221VOID 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*/
1237VOID 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*/
1254VOID RTMPPCIeLinkCtrlSetting(
1255 IN PRTMP_ADAPTER pAd,
1256 IN USHORT Max)
1257{
1258}
1259#endif // CONFIG_STA_SUPPORT //
1260
1261VOID 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
Greg Kroah-Hartman739b7972009-01-05 14:19:51 -08001269 pAd = net_dev->ml_priv;
Greg Kroah-Hartman91980992008-10-28 14:48:09 -07001270
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 */
1295dma_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
1332void 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