From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 41FA1A0093 for ; Mon, 18 May 2020 06:20:03 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 165501D54D; Mon, 18 May 2020 06:20:03 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id ABE9E1D441; Mon, 18 May 2020 06:19:58 +0200 (CEST) IronPort-SDR: my/6Jvr65GthNikhLd6rygr1NqZ45gmdWgv+ILPZwbtwhsFViy7vreRWc4EI3J2yNZX2f58xis QZ9QA3diIiyg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 May 2020 21:19:57 -0700 IronPort-SDR: KKj+P3dwMajH/BvGD/llLoJ2Z5dnkoRPuN/CGwTSRbr5Jh6uTu+pIHKK2zQBPsGPvH8UBWSM7O PhhZZ2gZKjdg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,406,1583222400"; d="scan'208";a="411120600" Received: from dpdk51.sh.intel.com ([10.67.111.82]) by orsmga004.jf.intel.com with ESMTP; 17 May 2020 21:19:55 -0700 From: Qi Zhang To: qiming.yang@intel.com Cc: dev@dpdk.org, xiaolong.ye@intel.com, Qi Zhang , stable@dpdk.org, Dan Nowlin Date: Mon, 18 May 2020 12:23:51 +0800 Message-Id: <20200518042351.39075-1-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.13.6 Subject: [dpdk-stable] [PATCH] net/ice: fix tunnel type match word handling X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Use a common function when selecting the proper word and mask match for a tunnel type when programming switch rules. Store switch recipe field mask as little endian, which avoids needing to convert back to big endian after reading recipe from FW. Obtain word mask from FW recipe. Fix word matching element and index pairing. Fixes: fed0c5ca5f19 ("net/ice/base: support programming a new switch recipe") Cc: stable@dpdk.org Signed-off-by: Dan Nowlin Signed-off-by: Qi Zhang --- drivers/net/ice/base/ice_osdep.h | 1 + drivers/net/ice/base/ice_protocol_type.h | 1 + drivers/net/ice/base/ice_switch.c | 89 ++++++++++++++++++++------------ 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/drivers/net/ice/base/ice_osdep.h b/drivers/net/ice/base/ice_osdep.h index c70f5f8a7..881bf5ddc 100644 --- a/drivers/net/ice/base/ice_osdep.h +++ b/drivers/net/ice/base/ice_osdep.h @@ -78,6 +78,7 @@ typedef uint64_t s64; #define CPU_TO_BE16(o) rte_cpu_to_be_16(o) #define CPU_TO_BE32(o) rte_cpu_to_be_32(o) #define CPU_TO_BE64(o) rte_cpu_to_be_64(o) +#define BE16_TO_CPU(o) rte_be_to_cpu_16(o) #define NTOHS(a) rte_be_to_cpu_16(a) #define NTOHL(a) rte_be_to_cpu_32(a) diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h index 46cd77e68..30233b9c4 100644 --- a/drivers/net/ice/base/ice_protocol_type.h +++ b/drivers/net/ice/base/ice_protocol_type.h @@ -163,6 +163,7 @@ enum ice_prot_id { #define ICE_MDID_SIZE 2 #define ICE_TUN_FLAG_MDID 21 +#define ICE_TUN_FLAG_MDID_OFF (ICE_MDID_SIZE * ICE_TUN_FLAG_MDID) #define ICE_TUN_FLAG_MASK 0xFF #define ICE_TUN_FLAG_FV_IND 2 diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index 17fbd26da..5f0986fcf 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -945,6 +945,8 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, rg_entry->fv_idx[i], &prot, &off); lkup_exts->fv_words[fv_word_idx].prot_id = prot; lkup_exts->fv_words[fv_word_idx].off = off; + lkup_exts->field_mask[fv_word_idx] = + rg_entry->fv_mask[i]; fv_word_idx++; } /* populate rg_list with the data from the child entry of this @@ -5253,20 +5255,23 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, /* if number of words we are looking for match */ if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { - struct ice_fv_word *a = lkup_exts->fv_words; - struct ice_fv_word *b = recp[i].lkup_exts.fv_words; - u16 *c = recp[i].lkup_exts.field_mask; - u16 *d = lkup_exts->field_mask; + struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; + struct ice_fv_word *be = lkup_exts->fv_words; + u16 *cr = recp[i].lkup_exts.field_mask; + u16 *de = lkup_exts->field_mask; bool found = true; - u8 p, q; - - for (p = 0; p < lkup_exts->n_val_words; p++) { - for (q = 0; q < recp[i].lkup_exts.n_val_words; - q++) { - if (a[p].off == b[q].off && - a[p].prot_id == b[q].prot_id && - d[p] == c[q]) - /* Found the "p"th word in the + u8 pe, qr; + + /* ar, cr, and qr are related to the recipe words, while + * be, de and pe are related to the lookup words + */ + for (pe = 0; pe < lkup_exts->n_val_words; pe++) { + for (qr = 0; qr < recp[i].lkup_exts.n_val_words; + qr++) { + if (ar[qr].off == be[pe].off && + ar[qr].prot_id == be[pe].prot_id && + cr[qr] == de[pe]) + /* Found the "pe"th word in the * given recipe */ break; @@ -5277,7 +5282,7 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, * So break out from this loop and try the next * recipe */ - if (q >= recp[i].lkup_exts.n_val_words) { + if (qr >= recp[i].lkup_exts.n_val_words) { found = false; break; } @@ -5285,7 +5290,8 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, /* If for "i"th recipe the found was never set to false * then it means we found our match */ - if (tun_type == recp[i].tun_type && found) + if ((tun_type == recp[i].tun_type || + tun_type == ICE_SW_TUN_AND_NON_TUN) && found) return i; /* Return the recipe ID */ } } @@ -5339,7 +5345,8 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule, ice_prot_ext[rule->type].offs[j]; lkup_exts->fv_words[word].prot_id = ice_prot_id_tbl[rule->type].protocol_id; - lkup_exts->field_mask[word] = ((u16 *)&rule->m_u)[j]; + lkup_exts->field_mask[word] = + BE16_TO_CPU(((__be16 *)&rule->m_u)[j]); word++; } @@ -5455,11 +5462,7 @@ ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list, /* Store index of field vector */ rg->fv_idx[i] = j; - /* Mask is given by caller as big - * endian, but sent to FW as little - * endian - */ - rg->fv_mask[i] = mask << 8 | mask >> 8; + rg->fv_mask[i] = mask; break; } @@ -5941,6 +5944,27 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, } /** + * ice_tun_type_match_mask - determine if tun type needs a match mask + * @tun_type: tunnel type + * @mask: mask to be used for the tunnel + */ +static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) +{ + switch (tun_type) { + case ICE_SW_TUN_VXLAN_GPE: + case ICE_SW_TUN_NVGRE: + case ICE_SW_TUN_UDP: + case ICE_ALL_TUNNELS: + *mask = ICE_TUN_FLAG_MASK; + return true; + + default: + *mask = 0; + return false; + } +} + +/** * ice_add_special_words - Add words that are not protocols, such as metadata * @rinfo: other information regarding the rule e.g. priority and action info * @lkup_exts: lookup word structure @@ -5949,17 +5973,18 @@ static enum ice_status ice_add_special_words(struct ice_adv_rule_info *rinfo, struct ice_prot_lkup_ext *lkup_exts) { + u16 mask; + /* If this is a tunneled packet, then add recipe index to match the * tunnel bit in the packet metadata flags. */ - if (rinfo->tun_type != ICE_NON_TUN) { + if (ice_tun_type_match_word(rinfo->tun_type, &mask)) { if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { u8 word = lkup_exts->n_val_words++; lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; - lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID * - ICE_MDID_SIZE; - lkup_exts->field_mask[word] = ICE_TUN_FLAG_MASK; + lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF; + lkup_exts->field_mask[word] = mask; } else { return ICE_ERR_MAX_LIMIT; } @@ -6099,6 +6124,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, enum ice_status status = ICE_SUCCESS; struct ice_sw_recipe *rm; bool match_tun = false; + u16 mask; u8 i; if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt) @@ -6156,14 +6182,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, if (status) goto err_unroll; - /* There is only profile for UDP tunnels. So, it is necessary to use a - * metadata ID flag to differentiate different tunnel types. A separate - * recipe needs to be used for the metadata. + /* For certain tunnel types it is necessary to use a metadata ID flag to + * differentiate different tunnel types. A separate recipe needs to be + * used for the metadata. */ - if ((rinfo->tun_type == ICE_SW_TUN_VXLAN_GPE || - rinfo->tun_type == ICE_SW_TUN_GENEVE || - rinfo->tun_type == ICE_SW_TUN_VXLAN) && rm->n_grp_count > 1) - match_tun = true; + if (ice_tun_type_match_word(rinfo->tun_type, &mask) && + rm->n_grp_count > 1) + match_tun = mask; /* set the recipe priority if specified */ rm->priority = (u8)rinfo->priority; -- 2.13.6