struct header_struct hdr; struct ethhdr *eh; 
struct ethhdr *hdr; 
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, ALIGN(data_len, 2),			       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;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8f2abf4430ef2a131926a537ee6325dc43b0ec28/orinoco.c/clean/drivers/net/wireless/orinoco.c