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

📄 orinoco.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (err)				return err;						err = HERMES_WRITE_RECORD(hw, USER_BAP,						  HERMES_RID_CNFWEPKEYS_AGERE,						  &priv->keys);			if (err)				return err;		}		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFWEPENABLED_AGERE,					   priv->wep_on);		if (err)			return err;		break;	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */		master_wep_flag = 0;		/* Off */		if (priv->wep_on) {			int keylen;			int i;			/* Fudge around firmware weirdness */			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);						/* Write all 4 keys */			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {/*  				int keylen = le16_to_cpu(priv->keys[i].len); */								if (keylen > LARGE_KEY_SIZE) {					printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",					       priv->ndev->name, i, keylen);					return -E2BIG;				}				err = hermes_write_ltv(hw, USER_BAP,						       HERMES_RID_CNFDEFAULTKEY0 + i,						       HERMES_BYTES_TO_RECLEN(keylen),						       priv->keys[i].data);				if (err)					return err;			}			/* Write the index of the key used in transmission */			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPDEFAULTKEYID,						   priv->tx_key);			if (err)				return err;						if (priv->wep_restrict) {				auth_flag = 2;				master_wep_flag = 3;			} else {				/* Authentication is where Intersil and Symbol				 * firmware differ... */				auth_flag = 1;				if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)					master_wep_flag = 3; /* Symbol */ 				else 					master_wep_flag = 1; /* Intersil */			}			err = hermes_write_wordrec(hw, USER_BAP,						   HERMES_RID_CNFAUTHENTICATION, auth_flag);			if (err)				return err;		}				/* Master WEP setting : on/off */		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFWEPFLAGS_INTERSIL,					   master_wep_flag);		if (err)			return err;			break;	default:		if (priv->wep_on) {			printk(KERN_ERR "%s: WEP enabled, although not supported!\n",			       priv->ndev->name);			return -EINVAL;		}	}	TRACE_EXIT(priv->ndev->name);	return 0;}static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]){	hermes_t *hw = &priv->hw;	int err = 0;	orinoco_lock(priv);	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,			      ETH_ALEN, NULL, buf);	orinoco_unlock(priv);	return err;}static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,			      char buf[IW_ESSID_MAX_SIZE+1]){	hermes_t *hw = &priv->hw;	int err = 0;	struct hermes_idstring essidbuf;	char *p = (char *)(&essidbuf.val);	int len;	TRACE_ENTER(priv->ndev->name);	orinoco_lock(priv);	if (strlen(priv->desired_essid) > 0) {		/* We read the desired SSID from the hardware rather		   than from priv->desired_essid, just in case the		   firmware is allowed to change it on us. I'm not		   sure about this */		/* My guess is that the OWNSSID should always be whatever		 * we set to the card, whereas CURRENT_SSID is the one that		 * may change... - Jean II */		u16 rid;		*active = 1;		rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :			HERMES_RID_CNFDESIREDSSID;				err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),				      NULL, &essidbuf);		if (err)			goto fail_unlock;	} else {		*active = 0;		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,				      sizeof(essidbuf), NULL, &essidbuf);		if (err)			goto fail_unlock;	}	len = le16_to_cpu(essidbuf.len);	memset(buf, 0, IW_ESSID_MAX_SIZE+1);	memcpy(buf, p, len);	buf[len] = '\0'; fail_unlock:	orinoco_unlock(priv);	TRACE_EXIT(priv->ndev->name);	return err;       }static long orinoco_hw_get_freq(struct orinoco_private *priv){		hermes_t *hw = &priv->hw;	int err = 0;	u16 channel;	long freq = 0;	orinoco_lock(priv);		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);	if (err)		goto out;	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {		struct net_device *dev = priv->ndev;		printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);		err = -EBUSY;		goto out;	}	freq = channel_frequency[channel-1] * 100000; out:	orinoco_unlock(priv);	if (err > 0)		err = -EBUSY;	return err ? err : freq;}static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,				    s32 *rates, int max){	hermes_t *hw = &priv->hw;	struct hermes_idstring list;	unsigned char *p = (unsigned char *)&list.val;	int err = 0;	int num;	int i;	orinoco_lock(priv);	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,			      sizeof(list), NULL, &list);	orinoco_unlock(priv);	if (err)		return err;		num = le16_to_cpu(list.len);	*numrates = num;	num = min(num, max);	for (i = 0; i < num; i++) {		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */	}	return 0;}#if 0#ifndef ORINOCO_DEBUGstatic inline void show_rx_frame(struct orinoco_rxframe_hdr *frame) {}#elsestatic void show_rx_frame(struct orinoco_rxframe_hdr *frame){	printk(KERN_DEBUG "RX descriptor:\n");	printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);	printk(KERN_DEBUG "  time        = 0x%08x\n", frame->desc.time);	printk(KERN_DEBUG "  silence     = 0x%02x\n", frame->desc.silence);	printk(KERN_DEBUG "  signal      = 0x%02x\n", frame->desc.signal);	printk(KERN_DEBUG "  rate        = 0x%02x\n", frame->desc.rate);	printk(KERN_DEBUG "  rxflow      = 0x%02x\n", frame->desc.rxflow);	printk(KERN_DEBUG "  reserved    = 0x%08x\n", frame->desc.reserved);	printk(KERN_DEBUG "IEEE 802.11 header:\n");	printk(KERN_DEBUG "  frame_ctl   = 0x%04x\n",	       frame->p80211.frame_ctl);	printk(KERN_DEBUG "  duration_id = 0x%04x\n",	       frame->p80211.duration_id);	printk(KERN_DEBUG "  addr1       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr1[0], frame->p80211.addr1[1],	       frame->p80211.addr1[2], frame->p80211.addr1[3],	       frame->p80211.addr1[4], frame->p80211.addr1[5]);	printk(KERN_DEBUG "  addr2       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr2[0], frame->p80211.addr2[1],	       frame->p80211.addr2[2], frame->p80211.addr2[3],	       frame->p80211.addr2[4], frame->p80211.addr2[5]);	printk(KERN_DEBUG "  addr3       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr3[0], frame->p80211.addr3[1],	       frame->p80211.addr3[2], frame->p80211.addr3[3],	       frame->p80211.addr3[4], frame->p80211.addr3[5]);	printk(KERN_DEBUG "  seq_ctl     = 0x%04x\n",	       frame->p80211.seq_ctl);	printk(KERN_DEBUG "  addr4       = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p80211.addr4[0], frame->p80211.addr4[1],	       frame->p80211.addr4[2], frame->p80211.addr4[3],	       frame->p80211.addr4[4], frame->p80211.addr4[5]);	printk(KERN_DEBUG "  data_len    = 0x%04x\n",	       frame->p80211.data_len);	printk(KERN_DEBUG "IEEE 802.3 header:\n");	printk(KERN_DEBUG "  dest        = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p8023.h_dest[0], frame->p8023.h_dest[1],	       frame->p8023.h_dest[2], frame->p8023.h_dest[3],	       frame->p8023.h_dest[4], frame->p8023.h_dest[5]);	printk(KERN_DEBUG "  src         = %02x:%02x:%02x:%02x:%02x:%02x\n",	       frame->p8023.h_source[0], frame->p8023.h_source[1],	       frame->p8023.h_source[2], frame->p8023.h_source[3],	       frame->p8023.h_source[4], frame->p8023.h_source[5]);	printk(KERN_DEBUG "  len         = 0x%04x\n", frame->p8023.h_proto);	printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");	printk(KERN_DEBUG "  DSAP        = 0x%02x\n", frame->p8022.dsap);	printk(KERN_DEBUG "  SSAP        = 0x%02x\n", frame->p8022.ssap);	printk(KERN_DEBUG "  ctrl        = 0x%02x\n", frame->p8022.ctrl);	printk(KERN_DEBUG "  OUI         = %02x:%02x:%02x\n",	       frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);	printk(KERN_DEBUG "  ethertype  = 0x%04x\n", frame->ethertype);}#endif#endif/* * Interrupt handler */void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs){	struct orinoco_private *priv = (struct orinoco_private *) dev_id;	hermes_t *hw = &priv->hw;	struct net_device *dev = priv->ndev;	int count = MAX_IRQLOOPS_PER_IRQ;	u16 evstat, events;	/* These are used to detect a runaway interrupt situation */	/* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,	 * we panic and shut down the hardware */	static int last_irq_jiffy = 0; /* jiffies value the last time we were called */	static int loops_this_jiffy = 0;	if (test_and_set_bit(ORINOCO_STATE_INIRQ, &priv->state))		BUG();	if (! orinoco_irqs_allowed(priv)) {		clear_bit(ORINOCO_STATE_INIRQ, &priv->state);		return;	}	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev->name);	evstat = hermes_read_regn(hw, EVSTAT);	events = evstat & hw->inten;	/*  	if (! events) { *//*  		printk(KERN_WARNING "%s: Null event\n", dev->name); *//*  	} */	if (jiffies != last_irq_jiffy)		loops_this_jiffy = 0;	last_irq_jiffy = jiffies;	while (events && count--) {		DEBUG(3, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",		      count, evstat);				if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {			printk(KERN_CRIT "%s: IRQ handler is looping too \much! Shutting down.\n",			       dev->name);			/* Perform an emergency shutdown */			clear_bit(ORINOCO_STATE_DOIRQ, &priv->state);			hermes_set_irqmask(hw, 0);			break;		}		/* Check the card hasn't been removed */		if (! hermes_present(hw)) {			DEBUG(0, "orinoco_interrupt(): card removed\n");			break;		}		if (events & HERMES_EV_TICK)			__orinoco_ev_tick(priv, hw);		if (events & HERMES_EV_WTERR)			__orinoco_ev_wterr(priv, hw);		if (events & HERMES_EV_INFDROP)			__orinoco_ev_infdrop(priv, hw);		if (events & HERMES_EV_INFO)			__orinoco_ev_info(priv, hw);		if (events & HERMES_EV_RX)			__orinoco_ev_rx(priv, hw);		if (events & HERMES_EV_TXEXC)			__orinoco_ev_txexc(priv, hw);		if (events & HERMES_EV_TX)			__orinoco_ev_tx(priv, hw);		if (events & HERMES_EV_ALLOC)			__orinoco_ev_alloc(priv, hw);				hermes_write_regn(hw, EVACK, events);		evstat = hermes_read_regn(hw, EVSTAT);		events = evstat & hw->inten;	};	clear_bit(ORINOCO_STATE_INIRQ, &priv->state);}static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw){	printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name);}static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw){	/* This seems to happen a fair bit under load, but ignoring it	   seems to work fine...*/	DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",	      priv->ndev->name);}static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw){	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name);}static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw){	struct net_device *dev = priv->ndev;	u16 infofid;	struct {		u16 len;		u16 type;	} __attribute__ ((packed)) info;	int err;	/* This is an answer to an INQUIRE command that we did earlier,	 * or an information "event" generated by the card	 * The controller return to us a pseudo frame containing	 * the information in question - Jean II */	infofid = hermes_read_regn(hw, INFOFID);	DEBUG(3, "%s: __orinoco_ev_info(): INFOFID=0x%04x\n", dev->name,	      infofid);	/* Read the info frame header - don't try too hard */	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),			       infofid, 0);	if (err) {		printk(KERN_ERR "%s: error %d reading info frame. "		       "Frame dropped.\n", dev->name, err);		return;	}		switch (le16_to_cpu(info.type)) {	case HERMES_INQ_TALLIES: {		struct hermes_tallies_frame tallies;		struct iw_statistics *wstats = &priv->wstats;		int len = le16_to_cpu(info.len) - 1;				if (len > (sizeof(tallies) / 2)) {			DEBUG(1, "%s: tallies frame too long.\n", dev->name);			len = sizeof(tallies) / 2;

⌨️ 快捷键说明

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