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

📄 orinoco.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
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 && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {		/* 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;}/* Set fixed AP address */static int __orinoco_hw_set_wap(struct orinoco_private *priv){	int roaming_flag;	int err = 0;	hermes_t *hw = &priv->hw;	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE:		/* not supported */		break;	case FIRMWARE_TYPE_INTERSIL:		if (priv->bssid_fixed)			roaming_flag = 2;		else			roaming_flag = 1;		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFROAMINGMODE,					   roaming_flag);		break;	case FIRMWARE_TYPE_SYMBOL:		err = HERMES_WRITE_RECORD(hw, USER_BAP,					  HERMES_RID_CNFMANDATORYBSSID_SYMBOL,					  &priv->desired_bssid);		break;	}	return err;}/* Change the WEP keys and/or the current keys.  Can be called * either from __orinoco_hw_setup_wep() or directly from * orinoco_ioctl_setiwencode().  In the later case the association * with the AP is not broken (if the firmware can handle it), * which is needed for 802.1x implementations. */static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv){	hermes_t *hw = &priv->hw;	int err = 0;	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE:		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_CNFTXKEY_AGERE,					   priv->tx_key);		if (err)			return err;		break;	case FIRMWARE_TYPE_INTERSIL:	case FIRMWARE_TYPE_SYMBOL:		{			int keylen;			int i;			/* Force uniform key length to work around firmware bugs */			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);						if (keylen > LARGE_KEY_SIZE) {				printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",				       priv->ndev->name, priv->tx_key, keylen);				return -E2BIG;			}			/* Write all 4 keys */			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {				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;		}		break;	}	return 0;}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;	if (priv->wep_on)		__orinoco_hw_setup_wepkeys(priv);	if (priv->wep_restrict)		auth_flag = HERMES_AUTH_SHARED_KEY;	else		auth_flag = HERMES_AUTH_OPEN;	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */		if (priv->wep_on) {			/* Enable the shared-key authentication. */			err = hermes_write_wordrec(hw, USER_BAP,						   HERMES_RID_CNFAUTHENTICATION_AGERE,						   auth_flag);		}		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 */		if (priv->wep_on) {			if (priv->wep_restrict ||			    (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |						  HERMES_WEP_EXCL_UNENCRYPTED;			else				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;			err = hermes_write_wordrec(hw, USER_BAP,						   HERMES_RID_CNFAUTHENTICATION,						   auth_flag);			if (err)				return err;		} else			master_wep_flag = 0;		if (priv->iw_mode == IW_MODE_MONITOR)			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;		/* Master WEP setting : on/off */		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFWEPFLAGS_INTERSIL,					   master_wep_flag);		if (err)			return err;			break;	}	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 && priv->iw_mode != IW_MODE_INFRA) {		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFOWNCHANNEL,					   priv->channel);		if (err) {			printk(KERN_ERR "%s: Error %d setting channel %d\n",			       dev->name, err, priv->channel);			return err;		}	}	if (priv->has_ibss) {		u16 createibss;		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {			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 */			createibss = 0;		} else {			createibss = priv->createibss;		}				err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFCREATEIBSS,					   createibss);		if (err) {			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",			       dev->name, err);			return err;		}	}	/* Set the desired BSSID */	err = __orinoco_hw_set_wap(priv);	if (err) {		printk(KERN_ERR "%s: Error %d setting AP address\n",		       dev->name, err);		return err;	}	/* 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,					   HERMES_RID_CNFPMENABLED,					   priv->pm_on);		if (err) {			printk(KERN_ERR "%s: Error %d setting up PM\n",			       dev->name, err);			return err;		}		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFMULTICASTRECEIVE,					   priv->pm_mcast);		if (err) {			printk(KERN_ERR "%s: Error %d setting up PM\n",			       dev->name, err);			return err;		}		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFMAXSLEEPDURATION,					   priv->pm_period);		if (err) {			printk(KERN_ERR "%s: Error %d setting up PM\n",			       dev->name, err);			return err;		}		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFPMHOLDOVERDURATION,					   priv->pm_timeout);		if (err) {			printk(KERN_ERR "%s: Error %d setting up PM\n",			       dev->name, err);			return err;		}	}	/* Set preamble - only for Symbol so far... */	if (priv->has_preamble) {		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFPREAMBLE_SYMBOL,					   priv->preamble);		if (err) {			printk(KERN_ERR "%s: Error %d setting preamble\n",			       dev->name, err);			return err;		}	}	/* Set up encryption */	if (priv->has_wep) {		err = __orinoco_hw_setup_wep(priv);		if (err) {			printk(KERN_ERR "%s: Error %d activating WEP\n",			       dev->name, err);			return err;		}	}	if (priv->iw_mode == IW_MODE_MONITOR) {		/* Enable monitor mode */		dev->type = ARPHRD_IEEE80211;		err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 					    HERMES_TEST_MONITOR, 0, NULL);	} else {		/* Disable monitor mode */		dev->type = ARPHRD_ETHER;		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |					    HERMES_TEST_STOP, 0, NULL);	}	if (err)		return err;	/* Set promiscuity / multicast*/	priv->promiscuous = 0;	priv->mc_count = 0;	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */	return 0;}/* FIXME: return int? */static void__orinoco_set_multicast_list(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	hermes_t *hw = &priv->hw;	int err = 0;	int promisc, mc_count;	/* The Hermes doesn't seem to have an allmulti mode, so we go	 * into promiscuous mode and let the upper levels deal. */	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||	     (dev->mc_count > MAX_MULTICAST(priv)) ) {		promisc = 1;		mc_count = 0;	} else {		promisc = 0;		mc_count = dev->mc_count;	}	if (promisc != priv->promiscuous) {		err = hermes_write_wordrec(hw, USER_BAP,					   HERMES_RID_CNFPROMISCUOUSMODE,					   promisc);		if (err) {			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",

⌨️ 快捷键说明

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