aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ethtool.h1
-rw-r--r--include/linux/netdevice.h5
-rw-r--r--net/core/ethtool.c47
3 files changed, 27 insertions, 26 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 806e716bb4fb..54d776c2c1b5 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -625,7 +625,6 @@ struct net_device;
625 625
626/* Some generic methods drivers may use in their ethtool_ops */ 626/* Some generic methods drivers may use in their ethtool_ops */
627u32 ethtool_op_get_link(struct net_device *dev); 627u32 ethtool_op_get_link(struct net_device *dev);
628u32 ethtool_op_get_rx_csum(struct net_device *dev);
629u32 ethtool_op_get_tx_csum(struct net_device *dev); 628u32 ethtool_op_get_tx_csum(struct net_device *dev);
630int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); 629int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
631int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data); 630int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 85f67e225f60..ffe56c16df8a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -977,6 +977,7 @@ struct net_device {
977#define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/ 977#define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
978#define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */ 978#define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */
979#define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */ 979#define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */
980#define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */
980 981
981 /* Segmentation offload features */ 982 /* Segmentation offload features */
982#define NETIF_F_GSO_SHIFT 16 983#define NETIF_F_GSO_SHIFT 16
@@ -992,7 +993,7 @@ struct net_device {
992 /* = all defined minus driver/device-class-related */ 993 /* = all defined minus driver/device-class-related */
993#define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \ 994#define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \
994 NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) 995 NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
995#define NETIF_F_ETHTOOL_BITS (0x1f3fffff & ~NETIF_F_NEVER_CHANGE) 996#define NETIF_F_ETHTOOL_BITS (0x3f3fffff & ~NETIF_F_NEVER_CHANGE)
996 997
997 /* List of features with software fallbacks. */ 998 /* List of features with software fallbacks. */
998#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ 999#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,
2510 2511
2511static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) 2512static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
2512{ 2513{
2514 if (dev->hw_features & NETIF_F_RXCSUM)
2515 return !!(dev->features & NETIF_F_RXCSUM);
2513 if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum) 2516 if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
2514 return 0; 2517 return 0;
2515 return dev->ethtool_ops->get_rx_csum(dev); 2518 return dev->ethtool_ops->get_rx_csum(dev);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 65b3d50a6df2..66cdc76770ce 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -34,12 +34,6 @@ u32 ethtool_op_get_link(struct net_device *dev)
34} 34}
35EXPORT_SYMBOL(ethtool_op_get_link); 35EXPORT_SYMBOL(ethtool_op_get_link);
36 36
37u32 ethtool_op_get_rx_csum(struct net_device *dev)
38{
39 return (dev->features & NETIF_F_ALL_CSUM) != 0;
40}
41EXPORT_SYMBOL(ethtool_op_get_rx_csum);
42
43u32 ethtool_op_get_tx_csum(struct net_device *dev) 37u32 ethtool_op_get_tx_csum(struct net_device *dev)
44{ 38{
45 return (dev->features & NETIF_F_ALL_CSUM) != 0; 39 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
274 /* NETIF_F_FCOE_MTU */ "fcoe-mtu", 268 /* NETIF_F_FCOE_MTU */ "fcoe-mtu",
275 /* NETIF_F_NTUPLE */ "rx-ntuple-filter", 269 /* NETIF_F_NTUPLE */ "rx-ntuple-filter",
276 /* NETIF_F_RXHASH */ "rx-hashing", 270 /* NETIF_F_RXHASH */ "rx-hashing",
277 "", 271 /* NETIF_F_RXCSUM */ "rx-checksum",
278 "", 272 "",
279 "", 273 "",
280}; 274};
@@ -313,6 +307,9 @@ static u32 ethtool_get_feature_mask(u32 eth_cmd)
313 case ETHTOOL_GTXCSUM: 307 case ETHTOOL_GTXCSUM:
314 case ETHTOOL_STXCSUM: 308 case ETHTOOL_STXCSUM:
315 return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM; 309 return NETIF_F_ALL_CSUM | NETIF_F_SCTP_CSUM;
310 case ETHTOOL_GRXCSUM:
311 case ETHTOOL_SRXCSUM:
312 return NETIF_F_RXCSUM;
316 case ETHTOOL_GSG: 313 case ETHTOOL_GSG:
317 case ETHTOOL_SSG: 314 case ETHTOOL_SSG:
318 return NETIF_F_SG; 315 return NETIF_F_SG;
@@ -343,6 +340,8 @@ static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
343 switch (ethcmd) { 340 switch (ethcmd) {
344 case ETHTOOL_GTXCSUM: 341 case ETHTOOL_GTXCSUM:
345 return ops->get_tx_csum; 342 return ops->get_tx_csum;
343 case ETHTOOL_GRXCSUM:
344 return ops->get_rx_csum;
346 case ETHTOOL_SSG: 345 case ETHTOOL_SSG:
347 return ops->get_sg; 346 return ops->get_sg;
348 case ETHTOOL_STSO: 347 case ETHTOOL_STSO:
@@ -354,6 +353,11 @@ static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
354 } 353 }
355} 354}
356 355
356static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev)
357{
358 return !!(dev->features & NETIF_F_ALL_CSUM);
359}
360
357static int ethtool_get_one_feature(struct net_device *dev, 361static int ethtool_get_one_feature(struct net_device *dev,
358 char __user *useraddr, u32 ethcmd) 362 char __user *useraddr, u32 ethcmd)
359{ 363{
@@ -369,6 +373,10 @@ static int ethtool_get_one_feature(struct net_device *dev,
369 373
370 actor = __ethtool_get_one_feature_actor(dev, ethcmd); 374 actor = __ethtool_get_one_feature_actor(dev, ethcmd);
371 375
376 /* bug compatibility with old get_rx_csum */
377 if (ethcmd == ETHTOOL_GRXCSUM && !actor)
378 actor = __ethtool_get_rx_csum_oldbug;
379
372 if (actor) 380 if (actor)
373 edata.data = actor(dev); 381 edata.data = actor(dev);
374 } 382 }
@@ -379,6 +387,7 @@ static int ethtool_get_one_feature(struct net_device *dev,
379} 387}
380 388
381static int __ethtool_set_tx_csum(struct net_device *dev, u32 data); 389static int __ethtool_set_tx_csum(struct net_device *dev, u32 data);
390static int __ethtool_set_rx_csum(struct net_device *dev, u32 data);
382static int __ethtool_set_sg(struct net_device *dev, u32 data); 391static int __ethtool_set_sg(struct net_device *dev, u32 data);
383static int __ethtool_set_tso(struct net_device *dev, u32 data); 392static int __ethtool_set_tso(struct net_device *dev, u32 data);
384static int __ethtool_set_ufo(struct net_device *dev, u32 data); 393static int __ethtool_set_ufo(struct net_device *dev, u32 data);
@@ -416,6 +425,8 @@ static int ethtool_set_one_feature(struct net_device *dev,
416 switch (ethcmd) { 425 switch (ethcmd) {
417 case ETHTOOL_STXCSUM: 426 case ETHTOOL_STXCSUM:
418 return __ethtool_set_tx_csum(dev, edata.data); 427 return __ethtool_set_tx_csum(dev, edata.data);
428 case ETHTOOL_SRXCSUM:
429 return __ethtool_set_rx_csum(dev, edata.data);
419 case ETHTOOL_SSG: 430 case ETHTOOL_SSG:
420 return __ethtool_set_sg(dev, edata.data); 431 return __ethtool_set_sg(dev, edata.data);
421 case ETHTOOL_STSO: 432 case ETHTOOL_STSO:
@@ -1404,20 +1415,15 @@ static int __ethtool_set_tx_csum(struct net_device *dev, u32 data)
1404 return dev->ethtool_ops->set_tx_csum(dev, data); 1415 return dev->ethtool_ops->set_tx_csum(dev, data);
1405} 1416}
1406 1417
1407static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr) 1418static int __ethtool_set_rx_csum(struct net_device *dev, u32 data)
1408{ 1419{
1409 struct ethtool_value edata;
1410
1411 if (!dev->ethtool_ops->set_rx_csum) 1420 if (!dev->ethtool_ops->set_rx_csum)
1412 return -EOPNOTSUPP; 1421 return -EOPNOTSUPP;
1413 1422
1414 if (copy_from_user(&edata, useraddr, sizeof(edata))) 1423 if (!data)
1415 return -EFAULT;
1416
1417 if (!edata.data && dev->ethtool_ops->set_sg)
1418 dev->features &= ~NETIF_F_GRO; 1424 dev->features &= ~NETIF_F_GRO;
1419 1425
1420 return dev->ethtool_ops->set_rx_csum(dev, edata.data); 1426 return dev->ethtool_ops->set_rx_csum(dev, data);
1421} 1427}
1422 1428
1423static int __ethtool_set_tso(struct net_device *dev, u32 data) 1429static int __ethtool_set_tso(struct net_device *dev, u32 data)
@@ -1765,15 +1771,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1765 case ETHTOOL_SPAUSEPARAM: 1771 case ETHTOOL_SPAUSEPARAM:
1766 rc = ethtool_set_pauseparam(dev, useraddr); 1772 rc = ethtool_set_pauseparam(dev, useraddr);
1767 break; 1773 break;
1768 case ETHTOOL_GRXCSUM:
1769 rc = ethtool_get_value(dev, useraddr, ethcmd,
1770 (dev->ethtool_ops->get_rx_csum ?
1771 dev->ethtool_ops->get_rx_csum :
1772 ethtool_op_get_rx_csum));
1773 break;
1774 case ETHTOOL_SRXCSUM:
1775 rc = ethtool_set_rx_csum(dev, useraddr);
1776 break;
1777 case ETHTOOL_TEST: 1774 case ETHTOOL_TEST:
1778 rc = ethtool_self_test(dev, useraddr); 1775 rc = ethtool_self_test(dev, useraddr);
1779 break; 1776 break;
@@ -1846,6 +1843,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1846 rc = ethtool_set_features(dev, useraddr); 1843 rc = ethtool_set_features(dev, useraddr);
1847 break; 1844 break;
1848 case ETHTOOL_GTXCSUM: 1845 case ETHTOOL_GTXCSUM:
1846 case ETHTOOL_GRXCSUM:
1849 case ETHTOOL_GSG: 1847 case ETHTOOL_GSG:
1850 case ETHTOOL_GTSO: 1848 case ETHTOOL_GTSO:
1851 case ETHTOOL_GUFO: 1849 case ETHTOOL_GUFO:
@@ -1854,6 +1852,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1854 rc = ethtool_get_one_feature(dev, useraddr, ethcmd); 1852 rc = ethtool_get_one_feature(dev, useraddr, ethcmd);
1855 break; 1853 break;
1856 case ETHTOOL_STXCSUM: 1854 case ETHTOOL_STXCSUM:
1855 case ETHTOOL_SRXCSUM:
1857 case ETHTOOL_SSG: 1856 case ETHTOOL_SSG:
1858 case ETHTOOL_STSO: 1857 case ETHTOOL_STSO:
1859 case ETHTOOL_SUFO: 1858 case ETHTOOL_SUFO: