From 5ad10b85c2160160aa25e782e294f9411b0acb88 Mon Sep 17 00:00:00 2001 From: Qi Zhang Date: Mon, 30 Mar 2020 19:45:30 +0800 Subject: [PATCH] net/ice/base: allow profile based switch rules Switch rules usually match packet fields to take actions. Add capability to add a switch rule that does not match any packet fields, but instead matches the profile that the packet hits in the switch block. Signed-off-by: Dan Nowlin Signed-off-by: Wei Zhao Signed-off-by: Paul M Stillwell Jr Signed-off-by: Qi Zhang Acked-by: Qiming Yang --- drivers/net/ice/base/ice_protocol_type.h | 3 + drivers/net/ice/base/ice_switch.c | 86 ++++++++++++++++++++++-- drivers/net/ice/base/ice_switch.h | 5 ++ 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h index eda71722d1..a63ef0c96c 100644 --- a/drivers/net/ice/base/ice_protocol_type.h +++ b/drivers/net/ice/base/ice_protocol_type.h @@ -61,6 +61,9 @@ enum ice_sw_tunnel_type { */ ICE_SW_TUN_GTP, ICE_SW_TUN_PPPOE, + ICE_SW_TUN_PROFID_IPV6_ESP, + ICE_SW_TUN_PROFID_IPV6_AH, + ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3, ICE_ALL_TUNNELS /* All tunnel types including NVGRE */ }; diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index 103894f652..83fb40f7a2 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -5147,6 +5147,19 @@ ice_create_first_fit_recp_def(struct ice_hw *hw, *recp_cnt = 0; + if (!lkup_exts->n_val_words) { + struct ice_recp_grp_entry *entry; + + entry = (struct ice_recp_grp_entry *) + ice_malloc(hw, sizeof(*entry)); + if (!entry) + return ICE_ERR_NO_MEMORY; + LIST_ADD(&entry->l_entry, rg_list); + grp = &entry->r_group; + (*recp_cnt)++; + grp->n_val_pairs = 0; + } + /* Walk through every word in the rule to check if it is not done. If so * then this word needs to be part of a new recipe. */ @@ -5679,6 +5692,9 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, u8 *prot_ids; u16 i; + if (!lkups_cnt) + return ICE_SUCCESS; + prot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids)); if (!prot_ids) return ICE_ERR_NO_MEMORY; @@ -5736,6 +5752,8 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, { enum ice_prof_type prof_type; + ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES); + switch (rinfo->tun_type) { case ICE_NON_TUN: prof_type = ICE_PROF_NON_TUN; @@ -5756,6 +5774,15 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, case ICE_SW_TUN_PPPOE: prof_type = ICE_PROF_TUN_PPPOE; break; + case ICE_SW_TUN_PROFID_IPV6_ESP: + ice_set_bit(ICE_PROFID_IPV6_ESP, bm); + return; + case ICE_SW_TUN_PROFID_IPV6_AH: + ice_set_bit(ICE_PROFID_IPV6_AH, bm); + return; + case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3: + ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm); + return; case ICE_SW_TUN_AND_NON_TUN: default: prof_type = ICE_PROF_ALL; @@ -5765,6 +5792,27 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, ice_get_sw_fv_bitmap(hw, prof_type, bm); } +/** + * ice_is_prof_rule - determine if rule type is a profile rule + * @type: the rule type + * + * if the rule type is a profile rule, that means that there no field value + * match required, in this case just a profile hit is required. + */ +static bool ice_is_prof_rule(enum ice_sw_tunnel_type type) +{ + switch (type) { + case ICE_SW_TUN_PROFID_IPV6_ESP: + case ICE_SW_TUN_PROFID_IPV6_AH: + case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3: + return true; + default: + break; + } + + return false; +} + /** * ice_add_adv_recipe - Add an advanced recipe that is not part of the default * @hw: pointer to hardware structure @@ -5790,7 +5838,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, bool match_tun = false; u8 i; - if (!lkups_cnt) + if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt) return ICE_ERR_PARAM; lkup_exts = (struct ice_prot_lkup_ext *) @@ -5864,6 +5912,26 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, if (status) goto err_unroll; + /* An empty FV list means to use all the profiles returned in the + * profile bitmap + */ + if (LIST_EMPTY(&rm->fv_list)) { + u16 j; + + for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) + if (ice_is_bit_set(fv_bitmap, j)) { + struct ice_sw_fv_list_entry *fvl; + + fvl = (struct ice_sw_fv_list_entry *) + ice_malloc(hw, sizeof(*fvl)); + if (!fvl) + goto err_unroll; + fvl->fv_ptr = NULL; + fvl->profile_id = j; + LIST_ADD(&fvl->list_entry, &rm->fv_list); + } + } + /* get bitmap of all profiles the recipe will be associated with */ ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES); LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry, @@ -6453,6 +6521,7 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, struct ice_switch_info *sw; enum ice_status status; const u8 *pkt = NULL; + bool prof_rule; u16 word_cnt; u32 act = 0; u8 q_rgn; @@ -6463,7 +6532,8 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ice_init_prof_result_bm(hw); } - if (!lkups_cnt) + prof_rule = ice_is_prof_rule(rinfo->tun_type); + if (!prof_rule && !lkups_cnt) return ICE_ERR_PARAM; /* get # of words we need to match */ @@ -6476,8 +6546,14 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, if (ptr[j] != 0) word_cnt++; } - if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS) - return ICE_ERR_PARAM; + + if (prof_rule) { + if (word_cnt > ICE_MAX_CHAIN_WORDS) + return ICE_ERR_PARAM; + } else { + if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS) + return ICE_ERR_PARAM; + } /* make sure that we can locate a dummy packet */ ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len, @@ -6608,7 +6684,7 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, adv_fltr->lkups = (struct ice_adv_lkup_elem *) ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups), ICE_NONDMA_TO_NONDMA); - if (!adv_fltr->lkups) { + if (!adv_fltr->lkups && !prof_rule) { status = ICE_ERR_NO_MEMORY; goto err_ice_add_adv_rule; } diff --git a/drivers/net/ice/base/ice_switch.h b/drivers/net/ice/base/ice_switch.h index c01fa8a6dc..30f3746dc8 100644 --- a/drivers/net/ice/base/ice_switch.h +++ b/drivers/net/ice/base/ice_switch.h @@ -15,6 +15,11 @@ #define ICE_FLTR_TX BIT(1) #define ICE_FLTR_TX_RX (ICE_FLTR_RX | ICE_FLTR_TX) +/* Switch Profile IDs for Profile related switch rules */ +#define ICE_PROFID_IPV6_ESP 72 +#define ICE_PROFID_IPV6_AH 74 +#define ICE_PROFID_MAC_IPV6_L2TPV3 78 + /* Worst case buffer length for ice_aqc_opc_get_res_alloc */ #define ICE_MAX_RES_TYPES 0x80 #define ICE_AQ_GET_RES_ALLOC_BUF_LEN \ -- 2.20.1