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