X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fbase%2Fice_flow.c;h=1f621ca8816ebbcd914d677295a1b3375ffd9393;hb=3fbba579a2b9ee43e6692ea372da3a7848b174ab;hp=667c07743133bc53237cf19096c326d4a27dda71;hpb=8c98e3c539625b6dbdf8acb1817b55eae101e537;p=dpdk.git diff --git a/drivers/net/ice/base/ice_flow.c b/drivers/net/ice/base/ice_flow.c index 667c077431..1f621ca881 100644 --- a/drivers/net/ice/base/ice_flow.c +++ b/drivers/net/ice/base/ice_flow.c @@ -224,7 +224,7 @@ static const u32 ice_ptypes_macvlan_il[] = { static const u32 ice_ptypes_ipv4_ofos[] = { 0x1DC00000, 0x04000800, 0x00000000, 0x00000000, 0x00000000, 0x00000155, 0x00000000, 0x00000000, - 0x00000000, 0x000FC000, 0x00000000, 0x00000000, + 0x00000000, 0x000FC000, 0x000002A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -238,7 +238,7 @@ static const u32 ice_ptypes_ipv4_ofos[] = { static const u32 ice_ptypes_ipv4_ofos_all[] = { 0x1DC00000, 0x04000800, 0x00000000, 0x00000000, 0x00000000, 0x00000155, 0x00000000, 0x00000000, - 0x00000000, 0x000FC000, 0x83E0F800, 0x00000101, + 0x00000000, 0x000FC000, 0x83E0FAA0, 0x00000101, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -264,7 +264,7 @@ static const u32 ice_ptypes_ipv4_il[] = { static const u32 ice_ptypes_ipv6_ofos[] = { 0x00000000, 0x00000000, 0x77000000, 0x10002000, 0x00000000, 0x000002AA, 0x00000000, 0x00000000, - 0x00000000, 0x03F00000, 0x00000000, 0x00000000, + 0x00000000, 0x03F00000, 0x00000540, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -278,7 +278,7 @@ static const u32 ice_ptypes_ipv6_ofos[] = { static const u32 ice_ptypes_ipv6_ofos_all[] = { 0x00000000, 0x00000000, 0x77000000, 0x10002000, 0x00000000, 0x000002AA, 0x00000000, 0x00000000, - 0x00080F00, 0x03F00000, 0x7C1F0000, 0x00000206, + 0x00000000, 0x03F00000, 0x7C1F0540, 0x00000206, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -302,7 +302,7 @@ static const u32 ice_ptypes_ipv6_il[] = { static const u32 ice_ipv4_ofos_no_l4[] = { 0x10C00000, 0x04000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x000cc000, 0x00000000, 0x00000000, + 0x00000000, 0x000cc000, 0x000002A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -326,7 +326,7 @@ static const u32 ice_ipv4_il_no_l4[] = { static const u32 ice_ipv6_ofos_no_l4[] = { 0x00000000, 0x00000000, 0x43000000, 0x10002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x02300000, 0x00000000, 0x00000000, + 0x00000000, 0x02300000, 0x00000540, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -448,7 +448,7 @@ static const u32 ice_ptypes_mac_il[] = { static const u32 ice_ptypes_gtpc[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000180, 0x00000000, + 0x00000000, 0x00000000, 0x000001E0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -469,6 +469,29 @@ static const u32 ice_ptypes_gtpc_tid[] = { }; /* Packet types for GTPU */ +static const struct ice_ptype_attributes ice_attr_gtpu_session[] = { + { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV4_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV4_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV4_ICMP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV4_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV6_FRAG, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV6_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV6_UDP_PAY, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV6_TCP, ICE_PTYPE_ATTR_GTP_SESSION }, + { ICE_MAC_IPV6_GTPU_IPV6_ICMPV6, ICE_PTYPE_ATTR_GTP_SESSION }, +}; + static const struct ice_ptype_attributes ice_attr_gtpu_eh[] = { { ICE_MAC_IPV4_GTPU_IPV4_FRAG, ICE_PTYPE_ATTR_GTP_PDU_EH }, { ICE_MAC_IPV4_GTPU_IPV4_PAY, ICE_PTYPE_ATTR_GTP_PDU_EH }, @@ -553,7 +576,7 @@ static const u32 ice_ptypes_gtpu[] = { static const u32 ice_ptypes_pppoe[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x03fff000, 0x00000000, 0x00000000, + 0x00000000, 0x03ffe000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -644,6 +667,17 @@ static const u32 ice_ptypes_mac_non_ip_ofos[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; +static const u32 ice_ptypes_gtpu_no_ip[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000600, 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; @@ -668,7 +702,7 @@ struct ice_flow_prof_params { ICE_FLOW_SEG_HDR_GTPC_TEID | ICE_FLOW_SEG_HDR_GTPU | \ ICE_FLOW_SEG_HDR_PFCP_SESSION | ICE_FLOW_SEG_HDR_L2TPV3 | \ ICE_FLOW_SEG_HDR_ESP | ICE_FLOW_SEG_HDR_AH | \ - ICE_FLOW_SEG_HDR_NAT_T_ESP) + ICE_FLOW_SEG_HDR_NAT_T_ESP | ICE_FLOW_SEG_HDR_GTPU_NON_IP) #define ICE_FLOW_SEG_HDRS_L2_MASK \ (ICE_FLOW_SEG_HDR_ETH | ICE_FLOW_SEG_HDR_VLAN) @@ -805,16 +839,16 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) } if ((hdrs & ICE_FLOW_SEG_HDR_IPV4) && (hdrs & ICE_FLOW_SEG_HDR_IPV_OTHER)) { - src = !i ? - (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all : - (const ice_bitmap_t *)ice_ptypes_ipv4_il; + src = i ? + (const ice_bitmap_t *)ice_ptypes_ipv4_il : + (const ice_bitmap_t *)ice_ptypes_ipv4_ofos_all; 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_OTHER)) { - src = !i ? - (const ice_bitmap_t *)ice_ptypes_ipv6_ofos_all : - (const ice_bitmap_t *)ice_ptypes_ipv6_il; + src = i ? + (const ice_bitmap_t *)ice_ptypes_ipv6_il : + (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) && @@ -888,6 +922,10 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) src = (const ice_bitmap_t *)ice_ptypes_gtpc_tid; ice_and_bitmap(params->ptypes, params->ptypes, src, ICE_FLOW_PTYPE_MAX); + } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_NON_IP) { + src = (const ice_bitmap_t *)ice_ptypes_gtpu_no_ip; + ice_and_bitmap(params->ptypes, params->ptypes, + src, ICE_FLOW_PTYPE_MAX); } else if (hdrs & ICE_FLOW_SEG_HDR_GTPU_DWN) { src = (const ice_bitmap_t *)ice_ptypes_gtpu; ice_and_bitmap(params->ptypes, params->ptypes, @@ -916,6 +954,10 @@ ice_flow_proc_seg_hdrs(struct ice_flow_prof_params *params) src = (const ice_bitmap_t *)ice_ptypes_gtpu; ice_and_bitmap(params->ptypes, params->ptypes, src, ICE_FLOW_PTYPE_MAX); + + /* Attributes for GTP packet without Extension Header */ + params->attr = ice_attr_gtpu_session; + params->attr_cnt = ARRAY_SIZE(ice_attr_gtpu_session); } else if (hdrs & ICE_FLOW_SEG_HDR_L2TPV3) { src = (const ice_bitmap_t *)ice_ptypes_l2tpv3; ice_and_bitmap(params->ptypes, params->ptypes, @@ -1212,7 +1254,7 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params, * ice_flow_xtract_raws - Create extract sequence entries for raw bytes * @hw: pointer to the HW struct * @params: information about the flow to be processed - * @seg: index of packet segment whose raw fields are to be be extracted + * @seg: index of packet segment whose raw fields are to be extracted */ static enum ice_status ice_flow_xtract_raws(struct ice_hw *hw, struct ice_flow_prof_params *params, @@ -1313,16 +1355,12 @@ ice_flow_create_xtrct_seq(struct ice_hw *hw, u64 match = params->prof->segs[i].match; enum ice_flow_field j; - for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) { - const u64 bit = BIT_ULL(j); - - if (match & bit) { - status = ice_flow_xtract_fld(hw, params, i, j, - match); - if (status) - return status; - match &= ~bit; - } + ice_for_each_set_bit(j, (ice_bitmap_t *)&match, + ICE_FLOW_FIELD_IDX_MAX) { + status = ice_flow_xtract_fld(hw, params, i, j, match); + if (status) + return status; + ice_clear_bit(j, (ice_bitmap_t *)&match); } /* Process raw matching bytes */ @@ -1379,17 +1417,12 @@ ice_flow_acl_def_entry_frmt(struct ice_flow_prof_params *params) for (i = 0; i < params->prof->segs_cnt; i++) { struct ice_flow_seg_info *seg = ¶ms->prof->segs[i]; - u64 match = seg->match; u8 j; - for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) { - struct ice_flow_fld_info *fld; - const u64 bit = BIT_ULL(j); - - if (!(match & bit)) - continue; + ice_for_each_set_bit(j, (ice_bitmap_t *)&seg->match, + ICE_FLOW_FIELD_IDX_MAX) { + struct ice_flow_fld_info *fld = &seg->fields[j]; - fld = &seg->fields[j]; fld->entry.mask = ICE_FLOW_FLD_OFF_INVAL; if (fld->type == ICE_FLOW_FLD_TYPE_RANGE) { @@ -1421,8 +1454,6 @@ ice_flow_acl_def_entry_frmt(struct ice_flow_prof_params *params) fld->entry.val = index; index += fld->entry.last; } - - match &= ~bit; } for (j = 0; j < seg->raws_cnt; j++) { @@ -1611,6 +1642,30 @@ ice_dealloc_flow_entry(struct ice_hw *hw, struct ice_flow_entry *entry) ice_free(hw, entry); } +/** + * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle + * @hw: pointer to the HW struct + * @blk: classification stage + * @prof_id: the profile ID handle + * @hw_prof_id: pointer to variable to receive the HW profile ID + */ +enum ice_status +ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id, + u8 *hw_prof_id) +{ + enum ice_status status = ICE_ERR_DOES_NOT_EXIST; + struct ice_prof_map *map; + + ice_acquire_lock(&hw->blk[blk].es.prof_map_lock); + map = ice_search_prof_id(hw, blk, prof_id); + if (map) { + *hw_prof_id = map->prof_id; + status = ICE_SUCCESS; + } + ice_release_lock(&hw->blk[blk].es.prof_map_lock); + return status; +} + #define ICE_ACL_INVALID_SCEN 0x3f /** @@ -1657,8 +1712,8 @@ ice_flow_acl_is_prof_in_use(struct ice_hw *hw, struct ice_flow_prof *prof, buf->pf_scenario_num[6] == ICE_ACL_INVALID_SCEN && buf->pf_scenario_num[7] == ICE_ACL_INVALID_SCEN) return ICE_SUCCESS; - else - return ICE_ERR_IN_USE; + + return ICE_ERR_IN_USE; } /** @@ -1725,7 +1780,7 @@ ice_flow_acl_disassoc_scen(struct ice_hw *hw, struct ice_flow_prof *prof) /* Clear scenario for this PF */ buf.pf_scenario_num[hw->pf_id] = ICE_ACL_INVALID_SCEN; - status = ice_prgm_acl_prof_extrt(hw, prof_id, &buf, NULL); + status = ice_prgm_acl_prof_xtrct(hw, prof_id, &buf, NULL); return status; } @@ -1788,77 +1843,83 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk, struct ice_flow_action *acts, u8 acts_cnt, struct ice_flow_prof **prof) { - struct ice_flow_prof_params params; + struct ice_flow_prof_params *params; enum ice_status status; u8 i; if (!prof || (acts_cnt && !acts)) return ICE_ERR_BAD_PTR; - ice_memset(¶ms, 0, sizeof(params), ICE_NONDMA_MEM); - params.prof = (struct ice_flow_prof *) - ice_malloc(hw, sizeof(*params.prof)); - if (!params.prof) + params = (struct ice_flow_prof_params *)ice_malloc(hw, sizeof(*params)); + if (!params) return ICE_ERR_NO_MEMORY; + params->prof = (struct ice_flow_prof *) + ice_malloc(hw, sizeof(*params->prof)); + if (!params->prof) { + status = ICE_ERR_NO_MEMORY; + goto free_params; + } + /* initialize extraction sequence to all invalid (0xff) */ for (i = 0; i < ICE_MAX_FV_WORDS; i++) { - params.es[i].prot_id = ICE_PROT_INVALID; - params.es[i].off = ICE_FV_OFFSET_INVAL; + params->es[i].prot_id = ICE_PROT_INVALID; + params->es[i].off = ICE_FV_OFFSET_INVAL; } - params.blk = blk; - params.prof->id = prof_id; - params.prof->dir = dir; - params.prof->segs_cnt = segs_cnt; + params->blk = blk; + params->prof->id = prof_id; + params->prof->dir = dir; + params->prof->segs_cnt = segs_cnt; /* Make a copy of the segments that need to be persistent in the flow * profile instance */ for (i = 0; i < segs_cnt; i++) - ice_memcpy(¶ms.prof->segs[i], &segs[i], sizeof(*segs), + ice_memcpy(¶ms->prof->segs[i], &segs[i], sizeof(*segs), ICE_NONDMA_TO_NONDMA); /* Make a copy of the actions that need to be persistent in the flow * profile instance. */ if (acts_cnt) { - params.prof->acts = (struct ice_flow_action *) + params->prof->acts = (struct ice_flow_action *) ice_memdup(hw, acts, acts_cnt * sizeof(*acts), ICE_NONDMA_TO_NONDMA); - if (!params.prof->acts) { + if (!params->prof->acts) { status = ICE_ERR_NO_MEMORY; goto out; } } - status = ice_flow_proc_segs(hw, ¶ms); + status = ice_flow_proc_segs(hw, params); if (status) { - ice_debug(hw, ICE_DBG_FLOW, - "Error processing a flow's packet segments\n"); + ice_debug(hw, ICE_DBG_FLOW, "Error processing a flow's packet segments\n"); goto out; } /* Add a HW profile for this flow profile */ - status = ice_add_prof(hw, blk, prof_id, (u8 *)params.ptypes, - params.attr, params.attr_cnt, params.es, - params.mask); + status = ice_add_prof(hw, blk, prof_id, (u8 *)params->ptypes, + params->attr, params->attr_cnt, params->es, + params->mask); if (status) { ice_debug(hw, ICE_DBG_FLOW, "Error adding a HW flow profile\n"); goto out; } - INIT_LIST_HEAD(¶ms.prof->entries); - ice_init_lock(¶ms.prof->entries_lock); - *prof = params.prof; + INIT_LIST_HEAD(¶ms->prof->entries); + ice_init_lock(¶ms->prof->entries_lock); + *prof = params->prof; out: if (status) { - if (params.prof->acts) - ice_free(hw, params.prof->acts); - ice_free(hw, params.prof); + if (params->prof->acts) + ice_free(hw, params->prof->acts); + ice_free(hw, params->prof); } +free_params: + ice_free(hw, params); return status; } @@ -1994,25 +2055,18 @@ ice_flow_acl_set_xtrct_seq(struct ice_hw *hw, struct ice_flow_prof *prof) for (i = 0; i < prof->segs_cnt; i++) { struct ice_flow_seg_info *seg = &prof->segs[i]; - u64 match = seg->match; u16 j; - for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) { - const u64 bit = BIT_ULL(j); - - if (!(match & bit)) - continue; - + ice_for_each_set_bit(j, (ice_bitmap_t *)&seg->match, + ICE_FLOW_FIELD_IDX_MAX) { info = &seg->fields[j]; if (info->type == ICE_FLOW_FLD_TYPE_RANGE) buf.word_selection[info->entry.val] = - info->xtrct.idx; + info->xtrct.idx; else ice_flow_acl_set_xtrct_seq_fld(&buf, info); - - match &= ~bit; } for (j = 0; j < seg->raws_cnt; j++) { @@ -2028,7 +2082,7 @@ ice_flow_acl_set_xtrct_seq(struct ice_hw *hw, struct ice_flow_prof *prof) /* Update the current PF */ buf.pf_scenario_num[hw->pf_id] = (u8)prof->cfg.scen->id; - status = ice_prgm_acl_prof_extrt(hw, prof_id, &buf, NULL); + status = ice_prgm_acl_prof_xtrct(hw, prof_id, &buf, NULL); return status; } @@ -2090,8 +2144,7 @@ ice_flow_assoc_prof(struct ice_hw *hw, enum ice_block blk, if (!status) ice_set_bit(vsi_handle, prof->vsis); else - ice_debug(hw, ICE_DBG_FLOW, - "HW profile add failed, %d\n", + ice_debug(hw, ICE_DBG_FLOW, "HW profile add failed, %d\n", status); } @@ -2122,8 +2175,7 @@ ice_flow_disassoc_prof(struct ice_hw *hw, enum ice_block blk, if (!status) ice_clear_bit(vsi_handle, prof->vsis); else - ice_debug(hw, ICE_DBG_FLOW, - "HW profile remove failed, %d\n", + ice_debug(hw, ICE_DBG_FLOW, "HW profile remove failed, %d\n", status); } @@ -2204,28 +2256,6 @@ out: return status; } -/** - * ice_flow_get_hw_prof - return the HW profile for a specific profile ID handle - * @hw: pointer to the HW struct - * @blk: classification stage - * @prof_id: the profile ID handle - * @hw_prof_id: pointer to variable to receive the HW profile ID - */ -enum ice_status -ice_flow_get_hw_prof(struct ice_hw *hw, enum ice_block blk, u64 prof_id, - u8 *hw_prof_id) -{ - struct ice_prof_map *map; - - map = ice_search_prof_id(hw, blk, prof_id); - if (map) { - *hw_prof_id = map->prof_id; - return ICE_SUCCESS; - } - - return ICE_ERR_DOES_NOT_EXIST; -} - /** * ice_flow_find_entry - look for a flow entry using its unique ID * @hw: pointer to the HW struct @@ -2480,7 +2510,6 @@ ice_flow_acl_frmt_entry(struct ice_hw *hw, struct ice_flow_prof *prof, e->acts = (struct ice_flow_action *) ice_memdup(hw, acts, acts_cnt * sizeof(*acts), ICE_NONDMA_TO_NONDMA); - if (!e->acts) goto out; @@ -2513,17 +2542,11 @@ ice_flow_acl_frmt_entry(struct ice_hw *hw, struct ice_flow_prof *prof, for (i = 0; i < prof->segs_cnt; i++) { struct ice_flow_seg_info *seg = &prof->segs[i]; - u64 match = seg->match; - u16 j; - - for (j = 0; j < ICE_FLOW_FIELD_IDX_MAX && match; j++) { - struct ice_flow_fld_info *info; - const u64 bit = BIT_ULL(j); - - if (!(match & bit)) - continue; + u8 j; - info = &seg->fields[j]; + ice_for_each_set_bit(j, (ice_bitmap_t *)&seg->match, + ICE_FLOW_FIELD_IDX_MAX) { + struct ice_flow_fld_info *info = &seg->fields[j]; if (info->type == ICE_FLOW_FLD_TYPE_RANGE) ice_flow_acl_frmt_entry_range(j, info, @@ -2532,8 +2555,6 @@ ice_flow_acl_frmt_entry(struct ice_hw *hw, struct ice_flow_prof *prof, else ice_flow_acl_frmt_entry_fld(j, info, buf, dontcare, data); - - match &= ~bit; } for (j = 0; j < seg->raws_cnt; j++) { @@ -2796,7 +2817,7 @@ ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof, if (!entry || !(*entry) || !prof) return ICE_ERR_BAD_PTR; - e = *(entry); + e = *entry; do_chg_rng_chk = false; if (e->range_buf) { @@ -2839,7 +2860,6 @@ ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof, */ exist = ice_flow_acl_find_scen_entry_cond(prof, e, &do_chg_action, &do_add_entry, &do_rem_entry); - if (do_rem_entry) { status = ice_flow_rem_entry_sync(hw, ICE_BLK_ACL, exist); if (status) @@ -2847,8 +2867,11 @@ ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof, } /* Prepare the result action buffer */ - acts = (struct ice_acl_act_entry *)ice_calloc - (hw, e->entry_sz, sizeof(struct ice_acl_act_entry)); + acts = (struct ice_acl_act_entry *) + ice_calloc(hw, e->entry_sz, sizeof(struct ice_acl_act_entry)); + if (!acts) + return ICE_ERR_NO_MEMORY; + for (i = 0; i < e->acts_cnt; i++) ice_memcpy(&acts[i], &e->acts[i].data.acl_act, sizeof(struct ice_acl_act_entry), @@ -2915,8 +2938,7 @@ ice_flow_acl_add_scen_entry_sync(struct ice_hw *hw, struct ice_flow_prof *prof, *(entry) = exist; } out: - if (acts) - ice_free(hw, acts); + ice_free(hw, acts); return status; } @@ -3083,7 +3105,7 @@ enum ice_status ice_flow_rem_entry(struct ice_hw *hw, enum ice_block blk, * * This helper function stores information of a field being matched, including * the type of the field and the locations of the value to match, the mask, and - * and the upper-bound value in the start of the input buffer for a flow entry. + * the upper-bound value in the start of the input buffer for a flow entry. * This function should only be used for fixed-size data structures. * * This function also opportunistically determines the protocol headers to be @@ -3213,8 +3235,7 @@ ice_flow_add_fld_raw(struct ice_flow_seg_info *seg, u16 off, u8 len, (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_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ (ICE_FLOW_RSS_SEG_HDR_L2_MASKS | \ @@ -3235,20 +3256,15 @@ static enum ice_status ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields, u32 flow_hdr) { - u64 val = hash_fields; + u64 val; u8 i; - for (i = 0; val && i < ICE_FLOW_FIELD_IDX_MAX; i++) { - u64 bit = BIT_ULL(i); + ice_for_each_set_bit(i, (ice_bitmap_t *)&hash_fields, + ICE_FLOW_FIELD_IDX_MAX) + ice_flow_set_fld(segs, (enum ice_flow_field)i, + ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, + ICE_FLOW_FLD_OFF_INVAL, false); - if (val & bit) { - ice_flow_set_fld(segs, (enum ice_flow_field)i, - ICE_FLOW_FLD_OFF_INVAL, - ICE_FLOW_FLD_OFF_INVAL, - ICE_FLOW_FLD_OFF_INVAL, false); - val &= ~bit; - } - } ICE_FLOW_SET_HDRS(segs, flow_hdr); if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS & @@ -3312,7 +3328,7 @@ enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle) if (LIST_EMPTY(&hw->fl_profs[blk])) return ICE_SUCCESS; - ice_acquire_lock(&hw->fl_profs_locks[blk]); + ice_acquire_lock(&hw->rss_locks); LIST_FOR_EACH_ENTRY_SAFE(p, t, &hw->fl_profs[blk], ice_flow_prof, l_entry) if (ice_is_bit_set(p->vsis, vsi_handle)) { @@ -3321,12 +3337,12 @@ enum ice_status ice_rem_vsi_rss_cfg(struct ice_hw *hw, u16 vsi_handle) break; if (!ice_is_any_bit_set(p->vsis, ICE_MAX_VSI)) { - status = ice_flow_rem_prof_sync(hw, blk, p); + status = ice_flow_rem_prof(hw, blk, p->id); if (status) break; } } - ice_release_lock(&hw->fl_profs_locks[blk]); + ice_release_lock(&hw->rss_locks); return status; } @@ -3456,9 +3472,13 @@ ice_rss_update_symm(struct ice_hw *hw, struct ice_prof_map *map; u8 prof_id, m; + ice_acquire_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); map = ice_search_prof_id(hw, ICE_BLK_RSS, prof->id); - prof_id = map->prof_id; - + if (map) + prof_id = map->prof_id; + ice_release_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock); + if (!map) + return; /* clear to default */ for (m = 0; m < 6; m++) wr32(hw, GLQF_HSYMM(prof_id, m), 0); @@ -3551,6 +3571,13 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, if (status) goto exit; + /* Don't do RSS for GTPU Outer */ + if (segs_cnt == ICE_RSS_OUTER_HEADERS && + segs[segs_cnt - 1].hdrs & ICE_FLOW_SEG_HDR_GTPU) { + status = ICE_SUCCESS; + goto exit; + } + /* Search for a flow profile that has matching headers, hash fields * and has the input VSI associated to it. If found, no further * operations required and exit. @@ -3706,6 +3733,13 @@ ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, if (status) goto out; + /* Don't do RSS for GTPU Outer */ + if (segs_cnt == ICE_RSS_OUTER_HEADERS && + segs[segs_cnt - 1].hdrs & ICE_FLOW_SEG_HDR_GTPU) { + status = ICE_SUCCESS; + goto out; + } + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, vsi_handle, ICE_FLOW_FIND_PROF_CHK_FLDS); @@ -3814,7 +3848,8 @@ enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) */ u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs) { - struct ice_rss_cfg *r, *rss_cfg = NULL; + u64 rss_hash = ICE_HASH_INVALID; + struct ice_rss_cfg *r; /* verify if the protocol header is non zero and VSI is valid */ if (hdrs == ICE_FLOW_SEG_HDR_NONE || !ice_is_vsi_valid(hw, vsi_handle)) @@ -3825,10 +3860,10 @@ u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs) ice_rss_cfg, l_entry) if (ice_is_bit_set(r->vsis, vsi_handle) && r->packet_hdr == hdrs) { - rss_cfg = r; + rss_hash = r->hashed_flds; break; } ice_release_lock(&hw->rss_locks); - return rss_cfg ? rss_cfg->hashed_flds : ICE_HASH_INVALID; + return rss_hash; }