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: 94c3518958 ("net/enic: update UDP RSS controls")
Cc: stable@dpdk.org

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
This commit is contained in:
Hyong Youb Kim 2018-06-29 02:29:31 -07:00 committed by Ferruh Yigit
parent 15666e5309
commit 5bc989e6db
8 changed files with 61 additions and 13 deletions

View File

@ -528,6 +528,22 @@ int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode,
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;

View File

@ -6,6 +6,8 @@
#ifndef _VNIC_DEV_H_
#define _VNIC_DEV_H_
#include <stdbool.h>
#include <rte_pci.h>
#include <rte_bus_pci.h>
@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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)