int ret = (*ieee->hard_start_xmit) (txb, dev); 
int ret = (*ieee->hard_start_xmit) (txb, dev, priority); 
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, host_encrypt_msdu;	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;	int priority = skb->priority;	int snapped = 0;	if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))		return NETDEV_TX_BUSY;	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;	host_encrypt_msdu = ieee->host_encrypt_msdu && 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;	/* Encrypt msdu first on the whole data packet. */	if ((host_encrypt || host_encrypt_msdu) &&	    crypt && crypt->ops && crypt->ops->encrypt_msdu) {		int res = 0;		int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +		    crypt->ops->extra_msdu_postfix_len;		struct sk_buff *skb_new = dev_alloc_skb(len);		if (unlikely(!skb_new))			goto failed;		skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);		memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);		snapped = 1;		ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),				    ether_type);		memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);		res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);		if (res < 0) {			IEEE80211_ERROR("msdu encryption failed\n");			dev_kfree_skb_any(skb_new);			goto failed;		}		dev_kfree_skb_any(skb);		skb = skb_new;		bytes += crypt->ops->extra_msdu_prefix_len +		    crypt->ops->extra_msdu_postfix_len;		skb_pull(skb, hdr_len);	}	if (host_encrypt || ieee->host_open_frag) {		/* Determine fragmentation size based on destination (multicast		 * and broadcast are not fragmented) */		if (is_multicast_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_mpdu_prefix_len +			    crypt->ops->extra_mpdu_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;	} else {		nr_frags = 1;		bytes_per_frag = bytes_last_frag = bytes;		frag_size = bytes + IEEE80211_3ADDR_LEN;	}	rts_required = (frag_size > ieee->rts			&& ieee->config & CFG_IEEE80211_RTS);	if (rts_required)		nr_frags++;	/* 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;	if (host_encrypt)		txb->payload_size = frag_size * (nr_frags - 1) +		    bytes_last_frag;	else		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_mpdu_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;		}		if (i == 0 && !snapped) {			ieee80211_copy_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);		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) {		int ret = (*ieee->hard_start_xmit) (txb, dev);		if (ret == 0) {			stats->tx_packets++;			stats->tx_bytes += txb->payload_size;			return 0;		}		if (ret == NETDEV_TX_BUSY) {			printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "			       "driver should report queue full via "			       "ieee_device->is_queue_full.\n",			       ieee->dev->name);		}		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/9e8571affd1c54b9638b4ff9844e47aae07310f6/ieee80211_tx.c/buggy/net/ieee80211/ieee80211_tx.c