From patchwork Wed Sep 2 08:28:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiming Yang X-Patchwork-Id: 76297 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 dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id F0F6FA04B7; Wed, 2 Sep 2020 10:50:09 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 52D954C99; Wed, 2 Sep 2020 10:50:09 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id ADBBB255 for ; Wed, 2 Sep 2020 10:50:07 +0200 (CEST) IronPort-SDR: fq06hf/gy7RmlH6BD68AJTDvzEnobHvH4so0Ez25UknwCvTBt+ppEh7Pi4fNieXLwHL14wKbE7 kekQkLFWtbKw== X-IronPort-AV: E=McAfee;i="6000,8403,9731"; a="157353599" X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="157353599" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Sep 2020 01:50:03 -0700 IronPort-SDR: FMG7XNmMVpu3GuDdTbO8J9ra9eWBl++ai8tTMXRt09ShPyAvZgL89aecYCi9aaDTkjbVjnqi7k gNdAYwt9A7Fg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,381,1592895600"; d="scan'208";a="325697889" Received: from dpdk-qiming1.sh.intel.com ([10.67.119.9]) by fmsmga004.fm.intel.com with ESMTP; 02 Sep 2020 01:50:02 -0700 From: Qiming Yang To: dev@dpdk.org Cc: qi.z.zhang@intel.com, Qiming Yang Date: Wed, 2 Sep 2020 16:28:41 +0800 Message-Id: <20200902082841.106117-1-qiming.yang@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-dev] [PATCH] net/iavf: support enhanced VLAN offload X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" This patch add VIRTCHNL_VF_OFFLOAD_VLAN_V2 series virtual channel support, included get VLAN offload capability, support VLAN filter and double VLAN strip. Signed-off-by: Qiming Yang --- drivers/net/iavf/iavf.h | 5 ++ drivers/net/iavf/iavf_ethdev.c | 70 ++++++++++++++++++++------- drivers/net/iavf/iavf_vchnl.c | 87 ++++++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 17 deletions(-) diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h index 9ad331ee9..8c10f7e59 100644 --- a/drivers/net/iavf/iavf.h +++ b/drivers/net/iavf/iavf.h @@ -149,6 +149,7 @@ struct iavf_info { struct iavf_parser_list dist_parser_list; struct iavf_fdir_info fdir; /* flow director info */ + struct virtchnl_vlan_caps *vlan_cap; }; #define IAVF_MAX_PKT_TYPE 1024 @@ -279,4 +280,8 @@ int iavf_add_del_rss_cfg(struct iavf_adapter *adapter, int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter, struct rte_ether_addr *mc_addrs, uint32_t mc_addrs_num, bool add); +int iavf_get_vlan_offload_capa(struct rte_eth_dev *dev); +int iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, + bool add, bool qinq); +int iavf_switch_vlan_strip(struct iavf_adapter *adapter, bool qinq, bool on); #endif /* _IAVF_ETHDEV_H_ */ diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index 28ca3fa8f..af9698009 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -807,14 +807,22 @@ iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) struct iavf_adapter *adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + int qinq = dev->data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_EXTEND; int err; - if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) - return -ENOTSUP; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { + err = iavf_add_del_vlan_v2(adapter, vlan_id, on, qinq); + if (err) + return -EIO; + return 0; + } - err = iavf_add_del_vlan(adapter, vlan_id, on); - if (err) - return -EIO; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) { + err = iavf_add_del_vlan(adapter, vlan_id, on); + if (err) + return -EIO; + } return 0; } @@ -825,22 +833,48 @@ iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); struct rte_eth_conf *dev_conf = &dev->data->dev_conf; + int qinq = dev->data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_EXTEND; + bool on; int err; - if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) - return -ENOTSUP; - - /* Vlan stripping setting */ - if (mask & ETH_VLAN_STRIP_MASK) { - /* Enable or disable VLAN stripping */ - if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) - err = iavf_enable_vlan_strip(adapter); - else - err = iavf_disable_vlan_strip(adapter); + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { + /* Double vlan stripping setting */ + if (mask & ETH_QINQ_STRIP_MASK) { + /* Enable or disable inner VLAN stripping */ + on = dev_conf->rxmode.offloads & + DEV_RX_OFFLOAD_QINQ_STRIP; + err = iavf_switch_vlan_strip(adapter, qinq, on); + if (err) + return -EIO; + } + /* Single vlan stripping setting */ + if (mask & ETH_VLAN_STRIP_MASK) { + /* Enable or disable VLAN stripping */ + on = dev_conf->rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_STRIP; + err = iavf_switch_vlan_strip(adapter, qinq, on); + if (err) + return -EIO; + } + return 0; + } - if (err) - return -EIO; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) { + /* Vlan stripping setting */ + if (mask & ETH_VLAN_STRIP_MASK) { + /* Enable or disable VLAN stripping */ + if (dev_conf->rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_STRIP) + err = iavf_enable_vlan_strip(adapter); + else + err = iavf_disable_vlan_strip(adapter); + + if (err) + return -EIO; + } } + return 0; } @@ -1453,6 +1487,8 @@ iavf_dev_init(struct rte_eth_dev *eth_dev) return ret; } + iavf_get_vlan_offload_capa(eth_dev); + return 0; } diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c index 6b57ecbba..74e73b0d3 100644 --- a/drivers/net/iavf/iavf_vchnl.c +++ b/drivers/net/iavf/iavf_vchnl.c @@ -314,6 +314,93 @@ iavf_disable_vlan_strip(struct iavf_adapter *adapter) return ret; } +int +iavf_get_vlan_offload_capa(struct rte_eth_dev *dev) +{ + struct iavf_adapter *adapter = + IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_caps *vlan_cap = NULL; + struct iavf_cmd_info args; + int ret; + + memset(&args, 0, sizeof(args)); + args.ops = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS; + args.in_args = NULL; + args.in_args_size = 0; + args.out_buffer = vf->aq_resp; + args.out_size = IAVF_AQ_BUF_SZ; + ret = iavf_execute_vf_cmd(adapter, &args); + if (ret) + PMD_DRV_LOG(ERR, "Failed to execute command of" + " OP_GET_OFFLOAD_VLAN_V2_CAPS"); + vlan_cap = (struct virtchnl_vlan_caps *)args.out_buffer; + vf->vlan_cap = vlan_cap; + + return ret; +} + +int +iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, + bool add, bool qinq) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_filter vlan_filter; + struct iavf_cmd_info args; + int err; + + if (qinq) { + vlan_filter.inner.id = vlanid; + vlan_filter.inner.ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100; + } else { + vlan_filter.outer.id = vlanid; + vlan_filter.outer.ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100; + } + + args.ops = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2; + args.in_args = (uint8_t *)&vlan_filter; + args.in_args_size = sizeof(vlan_filter); + args.out_buffer = vf->aq_resp; + args.out_size = IAVF_AQ_BUF_SZ; + err = iavf_execute_vf_cmd(adapter, &args); + if (err) + PMD_DRV_LOG(ERR, "fail to execute command %s", + add ? "OP_ADD_VLAN" : "OP_DEL_VLAN"); + + return err; +} + +int +iavf_switch_vlan_strip(struct iavf_adapter *adapter, bool qinq, bool on) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_strip vlan_strip; + struct iavf_cmd_info args; + int ret; + + memset(&args, 0, sizeof(args)); + vlan_strip.vsi_id = vf->vsi_res->vsi_id; + if (qinq) + vlan_strip.inner_ethertype_setting = + VIRTCHNL_VLAN_ETHERTYPE_8100; + else + vlan_strip.outer_ethertype_setting = + VIRTCHNL_VLAN_ETHERTYPE_8100; + args.ops = on ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 + : VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2; + args.in_args = (uint8_t *)&vlan_strip; + args.in_args_size = sizeof(vlan_strip); + args.out_buffer = vf->aq_resp; + args.out_size = IAVF_AQ_BUF_SZ; + ret = iavf_execute_vf_cmd(adapter, &args); + if (ret) + PMD_DRV_LOG(ERR, "fail to execute command %s", + on ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" + : "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2"); + + return ret; +} + #define VIRTCHNL_VERSION_MAJOR_START 1 #define VIRTCHNL_VERSION_MINOR_START 1