From 5bc989e6db9df8acbf8129a4ea4a78d8614944f7 Mon Sep 17 00:00:00 2001 From: Hyong Youb Kim Date: Fri, 29 Jun 2018 02:29:31 -0700 Subject: [PATCH] net/enic: update the UDP RSS detection mechanism The UDP RSS interface has changed in the release firmware for 100G VIC adapters. The capability bit is now in NIC_CFG. Also the driver is supposed to use CMD_NIC_CFG_CHK and check if RSS config is successful. No more changes are expected with respect to UDP RSS API. Fixes: 94c351895888 ("net/enic: update UDP RSS controls") Cc: stable@dpdk.org Signed-off-by: Hyong Youb Kim Reviewed-by: John Daley --- drivers/net/enic/base/vnic_dev.c | 16 ++++++++++++++++ drivers/net/enic/base/vnic_dev.h | 4 ++++ drivers/net/enic/base/vnic_devcmd.h | 23 ++++++++++++++++++++++- drivers/net/enic/base/vnic_enet.h | 5 ++--- drivers/net/enic/base/vnic_nic.h | 4 ++-- drivers/net/enic/enic.h | 2 ++ drivers/net/enic/enic_main.c | 9 ++++++--- drivers/net/enic/enic_res.c | 11 +++++++---- 8 files changed, 61 insertions(+), 13 deletions(-) diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c index 8483f76f35..16e8814a6a 100644 --- a/drivers/net/enic/base/vnic_dev.c +++ b/drivers/net/enic/base/vnic_dev.c @@ -528,6 +528,22 @@ parse_max_level: return 0; } +void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk, + bool *weak) +{ + u64 a0 = CMD_NIC_CFG, a1 = 0; + int wait = 1000; + int err; + + *cfg_chk = false; + *weak = false; + err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait); + if (err == 0 && a0 != 0 && a1 != 0) { + *cfg_chk = true; + *weak = !!((a1 >> 32) & CMD_NIC_CFG_CAPF_UDP_WEAK); + } +} + int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd) { u64 a0 = (u32)cmd, a1 = 0; diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h index 3c9084304f..270a47bd23 100644 --- a/drivers/net/enic/base/vnic_dev.h +++ b/drivers/net/enic/base/vnic_dev.h @@ -6,6 +6,8 @@ #ifndef _VNIC_DEV_H_ #define _VNIC_DEV_H_ +#include + #include #include @@ -109,6 +111,8 @@ int vnic_dev_capable_adv_filters(struct vnic_dev *vdev); int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd); int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode, u8 *filter_actions); +void vnic_dev_capable_udp_rss_weak(struct vnic_dev *vdev, bool *cfg_chk, + bool *weak); int vnic_dev_asic_info(struct vnic_dev *vdev, u16 *asic_type, u16 *asic_rev); int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size, void *value); diff --git a/drivers/net/enic/base/vnic_devcmd.h b/drivers/net/enic/base/vnic_devcmd.h index 2865eb4d44..a22d8a76c5 100644 --- a/drivers/net/enic/base/vnic_devcmd.h +++ b/drivers/net/enic/base/vnic_devcmd.h @@ -138,9 +138,27 @@ enum vnic_devcmd_cmd { /* del VLAN id in (u16)a0 */ CMD_VLAN_DEL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 15), - /* nic_cfg in (u32)a0 */ + /* + * nic_cfg in (u32)a0 + * + * Capability query: + * out: (u64) a0= 1 if a1 is valid + * (u64) a1= (NIC_CFG bits supported) | (flags << 32) + * (flags are CMD_NIC_CFG_CAPF_xxx) + */ CMD_NIC_CFG = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16), + /* + * nic_cfg_chk (same as nic_cfg, but may return error) + * in (u32)a0 + * + * Capability query: + * out: (u64) a0= 1 if a1 is valid + * (u64) a1= (NIC_CFG bits supported) | (flags << 32) + * (flags are CMD_NIC_CFG_CAPF_xxx) + */ + CMD_NIC_CFG_CHK = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 16), + /* union vnic_rss_key in mem: (u64)a0=paddr, (u16)a1=len */ CMD_RSS_KEY = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 17), @@ -605,6 +623,9 @@ enum filter_cap_mode { /* flags for CMD_INIT */ #define CMD_INITF_DEFAULT_MAC 0x1 /* init with default mac addr */ +/* flags for CMD_NIC_CFG */ +#define CMD_NIC_CFG_CAPF_UDP_WEAK (1ULL << 0) /* Bodega-style UDP RSS */ + /* flags for CMD_PACKET_FILTER */ #define CMD_PFILTER_DIRECTED 0x01 #define CMD_PFILTER_MULTICAST 0x02 diff --git a/drivers/net/enic/base/vnic_enet.h b/drivers/net/enic/base/vnic_enet.h index 49504a7dac..901f3b46ef 100644 --- a/drivers/net/enic/base/vnic_enet.h +++ b/drivers/net/enic/base/vnic_enet.h @@ -53,9 +53,8 @@ struct vnic_enet_config { #define VENETF_NVGRE 0x20000 /* NVGRE offload */ #define VENETF_GRPINTR 0x40000 /* group interrupt */ #define VENETF_NICSWITCH 0x80000 /* NICSWITCH enabled */ -#define VENETF_RSSHASH_UDP_WEAK 0x100000 /* VIC has Bodega-style UDP RSS */ -#define VENETF_RSSHASH_UDPIPV4 0x200000 /* Hash on UDP + IPv4 fields */ -#define VENETF_RSSHASH_UDPIPV6 0x400000 /* Hash on UDP + IPv6 fields */ +#define VENETF_RSSHASH_UDPIPV4 0x100000 /* Hash on UDP + IPv4 fields */ +#define VENETF_RSSHASH_UDPIPV6 0x200000 /* Hash on UDP + IPv6 fields */ #define VENET_INTR_TYPE_MIN 0 /* Timer specs min interrupt spacing */ #define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */ diff --git a/drivers/net/enic/base/vnic_nic.h b/drivers/net/enic/base/vnic_nic.h index e318d0cb5c..1604085222 100644 --- a/drivers/net/enic/base/vnic_nic.h +++ b/drivers/net/enic/base/vnic_nic.h @@ -32,8 +32,8 @@ #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 (1 << 2) #define NIC_CFG_RSS_HASH_TYPE_IPV6 (1 << 3) #define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 (1 << 4) -#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX (1 << 5) -#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX (1 << 6) +#define NIC_CFG_RSS_HASH_TYPE_RSVD1 (1 << 5) +#define NIC_CFG_RSS_HASH_TYPE_RSVD2 (1 << 6) #define NIC_CFG_RSS_HASH_TYPE_UDP_IPV6 (1 << 7) static inline void vnic_set_nic_cfg(u32 *nic_cfg, diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index ee83fe573b..ea0a688d3b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -123,6 +123,8 @@ struct enic { u8 filter_actions; /* HW supported actions */ bool vxlan; bool disable_overlay; /* devargs disable_overlay=1 */ + bool nic_cfg_chk; /* NIC_CFG_CHK available */ + bool udp_rss_weak; /* Bodega style UDP RSS */ unsigned int flags; unsigned int priv_flags; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a25d303dea..899603fa7e 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1197,7 +1197,7 @@ int enic_set_rss_conf(struct enic *enic, struct rte_eth_rss_conf *rss_conf) rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_TCP_IPV4; if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) { rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_UDP_IPV4; - if (ENIC_SETTING(enic, RSSHASH_UDP_WEAK)) { + if (enic->udp_rss_weak) { /* * 'TCP' is not a typo. The "weak" version of * UDP RSS requires both the TCP and UDP bits @@ -1213,7 +1213,7 @@ int enic_set_rss_conf(struct enic *enic, struct rte_eth_rss_conf *rss_conf) rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_TCP_IPV6; if (rss_hf & (ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_IPV6_UDP_EX)) { rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_UDP_IPV6; - if (ENIC_SETTING(enic, RSSHASH_UDP_WEAK)) + if (enic->udp_rss_weak) rss_hash_type |= NIC_CFG_RSS_HASH_TYPE_TCP_IPV6; } } else { @@ -1237,8 +1237,11 @@ int enic_set_rss_conf(struct enic *enic, struct rte_eth_rss_conf *rss_conf) enic->rss_hf = rss_hf; enic->rss_hash_type = rss_hash_type; enic->rss_enable = rss_enable; + } else { + dev_err(enic, "Failed to update RSS configurations." + " hash=0x%x\n", rss_hash_type); } - return 0; + return ret; } int enic_set_vlan_strip(struct enic *enic) diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 6b404c3c0f..d1113b2f15 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -82,6 +82,8 @@ int enic_get_vnic_config(struct enic *enic) "Error getting filter modes, %d\n", err); return err; } + vnic_dev_capable_udp_rss_weak(enic->vdev, &enic->nic_cfg_chk, + &enic->udp_rss_weak); dev_info(enic, "Flow api filter mode: %s Actions: %s%s%s\n", ((enic->flow_filter_mode == FILTER_DPDK_1) ? "DPDK" : @@ -124,7 +126,7 @@ int enic_get_vnic_config(struct enic *enic) ENIC_SETTING(enic, RXCSUM) ? "yes" : "no", ENIC_SETTING(enic, RSS) ? (ENIC_SETTING(enic, RSSHASH_UDPIPV4) ? "+UDP" : - ((ENIC_SETTING(enic, RSSHASH_UDP_WEAK) ? "+udp" : + ((enic->udp_rss_weak ? "+udp" : "yes"))) : "no", c->intr_mode == VENET_INTR_MODE_INTX ? "INTx" : c->intr_mode == VENET_INTR_MODE_MSI ? "MSI" : @@ -161,7 +163,7 @@ int enic_get_vnic_config(struct enic *enic) if (ENIC_SETTING(enic, RSSHASH_TCPIPV6)) enic->flow_type_rss_offloads |= ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX; - if (ENIC_SETTING(enic, RSSHASH_UDP_WEAK)) + if (enic->udp_rss_weak) enic->flow_type_rss_offloads |= ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_IPV6_UDP_EX; @@ -235,6 +237,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 ig_vlan_strip_en) { + enum vnic_devcmd_cmd cmd; u64 a0, a1; u32 nic_cfg; int wait = 1000; @@ -245,8 +248,8 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type, a0 = nic_cfg; a1 = 0; - - return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait); + cmd = enic->nic_cfg_chk ? CMD_NIC_CFG_CHK : CMD_NIC_CFG; + 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) -- 2.20.1