diff mbox series

[4/9] net/cxgbe: add rte_flow support for matching all packets on VF

Message ID 56b36451dd4562b942c0d4cb0c173d32c42e0fc6.1583906144.git.kaara.satwik@chelsio.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers show
Series net/cxgbe: updates for rte_flow support | expand

Checks

Context Check Description
ci/Intel-compilation fail Compilation issues
ci/checkpatch success coding style OK

Commit Message

Rahul Lakkireddy March 11, 2020, 9:05 a.m. UTC
From: Karra Satwik <kaara.satwik@chelsio.com>

Add support to match all packets received on the underlying VF.

Use new firmware API to fetch the Virtual Interface Number (VIN)
allocated to each VF by the firmware. The VIN is required to
write filter rules to match all packets on VFs, whose identifier
is beyond max 7-bit value (i.e. 127) in VIID.

If firmware doesn't support fetching the VIN information, then
fallback to manually retrieving the VIN value from the 7-bit field
in the VIID, which only supports in range of 0..127. In this case,
packets belonging to VFs, whose identifier is beyond 127 can't be
matched.

Signed-off-by: Karra Satwik <kaara.satwik@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/base/adapter.h        |  6 ++++
 drivers/net/cxgbe/base/common.h         |  6 ++--
 drivers/net/cxgbe/base/t4_hw.c          | 27 +++++++++++++---
 drivers/net/cxgbe/base/t4fw_interface.h | 23 ++++++++++++++
 drivers/net/cxgbe/cxgbe_filter.c        |  9 +++---
 drivers/net/cxgbe/cxgbe_filter.h        |  2 +-
 drivers/net/cxgbe/cxgbe_flow.c          | 41 +++++++++++++++++++++++--
 drivers/net/cxgbe/cxgbe_main.c          |  9 ++++++
 8 files changed, 109 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index db654ad9c..c6b8036fd 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -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,
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 793cad11d..892aab64b 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -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);
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index cd4da0b9f..48b6d77b1 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -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;
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index e992d196d..39e02077f 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -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)
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 4c50932af..9c10520b2 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -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;
 	}
diff --git a/drivers/net/cxgbe/cxgbe_filter.h b/drivers/net/cxgbe/cxgbe_filter.h
index 2ac210045..6b1bf25e2 100644
--- a/drivers/net/cxgbe/cxgbe_filter.h
+++ b/drivers/net/cxgbe/cxgbe_filter.h
@@ -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
 
diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c
index c1f5ef045..3e27a3f68 100644
--- a/drivers/net/cxgbe/cxgbe_flow.c
+++ b/drivers/net/cxgbe/cxgbe_flow.c
@@ -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
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 0d0827c0e..a286d8557 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -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,