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

📄 airo.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
static int readrids(struct net_device *dev, aironet_ioctl *comp);static int writerids(struct net_device *dev, aironet_ioctl *comp);int flashcard(struct net_device *dev, aironet_ioctl *comp);#endif /* CISCO_EXT */#ifdef MICSUPPORTstatic void micinit(struct airo_info *ai, MICRid *micr);static void micsetup(struct airo_info *ai);static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);#endifstruct airo_info {	struct net_device_stats	stats;	int open;	struct net_device             *dev;	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we	   use the high bit to mark wether it is in use. */#define MAX_FIDS 6	int                           fids[MAX_FIDS];	int registered;	ConfigRid config;	int need_commit;	// Need to set config	char keyindex; // Used with auto wep	char defindex; // Used with auto wep	struct timer_list timer;	struct proc_dir_entry *proc_entry;	struct airo_info *next;        spinlock_t aux_lock;        unsigned long flags;#define FLAG_PROMISC   IFF_PROMISC	/* 0x100 - include/linux/if.h */#define FLAG_RADIO_OFF 0x02		/* User disabling of MAC */#define FLAG_RADIO_DOWN 0x08		/* ifup/ifdown disabling of MAC */#define FLAG_LOCKED    2		/* 0x04 - use as a bit offset */#define FLAG_FLASHING  0x10#define FLAG_ADHOC        0x01 /* Needed by MIC */#define FLAG_MIC_CAPABLE  0x20#define FLAG_UPDATE_MULTI 0x40#define FLAG_UPDATE_UNI   0x80#define FLAG_802_11    0x200	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,			int whichbap);	unsigned short *flash;	tdsRssiEntry *rssi;	struct semaphore sem;	struct task_struct *task;	struct tq_struct promisc_task;	struct {		struct sk_buff *skb;		int fid;		struct tq_struct task;	} xmit, xmit11;	struct net_device *wifidev;#ifdef WIRELESS_EXT	struct iw_statistics	wstats;		// wireless stats	unsigned long		scan_timestamp;	/* Time started to scan */	struct tq_struct	event_task;#ifdef WIRELESS_SPY	int			spy_number;	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];	struct iw_quality	spy_stat[IW_MAX_SPY];#endif /* WIRELESS_SPY */#endif /* WIRELESS_EXT */	/* MIC stuff */	mic_module		mod[2];	mic_statistics		micstats;	struct tq_struct 	mic_task;};static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,			   int whichbap) {	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);}static int setup_proc_entry( struct net_device *dev,			     struct airo_info *apriv );static int takedown_proc_entry( struct net_device *dev,				struct airo_info *apriv );#ifdef MICSUPPORT#include "mic.h"#endifstatic int readBSSListRid(struct airo_info *ai, int first,		      BSSListRid *list) {	int rc;			Cmd cmd;			Resp rsp;	if (first == 1) {			memset(&cmd, 0, sizeof(cmd));			cmd.cmd=CMD_LISTBSS;			if (down_interruptible(&ai->sem))				return -ERESTARTSYS;			issuecommand(ai, &cmd, &rsp);			up(&ai->sem);			/* Let the command take effect */			set_current_state (TASK_INTERRUPTIBLE);			ai->task = current;			schedule_timeout (3*HZ);			ai->task = NULL;		}	rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,			    list, sizeof(*list));	list->len = le16_to_cpu(list->len);	list->index = le16_to_cpu(list->index);	list->radioType = le16_to_cpu(list->radioType);	list->cap = le16_to_cpu(list->cap);	list->beaconInterval = le16_to_cpu(list->beaconInterval);	list->fh.dwell = le16_to_cpu(list->fh.dwell);	list->dsChannel = le16_to_cpu(list->dsChannel);	list->atimWindow = le16_to_cpu(list->atimWindow);	return rc;}static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp) {	int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,				wkr, sizeof(*wkr));	wkr->len = le16_to_cpu(wkr->len);	wkr->kindex = le16_to_cpu(wkr->kindex);	wkr->klen = le16_to_cpu(wkr->klen);	return rc;}/* In the writeXXXRid routines we copy the rids so that we don't screwup * the originals when we endian them... */static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm) {	int rc;	WepKeyRid wkr = *pwkr;	wkr.len = cpu_to_le16(wkr.len);	wkr.kindex = cpu_to_le16(wkr.kindex);	wkr.klen = cpu_to_le16(wkr.klen);	rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr));	if (rc!=SUCCESS) printk(KERN_ERR "airo:  WEP_TEMP set %x\n", rc);	if (perm) {		rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr));		if (rc!=SUCCESS) {			printk(KERN_ERR "airo:  WEP_PERM set %x\n", rc);		}	}	return rc;}static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {	int i;	int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr));	ssidr->len = le16_to_cpu(ssidr->len);	for(i = 0; i < 3; i++) {		ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);	}	return rc;}static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr) {	int rc;	int i;	SsidRid ssidr = *pssidr;	ssidr.len = cpu_to_le16(ssidr.len);	for(i = 0; i < 3; i++) {		ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);	}	rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr));	return rc;}static int readConfigRid(struct airo_info*ai) {	int rc;	u16 *s;	ConfigRid cfg;	if (ai->config.len)		return SUCCESS;	rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg));	if (rc != SUCCESS)		return rc;	for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);	for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)		*s = le16_to_cpu(*s);	for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)		*s = le16_to_cpu(*s);	for(s = &cfg.arlThreshold; s <= &cfg.autoWake; s++)		*s = le16_to_cpu(*s);	ai->config = cfg;	return SUCCESS;}static inline void checkThrottle(struct airo_info *ai) {	int i;/* Old hardware had a limit on encryption speed */	if (ai->config.authType != AUTH_OPEN && maxencrypt) {		for(i=0; i<8; i++) {			if (ai->config.rates[i] > maxencrypt) {				ai->config.rates[i] = 0;			}		}	}}static int writeConfigRid(struct airo_info*ai) {	u16 *s;	ConfigRid cfgr;	if (!ai->need_commit)		return SUCCESS;	ai->need_commit = 0;	checkThrottle(ai);	if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)		ai->flags |= FLAG_ADHOC;	else		ai->flags &= ~FLAG_ADHOC;	cfgr = ai->config;	for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);	for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)		*s = cpu_to_le16(*s);	for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)		*s = cpu_to_le16(*s);	for(s = &cfgr.arlThreshold; s <= &cfgr.autoWake; s++)		*s = cpu_to_le16(*s);	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr));}static int readStatusRid(struct airo_info*ai, StatusRid *statr) {	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr));	u16 *s;	statr->len = le16_to_cpu(statr->len);	for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);	for(s = &statr->beaconPeriod; s <= &statr->_reserved[9]; s++)		*s = le16_to_cpu(*s);	return rc;}static int readAPListRid(struct airo_info*ai, APListRid *aplr) {	int rc =  PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr));	aplr->len = le16_to_cpu(aplr->len);	return rc;}static int writeAPListRid(struct airo_info*ai, APListRid *aplr) {	int rc;	aplr->len = cpu_to_le16(aplr->len);	rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr));	return rc;}static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr) {	int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr));	u16 *s;	capr->len = le16_to_cpu(capr->len);	capr->prodNum = le16_to_cpu(capr->prodNum);	capr->radioType = le16_to_cpu(capr->radioType);	capr->country = le16_to_cpu(capr->country);	for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)		*s = le16_to_cpu(*s);	return rc;}static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid) {	int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr));	u32 *i;	sr->len = le16_to_cpu(sr->len);	for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);	return rc;}static int airo_open(struct net_device *dev) {	struct airo_info *info = dev->priv;	Resp rsp;	if (info->flags & FLAG_FLASHING)		return -EIO;	/* Make sure the card is configured.	 * Wireless Extensions may postpone config changes until the card	 * is open (to pipeline changes and speed-up card setup). If	 * those changes are not yet commited, do it now - Jean II */	if(info->need_commit) {		disable_MAC(info);		writeConfigRid(info);	}	if (info->wifidev != dev) {		/* Power on the MAC controller (which may have been disabled) */		info->flags &= ~FLAG_RADIO_DOWN;		enable_interrupts(info);	}	enable_MAC(info, &rsp);	netif_start_queue(dev);	return 0;}static void get_tx_error(struct airo_info *ai, u32 fid){	u16 status;	if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) == SUCCESS) {		bap_read(ai, &status, 2, BAP0);		if (le16_to_cpu(status) & 2) /* Too many retries */			ai->stats.tx_aborted_errors++;		if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */			ai->stats.tx_heartbeat_errors++;		if (le16_to_cpu(status) & 8) /* Aid fail */			{ }		if (le16_to_cpu(status) & 0x10) /* MAC disabled */			ai->stats.tx_carrier_errors++;		if (le16_to_cpu(status) & 0x20) /* Association lost */			{ }#if WIRELESS_EXT > 13		/* We produce a TXDROP event only for retry or lifetime		 * exceeded, because that's the only status that really mean		 * that this particular node went away.		 * Other errors means that *we* screwed up. - Jean II */		if ((le16_to_cpu(status) & 2) ||		     (le16_to_cpu(status) & 4)) {			union iwreq_data	wrqu;			char junk[0x18];			/* Faster to skip over useless data than to do			 * another bap_setup(). We are at offset 0x6 and			 * need to go to 0x18 and read 6 bytes - Jean II */			bap_read(ai, (u16 *) junk, 0x18, BAP0);			/* Copy 802.11 dest address.			 * We use the 802.11 header because the frame may			 * not be 802.3 or may be mangled...			 * In Ad-Hoc mode, it will be the node address.			 * In managed mode, it will be most likely the AP addr			 * User space will figure out how to convert it to			 * whatever it needs (IP address or else).			 * - Jean II */			memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);			wrqu.addr.sa_family = ARPHRD_ETHER;			/* Send event to user space */			wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);		}#endif /* WIRELESS_EXT > 13 */	}}static void airo_do_xmit(struct net_device *dev) {	u16 status;	int i;	struct airo_info *priv = dev->priv;	struct sk_buff *skb = priv->xmit.skb;	int fid = priv->xmit.fid;	u32 *fids = priv->fids;	if (down_trylock(&priv->sem) != 0) {		netif_stop_queue(dev);		priv->xmit.task.routine = (void (*)(void *))airo_do_xmit;		priv->xmit.task.data = (void *)dev;		schedule_task(&priv->xmit.task);		return;	}	status = transmit_802_3_packet (priv, fids[fid], skb->data);	up(&priv->sem);	i = 0;	if ( status == SUCCESS ) {		dev->trans_start = jiffies;		for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);	} else {		priv->fids[fid] &= 0xffff;		priv->stats.tx_window_errors++;	}	if (i < MAX_FIDS / 2)		netif_wake_queue(dev);	else		netif_stop_queue(dev);	dev_kfree_skb(skb);}static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {	s16 len;	int i;	struct airo_info *priv = dev->priv;	u32 *fids = priv->fids;	if ( skb == NULL ) {		printk( KERN_ERR "airo:  skb == NULL!!!\n" );		return 0;	}	/* Find a vacant FID */	for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );	if ( i == MAX_FIDS / 2 ) {		priv->stats.tx_fifo_errors++;		dev_kfree_skb(skb);	} else {		/* check min length*/		len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;	        /* Mark fid as used & save length for later */		fids[i] |= (len << 16);		priv->xmit.skb = skb;		priv->xmit.fid = i;		airo_do_xmit(dev);	}	return 0;}static void airo_do_xmit11(struct net_device *dev) {	u16 status;	int i;	struct airo_info *priv = dev->priv;	struct sk_buff *skb = priv->xmit11.skb;	int fid = priv->xmit11.fid;	u32 *fids = priv->fids;	if (down_trylock(&priv->sem) != 0) {		netif_stop_queue(dev);		priv->xmit11.task.routine = (void (*)(void *))airo_do_xmit11;		priv->xmit11.task.data = (void *)dev;		schedule_task(&priv->xmit11.task);		return;	}	status = transmit_802_11_packet (priv, fids[fid], skb->data);	up(&priv->sem);	i = MAX_FIDS / 2;	if ( status == SUCCESS ) {		dev->trans_start = jiffies;		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);	} else {		priv->fids[fid] &= 0xffff;		priv->stats.tx_window_errors++;	}	if (i < MAX_FIDS)		netif_wake_queue(dev);	else		netif_stop_queue(dev);	dev_kfree_skb(skb);}static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {	s16 len;	int i;	struct airo_info *priv = dev->priv;	u32 *fids = priv->fids;	if ( skb == NULL ) {		printk( KERN_ERR "airo:  skb == NULL!!!\n" );		return 0;	}	/* Find a vacant FID */	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );	if ( i == MAX_FIDS ) {		priv->stats.tx_fifo_errors++;		dev_kfree_skb(skb);	} else {		/* check min length*/		len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;	        /* Mark fid as used & save length for later */		fids[i] |= (len << 16);		priv->xmit11.skb = skb;		priv->xmit11.fid = i;		airo_do_xmit11(dev);	}	return 0;}struct net_device_stats *airo_get_stats(struct net_device *dev){	struct airo_info *local =  dev->priv;	StatsRid stats_rid;	u32 *vals = stats_rid.vals;

⌨️ 快捷键说明

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