MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / Module / rtmp_main.c
blobc0dcaa1b1e5a8c44951111429f5239785f12b552
1 /*************************************************************************
2 * Ralink Tech Inc. *
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
6 * *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 * *
24 *************************************************************************
26 Module Name:
27 rtmp_main.c
29 Abstract:
31 Revision History:
32 Who When What
33 -------- ---------- ----------------------------------------------
34 Name Date Modification logs
35 Paul Lin 2002-11-25 Initial version
38 #include "rt_config.h"
41 // Global static variable, Debug level flag
42 #ifdef RT2500_DBG
43 ULONG RTDebugLevel = RT_DEBUG_TRACE;
44 #endif
46 // Following information will be show when you run 'modinfo'
47 // *** If you have a solution for the bug in current version of driver, please mail to me.
48 // Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
49 MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
50 MODULE_DESCRIPTION("Ralink RT2500 802.11b/g WLAN driver ");
52 #if LINUX_VERSION_CODE >= 0x20412 // Red Hat 7.3
53 MODULE_LICENSE("GPL");
54 #endif
56 extern const struct iw_handler_def rt2500_iw_handler_def;
58 static INT __devinit RT2500_init_one (
59 IN struct pci_dev *pPci_Dev,
60 IN const struct pci_device_id *ent)
62 INT rc;
64 // wake up and enable device
65 if (pci_enable_device (pPci_Dev))
67 rc = -EIO;
69 else
71 rc = RT2500_probe(pPci_Dev, ent);
73 return rc;
76 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
77 static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *))
79 struct net_device *dev;
80 int alloc_size;
82 /* ensure 32-byte alignment of the private area */
83 alloc_size = sizeof (*dev) + sizeof_priv + 31;
85 dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
86 if (dev == NULL)
88 DBGPRINT(RT_DEBUG_ERROR, "alloc_netdev: Unable to allocate device memory.\n");
89 return NULL;
92 memset(dev, 0, alloc_size);
94 if (sizeof_priv)
95 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
97 setup(dev);
98 strcpy(dev->name,mask);
100 return dev;
102 #endif
105 // PCI device probe & initialization function
107 INT __devinit RT2500_probe(
108 IN struct pci_dev *pPci_Dev,
109 IN const struct pci_device_id *ent)
111 struct net_device *net_dev;
112 RTMP_ADAPTER *pAd;
113 CHAR *print_name;
114 INT chip_id = (int) ent->driver_data;
115 unsigned long csr_addr;
116 CSR3_STRUC StaMacReg0;
117 CSR4_STRUC StaMacReg1;
118 INT Status;
120 print_name = pPci_Dev ? pci_name(pPci_Dev) : "rt2500";
122 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
123 net_dev = alloc_netdev(sizeof(RTMP_ADAPTER), "eth%d", ether_setup);
124 #else
125 net_dev = alloc_etherdev(sizeof(RTMP_ADAPTER));
126 #endif
127 if (net_dev == NULL)
129 DBGPRINT(RT_DEBUG_TRACE, "init_ethernet failed\n");
130 goto err_out;
133 SET_MODULE_OWNER(net_dev);
135 if (pci_request_regions(pPci_Dev, print_name))
136 goto err_out_free_netdev;
138 // Interrupt IRQ number
139 net_dev->irq = pPci_Dev->irq;
141 // map physical address to virtual address for accessing register
142 csr_addr = (unsigned long) ioremap(pci_resource_start(pPci_Dev, 0), pci_resource_len(pPci_Dev, 0));
143 if (!csr_addr)
145 DBGPRINT(RT_DEBUG_TRACE, "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
146 pPci_Dev->slot_name, (ULONG)pci_resource_len(pPci_Dev, 0), pci_resource_start(pPci_Dev, 0));
147 goto err_out_free_res;
150 // Save CSR virtual address and irq to device structure
151 net_dev->base_addr = csr_addr;
152 pAd = net_dev->priv;
153 pAd->CSRBaseAddress = net_dev->base_addr;
154 pAd->net_dev = net_dev;
156 // Set DMA master
157 pci_set_master(pPci_Dev);
159 // Read MAC address
160 NICReadAdapterInfo(pAd);
162 RTMP_IO_READ32(pAd, CSR3, &StaMacReg0.word);
163 RTMP_IO_READ32(pAd, CSR4, &StaMacReg1.word);
164 net_dev->dev_addr[0] = StaMacReg0.field.Byte0;
165 net_dev->dev_addr[1] = StaMacReg0.field.Byte1;
166 net_dev->dev_addr[2] = StaMacReg0.field.Byte2;
167 net_dev->dev_addr[3] = StaMacReg0.field.Byte3;
168 net_dev->dev_addr[4] = StaMacReg1.field.Byte4;
169 net_dev->dev_addr[5] = StaMacReg1.field.Byte5;
171 pAd->chip_id = chip_id;
172 pAd->pPci_Dev = pPci_Dev;
174 // The chip-specific entries in the device structure.
175 net_dev->open = RT2500_open;
176 net_dev->hard_start_xmit = RTMPSendPackets;
177 net_dev->stop = RT2500_close;
178 net_dev->get_stats = RT2500_get_ether_stats;
180 #if WIRELESS_EXT >= 12
181 net_dev->get_wireless_stats = RT2500_get_wireless_stats;
182 net_dev->wireless_handlers = (struct iw_handler_def *) &rt2500_iw_handler_def;
183 #endif
185 net_dev->set_multicast_list = RT2500_set_rx_mode;
186 net_dev->do_ioctl = RT2500_ioctl;
188 {// find available
189 int i=0;
190 char slot_name[IFNAMSIZ];
191 struct net_device *device;
193 for (i = 0; i < 8; i++)
195 sprintf(slot_name, "ra%d", i);
197 for (device = dev_base; device != NULL; device = device->next)
199 if (strncmp(device->name, slot_name, 4) == 0)
201 break;
204 if(device == NULL) break;
206 if(i == 8)
208 DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n");
209 goto err_out_unmap;
212 sprintf(net_dev->name, "ra%d", i);
215 // Register this device
216 Status = register_netdev(net_dev);
217 if (Status)
218 goto err_out_unmap;
220 DBGPRINT(RT_DEBUG_TRACE, "%s: at 0x%lx, VA 0x%1x, IRQ %d. \n",
221 net_dev->name, pci_resource_start(pPci_Dev, 0), (ULONG)csr_addr, pPci_Dev->irq);
223 // Set driver data
224 pci_set_drvdata(pPci_Dev, net_dev);
226 return 0;
228 err_out_unmap:
229 iounmap((void *)csr_addr);
230 release_mem_region(pci_resource_start(pPci_Dev, 0), pci_resource_len(pPci_Dev, 0));
231 err_out_free_res:
232 pci_release_regions(pPci_Dev);
233 err_out_free_netdev:
234 kfree (net_dev);
235 err_out:
236 return -ENODEV;
239 INT RT2500_open(
240 IN struct net_device *net_dev)
242 PRTMP_ADAPTER pAd = net_dev->priv;
243 INT status = NDIS_STATUS_SUCCESS;
245 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
246 if (!try_module_get(THIS_MODULE))
248 DBGPRINT(RT_DEBUG_ERROR, "%s: cannot reserve module\n", __FUNCTION__);
249 return -1;
251 #else
252 MOD_INC_USE_COUNT;
253 #endif
255 // 1. Allocate DMA descriptors & buffers
256 status = RTMPAllocDMAMemory(pAd);
257 if (status != NDIS_STATUS_SUCCESS)
258 goto out_module_put;
260 // 2. request interrupt\x14
261 // Disable interrupts here which is as soon as possible
262 // This statement should never be true. We might consider to remove it later
263 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
265 NICDisableInterrupt(pAd);
268 status = request_irq(pAd->pPci_Dev->irq, &RTMPIsr, SA_SHIRQ, net_dev->name, net_dev);
269 if (status)
271 RTMPFreeDMAMemory(pAd);
272 goto out_module_put;
274 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
276 // 3. Read MAC address
277 //NICReadAdapterInfo(pAd);
279 DBGPRINT(RT_DEBUG_TRACE, "%s: RT2500_open() irq %d. MAC = %02x:%02x:%02x:%02x:%02x:%02x \n",
280 net_dev->name, pAd->pPci_Dev->irq, pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2],
281 pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5]);
283 NICInitTransmit(pAd);
285 // manufacture default
286 PortCfgInit(pAd);
288 // Read RaConfig profile parameters
289 RTMPReadParametersFromFile(pAd);
291 // initialize MLME
292 status = MlmeInit(pAd);
294 // Initialize Mlme Memory Handler
295 // Allocate 20 nonpaged memory pool which size are MAX_LEN_OF_MLME_BUFFER for use
296 status = MlmeInitMemoryHandler(pAd, 20, MAX_LEN_OF_MLME_BUFFER);
298 if(status != NDIS_STATUS_SUCCESS)
300 free_irq(net_dev->irq, net_dev);
301 RTMPFreeDMAMemory(pAd);
302 goto out_module_put;
305 // Initialize Asics
306 NICInitializeAdapter(pAd);
308 NICReadEEPROMParameters(pAd);
310 NICInitAsicFromEEPROM(pAd);
312 // 2nd stage hardware initialization after all parameters are acquired from
313 // Registry or E2PROM
314 RTMPSetPhyMode(pAd, PHY_11BG_MIXED);
316 // Set the timer to check for link beat.
317 /* RTMPInitTimer(pAd, &pAd->timer, RT2500_timer);
318 RTMPSetTimer(pAd, &pAd->timer, DEBUG_TASK_DELAY);*/
320 // Enable interrupt
321 NICEnableInterrupt(pAd);
323 // Start net interface tx /rx
324 netif_start_queue(net_dev);
326 netif_carrier_on(net_dev);
327 netif_wake_queue(net_dev);
329 return 0;
331 out_module_put:
332 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
333 module_put(THIS_MODULE);
334 #else
335 MOD_DEC_USE_COUNT;
336 #endif
338 return status;
341 VOID RT2500_timer(
342 IN unsigned long data)
344 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;
346 // NICCheckForHang(pAd);
348 RTMPSetTimer(pAd, &pAd->timer, DEBUG_TASK_DELAY);
352 ========================================================================
354 Routine Description:
355 hard_start_xmit handler
357 Arguments:
358 skb point to sk_buf which upper layer transmit
359 net_dev point to net_dev
360 Return Value:
361 None
363 Note:
365 ========================================================================
367 INT RTMPSendPackets(
368 IN struct sk_buff *skb,
369 IN struct net_device *net_dev)
371 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
372 PRTMP_ADAPTER pAdapter = net_dev->priv;
374 DBGPRINT(RT_DEBUG_INFO, "<==== RTMPSendPackets\n");
376 // Drop packets if no associations
377 if (!INFRA_ON(pAdapter) && !ADHOC_ON(pAdapter))
379 // Drop send request since there are no physical connection yet
380 // Check the association status for infrastructure mode
381 // And Mibss for Ad-hoc mode setup
382 RTMPFreeSkbBuffer(skb);
384 else
386 // This function has to manage NdisSendComplete return call within its routine
387 // NdisSendComplete will acknowledge upper layer in two steps.
388 // 1. Within Packet Enqueue, set the NDIS_STATUS_PENDING
389 // 2. Within TxRingTxDone / PrioRingTxDone call NdisSendComplete with final status
390 // initial skb->data_len=0, we will use this variable to store data size when fragment(in TKIP)
391 // and skb->len is actual data len
392 skb->data_len = skb->len;
393 Status = RTMPSendPacket(pAdapter,skb);
395 if (Status != NDIS_STATUS_SUCCESS)
397 // Errors before enqueue stage
398 RTMPFreeSkbBuffer(skb);
402 // Dequeue one frame from SendTxWait queue and process it
403 // There are two place calling dequeue for TX ring.
404 // 1. Here, right after queueing the frame.
405 // 2. At the end of TxRingTxDone service routine.
406 if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
407 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)) &&
408 (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
410 //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
411 // Call dequeue without selected queue, let the subroutine select the right priority
412 // Tx software queue
413 RTMPDeQueuePacket(pAdapter);
416 return 0;
420 ========================================================================
422 Routine Description:
423 Interrupt handler
425 Arguments:
426 irq interrupt line
427 dev_instance Pointer to net_device
428 rgs store process's context before entering ISR,
429 this parameter is just for debug purpose.
431 Return Value:
432 VOID
434 Note:
436 ========================================================================
438 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
439 irqreturn_t
440 #else
441 VOID
442 #endif
443 RTMPIsr(
444 IN INT irq,
445 IN VOID *dev_instance,
446 IN struct pt_regs *rgs)
448 struct net_device *net_dev = dev_instance;
449 PRTMP_ADAPTER pAdapter = net_dev->priv;
450 INTSRC_STRUC IntSource;
452 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleInterrupt\n");
454 // 1. Disable interrupt
455 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE) && RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
457 NICDisableInterrupt(pAdapter);
461 // Get the interrupt sources & saved to local variable
463 // RTMP_IO_READ32(pAdapter, CSR7, &IntSource);
464 RTMP_IO_READ32(pAdapter, CSR7, &IntSource.word);
465 RTMP_IO_WRITE32(pAdapter, CSR7, IntSource.word);
468 // Handle interrupt, walk through all bits
469 // Should start from highest priority interrupt
470 // The priority can be adjust by altering processing if statement
472 // If required spinlock, each interrupt service routine has to acquire
473 // and release itself.
475 if (IntSource.field.TbcnExpire)
477 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleTbcnInterrupt\n");
478 RTMPHandleTbcnInterrupt(pAdapter);
481 if (IntSource.field.TwakeExpire)
483 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleTwakeupInterrupt\n");
484 RTMPHandleTwakeupInterrupt(pAdapter);
487 if (IntSource.field.TatimwExpire)
489 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleTatimInterrupt\n");
490 // RTMPHandleTatimInterrupt(pAdapter);
493 if (IntSource.field.EncryptionDone)
495 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleEncryptionDoneInterrupt\n");
496 RTMPHandleEncryptionDoneInterrupt(pAdapter);
499 if (IntSource.field.TxRingTxDone)
501 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleTxRingTxDoneInterrupt\n");
502 RTMPHandleTxRingTxDoneInterrupt(pAdapter);
505 if (IntSource.field.AtimRingTxDone)
507 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleAtimRingTxDoneInterrupt\n");
508 RTMPHandleAtimRingTxDoneInterrupt(pAdapter);
511 if (IntSource.field.PrioRingTxDone)
513 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandlePrioRingTxDoneInterrupt\n");
514 RTMPHandlePrioRingTxDoneInterrupt(pAdapter);
517 if (IntSource.field.DecryptionDone)
519 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleDecryptionDoneInterrupt\n");
520 RTMPHandleDecryptionDoneInterrupt(pAdapter);
523 if (IntSource.field.RxDone)
525 DBGPRINT(RT_DEBUG_INFO, "====> RTMPHandleRxDoneInterrupt\n");
526 RTMPHandleRxDoneInterrupt(pAdapter);
527 RTMPHandleEncryptionDoneInterrupt(pAdapter);
530 // Do nothing if Reset in progress
531 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS))
533 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
534 return IRQ_HANDLED;
535 #else
536 return;
537 #endif
541 // Re-enable the interrupt (disabled in RTMPIsr)
543 NICEnableInterrupt(pAdapter);
545 DBGPRINT(RT_DEBUG_INFO, "<==== RTMPHandleInterrupt\n");
546 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
547 return IRQ_HANDLED;
548 #endif
551 #if WIRELESS_EXT >= 12
553 ========================================================================
555 Routine Description:
556 get wireless statistics
558 Arguments:
559 net_dev Pointer to net_device
561 Return Value:
562 struct iw_statistics
564 Note:
565 This function will be called when query /proc
567 ========================================================================
569 struct iw_statistics *RT2500_get_wireless_stats(
570 IN struct net_device *net_dev)
572 RTMP_ADAPTER *pAd = net_dev->priv;
574 DBGPRINT(RT_DEBUG_TRACE, "RT2500_get_wireless_stats --->\n");
576 // TODO: All elements are zero before be implemented
578 pAd->iw_stats.status = 0; // Status - device dependent for now
580 pAd->iw_stats.qual.qual = pAd->Mlme.ChannelQuality; // link quality (%retries, SNR, %missed beacons or better...)
581 pAd->iw_stats.qual.level = abs(pAd->PortCfg.LastRssi);; // signal level (dBm)
582 pAd->iw_stats.qual.level += 256 - RSSI_TO_DBM_OFFSET;
584 pAd->iw_stats.qual.noise = (pAd->PortCfg.LastR17Value > BBP_R17_DYNAMIC_UP_BOUND) ? BBP_R17_DYNAMIC_UP_BOUND : ((ULONG) pAd->PortCfg.LastR17Value);; // noise level (dBm)
585 pAd->iw_stats.qual.noise += 256 - 143;
586 pAd->iw_stats.qual.updated = 1; // Flags to know if updated
588 pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
589 pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
591 // pAd->iw_stats.discard.code, discard.fragment, discard.retries, discard.misc has counted in other place
593 return &pAd->iw_stats;
595 #endif
598 ========================================================================
600 Routine Description:
601 return ethernet statistics counter
603 Arguments:
604 net_dev Pointer to net_device
606 Return Value:
607 net_device_stats*
609 Note:
611 ========================================================================
613 struct net_device_stats *RT2500_get_ether_stats(
614 IN struct net_device *net_dev)
616 RTMP_ADAPTER *pAd = net_dev->priv;
618 DBGPRINT(RT_DEBUG_INFO, "RT2500_get_ether_stats --->\n");
620 pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.vv.LowPart; // total packets received
621 pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart; // total packets transmitted
623 pAd->stats.rx_bytes= pAd->RalinkCounters.ReceivedByteCount; // total bytes received
624 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount; // total bytes transmitted
626 pAd->stats.rx_errors = pAd->Counters.RxErrors; // bad packets received
627 pAd->stats.tx_errors = pAd->Counters.TxErrors; // packet transmit problems
629 pAd->stats.rx_dropped = pAd->Counters.RxNoBuffer; // no space in linux buffers
630 pAd->stats.tx_dropped = pAd->WlanCounters.FailedCount.vv.LowPart; // no space available in linux
632 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.vv.LowPart; // multicast packets received
633 pAd->stats.collisions = pAd->Counters.OneCollision + pAd->Counters.MoreCollisions; // Collision packets
635 pAd->stats.rx_length_errors = 0;
636 pAd->stats.rx_over_errors = pAd->Counters.RxNoBuffer; // receiver ring buff overflow
637 pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
638 pAd->stats.rx_frame_errors = pAd->Counters.RcvAlignmentErrors; // recv'd frame alignment error
639 pAd->stats.rx_fifo_errors = pAd->Counters.RxNoBuffer; // recv'r fifo overrun
640 pAd->stats.rx_missed_errors = 0; // receiver missed packet
642 // detailed tx_errors
643 pAd->stats.tx_aborted_errors = 0;
644 pAd->stats.tx_carrier_errors = 0;
645 pAd->stats.tx_fifo_errors = 0;
646 pAd->stats.tx_heartbeat_errors = 0;
647 pAd->stats.tx_window_errors = 0;
649 // for cslip etc
650 pAd->stats.rx_compressed = 0;
651 pAd->stats.tx_compressed = 0;
653 return &pAd->stats;
657 ========================================================================
659 Routine Description:
660 Set to filter multicast list
662 Arguments:
663 net_dev Pointer to net_device
665 Return Value:
666 VOID
668 Note:
670 ========================================================================
672 VOID RT2500_set_rx_mode(
673 IN struct net_device *net_dev)
675 // RTMP_ADAPTER *pAd = net_dev->priv;
676 // TODO: set_multicast_list
680 // Close driver function
682 INT RT2500_close(
683 IN struct net_device *net_dev)
685 RTMP_ADAPTER *pAd = net_dev->priv;
686 // LONG ioaddr = net_dev->base_addr;
688 DBGPRINT(RT_DEBUG_TRACE, "%s: ===> RT2500_close\n", net_dev->name);
690 // Stop Mlme state machine
691 RTMPCancelTimer(&pAd->PortCfg.RfTuningTimer);
692 MlmeHalt(pAd);
694 netif_stop_queue(net_dev);
695 netif_carrier_off(net_dev);
697 // Shut down monitor timer task
698 //RTMPCancelTimer(&pAd->timer);
700 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
702 NICDisableInterrupt(pAd);
705 // Disable Rx, register value supposed will remain after reset
706 NICIssueReset(pAd);
708 // Free IRQ
709 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
711 // Deregister interrupt function
712 free_irq(net_dev->irq, net_dev);
713 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
716 // Free Ring buffers
717 RTMPFreeDMAMemory(pAd);
719 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
720 module_put(THIS_MODULE);
721 #else
722 MOD_DEC_USE_COUNT;
723 #endif
725 return 0;
729 // Remove driver function
731 static VOID __devexit RT2500_remove_one(
732 IN struct pci_dev *pPci_Dev)
734 struct net_device *net_dev = pci_get_drvdata(pPci_Dev);
735 // RTMP_ADAPTER *pAd = net_dev->priv;
737 // Unregister network device
738 unregister_netdev(net_dev);
740 // Unmap CSR base address
741 iounmap((char *)(net_dev->base_addr));
743 // release memory region
744 release_mem_region(pci_resource_start(pPci_Dev, 0), pci_resource_len(pPci_Dev, 0));
746 // Free pre-allocated net_device memory
747 kfree(net_dev);
751 // Ralink PCI device table, include all supported chipsets
753 static struct pci_device_id rt2500_pci_tbl[] __devinitdata =
755 {0x1814, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RT2560A},
756 {0,} /* terminate list */
758 MODULE_DEVICE_TABLE(pci, rt2500_pci_tbl);
761 // Our PCI driver structure
763 static struct pci_driver rt2500_driver =
765 name: "rt2500",
766 id_table: rt2500_pci_tbl,
767 probe: RT2500_init_one,
768 #if LINUX_VERSION_CODE >= 0x20412 || BIG_ENDIAN == TRUE
769 remove: __devexit_p(RT2500_remove_one),
770 #else
771 remove: __devexit(RT2500_remove_one),
772 #endif
775 // =======================================================================
776 // LOAD / UNLOAD sections
777 // =======================================================================
779 // Driver module load function
781 static INT __init rt2500_init_module(VOID)
783 return pci_module_init(&rt2500_driver);
787 // Driver module unload function
789 static VOID __exit rt2500_cleanup_module(VOID)
791 pci_unregister_driver(&rt2500_driver);
794 module_init(rt2500_init_module);
795 module_exit(rt2500_cleanup_module);