diff options
-rw-r--r-- | include/linux/ethtool.h | 21 | ||||
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | net/core/ethtool.c | 61 |
3 files changed, 83 insertions, 0 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 23ccea811297..0e5de2fb960c 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -256,6 +256,19 @@ struct ethtool_perm_addr { | |||
256 | __u8 data[0]; | 256 | __u8 data[0]; |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* boolean flags controlling per-interface behavior characteristics. | ||
260 | * When reading, the flag indicates whether or not a certain behavior | ||
261 | * is enabled/present. When writing, the flag indicates whether | ||
262 | * or not the driver should turn on (set) or off (clear) a behavior. | ||
263 | * | ||
264 | * Some behaviors may read-only (unconditionally absent or present). | ||
265 | * If such is the case, return EINVAL in the set-flags operation if the | ||
266 | * flag differs from the read-only value. | ||
267 | */ | ||
268 | enum ethtool_flags { | ||
269 | ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ | ||
270 | }; | ||
271 | |||
259 | #ifdef __KERNEL__ | 272 | #ifdef __KERNEL__ |
260 | 273 | ||
261 | struct net_device; | 274 | struct net_device; |
@@ -272,6 +285,8 @@ u32 ethtool_op_get_tso(struct net_device *dev); | |||
272 | int ethtool_op_set_tso(struct net_device *dev, u32 data); | 285 | int ethtool_op_set_tso(struct net_device *dev, u32 data); |
273 | u32 ethtool_op_get_ufo(struct net_device *dev); | 286 | u32 ethtool_op_get_ufo(struct net_device *dev); |
274 | int ethtool_op_set_ufo(struct net_device *dev, u32 data); | 287 | int ethtool_op_set_ufo(struct net_device *dev, u32 data); |
288 | u32 ethtool_op_get_flags(struct net_device *dev); | ||
289 | int ethtool_op_set_flags(struct net_device *dev, u32 data); | ||
275 | 290 | ||
276 | /** | 291 | /** |
277 | * ðtool_ops - Alter and report network device settings | 292 | * ðtool_ops - Alter and report network device settings |
@@ -307,6 +322,8 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); | |||
307 | * get_strings: Return a set of strings that describe the requested objects | 322 | * get_strings: Return a set of strings that describe the requested objects |
308 | * phys_id: Identify the device | 323 | * phys_id: Identify the device |
309 | * get_stats: Return statistics about the device | 324 | * get_stats: Return statistics about the device |
325 | * get_flags: get 32-bit flags bitmap | ||
326 | * set_flags: set 32-bit flags bitmap | ||
310 | * | 327 | * |
311 | * Description: | 328 | * Description: |
312 | * | 329 | * |
@@ -369,6 +386,8 @@ struct ethtool_ops { | |||
369 | void (*complete)(struct net_device *); | 386 | void (*complete)(struct net_device *); |
370 | u32 (*get_ufo)(struct net_device *); | 387 | u32 (*get_ufo)(struct net_device *); |
371 | int (*set_ufo)(struct net_device *, u32); | 388 | int (*set_ufo)(struct net_device *, u32); |
389 | u32 (*get_flags)(struct net_device *); | ||
390 | int (*set_flags)(struct net_device *, u32); | ||
372 | }; | 391 | }; |
373 | #endif /* __KERNEL__ */ | 392 | #endif /* __KERNEL__ */ |
374 | 393 | ||
@@ -410,6 +429,8 @@ struct ethtool_ops { | |||
410 | #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ | 429 | #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ |
411 | #define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ | 430 | #define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ |
412 | #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ | 431 | #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ |
432 | #define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ | ||
433 | #define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ | ||
413 | 434 | ||
414 | /* compatibility with older code */ | 435 | /* compatibility with older code */ |
415 | #define SPARC_ETH_GSET ETHTOOL_GSET | 436 | #define SPARC_ETH_GSET ETHTOOL_GSET |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b93575db8cce..8f00bdf95ef4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -449,6 +449,7 @@ struct net_device | |||
449 | #define NETIF_F_GSO 2048 /* Enable software GSO. */ | 449 | #define NETIF_F_GSO 2048 /* Enable software GSO. */ |
450 | #define NETIF_F_LLTX 4096 /* LockLess TX */ | 450 | #define NETIF_F_LLTX 4096 /* LockLess TX */ |
451 | #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ | 451 | #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ |
452 | #define NETIF_F_LRO 32768 /* large receive offload */ | ||
452 | 453 | ||
453 | /* Segmentation offload features */ | 454 | /* Segmentation offload features */ |
454 | #define NETIF_F_GSO_SHIFT 16 | 455 | #define NETIF_F_GSO_SHIFT 16 |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index c5e059352d43..6f8b78bcfd84 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -109,6 +109,32 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data) | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | /* the following list of flags are the same as their associated | ||
113 | * NETIF_F_xxx values in include/linux/netdevice.h | ||
114 | */ | ||
115 | static const u32 flags_dup_features = | ||
116 | ETH_FLAG_LRO; | ||
117 | |||
118 | u32 ethtool_op_get_flags(struct net_device *dev) | ||
119 | { | ||
120 | /* in the future, this function will probably contain additional | ||
121 | * handling for flags which are not so easily handled | ||
122 | * by a simple masking operation | ||
123 | */ | ||
124 | |||
125 | return dev->features & flags_dup_features; | ||
126 | } | ||
127 | |||
128 | int ethtool_op_set_flags(struct net_device *dev, u32 data) | ||
129 | { | ||
130 | if (data & ETH_FLAG_LRO) | ||
131 | dev->features |= NETIF_F_LRO; | ||
132 | else | ||
133 | dev->features &= ~NETIF_F_LRO; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
112 | /* Handlers for each ethtool command */ | 138 | /* Handlers for each ethtool command */ |
113 | 139 | ||
114 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | 140 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) |
@@ -783,6 +809,33 @@ static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr) | |||
783 | return 0; | 809 | return 0; |
784 | } | 810 | } |
785 | 811 | ||
812 | static int ethtool_get_flags(struct net_device *dev, char __user *useraddr) | ||
813 | { | ||
814 | struct ethtool_value edata = { ETHTOOL_GFLAGS }; | ||
815 | |||
816 | if (!dev->ethtool_ops->get_flags) | ||
817 | return -EOPNOTSUPP; | ||
818 | |||
819 | edata.data = dev->ethtool_ops->get_flags(dev); | ||
820 | |||
821 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | ||
822 | return -EFAULT; | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static int ethtool_set_flags(struct net_device *dev, char __user *useraddr) | ||
827 | { | ||
828 | struct ethtool_value edata; | ||
829 | |||
830 | if (!dev->ethtool_ops->set_flags) | ||
831 | return -EOPNOTSUPP; | ||
832 | |||
833 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | ||
834 | return -EFAULT; | ||
835 | |||
836 | return dev->ethtool_ops->set_flags(dev, edata.data); | ||
837 | } | ||
838 | |||
786 | /* The main entry point in this file. Called from net/core/dev.c */ | 839 | /* The main entry point in this file. Called from net/core/dev.c */ |
787 | 840 | ||
788 | int dev_ethtool(struct ifreq *ifr) | 841 | int dev_ethtool(struct ifreq *ifr) |
@@ -935,6 +988,12 @@ int dev_ethtool(struct ifreq *ifr) | |||
935 | case ETHTOOL_SGSO: | 988 | case ETHTOOL_SGSO: |
936 | rc = ethtool_set_gso(dev, useraddr); | 989 | rc = ethtool_set_gso(dev, useraddr); |
937 | break; | 990 | break; |
991 | case ETHTOOL_GFLAGS: | ||
992 | rc = ethtool_get_flags(dev, useraddr); | ||
993 | break; | ||
994 | case ETHTOOL_SFLAGS: | ||
995 | rc = ethtool_set_flags(dev, useraddr); | ||
996 | break; | ||
938 | default: | 997 | default: |
939 | rc = -EOPNOTSUPP; | 998 | rc = -EOPNOTSUPP; |
940 | } | 999 | } |
@@ -959,3 +1018,5 @@ EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); | |||
959 | EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum); | 1018 | EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum); |
960 | EXPORT_SYMBOL(ethtool_op_set_ufo); | 1019 | EXPORT_SYMBOL(ethtool_op_set_ufo); |
961 | EXPORT_SYMBOL(ethtool_op_get_ufo); | 1020 | EXPORT_SYMBOL(ethtool_op_get_ufo); |
1021 | EXPORT_SYMBOL(ethtool_op_set_flags); | ||
1022 | EXPORT_SYMBOL(ethtool_op_get_flags); | ||