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

📄 orinoco.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
					   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;		}	}	/* Set promiscuity / multicast*/	priv->promiscuous = 0;	priv->mc_count = 0;	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */	return 0;}/* xyzzy */static int orinoco_reconfigure(struct orinoco_private *priv){	struct hermes *hw = &priv->hw;	unsigned long flags;	int err = 0;	orinoco_lock(priv, &flags);	err = hermes_disable_port(hw, 0);	if (err) {		printk(KERN_ERR "%s: Unable to disable port in orinco_reconfigure()\n",		       priv->ndev->name);		goto out;	}	err = __orinoco_program_rids(priv);	if (err)		goto out;	err = hermes_enable_port(hw, 0);	if (err) {		printk(KERN_ERR "%s: Unable to enable port in orinco_reconfigure()\n",		       priv->ndev->name);		goto out;	} out:	orinoco_unlock(priv, &flags);	return err;}/* This must be called from user context, without locks held - use * schedule_task() */static void orinoco_reset(struct net_device *dev){	struct orinoco_private *priv = dev->priv;	int err;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return;	priv->hw_unavailable = 1;	orinoco_unlock(priv, &flags);	if (priv->hard_reset)		err = (*priv->hard_reset)(priv);	if (err) {		printk(KERN_ERR "%s: orinoco_reset: Error %d performing hard reset\n",		       dev->name, err);		/* FIXME: shutdown of some sort */		return;	}	err = orinoco_reinit_firmware(dev);	if (err) {		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",		       dev->name, err);		return;	}	spin_lock_irqsave(&priv->lock, flags);	priv->hw_unavailable = 0;	err = __orinoco_up(dev);	if (err) {		printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",		       dev->name, err);	} else		dev->trans_start = jiffies;	orinoco_unlock(priv, &flags);	return;}/********************************************************************//* Internal helper functions                                        *//********************************************************************/static inline voidset_port_type(struct orinoco_private *priv){	switch (priv->iw_mode) {	case IW_MODE_INFRA:		priv->port_type = 1;		priv->createibss = 0;		break;	case IW_MODE_ADHOC:		if (priv->prefer_port3) {			priv->port_type = 3;			priv->createibss = 0;		} else {			priv->port_type = priv->ibss_port;			priv->createibss = 1;		}		break;	default:		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",		       priv->ndev->name);	}}static inline intis_snap(struct header_struct *hdr){	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);}static voidorinoco_set_multicast_list(struct net_device *dev){	struct orinoco_private *priv = dev->priv;	unsigned long flags;	if (orinoco_lock(priv, &flags) != 0) {		printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "		       "called when hw_unavailable\n", dev->name);		return;	}	__orinoco_set_multicast_list(dev);	orinoco_unlock(priv, &flags);}/********************************************************************//* Hardware control functions                                       *//********************************************************************/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_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]){	hermes_t *hw = &priv->hw;	int err = 0;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,			      ETH_ALEN, NULL, buf);	orinoco_unlock(priv, &flags);	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;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;	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, &flags);	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;	unsigned long flags;	err = orinoco_lock(priv, &flags);	if (err)		return err;		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);	if (err)		goto out;	/* Intersil firmware 1.3.5 returns 0 when the interface is down */	if (channel == 0) {		err = -EBUSY;		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;

⌨️ 快捷键说明

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