diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2011-04-05 10:00:02 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2011-04-05 10:00:02 -0400 |
commit | abfe903980161b11f3594e3dcbab8b5c5a67168b (patch) | |
tree | 4bfde1e260cdfe855cfa0e94718ecb1747bac3b4 | |
parent | f82d9a67fbcdfd8af6be7a7c9e381864ec9a271a (diff) |
sfc: Implement generic features interface
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | drivers/net/sfc/efx.c | 20 | ||||
-rw-r--r-- | drivers/net/sfc/ethtool.c | 78 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/rx.c | 2 |
4 files changed, 18 insertions, 84 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 542f32d21acf..db72a6e054e1 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -1874,6 +1874,17 @@ static void efx_set_multicast_list(struct net_device *net_dev) | |||
1874 | /* Otherwise efx_start_port() will do this */ | 1874 | /* Otherwise efx_start_port() will do this */ |
1875 | } | 1875 | } |
1876 | 1876 | ||
1877 | static int efx_set_features(struct net_device *net_dev, u32 data) | ||
1878 | { | ||
1879 | struct efx_nic *efx = netdev_priv(net_dev); | ||
1880 | |||
1881 | /* If disabling RX n-tuple filtering, clear existing filters */ | ||
1882 | if (net_dev->features & ~data & NETIF_F_NTUPLE) | ||
1883 | efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); | ||
1884 | |||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1877 | static const struct net_device_ops efx_netdev_ops = { | 1888 | static const struct net_device_ops efx_netdev_ops = { |
1878 | .ndo_open = efx_net_open, | 1889 | .ndo_open = efx_net_open, |
1879 | .ndo_stop = efx_net_stop, | 1890 | .ndo_stop = efx_net_stop, |
@@ -1885,6 +1896,7 @@ static const struct net_device_ops efx_netdev_ops = { | |||
1885 | .ndo_change_mtu = efx_change_mtu, | 1896 | .ndo_change_mtu = efx_change_mtu, |
1886 | .ndo_set_mac_address = efx_set_mac_address, | 1897 | .ndo_set_mac_address = efx_set_mac_address, |
1887 | .ndo_set_multicast_list = efx_set_multicast_list, | 1898 | .ndo_set_multicast_list = efx_set_multicast_list, |
1899 | .ndo_set_features = efx_set_features, | ||
1888 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1900 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1889 | .ndo_poll_controller = efx_netpoll, | 1901 | .ndo_poll_controller = efx_netpoll, |
1890 | #endif | 1902 | #endif |
@@ -2269,7 +2281,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
2269 | strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); | 2281 | strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); |
2270 | 2282 | ||
2271 | efx->net_dev = net_dev; | 2283 | efx->net_dev = net_dev; |
2272 | efx->rx_checksum_enabled = true; | ||
2273 | spin_lock_init(&efx->stats_lock); | 2284 | spin_lock_init(&efx->stats_lock); |
2274 | mutex_init(&efx->mac_lock); | 2285 | mutex_init(&efx->mac_lock); |
2275 | efx->mac_op = type->default_mac_ops; | 2286 | efx->mac_op = type->default_mac_ops; |
@@ -2452,12 +2463,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2452 | return -ENOMEM; | 2463 | return -ENOMEM; |
2453 | net_dev->features |= (type->offload_features | NETIF_F_SG | | 2464 | net_dev->features |= (type->offload_features | NETIF_F_SG | |
2454 | NETIF_F_HIGHDMA | NETIF_F_TSO | | 2465 | NETIF_F_HIGHDMA | NETIF_F_TSO | |
2455 | NETIF_F_GRO); | 2466 | NETIF_F_RXCSUM); |
2456 | if (type->offload_features & NETIF_F_V6_CSUM) | 2467 | if (type->offload_features & NETIF_F_V6_CSUM) |
2457 | net_dev->features |= NETIF_F_TSO6; | 2468 | net_dev->features |= NETIF_F_TSO6; |
2458 | /* Mask for features that also apply to VLAN devices */ | 2469 | /* Mask for features that also apply to VLAN devices */ |
2459 | net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | | 2470 | net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | |
2460 | NETIF_F_HIGHDMA | NETIF_F_ALL_TSO); | 2471 | NETIF_F_HIGHDMA | NETIF_F_ALL_TSO | |
2472 | NETIF_F_RXCSUM); | ||
2473 | /* All offloads can be toggled */ | ||
2474 | net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA; | ||
2461 | efx = netdev_priv(net_dev); | 2475 | efx = netdev_priv(net_dev); |
2462 | pci_set_drvdata(pci_dev, efx); | 2476 | pci_set_drvdata(pci_dev, efx); |
2463 | SET_NETDEV_DEV(net_dev, &pci_dev->dev); | 2477 | SET_NETDEV_DEV(net_dev, &pci_dev->dev); |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 807178ef65ad..0d5543972574 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -518,72 +518,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
518 | } | 518 | } |
519 | } | 519 | } |
520 | 520 | ||
521 | static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) | ||
522 | { | ||
523 | struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev); | ||
524 | u32 features; | ||
525 | |||
526 | features = NETIF_F_TSO; | ||
527 | if (efx->type->offload_features & NETIF_F_V6_CSUM) | ||
528 | features |= NETIF_F_TSO6; | ||
529 | |||
530 | if (enable) | ||
531 | net_dev->features |= features; | ||
532 | else | ||
533 | net_dev->features &= ~features; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) | ||
539 | { | ||
540 | struct efx_nic *efx = netdev_priv(net_dev); | ||
541 | u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM; | ||
542 | |||
543 | if (enable) | ||
544 | net_dev->features |= features; | ||
545 | else | ||
546 | net_dev->features &= ~features; | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable) | ||
552 | { | ||
553 | struct efx_nic *efx = netdev_priv(net_dev); | ||
554 | |||
555 | /* No way to stop the hardware doing the checks; we just | ||
556 | * ignore the result. | ||
557 | */ | ||
558 | efx->rx_checksum_enabled = !!enable; | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) | ||
564 | { | ||
565 | struct efx_nic *efx = netdev_priv(net_dev); | ||
566 | |||
567 | return efx->rx_checksum_enabled; | ||
568 | } | ||
569 | |||
570 | static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) | ||
571 | { | ||
572 | struct efx_nic *efx = netdev_priv(net_dev); | ||
573 | u32 supported = (efx->type->offload_features & | ||
574 | (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE)); | ||
575 | int rc; | ||
576 | |||
577 | rc = ethtool_op_set_flags(net_dev, data, supported); | ||
578 | if (rc) | ||
579 | return rc; | ||
580 | |||
581 | if (!(data & ETH_FLAG_NTUPLE)) | ||
582 | efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static void efx_ethtool_self_test(struct net_device *net_dev, | 521 | static void efx_ethtool_self_test(struct net_device *net_dev, |
588 | struct ethtool_test *test, u64 *data) | 522 | struct ethtool_test *test, u64 *data) |
589 | { | 523 | { |
@@ -1070,18 +1004,6 @@ const struct ethtool_ops efx_ethtool_ops = { | |||
1070 | .set_ringparam = efx_ethtool_set_ringparam, | 1004 | .set_ringparam = efx_ethtool_set_ringparam, |
1071 | .get_pauseparam = efx_ethtool_get_pauseparam, | 1005 | .get_pauseparam = efx_ethtool_get_pauseparam, |
1072 | .set_pauseparam = efx_ethtool_set_pauseparam, | 1006 | .set_pauseparam = efx_ethtool_set_pauseparam, |
1073 | .get_rx_csum = efx_ethtool_get_rx_csum, | ||
1074 | .set_rx_csum = efx_ethtool_set_rx_csum, | ||
1075 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
1076 | /* Need to enable/disable IPv6 too */ | ||
1077 | .set_tx_csum = efx_ethtool_set_tx_csum, | ||
1078 | .get_sg = ethtool_op_get_sg, | ||
1079 | .set_sg = ethtool_op_set_sg, | ||
1080 | .get_tso = ethtool_op_get_tso, | ||
1081 | /* Need to enable/disable TSO-IPv6 too */ | ||
1082 | .set_tso = efx_ethtool_set_tso, | ||
1083 | .get_flags = ethtool_op_get_flags, | ||
1084 | .set_flags = efx_ethtool_set_flags, | ||
1085 | .get_sset_count = efx_ethtool_get_sset_count, | 1007 | .get_sset_count = efx_ethtool_get_sset_count, |
1086 | .self_test = efx_ethtool_self_test, | 1008 | .self_test = efx_ethtool_self_test, |
1087 | .get_strings = efx_ethtool_get_strings, | 1009 | .get_strings = efx_ethtool_get_strings, |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 215d5c51bfa0..f0f8ca535a4d 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -681,7 +681,6 @@ struct efx_filter_state; | |||
681 | * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock | 681 | * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock |
682 | * @port_initialized: Port initialized? | 682 | * @port_initialized: Port initialized? |
683 | * @net_dev: Operating system network device. Consider holding the rtnl lock | 683 | * @net_dev: Operating system network device. Consider holding the rtnl lock |
684 | * @rx_checksum_enabled: RX checksumming enabled | ||
685 | * @stats_buffer: DMA buffer for statistics | 684 | * @stats_buffer: DMA buffer for statistics |
686 | * @mac_op: MAC interface | 685 | * @mac_op: MAC interface |
687 | * @phy_type: PHY type | 686 | * @phy_type: PHY type |
@@ -771,7 +770,6 @@ struct efx_nic { | |||
771 | 770 | ||
772 | bool port_initialized; | 771 | bool port_initialized; |
773 | struct net_device *net_dev; | 772 | struct net_device *net_dev; |
774 | bool rx_checksum_enabled; | ||
775 | 773 | ||
776 | struct efx_buffer stats_buffer; | 774 | struct efx_buffer stats_buffer; |
777 | 775 | ||
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index fb402c52aaff..b7dc891b4461 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c | |||
@@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel, | |||
605 | skb_record_rx_queue(skb, channel->channel); | 605 | skb_record_rx_queue(skb, channel->channel); |
606 | } | 606 | } |
607 | 607 | ||
608 | if (unlikely(!efx->rx_checksum_enabled)) | 608 | if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) |
609 | checksummed = false; | 609 | checksummed = false; |
610 | 610 | ||
611 | if (likely(checksummed || rx_buf->is_page)) { | 611 | if (likely(checksummed || rx_buf->is_page)) { |