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

Commit 4016a7f1 authored by Govindarajulu Varadarajan's avatar Govindarajulu Varadarajan Committed by David S. Miller
Browse files

enic: fix UDP rss bits



In commit 48398b6e ("enic: set UDP rss flag") driver needed to set a
single bit to enable UDP rss. This is changed to two bit. One for UDP
IPv4 and other bit for UDP IPv6. The hardware which supports this is not
released yet. When released, driver should set 2 bit to enable UDP rss for
both IPv4 and IPv6.

Also add spinlock around vnic_dev_capable_rss_hash_type().

Signed-off-by: default avatarGovindarajulu Varadarajan <gvaradar@cisco.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 75d4e704
Loading
Loading
Loading
Loading
+14 −4
Original line number Original line Diff line number Diff line
@@ -476,18 +476,28 @@ static int enic_grxclsrule(struct enic *enic, struct ethtool_rxnfc *cmd)


static int enic_get_rx_flow_hash(struct enic *enic, struct ethtool_rxnfc *cmd)
static int enic_get_rx_flow_hash(struct enic *enic, struct ethtool_rxnfc *cmd)
{
{
	u8 rss_hash_type = 0;
	cmd->data = 0;
	cmd->data = 0;


	spin_lock_bh(&enic->devcmd_lock);
	(void)vnic_dev_capable_rss_hash_type(enic->vdev, &rss_hash_type);
	spin_unlock_bh(&enic->devcmd_lock);
	switch (cmd->flow_type) {
	switch (cmd->flow_type) {
	case TCP_V6_FLOW:
	case TCP_V6_FLOW:
	case TCP_V4_FLOW:
	case TCP_V4_FLOW:
		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
		cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3 |
		/* Fall through */
			     RXH_IP_SRC | RXH_IP_DST;
		break;
	case UDP_V6_FLOW:
	case UDP_V6_FLOW:
		cmd->data |= RXH_IP_SRC | RXH_IP_DST;
		if (rss_hash_type & NIC_CFG_RSS_HASH_TYPE_UDP_IPV6)
			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
		break;
	case UDP_V4_FLOW:
	case UDP_V4_FLOW:
		if (vnic_dev_capable_udp_rss(enic->vdev))
		cmd->data |= RXH_IP_SRC | RXH_IP_DST;
		if (rss_hash_type & NIC_CFG_RSS_HASH_TYPE_UDP_IPV4)
			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
		/* Fall through */
		break;
	case SCTP_V4_FLOW:
	case SCTP_V4_FLOW:
	case AH_ESP_V4_FLOW:
	case AH_ESP_V4_FLOW:
	case AH_V4_FLOW:
	case AH_V4_FLOW:
+14 −6
Original line number Original line Diff line number Diff line
@@ -2320,16 +2320,24 @@ static int enic_set_rss_nic_cfg(struct enic *enic)
{
{
	struct device *dev = enic_get_dev(enic);
	struct device *dev = enic_get_dev(enic);
	const u8 rss_default_cpu = 0;
	const u8 rss_default_cpu = 0;
	u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 |
		NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 |
		NIC_CFG_RSS_HASH_TYPE_IPV6 |
		NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
	const u8 rss_hash_bits = 7;
	const u8 rss_hash_bits = 7;
	const u8 rss_base_cpu = 0;
	const u8 rss_base_cpu = 0;
	u8 rss_hash_type;
	int res;
	u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);
	u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1);


	if (vnic_dev_capable_udp_rss(enic->vdev))
	spin_lock_bh(&enic->devcmd_lock);
		rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_UDP;
	res = vnic_dev_capable_rss_hash_type(enic->vdev, &rss_hash_type);
	spin_unlock_bh(&enic->devcmd_lock);
	if (res) {
		/* defaults for old adapters
		 */
		rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4	|
				NIC_CFG_RSS_HASH_TYPE_TCP_IPV4	|
				NIC_CFG_RSS_HASH_TYPE_IPV6	|
				NIC_CFG_RSS_HASH_TYPE_TCP_IPV6;
	}

	if (rss_enable) {
	if (rss_enable) {
		if (!enic_set_rsskey(enic)) {
		if (!enic_set_rsskey(enic)) {
			if (enic_set_rsscpu(enic, rss_hash_bits)) {
			if (enic_set_rsscpu(enic, rss_hash_bits)) {
+6 −1
Original line number Original line Diff line number Diff line
@@ -149,6 +149,7 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
	u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
	u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
	u8 ig_vlan_strip_en)
	u8 ig_vlan_strip_en)
{
{
	enum vnic_devcmd_cmd cmd = CMD_NIC_CFG;
	u64 a0, a1;
	u64 a0, a1;
	u32 nic_cfg;
	u32 nic_cfg;
	int wait = 1000;
	int wait = 1000;
@@ -160,7 +161,11 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
	a0 = nic_cfg;
	a0 = nic_cfg;
	a1 = 0;
	a1 = 0;


	return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait);
	if (rss_hash_type & (NIC_CFG_RSS_HASH_TYPE_UDP_IPV4 |
			     NIC_CFG_RSS_HASH_TYPE_UDP_IPV6))
		cmd = CMD_NIC_CFG_CHK;

	return vnic_dev_cmd(enic->vdev, cmd, &a0, &a1, wait);
}
}


int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len)
int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len)
+11 −7
Original line number Original line Diff line number Diff line
@@ -1282,19 +1282,23 @@ int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
	return ret;
	return ret;
}
}


bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev)
int vnic_dev_capable_rss_hash_type(struct vnic_dev *vdev, u8 *rss_hash_type)
{
{
	u64 a0 = CMD_NIC_CFG, a1 = 0;
	u64 a0 = CMD_NIC_CFG, a1 = 0;
	u64 rss_hash_type;
	int wait = 1000;
	int wait = 1000;
	int err;
	int err;


	err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
	err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
	if (err || !a0)
	/* rss_hash_type is valid only when a0 is 1. Adapter which does not
		return false;
	 * support CMD_CAPABILITY for rss_hash_type has a0 = 0
	 */
	if (err || (a0 != 1))
		return -EOPNOTSUPP;


	rss_hash_type = (a1 >> NIC_CFG_RSS_HASH_TYPE_SHIFT) &
	a1 = (a1 >> NIC_CFG_RSS_HASH_TYPE_SHIFT) &
	     NIC_CFG_RSS_HASH_TYPE_MASK_FIELD;
	     NIC_CFG_RSS_HASH_TYPE_MASK_FIELD;


	return (rss_hash_type & NIC_CFG_RSS_HASH_TYPE_UDP);
	*rss_hash_type = (u8)a1;

	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -184,6 +184,6 @@ int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
				 u16 vxlan_udp_port_number);
				 u16 vxlan_udp_port_number);
int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
				       u64 *supported_versions, u64 *a1);
				       u64 *supported_versions, u64 *a1);
bool vnic_dev_capable_udp_rss(struct vnic_dev *vdev);
int vnic_dev_capable_rss_hash_type(struct vnic_dev *vdev, u8 *rss_hash_type);


#endif /* _VNIC_DEV_H_ */
#endif /* _VNIC_DEV_H_ */
Loading