From patchwork Tue Aug 3 08:38:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenjun Wu X-Patchwork-Id: 96595 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id AAFC1A0C41; Tue, 3 Aug 2021 10:58:51 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7E38741216; Tue, 3 Aug 2021 10:57:32 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 9B47A411D5 for ; Tue, 3 Aug 2021 10:57:16 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10064"; a="211764413" X-IronPort-AV: E=Sophos;i="5.84,291,1620716400"; d="scan'208";a="211764413" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Aug 2021 01:57:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,291,1620716400"; d="scan'208";a="479396674" Received: from wuwenjun.sh.intel.com ([10.67.110.197]) by fmsmga008.fm.intel.com with ESMTP; 03 Aug 2021 01:57:07 -0700 From: Wenjun Wu To: dev@dpdk.org Date: Tue, 3 Aug 2021 16:38:11 +0800 Message-Id: <20210803083817.1243796-17-wenjun1.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210803083817.1243796-1-wenjun1.wu@intel.com> References: <20210803083817.1243796-1-wenjun1.wu@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 16/22] net/ice: fix VLAN strip for double VLAN X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Haiyue Wang [ upstream commit 8ac4307504bed19ce68b39bc2703975ee0b9ab81 ] VLAN strip was failing for double VLAN because of hardware configuration, resulting mbuf not having the vlan_tci information. Adjusted the strip setting according to current VLAN mode to fix the VLAN strip. Fixes: 14e7a4b37b4f ("net/ice/base: support configuring device in double VLAN mode") Signed-off-by: Haiyue Wang Acked-by: Qiming Yang --- drivers/net/ice/ice_ethdev.c | 297 +++++++++++++++-------------------- 1 file changed, 131 insertions(+), 166 deletions(-) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 9ce0280726..1d7e5ffbc4 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -70,8 +70,6 @@ static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = { .ol_flag = &rte_net_ice_dynflag_proto_xtr_ip_offset_mask }, }; -#define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100 - #define ICE_OS_DEFAULT_PKG_NAME "ICE OS Default Package" #define ICE_COMMS_PKG_NAME "ICE COMMS Package" #define ICE_MAX_RES_DESC_NUM 1024 @@ -1119,127 +1117,6 @@ ice_remove_all_mac_vlan_filters(struct ice_vsi *vsi) return ret; } -static int -ice_vsi_config_qinq_insertion(struct ice_vsi *vsi, bool on) -{ - struct ice_hw *hw = ICE_VSI_TO_HW(vsi); - struct ice_vsi_ctx ctxt; - uint8_t qinq_flags; - int ret = 0; - - /* Check if it has been already on or off */ - if (vsi->info.valid_sections & - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) { - if (on) { - if ((vsi->info.outer_vlan_flags & - ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST) == - ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST) - return 0; /* already on */ - } else { - if (!(vsi->info.outer_vlan_flags & - ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST)) - return 0; /* already off */ - } - } - - if (on) - qinq_flags = ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST; - else - qinq_flags = 0; - /* clear global insertion and use per packet insertion */ - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_INSERT); - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_VLAN_PORT_BASED_ACCEPT_HOST); - vsi->info.outer_vlan_flags |= qinq_flags; - /* use default vlan type 0x8100 */ - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M); - vsi->info.outer_vlan_flags |= ICE_DFLT_OUTER_TAG_TYPE << - ICE_AQ_VSI_OUTER_TAG_TYPE_S; - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); - ctxt.info.valid_sections = - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); - ctxt.vsi_num = vsi->vsi_id; - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); - if (ret) { - PMD_DRV_LOG(INFO, - "Update VSI failed to %s qinq stripping", - on ? "enable" : "disable"); - return -EINVAL; - } - - vsi->info.valid_sections |= - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); - - return ret; -} - -static int -ice_vsi_config_qinq_stripping(struct ice_vsi *vsi, bool on) -{ - struct ice_hw *hw = ICE_VSI_TO_HW(vsi); - struct ice_vsi_ctx ctxt; - uint8_t qinq_flags; - int ret = 0; - - /* Check if it has been already on or off */ - if (vsi->info.valid_sections & - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID)) { - if (on) { - if ((vsi->info.outer_vlan_flags & - ICE_AQ_VSI_OUTER_VLAN_EMODE_M) == - ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW) - return 0; /* already on */ - } else { - if ((vsi->info.outer_vlan_flags & - ICE_AQ_VSI_OUTER_VLAN_EMODE_M) == - ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH) - return 0; /* already off */ - } - } - - if (on) - qinq_flags = ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW; - else - qinq_flags = ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH; - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_VLAN_EMODE_M); - vsi->info.outer_vlan_flags |= qinq_flags; - /* use default vlan type 0x8100 */ - vsi->info.outer_vlan_flags &= ~(ICE_AQ_VSI_OUTER_TAG_TYPE_M); - vsi->info.outer_vlan_flags |= ICE_DFLT_OUTER_TAG_TYPE << - ICE_AQ_VSI_OUTER_TAG_TYPE_S; - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); - ctxt.info.valid_sections = - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); - ctxt.vsi_num = vsi->vsi_id; - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); - if (ret) { - PMD_DRV_LOG(INFO, - "Update VSI failed to %s qinq stripping", - on ? "enable" : "disable"); - return -EINVAL; - } - - vsi->info.valid_sections |= - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); - - return ret; -} - -static int -ice_vsi_config_double_vlan(struct ice_vsi *vsi, int on) -{ - int ret; - - ret = ice_vsi_config_qinq_stripping(vsi, on); - if (ret) - PMD_DRV_LOG(ERR, "Fail to set qinq stripping - %d", ret); - - ret = ice_vsi_config_qinq_insertion(vsi, on); - if (ret) - PMD_DRV_LOG(ERR, "Fail to set qinq insertion - %d", ret); - - return ret; -} - /* Enable IRQ0 */ static void ice_pf_enable_irq0(struct ice_hw *hw) @@ -2226,9 +2103,6 @@ ice_dev_init(struct rte_eth_dev *dev) vsi = pf->main_vsi; - /* Disable double vlan by default */ - ice_vsi_config_double_vlan(vsi, false); - ret = ice_aq_stop_lldp(hw, true, false, NULL); if (ret != ICE_SUCCESS) PMD_INIT_LOG(DEBUG, "lldp has already stopped\n"); @@ -4112,49 +3986,147 @@ ice_vsi_config_vlan_filter(struct ice_vsi *vsi, bool on) return 0; } +/* Manage VLAN stripping for the VSI for Rx */ static int -ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool on) +ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) { struct ice_hw *hw = ICE_VSI_TO_HW(vsi); struct ice_vsi_ctx ctxt; - uint8_t vlan_flags; - int ret = 0; + enum ice_status status; + int err = 0; - /* Check if it has been already on or off */ - if (vsi->info.valid_sections & - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID)) { - if (on) { - if ((vsi->info.inner_vlan_flags & - ICE_AQ_VSI_INNER_VLAN_EMODE_M) == - ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH) - return 0; /* already on */ - } else { - if ((vsi->info.inner_vlan_flags & - ICE_AQ_VSI_INNER_VLAN_EMODE_M) == - ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING) - return 0; /* already off */ - } - } + /* do not allow modifying VLAN stripping when a port VLAN is configured + * on this VSI + */ + if (vsi->info.port_based_inner_vlan) + return 0; - if (on) - vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH; + memset(&ctxt, 0, sizeof(ctxt)); + + if (ena) + /* Strip VLAN tag from Rx packet and put it in the desc */ + ctxt.info.inner_vlan_flags = + ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH; else - vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; - vsi->info.inner_vlan_flags &= ~(ICE_AQ_VSI_INNER_VLAN_EMODE_M); - vsi->info.inner_vlan_flags |= vlan_flags; - (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); + /* Disable stripping. Leave tag in packet */ + ctxt.info.inner_vlan_flags = + ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; + + /* Allow all packets untagged/tagged */ + ctxt.info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL; + + ctxt.info.valid_sections = rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID); + + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); + if (status) { + PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan stripping", + ena ? "enable" : "disable"); + err = -EIO; + } else { + vsi->info.inner_vlan_flags = ctxt.info.inner_vlan_flags; + } + + return err; +} + +static int +ice_vsi_ena_inner_stripping(struct ice_vsi *vsi) +{ + return ice_vsi_manage_vlan_stripping(vsi, true); +} + +static int +ice_vsi_dis_inner_stripping(struct ice_vsi *vsi) +{ + return ice_vsi_manage_vlan_stripping(vsi, false); +} + +static int ice_vsi_ena_outer_stripping(struct ice_vsi *vsi) +{ + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_vsi_ctx ctxt; + enum ice_status status; + int err = 0; + + /* do not allow modifying VLAN stripping when a port VLAN is configured + * on this VSI + */ + if (vsi->info.port_based_outer_vlan) + return 0; + + memset(&ctxt, 0, sizeof(ctxt)); + ctxt.info.valid_sections = - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID); - ctxt.vsi_num = vsi->vsi_id; - ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); - if (ret) { - PMD_DRV_LOG(INFO, "Update VSI failed to %s vlan stripping", - on ? "enable" : "disable"); - return -EINVAL; + rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); + /* clear current outer VLAN strip settings */ + ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags & + ~(ICE_AQ_VSI_OUTER_VLAN_EMODE_M | ICE_AQ_VSI_OUTER_TAG_TYPE_M); + ctxt.info.outer_vlan_flags |= + (ICE_AQ_VSI_OUTER_VLAN_EMODE_SHOW_BOTH << + ICE_AQ_VSI_OUTER_VLAN_EMODE_S) | + (ICE_AQ_VSI_OUTER_TAG_VLAN_8100 << + ICE_AQ_VSI_OUTER_TAG_TYPE_S); + + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); + if (status) { + PMD_DRV_LOG(ERR, "Update VSI failed to enable outer VLAN stripping"); + err = -EIO; + } else { + vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags; } - vsi->info.valid_sections |= - rte_cpu_to_le_16(ICE_AQ_VSI_PROP_VLAN_VALID); + return err; +} + +static int +ice_vsi_dis_outer_stripping(struct ice_vsi *vsi) +{ + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_vsi_ctx ctxt; + enum ice_status status; + int err = 0; + + if (vsi->info.port_based_outer_vlan) + return 0; + + memset(&ctxt, 0, sizeof(ctxt)); + + ctxt.info.valid_sections = + rte_cpu_to_le_16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID); + /* clear current outer VLAN strip settings */ + ctxt.info.outer_vlan_flags = vsi->info.outer_vlan_flags & + ~ICE_AQ_VSI_OUTER_VLAN_EMODE_M; + ctxt.info.outer_vlan_flags |= ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING << + ICE_AQ_VSI_OUTER_VLAN_EMODE_S; + + status = ice_update_vsi(hw, vsi->idx, &ctxt, NULL); + if (status) { + PMD_DRV_LOG(ERR, "Update VSI failed to disable outer VLAN stripping"); + err = -EIO; + } else { + vsi->info.outer_vlan_flags = ctxt.info.outer_vlan_flags; + } + + return err; +} + +static int +ice_vsi_config_vlan_stripping(struct ice_vsi *vsi, bool ena) +{ + struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + int ret; + + if (ice_is_dvm_ena(hw)) { + if (ena) + ret = ice_vsi_ena_outer_stripping(vsi); + else + ret = ice_vsi_dis_outer_stripping(vsi); + } else { + if (ena) + ret = ice_vsi_ena_inner_stripping(vsi); + else + ret = ice_vsi_dis_inner_stripping(vsi); + } return ret; } @@ -4181,13 +4153,6 @@ ice_vlan_offload_set(struct rte_eth_dev *dev, int mask) ice_vsi_config_vlan_stripping(vsi, false); } - if (mask & ETH_VLAN_EXTEND_MASK) { - if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) - ice_vsi_config_double_vlan(vsi, true); - else - ice_vsi_config_double_vlan(vsi, false); - } - return 0; }