net: introduce NETIF_F_RXCSUM
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>
Tue, 15 Feb 2011 16:59:18 +0000 (16:59 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 17 Feb 2011 22:16:35 +0000 (14:16 -0800)
Introduce NETIF_F_RXCSUM to replace device-private flags for RX checksum
offload. Integrate it with ndo_fix_features.

ethtool_op_get_rx_csum() is removed altogether as nothing in-tree uses it.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/ethtool.h
include/linux/netdevice.h
net/core/ethtool.c

index 806e716..54d776c 100644 (file)
@@ -625,7 +625,6 @@ struct net_device;
 
 /* Some generic methods drivers may use in their ethtool_ops */
 u32 ethtool_op_get_link(struct net_device *dev);
-u32 ethtool_op_get_rx_csum(struct net_device *dev);
 u32 ethtool_op_get_tx_csum(struct net_device *dev);
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
 int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data);
index 85f67e2..ffe56c1 100644 (file)
@@ -977,6 +977,7 @@ struct net_device {
 #define NETIF_F_FCOE_MTU       (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
 #define NETIF_F_NTUPLE         (1 << 27) /* N-tuple filters supported */
 #define NETIF_F_RXHASH         (1 << 28) /* Receive hashing offload */
+#define NETIF_F_RXCSUM         (1 << 29) /* Receive checksumming offload */
 
        /* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT      16
@@ -992,7 +993,7 @@ struct net_device {
        /* = all defined minus driver/device-class-related */
 #define NETIF_F_NEVER_CHANGE   (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \
                                  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
-#define NETIF_F_ETHTOOL_BITS   (0x1f3fffff & ~NETIF_F_NEVER_CHANGE)
+#define NETIF_F_ETHTOOL_BITS   (0x3f3fffff & ~NETIF_F_NEVER_CHANGE)
 
        /* List of features with software fallbacks. */
 #define NETIF_F_GSO_SOFTWARE   (NETIF_F_TSO | NETIF_F_TSO_ECN | \
@@ -2510,6 +2511,8 @@ static inline int dev_ethtool_get_settings(struct net_device *dev,
 
 static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
 {
+       if (dev->hw_features & NETIF_F_RXCSUM)
+               return !!(dev->features & NETIF_F_RXCSUM);
        if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
                return 0;
        return dev->ethtool_ops->get_rx_csum(dev);
index 65b3d50..66cdc76 100644 (file)
@@ -34,12 +34,6 @@ u32 ethtool_op_get_link(struct net_device *dev)
 }
 EXPORT_SYMBOL(ethtool_op_get_link);
 
-u32 ethtool_op_get_rx_csum(struct net_device *dev)
-{
-       return (dev->features & NETIF_F_ALL_CSUM) != 0;
-}
-EXPORT_SYMBOL(ethtool_op_get_rx_csum);
-
 u32 ethtool_op_get_tx_csum(struct net_device *dev)
 {
        return (dev->features & NETIF_F_ALL_CSUM) != 0;
@@ -274,7 +268,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS
        /* NETIF_F_FCOE_MTU */        "fcoe-mtu",
        /* NETIF_F_NTUPLE */          "rx-ntuple-filter",
        /* NETIF_F_RXHASH */          "rx-hashing",
-       "",
+       /* NETIF_F_RXCSUM */          "rx-checksum",
        "",
        "",
 };
@@ -313,6 +307,9 @@ static u32 ethtool_get_feature_mask(u32 eth_cmd)
        case ETHTOOL_GTXCSUM:
        case ETHTOOL_STXCSUM:
                return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
+       case ETHTOOL_GRXCSUM:
+       case ETHTOOL_SRXCSUM:
+               return NETIF_F_RXCSUM;
        case ETHTOOL_GSG:
        case ETHTOOL_SSG:
                return NETIF_F_SG;
@@ -343,6 +340,8 @@ static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
        switch (ethcmd) {
        case ETHTOOL_GTXCSUM:
                return ops->get_tx_csum;
+       case ETHTOOL_GRXCSUM:
+               return ops->get_rx_csum;
        case ETHTOOL_SSG:
                return ops->get_sg;
        case ETHTOOL_STSO:
@@ -354,6 +353,11 @@ static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
        }
 }
 
+static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev)
+{
+       return !!(dev->features & NETIF_F_ALL_CSUM);
+}
+
 static int ethtool_get_one_feature(struct net_device *dev,
        char __user *useraddr, u32 ethcmd)
 {
@@ -369,6 +373,10 @@ static int ethtool_get_one_feature(struct net_device *dev,
 
                actor = __ethtool_get_one_feature_actor(dev, ethcmd);
 
+               /* bug compatibility with old get_rx_csum */
+               if (ethcmd == ETHTOOL_GRXCSUM && !actor)
+                       actor = __ethtool_get_rx_csum_oldbug;
+
                if (actor)
                        edata.data = actor(dev);
        }
@@ -379,6 +387,7 @@ static int ethtool_get_one_feature(struct net_device *dev,
 }
 
 static int __ethtool_set_tx_csum(struct net_device *dev, u32 data);
+static int __ethtool_set_rx_csum(struct net_device *dev, u32 data);
 static int __ethtool_set_sg(struct net_device *dev, u32 data);
 static int __ethtool_set_tso(struct net_device *dev, u32 data);
 static int __ethtool_set_ufo(struct net_device *dev, u32 data);
@@ -416,6 +425,8 @@ static int ethtool_set_one_feature(struct net_device *dev,
        switch (ethcmd) {
        case ETHTOOL_STXCSUM:
                return __ethtool_set_tx_csum(dev, edata.data);
+       case ETHTOOL_SRXCSUM:
+               return __ethtool_set_rx_csum(dev, edata.data);
        case ETHTOOL_SSG:
                return __ethtool_set_sg(dev, edata.data);
        case ETHTOOL_STSO:
@@ -1404,20 +1415,15 @@ static int __ethtool_set_tx_csum(struct net_device *dev, u32 data)
        return dev->ethtool_ops->set_tx_csum(dev, data);
 }
 
-static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr)
+static int __ethtool_set_rx_csum(struct net_device *dev, u32 data)
 {
-       struct ethtool_value edata;
-
        if (!dev->ethtool_ops->set_rx_csum)
                return -EOPNOTSUPP;
 
-       if (copy_from_user(&edata, useraddr, sizeof(edata)))
-               return -EFAULT;
-
-       if (!edata.data && dev->ethtool_ops->set_sg)
+       if (!data)
                dev->features &= ~NETIF_F_GRO;
 
-       return dev->ethtool_ops->set_rx_csum(dev, edata.data);
+       return dev->ethtool_ops->set_rx_csum(dev, data);
 }
 
 static int __ethtool_set_tso(struct net_device *dev, u32 data)
@@ -1765,15 +1771,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_SPAUSEPARAM:
                rc = ethtool_set_pauseparam(dev, useraddr);
                break;
-       case ETHTOOL_GRXCSUM:
-               rc = ethtool_get_value(dev, useraddr, ethcmd,
-                                      (dev->ethtool_ops->get_rx_csum ?
-                                       dev->ethtool_ops->get_rx_csum :
-                                       ethtool_op_get_rx_csum));
-               break;
-       case ETHTOOL_SRXCSUM:
-               rc = ethtool_set_rx_csum(dev, useraddr);
-               break;
        case ETHTOOL_TEST:
                rc = ethtool_self_test(dev, useraddr);
                break;
@@ -1846,6 +1843,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
                rc = ethtool_set_features(dev, useraddr);
                break;
        case ETHTOOL_GTXCSUM:
+       case ETHTOOL_GRXCSUM:
        case ETHTOOL_GSG:
        case ETHTOOL_GTSO:
        case ETHTOOL_GUFO:
@@ -1854,6 +1852,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
                rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
                break;
        case ETHTOOL_STXCSUM:
+       case ETHTOOL_SRXCSUM:
        case ETHTOOL_SSG:
        case ETHTOOL_STSO:
        case ETHTOOL_SUFO: