From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 812ACA0508; Wed, 13 Apr 2022 10:11:45 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 64A6642827; Wed, 13 Apr 2022 10:11:07 +0200 (CEST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mails.dpdk.org (Postfix) with ESMTP id E1D794281E for ; Wed, 13 Apr 2022 10:11:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1649837465; x=1681373465; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=czQYGmqdwsiJjeNH0C2rD08JOg7Y4c6jT9LjqLzrkTE=; b=QV7IMhd6unTLIiTJuOsKJLMf1DRyMtBpaN9zxEEpkq861nezpH/2amkJ KK9TXmrgntlpAWyvPlVGaIAeCxf8kOzMdaZ+BGx1GrxS26Jd6ym4Emg/S M81nrcf0LUZUiy85IlkgkDPhhgPm9zCQ67cBUC5RE1rA9JKK4NpHI4jN+ sgo+tDEGmoiY7uTgX2aqtwCCJcThuawmpMxSf63Xuix1vu0IadPnRisQW bgHmWwtsyZUVSR5zqMvehkF8i8yk2I1tcx3qX61KbZJOv0Ae4pMTGQ8Gj hTIxk9uRV16678KyiMUf2evP6z/JC6zEG+XRIqtjTHlkdC9hsWJrE2ME4 g==; X-IronPort-AV: E=McAfee;i="6400,9594,10315"; a="243189106" X-IronPort-AV: E=Sophos;i="5.90,256,1643702400"; d="scan'208";a="243189106" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2022 01:11:03 -0700 X-IronPort-AV: E=Sophos;i="5.90,256,1643702400"; d="scan'208";a="526847593" Received: from intel-cd-odc-kevin.cd.intel.com ([10.240.178.195]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Apr 2022 01:11:01 -0700 From: Kevin Liu To: dev@dpdk.org Cc: qiming.yang@intel.com, qi.z.zhang@intel.com, stevex.yang@intel.com, Alvin Zhang , Kevin Liu Subject: [PATCH v2 09/33] net/ice: support DCF new VLAN capabilities Date: Wed, 13 Apr 2022 16:09:08 +0000 Message-Id: <20220413160932.2074781-10-kevinx.liu@intel.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220413160932.2074781-1-kevinx.liu@intel.com> References: <20220407105706.18889-1-kevinx.liu@intel.com> <20220413160932.2074781-1-kevinx.liu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 From: Alvin Zhang The new VLAN virtchnl opcodes introduce new capabilities like VLAN filtering, stripping and insertion. The DCF needs to query the VLAN capabilities based on current device configuration firstly. DCF is able to configure inner VLAN filter when port VLAN is enabled base on negotiation; and DCF is able to configure outer VLAN (0x8100) if port VLAN is disabled to be compatible with legacy mode. When port VLAN is updated by DCF, the DCF needs to reset to query the new VLAN capabilities. Signed-off-by: Alvin Zhang Signed-off-by: Kevin Liu --- drivers/net/ice/ice_dcf.c | 27 +++++ drivers/net/ice/ice_dcf.h | 1 + drivers/net/ice/ice_dcf_ethdev.c | 171 ++++++++++++++++++++++++++++--- 3 files changed, 182 insertions(+), 17 deletions(-) diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c index 55ae68c456..885d58c0f4 100644 --- a/drivers/net/ice/ice_dcf.c +++ b/drivers/net/ice/ice_dcf.c @@ -587,6 +587,29 @@ ice_dcf_get_supported_rxdid(struct ice_dcf_hw *hw) return 0; } +static int +dcf_get_vlan_offload_caps_v2(struct ice_dcf_hw *hw) +{ + struct virtchnl_vlan_caps vlan_v2_caps; + struct dcf_virtchnl_cmd args; + int ret; + + memset(&args, 0, sizeof(args)); + args.v_op = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS; + args.rsp_msgbuf = (uint8_t *)&vlan_v2_caps; + args.rsp_buflen = sizeof(vlan_v2_caps); + + ret = ice_dcf_execute_virtchnl_cmd(hw, &args); + if (ret) { + PMD_DRV_LOG(ERR, + "Failed to execute command of VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS"); + return ret; + } + + rte_memcpy(&hw->vlan_v2_caps, &vlan_v2_caps, sizeof(vlan_v2_caps)); + return 0; +} + int ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw) { @@ -701,6 +724,10 @@ ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw) rte_intr_enable(pci_dev->intr_handle); ice_dcf_enable_irq0(hw); + if ((hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) && + dcf_get_vlan_offload_caps_v2(hw)) + goto err_rss; + return 0; err_rss: diff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h index 78df202a77..32e6031bd9 100644 --- a/drivers/net/ice/ice_dcf.h +++ b/drivers/net/ice/ice_dcf.h @@ -107,6 +107,7 @@ struct ice_dcf_hw { uint16_t nb_msix; uint16_t rxq_map[16]; struct virtchnl_eth_stats eth_stats_offset; + struct virtchnl_vlan_caps vlan_v2_caps; /* Link status */ bool link_up; diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c index e58cdf47d2..d4bfa182a4 100644 --- a/drivers/net/ice/ice_dcf_ethdev.c +++ b/drivers/net/ice/ice_dcf_ethdev.c @@ -1026,6 +1026,46 @@ dcf_dev_set_default_mac_addr(struct rte_eth_dev *dev, return 0; } +static int +dcf_add_del_vlan_v2(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) +{ + struct virtchnl_vlan_supported_caps *supported_caps = + &hw->vlan_v2_caps.filtering.filtering_support; + struct virtchnl_vlan *vlan_setting; + struct virtchnl_vlan_filter_list_v2 vlan_filter; + struct dcf_virtchnl_cmd args; + uint32_t filtering_caps; + int err; + + if (supported_caps->outer) { + filtering_caps = supported_caps->outer; + vlan_setting = &vlan_filter.filters[0].outer; + } else { + filtering_caps = supported_caps->inner; + vlan_setting = &vlan_filter.filters[0].inner; + } + + if (!(filtering_caps & VIRTCHNL_VLAN_ETHERTYPE_8100)) + return -ENOTSUP; + + memset(&vlan_filter, 0, sizeof(vlan_filter)); + vlan_filter.vport_id = hw->vsi_res->vsi_id; + vlan_filter.num_elements = 1; + vlan_setting->tpid = RTE_ETHER_TYPE_VLAN; + vlan_setting->tci = vlanid; + + memset(&args, 0, sizeof(args)); + args.v_op = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2; + args.req_msg = (uint8_t *)&vlan_filter; + args.req_msglen = sizeof(vlan_filter); + err = ice_dcf_execute_virtchnl_cmd(hw, &args); + if (err) + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_VLAN_V2" : "OP_DEL_VLAN_V2"); + + return err; +} + static int dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) { @@ -1052,6 +1092,116 @@ dcf_add_del_vlan(struct ice_dcf_hw *hw, uint16_t vlanid, bool add) return err; } +static int +dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) +{ + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_dcf_hw *hw = &adapter->real_hw; + int err; + + if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { + err = dcf_add_del_vlan_v2(hw, vlan_id, on); + if (err) + return -EIO; + return 0; + } + + if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) + return -ENOTSUP; + + err = dcf_add_del_vlan(hw, vlan_id, on); + if (err) + return -EIO; + return 0; +} + +static void +dcf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable) +{ + struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf; + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_dcf_hw *hw = &adapter->real_hw; + uint32_t i, j; + uint64_t ids; + + for (i = 0; i < RTE_DIM(vfc->ids); i++) { + if (vfc->ids[i] == 0) + continue; + + ids = vfc->ids[i]; + for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) { + if (ids & 1) + dcf_add_del_vlan_v2(hw, 64 * i + j, enable); + } + } +} + +static int +dcf_config_vlan_strip_v2(struct ice_dcf_hw *hw, bool enable) +{ + struct virtchnl_vlan_supported_caps *stripping_caps = + &hw->vlan_v2_caps.offloads.stripping_support; + struct virtchnl_vlan_setting vlan_strip; + struct dcf_virtchnl_cmd args; + uint32_t *ethertype; + int ret; + + if ((stripping_caps->outer & VIRTCHNL_VLAN_ETHERTYPE_8100) && + (stripping_caps->outer & VIRTCHNL_VLAN_TOGGLE)) + ethertype = &vlan_strip.outer_ethertype_setting; + else if ((stripping_caps->inner & VIRTCHNL_VLAN_ETHERTYPE_8100) && + (stripping_caps->inner & VIRTCHNL_VLAN_TOGGLE)) + ethertype = &vlan_strip.inner_ethertype_setting; + else + return -ENOTSUP; + + memset(&vlan_strip, 0, sizeof(vlan_strip)); + vlan_strip.vport_id = hw->vsi_res->vsi_id; + *ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100; + + memset(&args, 0, sizeof(args)); + args.v_op = enable ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 : + VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2; + args.req_msg = (uint8_t *)&vlan_strip; + args.req_msglen = sizeof(vlan_strip); + ret = ice_dcf_execute_virtchnl_cmd(hw, &args); + if (ret) + PMD_DRV_LOG(ERR, "fail to execute command %s", + enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" : + "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2"); + + return ret; +} + +static int +dcf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask) +{ + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_dcf_hw *hw = &adapter->real_hw; + bool enable; + int err; + + if (mask & RTE_ETH_VLAN_FILTER_MASK) { + enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER); + + dcf_iterate_vlan_filters_v2(dev, enable); + } + + if (mask & RTE_ETH_VLAN_STRIP_MASK) { + enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP); + + err = dcf_config_vlan_strip_v2(hw, enable); + /* If not support, the stripping is already disabled by PF */ + if (err == -ENOTSUP && !enable) + err = 0; + if (err) + return -EIO; + } + + return 0; +} + static int dcf_enable_vlan_strip(struct ice_dcf_hw *hw) { @@ -1084,30 +1234,17 @@ dcf_disable_vlan_strip(struct ice_dcf_hw *hw) return ret; } -static int -dcf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) -{ - struct ice_dcf_adapter *adapter = dev->data->dev_private; - struct ice_dcf_hw *hw = &adapter->real_hw; - int err; - - if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) - return -ENOTSUP; - - err = dcf_add_del_vlan(hw, vlan_id, on); - if (err) - return -EIO; - return 0; -} - static int dcf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) { + struct rte_eth_conf *dev_conf = &dev->data->dev_conf; struct ice_dcf_adapter *adapter = dev->data->dev_private; struct ice_dcf_hw *hw = &adapter->real_hw; - struct rte_eth_conf *dev_conf = &dev->data->dev_conf; int err; + if (hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) + return dcf_dev_vlan_offload_set_v2(dev, mask); + if (!(hw->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) return -ENOTSUP; -- 2.33.1