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

📄 fastvnet_cs.c

📁 Atmel公司的USB无线局域网卡11 mbps Linux设备驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************//*                             						   					   *//*            Copyright (c) 1999-2000 by Atmel Corporation    	 	   	   *//*                                     									   *//*  This software is copyrighted by and is the sole property of Atmel	   *//*  Corporation.  All rights, title, ownership, or other interests	  	   *//*  in the software remain the property of Atmel Corporation.  This        *//*  software may only be used in accordance with the corresponding         *//*  license agreement.  Any un-authorized use, duplication, transmission,  *//*  distribution, or disclosure of this software is expressly forbidden.   *//*                                                                         *//*  This Copyright notice may not be removed or modified without prior     *//*  written consent of Atmel Corporation.                                  *//*                                                                         *//*  Atmel Corporation, Inc. reserves the right to modify this software     *//*  without notice.                                                        *//*                                                                         *//*  Atmel Corporation.                                                     *//*  2325 Orchard Parkway               literature@atmel.com                *//*  San Jose, CA 95131                 http://www.atmel.com                *//*                                                                         *//***************************************************************************//***************************************************************************//***************************************************************************//**                                                                        *//** FastVNET (PCMCIA) Linux Driver		                           	  	   *//**                                                                        *//***************************************************************************//***************************************************************************/#include "vnet.h"#include "vnetioctl.h"#include "interrupt.h"/******************************************************************** * Module parameters, Globals and miscelenious definitions ********************************************************************/static 	char 		*version = "4.0.0.3";static 	dev_info_t 	dev_info = "fastvnet_cs";static 	dev_link_t 	*dev_list = NULL;static 	u_int 	irq_mask = 0xdeb8;	// Interrupt maskstatic 	int 	irq_list[4] = { -1 };	// Interrupt list (alternative)static 	int 	mtu = 1500;static 	int 	eth = 1;static 	UCHAR 	channel = 4;static 	UCHAR	TxRate = 3;static 	USHORT 	RTSThreshold = 2347;static 	USHORT 	FragThreshold = 2346;static 	UCHAR 	OpMode = INFRASTRUCTURE_MODE;static 	char    ESSID[MAX_SSID_LENGTH+1] = "ANY\0";	static 	UCHAR 	WepKeyToUse = 0;static	char	WepKey1[(SHORT_WEP_KEY_SIZE*2)+1]=  "0000000000\0";static	char	WepKey2[(SHORT_WEP_KEY_SIZE*2)+1] = "0000000000\0";static	char	WepKey3[(SHORT_WEP_KEY_SIZE*2)+1] = "0000000000\0";static	char	WepKey4[(SHORT_WEP_KEY_SIZE*2)+1] = "0000000000\0";static  	UCHAR	WepMode = WEP_MODE_MANDATORY;static 	UCHAR	EncryptionLevel = WEP_DISABLED;static  	UCHAR	AuthenticationType = C80211_MGMT_AAN_OPENSYSTEM;static 	UCHAR 	PreambleType = LONG_PREAMBLE;static 	UCHAR 	PwrMgmtMode = ACTIVE_MODE;static	int pc_debug = 0;MODULE_PARM(pc_debug, "i");MODULE_PARM(irq_mask, "i");MODULE_PARM(irq_list, "1-4i");MODULE_PARM(mtu, "i");MODULE_PARM(eth, "i");MODULE_PARM(channel, "i");MODULE_PARM(TxRate, "i");MODULE_PARM(RTSThreshold, "i");MODULE_PARM(FragThreshold, "i");MODULE_PARM(OpMode, "i");MODULE_PARM(ESSID, "c" __MODULE_STRING(MAX_SSID_LENGTH));MODULE_PARM(WepKeyToUse,"i");MODULE_PARM(WepKey1, "c" __MODULE_STRING(11));MODULE_PARM(WepKey2, "c" __MODULE_STRING(11));MODULE_PARM(WepKey3, "c" __MODULE_STRING(11));MODULE_PARM(WepKey4, "c" __MODULE_STRING(11));MODULE_PARM(WepMode, "i");MODULE_PARM(EncryptionLevel, "i");MODULE_PARM(AuthenticationType, "i");MODULE_PARM(PreambleType, "i");MODULE_PARM(PwrMgmtMode, "i");// Macros not included in kernel#ifndef __IN_PCMCIA_PACKAGE__#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb);#define skb_tx_check(dev, skb)#define add_rx_bytes(stats, n) (stats)->rx_bytes += n;#define add_tx_bytes(stats, n) (stats)->tx_bytes += n;#endif// Ethernet timeout is ((400*HZ)/1000), but we should use a higher// value, because wireless transmissions are much slower#define TX_TIMEOUT ((4000*HZ)/1000)#define MAX_VNET_CARDS 	16static struct net_device *vnet_index[MAX_VNET_CARDS];//// Local data for netdevice//struct net_local {	dev_node_t			node;	struct net_device	*dev;		// backtrack device	dev_link_t			*link;	// backtrack link	spinlock_t			slock;	// spinlock	int					interrupt;	// interrupt	struct net_device_stats	stats;	// device stats#ifdef WIRELESS_EXT#ifdef WIRELESS_SPY	int				spy_number;	u_char			spy_address[IW_MAX_SPY][VNet_LENGTH_OF_ADDRESS];	struct iw_quality	spy_stat[IW_MAX_SPY];#endif	struct iw_statistics	wstats;#endif			VNet_ADAPTER	Adapter;};//	Driver Info/******************************************************************** * Function Prototypes ********************************************************************/static	int 			vnet_tx (struct sk_buff *skb, struct net_device *dev);static 	int 			vnet_open (struct net_device *dev);static 	int 			vnet_close (struct net_device *dev);static 	void 			vnet_interrupt (int irq, void *dev_id, struct pt_regs *regs);static 	int 			vnet_config (dev_link_t *link);static 	void 			vnet_release (u_long arg);static 	dev_link_t 		*vnet_attach (void);static 	void 			vnet_detach (dev_link_t *link);static 	int 			vnet_event (event_t event, int priority, event_callback_args_t *args);static 	void 			cs_error (client_handle_t handle, int func, int ret);extern 	int 			init_module (void);extern 	void 			cleanup_module (void);struct 	net_device_stats 	*vnet_get_stats (struct net_device *dev);#ifdef	WIRELESS_EXTstatic  int				vnet_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);struct  iw_statistics	*vnet_get_wireless_stats (struct net_device *dev);#endif	/******************************************************************** * PCMCIA CONFIG / RELEASE ********************************************************************/#define CS_CHECK(fn, args...) while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed#define CFG_CHECK(fn, args...) if (CardServices(fn, args) != 0) goto next_entrystatic int vnet_config (dev_link_t *link){	client_handle_t handle = link->handle;	tuple_t tuple;	cisparse_t parse;	struct net_device *dev = (struct net_device *) link->priv;	struct net_local *local = (struct net_local *) dev->priv;	int last_fn, last_ret;	u_char buf[64];	win_req_t req;	memreq_t map;	int rc, i, cs_r;	config_info_t config;//	cistpl_cftable_entry_t dflt = { 0 };	PVNet_ADAPTER Adapter = (PVNet_ADAPTER)&local->Adapter;		IF_VERY_LOUD(DbgPrint("-> vnet_config(0x%p)\n", link);)	// This reads the card's CONFIG tuple to find its configuration registers.	tuple.DesiredTuple = CISTPL_CONFIG;	tuple.Attributes = 0;	tuple.TupleData = buf;	tuple.TupleDataMax = sizeof(buf);	tuple.TupleOffset = 0;	CS_CHECK(GetFirstTuple, handle, &tuple);	CS_CHECK(GetTupleData, handle, &tuple);	CS_CHECK(ParseTuple, handle, &tuple, &parse);	link->conf.ConfigBase = parse.config.base;	link->conf.Present = parse.config.rmask[0];	// Configure card	link->state |= DEV_CONFIG;	// 2-05-2001 Test : Added GetConfigurationInfo. Check if needed	CS_CHECK(GetConfigurationInfo, handle, &config);	link->conf.Vcc = config.Vcc;	// In this loop, we scan the CIS for configuration table entries,	// each of which describes a valid card configuration, including	// voltage, IO window, memory window, and interrupt settings.	// We make no assumptions about the card to be configured: we use	// just the information available in the CIS.  In an ideal world,	// this would work for any PCMCIA card, but it requires a complete	// and accurate CIS.  In practice, a driver usually "knows" most of	// these things without consulting the CIS, and most client drivers	// will only use the CIS to fill in implementation-defined details.	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	CS_CHECK(GetFirstTuple, handle, &tuple);	while (1) 	{		cistpl_cftable_entry_t dflt = { 0 };		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);		CFG_CHECK(GetTupleData, handle, &tuple);		CFG_CHECK(ParseTuple, handle, &tuple, &parse);		if (cfg->index == 0) 			goto next_entry;		link->conf.ConfigIndex = cfg->index;		// Does this card need audio output?		if (cfg->flags & CISTPL_CFTABLE_AUDIO)		{			link->conf.Attributes |= CONF_ENABLE_SPKR;			link->conf.Status = CCSR_AUDIO_ENA;		}			// Use power settings for Vcc and Vpp if present		// Note that the CIS values need to be rescaled		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))			link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;		else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))			link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;		if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))			link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;		else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))			link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;		// Do we need to allocate an interrupt?		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)			link->conf.Attributes |= CONF_ENABLE_IRQ;		// IO window settings		link->io.NumPorts1 = link->io.NumPorts2 = 0;		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) 		{			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;			if (!(io->flags & CISTPL_IO_8BIT))				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;			if (!(io->flags & CISTPL_IO_16BIT))				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;			link->io.BasePort1 = io->win[0].base;			link->io.NumPorts1 = io->win[0].len;			if (io->nwin > 1) 			{				link->io.Attributes2 = link->io.Attributes1;				link->io.BasePort2 = io->win[1].base;				link->io.NumPorts2 = io->win[1].len;			}		}                                                                     			// This reserves IO space but doesn't actually enable it		CFG_CHECK(RequestIO, link->handle, &link->io);			// Now set up a common memory window, if needed.  There is room		// in the dev_link_t structure for one memory window handle,		// but if the base addresses need to be saved, or if multiple		// windows are needed, the info should go in the private data		// structure for this device.		// Note that the memory window base is a physical address, and		// needs to be mapped to virtual space with ioremap() before it		// is used.		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) 		{			cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;			req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;			req.Base = mem->win[0].host_addr;			req.Size = mem->win[0].len;			req.AccessSpeed = 0;			link->win = (window_handle_t)link->handle;			CFG_CHECK(RequestWindow, &link->win, &req);			map.Page = 0; map.CardOffset = mem->win[0].card_addr;			CFG_CHECK(MapMemPage, link->win, &map);		}		break;next_entry:		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)			dflt = *cfg;		CS_CHECK(GetNextTuple, handle, &tuple);	}	// Allocate an interrupt line.  Note that this does not assign a	// handler to the interrupt, unless the 'Handler' member of the	// irq structure is initialized.	if (link->conf.Attributes & CONF_ENABLE_IRQ)	{		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;		link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;		if (irq_list[0] == -1)			link->irq.IRQInfo2 = irq_mask;		else			for (i=0; i<4; i++)				link->irq.IRQInfo2 |= 1 << irq_list[i];		link->irq.Handler = vnet_interrupt;		link->irq.Instance = dev;		CS_CHECK(RequestIRQ, link->handle, &link->irq);	}	// This actually configures the PCMCIA socket -- setting up	// the I/O windows and the interrupt mapping, and putting the	// card and host interface into "Memory and IO" mode.	CS_CHECK(RequestConfiguration, link->handle, &link->conf);	// Feed the netdevice with this info	dev->irq = link->irq.AssignedIRQ;	dev->base_addr = link->io.BasePort1;	netif_start_queue(dev);	// Report what we've done	IF_LOUD(DbgPrint("%s: index 0x%02x: Vcc %d.%d", dev_info, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10);)	if (link->conf.Vpp1)	{		IF_LOUD(DbgPrint(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);)	}	if (link->conf.Attributes & CONF_ENABLE_IRQ)	{		IF_LOUD(DbgPrint(", irq %d", link->irq.AssignedIRQ);)	}	if (link->io.NumPorts1)	{		IF_LOUD(DbgPrint(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1);)	}	if (link->io.NumPorts2)	{		IF_LOUD(DbgPrint(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1);)	}	if (link->win)	{		IF_LOUD(DbgPrint(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1);)	}	IF_LOUD(DbgPrint("\n");)	link->state &= ~DEV_CONFIG_PENDING;	if(!eth)	{		for (i=0; i<MAX_VNET_CARDS; ++i)			if (!vnet_index[i])			{				sprintf(dev->name, "vnet%d",i);				vnet_index[i]=dev;				break;			}	}	// Register the netdevice	rc = register_netdev(dev);	if (rc)	{		IF_DEBUG_ERRORS(DbgPrint("%s: register_netdev() failed!\n", dev_info);)		vnet_release((u_long)link);		return 0;	}	IF_LOUD(DbgPrint("%s: Registered netdevice %s\n", dev_info, dev->name);)	copy_dev_name(local->node, dev);	local->Adapter.dev = dev;	local->Adapter.IoBase = dev->base_addr;	link->dev = &local->node;	IF_VERY_LOUD(DbgPrint("<- vnet_config()\n");)	return 1;cs_failed:	cs_error(link->handle, last_fn, last_ret);	vnet_release((u_long)link);	IF_VERY_LOUD(DbgPrint("<- vnet_config()\n");)	return 0;}static void vnet_release (u_long arg){	dev_link_t *link = (dev_link_t *) arg;	struct net_device *dev = (struct net_device *) link->priv;	struct net_local *local = (struct net_local *) dev->priv;	PVNet_ADAPTER Adapter = &local->Adapter;	IF_VERY_LOUD(DbgPrint("-> vnet_release(0x%p)\n", link);)	// If the device is currently in use, we won't release	// until it's actually closed.	if (link->open)	{		IF_VERY_LOUD(DbgPrint("%s: vnet_release: release postponed, %s still locked\n", dev_info, link->dev->dev_name);)		link->state |= DEV_STALE_CONFIG;		return;	}	del_timer(&Adapter->MgmtTimer);	CardStop(Adapter);			Adapter->IsUp = FALSE;	if (link->win)		CardServices(ReleaseWindow, link->win);	CardServices(ReleaseConfiguration, link->handle);	if (link->io.NumPorts1)       	CardServices(ReleaseIO, link->handle, &link->io);	if (link->irq.AssignedIRQ)		CardServices(ReleaseIRQ, link->handle, &link->irq);	link->state &= ~DEV_CONFIG;	IF_VERY_LOUD(DbgPrint("<- vnet_release()\n");)

⌨️ 快捷键说明

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