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>
This commit is contained in:
parent
ecbed6a419
commit
0853ad66b1
|
@ -272,6 +272,12 @@ enum ethtool_flags {
|
||||||
ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
|
ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ethtool_rxnfc {
|
||||||
|
__u32 cmd;
|
||||||
|
__u32 flow_type;
|
||||||
|
__u64 data;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
struct net_device;
|
struct net_device;
|
||||||
|
@ -396,6 +402,8 @@ struct ethtool_ops {
|
||||||
/* the following hooks are obsolete */
|
/* the following hooks are obsolete */
|
||||||
int (*self_test_count)(struct net_device *);/* use get_sset_count */
|
int (*self_test_count)(struct net_device *);/* use get_sset_count */
|
||||||
int (*get_stats_count)(struct net_device *);/* use get_sset_count */
|
int (*get_stats_count)(struct net_device *);/* use get_sset_count */
|
||||||
|
int (*get_rxhash)(struct net_device *, struct ethtool_rxnfc *);
|
||||||
|
int (*set_rxhash)(struct net_device *, struct ethtool_rxnfc *);
|
||||||
};
|
};
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
@ -442,6 +450,9 @@ struct ethtool_ops {
|
||||||
#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
|
#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */
|
||||||
#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
|
#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */
|
||||||
|
|
||||||
|
#define ETHTOOL_GRXFH 0x00000029 /* Get RX flow hash configuration */
|
||||||
|
#define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */
|
||||||
|
|
||||||
/* compatibility with older code */
|
/* compatibility with older code */
|
||||||
#define SPARC_ETH_GSET ETHTOOL_GSET
|
#define SPARC_ETH_GSET ETHTOOL_GSET
|
||||||
#define SPARC_ETH_SSET ETHTOOL_SSET
|
#define SPARC_ETH_SSET ETHTOOL_SSET
|
||||||
|
@ -528,4 +539,26 @@ struct ethtool_ops {
|
||||||
#define WAKE_MAGIC (1 << 5)
|
#define WAKE_MAGIC (1 << 5)
|
||||||
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
|
#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
|
||||||
|
|
||||||
|
/* L3-L4 network traffic flow types */
|
||||||
|
#define TCP_V4_FLOW 0x01
|
||||||
|
#define UDP_V4_FLOW 0x02
|
||||||
|
#define SCTP_V4_FLOW 0x03
|
||||||
|
#define AH_ESP_V4_FLOW 0x04
|
||||||
|
#define TCP_V6_FLOW 0x05
|
||||||
|
#define UDP_V6_FLOW 0x06
|
||||||
|
#define SCTP_V6_FLOW 0x07
|
||||||
|
#define AH_ESP_V6_FLOW 0x08
|
||||||
|
|
||||||
|
/* L3-L4 network traffic flow hash options */
|
||||||
|
#define RXH_DEV_PORT (1 << 0)
|
||||||
|
#define RXH_L2DA (1 << 1)
|
||||||
|
#define RXH_VLAN (1 << 2)
|
||||||
|
#define RXH_L3_PROTO (1 << 3)
|
||||||
|
#define RXH_IP_SRC (1 << 4)
|
||||||
|
#define RXH_IP_DST (1 << 5)
|
||||||
|
#define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */
|
||||||
|
#define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */
|
||||||
|
#define RXH_DISCARD (1 << 31)
|
||||||
|
|
||||||
|
|
||||||
#endif /* _LINUX_ETHTOOL_H */
|
#endif /* _LINUX_ETHTOOL_H */
|
||||||
|
|
|
@ -209,6 +209,36 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ethtool_set_rxhash(struct net_device *dev, void __user *useraddr)
|
||||||
|
{
|
||||||
|
struct ethtool_rxnfc cmd;
|
||||||
|
|
||||||
|
if (!dev->ethtool_ops->set_rxhash)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return dev->ethtool_ops->set_rxhash(dev, &cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ethtool_get_rxhash(struct net_device *dev, void __user *useraddr)
|
||||||
|
{
|
||||||
|
struct ethtool_rxnfc info;
|
||||||
|
|
||||||
|
if (!dev->ethtool_ops->get_rxhash)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
if (copy_from_user(&info, useraddr, sizeof(info)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
dev->ethtool_ops->get_rxhash(dev, &info);
|
||||||
|
|
||||||
|
if (copy_to_user(useraddr, &info, sizeof(info)))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
|
static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
|
||||||
{
|
{
|
||||||
struct ethtool_regs regs;
|
struct ethtool_regs regs;
|
||||||
|
@ -826,6 +856,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
|
||||||
case ETHTOOL_GGSO:
|
case ETHTOOL_GGSO:
|
||||||
case ETHTOOL_GFLAGS:
|
case ETHTOOL_GFLAGS:
|
||||||
case ETHTOOL_GPFLAGS:
|
case ETHTOOL_GPFLAGS:
|
||||||
|
case ETHTOOL_GRXFH:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!capable(CAP_NET_ADMIN))
|
if (!capable(CAP_NET_ADMIN))
|
||||||
|
@ -977,6 +1008,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
|
||||||
rc = ethtool_set_value(dev, useraddr,
|
rc = ethtool_set_value(dev, useraddr,
|
||||||
dev->ethtool_ops->set_priv_flags);
|
dev->ethtool_ops->set_priv_flags);
|
||||||
break;
|
break;
|
||||||
|
case ETHTOOL_GRXFH:
|
||||||
|
rc = ethtool_get_rxhash(dev, useraddr);
|
||||||
|
break;
|
||||||
|
case ETHTOOL_SRXFH:
|
||||||
|
rc = ethtool_set_rxhash(dev, useraddr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue