txb->payload_size = bytes; 
if (host_encrypt) txb->payload_size = frag_size * (nr_frags - 1) + bytes_last_frag; else txb->payload_size = bytes; 
int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev){	struct ieee80211_device *ieee = netdev_priv(dev);	struct ieee80211_txb *txb = NULL;	struct ieee80211_hdr_3addr *frag_hdr;	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,	    rts_required;	unsigned long flags;	struct net_device_stats *stats = &ieee->stats;	int ether_type, encrypt, host_encrypt;	int bytes, fc, hdr_len;	struct sk_buff *skb_frag;	struct ieee80211_hdr_3addr header = {	/* Ensure zero initialized */		.duration_id = 0,		.seq_ctl = 0	};	u8 dest[ETH_ALEN], src[ETH_ALEN];	struct ieee80211_crypt_data *crypt;	spin_lock_irqsave(&ieee->lock, flags);	/* If there is no driver handler to take the TXB, dont' bother	 * creating it... */	if (!ieee->hard_start_xmit) {		printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);		goto success;	}	if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {		printk(KERN_WARNING "%s: skb too small (%d).\n",		       ieee->dev->name, skb->len);		goto success;	}	ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);	crypt = ieee->crypt[ieee->tx_keyidx];	encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&	    ieee->sec.encrypt;	host_encrypt = ieee->host_encrypt && encrypt;	if (!encrypt && ieee->ieee802_1x &&	    ieee->drop_unencrypted && ether_type != ETH_P_PAE) {		stats->tx_dropped++;		goto success;	}	/* Save source and destination addresses */	memcpy(dest, skb->data, ETH_ALEN);	memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);	/* Advance the SKB to the start of the payload */	skb_pull(skb, sizeof(struct ethhdr));	/* Determine total amount of storage required for TXB packets */	bytes = skb->len + SNAP_SIZE + sizeof(u16);	if (host_encrypt)		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |		    IEEE80211_FCTL_PROTECTED;	else		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;	if (ieee->iw_mode == IW_MODE_INFRA) {		fc |= IEEE80211_FCTL_TODS;		/* To DS: Addr1 = BSSID, Addr2 = SA,		   Addr3 = DA */		memcpy(header.addr1, ieee->bssid, ETH_ALEN);		memcpy(header.addr2, src, ETH_ALEN);		memcpy(header.addr3, dest, ETH_ALEN);	} else if (ieee->iw_mode == IW_MODE_ADHOC) {		/* not From/To DS: Addr1 = DA, Addr2 = SA,		   Addr3 = BSSID */		memcpy(header.addr1, dest, ETH_ALEN);		memcpy(header.addr2, src, ETH_ALEN);		memcpy(header.addr3, ieee->bssid, ETH_ALEN);	}	header.frame_ctl = cpu_to_le16(fc);	hdr_len = IEEE80211_3ADDR_LEN;	/* Determine fragmentation size based on destination (multicast	 * and broadcast are not fragmented) */	if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))		frag_size = MAX_FRAG_THRESHOLD;	else		frag_size = ieee->fts;	/* Determine amount of payload per fragment.  Regardless of if	 * this stack is providing the full 802.11 header, one will	 * eventually be affixed to this fragment -- so we must account for	 * it when determining the amount of payload space. */	bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;	if (ieee->config &	    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))		bytes_per_frag -= IEEE80211_FCS_LEN;	/* Each fragment may need to have room for encryptiong pre/postfix */	if (host_encrypt)		bytes_per_frag -= crypt->ops->extra_prefix_len +		    crypt->ops->extra_postfix_len;	/* Number of fragments is the total bytes_per_frag /	 * payload_per_fragment */	nr_frags = bytes / bytes_per_frag;	bytes_last_frag = bytes % bytes_per_frag;	if (bytes_last_frag)		nr_frags++;	else		bytes_last_frag = bytes_per_frag;	rts_required = (frag_size > ieee->rts			&& ieee->config & CFG_IEEE80211_RTS);	if (rts_required)		nr_frags++;	else		bytes_last_frag = bytes_per_frag;	/* When we allocate the TXB we allocate enough space for the reserve	 * and full fragment bytes (bytes_per_frag doesn't include prefix,	 * postfix, header, FCS, etc.) */	txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);	if (unlikely(!txb)) {		printk(KERN_WARNING "%s: Could not allocate TXB\n",		       ieee->dev->name);		goto failed;	}	txb->encrypted = encrypt;	txb->payload_size = bytes;	if (rts_required) {		skb_frag = txb->fragments[0];		frag_hdr =		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);		/*		 * Set header frame_ctl to the RTS.		 */		header.frame_ctl =		    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);		memcpy(frag_hdr, &header, hdr_len);		/*		 * Restore header frame_ctl to the original data setting.		 */		header.frame_ctl = cpu_to_le16(fc);		if (ieee->config &		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))			skb_put(skb_frag, 4);		txb->rts_included = 1;		i = 1;	} else		i = 0;	for (; i < nr_frags; i++) {		skb_frag = txb->fragments[i];		if (host_encrypt)			skb_reserve(skb_frag, crypt->ops->extra_prefix_len);		frag_hdr =		    (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);		memcpy(frag_hdr, &header, hdr_len);		/* If this is not the last fragment, then add the MOREFRAGS		 * bit to the frame control */		if (i != nr_frags - 1) {			frag_hdr->frame_ctl =			    cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);			bytes = bytes_per_frag;		} else {			/* The last fragment takes the remaining length */			bytes = bytes_last_frag;		}		/* Put a SNAP header on the first fragment */		if (i == 0) {			ieee80211_put_snap(skb_put					   (skb_frag, SNAP_SIZE + sizeof(u16)),					   ether_type);			bytes -= SNAP_SIZE + sizeof(u16);		}		memcpy(skb_put(skb_frag, bytes), skb->data, bytes);		/* Advance the SKB... */		skb_pull(skb, bytes);		/* Encryption routine will move the header forward in order		 * to insert the IV between the header and the payload */		if (host_encrypt)			ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);		/* ipw2200/2915 Hardware encryption doesn't support TKIP MIC */		if (!ieee->host_encrypt && encrypt &&		    (ieee->sec.level == SEC_LEVEL_2) &&		    crypt && crypt->ops && crypt->ops->encrypt_msdu) {			int res = 0;			res = crypt->ops->encrypt_msdu(skb_frag, hdr_len,						       crypt->priv);			if (res < 0) {				IEEE80211_ERROR("TKIP MIC encryption failed\n");				goto failed;			}		}		if (ieee->config &		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))			skb_put(skb_frag, 4);	}      success:	spin_unlock_irqrestore(&ieee->lock, flags);	dev_kfree_skb_any(skb);	if (txb) {		if ((*ieee->hard_start_xmit) (txb, dev) == 0) {			stats->tx_packets++;			stats->tx_bytes += txb->payload_size;			return 0;		}		ieee80211_txb_free(txb);	}	return 0;      failed:	spin_unlock_irqrestore(&ieee->lock, flags);	netif_stop_queue(dev);	stats->tx_errors++;	return 1;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/1264fc0498e1e20f97b1ab690e523e7a7fc50eab/ieee80211_tx.c/clean/net/ieee80211/ieee80211_tx.c