1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
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. *
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. *
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. *
24 *************************************************************************
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
43 ULONG RTDebugLevel
= RT_DEBUG_TRACE
;
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");
56 extern const struct iw_handler_def rt2500_iw_handler_def
;
58 #if 1 // add by Victor Yu. 01-12-2006
59 #include <linux/kmod.h>
60 static void itfact(char *action
)
62 char *argv
[2], **envp
, *buf
, *scratch
;
67 if ( !current
->fs
->root
)
69 if ( !(envp
=(char **)kmalloc(10*sizeof(char *), GFP_KERNEL
)) )
71 if ( !(buf
=kmalloc(256, GFP_KERNEL
)) )
73 argv
[0] = "/bin/wirelesspnp";
76 envp
[i
++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
79 scratch
+= sprintf(scratch
, "ACTION=%s", action
) + 1;
81 call_usermodehelper(argv
[0], argv
, envp
, 0);
87 static INT __devinit
RT2500_init_one (
88 IN
struct pci_dev
*pPci_Dev
,
89 IN
const struct pci_device_id
*ent
)
93 // wake up and enable device
94 if (pci_enable_device (pPci_Dev
))
100 rc
= RT2500_probe(pPci_Dev
, ent
);
101 #if 1 // add by Victor Yu. 01-12-2006
109 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
110 static struct net_device
*alloc_netdev(int sizeof_priv
, const char *mask
, void (*setup
)(struct net_device
*))
112 struct net_device
*dev
;
115 /* ensure 32-byte alignment of the private area */
116 alloc_size
= sizeof (*dev
) + sizeof_priv
+ 31;
118 dev
= (struct net_device
*) kmalloc (alloc_size
, GFP_KERNEL
);
121 DBGPRINT(RT_DEBUG_ERROR
, "alloc_netdev: Unable to allocate device memory.\n");
125 memset(dev
, 0, alloc_size
);
128 dev
->priv
= (void *) (((long)(dev
+ 1) + 31) & ~31);
131 strcpy(dev
->name
,mask
);
138 // PCI device probe & initialization function
140 INT __devinit
RT2500_probe(
141 IN
struct pci_dev
*pPci_Dev
,
142 IN
const struct pci_device_id
*ent
)
144 struct net_device
*net_dev
;
147 INT chip_id
= (int) ent
->driver_data
;
148 unsigned long csr_addr
;
149 CSR3_STRUC StaMacReg0
;
150 CSR4_STRUC StaMacReg1
;
153 print_name
= pPci_Dev
? pci_name(pPci_Dev
) : "rt2500";
155 #if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
156 net_dev
= alloc_netdev(sizeof(RTMP_ADAPTER
), "eth%d", ether_setup
);
158 net_dev
= alloc_etherdev(sizeof(RTMP_ADAPTER
));
162 DBGPRINT(RT_DEBUG_TRACE
, "init_ethernet failed\n");
166 SET_MODULE_OWNER(net_dev
);
168 if (pci_request_regions(pPci_Dev
, print_name
))
169 goto err_out_free_netdev
;
171 // Interrupt IRQ number
172 net_dev
->irq
= pPci_Dev
->irq
;
174 // map physical address to virtual address for accessing register
175 csr_addr
= (unsigned long) ioremap(pci_resource_start(pPci_Dev
, 0), pci_resource_len(pPci_Dev
, 0));
178 DBGPRINT(RT_DEBUG_TRACE
, "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
179 pPci_Dev
->slot_name
, (ULONG
)pci_resource_len(pPci_Dev
, 0), pci_resource_start(pPci_Dev
, 0));
180 goto err_out_free_res
;
183 // Save CSR virtual address and irq to device structure
184 net_dev
->base_addr
= csr_addr
;
186 pAd
->CSRBaseAddress
= net_dev
->base_addr
;
187 pAd
->net_dev
= net_dev
;
190 pci_set_master(pPci_Dev
);
193 NICReadAdapterInfo(pAd
);
195 RTMP_IO_READ32(pAd
, CSR3
, &StaMacReg0
.word
);
196 RTMP_IO_READ32(pAd
, CSR4
, &StaMacReg1
.word
);
197 net_dev
->dev_addr
[0] = StaMacReg0
.field
.Byte0
;
198 net_dev
->dev_addr
[1] = StaMacReg0
.field
.Byte1
;
199 net_dev
->dev_addr
[2] = StaMacReg0
.field
.Byte2
;
200 net_dev
->dev_addr
[3] = StaMacReg0
.field
.Byte3
;
201 net_dev
->dev_addr
[4] = StaMacReg1
.field
.Byte4
;
202 net_dev
->dev_addr
[5] = StaMacReg1
.field
.Byte5
;
204 pAd
->chip_id
= chip_id
;
205 pAd
->pPci_Dev
= pPci_Dev
;
207 // The chip-specific entries in the device structure.
208 net_dev
->open
= RT2500_open
;
209 net_dev
->hard_start_xmit
= RTMPSendPackets
;
210 net_dev
->stop
= RT2500_close
;
211 net_dev
->get_stats
= RT2500_get_ether_stats
;
213 #if WIRELESS_EXT >= 12
214 net_dev
->get_wireless_stats
= RT2500_get_wireless_stats
;
215 net_dev
->wireless_handlers
= (struct iw_handler_def
*) &rt2500_iw_handler_def
;
218 net_dev
->set_multicast_list
= RT2500_set_rx_mode
;
219 net_dev
->do_ioctl
= RT2500_ioctl
;
221 #ifdef CONFIG_ARCH_MOXACPU // add by Victor Yu. 01-11-2006
222 sprintf(net_dev
->name
, "eth2");
226 char slot_name
[IFNAMSIZ
];
227 struct net_device
*device
;
229 for (i
= 0; i
< 8; i
++)
231 sprintf(slot_name
, "ra%d", i
);
233 for (device
= dev_base
; device
!= NULL
; device
= device
->next
)
235 if (strncmp(device
->name
, slot_name
, 4) == 0)
240 if(device
== NULL
) break;
244 DBGPRINT(RT_DEBUG_ERROR
, "No available slot name\n");
248 sprintf(net_dev
->name
, "ra%d", i
);
251 // Register this device
252 Status
= register_netdev(net_dev
);
256 DBGPRINT(RT_DEBUG_TRACE
, "%s: at 0x%lx, VA 0x%1x, IRQ %d. \n",
257 net_dev
->name
, pci_resource_start(pPci_Dev
, 0), (ULONG
)csr_addr
, pPci_Dev
->irq
);
260 pci_set_drvdata(pPci_Dev
, net_dev
);
265 iounmap((void *)csr_addr
);
266 release_mem_region(pci_resource_start(pPci_Dev
, 0), pci_resource_len(pPci_Dev
, 0));
268 pci_release_regions(pPci_Dev
);
276 IN
struct net_device
*net_dev
)
278 PRTMP_ADAPTER pAd
= net_dev
->priv
;
279 INT status
= NDIS_STATUS_SUCCESS
;
281 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
282 if (!try_module_get(THIS_MODULE
))
284 DBGPRINT(RT_DEBUG_ERROR
, "%s: cannot reserve module\n", __FUNCTION__
);
291 // 1. Allocate DMA descriptors & buffers
292 status
= RTMPAllocDMAMemory(pAd
);
293 if (status
!= NDIS_STATUS_SUCCESS
)
296 // 2. request interrupt\x14
297 // Disable interrupts here which is as soon as possible
298 // This statement should never be true. We might consider to remove it later
299 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
))
301 NICDisableInterrupt(pAd
);
304 status
= request_irq(pAd
->pPci_Dev
->irq
, &RTMPIsr
, SA_SHIRQ
, net_dev
->name
, net_dev
);
307 RTMPFreeDMAMemory(pAd
);
310 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
312 // 3. Read MAC address
313 //NICReadAdapterInfo(pAd);
315 DBGPRINT(RT_DEBUG_TRACE
, "%s: RT2500_open() irq %d. MAC = %02x:%02x:%02x:%02x:%02x:%02x \n",
316 net_dev
->name
, pAd
->pPci_Dev
->irq
, pAd
->CurrentAddress
[0], pAd
->CurrentAddress
[1], pAd
->CurrentAddress
[2],
317 pAd
->CurrentAddress
[3], pAd
->CurrentAddress
[4], pAd
->CurrentAddress
[5]);
319 NICInitTransmit(pAd
);
321 // manufacture default
324 // Read RaConfig profile parameters
325 RTMPReadParametersFromFile(pAd
);
328 status
= MlmeInit(pAd
);
330 // Initialize Mlme Memory Handler
331 // Allocate 20 nonpaged memory pool which size are MAX_LEN_OF_MLME_BUFFER for use
332 status
= MlmeInitMemoryHandler(pAd
, 20, MAX_LEN_OF_MLME_BUFFER
);
334 if(status
!= NDIS_STATUS_SUCCESS
)
336 free_irq(net_dev
->irq
, net_dev
);
337 RTMPFreeDMAMemory(pAd
);
342 NICInitializeAdapter(pAd
);
344 NICReadEEPROMParameters(pAd
);
346 NICInitAsicFromEEPROM(pAd
);
348 // 2nd stage hardware initialization after all parameters are acquired from
349 // Registry or E2PROM
350 RTMPSetPhyMode(pAd
, PHY_11BG_MIXED
);
352 // Set the timer to check for link beat.
353 /* RTMPInitTimer(pAd, &pAd->timer, RT2500_timer);
354 RTMPSetTimer(pAd, &pAd->timer, DEBUG_TASK_DELAY);*/
357 NICEnableInterrupt(pAd
);
359 // Start net interface tx /rx
360 netif_start_queue(net_dev
);
362 netif_carrier_on(net_dev
);
363 netif_wake_queue(net_dev
);
368 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
369 module_put(THIS_MODULE
);
378 IN
unsigned long data
)
380 RTMP_ADAPTER
*pAd
= (RTMP_ADAPTER
*)data
;
382 // NICCheckForHang(pAd);
384 RTMPSetTimer(pAd
, &pAd
->timer
, DEBUG_TASK_DELAY
);
388 ========================================================================
391 hard_start_xmit handler
394 skb point to sk_buf which upper layer transmit
395 net_dev point to net_dev
401 ========================================================================
404 IN
struct sk_buff
*skb
,
405 IN
struct net_device
*net_dev
)
407 NDIS_STATUS Status
= NDIS_STATUS_SUCCESS
;
408 PRTMP_ADAPTER pAdapter
= net_dev
->priv
;
410 DBGPRINT(RT_DEBUG_INFO
, "<==== RTMPSendPackets\n");
412 // Drop packets if no associations
413 if (!INFRA_ON(pAdapter
) && !ADHOC_ON(pAdapter
))
415 // Drop send request since there are no physical connection yet
416 // Check the association status for infrastructure mode
417 // And Mibss for Ad-hoc mode setup
418 RTMPFreeSkbBuffer(skb
);
422 // This function has to manage NdisSendComplete return call within its routine
423 // NdisSendComplete will acknowledge upper layer in two steps.
424 // 1. Within Packet Enqueue, set the NDIS_STATUS_PENDING
425 // 2. Within TxRingTxDone / PrioRingTxDone call NdisSendComplete with final status
426 // initial skb->data_len=0, we will use this variable to store data size when fragment(in TKIP)
427 // and skb->len is actual data len
428 skb
->data_len
= skb
->len
;
429 Status
= RTMPSendPacket(pAdapter
,skb
);
431 if (Status
!= NDIS_STATUS_SUCCESS
)
433 // Errors before enqueue stage
434 RTMPFreeSkbBuffer(skb
);
438 // Dequeue one frame from SendTxWait queue and process it
439 // There are two place calling dequeue for TX ring.
440 // 1. Here, right after queueing the frame.
441 // 2. At the end of TxRingTxDone service routine.
442 if ((!RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS
)) &&
443 (!RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_RADIO_OFF
)) &&
444 (!RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_RESET_IN_PROGRESS
)))
446 //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);
447 // Call dequeue without selected queue, let the subroutine select the right priority
449 RTMPDeQueuePacket(pAdapter
);
456 ========================================================================
463 dev_instance Pointer to net_device
464 rgs store process's context before entering ISR,
465 this parameter is just for debug purpose.
472 ========================================================================
474 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
481 IN VOID
*dev_instance
,
482 IN
struct pt_regs
*rgs
)
484 struct net_device
*net_dev
= dev_instance
;
485 PRTMP_ADAPTER pAdapter
= net_dev
->priv
;
486 INTSRC_STRUC IntSource
;
488 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleInterrupt\n");
490 // 1. Disable interrupt
491 if (RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_INTERRUPT_IN_USE
) && RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
))
493 NICDisableInterrupt(pAdapter
);
497 // Get the interrupt sources & saved to local variable
499 // RTMP_IO_READ32(pAdapter, CSR7, &IntSource);
500 RTMP_IO_READ32(pAdapter
, CSR7
, &IntSource
.word
);
501 RTMP_IO_WRITE32(pAdapter
, CSR7
, IntSource
.word
);
504 // Handle interrupt, walk through all bits
505 // Should start from highest priority interrupt
506 // The priority can be adjust by altering processing if statement
508 // If required spinlock, each interrupt service routine has to acquire
509 // and release itself.
511 if (IntSource
.field
.TbcnExpire
)
513 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleTbcnInterrupt\n");
514 RTMPHandleTbcnInterrupt(pAdapter
);
517 if (IntSource
.field
.TwakeExpire
)
519 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleTwakeupInterrupt\n");
520 RTMPHandleTwakeupInterrupt(pAdapter
);
523 if (IntSource
.field
.TatimwExpire
)
525 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleTatimInterrupt\n");
526 // RTMPHandleTatimInterrupt(pAdapter);
529 if (IntSource
.field
.EncryptionDone
)
531 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleEncryptionDoneInterrupt\n");
532 RTMPHandleEncryptionDoneInterrupt(pAdapter
);
535 if (IntSource
.field
.TxRingTxDone
)
537 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleTxRingTxDoneInterrupt\n");
538 RTMPHandleTxRingTxDoneInterrupt(pAdapter
);
541 if (IntSource
.field
.AtimRingTxDone
)
543 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleAtimRingTxDoneInterrupt\n");
544 RTMPHandleAtimRingTxDoneInterrupt(pAdapter
);
547 if (IntSource
.field
.PrioRingTxDone
)
549 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandlePrioRingTxDoneInterrupt\n");
550 RTMPHandlePrioRingTxDoneInterrupt(pAdapter
);
553 if (IntSource
.field
.DecryptionDone
)
555 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleDecryptionDoneInterrupt\n");
556 RTMPHandleDecryptionDoneInterrupt(pAdapter
);
559 if (IntSource
.field
.RxDone
)
561 DBGPRINT(RT_DEBUG_INFO
, "====> RTMPHandleRxDoneInterrupt\n");
562 RTMPHandleRxDoneInterrupt(pAdapter
);
563 RTMPHandleEncryptionDoneInterrupt(pAdapter
);
566 // Do nothing if Reset in progress
567 if (RTMP_TEST_FLAG(pAdapter
, fRTMP_ADAPTER_RESET_IN_PROGRESS
))
569 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
577 // Re-enable the interrupt (disabled in RTMPIsr)
579 NICEnableInterrupt(pAdapter
);
581 DBGPRINT(RT_DEBUG_INFO
, "<==== RTMPHandleInterrupt\n");
582 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
587 #if WIRELESS_EXT >= 12
589 ========================================================================
592 get wireless statistics
595 net_dev Pointer to net_device
601 This function will be called when query /proc
603 ========================================================================
605 struct iw_statistics
*RT2500_get_wireless_stats(
606 IN
struct net_device
*net_dev
)
608 RTMP_ADAPTER
*pAd
= net_dev
->priv
;
610 DBGPRINT(RT_DEBUG_TRACE
, "RT2500_get_wireless_stats --->\n");
612 // TODO: All elements are zero before be implemented
614 pAd
->iw_stats
.status
= 0; // Status - device dependent for now
616 pAd
->iw_stats
.qual
.qual
= pAd
->Mlme
.ChannelQuality
; // link quality (%retries, SNR, %missed beacons or better...)
617 pAd
->iw_stats
.qual
.level
= abs(pAd
->PortCfg
.LastRssi
);; // signal level (dBm)
618 pAd
->iw_stats
.qual
.level
+= 256 - RSSI_TO_DBM_OFFSET
;
620 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)
621 pAd
->iw_stats
.qual
.noise
+= 256 - 143;
622 pAd
->iw_stats
.qual
.updated
= 1; // Flags to know if updated
624 pAd
->iw_stats
.discard
.nwid
= 0; // Rx : Wrong nwid/essid
625 pAd
->iw_stats
.miss
.beacon
= 0; // Missed beacons/superframe
627 // pAd->iw_stats.discard.code, discard.fragment, discard.retries, discard.misc has counted in other place
629 return &pAd
->iw_stats
;
634 ========================================================================
637 return ethernet statistics counter
640 net_dev Pointer to net_device
647 ========================================================================
649 struct net_device_stats
*RT2500_get_ether_stats(
650 IN
struct net_device
*net_dev
)
652 RTMP_ADAPTER
*pAd
= net_dev
->priv
;
654 DBGPRINT(RT_DEBUG_INFO
, "RT2500_get_ether_stats --->\n");
656 pAd
->stats
.rx_packets
= pAd
->WlanCounters
.ReceivedFragmentCount
.vv
.LowPart
; // total packets received
657 pAd
->stats
.tx_packets
= pAd
->WlanCounters
.TransmittedFragmentCount
.vv
.LowPart
; // total packets transmitted
659 pAd
->stats
.rx_bytes
= pAd
->RalinkCounters
.ReceivedByteCount
; // total bytes received
660 pAd
->stats
.tx_bytes
= pAd
->RalinkCounters
.TransmittedByteCount
; // total bytes transmitted
662 pAd
->stats
.rx_errors
= pAd
->Counters
.RxErrors
; // bad packets received
663 pAd
->stats
.tx_errors
= pAd
->Counters
.TxErrors
; // packet transmit problems
665 pAd
->stats
.rx_dropped
= pAd
->Counters
.RxNoBuffer
; // no space in linux buffers
666 pAd
->stats
.tx_dropped
= pAd
->WlanCounters
.FailedCount
.vv
.LowPart
; // no space available in linux
668 pAd
->stats
.multicast
= pAd
->WlanCounters
.MulticastReceivedFrameCount
.vv
.LowPart
; // multicast packets received
669 pAd
->stats
.collisions
= pAd
->Counters
.OneCollision
+ pAd
->Counters
.MoreCollisions
; // Collision packets
671 pAd
->stats
.rx_length_errors
= 0;
672 pAd
->stats
.rx_over_errors
= pAd
->Counters
.RxNoBuffer
; // receiver ring buff overflow
673 pAd
->stats
.rx_crc_errors
= 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
674 pAd
->stats
.rx_frame_errors
= pAd
->Counters
.RcvAlignmentErrors
; // recv'd frame alignment error
675 pAd
->stats
.rx_fifo_errors
= pAd
->Counters
.RxNoBuffer
; // recv'r fifo overrun
676 pAd
->stats
.rx_missed_errors
= 0; // receiver missed packet
678 // detailed tx_errors
679 pAd
->stats
.tx_aborted_errors
= 0;
680 pAd
->stats
.tx_carrier_errors
= 0;
681 pAd
->stats
.tx_fifo_errors
= 0;
682 pAd
->stats
.tx_heartbeat_errors
= 0;
683 pAd
->stats
.tx_window_errors
= 0;
686 pAd
->stats
.rx_compressed
= 0;
687 pAd
->stats
.tx_compressed
= 0;
693 ========================================================================
696 Set to filter multicast list
699 net_dev Pointer to net_device
706 ========================================================================
708 VOID
RT2500_set_rx_mode(
709 IN
struct net_device
*net_dev
)
711 // RTMP_ADAPTER *pAd = net_dev->priv;
712 // TODO: set_multicast_list
716 // Close driver function
719 IN
struct net_device
*net_dev
)
721 RTMP_ADAPTER
*pAd
= net_dev
->priv
;
722 // LONG ioaddr = net_dev->base_addr;
724 DBGPRINT(RT_DEBUG_TRACE
, "%s: ===> RT2500_close\n", net_dev
->name
);
726 // Stop Mlme state machine
727 RTMPCancelTimer(&pAd
->PortCfg
.RfTuningTimer
);
730 netif_stop_queue(net_dev
);
731 netif_carrier_off(net_dev
);
733 // Shut down monitor timer task
734 //RTMPCancelTimer(&pAd->timer);
736 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
))
738 NICDisableInterrupt(pAd
);
741 // Disable Rx, register value supposed will remain after reset
745 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
))
747 // Deregister interrupt function
748 free_irq(net_dev
->irq
, net_dev
);
749 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
753 RTMPFreeDMAMemory(pAd
);
755 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
756 module_put(THIS_MODULE
);
765 // Remove driver function
767 static VOID __devexit
RT2500_remove_one(
768 IN
struct pci_dev
*pPci_Dev
)
770 struct net_device
*net_dev
= pci_get_drvdata(pPci_Dev
);
771 // RTMP_ADAPTER *pAd = net_dev->priv;
772 #if 1 // add by Victor Yu. 01-12-2006
775 // Unregister network device
776 unregister_netdev(net_dev
);
778 // Unmap CSR base address
779 iounmap((char *)(net_dev
->base_addr
));
781 // release memory region
782 release_mem_region(pci_resource_start(pPci_Dev
, 0), pci_resource_len(pPci_Dev
, 0));
784 // Free pre-allocated net_device memory
789 // Ralink PCI device table, include all supported chipsets
791 static struct pci_device_id rt2500_pci_tbl
[] __devinitdata
=
793 {0x1814, 0x0201, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, RT2560A
},
794 {0,} /* terminate list */
796 MODULE_DEVICE_TABLE(pci
, rt2500_pci_tbl
);
799 // Our PCI driver structure
801 static struct pci_driver rt2500_driver
=
804 id_table
: rt2500_pci_tbl
,
805 probe
: RT2500_init_one
,
806 #if LINUX_VERSION_CODE >= 0x20412 || BIG_ENDIAN == TRUE
807 remove
: __devexit_p(RT2500_remove_one
),
809 remove
: __devexit(RT2500_remove_one
),
813 // =======================================================================
814 // LOAD / UNLOAD sections
815 // =======================================================================
817 // Driver module load function
819 static INT __init
rt2500_init_module(VOID
)
821 return pci_module_init(&rt2500_driver
);
825 // Driver module unload function
827 static VOID __exit
rt2500_cleanup_module(VOID
)
829 pci_unregister_driver(&rt2500_driver
);
832 module_init(rt2500_init_module
);
833 module_exit(rt2500_cleanup_module
);