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

📄 orinoco.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
		}				/* Read directly the data (no seek) */		hermes_read_words(hw, HERMES_DATA1, (void *) &tallies, len);				/* Increment our various counters */		/* wstats->discard.nwid - no wrong BSSID stuff */		wstats->discard.code +=			le16_to_cpu(tallies.RxWEPUndecryptable);		if (len == (sizeof(tallies) / 2))  			wstats->discard.code +=				le16_to_cpu(tallies.RxDiscards_WEPICVError) +				le16_to_cpu(tallies.RxDiscards_WEPExcluded);		wstats->discard.misc +=			le16_to_cpu(tallies.TxDiscardsWrongSA);#if WIRELESS_EXT > 11		wstats->discard.fragment +=			le16_to_cpu(tallies.RxMsgInBadMsgFragments);		wstats->discard.retries +=			le16_to_cpu(tallies.TxRetryLimitExceeded);		/* wstats->miss.beacon - no match */#if ORINOCO_DEBUG > 3		/* Hack for debugging - should not be taken as an example */		wstats->discard.nwid += le16_to_cpu(tallies.TxUnicastFrames);		wstats->miss.beacon += le16_to_cpu(tallies.RxUnicastFrames);#endif#endif /* WIRELESS_EXT > 11 */	}	break;	default:		DEBUG(1, "%s: Unknown information frame received (type %04x).\n",		      priv->ndev->name, le16_to_cpu(info.type));		/* We don't actually do anything about it */		break;	}}static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw){	struct net_device *dev = priv->ndev;	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);	DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", 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 < sizeof(struct header_struct)) {		printk(KERN_WARNING "%s: Undersized frame received (%d bytes)\n",		       dev->name, length);		stats->rx_length_errors++;		stats->rx_errors++;		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);		stats->rx_dropped++;		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 (note : only 3 bytes out of 6).	 */	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||	   is_snap(&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) {			stats->rx_length_errors++;			stats->rx_dropped++;			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 header. "		       "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++;	add_rx_bytes(stats, length);	return; drop:		if (skb)		dev_kfree_skb_irq(skb);	return;}static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw){	struct net_device *dev = priv->ndev;	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++;	netif_wake_queue(dev);	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);}static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw){/*  	struct net_device *dev = priv->ndev; */	struct net_device_stats *stats = &priv->stats;/*  	u16 fid = hermes_read_regn(hw, TXCOMPLFID); *//*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev->name, fid); */	stats->tx_packets++;	netif_wake_queue(priv->ndev);	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);}static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw){	struct net_device *dev = priv->ndev;	u16 fid = hermes_read_regn(hw, ALLOCFID);	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev->name, fid);	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, vendor, major, minor;} __attribute__ ((packed));static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id){	u32 firmver = ((u32)sta_id->major << 16) | sta_id->minor;		if (sta_id->vendor == 1)		return FIRMWARE_TYPE_AGERE;	else if ((sta_id->vendor == 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 = dev->priv;	hermes_t *hw = &priv->hw;	int err;	struct sta_id sta_id;	u32 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.vendor);	le16_to_cpus(&sta_id.major);	le16_to_cpus(&sta_id.minor);	firmver = ((u32)sta_id.major << 16) | sta_id.minor;	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",	       dev->name, sta_id.id, sta_id.vendor,	       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;	priv->broken_cor_reset = 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);		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;		/* FIXME: Which firmware really do have a broken reset */		priv->broken_cor_reset = (firmver < 0x60000);		/* 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.%02d\n", dev->name,		       sta_id.major, sta_id.minor);		priv->has_ibss = (firmver >= 0x00007); /* FIXME */		priv->has_big_wep = priv->has_wep = (firmver >= 0x00008);		priv->has_pm = (firmver >= 0x00007);		if (firmver >= 0x00008)			priv->ibss_port = 0;		else {			printk(KERN_NOTICE "%s: Intersil firmware earlier "			       "than v0.08 - 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 = dev->priv;	hermes_t *hw = &priv->hw;	int err = 0;	struct hermes_idstring nickbuf;	u16 reclen;	int len;	TRACE_ENTER("orinoco");	orinoco_lock(priv);	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;	/* Do standard firmware reset */	err = hermes_reset(hw);

⌨️ 快捷键说明

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