X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fbase%2Fice_flow.c;h=d9192252742874f2804a823bcb6f5371b7872da1;hb=b2ad03452a0e5f0083d59b4da24e5bc32fe472c5;hp=0f52b3379e7bae672847f636d23e3a2f69f32d06;hpb=d1c2f76b440a7468878d246332d9a6ebda5deb43;p=dpdk.git diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c index 0f52b3379e..d919225274 100644 --- a/drivers/net/ice/base/ice_flow.c +++ b/drivers/net/ice/base/ice_flow.c @@ -143,7 +143,7 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = { static const u32 ice_ptypes_mac_ofos[] = { 0xFDC00CC6, 0xBFBF7F7E, 0xF7EFDFDF, 0xFEFDFDFB, 0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000, - 0x000B0F0F, 0x00000000, 0x00000000, 0x00000000, + 0x000B0F0F, 0x00003000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -167,7 +167,7 @@ static const u32 ice_ptypes_macvlan_il[] = { static const u32 ice_ptypes_ipv4_ofos[] = { 0xFDC00000, 0xBFBF7F7E, 0x00EFDFDF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0003000F, 0x00000000, 0x00000000, 0x00000000, + 0x0003000F, 0x000FC000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -179,7 +179,7 @@ static const u32 ice_ptypes_ipv4_ofos[] = { static const u32 ice_ptypes_ipv4_il[] = { 0xE0000000, 0xB807700E, 0x8001DC03, 0xE01DC03B, 0x0007700E, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x000FF800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -191,7 +191,7 @@ static const u32 ice_ptypes_ipv4_il[] = { static const u32 ice_ptypes_ipv6_ofos[] = { 0x00000000, 0x00000000, 0xF7000000, 0xFEFDFDFB, 0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000, - 0x00080F00, 0x00000000, 0x00000000, 0x00000000, + 0x00080F00, 0x03F00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -203,7 +203,7 @@ static const u32 ice_ptypes_ipv6_ofos[] = { static const u32 ice_ptypes_ipv6_il[] = { 0x00000000, 0x03B80770, 0x00EE01DC, 0x0EE00000, 0x03B80770, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x7FE00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -229,7 +229,7 @@ static const u32 ice_ptypes_arp_of[] = { static const u32 ice_ptypes_udp_il[] = { 0x81000000, 0x20204040, 0x04081010, 0x80810102, 0x00204040, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00410000, 0x10842000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -241,7 +241,7 @@ static const u32 ice_ptypes_udp_il[] = { static const u32 ice_ptypes_tcp_il[] = { 0x04000000, 0x80810102, 0x10204040, 0x42040408, 0x00810102, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00820000, 0x21084000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -253,7 +253,7 @@ static const u32 ice_ptypes_tcp_il[] = { static const u32 ice_ptypes_sctp_il[] = { 0x08000000, 0x01020204, 0x20408081, 0x04080810, 0x01020204, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x01040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -277,7 +277,7 @@ static const u32 ice_ptypes_icmp_of[] = { static const u32 ice_ptypes_icmp_il[] = { 0x00000000, 0x02040408, 0x40810102, 0x08101020, 0x02040408, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x42108000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -345,6 +345,18 @@ static const u32 ice_ptypes_gtpu[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; +/* Packet types for pppoe */ +static const u32 ice_ptypes_pppoe[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x03FFF000, 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; @@ -360,25 +372,18 @@ struct ice_flow_prof_params { ice_declare_bitmap(ptypes, ICE_FLOW_PTYPE_MAX); }; -/** - * ice_is_pow2 - check if integer value is a power of 2 - * @val: unsigned integer to be validated - */ -static bool ice_is_pow2(u64 val) -{ - return (val && !(val & (val - 1))); -} +#define ICE_FLOW_RSS_HDRS_INNER_MASK \ + (ICE_FLOW_SEG_HDR_PPPOE | ICE_FLOW_SEG_HDR_GTPC | \ + ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU) #define ICE_FLOW_SEG_HDRS_L2_MASK \ (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) #define ICE_FLOW_SEG_HDRS_L3_MASK \ (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | \ - ICE_FLOW_SEG_HDR_ARP | ICE_FLOW_SEG_HDR_PPPOE) + ICE_FLOW_SEG_HDR_ARP) #define ICE_FLOW_SEG_HDRS_L4_MASK \ (ICE_FLOW_SEG_HDR_ICMP | ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \ - ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_GTPC | \ - ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU_IP | \ - ICE_FLOW_SEG_HDR_GTPU_UP | ICE_FLOW_SEG_HDR_GTPU_DWN) + ICE_FLOW_SEG_HDR_SCTP) /** * ice_flow_val_hdrs - validates packet segments for valid protocol headers @@ -388,16 +393,9 @@ static bool ice_is_pow2(u64 val) static enum ice_status ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt) { - const u32 masks = (ICE_FLOW_SEG_HDRS_L2_MASK | - ICE_FLOW_SEG_HDRS_L3_MASK | - ICE_FLOW_SEG_HDRS_L4_MASK); u8 i; for (i = 0; i < segs_cnt; i++) { - /* No header specified */ - if (!(segs[i].hdrs & masks) || (segs[i].hdrs & ~masks)) - return ICE_ERR_PARAM; - /* Multiple L3 headers */ if (segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK && !ice_is_pow2(segs[i].hdrs & ICE_FLOW_SEG_HDRS_L3_MASK)) @@ -503,6 +501,12 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) ICE_FLOW_PTYPE_MAX); } + if (hdrs & ICE_FLOW_SEG_HDR_PPPOE) { + src = (const ice_bitmap_t *)ice_ptypes_pppoe; + ice_and_bitmap(params->ptypes, params->ptypes, src, + ICE_FLOW_PTYPE_MAX); + } + if (hdrs & ICE_FLOW_SEG_HDR_IPV4) { src = !i ? (const ice_bitmap_t *)ice_ptypes_ipv4_ofos : (const ice_bitmap_t *)ice_ptypes_ipv4_il; @@ -566,7 +570,7 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) * ice_flow_xtract_pkt_flags - Create an extr sequence entry for packet flags * @hw: pointer to the HW struct * @params: information about the flow to be processed - * @flags: The value of pkt_flags[x:x] in RX/TX MDID metadata. + * @flags: The value of pkt_flags[x:x] in Rx/Tx MDID metadata. * * This function will allocate an extraction sequence entries for a DWORD size * chunk of the packet flags. @@ -679,7 +683,7 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params, break; case ICE_FLOW_FIELD_IDX_UDP_SRC_PORT: case ICE_FLOW_FIELD_IDX_UDP_DST_PORT: - prot_id = seg == 0 ? ICE_PROT_UDP_IL_OR_S : ICE_PROT_UDP_OF; + prot_id = ICE_PROT_UDP_IL_OR_S; break; case ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT: case ICE_FLOW_FIELD_IDX_SCTP_DST_PORT: @@ -865,9 +869,12 @@ ice_flow_create_xtrct_seq(struct ice_hw *hw, /* For ACL, we also need to extract the direction bit (Rx,Tx) data from * packet flags */ - if (params->blk == ICE_BLK_ACL) - ice_flow_xtract_pkt_flags(hw, params, - ICE_RX_MDID_PKT_FLAGS_15_0); + if (params->blk == ICE_BLK_ACL) { + status = ice_flow_xtract_pkt_flags(hw, params, + ICE_RX_MDID_PKT_FLAGS_15_0); + if (status) + return status; + } for (i = 0; i < params->prof->segs_cnt; i++) { u64 match = params->prof->segs[i].match; @@ -949,8 +956,9 @@ ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, struct ice_flow_seg_info *segs, u8 segs_cnt, u16 vsi_handle, u32 conds) { - struct ice_flow_prof *p; + struct ice_flow_prof *p, *prof = NULL; + ice_acquire_lock(&hw->fl_profs_locks[blk]); LIST_FOR_EACH_ENTRY(p, &hw->fl_profs[blk], ice_flow_prof, l_entry) { if ((p->dir == dir || conds & ICE_FLOW_FIND_PROF_NOT_CHK_DIR) && segs_cnt && segs_cnt == p->segs_cnt) { @@ -972,12 +980,15 @@ ice_flow_find_prof_conds(struct ice_hw *hw, enum ice_block blk, break; /* A match is found if all segments are matched */ - if (i == segs_cnt) - return p; + if (i == segs_cnt) { + prof = p; + break; + } } } + ice_release_lock(&hw->fl_profs_locks[blk]); - return NULL; + return prof; } /** @@ -994,10 +1005,8 @@ ice_flow_find_prof(struct ice_hw *hw, enum ice_block blk, enum ice_flow_dir dir, { struct ice_flow_prof *p; - ice_acquire_lock(&hw->fl_profs_locks[blk]); p = ice_flow_find_prof_conds(hw, blk, dir, segs, segs_cnt, ICE_MAX_VSI, ICE_FLOW_FIND_PROF_CHK_FLDS); - ice_release_lock(&hw->fl_profs_locks[blk]); return p ? p->id : ICE_FLOW_PROF_ID_INVAL; } @@ -1497,9 +1506,12 @@ ice_flow_add_entry(struct ice_hw *hw, enum ice_block blk, u64 prof_id, goto out; } - ice_acquire_lock(&prof->entries_lock); - LIST_ADD(&e->l_entry, &prof->entries); - ice_release_lock(&prof->entries_lock); + if (blk != ICE_BLK_ACL) { + /* ACL will handle the entry management */ + ice_acquire_lock(&prof->entries_lock); + LIST_ADD(&e->l_entry, &prof->entries); + ice_release_lock(&prof->entries_lock); + } *entry_h = ICE_FLOW_ENTRY_HNDL(e); @@ -1676,16 +1688,19 @@ ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len, seg->raws_cnt++; } +#define ICE_FLOW_RSS_SEG_HDR_L2_MASKS \ +(ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) + #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \ - (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_PPPOE) + (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6) #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \ (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | \ - ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_GTPC_TEID) - + ICE_FLOW_SEG_HDR_SCTP) #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ - (ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ + (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \ + ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ ICE_FLOW_RSS_SEG_HDR_L4_MASKS) /** @@ -1718,11 +1733,12 @@ ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields, } ICE_FLOW_SET_HDRS(segs, flow_hdr); - if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS) + if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS & + ~ICE_FLOW_RSS_HDRS_INNER_MASK) return ICE_ERR_PARAM; val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS); - if (!ice_is_pow2(val)) + if (val && !ice_is_pow2(val)) return ICE_ERR_CFG; val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS); @@ -1870,11 +1886,22 @@ ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) #define ICE_FLOW_PROF_HASH_S 0 #define ICE_FLOW_PROF_HASH_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HASH_S) #define ICE_FLOW_PROF_HDR_S 32 -#define ICE_FLOW_PROF_HDR_M (0xFFFFFFFFULL << ICE_FLOW_PROF_HDR_S) +#define ICE_FLOW_PROF_HDR_M (0x3FFFFFFFULL << ICE_FLOW_PROF_HDR_S) +#define ICE_FLOW_PROF_ENCAP_S 63 +#define ICE_FLOW_PROF_ENCAP_M (BIT_ULL(ICE_FLOW_PROF_ENCAP_S)) + +#define ICE_RSS_OUTER_HEADERS 1 +#define ICE_RSS_INNER_HEADERS 2 -#define ICE_FLOW_GEN_PROFID(hash, hdr) \ +/* Flow profile ID format: + * [0:31] - Packet match fields + * [32:62] - Protocol header + * [63] - Encapsulation flag, 0 if non-tunneled, 1 if tunneled + */ +#define ICE_FLOW_GEN_PROFID(hash, hdr, segs_cnt) \ (u64)(((u64)(hash) & ICE_FLOW_PROF_HASH_M) | \ - (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M)) + (((u64)(hdr) << ICE_FLOW_PROF_HDR_S) & ICE_FLOW_PROF_HDR_M) | \ + ((u8)((segs_cnt) - 1) ? ICE_FLOW_PROF_ENCAP_M : 0)) /** * ice_add_rss_cfg_sync - add an RSS configuration @@ -1882,24 +1909,30 @@ ice_add_rss_list(struct ice_hw *hw, u16 vsi_handle, struct ice_flow_prof *prof) * @vsi_handle: software VSI handle * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure * @addl_hdrs: protocol header fields + * @segs_cnt: packet segment count * * Assumption: lock has already been acquired for RSS list */ static enum ice_status ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, - u32 addl_hdrs) + u32 addl_hdrs, u8 segs_cnt) { const enum ice_block blk = ICE_BLK_RSS; struct ice_flow_prof *prof = NULL; struct ice_flow_seg_info *segs; enum ice_status status = ICE_SUCCESS; - segs = (struct ice_flow_seg_info *)ice_malloc(hw, sizeof(*segs)); + if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX) + return ICE_ERR_PARAM; + + segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt, + sizeof(*segs)); if (!segs) return ICE_ERR_NO_MEMORY; /* Construct the packet segment info from the hashed fields */ - status = ice_flow_set_rss_seg_info(segs, hashed_flds, addl_hdrs); + status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds, + addl_hdrs); if (status) goto exit; @@ -1907,7 +1940,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, * and has the input VSI associated to it. If found, no further * operations required and exit. */ - prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, 1, + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, vsi_handle, ICE_FLOW_FIND_PROF_CHK_FLDS | ICE_FLOW_FIND_PROF_CHK_VSI); @@ -1919,7 +1952,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, * this profile. The VSI will be added to a new profile created with * the protocol header and new hash field configuration. */ - prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, 1, + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, vsi_handle, ICE_FLOW_FIND_PROF_CHK_VSI); if (prof) { status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); @@ -1930,7 +1963,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, /* Remove profile if it has no VSIs associated */ if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) { - status = ice_flow_rem_prof_sync(hw, blk, prof); + status = ice_flow_rem_prof(hw, blk, prof->id); if (status) goto exit; } @@ -1939,7 +1972,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, /* Search for a profile that has same match fields only. If this * exists then associate the VSI to this profile. */ - prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, 1, + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, vsi_handle, ICE_FLOW_FIND_PROF_CHK_FLDS); if (prof) { @@ -1953,8 +1986,10 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, * segment information. */ status = ice_flow_add_prof(hw, blk, ICE_FLOW_RX, - ICE_FLOW_GEN_PROFID(hashed_flds, segs->hdrs), - segs, 1, NULL, 0, &prof); + ICE_FLOW_GEN_PROFID(hashed_flds, + segs[segs_cnt - 1].hdrs, + segs_cnt), + segs, segs_cnt, NULL, 0, &prof); if (status) goto exit; @@ -1963,7 +1998,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, * be removed. */ if (status) { - ice_flow_rem_prof_sync(hw, blk, prof); + ice_flow_rem_prof(hw, blk, prof->id); goto exit; } @@ -1996,7 +2031,11 @@ ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, return ICE_ERR_PARAM; ice_acquire_lock(&hw->rss_locks); - status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs); + status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs, + ICE_RSS_OUTER_HEADERS); + if (!status) + status = ice_add_rss_cfg_sync(hw, vsi_handle, hashed_flds, + addl_hdrs, ICE_RSS_INNER_HEADERS); ice_release_lock(&hw->rss_locks); return status; @@ -2008,12 +2047,13 @@ ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, * @vsi_handle: software VSI handle * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove * @addl_hdrs: Protocol header fields within a packet segment + * @segs_cnt: packet segment count * * Assumption: lock has already been acquired for RSS list */ static enum ice_status ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, - u32 addl_hdrs) + u32 addl_hdrs, u8 segs_cnt) { const enum ice_block blk = ICE_BLK_RSS; struct ice_flow_seg_info *segs; @@ -2029,7 +2069,7 @@ ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, if (status) goto out; - prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, 1, + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, vsi_handle, ICE_FLOW_FIND_PROF_CHK_FLDS); if (!prof) { @@ -2047,141 +2087,13 @@ ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, ice_rem_rss_list(hw, vsi_handle, prof); if (!ice_is_any_bit_set(prof->vsis, ICE_MAX_VSI)) - status = ice_flow_rem_prof_sync(hw, blk, prof); + status = ice_flow_rem_prof(hw, blk, prof->id); out: ice_free(hw, segs); return status; } -/* Mapping of AVF hash bit fields to an L3-L4 hash combination. - * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash, - * convert its values to their appropriate flow L3, L4 values. - */ -#define ICE_FLOW_AVF_RSS_IPV4_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_OTHER) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV4)) -#define ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP_SYN_NO_ACK) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_TCP)) -#define ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV4_UDP) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV4_UDP) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_UDP)) -#define ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS \ - (ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS | \ - ICE_FLOW_AVF_RSS_IPV4_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) - -#define ICE_FLOW_AVF_RSS_IPV6_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_OTHER) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_FRAG_IPV6)) -#define ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_UNICAST_IPV6_UDP) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_MULTICAST_IPV6_UDP) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_UDP)) -#define ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS \ - (BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP_SYN_NO_ACK) | \ - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_TCP)) -#define ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS \ - (ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS | ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS | \ - ICE_FLOW_AVF_RSS_IPV6_MASKS | BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) - -#define ICE_FLOW_MAX_CFG 10 - -/** - * ice_add_avf_rss_cfg - add an RSS configuration for AVF driver - * @hw: pointer to the hardware structure - * @vsi_handle: software VSI handle - * @avf_hash: hash bit fields (ICE_AVF_FLOW_FIELD_*) to configure - * - * This function will take the hash bitmap provided by the AVF driver via a - * message, convert it to ICE-compatible values, and configure RSS flow - * profiles. - */ -enum ice_status -ice_add_avf_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 avf_hash) -{ - enum ice_status status = ICE_SUCCESS; - u64 hash_flds; - - if (avf_hash == ICE_AVF_FLOW_FIELD_INVALID || - !ice_is_vsi_valid(hw, vsi_handle)) - return ICE_ERR_PARAM; - - /* Make sure no unsupported bits are specified */ - if (avf_hash & ~(ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS | - ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS)) - return ICE_ERR_CFG; - - hash_flds = avf_hash; - - /* Always create an L3 RSS configuration for any L4 RSS configuration */ - if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) - hash_flds |= ICE_FLOW_AVF_RSS_IPV4_MASKS; - - if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) - hash_flds |= ICE_FLOW_AVF_RSS_IPV6_MASKS; - - /* Create the corresponding RSS configuration for each valid hash bit */ - while (hash_flds) { - u64 rss_hash = ICE_HASH_INVALID; - - if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV4_MASKS) { - if (hash_flds & ICE_FLOW_AVF_RSS_IPV4_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV4; - hash_flds &= ~ICE_FLOW_AVF_RSS_IPV4_MASKS; - } else if (hash_flds & - ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV4 | - ICE_FLOW_HASH_TCP_PORT; - hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV4_MASKS; - } else if (hash_flds & - ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV4 | - ICE_FLOW_HASH_UDP_PORT; - hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV4_MASKS; - } else if (hash_flds & - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP)) { - rss_hash = ICE_FLOW_HASH_IPV4 | - ICE_FLOW_HASH_SCTP_PORT; - hash_flds &= - ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV4_SCTP); - } - } else if (hash_flds & ICE_FLOW_AVF_RSS_ALL_IPV6_MASKS) { - if (hash_flds & ICE_FLOW_AVF_RSS_IPV6_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV6; - hash_flds &= ~ICE_FLOW_AVF_RSS_IPV6_MASKS; - } else if (hash_flds & - ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV6 | - ICE_FLOW_HASH_TCP_PORT; - hash_flds &= ~ICE_FLOW_AVF_RSS_TCP_IPV6_MASKS; - } else if (hash_flds & - ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS) { - rss_hash = ICE_FLOW_HASH_IPV6 | - ICE_FLOW_HASH_UDP_PORT; - hash_flds &= ~ICE_FLOW_AVF_RSS_UDP_IPV6_MASKS; - } else if (hash_flds & - BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP)) { - rss_hash = ICE_FLOW_HASH_IPV6 | - ICE_FLOW_HASH_SCTP_PORT; - hash_flds &= - ~BIT_ULL(ICE_AVF_FLOW_FIELD_IPV6_SCTP); - } - } - - if (rss_hash == ICE_HASH_INVALID) - return ICE_ERR_OUT_OF_RANGE; - - status = ice_add_rss_cfg(hw, vsi_handle, rss_hash, - ICE_FLOW_SEG_HDR_NONE); - if (status) - break; - } - - return status; -} - /** * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields * @hw: pointer to the hardware structure @@ -2206,7 +2118,11 @@ ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, return ICE_ERR_PARAM; ice_acquire_lock(&hw->rss_locks); - status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs); + status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs, + ICE_RSS_OUTER_HEADERS); + if (!status) + status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, + addl_hdrs, ICE_RSS_INNER_HEADERS); ice_release_lock(&hw->rss_locks); return status; @@ -2231,7 +2147,14 @@ enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) if (ice_is_bit_set(r->vsis, vsi_handle)) { status = ice_add_rss_cfg_sync(hw, vsi_handle, r->hashed_flds, - r->packet_hdr); + r->packet_hdr, + ICE_RSS_OUTER_HEADERS); + if (status) + break; + status = ice_add_rss_cfg_sync(hw, vsi_handle, + r->hashed_flds, + r->packet_hdr, + ICE_RSS_INNER_HEADERS); if (status) break; }