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...@intel.com>
Signed-off-by: Jeff Guo <jia....@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 --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,
-- 
2.20.1

Reply via email to