From patchwork Mon Jan 11 13:34: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: 86278 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 A3C72A09FF; Mon, 11 Jan 2021 14:50:18 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2F5BD140CDB; Mon, 11 Jan 2021 14:50:06 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 23272140CC1 for ; Mon, 11 Jan 2021 14:50:01 +0100 (CET) IronPort-SDR: Iwk6GJL4RxFSCQ/rzy4A3TMwvNSRuH5hcNpROaH+yt7i8dbG29W+1+r03NOWnxBg37QULgNU8j IMlOFsb5XhuQ== X-IronPort-AV: E=McAfee;i="6000,8403,9860"; a="177083519" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="177083519" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 05:49:57 -0800 IronPort-SDR: bUTRj68soKqC9RPuwbh/3qmWbQFei2c3taqDTwCs9vpIC9KS7doK1hYGfQlXN2WHxdcBz+xeUg yTmX1XY18BKg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="352607016" Received: from npg-dpdk-haiyue-3.sh.intel.com ([10.67.118.189]) by fmsmga008.fm.intel.com with ESMTP; 11 Jan 2021 05:49:55 -0800 From: Haiyue Wang To: dev@dpdk.org Cc: qiming.yang@intel.com, jingjing.wu@intel.com, qi.z.zhang@intel.com, qi.fu@intel.com, Haiyue Wang , Beilei Xing Date: Mon, 11 Jan 2021 21:34:03 +0800 Message-Id: <20210111133406.484200-2-haiyue.wang@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111133406.484200-1-haiyue.wang@intel.com> References: <20201214071155.98764-1-haiyue.wang@intel.com> <20210111133406.484200-1-haiyue.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 1/4] common/iavf: new VLAN opcode 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" Add new VLAN opcode support. Signed-off-by: Haiyue Wang --- drivers/common/iavf/virtchnl.h | 416 +++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) diff --git a/drivers/common/iavf/virtchnl.h b/drivers/common/iavf/virtchnl.h index fcbaa31fa..b549a853c 100644 --- a/drivers/common/iavf/virtchnl.h +++ b/drivers/common/iavf/virtchnl.h @@ -129,6 +129,7 @@ enum virtchnl_ops { VIRTCHNL_OP_ADD_CLOUD_FILTER = 32, VIRTCHNL_OP_DEL_CLOUD_FILTER = 33, /* opcodes 34, 35, 36, 37 and 38 are reserved */ + VIRTCHNL_OP_DCF_VLAN_OFFLOAD = 38, VIRTCHNL_OP_DCF_CMD_DESC = 39, VIRTCHNL_OP_DCF_CMD_BUFF = 40, VIRTCHNL_OP_DCF_DISABLE = 41, @@ -141,6 +142,13 @@ enum virtchnl_ops { VIRTCHNL_OP_DEL_FDIR_FILTER = 48, VIRTCHNL_OP_QUERY_FDIR_FILTER = 49, VIRTCHNL_OP_GET_MAX_RSS_QREGION = 50, + VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS = 51, + VIRTCHNL_OP_ADD_VLAN_V2 = 52, + VIRTCHNL_OP_DEL_VLAN_V2 = 53, + VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 = 54, + VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 = 55, + VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 = 56, + VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2 = 57, VIRTCHNL_OP_ENABLE_QUEUES_V2 = 107, VIRTCHNL_OP_DISABLE_QUEUES_V2 = 108, VIRTCHNL_OP_MAP_QUEUE_VECTOR = 111, @@ -251,6 +259,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource); #define VIRTCHNL_VF_OFFLOAD_CRC 0x00000080 /* 0X00000100 is reserved */ #define VIRTCHNL_VF_LARGE_NUM_QPAIRS 0x00000200 +#define VIRTCHNL_VF_OFFLOAD_VLAN_V2 0x00008000 #define VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000 #define VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000 #define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000 @@ -536,6 +545,349 @@ struct virtchnl_vlan_filter_list { VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list); +/* This enum is used for all of the VIRTCHNL_VF_OFFLOAD_VLAN_V2_CAPS related + * structures and opcodes. + * + * VIRTCHNL_VLAN_UNSUPPORTED - This field is not supported and if a VF driver + * populates it the PF should return VIRTCHNL_STATUS_ERR_NOT_SUPPORTED. + * + * VIRTCHNL_VLAN_ETHERTYPE_8100 - This field supports 0x8100 ethertype. + * VIRTCHNL_VLAN_ETHERTYPE_88A8 - This field supports 0x88A8 ethertype. + * VIRTCHNL_VLAN_ETHERTYPE_9100 - This field supports 0x9100 ethertype. + * + * VIRTCHNL_VLAN_ETHERTYPE_AND - Used when multiple ethertypes can be supported + * by the PF concurrently. For example, if the PF can support + * VIRTCHNL_VLAN_ETHERTYPE_8100 AND VIRTCHNL_VLAN_ETHERTYPE_88A8 filters it + * would OR the following bits: + * + * VIRTHCNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_AND; + * + * The VF would interpret this as VLAN filtering can be supported on both 0x8100 + * and 0x88A8 VLAN ethertypes. + * + * VIRTCHNL_ETHERTYPE_XOR - Used when only a single ethertype can be supported + * by the PF concurrently. For example if the PF can support + * VIRTCHNL_VLAN_ETHERTYPE_8100 XOR VIRTCHNL_VLAN_ETHERTYPE_88A8 stripping + * offload it would OR the following bits: + * + * VIRTCHNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_XOR; + * + * The VF would interpret this as VLAN stripping can be supported on either + * 0x8100 or 0x88a8 VLAN ethertypes. So when requesting VLAN stripping via + * VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 the specified ethertype will override + * the previously set value. + * + * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1 - Used to tell the VF to insert and/or + * strip the VLAN tag using the L2TAG1 field of the Tx/Rx descriptors. + * + * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 - Used to tell the VF to insert hardware + * offloaded VLAN tags using the L2TAG2 field of the Tx descriptor. + * + * VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 - Used to tell the VF to strip hardware + * offloaded VLAN tags using the L2TAG2_2 field of the Rx descriptor. + * + * VIRTCHNL_VLAN_PRIO - This field supports VLAN priority bits. This is used for + * VLAN filtering if the underlying PF supports it. + * + * VIRTCHNL_VLAN_TOGGLE_ALLOWED - This field is used to say whether a + * certain VLAN capability can be toggled. For example if the underlying PF/CP + * allows the VF to toggle VLAN filtering, stripping, and/or insertion it should + * set this bit along with the supported ethertypes. + */ +enum virtchnl_vlan_support { + VIRTCHNL_VLAN_UNSUPPORTED = 0, + VIRTCHNL_VLAN_ETHERTYPE_8100 = 0x00000001, + VIRTCHNL_VLAN_ETHERTYPE_88A8 = 0x00000002, + VIRTCHNL_VLAN_ETHERTYPE_9100 = 0x00000004, + VIRTCHNL_VLAN_TAG_LOCATION_L2TAG1 = 0x00000100, + VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2 = 0x00000200, + VIRTCHNL_VLAN_TAG_LOCATION_L2TAG2_2 = 0x00000400, + VIRTCHNL_VLAN_PRIO = 0x01000000, + VIRTCHNL_VLAN_FILTER_MASK = 0x10000000, + VIRTCHNL_VLAN_ETHERTYPE_AND = 0x20000000, + VIRTCHNL_VLAN_ETHERTYPE_XOR = 0x40000000, + VIRTCHNL_VLAN_TOGGLE = 0x80000000 +}; + +/* This structure is used as part of the VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS + * for filtering, insertion, and stripping capabilities. + * + * If only outer capabilities are supported (for filtering, insertion, and/or + * stripping) then this refers to the outer most or single VLAN from the VF's + * perspective. + * + * If only inner capabilities are supported (for filtering, insertion, and/or + * stripping) then this refers to the outer most or single VLAN from the VF's + * perspective. + * + * If both outer and inner capabilities are supported (for filtering, insertion, + * and/or stripping) then outer refers to the outer most or single VLAN and + * inner refers to the second VLAN, if it exists, in the packet. + * + * There is no support for tunneled VLAN offloads, so outer or inner are never + * referring to a tunneled packet from the VF's perspective. + */ +struct virtchnl_vlan_supported_caps { + u32 outer; + u32 inner; +}; + +/* The PF populates these fields based on the supported VLAN filtering. If a + * field is VIRTCHNL_VLAN_UNSUPPORTED then it's not supported and the PF will + * reject any VIRTCHNL_OP_ADD_VLAN_V2 or VIRTCHNL_OP_DEL_VLAN_V2 messages using + * the unsupported fields. + * + * Also, a VF is only allowed to toggle its VLAN filtering setting if the + * VIRTCHNL_VLAN_TOGGLE bit is set. + * + * The ethertype(s) specified in the ethertype_init field are the ethertypes + * enabled for VLAN filtering. VLAN filtering in this case refers to the outer + * most VLAN from the VF's perspective. If both inner and outer filtering are + * allowed then ethertype_init only refers to the outer most VLAN as only + * VLAN ethertype supported for inner VLAN filtering is + * VIRTCHNL_VLAN_ETHERTYPE_8100. By default, inner VLAN filtering is disabled + * when both inner and outer filtering are allowed. + * + * The max_filters field tells the VF how many VLAN filters it's allowed to have + * at any one time. If it exceeds this amount and tries to add another filter, + * then the request will be rejected by the PF. To prevent failures, the VF + * should keep track of how many VLAN filters it has added and not attempt to + * add more than max_filters. + */ +struct virtchnl_vlan_filtering_caps { + struct virtchnl_vlan_supported_caps filtering_support; + u32 ethertype_init; + u16 max_filters; + u8 pad[2]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vlan_filtering_caps); + +/* This enum is used for the virtchnl_vlan_offload_caps structure to specify + * if the PF supports a different ethertype for stripping and insertion. + * + * VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION - The ethertype(s) specified + * for stripping affect the ethertype(s) sepcified for insertion and visa versa + * as well. If the VF tries to configure VLAN stripping via + * VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 with VIRTCHNL_VLAN_ETHERTYPE_8100 then + * that will be the ethertype for both stripping and insertion. + * + * VIRTCHNL_ETHERTYPE_MATCH_NOT_REQUIRED - The ethertype(s) specified for + * stripping do not affect the ethertype(s) specified for insertion and visa + * versa. + */ +enum virtchnl_vlan_ethertype_match { + VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION = 0, + VIRTCHNL_ETHERTYPE_MATCH_NOT_REQUIRED = 1, +}; + +/* The PF populates these fields based on the supported VLAN offloads. If a + * field is VIRTCHNL_VLAN_UNSUPPORTED then it's not supported and the PF will + * reject any VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 or + * VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 messages using the unsupported fields. + * + * Also, a VF is only allowed to toggle its VLAN offload setting if the + * VIRTCHNL_VLAN_TOGGLE_ALLOWED bit is set. + * + * The VF driver needs to be aware of how the tags are stipped by hardware and + * inserted by the VF driver based on the level of offload support. The PF will + * populate these fields based on where the VLAN tags are expected to be + * offloaded via the VIRTHCNL_VLAN_TAG_LOCATION_* bits. The VF will need to + * interpret these fields. See the definition of the + * VIRTCHNL_VLAN_TAG_LOCATION_* bits above the virtchnl_vlan_support + * enumeration. + */ +struct virtchnl_vlan_offload_caps { + struct virtchnl_vlan_supported_caps stripping_support; + struct virtchnl_vlan_supported_caps insertion_support; + u32 ethertype_init; + u8 ethertype_match; + u8 pad[3]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_vlan_offload_caps); + +/* VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS + * VF sends this message to determine its VLAN capabilities. + * + * PF will mark which capabilities it supports based on hardware support and + * current configuration. For example, if a port VLAN is configured the PF will + * not allow outer VLAN filtering, stripping, or insertion to be configured so + * it will block these features from the VF. + * + * The VF will need to cross reference its capabilities with the PFs + * capabilities in the response message from the PF to determine the VLAN + * support. + */ +struct virtchnl_vlan_caps { + struct virtchnl_vlan_filtering_caps filtering; + struct virtchnl_vlan_offload_caps offloads; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_vlan_caps); + +struct virtchnl_vlan { + u16 tci; /* tci[15:13] = PCP and tci[11:0] = VID */ + u16 tci_mask; /* only valid if VIRTCHNL_VLAN_FILTER_MASK set in + * filtering caps + */ + u16 tpid; /* 0x8100, 0x88a8, etc. and only type(s) set in + * filtering caps. Note that tpid here does not refer to + * VIRTCHNL_VLAN_ETHERTYPE_*, but it refers to the + * actual 2-byte VLAN TPID + */ + u8 pad[2]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_vlan); + +struct virtchnl_vlan_filter { + struct virtchnl_vlan inner; + struct virtchnl_vlan outer; + u8 pad[16]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(32, virtchnl_vlan_filter); + +/* VIRTCHNL_OP_ADD_VLAN_V2 + * VIRTCHNL_OP_DEL_VLAN_V2 + * + * VF sends these messages to add/del one or more VLAN tag filters for Rx + * traffic. + * + * The PF attempts to add the filters and returns status. + * + * The VF should only ever attempt to add/del virtchnl_vlan_filter(s) using the + * supported fields negotiated via VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS. + */ +struct virtchnl_vlan_filter_list_v2 { + u16 vport_id; + u16 num_elements; + u8 pad[4]; + struct virtchnl_vlan_filter filters[1]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_vlan_filter_list_v2); + +/* VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 + * VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2 + * VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 + * VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2 + * + * VF sends this message to enable or disable VLAN stripping or insertion. It + * also needs to specify an ethertype. The VF knows which VLAN ethertypes are + * allowed and whether or not it's allowed to enable/disable the specific + * offload via the VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS message. The VF needs to + * parse the virtchnl_vlan_caps.offloads fields to determine which offload + * messages are allowed. + * + * For example, if the PF populates the virtchnl_vlan_caps.offloads in the + * following manner the VF will be allowed to enable and/or disable 0x8100 inner + * VLAN insertion and/or stripping via the opcodes listed above. Inner in this + * case means the outer most or single VLAN from the VF's perspective. This is + * because no outer offloads are supported. See the comments above the + * virtchnl_vlan_supported_caps structure for more details. + * + * virtchnl_vlan_caps.offloads.stripping_support.inner = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100; + * + * virtchnl_vlan_caps.offloads.insertion_support.inner = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100; + * + * In order to enable inner (again note that in this case inner is the outer + * most or single VLAN from the VF's perspective) VLAN stripping for 0x8100 + * VLANs, the VF would populate the virtchnl_vlan_offload structure in the + * following manner and send the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 message. + * + * virtchnl_vlan_offload.inner_ethertype_setting = + * VIRTCHNL_VLAN_ETHERTYPE_8100; + * + * virtchnl_vlan_offload.vport_id = vport_id or vsi_id assigned to the VF on + * initialization. + * + * The reason that VLAN TPID(s) are not being used for the + * outer_ethertype_setting and inner_ethertype_setting fields is because it's + * possible a device could support VLAN insertion and/or stripping offload on + * multiple ethertypes concurrently, so this method allows a VF to request + * multiple ethertypes in one message using the virtchnl_vlan_support + * enumeration. + * + * For example, if the PF populates the virtchnl_vlan_caps.offloads in the + * following manner the VF will be allowed to enable 0x8100 and 0x88a8 outer + * VLAN insertion and stripping simultaneously. The + * virtchnl_vlan_caps.offloads.ethertype_match field will also have to be + * populated based on what the PF can support. + * + * virtchnl_vlan_caps.offloads.stripping_support.outer = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_AND; + * + * virtchnl_vlan_caps.offloads.insertion_support.outer = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_AND; + * + * In order to enable outer VLAN stripping for 0x8100 and 0x88a8 VLANs, the VF + * would populate the virthcnl_vlan_offload_structure in the following manner + * and send the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2 message. + * + * virtchnl_vlan_offload.outer_ethertype_setting = + * VIRTHCNL_VLAN_ETHERTYPE_8100 | + * VIRTHCNL_VLAN_ETHERTYPE_88A8; + * + * virtchnl_vlan_offload.vport_id = vport_id or vsi_id assigned to the VF on + * initialization. + * + * There is also the case where a PF and the underlying hardware can support + * VLAN offloads on multiple ethertypes, but not concurrently. For example, if + * the PF populates the virtchnl_vlan_caps.offloads in the following manner the + * VF will be allowed to enable and/or disable 0x8100 XOR 0x88a8 outer VLAN + * offloads. The ethertypes must match for stripping and insertion. + * + * virtchnl_vlan_caps.offloads.stripping_support.outer = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_XOR; + * + * virtchnl_vlan_caps.offloads.insertion_support.outer = + * VIRTCHNL_VLAN_TOGGLE | + * VIRTCHNL_VLAN_ETHERTYPE_8100 | + * VIRTCHNL_VLAN_ETHERTYPE_88A8 | + * VIRTCHNL_VLAN_ETHERTYPE_XOR; + * + * virtchnl_vlan_caps.offloads.ethertype_match = + * VIRTCHNL_ETHERTYPE_STRIPPING_MATCHES_INSERTION; + * + * In order to enable outer VLAN stripping for 0x88a8 VLANs, the VF would + * populate the virtchnl_vlan_offload_structure in the following manner and send + * the VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2. Also, this will change the + * ethertype for VLAN insertion if it's enabled. So, for completeness, a + * VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 with the same ethertype should be sent. + * + * virtchnl_vlan_offload.outer_ethertype_setting = VIRTHCNL_VLAN_ETHERTYPE_88A8; + * + * virtchnl_vlan_offload.vport_id = vport_id or vsi_id assigned to the VF on + * initialization. + */ +struct virtchnl_vlan_offload { + u32 outer_ethertype_setting; + u32 inner_ethertype_setting; + u16 vport_id; + u8 pad[6]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vlan_offload); + /* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE * VF sends VSI id and flags. * PF returns status code in retval. @@ -754,6 +1106,38 @@ struct virtchnl_pkg_info { VIRTCHNL_CHECK_STRUCT_LEN(48, virtchnl_pkg_info); +/* VIRTCHNL_OP_DCF_VLAN_OFFLOAD + * DCF negotiates the VIRTCHNL_VF_OFFLOAD_VLAN_V2 capabilitiy firstly to get + * the double VLAN configuration, then DCF sends this message to configure the + * outer or inner VLAN offloads (insertion and strip) for the target VF. + */ +struct virtchnl_dcf_vlan_offload { + u16 vf_id; + u16 tpid; + u16 vlan_flags; +#define VIRTCHNL_DCF_VLAN_TYPE_S 0 +#define VIRTCHNL_DCF_VLAN_TYPE_M \ + (0x1 << VIRTCHNL_DCF_VLAN_TYPE_S) +#define VIRTCHNL_DCF_VLAN_TYPE_INNER 0x0 +#define VIRTCHNL_DCF_VLAN_TYPE_OUTER 0x1 +#define VIRTCHNL_DCF_VLAN_INSERT_MODE_S 1 +#define VIRTCHNL_DCF_VLAN_INSERT_MODE_M \ + (0x7 << VIRTCHNL_DCF_VLAN_INSERT_MODE_S) +#define VIRTCHNL_DCF_VLAN_INSERT_DISABLE 0x1 +#define VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED 0x2 +#define VIRTCHNL_DCF_VLAN_INSERT_VIA_TX_DESC 0x3 +#define VIRTCHNL_DCF_VLAN_STRIP_MODE_S 4 +#define VIRTCHNL_DCF_VLAN_STRIP_MODE_M \ + (0x7 << VIRTCHNL_DCF_VLAN_STRIP_MODE_S) +#define VIRTCHNL_DCF_VLAN_STRIP_DISABLE 0x1 +#define VIRTCHNL_DCF_VLAN_STRIP_ONLY 0x2 +#define VIRTCHNL_DCF_VLAN_STRIP_INTO_RX_DESC 0x3 + u16 vlan_id; + u16 pad[4]; +}; + +VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_dcf_vlan_offload); + struct virtchnl_supported_rxdids { u64 supported_rxdids; }; @@ -1291,6 +1675,10 @@ enum virtchnl_vector_limits { VIRTCHNL_OP_MAP_UNMAP_QUEUE_VECTOR_MAX = ((u16)(~0) - sizeof(struct virtchnl_queue_vector_maps)) / sizeof(struct virtchnl_queue_vector), + + VIRTCHNL_OP_ADD_DEL_VLAN_V2_MAX = + ((u16)(~0) - sizeof(struct virtchnl_vlan_filter_list_v2)) / + sizeof(struct virtchnl_vlan_filter), }; /** @@ -1465,6 +1853,9 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, case VIRTCHNL_OP_DEL_CLOUD_FILTER: valid_len = sizeof(struct virtchnl_filter); break; + case VIRTCHNL_OP_DCF_VLAN_OFFLOAD: + valid_len = sizeof(struct virtchnl_dcf_vlan_offload); + break; case VIRTCHNL_OP_DCF_CMD_DESC: case VIRTCHNL_OP_DCF_CMD_BUFF: /* These two opcodes are specific to handle the AdminQ command, @@ -1491,6 +1882,31 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, case VIRTCHNL_OP_QUERY_FDIR_FILTER: valid_len = sizeof(struct virtchnl_fdir_query); break; + case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS: + break; + case VIRTCHNL_OP_ADD_VLAN_V2: + case VIRTCHNL_OP_DEL_VLAN_V2: + valid_len = sizeof(struct virtchnl_vlan_filter_list_v2); + if (msglen >= valid_len) { + struct virtchnl_vlan_filter_list_v2 *vfl = + (struct virtchnl_vlan_filter_list_v2 *)msg; + + if (vfl->num_elements == 0 || vfl->num_elements > + VIRTCHNL_OP_ADD_DEL_VLAN_V2_MAX) { + err_msg_format = true; + break; + } + + valid_len += (vfl->num_elements - 1) * + sizeof(struct virtchnl_vlan_filter); + } + break; + case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2: + case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2: + case VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2: + case VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2: + valid_len = sizeof(struct virtchnl_vlan_offload); + break; case VIRTCHNL_OP_ENABLE_QUEUES_V2: case VIRTCHNL_OP_DISABLE_QUEUES_V2: valid_len = sizeof(struct virtchnl_del_ena_dis_queues); From patchwork Mon Jan 11 13:34:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Haiyue" X-Patchwork-Id: 86277 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 B80D8A09FF; Mon, 11 Jan 2021 14:50:09 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EB83F140CCD; Mon, 11 Jan 2021 14:50:04 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id A68FB140CB5 for ; Mon, 11 Jan 2021 14:50:01 +0100 (CET) IronPort-SDR: bH4RNtCtlNpIJx1aKM+cqT17k8cXWWc7X4kvNzNQz/evaLrMCNSwUx3OCgI0jB/Lv7/i1b9Rje f4dm1vR9s30g== X-IronPort-AV: E=McAfee;i="6000,8403,9860"; a="177083523" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="177083523" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 05:49:59 -0800 IronPort-SDR: OgdAYpsVS8CP0PlJL0ERlqoEoJr4iPY0+mpV4HJkl0dxp0ONM9nUqdNRNDnTobZBsaWxmKbnzW mxRLrrFTkPNw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="352607033" Received: from npg-dpdk-haiyue-3.sh.intel.com ([10.67.118.189]) by fmsmga008.fm.intel.com with ESMTP; 11 Jan 2021 05:49:57 -0800 From: Haiyue Wang To: dev@dpdk.org Cc: qiming.yang@intel.com, jingjing.wu@intel.com, qi.z.zhang@intel.com, qi.fu@intel.com, Haiyue Wang , Beilei Xing Date: Mon, 11 Jan 2021 21:34:04 +0800 Message-Id: <20210111133406.484200-3-haiyue.wang@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111133406.484200-1-haiyue.wang@intel.com> References: <20201214071155.98764-1-haiyue.wang@intel.com> <20210111133406.484200-1-haiyue.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 2/4] net/iavf: support Ethernet CRC strip disable 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" The VF will check the PF's CRC strip capability firstly, then set the 'CRC strip disable' value in the queue configuration according to the RX CRC offload setting. Signed-off-by: Haiyue Wang --- drivers/net/iavf/iavf_ethdev.c | 3 +++ drivers/net/iavf/iavf_rxtx.c | 6 +++++- drivers/net/iavf/iavf_vchnl.c | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index 7bf31d4f4..49e6dd125 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -800,6 +800,9 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) DEV_TX_OFFLOAD_MULTI_SEGS | DEV_TX_OFFLOAD_MBUF_FAST_FREE; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_CRC) + dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_KEEP_CRC; + dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_free_thresh = IAVF_DEFAULT_RX_FREE_THRESH, .rx_drop_en = 0, diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c index 21d508b3f..d53d7b984 100644 --- a/drivers/net/iavf/iavf_rxtx.c +++ b/drivers/net/iavf/iavf_rxtx.c @@ -550,11 +550,15 @@ iavf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, rxq->rx_free_thresh = rx_free_thresh; rxq->queue_id = queue_idx; rxq->port_id = dev->data->port_id; - rxq->crc_len = 0; /* crc stripping by default */ rxq->rx_deferred_start = rx_conf->rx_deferred_start; rxq->rx_hdr_len = 0; rxq->vsi = vsi; + if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC) + rxq->crc_len = RTE_ETHER_CRC_LEN; + else + rxq->crc_len = 0; + len = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM; rxq->rx_buf_len = RTE_ALIGN(len, (1 << IAVF_RXQ_CTX_DBUFF_SHIFT)); diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c index 25d5cdaf5..c33194cdc 100644 --- a/drivers/net/iavf/iavf_vchnl.c +++ b/drivers/net/iavf/iavf_vchnl.c @@ -458,6 +458,7 @@ iavf_get_vf_resource(struct iavf_adapter *adapter) VIRTCHNL_VF_OFFLOAD_FDIR_PF | VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF | VIRTCHNL_VF_OFFLOAD_REQ_QUEUES | + VIRTCHNL_VF_OFFLOAD_CRC | VIRTCHNL_VF_LARGE_NUM_QPAIRS; args.in_args = (uint8_t *)∩︀ @@ -853,7 +854,7 @@ iavf_configure_queues(struct iavf_adapter *adapter, vc_qp->rxq.ring_len = rxq[i]->nb_rx_desc; vc_qp->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr; vc_qp->rxq.databuffer_size = rxq[i]->rx_buf_len; - + vc_qp->rxq.crc_disable = rxq[i]->crc_len != 0 ? 1 : 0; #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC && From patchwork Mon Jan 11 13:34:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Haiyue" X-Patchwork-Id: 86279 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 15A5CA09FF; Mon, 11 Jan 2021 14:50:27 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5A99C140CE7; Mon, 11 Jan 2021 14:50:07 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 71638140CB5 for ; Mon, 11 Jan 2021 14:50:02 +0100 (CET) IronPort-SDR: 4DSOK7kNquWqwGAoRVvg8vFZaopYCCIrIu0ODsdoWoHncgj6q/fnjOPCkUPlTxTd4hf9s3O/9h KS7vQz2kwWvA== X-IronPort-AV: E=McAfee;i="6000,8403,9860"; a="177083531" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="177083531" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 05:50:01 -0800 IronPort-SDR: 4Tt4+kF6H4k1dbkeORWEJKtQQVO6UmlJMijHoo+095+Z7V9Y2+zDF7lB/Rs6wp1ZH+ThH6d/SR cqkbdBCp06VQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="352607058" Received: from npg-dpdk-haiyue-3.sh.intel.com ([10.67.118.189]) by fmsmga008.fm.intel.com with ESMTP; 11 Jan 2021 05:49:59 -0800 From: Haiyue Wang To: dev@dpdk.org Cc: qiming.yang@intel.com, jingjing.wu@intel.com, qi.z.zhang@intel.com, qi.fu@intel.com, Haiyue Wang Date: Mon, 11 Jan 2021 21:34:05 +0800 Message-Id: <20210111133406.484200-4-haiyue.wang@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111133406.484200-1-haiyue.wang@intel.com> References: <20201214071155.98764-1-haiyue.wang@intel.com> <20210111133406.484200-1-haiyue.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 3/4] net/ice: add the DCF VLAN handling 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" Add the DCF port representor infrastructure for the VFs of DCF attached PF. Then the standard ethdev API like VLAN can be used to configure the VFs. Signed-off-by: Qiming Yang Signed-off-by: Haiyue Wang --- drivers/net/ice/ice_dcf.c | 1 + drivers/net/ice/ice_dcf_ethdev.c | 91 +++++- drivers/net/ice/ice_dcf_ethdev.h | 24 ++ drivers/net/ice/ice_dcf_vf_representor.c | 334 +++++++++++++++++++++++ drivers/net/ice/meson.build | 1 + 5 files changed, 444 insertions(+), 7 deletions(-) create mode 100644 drivers/net/ice/ice_dcf_vf_representor.c diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c index 44dbd3bb8..4a9af3292 100644 --- a/drivers/net/ice/ice_dcf.c +++ b/drivers/net/ice/ice_dcf.c @@ -234,6 +234,7 @@ ice_dcf_get_vf_resource(struct ice_dcf_hw *hw) caps = VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | VIRTCHNL_VF_OFFLOAD_RX_POLLING | VIRTCHNL_VF_CAP_ADV_LINK_SPEED | VIRTCHNL_VF_CAP_DCF | + VIRTCHNL_VF_OFFLOAD_VLAN_V2 | VF_BASE_MODE_OFFLOADS | VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC; err = ice_dcf_send_cmd_req_no_irq(hw, VIRTCHNL_OP_GET_VF_RESOURCES, diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c index b0b2ecb0d..a9e78064d 100644 --- a/drivers/net/ice/ice_dcf_ethdev.c +++ b/drivers/net/ice/ice_dcf_ethdev.c @@ -970,20 +970,97 @@ ice_dcf_cap_selected(struct rte_devargs *devargs) return ret; } -static int eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, - struct rte_pci_device *pci_dev) +static int +eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, + struct rte_pci_device *pci_dev) { + struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; + struct ice_dcf_vf_repr_param repr_param; + char repr_name[RTE_ETH_NAME_MAX_LEN]; + struct ice_dcf_adapter *dcf_adapter; + struct rte_eth_dev *dcf_ethdev; + uint16_t dcf_vsi_id; + int i, ret; + if (!ice_dcf_cap_selected(pci_dev->device.devargs)) return 1; - return rte_eth_dev_pci_generic_probe(pci_dev, - sizeof(struct ice_dcf_adapter), - ice_dcf_dev_init); + ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, ð_da); + if (ret) + return ret; + + ret = rte_eth_dev_pci_generic_probe(pci_dev, + sizeof(struct ice_dcf_adapter), + ice_dcf_dev_init); + if (ret || !eth_da.nb_representor_ports) + return ret; + + dcf_ethdev = rte_eth_dev_allocated(pci_dev->device.name); + if (dcf_ethdev == NULL) + return -ENODEV; + + dcf_adapter = dcf_ethdev->data->dev_private; + + if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs || + eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) { + PMD_DRV_LOG(ERR, "the number of port representors is too large: %u", + eth_da.nb_representor_ports); + return -EINVAL; + } + + dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID; + + repr_param.adapter = dcf_adapter; + repr_param.switch_domain_id = 0; + + for (i = 0; i < eth_da.nb_representor_ports; i++) { + uint16_t vf_id = eth_da.representor_ports[i]; + + if (vf_id >= dcf_adapter->real_hw.num_vfs) { + PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)", + vf_id, dcf_adapter->real_hw.num_vfs - 1); + ret = -EINVAL; + break; + } + + if (dcf_adapter->real_hw.vf_vsi_map[vf_id] == dcf_vsi_id) { + PMD_DRV_LOG(ERR, "VF ID %u is DCF's ID.\n", vf_id); + ret = -EINVAL; + break; + } + + repr_param.vf_id = vf_id; + snprintf(repr_name, sizeof(repr_name), "net_%s_representor_%u", + pci_dev->device.name, vf_id); + ret = rte_eth_dev_create(&pci_dev->device, repr_name, + sizeof(struct ice_dcf_vf_repr), + NULL, NULL, ice_dcf_vf_repr_init, + &repr_param); + if (ret) { + PMD_DRV_LOG(ERR, "failed to create DCF VF representor %s", + repr_name); + break; + } + } + + return ret; } -static int eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) +static int +eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) { - return rte_eth_dev_pci_generic_remove(pci_dev, ice_dcf_dev_uninit); + struct rte_eth_dev *eth_dev; + + eth_dev = rte_eth_dev_allocated(pci_dev->device.name); + if (!eth_dev) + return 0; + + if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) + return rte_eth_dev_pci_generic_remove(pci_dev, + ice_dcf_vf_repr_uninit); + else + return rte_eth_dev_pci_generic_remove(pci_dev, + ice_dcf_dev_uninit); } static const struct rte_pci_id pci_id_ice_dcf_map[] = { diff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h index b54528bea..7695815e1 100644 --- a/drivers/net/ice/ice_dcf_ethdev.h +++ b/drivers/net/ice/ice_dcf_ethdev.h @@ -22,9 +22,33 @@ struct ice_dcf_adapter { struct ice_dcf_hw real_hw; }; +struct ice_dcf_vf_repr_param { + struct ice_dcf_adapter *adapter; + uint16_t switch_domain_id; + uint16_t vf_id; +}; + +struct ice_dcf_vlan { + uint16_t tpid; + uint16_t vid; +}; + +struct ice_dcf_vf_repr { + struct ice_dcf_adapter *dcf_adapter; + struct rte_ether_addr mac_addr; + uint16_t switch_domain_id; + uint16_t vf_id; + + bool port_vlan_ena; + struct ice_dcf_vlan port_vlan_info; +}; + void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw, uint8_t *msg, uint16_t msglen); int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev); void ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev); +int ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param); +int ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev); + #endif /* _ICE_DCF_ETHDEV_H_ */ diff --git a/drivers/net/ice/ice_dcf_vf_representor.c b/drivers/net/ice/ice_dcf_vf_representor.c new file mode 100644 index 000000000..09ca4df5a --- /dev/null +++ b/drivers/net/ice/ice_dcf_vf_representor.c @@ -0,0 +1,334 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#include +#include + +#include + +#include "ice_dcf_ethdev.h" +#include "ice_rxtx.h" + +static uint16_t +ice_dcf_vf_repr_rx_burst(__rte_unused void *rxq, + __rte_unused struct rte_mbuf **rx_pkts, + __rte_unused uint16_t nb_pkts) +{ + return 0; +} + +static uint16_t +ice_dcf_vf_repr_tx_burst(__rte_unused void *txq, + __rte_unused struct rte_mbuf **tx_pkts, + __rte_unused uint16_t nb_pkts) +{ + return 0; +} + +static int +ice_dcf_vf_repr_dev_configure(__rte_unused struct rte_eth_dev *dev) +{ + return 0; +} + +static int +ice_dcf_vf_repr_dev_start(struct rte_eth_dev *dev) +{ + dev->data->dev_link.link_status = ETH_LINK_UP; + + return 0; +} + +static int +ice_dcf_vf_repr_dev_stop(struct rte_eth_dev *dev) +{ + dev->data->dev_link.link_status = ETH_LINK_DOWN; + + return 0; +} + +static int +ice_dcf_vf_repr_dev_close(struct rte_eth_dev *dev) +{ + return ice_dcf_vf_repr_uninit(dev); +} + +static int +ice_dcf_vf_repr_rx_queue_setup(__rte_unused struct rte_eth_dev *dev, + __rte_unused uint16_t queue_id, + __rte_unused uint16_t nb_desc, + __rte_unused unsigned int socket_id, + __rte_unused const struct rte_eth_rxconf *conf, + __rte_unused struct rte_mempool *pool) +{ + return 0; +} + +static int +ice_dcf_vf_repr_tx_queue_setup(__rte_unused struct rte_eth_dev *dev, + __rte_unused uint16_t queue_id, + __rte_unused uint16_t nb_desc, + __rte_unused unsigned int socket_id, + __rte_unused const struct rte_eth_txconf *conf) +{ + return 0; +} + +static int +ice_dcf_vf_repr_promiscuous_enable(__rte_unused struct rte_eth_dev *ethdev) +{ + return 0; +} + +static int +ice_dcf_vf_repr_promiscuous_disable(__rte_unused struct rte_eth_dev *ethdev) +{ + return 0; +} + +static int +ice_dcf_vf_repr_allmulticast_enable(__rte_unused struct rte_eth_dev *dev) +{ + return 0; +} + +static int +ice_dcf_vf_repr_allmulticast_disable(__rte_unused struct rte_eth_dev *dev) +{ + return 0; +} + +static int +ice_dcf_vf_repr_link_update(__rte_unused struct rte_eth_dev *ethdev, + __rte_unused int wait_to_complete) +{ + return 0; +} + +static int +ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) +{ + struct ice_dcf_vf_repr *repr = dev->data->dev_private; + struct ice_dcf_hw *dcf_hw = + &repr->dcf_adapter->real_hw; + + dev_info->device = dev->device; + dev_info->max_mac_addrs = 1; + dev_info->max_rx_queues = dcf_hw->vsi_res->num_queue_pairs; + dev_info->max_tx_queues = dcf_hw->vsi_res->num_queue_pairs; + dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN; + dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX; + dev_info->hash_key_size = dcf_hw->vf_res->rss_key_size; + dev_info->reta_size = dcf_hw->vf_res->rss_lut_size; + dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL; + + dev_info->rx_offload_capa = + DEV_RX_OFFLOAD_VLAN_STRIP | + DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM | + DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_RX_OFFLOAD_SCATTER | + DEV_RX_OFFLOAD_JUMBO_FRAME | + DEV_RX_OFFLOAD_VLAN_FILTER | + DEV_RX_OFFLOAD_VLAN_EXTEND | + DEV_RX_OFFLOAD_RSS_HASH; + dev_info->tx_offload_capa = + DEV_TX_OFFLOAD_VLAN_INSERT | + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_SCTP_CKSUM | + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_TX_OFFLOAD_TCP_TSO | + DEV_TX_OFFLOAD_VXLAN_TNL_TSO | + DEV_TX_OFFLOAD_GRE_TNL_TSO | + DEV_TX_OFFLOAD_IPIP_TNL_TSO | + DEV_TX_OFFLOAD_GENEVE_TNL_TSO | + DEV_TX_OFFLOAD_MULTI_SEGS; + + dev_info->default_rxconf = (struct rte_eth_rxconf) { + .rx_thresh = { + .pthresh = ICE_DEFAULT_RX_PTHRESH, + .hthresh = ICE_DEFAULT_RX_HTHRESH, + .wthresh = ICE_DEFAULT_RX_WTHRESH, + }, + .rx_free_thresh = ICE_DEFAULT_RX_FREE_THRESH, + .rx_drop_en = 0, + .offloads = 0, + }; + + dev_info->default_txconf = (struct rte_eth_txconf) { + .tx_thresh = { + .pthresh = ICE_DEFAULT_TX_PTHRESH, + .hthresh = ICE_DEFAULT_TX_HTHRESH, + .wthresh = ICE_DEFAULT_TX_WTHRESH, + }, + .tx_free_thresh = ICE_DEFAULT_TX_FREE_THRESH, + .tx_rs_thresh = ICE_DEFAULT_TX_RSBIT_THRESH, + .offloads = 0, + }; + + dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = ICE_MAX_RING_DESC, + .nb_min = ICE_MIN_RING_DESC, + .nb_align = ICE_ALIGN_RING_DESC, + }; + + dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { + .nb_max = ICE_MAX_RING_DESC, + .nb_min = ICE_MIN_RING_DESC, + .nb_align = ICE_ALIGN_RING_DESC, + }; + + dev_info->switch_info.name = dcf_hw->eth_dev->device->name; + dev_info->switch_info.domain_id = repr->switch_domain_id; + dev_info->switch_info.port_id = repr->vf_id; + + return 0; +} + +static int +ice_dcf_vlan_offload_config(struct ice_dcf_vf_repr *repr, + struct virtchnl_dcf_vlan_offload *vlan_offload) +{ + struct dcf_virtchnl_cmd args; + + memset(&args, 0, sizeof(args)); + args.v_op = VIRTCHNL_OP_DCF_VLAN_OFFLOAD; + args.req_msg = (uint8_t *)vlan_offload; + args.req_msglen = sizeof(*vlan_offload); + + return ice_dcf_execute_virtchnl_cmd(&repr->dcf_adapter->real_hw, &args); +} + +static __rte_always_inline bool +ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr) +{ + return !!(repr->dcf_adapter->real_hw.vf_res->vf_cap_flags & + VIRTCHNL_VF_OFFLOAD_VLAN_V2); +} + +static int +ice_dcf_vf_repr_vlan_pvid_set(struct rte_eth_dev *dev, + uint16_t pvid, int on) +{ + struct ice_dcf_vf_repr *repr = dev->data->dev_private; + struct virtchnl_dcf_vlan_offload vlan_offload; + int err; + + if (!ice_dcf_vlan_offload_ena(repr)) + return -ENOTSUP; + + if (on && (pvid == 0 || pvid > RTE_ETHER_MAX_VLAN_ID)) + return -EINVAL; + + memset(&vlan_offload, 0, sizeof(vlan_offload)); + + vlan_offload.vf_id = repr->vf_id; + vlan_offload.tpid = repr->port_vlan_info.tpid; + vlan_offload.vlan_flags = (VIRTCHNL_DCF_VLAN_TYPE_OUTER << + VIRTCHNL_DCF_VLAN_TYPE_S) | + (VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED << + VIRTCHNL_DCF_VLAN_INSERT_MODE_S); + vlan_offload.vlan_id = on ? pvid : 0; + + err = ice_dcf_vlan_offload_config(repr, &vlan_offload); + if (!err) { + if (on) { + repr->port_vlan_ena = true; + repr->port_vlan_info.vid = pvid; + } else { + repr->port_vlan_ena = false; + } + } + + return err; +} + +static int +ice_dcf_vf_repr_vlan_tpid_set(struct rte_eth_dev *dev, + enum rte_vlan_type vlan_type, uint16_t tpid) +{ + struct ice_dcf_vf_repr *repr = dev->data->dev_private; + int err = 0; + + if (!ice_dcf_vlan_offload_ena(repr)) + return -ENOTSUP; + + if (vlan_type != ETH_VLAN_TYPE_OUTER) { + PMD_DRV_LOG(ERR, + "Can accelerate only outer VLAN in QinQ\n"); + return -EINVAL; + } + + if (tpid != RTE_ETHER_TYPE_QINQ && + tpid != RTE_ETHER_TYPE_VLAN && + tpid != RTE_ETHER_TYPE_QINQ1) { + PMD_DRV_LOG(ERR, + "Invalid TPID: 0x%04x\n", tpid); + return -EINVAL; + } + + repr->port_vlan_info.tpid = tpid; + + if (repr->port_vlan_ena) + err = ice_dcf_vf_repr_vlan_pvid_set(dev, + repr->port_vlan_info.vid, + true); + return err; +} + +static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = { + .dev_configure = ice_dcf_vf_repr_dev_configure, + .dev_start = ice_dcf_vf_repr_dev_start, + .dev_stop = ice_dcf_vf_repr_dev_stop, + .dev_close = ice_dcf_vf_repr_dev_close, + .dev_infos_get = ice_dcf_vf_repr_dev_info_get, + .rx_queue_setup = ice_dcf_vf_repr_rx_queue_setup, + .tx_queue_setup = ice_dcf_vf_repr_tx_queue_setup, + .promiscuous_enable = ice_dcf_vf_repr_promiscuous_enable, + .promiscuous_disable = ice_dcf_vf_repr_promiscuous_disable, + .allmulticast_enable = ice_dcf_vf_repr_allmulticast_enable, + .allmulticast_disable = ice_dcf_vf_repr_allmulticast_disable, + .link_update = ice_dcf_vf_repr_link_update, + .vlan_pvid_set = ice_dcf_vf_repr_vlan_pvid_set, + .vlan_tpid_set = ice_dcf_vf_repr_vlan_tpid_set, +}; + +int +ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param) +{ + struct ice_dcf_vf_repr *repr = ethdev->data->dev_private; + struct ice_dcf_vf_repr_param *param = init_param; + + repr->dcf_adapter = param->adapter; + repr->switch_domain_id = param->switch_domain_id; + repr->vf_id = param->vf_id; + repr->port_vlan_ena = false; + repr->port_vlan_info.tpid = RTE_ETHER_TYPE_VLAN; + + ethdev->dev_ops = &ice_dcf_vf_repr_dev_ops; + + ethdev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst; + ethdev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst; + + ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR; + ethdev->data->representor_id = repr->vf_id; + + ethdev->data->mac_addrs = &repr->mac_addr; + + rte_eth_random_addr(repr->mac_addr.addr_bytes); + + return 0; +} + +int +ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev) +{ + ethdev->data->mac_addrs = NULL; + + return 0; +} diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build index 7b291269d..d58936089 100644 --- a/drivers/net/ice/meson.build +++ b/drivers/net/ice/meson.build @@ -61,6 +61,7 @@ if arch_subdir == 'x86' endif sources += files('ice_dcf.c', + 'ice_dcf_vf_representor.c', 'ice_dcf_ethdev.c', 'ice_dcf_parent.c') From patchwork Mon Jan 11 13:34:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Haiyue" X-Patchwork-Id: 86280 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 52484A09FF; Mon, 11 Jan 2021 14:50:39 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F1F03140CF4; Mon, 11 Jan 2021 14:50:08 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 94212140CCB for ; Mon, 11 Jan 2021 14:50:04 +0100 (CET) IronPort-SDR: xHx3tfuc293hHtV0ZeDrUDnLe+B0yheAXt/VOhM4G06o6Qo6d7Kl6NuIGwxruFW9Pgsupk+T/u BVS/Kj5aU0AA== X-IronPort-AV: E=McAfee;i="6000,8403,9860"; a="177083540" X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="177083540" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jan 2021 05:50:03 -0800 IronPort-SDR: g3OmzmIFTWv/3uHspbuhcYlWaJbTycuInQFlHjli28j64VFEOs8yAnwzotNwoIDHRaDCcOh22o s/2LyS61emHg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,338,1602572400"; d="scan'208";a="352607083" Received: from npg-dpdk-haiyue-3.sh.intel.com ([10.67.118.189]) by fmsmga008.fm.intel.com with ESMTP; 11 Jan 2021 05:50:01 -0800 From: Haiyue Wang To: dev@dpdk.org Cc: qiming.yang@intel.com, jingjing.wu@intel.com, qi.z.zhang@intel.com, qi.fu@intel.com, Haiyue Wang , Beilei Xing Date: Mon, 11 Jan 2021 21:34:06 +0800 Message-Id: <20210111133406.484200-5-haiyue.wang@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111133406.484200-1-haiyue.wang@intel.com> References: <20201214071155.98764-1-haiyue.wang@intel.com> <20210111133406.484200-1-haiyue.wang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v5 4/4] net/iavf: implement new VLAN capability handling 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" The new VLAN virtchnl opcodes introduce new capabilities like VLAN filtering, stripping and insertion. The VF needs to query the VLAN capabilities based on current device configuration firstly. Signed-off-by: Qiming Yang Signed-off-by: Haiyue Wang --- drivers/net/iavf/iavf.h | 6 ++ drivers/net/iavf/iavf_ethdev.c | 117 ++++++++++++++++++++++++++++++-- drivers/net/iavf/iavf_vchnl.c | 120 +++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 7 deletions(-) diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h index 9754273b2..af11268fe 100644 --- a/drivers/net/iavf/iavf.h +++ b/drivers/net/iavf/iavf.h @@ -139,6 +139,7 @@ struct iavf_info { struct virtchnl_version_info virtchnl_version; struct virtchnl_vf_resource *vf_res; /* VF resource */ struct virtchnl_vsi_resource *vsi_res; /* LAN VSI */ + struct virtchnl_vlan_caps vlan_v2_caps; uint64_t supported_rxdid; uint8_t *proto_xtr; /* proto xtr type for all queues */ volatile enum virtchnl_ops pend_cmd; /* pending command not finished */ @@ -310,6 +311,11 @@ int iavf_configure_rss_key(struct iavf_adapter *adapter); int iavf_configure_queues(struct iavf_adapter *adapter, uint16_t num_queue_pairs, uint16_t index); int iavf_get_supported_rxdid(struct iavf_adapter *adapter); +int iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable); +int iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable); +int iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, + bool add); +int iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter); int iavf_config_irq_map(struct iavf_adapter *adapter); int iavf_config_irq_map_lv(struct iavf_adapter *adapter, uint16_t num, uint16_t index); diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index 49e6dd125..e22c62ed0 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -326,13 +326,52 @@ iavf_queues_req_reset(struct rte_eth_dev *dev, uint16_t num) return 0; } +static int +iavf_dev_vlan_insert_set(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); + bool enable; + + if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)) + return 0; + + enable = !!(dev->data->dev_conf.txmode.offloads & + DEV_TX_OFFLOAD_VLAN_INSERT); + iavf_config_vlan_insert_v2(adapter, enable); + + return 0; +} + +static int +iavf_dev_init_vlan(struct rte_eth_dev *dev) +{ + int err; + + err = iavf_dev_vlan_offload_set(dev, + ETH_VLAN_STRIP_MASK | + ETH_QINQ_STRIP_MASK | + ETH_VLAN_FILTER_MASK | + ETH_VLAN_EXTEND_MASK); + if (err) { + PMD_DRV_LOG(ERR, "Failed to update vlan offload"); + return err; + } + + err = iavf_dev_vlan_insert_set(dev); + if (err) + PMD_DRV_LOG(ERR, "Failed to update vlan insertion"); + + return err; +} + static int iavf_dev_configure(struct rte_eth_dev *dev) { struct iavf_adapter *ad = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad); - struct rte_eth_conf *dev_conf = &dev->data->dev_conf; uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues, dev->data->nb_tx_queues); int ret; @@ -389,12 +428,10 @@ iavf_dev_configure(struct rte_eth_dev *dev) vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT; } - /* Vlan stripping setting */ - if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) { - if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP) - iavf_enable_vlan_strip(ad); - else - iavf_disable_vlan_strip(ad); + ret = iavf_dev_init_vlan(dev); + if (ret) { + PMD_DRV_LOG(ERR, "configure VLAN failed: %d", ret); + return -1; } if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) { @@ -784,6 +821,7 @@ iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) DEV_RX_OFFLOAD_JUMBO_FRAME | DEV_RX_OFFLOAD_VLAN_FILTER | DEV_RX_OFFLOAD_RSS_HASH; + dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT | @@ -997,6 +1035,13 @@ iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); int err; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { + err = iavf_add_del_vlan_v2(adapter, vlan_id, on); + if (err) + return -EIO; + return 0; + } + if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) return -ENOTSUP; @@ -1006,6 +1051,54 @@ iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) return 0; } +static void +iavf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable) +{ + struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf; + struct iavf_adapter *adapter = + IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + 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) + iavf_add_del_vlan_v2(adapter, + 64 * i + j, enable); + } + } +} + +static int +iavf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask) +{ + struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; + struct iavf_adapter *adapter = + IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + bool enable; + int err; + + if (mask & ETH_VLAN_FILTER_MASK) { + enable = !!(rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER); + + iavf_iterate_vlan_filters_v2(dev, enable); + } + + if (mask & ETH_VLAN_STRIP_MASK) { + enable = !!(rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP); + + err = iavf_config_vlan_strip_v2(adapter, enable); + if (err) + return -EIO; + } + + return 0; +} + static int iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) { @@ -1015,6 +1108,9 @@ iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask) struct rte_eth_conf *dev_conf = &dev->data->dev_conf; int err; + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) + return iavf_dev_vlan_offload_set_v2(dev, mask); + if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) return -ENOTSUP; @@ -1898,6 +1994,13 @@ iavf_init_vf(struct rte_eth_dev *dev) } } + if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) { + if (iavf_get_vlan_offload_caps_v2(adapter) != 0) { + PMD_INIT_LOG(ERR, "failed to do get VLAN offload v2 capabilities"); + goto err_rss; + } + } + iavf_init_proto_xtr(dev); return 0; diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c index c33194cdc..890700d57 100644 --- a/drivers/net/iavf/iavf_vchnl.c +++ b/drivers/net/iavf/iavf_vchnl.c @@ -174,6 +174,7 @@ iavf_execute_vf_cmd(struct iavf_adapter *adapter, struct iavf_cmd_info *args) case VIRTCHNL_OP_VERSION: case VIRTCHNL_OP_GET_VF_RESOURCES: case VIRTCHNL_OP_GET_SUPPORTED_RXDIDS: + case VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS: /* for init virtchnl ops, need to poll the response */ do { result = iavf_read_msg_from_pf(adapter, args->out_size, @@ -459,6 +460,7 @@ iavf_get_vf_resource(struct iavf_adapter *adapter) VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF | VIRTCHNL_VF_OFFLOAD_REQ_QUEUES | VIRTCHNL_VF_OFFLOAD_CRC | + VIRTCHNL_VF_OFFLOAD_VLAN_V2 | VIRTCHNL_VF_LARGE_NUM_QPAIRS; args.in_args = (uint8_t *)∩︀ @@ -522,6 +524,124 @@ iavf_get_supported_rxdid(struct iavf_adapter *adapter) return 0; } +int +iavf_config_vlan_strip_v2(struct iavf_adapter *adapter, bool enable) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_offload vlan_strip; + struct iavf_cmd_info args; + int ret; + + if (!(vf->vlan_v2_caps.offloads.stripping_support.inner & + VIRTCHNL_VLAN_ETHERTYPE_8100)) + return -ENOTSUP; + + memset(&vlan_strip, 0, sizeof(vlan_strip)); + vlan_strip.vport_id = vf->vsi_res->vsi_id; + vlan_strip.inner_ethertype_setting = VIRTCHNL_VLAN_ETHERTYPE_8100; + + args.ops = enable ? 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", + enable ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2" : + "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2"); + + return ret; +} + +int +iavf_config_vlan_insert_v2(struct iavf_adapter *adapter, bool enable) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_offload vlan_insert; + struct iavf_cmd_info args; + int ret; + + if (!(vf->vlan_v2_caps.offloads.insertion_support.inner & + VIRTCHNL_VLAN_ETHERTYPE_8100)) + return -ENOTSUP; + + memset(&vlan_insert, 0, sizeof(vlan_insert)); + vlan_insert.vport_id = vf->vsi_res->vsi_id; + vlan_insert.inner_ethertype_setting = VIRTCHNL_VLAN_ETHERTYPE_8100; + + args.ops = enable ? VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2 : + VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2; + args.in_args = (uint8_t *)&vlan_insert; + args.in_args_size = sizeof(vlan_insert); + 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", + enable ? "VIRTCHNL_OP_ENABLE_VLAN_INSERTION_V2" : + "VIRTCHNL_OP_DISABLE_VLAN_INSERTION_V2"); + + return ret; +} + +int +iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid, bool add) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct virtchnl_vlan_filter_list_v2 vlan_filter; + struct iavf_cmd_info args; + int err; + + if (!(vf->vlan_v2_caps.filtering.filtering_support.inner & + VIRTCHNL_VLAN_ETHERTYPE_8100)) + return -ENOTSUP; + + memset(&vlan_filter, 0, sizeof(vlan_filter)); + vlan_filter.vport_id = vf->vsi_res->vsi_id; + vlan_filter.num_elements = 1; + vlan_filter.filters[0].inner.tpid = RTE_ETHER_TYPE_VLAN; + vlan_filter.filters[0].inner.tci = vlanid; + + 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_V2" : "OP_DEL_VLAN_V2"); + + return err; +} + +int +iavf_get_vlan_offload_caps_v2(struct iavf_adapter *adapter) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + struct iavf_cmd_info args; + int ret; + + 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 VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS"); + return ret; + } + + rte_memcpy(&vf->vlan_v2_caps, vf->aq_resp, sizeof(vf->vlan_v2_caps)); + + return 0; +} + int iavf_enable_queues(struct iavf_adapter *adapter) {