Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b111ceb6 authored by Dale Farnsworth's avatar Dale Farnsworth Committed by Jeff Garzik
Browse files

[PATCH] mv643xx: fix outstanding tx skb counter



This patch corrects the accounting of outstanding tx skbs.  It fixes
a bug that causes "Error on Queue Full" messages seen since scatter-gather
was enabled by using the hardware tcp/udp checksum generator.

Signed-off-by: default avatarDale Farnsworth <dale@farnsworth.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent b1dd9ca1
Loading
Loading
Loading
Loading
+9 −15
Original line number Diff line number Diff line
@@ -369,15 +369,6 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev,

			dev_kfree_skb_irq(pkt_info.return_info);
			released = 0;

			/*
			 * Decrement the number of outstanding skbs counter on
			 * the TX queue.
			 */
			if (mp->tx_ring_skbs == 0)
				panic("ERROR - TX outstanding SKBs"
						" counter is corrupted");
			mp->tx_ring_skbs--;
		} else
			dma_unmap_page(NULL, pkt_info.buf_ptr,
					pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -1042,9 +1033,6 @@ static void mv643xx_tx(struct net_device *dev)
						DMA_TO_DEVICE);

			dev_kfree_skb_irq(pkt_info.return_info);

			if (mp->tx_ring_skbs)
				mp->tx_ring_skbs--;
		} else
			dma_unmap_page(NULL, pkt_info.buf_ptr,
					pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -1187,7 +1175,6 @@ linear:
		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
							DMA_TO_DEVICE);
		pkt_info.return_info = skb;
		mp->tx_ring_skbs++;
		status = eth_port_send(mp, &pkt_info);
		if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
			printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1272,7 +1259,6 @@ linear:
				pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
							ETH_TX_LAST_DESC;
				pkt_info.return_info = skb;
				mp->tx_ring_skbs++;
			} else {
				pkt_info.return_info = 0;
			}
@@ -1309,7 +1295,6 @@ linear:
	pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
								DMA_TO_DEVICE);
	pkt_info.return_info = skb;
	mp->tx_ring_skbs++;
	status = eth_port_send(mp, &pkt_info);
	if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
		printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -2526,6 +2511,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
		return ETH_ERROR;
	}

	mp->tx_ring_skbs++;
	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);

	/* Get the Tx Desc ring indexes */
	tx_desc_curr = mp->tx_curr_desc_q;
	tx_desc_used = mp->tx_used_desc_q;
@@ -2592,6 +2580,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
	if (mp->tx_resource_err)
		return ETH_QUEUE_FULL;

	mp->tx_ring_skbs++;
	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);

	/* Get the Tx Desc ring indexes */
	tx_desc_curr = mp->tx_curr_desc_q;
	tx_desc_used = mp->tx_used_desc_q;
@@ -2692,6 +2683,9 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
	/* Any Tx return cancels the Tx resource error status */
	mp->tx_resource_err = 0;

	BUG_ON(mp->tx_ring_skbs == 0);
	mp->tx_ring_skbs--;

	return ETH_OK;
}