Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0853ad66 authored by Santwona Behera's avatar Santwona Behera Committed by David S. Miller
Browse files

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: default avatarSantwona Behera <santwona.behera@sun.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ecbed6a4
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -272,6 +272,12 @@ enum ethtool_flags {
	ETH_FLAG_LRO		= (1 << 15),	/* LRO is enabled */
};

struct ethtool_rxnfc {
	__u32		cmd;
	__u32		flow_type;
	__u64		data;
};

#ifdef __KERNEL__

struct net_device;
@@ -396,6 +402,8 @@ struct ethtool_ops {
	/* the following hooks are obsolete */
	int	(*self_test_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__ */

@@ -442,6 +450,9 @@ struct ethtool_ops {
#define ETHTOOL_GPFLAGS		0x00000027 /* Get 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 */
#define SPARC_ETH_GSET		ETHTOOL_GSET
#define SPARC_ETH_SSET		ETHTOOL_SSET
@@ -528,4 +539,26 @@ struct ethtool_ops {
#define WAKE_MAGIC		(1 << 5)
#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 */
+37 −0
Original line number Diff line number Diff line
@@ -209,6 +209,36 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr)
	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)
{
	struct ethtool_regs regs;
@@ -826,6 +856,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
	case ETHTOOL_GGSO:
	case ETHTOOL_GFLAGS:
	case ETHTOOL_GPFLAGS:
	case ETHTOOL_GRXFH:
		break;
	default:
		if (!capable(CAP_NET_ADMIN))
@@ -977,6 +1008,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
		rc = ethtool_set_value(dev, useraddr,
				       dev->ethtool_ops->set_priv_flags);
		break;
	case ETHTOOL_GRXFH:
		rc = ethtool_get_rxhash(dev, useraddr);
		break;
	case ETHTOOL_SRXFH:
		rc = ethtool_set_rxhash(dev, useraddr);
		break;
	default:
		rc = -EOPNOTSUPP;
	}