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

📄 orinoco.c

📁 linux 下的无限网卡驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	int frame_size;	TRACE_ENTER(priv->ndev.name);	/* Stop other people bothering us */	dldwd_lock(priv);	__dldwd_stop_irqs(priv);	/* Check if we need a card reset */	if((priv->need_card_reset) && (priv->card_reset_handler != NULL))		priv->card_reset_handler(priv);	/* Do standard firmware reset if we can */	err = __dldwd_hw_reset(priv);	if (err)		goto out;	frame_size = TX_NICBUF_SIZE;	/* This stupid bug is present in Intel firmware 1.10, and	 * may be fixed in later firmwares - Jean II */	if(priv->broken_allocate)		frame_size = TX_NICBUF_SIZE_BUG;	err = hermes_allocate(hw, frame_size, &priv->txfid);	if (err)		goto out;	/* Now set up all the parameters on the card */		/* Set up the link mode */		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PORTTYPE, priv->port_type);	if (err)		goto out;	if (priv->has_ibss) {		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CREATEIBSS,					   priv->allow_ibss);		if (err)			goto out;		if((strlen(priv->desired_essid) == 0) && (priv->allow_ibss)		   && (!priv->has_ibss_any)) {			printk(KERN_WARNING "%s: This firmware requires an \ESSID in IBSS-Ad-Hoc mode.\n", dev->name);			/* With wvlan_cs, in this case, we would crash.			 * hopefully, this driver will behave better...			 * Jean II */		}	}	/* Set up encryption */	if (priv->has_wep) {		err = __dldwd_hw_setup_wep(priv);		if (err)			goto out;	}	/* Set the desired ESSID */	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));	err = hermes_write_ltv(hw, USER_BAP, (priv->port_type == 3) ?			       HERMES_RID_CNF_OWN_SSID : HERMES_RID_CNF_DESIRED_SSID,			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),			       &idbuf);	if (err)		goto out;	/* Set the station name */	idbuf.len = cpu_to_le16(strlen(priv->nick));	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNF_NICKNAME,			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),			       &idbuf);	if (err)		goto out;	/* Set the channel/frequency */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CHANNEL, priv->channel);	if (err)		goto out;	/* Set AP density */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, priv->ap_density);	if (err)		goto out;	/* Set RTS threshold */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_RTS_THRESH, priv->rts_thresh);	if (err)		goto out;	/* Set fragmentation threshold or MWO robustness */	if (priv->has_mwo)		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNF_MWO_ROBUST, priv->mwo_robust);	else		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNF_FRAG_THRESH, priv->frag_thresh);	if (err)		goto out;	/* Set bitrate */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_RATE_CTRL,				   priv->tx_rate_ctrl);	if (err)		goto out;	/* Set power management */	if (priv->has_pm) {		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_ENABLE,					   priv->pm_on);		if (err)			goto out;		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_MCAST_RX,					   priv->pm_mcast);		if (err)			goto out;		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD,					   priv->pm_period);		if (err)			goto out;		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER,					   priv->pm_timeout);		if (err)			goto out;	}	/* Set preamble - only for Symbol so far... */	if (priv->has_preamble) {		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_PREAMBLE,					   priv->preamble);		if (err) {			printk(KERN_WARNING "%s: Can't set preamble!\n", dev->name);			goto out;		}	}	/* Set promiscuity / multicast*/	priv->promiscuous = 0;	priv->allmulti = 0;	priv->mc_count = 0;	__dldwd_set_multicast_list(dev);		err = hermes_enable_port(hw, DLDWD_MACPORT);	if (err)		goto out;		__dldwd_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |			   HERMES_EV_TX | HERMES_EV_TXEXC |			   HERMES_EV_WTERR | HERMES_EV_INFO |			   HERMES_EV_INFDROP); out:	dldwd_unlock(priv);	TRACE_EXIT(priv->ndev.name);	return err;}static int __dldwd_hw_setup_wep(dldwd_priv_t *priv){	hermes_t *hw = &priv->hw;	int err = 0;	int	master_wep_flag;	int	auth_flag;	switch (priv->firmware_type) {	case FIRMWARE_TYPE_LUCENT: /* Lucent style WEP */		if (priv->wep_on) {			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_KEY, priv->tx_key);			if (err)				return err;						err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNF_KEYS, &priv->keys);			if (err)				return err;		}		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_WEP_ON, priv->wep_on);		if (err)			return err;		break;	case FIRMWARE_TYPE_PRISM2: /* Prism II style WEP */	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */		master_wep_flag = 0;		/* Off */		if (priv->wep_on) {			char keybuf[LARGE_KEY_SIZE+1];			int keylen;			int i;			/* Fudge around firmware weirdness */			keylen = priv->keys[priv->tx_key].len;			/* Write all 4 keys */			for(i = 0; i < MAX_KEYS; i++) {				memset(keybuf, 0, sizeof(keybuf));				memcpy(keybuf, priv->keys[i].data,				       priv->keys[i].len);				err = hermes_write_ltv(hw, USER_BAP,						       HERMES_RID_CNF_PRISM2_KEY0 + i,						       HERMES_BYTES_TO_RECLEN(keylen),						       keybuf);				if (err)					return err;			}			/* Write the index of the key used in transmission */			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_TX_KEY,						   priv->tx_key);			if (err)				return err;			/* Authentication is where Prism2 and Symbol			 * firmware differ... */			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {				/* Symbol cards : set the authentication :				 * 0 -> no encryption, 1 -> open,				 * 2 -> shared key				 * 3 -> shared key 128 -> AP only */				if(priv->wep_restrict)					auth_flag = 2;				else					auth_flag = 1;				err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_AUTH_TYPE, auth_flag);				if (err)					return err;				/* Master WEP setting is always 3 */				master_wep_flag = 3;			} else {				/* Prism2 card : we need to modify master				 * WEP setting */				if(priv->wep_restrict)					master_wep_flag = 3;				else					master_wep_flag = 1;			}		}				/* Master WEP setting : on/off */		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, 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;		}	}	return 0;}static int dldwd_hw_get_bssid(dldwd_priv_t *priv, char buf[ETH_ALEN]){	hermes_t *hw = &priv->hw;	int err = 0;	dldwd_lock(priv);	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_BSSID,			      ETH_ALEN, NULL, buf);	dldwd_unlock(priv);	return err;}static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active,			      char buf[IW_ESSID_MAX_SIZE+1]){	hermes_t *hw = &priv->hw;	int err = 0;	hermes_id_t essidbuf;	char *p = (char *)(&essidbuf.val);	int len;	TRACE_ENTER(priv->ndev.name);	dldwd_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 OWN_SSID should always be whatever		 * we set to the card, whereas CURRENT_SSID is the one that		 * may change... - Jean II */		uint16_t rid;		*active = 1;		rid = (priv->port_type == 3) ? HERMES_RID_CNF_OWN_SSID :			HERMES_RID_CNF_DESIRED_SSID;				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_CURRENT_SSID,				      sizeof(essidbuf), NULL, &essidbuf);		if (err)			goto fail_unlock;	}	len = le16_to_cpu(essidbuf.len);	memset(buf, 0, sizeof(buf));	memcpy(buf, p, len);	buf[len] = '\0'; fail_unlock:	dldwd_unlock(priv);	TRACE_EXIT(priv->ndev.name);	return err;       }static long dldwd_hw_get_freq(dldwd_priv_t *priv){		hermes_t *hw = &priv->hw;	int err = 0;	uint16_t channel;	long freq = 0;	dldwd_lock(priv);		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_CHANNEL, &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:	dldwd_unlock(priv);	if (err > 0)		err = -EBUSY;	return err ? err : freq;}static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,				    int32_t *rates, int max){	hermes_t *hw = &priv->hw;	hermes_id_t list;	unsigned char *p = (unsigned char *)&list.val;	int err = 0;	int num;	int i;	dldwd_lock(priv);	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_DATARATES, sizeof(list),			      NULL, &list);	dldwd_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;}#ifndef PCMCIA_DEBUGstatic inline void show_rx_frame(struct dldwd_frame_hdr *frame) {}#elsestatic void show_rx_frame(struct dldwd_frame_hdr *frame){	printk(KERN_DEBUG "RX descriptor:\n");	printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);	printk(KERN_DEBUG "  res1        = 0x%04x\n", frame->desc.res1);	printk(KERN_DEBUG "  res2        = 0x%04x\n", frame->desc.res2);	printk(KERN_DEBUG "  q_info      = 0x%04x\n", frame->desc.q_info);	printk(KERN_DEBUG "  res3        = 0x%04x\n", frame->desc.res3);	printk(KERN_DEBUG "  res4        = 0x%04x\n", frame->desc.res4);	printk(KERN_DEBUG "  tx_ctl      = 0x%04x\n", frame->desc.tx_ctl);	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/* * Interrupt handler */void dldwd_interrupt(int irq, void * dev_id, struct pt_regs *regs){	dldwd_priv_t *priv = (dldwd_priv_t *) dev_id;	hermes_t *hw = &priv->hw;	struct net_device *dev = &priv->ndev;	int count = IRQ_LOOP_MAX;	uint16_t evstat, events;	static int old_time = 0, timecount = 0; /* Eugh, revolting hack for now */	if (test_and_set_bit(DLDWD_STATE_INIRQ, &priv->state))		BUG();	if (! dldwd_irqs_allowed(priv)) {		clear_bit(DLDWD_STATE_INIRQ, &priv->state);		return;	}	DEBUG(3, "%s: dldwd_interrupt()\n", priv->ndev.name);	while (1) {		if (jiffies != old_time)			timecount = 0;		if ( (++timecount > 50) || (! count--) ) {			printk(KERN_CRIT "%s: IRQ handler is looping too \much! Shutting down.\n",

⌨️ 快捷键说明

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