diff mbox series

[v3,1/3] net/ice/base: support IP fragment RSS and FDIR

Message ID 20210411065703.73596-2-jia.guo@intel.com (mailing list archive)
State Superseded
Delegated to: Qi Zhang
Headers show
Series [v3,1/3] net/ice/base: support IP fragment RSS and FDIR | expand

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Guo, Jia April 11, 2021, 6:57 a.m. UTC
Add support for IP fragment RSS hash and FDIR according to packet ID.
Separate IP fragment and IP other packet types.

Signed-off-by: Ting Xu <ting.xu@intel.com>
Signed-off-by: Jeff Guo <jia.guo@intel.com>
---
 drivers/net/ice/base/ice_fdir.c | 50 +++++++++++++++++++++++++++++++--
 drivers/net/ice/base/ice_fdir.h | 22 ++++++++++++---
 drivers/net/ice/base/ice_flow.c | 50 ++++++++++++++++++++++++++++++++-
 drivers/net/ice/base/ice_flow.h |  5 +++-
 drivers/net/ice/base/ice_type.h |  1 +
 5 files changed, 120 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ice/base/ice_fdir.c b/drivers/net/ice/base/ice_fdir.c
index 2b39c13127..0eb7cdd729 100644
--- a/drivers/net/ice/base/ice_fdir.c
+++ b/drivers/net/ice/base/ice_fdir.c
@@ -518,6 +518,24 @@  static const u8 ice_fdir_ipv4_udp_ecpri_tp0_pkt[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+static const u8 ice_fdir_ipv6_frag_pkt[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const u8 ice_fdir_ipv4_frag_pkt[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
+	0x00, 0x14, 0x00, 0x00, 0x20, 0x00, 0x40, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00
+};
 static const u8 ice_fdir_tcpv6_pkt[] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00,
@@ -716,6 +734,16 @@  static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
 		sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
 		sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
 	},
+	{
+		ICE_FLTR_PTYPE_FRAG_IPV4,
+		sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_frag_pkt,
+		sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_frag_pkt,
+	},
+	{
+		ICE_FLTR_PTYPE_FRAG_IPV6,
+		sizeof(ice_fdir_ipv6_frag_pkt), ice_fdir_ipv6_frag_pkt,
+		sizeof(ice_fdir_ipv6_frag_pkt), ice_fdir_ipv6_frag_pkt,
+	},
 	{
 		ICE_FLTR_PTYPE_NONF_IPV4_GTPU,
 		sizeof(ice_fdir_ipv4_gtpu4_pkt),
@@ -1505,7 +1533,7 @@  ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
 		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
 		if (frag)
-			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
+			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_MF;
 		break;
 	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
 		ice_pkt_insert_mac_addr(pkt, input->ext_data_outer.dst_mac);
@@ -1808,6 +1836,23 @@  ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
 				  input->ip.v6.proto);
 		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
 		break;
+	case ICE_FLTR_PTYPE_FRAG_IPV4:
+		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
+				   input->ip.v4.src_ip);
+		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
+				   input->ip.v4.dst_ip);
+		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
+		ice_pkt_insert_u16(loc, ICE_IPV4_ID_OFFSET,
+				   input->ip.v4.packet_id);
+		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
+		ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
+				  input->ip.v4.proto);
+		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
+		break;
+	case ICE_FLTR_PTYPE_FRAG_IPV6:
+		ice_pkt_insert_u32(loc, ICE_IPV6_ID_OFFSET,
+				   input->ip.v6.packet_id);
+		break;
 	default:
 		return ICE_ERR_PARAM;
 	}
@@ -1838,7 +1883,8 @@  ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag)
  */
 bool ice_fdir_has_frag(enum ice_fltr_ptype flow)
 {
-	if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER)
+	if (flow == ICE_FLTR_PTYPE_FRAG_IPV4 ||
+	    flow == ICE_FLTR_PTYPE_FRAG_IPV6)
 		return true;
 	else
 		return false;
diff --git a/drivers/net/ice/base/ice_fdir.h b/drivers/net/ice/base/ice_fdir.h
index 6573f96bc1..2acc1d6f1b 100644
--- a/drivers/net/ice/base/ice_fdir.h
+++ b/drivers/net/ice/base/ice_fdir.h
@@ -43,9 +43,11 @@ 
 #define ICE_MAC_ETHTYPE_OFFSET		12
 #define ICE_IPV4_TOS_OFFSET		15
 #define ICE_IPV4_TTL_OFFSET		22
+#define ICE_IPV4_ID_OFFSET		18
 #define ICE_IPV6_TC_OFFSET		14
 #define ICE_IPV6_HLIM_OFFSET		21
 #define ICE_IPV6_PROTO_OFFSET		20
+#define ICE_IPV6_ID_OFFSET		58
 /* For TUN inner (without inner MAC) */
 #define ICE_IPV4_NO_MAC_TOS_OFFSET	1
 #define ICE_IPV4_NO_MAC_TTL_OFFSET	8
@@ -83,12 +85,22 @@ 
 
 #define ICE_FDIR_MAX_FLTRS		16384
 
-/* IP v4 has 2 flag bits that enable fragment processing: DF and MF. DF
+/* IPv4 has 2 flag bits that enable fragment processing: DF and MF. DF
  * requests that the packet not be fragmented. MF indicates that a packet has
- * been fragmented.
+ * been fragmented, except that for the last fragment has a non-zero
+ * Fragment Offset field with zero MF.
  */
-#define ICE_FDIR_IPV4_PKT_FLAG_DF		0x20
-#define ICE_FDIR_IPV4_PKT_FLAG_MF		0x40
+#define ICE_FDIR_IPV4_PKT_FLAG_MF		0x20
+#define ICE_FDIR_IPV4_PKT_FLAG_MF_SHIFT	8
+#ifndef NO_UNUSED_PACKAGE_CODE
+#define ICE_FDIR_IPV4_PKT_FLAG_DF		0x40
+#endif /* NO_UNUSED_PACKAGE_CODE */
+
+/* For IPv6 fragmented packets, all fragments except the last have
+ * the MF flag set.
+ */
+#define ICE_FDIR_IPV6_PKT_FLAG_MF		0x100
+#define ICE_FDIR_IPV6_PKT_FLAG_MF_SHIFT	8
 
 enum ice_fltr_prgm_desc_dest {
 	ICE_FLTR_PRGM_DESC_DEST_DROP_PKT,
@@ -150,6 +162,7 @@  struct ice_fdir_v4 {
 	u8 ip_ver;
 	u8 proto;
 	u8 ttl;
+	__be16 packet_id;
 };
 
 #define ICE_IPV6_ADDR_LEN_AS_U32		4
@@ -164,6 +177,7 @@  struct ice_fdir_v6 {
 	u8 tc;
 	u8 proto;
 	u8 hlim;
+	__be32 packet_id;
 };
 
 struct ice_fdir_udp_gtp {
diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c
index c12ddfa247..9dea881914 100644
--- a/drivers/net/ice/base/ice_flow.c
+++ b/drivers/net/ice/base/ice_flow.c
@@ -13,6 +13,8 @@ 
 #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR	4
 #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR	6
 #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR	8
+#define ICE_FLOW_FLD_SZ_IPV4_ID		2
+#define ICE_FLOW_FLD_SZ_IPV6_ID		4
 #define ICE_FLOW_FLD_SZ_IP_DSCP		1
 #define ICE_FLOW_FLD_SZ_IP_TTL		1
 #define ICE_FLOW_FLD_SZ_IP_PROT		1
@@ -96,6 +98,12 @@  struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR),
 	/* ICE_FLOW_FIELD_IDX_IPV6_DA */
 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
+	/* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
+			  ICE_FLOW_FLD_SZ_IPV4_ID),
+	/* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
+	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
+			  ICE_FLOW_FLD_SZ_IPV6_ID),
 	/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
 	ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
 			  ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
@@ -725,6 +733,27 @@  static const u32 ice_ptypes_udp_ecpri_tp0[] = {
 	0x00000000, 0x00000000, 0x00000000, 0x00000000,
 };
 
+static const u32 ice_ptypes_ipv4_frag[] = {
+	0x00400000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 ice_ptypes_ipv6_frag[] = {
+	0x00000000, 0x00000000, 0x01000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
 /* Manage parameters and info. used during the creation of a flow profile */
 struct ice_flow_prof_params {
 	enum ice_block blk;
@@ -899,6 +928,16 @@  ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params)
 				(const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all;
 			ice_and_bitmap(params->ptypes, params->ptypes, src,
 				       ICE_FLOW_PTYPE_MAX);
+		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
+			   (hdrs & ICE_FLOW_SEG_HDR_IPV_FRAG)) {
+			src = (const ice_bitmap_t *)ice_ptypes_ipv4_frag;
+			ice_and_bitmap(params->ptypes, params->ptypes, src,
+				       ICE_FLOW_PTYPE_MAX);
+		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV6) &&
+			   (hdrs & ICE_FLOW_SEG_HDR_IPV_FRAG)) {
+			src = (const ice_bitmap_t *)ice_ptypes_ipv6_frag;
+			ice_and_bitmap(params->ptypes, params->ptypes, src,
+				       ICE_FLOW_PTYPE_MAX);
 		} else if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) &&
 			   !(hdrs & ICE_FLOW_SEG_HDRS_L4_MASK_NO_OTHER)) {
 			src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_no_l4 :
@@ -1177,6 +1216,9 @@  ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
 	case ICE_FLOW_FIELD_IDX_IPV4_DA:
 		prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
 		break;
+	case ICE_FLOW_FIELD_IDX_IPV4_ID:
+		prot_id = ICE_PROT_IPV4_OF_OR_S;
+		break;
 	case ICE_FLOW_FIELD_IDX_IPV6_SA:
 	case ICE_FLOW_FIELD_IDX_IPV6_DA:
 	case ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA:
@@ -1187,6 +1229,9 @@  ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
 	case ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA:
 		prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
 		break;
+	case ICE_FLOW_FIELD_IDX_IPV6_ID:
+		prot_id = ICE_PROT_IPV6_FRAG;
+		break;
 	case ICE_FLOW_FIELD_IDX_TCP_SRC_PORT:
 	case ICE_FLOW_FIELD_IDX_TCP_DST_PORT:
 	case ICE_FLOW_FIELD_IDX_TCP_FLAGS:
@@ -3341,13 +3386,16 @@  ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u8 seg_cnt,
 	/* set outer most header */
 	if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV4)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV4 |
+						   ICE_FLOW_SEG_HDR_IPV_FRAG |
 						   ICE_FLOW_SEG_HDR_IPV_OTHER;
 	else if (cfg->hdr_type == ICE_RSS_INNER_HEADERS_W_OUTER_IPV6)
 		segs[ICE_RSS_OUTER_HEADERS].hdrs |= ICE_FLOW_SEG_HDR_IPV6 |
+						   ICE_FLOW_SEG_HDR_IPV_FRAG |
 						   ICE_FLOW_SEG_HDR_IPV_OTHER;
 
 	if (seg->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS &
-	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER)
+	    ~ICE_FLOW_RSS_HDRS_INNER_MASK & ~ICE_FLOW_SEG_HDR_IPV_OTHER &
+	    ~ICE_FLOW_SEG_HDR_IPV_FRAG)
 		return ICE_ERR_PARAM;
 
 	val = (u64)(seg->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS);
diff --git a/drivers/net/ice/base/ice_flow.h b/drivers/net/ice/base/ice_flow.h
index af15ecb0ff..d905b95b1c 100644
--- a/drivers/net/ice/base/ice_flow.h
+++ b/drivers/net/ice/base/ice_flow.h
@@ -186,8 +186,9 @@  enum ice_flow_seg_hdr {
 	ICE_FLOW_SEG_HDR_ECPRI_TP0	= 0x04000000,
 	ICE_FLOW_SEG_HDR_UDP_ECPRI_TP0	= 0x08000000,
 	/* The following is an additive bit for ICE_FLOW_SEG_HDR_IPV4 and
-	 * ICE_FLOW_SEG_HDR_IPV6 which include the IPV4 other PTYPEs
+	 * ICE_FLOW_SEG_HDR_IPV6.
 	 */
+	ICE_FLOW_SEG_HDR_IPV_FRAG	= 0x10000000,
 	ICE_FLOW_SEG_HDR_IPV_OTHER	= 0x20000000,
 };
 
@@ -225,6 +226,8 @@  enum ice_flow_field {
 	ICE_FLOW_FIELD_IDX_IPV4_DA,
 	ICE_FLOW_FIELD_IDX_IPV6_SA,
 	ICE_FLOW_FIELD_IDX_IPV6_DA,
+	ICE_FLOW_FIELD_IDX_IPV4_ID,
+	ICE_FLOW_FIELD_IDX_IPV6_ID,
 	ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA,
 	ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA,
 	ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA,
diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h
index a6599363f9..5abe9dc9ea 100644
--- a/drivers/net/ice/base/ice_type.h
+++ b/drivers/net/ice/base/ice_type.h
@@ -349,6 +349,7 @@  enum ice_fltr_ptype {
 	ICE_FLTR_PTYPE_NONF_ECPRI_TP0,
 	ICE_FLTR_PTYPE_NONF_IPV4_UDP_ECPRI_TP0,
 	ICE_FLTR_PTYPE_FRAG_IPV4,
+	ICE_FLTR_PTYPE_FRAG_IPV6,
 	ICE_FLTR_PTYPE_NONF_IPV6_UDP,
 	ICE_FLTR_PTYPE_NONF_IPV6_TCP,
 	ICE_FLTR_PTYPE_NONF_IPV6_SCTP,