From patchwork Wed Feb 3 14:03:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Haiyue" X-Patchwork-Id: 87696 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 2A9E4A0A0E; Wed, 3 Feb 2021 15:19:33 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1031C2405F2; Wed, 3 Feb 2021 15:19:33 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id CB97D2405F2 for ; Wed, 3 Feb 2021 15:19:31 +0100 (CET) IronPort-SDR: +Mm33gt2+48kby01QKzANg4niDx7+zlh3o/OgmKidJGFgyelURsrNOppDdzCB8hnMHlNj+uN4F vZwlEFmWpgFw== X-IronPort-AV: E=McAfee;i="6000,8403,9883"; a="181190774" X-IronPort-AV: E=Sophos;i="5.79,398,1602572400"; d="scan'208";a="181190774" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 06:19:30 -0800 IronPort-SDR: RyvuJHsgAjdrKds4S3APWvi71pJNkalEjO3fF/uPe1t99ivGYg7Y3yRhPv2r3kwzPu+jixG5jT S4AhpyDAn64w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,398,1602572400"; d="scan'208";a="392455814" Received: from npg-dpdk-haiyue-1.sh.intel.com ([10.67.118.220]) by orsmga008.jf.intel.com with ESMTP; 03 Feb 2021 06:19:29 -0800 From: Haiyue Wang To: dev@dpdk.org Cc: qiming.yang@intel.com, qi.z.zhang@intel.com, Haiyue Wang Date: Wed, 3 Feb 2021 22:03:03 +0800 Message-Id: <20210203140303.65761-1-haiyue.wang@intel.com> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v1] net/ice: update VLAN strip set in double VLAN mode 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" Since commit 14e7a4b37b4f ("net/ice/base: support configuring device in double VLAN mode"), the VLAN strip design is changed, double VLAN mode is not enabled by updating the VSI setting, it depends on the DDP and FW running support. Also, in double VLAN mode, the VLAN strip is applied on outer, since the VLAN filter is outer; in single VLAN mode, the VLAN strip is applied on inner, since the VLAN filter is inner. Signed-off-by: Haiyue Wang --- 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 02a25e8d2a..cb2c0cf449 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -68,8 +68,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 @@ -1122,127 +1120,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) @@ -2220,9 +2097,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"); @@ -4086,49 +3960,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; } @@ -4155,13 +4127,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; }