summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2015-01-16 18:46:55 (GMT)
committerDavid S. Miller <davem@davemloft.net>2015-01-17 03:24:20 (GMT)
commita83ef427b7d97314df30d6e25abc7aa3a80ffcfd (patch)
treef9e62392b9cbd429cd7543db19da44518650b1ec /drivers/net/ethernet/amd/xgbe/xgbe-dev.c
parent270894e7dc7afad8fb79592fe02aa05e604ddfc8 (diff)
downloadlinux-a83ef427b7d97314df30d6e25abc7aa3a80ffcfd.tar.xz
amd-xgbe: Remove need for Tx path spinlock
Since the Tx ring cleanup can run at the same time that data is being transmitted, a spin lock was used to protect the ring. This patch eliminates the need for Tx spinlocks by updating the current ring position only after all ownership bits for data being transmitted have been set. This will insure that ring operations in the Tx cleanup path do not interfere with the ring operations in the Tx transmit path. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/amd/xgbe/xgbe-dev.c')
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index e424997..5dff127 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1359,6 +1359,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
unsigned int tso_context, vlan_context;
unsigned int tx_set_ic;
int start_index = ring->cur;
+ int cur_index = ring->cur;
int i;
DBGPR("-->xgbe_dev_xmit\n");
@@ -1401,7 +1402,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
else
tx_set_ic = 0;
- rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc;
/* Create a context descriptor if this is a TSO packet */
@@ -1444,8 +1445,8 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
ring->tx.cur_vlan_ctag = packet->vlan_ctag;
}
- ring->cur++;
- rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+ cur_index++;
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc;
}
@@ -1473,7 +1474,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
/* Set OWN bit if not the first descriptor */
- if (ring->cur != start_index)
+ if (cur_index != start_index)
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
if (tso) {
@@ -1497,9 +1498,9 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
packet->length);
}
- for (i = ring->cur - start_index + 1; i < packet->rdesc_count; i++) {
- ring->cur++;
- rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+ for (i = cur_index - start_index + 1; i < packet->rdesc_count; i++) {
+ cur_index++;
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
rdesc = rdata->rdesc;
/* Update buffer address */
@@ -1551,7 +1552,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
/* Make sure ownership is written to the descriptor */
wmb();
- ring->cur++;
+ ring->cur = cur_index + 1;
if (!packet->skb->xmit_more ||
netif_xmit_stopped(netdev_get_tx_queue(pdata->netdev,
channel->queue_index)))