priv->ieee->stats.tx_packets++; 
static inline int __ipw2100_tx_process(struct ipw2100_priv *priv){	struct ipw2100_bd_queue *txq = &priv->tx_queue;	struct ipw2100_bd *tbd;	struct list_head *element;	struct ipw2100_tx_packet *packet;	int descriptors_used;	int e, i;	u32 r, w, frag_num = 0;	if (list_empty(&priv->fw_pend_list))		return 0;	element = priv->fw_pend_list.next;	packet = list_entry(element, struct ipw2100_tx_packet, list);	tbd = &txq->drv[packet->index];	/* Determine how many TBD entries must be finished... */	switch (packet->type) {	case COMMAND:		/* COMMAND uses only one slot; don't advance */		descriptors_used = 1;		e = txq->oldest;		break;	case DATA:		/* DATA uses two slots; advance and loop position. */		descriptors_used = tbd->num_fragments;		frag_num = tbd->num_fragments - 1;		e = txq->oldest + frag_num;		e %= txq->entries;		break;	default:		printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",		       priv->net_dev->name);		return 0;	}	/* if the last TBD is not done by NIC yet, then packet is	 * not ready to be released.	 *	 */	read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,		      &r);	read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,		      &w);	if (w != txq->next)		printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",		       priv->net_dev->name);	/*	 * txq->next is the index of the last packet written txq->oldest is	 * the index of the r is the index of the next packet to be read by	 * firmware	 */	/*	 * Quick graphic to help you visualize the following	 * if / else statement	 *	 * ===>|                     s---->|===============	 *                               e>|	 * | a | b | c | d | e | f | g | h | i | j | k | l	 *       r---->|	 *               w	 *	 * w - updated by driver	 * r - updated by firmware	 * s - start of oldest BD entry (txq->oldest)	 * e - end of oldest BD entry	 *	 */	if (!((r <= w && (e < r || e >= w)) || (e < r && e >= w))) {		IPW_DEBUG_TX("exit - no processed packets ready to release.\n");		return 0;	}	list_del(element);	DEC_STAT(&priv->fw_pend_stat);#ifdef CONFIG_IPW_DEBUG	{		int i = txq->oldest;		IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,			     &txq->drv[i],			     (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),			     txq->drv[i].host_addr, txq->drv[i].buf_length);		if (packet->type == DATA) {			i = (i + 1) % txq->entries;			IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,				     &txq->drv[i],				     (u32) (txq->nic + i *					    sizeof(struct ipw2100_bd)),				     (u32) txq->drv[i].host_addr,				     txq->drv[i].buf_length);		}	}#endif	switch (packet->type) {	case DATA:		if (txq->drv[txq->oldest].status.info.fields.txType != 0)			printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch.  "			       "Expecting DATA TBD but pulled "			       "something else: ids %d=%d.\n",			       priv->net_dev->name, txq->oldest, packet->index);		/* DATA packet; we have to unmap and free the SKB */		priv->ieee->stats.tx_packets++;		for (i = 0; i < frag_num; i++) {			tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];			IPW_DEBUG_TX("TX%d P=%08x L=%d\n",				     (packet->index + 1 + i) % txq->entries,				     tbd->host_addr, tbd->buf_length);			pci_unmap_single(priv->pci_dev,					 tbd->host_addr,					 tbd->buf_length, PCI_DMA_TODEVICE);		}		priv->ieee->stats.tx_bytes +=		    packet->info.d_struct.txb->payload_size;		ieee80211_txb_free(packet->info.d_struct.txb);		packet->info.d_struct.txb = NULL;		list_add_tail(element, &priv->tx_free_list);		INC_STAT(&priv->tx_free_stat);		/* We have a free slot in the Tx queue, so wake up the		 * transmit layer if it is stopped. */		if (priv->status & STATUS_ASSOCIATED &&		    netif_queue_stopped(priv->net_dev)) {			IPW_DEBUG_INFO(KERN_INFO				       "%s: Waking net queue.\n",				       priv->net_dev->name);			netif_wake_queue(priv->net_dev);		}		/* A packet was processed by the hardware, so update the		 * watchdog */		priv->net_dev->trans_start = jiffies;		break;	case COMMAND:		if (txq->drv[txq->oldest].status.info.fields.txType != 1)			printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch.  "			       "Expecting COMMAND TBD but pulled "			       "something else: ids %d=%d.\n",			       priv->net_dev->name, txq->oldest, packet->index);#ifdef CONFIG_IPW_DEBUG		if (packet->info.c_struct.cmd->host_command_reg <		    sizeof(command_types) / sizeof(*command_types))			IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",				     command_types[packet->info.c_struct.cmd->						   host_command_reg],				     packet->info.c_struct.cmd->				     host_command_reg,				     packet->info.c_struct.cmd->cmd_status_reg);#endif		list_add_tail(element, &priv->msg_free_list);		INC_STAT(&priv->msg_free_stat);		break;	}	/* advance oldest used TBD pointer to start of next entry */	txq->oldest = (e + 1) % txq->entries;	/* increase available TBDs number */	txq->available += descriptors_used;	SET_STAT(&priv->txq_stat, txq->available);	IPW_DEBUG_TX("packet latency (send to process)  %ld jiffies\n",		     jiffies - packet->jiffy_start);	return (!list_empty(&priv->fw_pend_list));}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/823283549da144ff49e65c6e4a670b7784203e0b/ipw2100.c/buggy/drivers/net/wireless/ipw2100.c