Commit 0853ad66b14feb12acde7ac13b7c3b75770a0adc
Committed by
David S. Miller
1 parent
ecbed6a419
Exists in
master
and in
4 other branches
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>
Showing 2 changed files with 70 additions and 0 deletions Side-by-side Diff
include/linux/ethtool.h
... | ... | @@ -272,6 +272,12 @@ |
272 | 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 | 281 | #ifdef __KERNEL__ |
276 | 282 | |
277 | 283 | struct net_device; |
... | ... | @@ -396,6 +402,8 @@ |
396 | 402 | /* the following hooks are obsolete */ |
397 | 403 | int (*self_test_count)(struct net_device *);/* use get_sset_count */ |
398 | 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 | 408 | #endif /* __KERNEL__ */ |
401 | 409 | |
... | ... | @@ -442,6 +450,9 @@ |
442 | 450 | #define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ |
443 | 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 | 456 | /* compatibility with older code */ |
446 | 457 | #define SPARC_ETH_GSET ETHTOOL_GSET |
447 | 458 | #define SPARC_ETH_SSET ETHTOOL_SSET |
... | ... | @@ -527,6 +538,28 @@ |
527 | 538 | #define WAKE_ARP (1 << 4) |
528 | 539 | #define WAKE_MAGIC (1 << 5) |
529 | 540 | #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ |
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 | + | |
530 | 563 | |
531 | 564 | #endif /* _LINUX_ETHTOOL_H */ |
net/core/ethtool.c
... | ... | @@ -209,6 +209,36 @@ |
209 | 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 | 242 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
213 | 243 | { |
214 | 244 | struct ethtool_regs regs; |
... | ... | @@ -826,6 +856,7 @@ |
826 | 856 | case ETHTOOL_GGSO: |
827 | 857 | case ETHTOOL_GFLAGS: |
828 | 858 | case ETHTOOL_GPFLAGS: |
859 | + case ETHTOOL_GRXFH: | |
829 | 860 | break; |
830 | 861 | default: |
831 | 862 | if (!capable(CAP_NET_ADMIN)) |
... | ... | @@ -976,6 +1007,12 @@ |
976 | 1007 | case ETHTOOL_SPFLAGS: |
977 | 1008 | rc = ethtool_set_value(dev, useraddr, |
978 | 1009 | dev->ethtool_ops->set_priv_flags); |
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); | |
979 | 1016 | break; |
980 | 1017 | default: |
981 | 1018 | rc = -EOPNOTSUPP; |