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

📄 rtusb_main.c

📁 华硕无线网卡 167G linux 驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************  * RT2x00 SourceForge Project - http://rt2x00.sourceforge.net              *  *                                                                         *  *   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.             *  *                                                                         *  *   Licensed under the GNU GPL                                            *  *   Original code supplied under license from RaLink Inc, 2004.           *  ***************************************************************************//***************************************************************************  *	Module Name:	rtusb_main.c * *	Abstract: * *	Revision History: *	Who		When		What *	--------	----------	------------------------------- *	Name		Date		Modification logs *	Jan Lee		2005-06-01	Release *	RobinC		02-06-2005	usb_kill_urb fixes for kernels =>2.6.7 ***************************************************************************/#include "rt_config.h"#include <linux/ethtool.h>unsigned long flagg;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)ULONG	debug = RT_DEBUG_OFF;MODULE_PARM(debug, "i");MODULE_PARM_DESC(debug, "Enable level: accepted values: 1 to switch debug on, 0 to switch debug off.");#elseULONG	debug = RT_DEBUG_OFF;module_param(debug, int, 0);MODULE_PARM_DESC(debug, "Enable level: accepted values: 1 to switch debug on, 0 to switch debug off.");#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */#define KERNEL_20424	0x20418#define KERNEL_20418	0x20412#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)/* Kernel thread and vars, which handles packets that are completed. Only * packets that have a "complete" function are sent here. This way, the * completion is run out of kernel context, and doesn't block the rest of * the stack. */static int mlme_kill;static int RTUSBCmd_kill;#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) */extern	const struct iw_handler_def rt2500usb_iw_handler_def;static struct usb_device_id rtusb_usb_id[] =	RTUSB_DEVICES;/* the number of entries in array above */int const rtusb_usb_id_len =	sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);#ifndef PF_NOFREEZE#define PF_NOFREEZE  0#endif/* * Register layout information. */#define CSR_REG_BASE			0x0400#define CSR_REG_SIZE			0x00ff#define EEPROM_BASE			0x0000#define EEPROM_SIZE			0x006a#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)static voidrt2x00_get_drvinfo(struct net_device *net_dev,	struct ethtool_drvinfo *drvinfo){	PRT2570ADAPTER   pAd = net_dev->priv;	strcpy(drvinfo->driver, NIC_DEVICE_NAME);	strcpy(drvinfo->version, DRV_VERSION);	strcpy(drvinfo->bus_info, pAd->usb->dev.bus_id);}static intrt2x00_get_regs_len(struct net_device *net_dev){	return CSR_REG_SIZE;}static voidrt2x00_get_regs(struct net_device *net_dev,	struct ethtool_regs *regs, void *data){	PRT2570ADAPTER   pAd = net_dev->priv;	unsigned int counter;	regs->len = CSR_REG_SIZE;	for (counter = 0; counter < CSR_REG_SIZE; counter += sizeof(u16)) {		RTUSBReadMACRegister(pAd, CSR_REG_BASE + counter, (u16*)data);		data += sizeof(u16);	}}static intrt2x00_get_eeprom_len(struct net_device *net_dev){	return EEPROM_SIZE;}static intrt2x00_get_eeprom(struct net_device *net_dev,	struct ethtool_eeprom *eeprom, u8 *data){	PRT2570ADAPTER   pAd = net_dev->priv;	RTUSBReadEEPROM(pAd, CSR_REG_BASE, data, eeprom->len);	return 0;}static struct ethtool_ops rt2x00_ethtool_ops = {	.get_drvinfo	= rt2x00_get_drvinfo,	.get_regs_len	= rt2x00_get_regs_len,	.get_regs	= rt2x00_get_regs,	.get_link	= ethtool_op_get_link,	.get_eeprom_len	= rt2x00_get_eeprom_len,	.get_eeprom	= rt2x00_get_eeprom,};#endif/**************************************************************************//**************************************************************************///tested for kernel 2.4 series/**************************************************************************//**************************************************************************/#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static void usb_rtusb_disconnect(struct usb_device *dev, void *ptr);static void *usb_rtusb_probe(struct usb_device *dev, UINT interface,				const struct usb_device_id *id_table);struct usb_driver rtusb_driver = {		name:"rt2500usb",		probe:usb_rtusb_probe,		disconnect:usb_rtusb_disconnect,		id_table:rtusb_usb_id,	};#else/**************************************************************************//**************************************************************************///tested for kernel 2.6series/**************************************************************************//**************************************************************************/static int usb_rtusb_probe (struct usb_interface *intf,					  const struct usb_device_id *id);static void usb_rtusb_disconnect(struct usb_interface *intf);struct usb_driver rtusb_driver = {#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) 	.owner =	THIS_MODULE,#endif	.name="rt2570",	.probe=usb_rtusb_probe,	.disconnect=usb_rtusb_disconnect,	.id_table=rtusb_usb_id,	};#endif//static void USB_RxPacketComplete_bh(unsigned long data)//{//	RTUSBRxPacket(data);//}#if 0#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)static inline unsigned int jiffies_to_msecs(const unsigned long j){#if HZ <= 1000 && !(1000 % HZ)         return (1000 / HZ) * j;#elif HZ > 1000 && !(HZ % 1000)         return (j + (HZ / 1000) - 1)/(HZ / 1000);#else         return (j * 1000) / HZ;#endif}static inline unsigned long msecs_to_jiffies(const unsigned int m){         if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))                 return MAX_JIFFY_OFFSET;#if HZ <= 1000 && !(1000 % HZ)         return (m + (1000 / HZ) - 1) / (1000 / HZ);#elif HZ > 1000 && !(HZ % 1000)         return m * (HZ / 1000); #else         return (m * HZ + 999) / 1000; #endif}/*** msleep - sleep safely even with waitqueue interruptions* @msecs: Time in milliseconds to sleep for*/ void msleep(unsigned int msecs){	unsigned long timeout = msecs_to_jiffies(msecs) + 1;	while (timeout)	{		set_current_state(TASK_UNINTERRUPTIBLE);		timeout = schedule_timeout(timeout);	}}#endifstruct net_device_stats *rt_getstats(struct net_device *dev){	PRT2570ADAPTER pAd = (PRT2570ADAPTER)dev->priv;	struct net_device_stats *stats= &pAd->net_device_stats;	stats->rx_bytes = pAd->RalinkCounters.ReceivedByteCount;	stats->rx_packets = pAd->Counters.GoodReceives;	stats->rx_errors = pAd->Counters.RxErrors;	stats->tx_bytes = pAd->RalinkCounters.TransmittedByteCount;	stats->tx_packets = pAd->Counters.GoodTransmits;	stats->tx_errors = pAd->Counters.TxErrors;	return stats;}#if WIRELESS_EXT >= 12/*    ========================================================================    Routine Description:        get wireless statistics    Arguments:        net_dev                     Pointer to net_device    Return Value:        struct iw_statistics    Note:        This function will be called when query /proc    ========================================================================*/struct iw_statistics *RTUSB_get_wireless_stats(    IN  struct net_device *net_dev){    PRT2570ADAPTER pAd = (PRT2570ADAPTER)net_dev->priv;    DBGPRINT(RT_DEBUG_TRACE, "--->RTUSB_get_wireless_stats \n");    // TODO: All elements are zero before be implemented    pAd->iw_stats.status = 0;                       // Status - device dependent for now    pAd->iw_stats.qual.qual = pAd->Mlme.ChannelQuality;//pAd->Mlme.RoamCqi;            // link quality (%retries, SNR, %missed beacons or better...)    pAd->iw_stats.qual.level = pAd->PortCfg.LastRssi - RSSI_TO_DBM_OFFSET;   // signal level (dBm)            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)    pAd->iw_stats.qual.updated = 1;     // Flags to know if updated    pAd->iw_stats.discard.nwid = 0;     // Rx : Wrong nwid/essid    pAd->iw_stats.miss.beacon = 0;      // Missed beacons/superframe    // pAd->iw_stats.discard.code, discard.fragment, discard.retries, discard.misc has counted in other place    return &pAd->iw_stats;}#endifint rt2570_set_mac_address(struct net_device *net_dev, void *addr){	RT2570ADAPTER		*pAd = net_dev->priv;	struct sockaddr		*mac = (struct sockaddr*) addr;	if(netif_running(net_dev))		return -EBUSY;	if(!is_valid_ether_addr(&mac->sa_data[0]))		return -EINVAL;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) 		BUG_ON(net_dev->addr_len != ETH_ALEN);#endif			memcpy(net_dev->dev_addr, mac->sa_data, ETH_ALEN);	memcpy(&pAd->CurrentAddress, &mac->sa_data, ETH_ALEN);	printk(KERN_INFO "***rt2x00***: Info - Mac address changed to: %02x:%02x:%02x:%02x:%02x:%02x.\n", net_dev->dev_addr[0], net_dev->dev_addr[1], net_dev->dev_addr[2], net_dev->dev_addr[3], net_dev->dev_addr[4], net_dev->dev_addr[5]);	return RTUSBWriteHWMACAddress(pAd);}VOID	RTUSBHalt(	IN	PRT2570ADAPTER	pAdapter, BOOLEAN IsFree){	MLME_DISASSOC_REQ_STRUCT DisReq;	MLME_QUEUE_ELEM          MsgElem;		DBGPRINT(RT_DEBUG_TRACE, "====> RTUSBHalt\n");	// before set flag fRTMP_ADAPTER_HALT_IN_PROGRESS, 	// we should send a disassoc frame to our AP.	//#if 1	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))	{		if (INFRA_ON(pAdapter)) 		{			COPY_MAC_ADDR(&DisReq.Addr, &pAdapter->PortCfg.Bssid);			DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;			MsgElem.Machine = ASSOC_STATE_MACHINE;			MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;			MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);			memcpy(MsgElem.Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));			MlmeDisassocReqAction(pAdapter, &MsgElem);			NdisMSleep(1000);		}		// disable BEACON generation and other BEACON related hardware timers		AsicDisableSync(pAdapter);	}#endif	RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS);	RTUSBCleanUpMLMEWaitQueue(pAdapter);	RTUSBCleanUpMLMEBulkOutQueue(pAdapter);	// Free MLME stuff	MlmeHalt(pAdapter);	ReleaseAdapter(pAdapter, IsFree);	RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS);}VOID CMDHandler(    IN PRT2570ADAPTER pAdapter) {	PCmdQElmt	cmdqelmt;	PUCHAR	pData;	NDIS_STATUS	NdisStatus = NDIS_STATUS_SUCCESS;	while (pAdapter->CmdQ.size > 0)	{		NdisStatus = NDIS_STATUS_SUCCESS;		NdisAcquireSpinLock(&pAdapter->CmdQLock);		RTUSBDequeueCmd(&pAdapter->CmdQ, &cmdqelmt);		NdisReleaseSpinLock(&pAdapter->CmdQLock);		if (cmdqelmt == NULL)			break;		pData = cmdqelmt->buffer;		switch (cmdqelmt->command)		{			case	RT_OID_CHECK_GPIO:			{				USHORT data;				// Read GPIO pin0 as Hardware controlled radio state				RTUSBReadMACRegister(pAdapter, MAC_CSR19, &data);				if (data & 0x80)				{					pAdapter->PortCfg.bHwRadio = TRUE;				}				else				{					pAdapter->PortCfg.bHwRadio = FALSE;				}				if (pAdapter->PortCfg.bRadio != (pAdapter->PortCfg.bHwRadio && pAdapter->PortCfg.bSwRadio))				{					pAdapter->PortCfg.bRadio = (pAdapter->PortCfg.bHwRadio && pAdapter->PortCfg.bSwRadio);					if (pAdapter->PortCfg.bRadio == TRUE)					{						MlmeRadioOn(pAdapter);						// Update extra information						pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;					}					else					{						MlmeRadioOff(pAdapter);						// Update extra information						pAdapter->ExtraInfo = HW_RADIO_OFF;					}				}					}			break;			case	RT_OID_PERIODIC_EXECUT:				PeriodicExec(pAdapter);			break;			case	OID_802_11_BSSID_LIST_SCAN:			{				if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! MLME busy (Line#%d)!!!\n", __LINE__);					MlmeRestartStateMachine(pAdapter);					MlmePostRestartStateMachine(pAdapter);				}				//Now = jiffies;				pAdapter->Mlme.CntlAux.CurrReqIsFromNdis = FALSE;				// Reset Missed scan number				pAdapter->PortCfg.IgnoredScanNumber = 0;				//pAdapter->PortCfg.LastScanTime = Now;				MlmeEnqueue(pAdapter,					MLME_CNTL_STATE_MACHINE,					OID_802_11_BSSID_LIST_SCAN,					0,					NULL);				RTUSBUp(pAdapter, &pAdapter->mlme_semaphore);			}			break;						case	RT_OID_802_11_BSSID:			{				if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! MLME busy (Line#%d)!!!\n", __LINE__);					MlmeRestartStateMachine(pAdapter);					MlmePostRestartStateMachine(pAdapter);				}				pAdapter->Mlme.CntlAux.CurrReqIsFromNdis = FALSE;				// Reset allowed scan retries				pAdapter->PortCfg.IgnoredScanNumber = 0;				MlmeEnqueue(pAdapter,					MLME_CNTL_STATE_MACHINE,					RT_OID_802_11_BSSID,					cmdqelmt->bufferlength,					cmdqelmt->buffer);				RTUSBUp(pAdapter, &pAdapter->mlme_semaphore);			}			break;						case	OID_802_11_SSID:			{				if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! MLME busy (Line#%d)!!!\n", __LINE__);					MlmeRestartStateMachine(pAdapter);					MlmePostRestartStateMachine(pAdapter);				}				pAdapter->Mlme.CntlAux.CurrReqIsFromNdis = FALSE;				// Reset allowed scan retries				pAdapter->PortCfg.IgnoredScanNumber = 0;				MlmeEnqueue(pAdapter,						MLME_CNTL_STATE_MACHINE,						OID_802_11_SSID,						cmdqelmt->bufferlength, 						pData);				RTUSBUp(pAdapter, &pAdapter->mlme_semaphore);			}			break;			case	OID_802_11_DISASSOCIATE:			{				if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)				{					DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! MLME busy (Line#%d)!!!\n", __LINE__);					MlmeRestartStateMachine(pAdapter);					MlmePostRestartStateMachine(pAdapter);				}				// Set to immediately send the media disconnect event				pAdapter->Mlme.CntlAux.CurrReqIsFromNdis = TRUE;				MlmeEnqueue(pAdapter,					MLME_CNTL_STATE_MACHINE,					OID_802_11_DISASSOCIATE,

⌨️ 快捷键说明

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