aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-04-05 10:00:02 -0400
committerBen Hutchings <bhutchings@solarflare.com>2011-04-05 10:00:02 -0400
commitabfe903980161b11f3594e3dcbab8b5c5a67168b (patch)
tree4bfde1e260cdfe855cfa0e94718ecb1747bac3b4
parentf82d9a67fbcdfd8af6be7a7c9e381864ec9a271a (diff)
sfc: Implement generic features interface
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/sfc/efx.c20
-rw-r--r--drivers/net/sfc/ethtool.c78
-rw-r--r--drivers/net/sfc/net_driver.h2
-rw-r--r--drivers/net/sfc/rx.c2
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
1877static 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
1877static const struct net_device_ops efx_netdev_ops = { 1888static 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
521static 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
538static 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
551static 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
563static 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
570static 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
587static void efx_ethtool_self_test(struct net_device *net_dev, 521static 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)) {