aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2014-11-20 12:04:02 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-21 15:19:11 -0500
commiteb79e640fab1fc163e6f04e0cc007c76b6a46f28 (patch)
tree99b763c03dff5894a397261af57cfc4b6a6a85c3
parent16978eb7bc2f6ecba71916a673a7840d17943b71 (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.c46
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),