aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/ethtool.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:44:59 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:42 -0400
commit60ac10658c2e234cf7bc27e0930e324c6c6fcf61 (patch)
treeb16ee9efd385806755c6912492db43997c4f4b98 /drivers/net/sfc/ethtool.c
parent26c086771a8ad0a1a72699674fa712fe6aeacb02 (diff)
sfc: Use separate hardware TX queues to select checksum generation
Checksum generation is an attribute of our hardware TX queues, not TX descriptors. We previously used a single queue and turned checksum generation on or off as requested through ethtool. However, this can result in regenerating checksums in raw packets that should not be modified. We now create 2 hardware TX queues with checksum generation on or off. They are presented to the net core as one queue since it does not know how to select between them. The self-test verifies that a bad checksum is unaltered on the queue with checksum generation off. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc/ethtool.c')
-rw-r--r--drivers/net/sfc/ethtool.c45
1 files changed, 2 insertions, 43 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 8a15be6548d2..ccd82f12456c 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -32,8 +32,6 @@ const char *efx_loopback_mode_names[] = {
32 [LOOPBACK_NETWORK] = "NETWORK", 32 [LOOPBACK_NETWORK] = "NETWORK",
33}; 33};
34 34
35static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);
36
37struct ethtool_string { 35struct ethtool_string {
38 char name[ETH_GSTRING_LEN]; 36 char name[ETH_GSTRING_LEN];
39}; 37};
@@ -442,45 +440,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
442 } 440 }
443} 441}
444 442
445static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
446{
447 int rc;
448
449 /* Our TSO requires TX checksumming, so force TX checksumming
450 * on when TSO is enabled.
451 */
452 if (enable) {
453 rc = efx_ethtool_set_tx_csum(net_dev, 1);
454 if (rc)
455 return rc;
456 }
457
458 return ethtool_op_set_tso(net_dev, enable);
459}
460
461static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
462{
463 struct efx_nic *efx = netdev_priv(net_dev);
464 int rc;
465
466 rc = ethtool_op_set_tx_csum(net_dev, enable);
467 if (rc)
468 return rc;
469
470 efx_flush_queues(efx);
471
472 /* Our TSO requires TX checksumming, so disable TSO when
473 * checksumming is disabled
474 */
475 if (!enable) {
476 rc = efx_ethtool_set_tso(net_dev, 0);
477 if (rc)
478 return rc;
479 }
480
481 return 0;
482}
483
484static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) 443static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
485{ 444{
486 struct efx_nic *efx = netdev_priv(net_dev); 445 struct efx_nic *efx = netdev_priv(net_dev);
@@ -701,11 +660,11 @@ struct ethtool_ops efx_ethtool_ops = {
701 .get_rx_csum = efx_ethtool_get_rx_csum, 660 .get_rx_csum = efx_ethtool_get_rx_csum,
702 .set_rx_csum = efx_ethtool_set_rx_csum, 661 .set_rx_csum = efx_ethtool_set_rx_csum,
703 .get_tx_csum = ethtool_op_get_tx_csum, 662 .get_tx_csum = ethtool_op_get_tx_csum,
704 .set_tx_csum = efx_ethtool_set_tx_csum, 663 .set_tx_csum = ethtool_op_set_tx_csum,
705 .get_sg = ethtool_op_get_sg, 664 .get_sg = ethtool_op_get_sg,
706 .set_sg = ethtool_op_set_sg, 665 .set_sg = ethtool_op_set_sg,
707 .get_tso = ethtool_op_get_tso, 666 .get_tso = ethtool_op_get_tso,
708 .set_tso = efx_ethtool_set_tso, 667 .set_tso = ethtool_op_set_tso,
709 .get_flags = ethtool_op_get_flags, 668 .get_flags = ethtool_op_get_flags,
710 .set_flags = ethtool_op_set_flags, 669 .set_flags = ethtool_op_set_flags,
711 .self_test_count = efx_ethtool_self_test_count, 670 .self_test_count = efx_ethtool_self_test_count,