hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb-> 
hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb-> 
static void ipw2100_tx_send_data(struct ipw2100_priv *priv){	struct list_head *element;	struct ipw2100_tx_packet *packet;	struct ipw2100_bd_queue *txq = &priv->tx_queue;	struct ipw2100_bd *tbd;	int next = txq->next;        int i = 0;	struct ipw2100_data_header *ipw_hdr;	struct ieee80211_hdr *hdr;	while (!list_empty(&priv->tx_pend_list)) {		/* if there isn't enough space in TBD queue, then		 * don't stuff a new one in.		 * NOTE: 4 are needed as a data will take two,		 *       and there is a minimum of 2 that must be		 *       maintained between the r and w indexes		 */		element = priv->tx_pend_list.next;                packet = list_entry(element, struct ipw2100_tx_packet, list);		if (unlikely(1 + packet->info.d_struct.txb->nr_frags >			     IPW_MAX_BDS)) {			/* TODO: Support merging buffers if more than			 * IPW_MAX_BDS are used */			IPW_DEBUG_INFO(			       "%s: Maximum BD theshold exceeded.  "			       "Increase fragmentation level.\n",			       priv->net_dev->name);		}		if (txq->available <= 3 +		    packet->info.d_struct.txb->nr_frags) {			IPW_DEBUG_TX("no room in tx_queue\n");			break;		}		list_del(element);		DEC_STAT(&priv->tx_pend_stat);		tbd = &txq->drv[txq->next];		packet->index = txq->next;		ipw_hdr = packet->info.d_struct.data;		hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->			fragments[0]->data;		if (priv->ieee->iw_mode == IW_MODE_INFRA) {			/* To DS: Addr1 = BSSID, Addr2 = SA,			   Addr3 = DA */			memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);			memcpy(ipw_hdr->dst_addr, hdr->addr3, ETH_ALEN);		} else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {			/* not From/To DS: Addr1 = DA, Addr2 = SA,			   Addr3 = BSSID */			memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);			memcpy(ipw_hdr->dst_addr, hdr->addr1, ETH_ALEN);		}		ipw_hdr->host_command_reg = SEND;		ipw_hdr->host_command_reg1 = 0;		/* For now we only support host based encryption */		ipw_hdr->needs_encryption = 0;		ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;		if (packet->info.d_struct.txb->nr_frags > 1)			ipw_hdr->fragment_size =				packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN;		else			ipw_hdr->fragment_size = 0;		tbd->host_addr = packet->info.d_struct.data_phys;		tbd->buf_length = sizeof(struct ipw2100_data_header);		tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;		tbd->status.info.field =			IPW_BD_STATUS_TX_FRAME_802_3 |			IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;		txq->next++;		txq->next %= txq->entries;		IPW_DEBUG_TX(			"data header tbd TX%d P=%08x L=%d\n",			packet->index, tbd->host_addr,			tbd->buf_length);#ifdef CONFIG_IPW_DEBUG		if (packet->info.d_struct.txb->nr_frags > 1)			IPW_DEBUG_FRAG("fragment Tx: %d frames\n",				       packet->info.d_struct.txb->nr_frags);#endif                for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {		        tbd = &txq->drv[txq->next];			if (i == packet->info.d_struct.txb->nr_frags - 1)				tbd->status.info.field =					IPW_BD_STATUS_TX_FRAME_802_3 |					IPW_BD_STATUS_TX_INTERRUPT_ENABLE;			else				tbd->status.info.field =					IPW_BD_STATUS_TX_FRAME_802_3 |					IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;			tbd->buf_length = packet->info.d_struct.txb->				fragments[i]->len - IEEE80211_3ADDR_LEN;                        tbd->host_addr = pci_map_single(				priv->pci_dev,				packet->info.d_struct.txb->fragments[i]->data +				IEEE80211_3ADDR_LEN,				tbd->buf_length,				PCI_DMA_TODEVICE);			IPW_DEBUG_TX(				"data frag tbd TX%d P=%08x L=%d\n",				txq->next, tbd->host_addr, tbd->buf_length);			pci_dma_sync_single_for_device(				priv->pci_dev, tbd->host_addr,				tbd->buf_length,				PCI_DMA_TODEVICE);			txq->next++;			txq->next %= txq->entries;                }		txq->available -= 1 + packet->info.d_struct.txb->nr_frags;		SET_STAT(&priv->txq_stat, txq->available);		list_add_tail(element, &priv->fw_pend_list);		INC_STAT(&priv->fw_pend_stat);	}	if (txq->next != next) {		/* kick off the DMA by notifying firmware the		 * write index has moved; make sure TBD stores are sync'd */		write_register(priv->net_dev,			       IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,			       txq->next);	}        return;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/99a4b232b6682a847c70d877e4a3c15e9138c8f6/ipw2100.c/buggy/drivers/net/wireless/ipw2100.c