⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt_main_dev.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify  *  * it under the terms of the GNU General Public License as published by  *  * the Free Software Foundation; either version 2 of the License, or     *  * (at your option) any later version.                                   *  *                                                                       *  * This program is distributed in the hope that it will be useful,       *  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *  * GNU General Public License for more details.                          *  *                                                                       *  * You should have received a copy of the GNU General Public License     *  * along with this program; if not, write to the                         *  * Free Software Foundation, Inc.,                                       *  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *  *                                                                       *  ************************************************************************* */#include <rt_config.h>#define FORTY_MHZ_INTOLERANT_INTERVAL	(60*1000) // 1 minstatic void rx_done_tasklet(unsigned long data);static void mgmt_dma_done_tasklet(unsigned long data);static void ac0_dma_done_tasklet(unsigned long data);static void ac1_dma_done_tasklet(unsigned long data);static void ac2_dma_done_tasklet(unsigned long data);static void ac3_dma_done_tasklet(unsigned long data);static void hcca_dma_done_tasklet(unsigned long data);static void fifo_statistic_full_tasklet(unsigned long data);/*---------------------------------------------------------------------*//* Symbol & Macro Definitions                                          *//*---------------------------------------------------------------------*/#define RT2860_INT_RX_DLY				(1<<0)		// bit 0	#define RT2860_INT_TX_DLY				(1<<1)		// bit 1#define RT2860_INT_RX_DONE				(1<<2)		// bit 2#define RT2860_INT_AC0_DMA_DONE			(1<<3)		// bit 3#define RT2860_INT_AC1_DMA_DONE			(1<<4)		// bit 4#define RT2860_INT_AC2_DMA_DONE			(1<<5)		// bit 5#define RT2860_INT_AC3_DMA_DONE			(1<<6)		// bit 6#define RT2860_INT_HCCA_DMA_DONE		(1<<7)		// bit 7#define RT2860_INT_MGMT_DONE			(1<<8)		// bit 8#define INT_RX			RT2860_INT_RX_DONE#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)#define INT_HCCA_DLY 	(RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE#ifdef CONFIG_STA_SUPPORTextern	const struct iw_handler_def rt2860_iw_handler_def;#if WIRELESS_EXT >= 12// This function will be called when query /procstruct iw_statistics *rt2860_get_wireless_stats(    IN struct net_device *net_dev);#endif#endif // CONFIG_STA_SUPPORT ///*---------------------------------------------------------------------*//* Prototypes of External Functions                                    *//*---------------------------------------------------------------------*//*---------------------------------------------------------------------*//* Prototypes of Functions Used                                        *//*---------------------------------------------------------------------*//* function declarations */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)irqreturn_t#elsevoid#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)rt2860_interrupt(int irq, void *dev_instance);#elsert2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);#endifstatic int rt2860_open(struct net_device *net_dev);static int rt2860_close(struct net_device *net_dev);static int rt2860_send_packets(struct sk_buff *skb, struct net_device *net_dev);static int rt2860_init(struct net_device *net_dev);static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id  *ent);static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);void kill_thread_task(PRTMP_ADAPTER pAd);void init_thread_task(PRTMP_ADAPTER pAd);static void __exit rt2860_cleanup_module(void);static int __init rt2860_init_module(void);extern INT rt2860_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd);static VOID rt2860_set_rx_mode(IN struct net_device *net_dev);struct net_device_stats *rt2860_get_ether_stats(IN struct net_device *net_dev);/*---------------------------------------------------------------------*//* External Variable Definitions                                       *//*---------------------------------------------------------------------*///// Ralink PCI device table, include all supported chipsets//static struct pci_device_id rt2860_pci_tbl[] __devinitdata ={	{0x1814, 0x0601, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},		//RT28602.4G	{0x1814, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{0x1814, 0x0781, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},    {0,}		// terminate list};MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);//// Our PCI driver structure//static struct pci_driver rt2860_driver ={    name:       "rt2860",    id_table:   rt2860_pci_tbl,    probe:      rt2860_init_one,#if LINUX_VERSION_CODE >= 0x20412    remove:     __devexit_p(rt2860_remove_one),#else    remove:     __devexit(rt2860_remove_one),#endif};static INT __init rt2860_init_module(VOID){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	return pci_register_driver(&rt2860_driver);#else    return pci_module_init(&rt2860_driver);#endif}//// Driver module unload function//static VOID __exit rt2860_cleanup_module(VOID){    pci_unregister_driver(&rt2860_driver);}module_init(rt2860_init_module);module_exit(rt2860_cleanup_module);static INT __devinit rt2860_init_one (    IN  struct pci_dev              *pci_dev,    IN  const struct pci_device_id  *ent){    INT rc;    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n"));    // wake up and enable device    if (pci_enable_device (pci_dev))    {        rc = -EIO;    }    else    {        rc = rt2860_probe(pci_dev, ent);    }    DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n"));    return rc;}static VOID __devexit rt2860_remove_one(    IN  struct pci_dev  *pci_dev){    struct net_device   *net_dev = pci_get_drvdata(pci_dev);    RTMP_ADAPTER        *pAd = net_dev->priv;    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));	if (pAd != NULL)	{            // Unregister network device        unregister_netdev(net_dev);        // Unmap CSR base address        iounmap((char *)(net_dev->base_addr));    	RTMPFreeAdapter(pAd);        // release memory region        release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));	}	else	{	    // Unregister network device    	unregister_netdev(net_dev);	    // Unmap CSR base address    	iounmap((char *)(net_dev->base_addr));	    // release memory region    	release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));	}    // Free pre-allocated net_device memory#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)    free_netdev(net_dev);#else	kfree(net_dev);#endif}//// PCI device probe & initialization function//static INT __devinit   rt2860_probe(    IN  struct pci_dev              *pci_dev,     IN  const struct pci_device_id  *ent){    struct  net_device      *net_dev;    PRTMP_ADAPTER           pAd;    CHAR                    *print_name;    ULONG                   csr_addr;    INT                     status;	PVOID					handle;	//#define DRIVER_VERSION "0.1"	    DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", DRIVER_VERSION));#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)    print_name = pci_dev ? pci_name(pci_dev) : "rt2860";#else    print_name = pci_dev ? pci_dev->slot_name : "rt2860";#endif#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1    net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);#else    net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));#endif    if (net_dev == NULL)     {        DBGPRINT(RT_DEBUG_TRACE, ("init_ethernet failed\n"));        goto err_out;    }    SET_MODULE_OWNER(net_dev);#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT/* for supporting Network Manager *//* Set the sysfs physical device reference for the network logical device * if set prior to registration will cause a symlink during initialization. */#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))    SET_NETDEV_DEV(net_dev, &(pci_dev->dev));#endif#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //            if (pci_request_regions(pci_dev, print_name))        goto err_out_free_netdev;    // Interrupt IRQ number    net_dev->irq = pci_dev->irq;    // map physical address to virtual address for accessing register    csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));    if (!csr_addr)     {        DBGPRINT(RT_DEBUG_ERROR, ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",            print_name, (ULONG)pci_resource_len(pci_dev, 0), pci_resource_start(pci_dev, 0)));        goto err_out_free_res;    }	// Allocate RTMP_ADAPTER miniport adapter structure		handle = kmalloc(sizeof(struct os_cookie) , GFP_KERNEL);		((POS_COOKIE)handle)->pci_dev = pci_dev;	status = RTMPAllocAdapterBlock(handle, &pAd);		if (status != NDIS_STATUS_SUCCESS) 	{		goto err_out_free_res;	}	net_dev->priv = (PVOID)pAd;    // Save CSR virtual address and irq to device structure    net_dev->base_addr = csr_addr;    pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr;    pAd->net_dev = net_dev;    // Set DMA master    pci_set_master(pci_dev);    // The chip-specific entries in the device structure.    net_dev->open = rt2860_open;    //net_dev->hard_start_xmit = rt2860_packet_xmit;    net_dev->hard_start_xmit = rt2860_send_packets;	net_dev->do_ioctl = rt2860_ioctl;    net_dev->stop = rt2860_close;    net_dev->priv_flags = INT_MAIN;		net_dev->get_stats = rt2860_get_ether_stats;	#ifdef CONFIG_STA_SUPPORT#if WIRELESS_EXT >= 12#if IW_HANDLER_VERSION < 7    net_dev->get_wireless_stats = rt2860_get_wireless_stats;#endif // IW_HANDLER_VERSION < 7 //    net_dev->wireless_handlers = (struct iw_handler_def *) &rt2860_iw_handler_def;#endif // WIRELESS_EXT >= 12 //    pAd->StaCfg.OriDevType = net_dev->type;#endif // CONFIG_STA_SUPPORT //	net_dev->set_multicast_list = rt2860_set_rx_mode;      //net_dev->priv_flags = INT_MAIN;    {// find available         INT     i=0;        CHAR    slot_name[IFNAMSIZ];        struct net_device   *device;        for (i = 0; i < 8; i++)        {            sprintf(slot_name, "ra%d", i);            #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)			device = dev_get_by_name(slot_name);#else            for (device = dev_base; device != NULL; device = device->next)            {                if (strncmp(device->name, slot_name, 4) == 0)                {                    break;                }            }#endif            if(device == NULL)  break;        }        if(i == 8)        {            DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));            goto err_out_unmap;        }        sprintf(net_dev->name, "ra%d", i);    }    // Register this device    status = register_netdev(net_dev);    if (status)        goto err_out_unmap;    DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",         net_dev->name, pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq));    // Set driver data    pci_set_drvdata(pci_dev, net_dev);    return 0;err_out_unmap:    iounmap((void *)csr_addr);    release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));err_out_free_res:    pci_release_regions(pci_dev);err_out_free_netdev:    kfree (net_dev);err_out:    return -ENODEV;}static int rt2860_close(IN struct net_device *net_dev){    RTMP_ADAPTER    *pAd = net_dev->priv;    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_close\n"));	if (pAd == NULL)		return 0;#ifdef CONFIG_STA_SUPPORT#ifdef WPA_SUPPLICANT_SUPPORT#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT    if (pAd->StaCfg.WpaSupplicantUP) {        union iwreq_data    wrqu;        // send wireless event to wpa_supplicant for infroming interface down.        memset(&wrqu, 0, sizeof(wrqu));        wrqu.data.flags = RT_INTERFACE_DOWN;        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);    } #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //#endif // WPA_SUPPLICANT_SUPPORT //    // If dirver doesn't wake up firmware here,    // NICLoadFirmware will hang forever when interface is up again.    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))		AsicForceWakeup(pAd);#endif // CONFIG_STA_SUPPORT //	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);	kill_thread_task(pAd);    // Stop Mlme state machine

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -