@@ -55,6 +55,12 @@ struct port_info {
u8 rss_mode; /* rss mode */
u16 rss_size; /* size of VI's RSS table slice */
u64 rss_hf; /* RSS Hash Function */
+
+ /* viid fields either returned by fw
+ * or decoded by parsing viid by driver.
+ */
+ u8 vin;
+ u8 vivld;
};
/* Enable or disable autonegotiation. If this is set to enable,
@@ -273,6 +273,7 @@ struct adapter_params {
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
u8 fw_caps_support; /* 32-bit Port Capabilities */
u8 filter2_wr_support; /* FW support for FILTER2_WR */
+ u32 viid_smt_extn_support:1; /* FW returns vin and smt index */
u32 max_tx_coalesce_num; /* Max # of Tx packets that can be coalesced */
};
@@ -382,10 +383,11 @@ int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox,
unsigned int port, unsigned int pf, unsigned int vf,
unsigned int nmac, u8 *mac, unsigned int *rss_size,
- unsigned int portfunc, unsigned int idstype);
+ unsigned int portfunc, unsigned int idstype,
+ u8 *vivld, u8 *vin);
int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
- unsigned int *rss_size);
+ unsigned int *rss_size, u8 *vivild, u8 *vin);
int t4_free_vi(struct adapter *adap, unsigned int mbox,
unsigned int pf, unsigned int vf,
unsigned int viid);
@@ -4017,7 +4017,8 @@ int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox,
unsigned int port, unsigned int pf, unsigned int vf,
unsigned int nmac, u8 *mac, unsigned int *rss_size,
- unsigned int portfunc, unsigned int idstype)
+ unsigned int portfunc, unsigned int idstype,
+ u8 *vivld, u8 *vin)
{
int ret;
struct fw_vi_cmd c;
@@ -4055,6 +4056,10 @@ int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox,
}
if (rss_size)
*rss_size = G_FW_VI_CMD_RSSSIZE(be16_to_cpu(c.norss_rsssize));
+ if (vivld)
+ *vivld = G_FW_VI_CMD_VFVLD(be32_to_cpu(c.alloc_to_len16));
+ if (vin)
+ *vin = G_FW_VI_CMD_VIN(be32_to_cpu(c.alloc_to_len16));
return G_FW_VI_CMD_VIID(cpu_to_be16(c.type_to_viid));
}
@@ -4075,10 +4080,10 @@ int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox,
*/
int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
- unsigned int *rss_size)
+ unsigned int *rss_size, u8 *vivld, u8 *vin)
{
return t4_alloc_vi_func(adap, mbox, port, pf, vf, nmac, mac, rss_size,
- FW_VI_FUNC_ETH, 0);
+ FW_VI_FUNC_ETH, 0, vivld, vin);
}
/**
@@ -5346,6 +5351,7 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
fw_port_cap32_t pcaps, acaps;
enum fw_port_type port_type;
struct fw_port_cmd cmd;
+ u8 vivld = 0, vin = 0;
int ret, i, j = 0;
int mdio_addr;
u32 action;
@@ -5417,7 +5423,8 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
acaps = be32_to_cpu(cmd.u.info32.acaps32);
}
- ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
+ ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size,
+ &vivld, &vin);
if (ret < 0)
return ret;
@@ -5426,6 +5433,18 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
pi->rss_size = rss_size;
t4_os_set_hw_addr(adap, i, addr);
+ /* If fw supports returning the VIN as part of FW_VI_CMD,
+ * save the returned values.
+ */
+ if (adap->params.viid_smt_extn_support) {
+ pi->vivld = vivld;
+ pi->vin = vin;
+ } else {
+ /* Retrieve the values from VIID */
+ pi->vivld = G_FW_VIID_VIVLD(pi->viid);
+ pi->vin = G_FW_VIID_VIN(pi->viid);
+ }
+
pi->port_type = port_type;
pi->mdio_addr = mdio_addr;
pi->mod_type = FW_PORT_MOD_TYPE_NA;
@@ -679,6 +679,7 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_TPREV = 0x0C, /* tp version */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
FW_PARAMS_PARAM_DEV_FILTER2_WR = 0x1D,
+ FW_PARAMS_PARAM_DEV_OPAQUE_VIID_SMT_EXTN = 0x27,
};
/*
@@ -1235,6 +1236,18 @@ enum fw_vi_func {
FW_VI_FUNC_ETH,
};
+/* Macros for VIID parsing:
+ * VIID - [10:8] PFN, [7] VI Valid, [6:0] VI number
+ */
+
+#define S_FW_VIID_VIVLD 7
+#define M_FW_VIID_VIVLD 0x1
+#define G_FW_VIID_VIVLD(x) (((x) >> S_FW_VIID_VIVLD) & M_FW_VIID_VIVLD)
+
+#define S_FW_VIID_VIN 0
+#define M_FW_VIID_VIN 0x7F
+#define G_FW_VIID_VIN(x) (((x) >> S_FW_VIID_VIN) & M_FW_VIID_VIN)
+
struct fw_vi_cmd {
__be32 op_to_vfn;
__be32 alloc_to_len16;
@@ -1276,6 +1289,16 @@ struct fw_vi_cmd {
#define G_FW_VI_CMD_FREE(x) (((x) >> S_FW_VI_CMD_FREE) & M_FW_VI_CMD_FREE)
#define F_FW_VI_CMD_FREE V_FW_VI_CMD_FREE(1U)
+#define S_FW_VI_CMD_VFVLD 24
+#define M_FW_VI_CMD_VFVLD 0x1
+#define G_FW_VI_CMD_VFVLD(x) \
+ (((x) >> S_FW_VI_CMD_VFVLD) & M_FW_VI_CMD_VFVLD)
+
+#define S_FW_VI_CMD_VIN 16
+#define M_FW_VI_CMD_VIN 0xff
+#define G_FW_VI_CMD_VIN(x) \
+ (((x) >> S_FW_VI_CMD_VIN) & M_FW_VI_CMD_VIN)
+
#define S_FW_VI_CMD_TYPE 15
#define M_FW_VI_CMD_TYPE 0x1
#define V_FW_VI_CMD_TYPE(x) ((x) << S_FW_VI_CMD_TYPE)
@@ -312,8 +312,9 @@ static u64 hash_filter_ntuple(const struct filter_entry *f)
if (tp->vnic_shift >= 0) {
if ((adap->params.tp.ingress_config & F_VNIC) &&
f->fs.mask.pfvf_vld)
- ntuple |= (u64)((f->fs.val.pfvf_vld << 16) |
- (f->fs.val.pf << 13)) << tp->vnic_shift;
+ ntuple |= (u64)(f->fs.val.pfvf_vld << 16 |
+ f->fs.val.pf << 13 | f->fs.val.vf) <<
+ tp->vnic_shift;
else if (!(adap->params.tp.ingress_config & F_VNIC) &&
f->fs.mask.ovlan_vld)
ntuple |= (u64)(f->fs.val.ovlan_vld << 16 |
@@ -1067,8 +1068,8 @@ int cxgbe_set_filter(struct rte_eth_dev *dev, unsigned int filter_id,
* to hardware.
*/
if (iconf & F_VNIC) {
- f->fs.val.ovlan = fs->val.pf << 13;
- f->fs.mask.ovlan = fs->mask.pf << 13;
+ f->fs.val.ovlan = fs->val.pf << 13 | fs->val.vf;
+ f->fs.mask.ovlan = fs->mask.pf << 13 | fs->mask.vf;
f->fs.val.ovlan_vld = fs->val.pfvf_vld;
f->fs.mask.ovlan_vld = fs->mask.pfvf_vld;
}
@@ -19,7 +19,7 @@
#define PROTO_BITWIDTH 8
#define TOS_BITWIDTH 8
#define PF_BITWIDTH 3
-#define VF_BITWIDTH 8
+#define VF_BITWIDTH 13
#define IVLAN_BITWIDTH 16
#define OVLAN_BITWIDTH 16
@@ -159,9 +159,9 @@ cxgbe_fill_filter_region(struct adapter *adap,
ntuple_mask |= (u64)(fs->val.ovlan_vld << 16 |
fs->mask.ovlan) << tp->vnic_shift;
else if (fs->mask.pfvf_vld)
- ntuple_mask |= (u64)((fs->mask.pfvf_vld << 16) |
- (fs->mask.pf << 13)) <<
- tp->vnic_shift;
+ ntuple_mask |= (u64)(fs->mask.pfvf_vld << 16 |
+ fs->mask.pf << 13 |
+ fs->mask.vf) << tp->vnic_shift;
}
if (tp->tos_shift >= 0)
ntuple_mask |= (u64)fs->mask.tos << tp->tos_shift;
@@ -316,6 +316,34 @@ ch_rte_parsetype_pf(const void *dmask __rte_unused,
return 0;
}
+static int
+ch_rte_parsetype_vf(const void *dmask, const struct rte_flow_item *item,
+ struct ch_filter_specification *fs,
+ struct rte_flow_error *e)
+{
+ const struct rte_flow_item_vf *umask = item->mask;
+ const struct rte_flow_item_vf *val = item->spec;
+ const struct rte_flow_item_vf *mask;
+
+ /* If user has not given any mask, then use chelsio supported mask. */
+ mask = umask ? umask : (const struct rte_flow_item_vf *)dmask;
+
+ CXGBE_FILL_FS(1, 1, pfvf_vld);
+
+ if (!val)
+ return 0; /* Wildcard, match all Vf */
+
+ if (val->id > UCHAR_MAX)
+ return rte_flow_error_set(e, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "VF ID > MAX(255)");
+
+ CXGBE_FILL_FS(val->id, mask->id, vf);
+
+ return 0;
+}
+
static int
ch_rte_parsetype_udp(const void *dmask, const struct rte_flow_item *item,
struct ch_filter_specification *fs,
@@ -948,6 +976,13 @@ static struct chrte_fparse parseitem[] = {
.fptr = ch_rte_parsetype_pf,
.dmask = NULL,
},
+
+ [RTE_FLOW_ITEM_TYPE_VF] = {
+ .fptr = ch_rte_parsetype_vf,
+ .dmask = &(const struct rte_flow_item_vf){
+ .id = 0xffffffff,
+ }
+ },
};
static int
@@ -1207,6 +1207,15 @@ static int adap_init0(struct adapter *adap)
adap->params.filter2_wr_support = (ret == 0 && val[0] != 0);
}
+ /* Check if FW supports returning vin.
+ * If this is not supported, driver will interpret
+ * these values from viid.
+ */
+ params[0] = CXGBE_FW_PARAM_DEV(OPAQUE_VIID_SMT_EXTN);
+ ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 1, params, val);
+ adap->params.viid_smt_extn_support = (ret == 0 && val[0] != 0);
+
/* query tid-related parameters */
params[0] = CXGBE_FW_PARAM_DEV(NTID);
ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,