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

📄 orinoco.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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_rx(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	struct net_device_stats *stats = &priv->stats;	struct iw_statistics *wstats = &priv->wstats;	struct sk_buff *skb = NULL;	u16 rxfid, status;	int length, data_len, data_off;	char *p;	struct hermes_rx_descriptor desc;	struct header_struct hdr;	struct ethhdr *eh;	int err;	rxfid = hermes_read_regn(hw, RXFID);	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),			       rxfid, 0);	if (err) {		printk(KERN_ERR "%s: error %d reading Rx descriptor. "		       "Frame dropped.\n", dev->name, err);		stats->rx_errors++;		goto drop;	}	status = le16_to_cpu(desc.status);		if (status & HERMES_RXSTAT_ERR) {		if (status & HERMES_RXSTAT_UNDECRYPTABLE) {			wstats->discard.code++;			DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",			       dev->name);		} else {			stats->rx_crc_errors++;			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);		}		stats->rx_errors++;		goto drop;	}	/* For now we ignore the 802.11 header completely, assuming           that the card's firmware has handled anything vital */	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),			       rxfid, HERMES_802_3_OFFSET);	if (err) {		printk(KERN_ERR "%s: error %d reading frame header. "		       "Frame dropped.\n", dev->name, err);		stats->rx_errors++;		goto drop;	}	length = ntohs(hdr.len);		/* Sanity checks */	if (length < 3) { /* No for even an 802.2 LLC header */		/* At least on Symbol firmware with PCF we get quite a                   lot of these legitimately - Poll frames with no                   data. */		stats->rx_dropped++;		goto drop;	}	if (length > IEEE802_11_DATA_LEN) {		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",		       dev->name, length);		stats->rx_length_errors++;		stats->rx_errors++;		goto drop;	}	/* We need space for the packet data itself, plus an ethernet	   header, plus 2 bytes so we can align the IP header on a	   32bit boundary, plus 1 byte so we can read in odd length	   packets from the card, which has an IO granularity of 16	   bits */  	skb = dev_alloc_skb(length+ETH_HLEN+2+1);	if (!skb) {		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",		       dev->name);		goto drop;	}	skb_reserve(skb, 2); /* This way the IP header is aligned */	/* Handle decapsulation	 * In most cases, the firmware tell us about SNAP frames.	 * For some reason, the SNAP frames sent by LinkSys APs	 * are not properly recognised by most firmwares.	 * So, check ourselves */	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||	   is_ethersnap(&hdr)) {		/* These indicate a SNAP within 802.2 LLC within		   802.11 frame which we'll need to de-encapsulate to		   the original EthernetII frame. */		if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */			stats->rx_length_errors++;			goto drop;		}		/* Remove SNAP header, reconstruct EthernetII frame */		data_len = length - ENCAPS_OVERHEAD;		data_off = HERMES_802_3_OFFSET + sizeof(hdr);		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);		memcpy(eh, &hdr, 2 * ETH_ALEN);		eh->h_proto = hdr.ethertype;	} else {		/* All other cases indicate a genuine 802.3 frame.  No		   decapsulation needed.  We just throw the whole		   thing in, and hope the protocol layer can deal with		   it as 802.3 */		data_len = length;		data_off = HERMES_802_3_OFFSET;		/* FIXME: we re-read from the card data we already read here */	}	p = skb_put(skb, data_len);	err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),			       rxfid, data_off);	if (err) {		printk(KERN_ERR "%s: error %d reading frame. "		       "Frame dropped.\n", dev->name, err);		stats->rx_errors++;		goto drop;	}	dev->last_rx = jiffies;	skb->dev = dev;	skb->protocol = eth_type_trans(skb, dev);	skb->ip_summed = CHECKSUM_NONE;		/* Process the wireless stats if needed */	orinoco_stat_gather(dev, skb, &desc);	/* Pass the packet to the networking stack */	netif_rx(skb);	stats->rx_packets++;	stats->rx_bytes += length;	return; drop:		stats->rx_dropped++;	if (skb)		dev_kfree_skb_irq(skb);	return;}static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	struct net_device_stats *stats = &priv->stats;	u16 fid = hermes_read_regn(hw, TXCOMPLFID);	struct hermes_tx_descriptor desc;	int err = 0;	if (fid == DUMMY_FID)		return; /* Nothing's really happened */	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);	if (err) {		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "		       "(FID=%04X error %d)\n",		       dev->name, fid, err);	} else {		DEBUG(1, "%s: Tx error, status %d\n",		      dev->name, le16_to_cpu(desc.status));	}		stats->tx_errors++;	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);}static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	struct net_device_stats *stats = &priv->stats;	stats->tx_packets++;	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);}static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	u16 fid = hermes_read_regn(hw, ALLOCFID);	if (fid != priv->txfid) {		if (fid != DUMMY_FID)			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",			       dev->name, fid);		return;	} else {		netif_wake_queue(dev);	}	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);}struct sta_id {	u16 id, variant, major, minor;} __attribute__ ((packed));static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id){	/* FIXME: this is fundamentally broken */	unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;		if (sta_id->variant == 1)		return FIRMWARE_TYPE_AGERE;	else if ((sta_id->variant == 2) &&		   ((firmver == 0x10001) || (firmver == 0x20001)))		return FIRMWARE_TYPE_SYMBOL;	else		return FIRMWARE_TYPE_INTERSIL;}static void determine_firmware(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	hermes_t *hw = &priv->hw;	int err;	struct sta_id sta_id;	unsigned int firmver;	char tmp[SYMBOL_MAX_VER_LEN+1];	/* Get the firmware version */	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);	if (err) {		printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",		       dev->name, err);		memset(&sta_id, 0, sizeof(sta_id));	}	le16_to_cpus(&sta_id.id);	le16_to_cpus(&sta_id.variant);	le16_to_cpus(&sta_id.major);	le16_to_cpus(&sta_id.minor);	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",	       dev->name, sta_id.id, sta_id.variant,	       sta_id.major, sta_id.minor);	if (! priv->firmware_type)		priv->firmware_type = determine_firmware_type(dev, &sta_id);	/* Default capabilities */	priv->has_sensitivity = 1;	priv->has_mwo = 0;	priv->has_preamble = 0;	priv->has_port3 = 1;	priv->has_ibss = 1;	priv->has_ibss_any = 0;	priv->has_wep = 0;	priv->has_big_wep = 0;	/* Determine capabilities from the firmware version */	switch (priv->firmware_type) {	case FIRMWARE_TYPE_AGERE:		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "		       "version %d.%02d\n", dev->name,		       sta_id.major, sta_id.minor);		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;		priv->has_ibss = (firmver >= 0x60006);		priv->has_ibss_any = (firmver >= 0x60010);		priv->has_wep = (firmver >= 0x40020);		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell					  Gold cards from the others? */		priv->has_mwo = (firmver >= 0x60000);		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */		priv->ibss_port = 1;		/* Tested with Agere firmware :		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II		 * Tested CableTron firmware : 4.32 => Anton */		break;	case FIRMWARE_TYPE_SYMBOL:		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */		/* Intel MAC : 00:02:B3:* */		/* 3Com MAC : 00:50:DA:* */		memset(tmp, 0, sizeof(tmp));		/* Get the Symbol firmware version */		err = hermes_read_ltv(hw, USER_BAP,				      HERMES_RID_SECONDARYVERSION_SYMBOL,				      SYMBOL_MAX_VER_LEN, NULL, &tmp);		if (err) {			printk(KERN_WARNING			       "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",			       dev->name, err);			firmver = 0;			tmp[0] = '\0';		} else {			/* The firmware revision is a string, the format is			 * something like : "V2.20-01".			 * Quick and dirty parsing... - Jean II			 */			firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)				| ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)				| (tmp[7] - '0');			tmp[SYMBOL_MAX_VER_LEN] = '\0';		}		printk(KERN_DEBUG "%s: Looks like a Symbol firmware "		       "version [%s] (parsing to %X)\n", dev->name,		       tmp, firmver);		priv->has_ibss = (firmver >= 0x20000);		priv->has_wep = (firmver >= 0x15012);		priv->has_big_wep = (firmver >= 0x20000);		priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);		priv->has_preamble = (firmver >= 0x20000);		priv->ibss_port = 4;		/* Tested with Intel firmware : 0x20015 => Jean II */		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */		break;	case FIRMWARE_TYPE_INTERSIL:		/* D-Link, Linksys, Adtron, ZoomAir, and many others...		 * Samsung, Compaq 100/200 and Proxim are slightly		 * different and less well tested */		/* D-Link MAC : 00:40:05:* */		/* Addtron MAC : 00:90:D1:* */		printk(KERN_DEBUG "%s: Looks like an Intersil firmware "		       "version %d.%d.%d\n", dev->name,		       sta_id.major, sta_id.minor, sta_id.variant);		firmver = ((unsigned long)sta_id.major << 16) |			((unsigned long)sta_id.minor << 8) | sta_id.variant;		priv->has_ibss = (firmver >= 0x000700); /* FIXME */		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);		priv->has_pm = (firmver >= 0x000700);		if (firmver >= 0x000800)			priv->ibss_port = 0;		else {			printk(KERN_NOTICE "%s: Intersil firmware earlier "			       "than v0.8.x - several features not supported\n",			       dev->name);			priv->ibss_port = 1;		}		break;	default:		break;	}}/* * struct net_device methods */static intorinoco_init(struct net_device *dev){	struct orinoco_private *priv = netdev_priv(dev);	hermes_t *hw = &priv->hw;	int err = 0;	struct hermes_idstring nickbuf;	u16 reclen;	int len;	TRACE_ENTER(dev->name);	/* No need to lock, the hw_unavailable flag is already set in	 * alloc_orinocodev() */	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;	/* Initialize the firmware */	err = hermes_init(hw);	if (err != 0) {		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",		       dev->name, err);		goto out;	}	determine_firmware(dev);	if (priv->has_port3)		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);	if (priv->has_ibss)		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",		       dev->name);	if (priv->has_wep) {		printk(KERN_DEBUG "%s: WEP supported, ", dev->name);		if (priv->has_big_wep)			printk("104-bit key\n");		else			printk("40-bit key\n");	}	/* Get the MAC address */	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,			     

⌨️ 快捷键说明

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