diff options
author | Santwona Behera <santwona.behera@sun.com> | 2008-07-02 06:47:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-02 06:47:41 -0400 |
commit | 0853ad66b14feb12acde7ac13b7c3b75770a0adc (patch) | |
tree | 0091f893aec69d708ec37ed9e56e1467fd5c95d8 | |
parent | ecbed6a41900126e7b9509e12a8d0cc22176e3eb (diff) |
netdev: Add support for rx flow hash configuration, using ethtool.
Added new interfaces to ethtool to configure receive network flow
distribution across multiple rx rings using hashing.
Signed-off-by: Santwona Behera <santwona.behera@sun.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/ethtool.h | 33 | ||||
-rw-r--r-- | net/core/ethtool.c | 37 |
2 files changed, 70 insertions, 0 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c8d216357865..8bb5e87df365 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -272,6 +272,12 @@ enum ethtool_flags { | |||
272 | ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ | 272 | ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ |
273 | }; | 273 | }; |
274 | 274 | ||
275 | struct ethtool_rxnfc { | ||
276 | __u32 cmd; | ||
277 | __u32 flow_type; | ||
278 | __u64 data; | ||
279 | }; | ||
280 | |||
275 | #ifdef __KERNEL__ | 281 | #ifdef __KERNEL__ |
276 | 282 | ||
277 | struct net_device; | 283 | struct net_device; |
@@ -396,6 +402,8 @@ struct ethtool_ops { | |||
396 | /* the following hooks are obsolete */ | 402 | /* the following hooks are obsolete */ |
397 | int (*self_test_count)(struct net_device *);/* use get_sset_count */ | 403 | int (*self_test_count)(struct net_device *);/* use get_sset_count */ |
398 | int (*get_stats_count)(struct net_device *);/* use get_sset_count */ | 404 | int (*get_stats_count)(struct net_device *);/* use get_sset_count */ |
405 | int (*get_rxhash)(struct net_device *, struct ethtool_rxnfc *); | ||
406 | int (*set_rxhash)(struct net_device *, struct ethtool_rxnfc *); | ||
399 | }; | 407 | }; |
400 | #endif /* __KERNEL__ */ | 408 | #endif /* __KERNEL__ */ |
401 | 409 | ||
@@ -442,6 +450,9 @@ struct ethtool_ops { | |||
442 | #define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ | 450 | #define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ |
443 | #define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ | 451 | #define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ |
444 | 452 | ||
453 | #define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */ | ||
454 | #define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */ | ||
455 | |||
445 | /* compatibility with older code */ | 456 | /* compatibility with older code */ |
446 | #define SPARC_ETH_GSET ETHTOOL_GSET | 457 | #define SPARC_ETH_GSET ETHTOOL_GSET |
447 | #define SPARC_ETH_SSET ETHTOOL_SSET | 458 | #define SPARC_ETH_SSET ETHTOOL_SSET |
@@ -528,4 +539,26 @@ struct ethtool_ops { | |||
528 | #define WAKE_MAGIC (1 << 5) | 539 | #define WAKE_MAGIC (1 << 5) |
529 | #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ | 540 | #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ |
530 | 541 | ||
542 | /* L3-L4 network traffic flow types */ | ||
543 | #define TCP_V4_FLOW 0x01 | ||
544 | #define UDP_V4_FLOW 0x02 | ||
545 | #define SCTP_V4_FLOW 0x03 | ||
546 | #define AH_ESP_V4_FLOW 0x04 | ||
547 | #define TCP_V6_FLOW 0x05 | ||
548 | #define UDP_V6_FLOW 0x06 | ||
549 | #define SCTP_V6_FLOW 0x07 | ||
550 | #define AH_ESP_V6_FLOW 0x08 | ||
551 | |||
552 | /* L3-L4 network traffic flow hash options */ | ||
553 | #define RXH_DEV_PORT (1 << 0) | ||
554 | #define RXH_L2DA (1 << 1) | ||
555 | #define RXH_VLAN (1 << 2) | ||
556 | #define RXH_L3_PROTO (1 << 3) | ||
557 | #define RXH_IP_SRC (1 << 4) | ||
558 | #define RXH_IP_DST (1 << 5) | ||
559 | #define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */ | ||
560 | #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ | ||
561 | #define RXH_DISCARD (1 << 31) | ||
562 | |||
563 | |||
531 | #endif /* _LINUX_ETHTOOL_H */ | 564 | #endif /* _LINUX_ETHTOOL_H */ |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 0133b5ebd545..14ada537f895 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -209,6 +209,36 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | |||
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | static int ethtool_set_rxhash(struct net_device *dev, void __user *useraddr) | ||
213 | { | ||
214 | struct ethtool_rxnfc cmd; | ||
215 | |||
216 | if (!dev->ethtool_ops->set_rxhash) | ||
217 | return -EOPNOTSUPP; | ||
218 | |||
219 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | ||
220 | return -EFAULT; | ||
221 | |||
222 | return dev->ethtool_ops->set_rxhash(dev, &cmd); | ||
223 | } | ||
224 | |||
225 | static int ethtool_get_rxhash(struct net_device *dev, void __user *useraddr) | ||
226 | { | ||
227 | struct ethtool_rxnfc info; | ||
228 | |||
229 | if (!dev->ethtool_ops->get_rxhash) | ||
230 | return -EOPNOTSUPP; | ||
231 | |||
232 | if (copy_from_user(&info, useraddr, sizeof(info))) | ||
233 | return -EFAULT; | ||
234 | |||
235 | dev->ethtool_ops->get_rxhash(dev, &info); | ||
236 | |||
237 | if (copy_to_user(useraddr, &info, sizeof(info))) | ||
238 | return -EFAULT; | ||
239 | return 0; | ||
240 | } | ||
241 | |||
212 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | 242 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
213 | { | 243 | { |
214 | struct ethtool_regs regs; | 244 | struct ethtool_regs regs; |
@@ -826,6 +856,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
826 | case ETHTOOL_GGSO: | 856 | case ETHTOOL_GGSO: |
827 | case ETHTOOL_GFLAGS: | 857 | case ETHTOOL_GFLAGS: |
828 | case ETHTOOL_GPFLAGS: | 858 | case ETHTOOL_GPFLAGS: |
859 | case ETHTOOL_GRXFH: | ||
829 | break; | 860 | break; |
830 | default: | 861 | default: |
831 | if (!capable(CAP_NET_ADMIN)) | 862 | if (!capable(CAP_NET_ADMIN)) |
@@ -977,6 +1008,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
977 | rc = ethtool_set_value(dev, useraddr, | 1008 | rc = ethtool_set_value(dev, useraddr, |
978 | dev->ethtool_ops->set_priv_flags); | 1009 | dev->ethtool_ops->set_priv_flags); |
979 | break; | 1010 | break; |
1011 | case ETHTOOL_GRXFH: | ||
1012 | rc = ethtool_get_rxhash(dev, useraddr); | ||
1013 | break; | ||
1014 | case ETHTOOL_SRXFH: | ||
1015 | rc = ethtool_set_rxhash(dev, useraddr); | ||
1016 | break; | ||
980 | default: | 1017 | default: |
981 | rc = -EOPNOTSUPP; | 1018 | rc = -EOPNOTSUPP; |
982 | } | 1019 | } |