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

📄 orinoco.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
				le16_to_cpu(tallies.RxDiscards_WEPICVError) +				le16_to_cpu(tallies.RxDiscards_WEPExcluded);		wstats->discard.misc +=			le16_to_cpu(tallies.TxDiscardsWrongSA);		wstats->discard.fragment +=			le16_to_cpu(tallies.RxMsgInBadMsgFragments);		wstats->discard.retries +=			le16_to_cpu(tallies.TxRetryLimitExceeded);		/* wstats->miss.beacon - no match */	}	break;	case HERMES_INQ_LINKSTATUS: {		struct hermes_linkstatus linkstatus;		u16 newstatus;		if (len != sizeof(linkstatus)) {			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",			       dev->name, len);			break;		}		hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,				  len / 2);		newstatus = le16_to_cpu(linkstatus.linkstatus);		if ( (newstatus == HERMES_LINKSTATUS_CONNECTED)		     || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)		     || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE) )			priv->connected = 1;		else if ( (newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)			  || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)			  || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)			  || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED) )			priv->connected = 0;		if (newstatus != priv->last_linkstatus)			print_linkstatus(dev, newstatus);		priv->last_linkstatus = newstatus;	}	break;	default:		printk(KERN_DEBUG "%s: Unknown information frame received "		       "(type %04x).\n", dev->name, type);		/* We don't actually do anything about it */		break;	}}static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw){	if (net_ratelimit())		printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);}/********************************************************************//* Internal hardware control routines                               *//********************************************************************/int __orinoco_up(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	struct hermes *hw = &priv->hw;	int err;	err = __orinoco_program_rids(dev);	if (err) {		printk(KERN_ERR "%s: Error %d configuring card\n",		       dev->name, err);		return err;	}	/* Fire things up again */	hermes_set_irqmask(hw, ORINOCO_INTEN);	err = hermes_enable_port(hw, 0);	if (err) {		printk(KERN_ERR "%s: Error %d enabling MAC port\n",		       dev->name, err);		return err;	}	netif_start_queue(dev);	return 0;}int __orinoco_down(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	struct hermes *hw = &priv->hw;	int err;	netif_stop_queue(dev);	if (! priv->hw_unavailable) {		if (! priv->broken_disableport) {			err = hermes_disable_port(hw, 0);			if (err) {				/* Some firmwares (e.g. Intersil 1.3.x) seem				 * to have problems disabling the port, oh				 * well, too bad. */				printk(KERN_WARNING "%s: Error %d disabling MAC port\n",				       dev->name, err);				priv->broken_disableport = 1;			}		}		hermes_set_irqmask(hw, 0);		hermes_write_regn(hw, EVACK, 0xffff);	}		/* firmware will have to reassociate */	priv->last_linkstatus = 0xffff;	priv->connected = 0;	return 0;}int orinoco_reinit_firmware(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	struct hermes *hw = &priv->hw;	int err;	err = hermes_init(hw);	if (err)		return err;	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);	if (err == -EIO) {		/* Try workaround for old Symbol firmware bug */		printk(KERN_WARNING "%s: firmware ALLOC bug detected "		       "(old Symbol firmware?). Trying to work around... ",		       dev->name);				priv->nicbuf_size = TX_NICBUF_SIZE_BUG;		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);		if (err)			printk("failed!\n");		else			printk("ok.\n");	}	return err;}static int __orinoco_hw_set_bitrate(struct orinoco_private *priv){	hermes_t *hw = &priv->hw;	int err = 0;	if (priv->bitratemode >= BITRATE_TABLE_SIZE) {		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",		       priv->ndev->name, priv->bitratemode);		return -EINVAL;	}	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE:		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFTXRATECONTROL,					   bitrate_table[priv->bitratemode].agere_txratectrl);		break;	case FIRMWARE_TYPE_INTERSIL:	case FIRMWARE_TYPE_SYMBOL:		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFTXRATECONTROL,					   bitrate_table[priv->bitratemode].intersil_txratectrl);		break;	default:		BUG();	}	return err;}static int __orinoco_hw_setup_wep(struct orinoco_private *priv){	hermes_t *hw = &priv->hw;	int err = 0;	int	master_wep_flag;	int	auth_flag;	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */		if (priv->wep_on) {			err = hermes_write_wordrec(hw, USER_BAP,						   HERMES_RID_CNFTXKEY_AGERE,						   priv->tx_key);			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;		}	}	return 0;}static int __orinoco_program_rids(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	hermes_t *hw = &priv->hw;	int err;	struct hermes_idstring idbuf;	/* Set the MAC address */	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);	if (err) {		printk(KERN_ERR "%s: Error %d setting MAC address\n",		       dev->name, err);		return err;	}	/* Set up the link mode */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,				   priv->port_type);	if (err) {		printk(KERN_ERR "%s: Error %d setting port type\n",		       dev->name, err);		return err;	}	/* Set the channel/frequency */	if (priv->channel == 0) {		printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);		if (priv->createibss)			priv->channel = 10;	}	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,				   priv->channel);	if (err) {		printk(KERN_ERR "%s: Error %d setting channel\n",		       dev->name, err);		return err;	}	if (priv->has_ibss) {		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFCREATEIBSS,					   priv->createibss);		if (err) {			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", dev->name, err);			return err;		}		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)		   && (!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 the desired ESSID */	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),			       &idbuf);	if (err) {		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",		       dev->name, err);		return err;	}	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),			       &idbuf);	if (err) {		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",		       dev->name, err);		return err;	}	/* 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_CNFOWNNAME,			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),			       &idbuf);	if (err) {		printk(KERN_ERR "%s: Error %d setting nickname\n",		       dev->name, err);		return err;	}	/* Set AP density */	if (priv->has_sensitivity) {		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFSYSTEMSCALE,					   priv->ap_density);		if (err) {			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "			       "Disabling sensitivity control\n",			       dev->name, err);			priv->has_sensitivity = 0;		}	}	/* Set RTS threshold */	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,				   priv->rts_thresh);	if (err) {		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",		       dev->name, err);		return err;	}	/* Set fragmentation threshold or MWO robustness */	if (priv->has_mwo)		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFMWOROBUST_AGERE,					   priv->mwo_robust);	else		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,					   priv->frag_thresh);	if (err) {		printk(KERN_ERR "%s: Error %d setting fragmentation\n",		       dev->name, err);		return err;	}	/* Set bitrate */	err = __orinoco_hw_set_bitrate(priv);	if (err) {		printk(KERN_ERR "%s: Error %d setting bitrate\n",		       dev->name, err);		return err;	}	/* Set power management */	if (priv->has_pm) {		err = hermes_write_wordrec(hw, USER_BAP,

⌨️ 快捷键说明

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