diff options
author | Lendacky, Thomas <Thomas.Lendacky@amd.com> | 2014-11-20 12:04:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-21 15:19:11 -0500 |
commit | eb79e640fab1fc163e6f04e0cc007c76b6a46f28 (patch) | |
tree | 99b763c03dff5894a397261af57cfc4b6a6a85c3 | |
parent | 16978eb7bc2f6ecba71916a673a7840d17943b71 (diff) |
amd-xgbe: Perform Tx coalescing on a packet basis
The current form of Tx coalescing works on a descriptor basis instead
of on a packet basis and doesn't take into account TSO packets. Update
the Tx coalescing support to work on a packet basis, taking into
account the number of packets associated with a TSO transmit. Also,
only activate the Tx timer if a timer value is set.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 78db5a657699..b3d2433b52bb 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
@@ -1334,7 +1334,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1334 | struct xgbe_packet_data *packet = &ring->packet_data; | 1334 | struct xgbe_packet_data *packet = &ring->packet_data; |
1335 | unsigned int csum, tso, vlan; | 1335 | unsigned int csum, tso, vlan; |
1336 | unsigned int tso_context, vlan_context; | 1336 | unsigned int tso_context, vlan_context; |
1337 | unsigned int tx_coalesce, tx_frames; | 1337 | unsigned int tx_set_ic; |
1338 | int start_index = ring->cur; | 1338 | int start_index = ring->cur; |
1339 | int i; | 1339 | int i; |
1340 | 1340 | ||
@@ -1357,10 +1357,26 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1357 | else | 1357 | else |
1358 | vlan_context = 0; | 1358 | vlan_context = 0; |
1359 | 1359 | ||
1360 | tx_coalesce = (pdata->tx_usecs || pdata->tx_frames) ? 1 : 0; | 1360 | /* Determine if an interrupt should be generated for this Tx: |
1361 | tx_frames = pdata->tx_frames; | 1361 | * Interrupt: |
1362 | if (tx_coalesce && !channel->tx_timer_active) | 1362 | * - Tx frame count exceeds the frame count setting |
1363 | ring->coalesce_count = 0; | 1363 | * - Addition of Tx frame count to the frame count since the |
1364 | * last interrupt was set exceeds the frame count setting | ||
1365 | * No interrupt: | ||
1366 | * - No frame count setting specified (ethtool -C ethX tx-frames 0) | ||
1367 | * - Addition of Tx frame count to the frame count since the | ||
1368 | * last interrupt was set does not exceed the frame count setting | ||
1369 | */ | ||
1370 | ring->coalesce_count += packet->tx_packets; | ||
1371 | if (!pdata->tx_frames) | ||
1372 | tx_set_ic = 0; | ||
1373 | else if (packet->tx_packets > pdata->tx_frames) | ||
1374 | tx_set_ic = 1; | ||
1375 | else if ((ring->coalesce_count % pdata->tx_frames) < | ||
1376 | packet->tx_packets) | ||
1377 | tx_set_ic = 1; | ||
1378 | else | ||
1379 | tx_set_ic = 0; | ||
1364 | 1380 | ||
1365 | rdata = XGBE_GET_DESC_DATA(ring, ring->cur); | 1381 | rdata = XGBE_GET_DESC_DATA(ring, ring->cur); |
1366 | rdesc = rdata->rdesc; | 1382 | rdesc = rdata->rdesc; |
@@ -1427,13 +1443,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1427 | if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) | 1443 | if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) |
1428 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1); | 1444 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1); |
1429 | 1445 | ||
1430 | /* Set IC bit based on Tx coalescing settings */ | ||
1431 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); | ||
1432 | if (tx_coalesce && (!tx_frames || | ||
1433 | (++ring->coalesce_count % tx_frames))) | ||
1434 | /* Clear IC bit */ | ||
1435 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0); | ||
1436 | |||
1437 | /* Mark it as First Descriptor */ | 1446 | /* Mark it as First Descriptor */ |
1438 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1); | 1447 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1); |
1439 | 1448 | ||
@@ -1478,13 +1487,6 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1478 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L, | 1487 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L, |
1479 | rdata->skb_dma_len); | 1488 | rdata->skb_dma_len); |
1480 | 1489 | ||
1481 | /* Set IC bit based on Tx coalescing settings */ | ||
1482 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); | ||
1483 | if (tx_coalesce && (!tx_frames || | ||
1484 | (++ring->coalesce_count % tx_frames))) | ||
1485 | /* Clear IC bit */ | ||
1486 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0); | ||
1487 | |||
1488 | /* Set OWN bit */ | 1490 | /* Set OWN bit */ |
1489 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); | 1491 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1); |
1490 | 1492 | ||
@@ -1500,6 +1502,10 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1500 | /* Set LAST bit for the last descriptor */ | 1502 | /* Set LAST bit for the last descriptor */ |
1501 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1); | 1503 | XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1); |
1502 | 1504 | ||
1505 | /* Set IC bit based on Tx coalescing settings */ | ||
1506 | if (tx_set_ic) | ||
1507 | XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1); | ||
1508 | |||
1503 | /* Save the Tx info to report back during cleanup */ | 1509 | /* Save the Tx info to report back during cleanup */ |
1504 | rdata->tx.packets = packet->tx_packets; | 1510 | rdata->tx.packets = packet->tx_packets; |
1505 | rdata->tx.bytes = packet->tx_bytes; | 1511 | rdata->tx.bytes = packet->tx_bytes; |
@@ -1530,7 +1536,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel) | |||
1530 | lower_32_bits(rdata->rdesc_dma)); | 1536 | lower_32_bits(rdata->rdesc_dma)); |
1531 | 1537 | ||
1532 | /* Start the Tx coalescing timer */ | 1538 | /* Start the Tx coalescing timer */ |
1533 | if (tx_coalesce && !channel->tx_timer_active) { | 1539 | if (pdata->tx_usecs && !channel->tx_timer_active) { |
1534 | channel->tx_timer_active = 1; | 1540 | channel->tx_timer_active = 1; |
1535 | hrtimer_start(&channel->tx_timer, | 1541 | hrtimer_start(&channel->tx_timer, |
1536 | ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC), | 1542 | ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC), |