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 7487FA054D; Thu, 9 Jun 2022 05:27:25 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 65A5D406B4; Thu, 9 Jun 2022 05:27:25 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id C997040220 for ; Thu, 9 Jun 2022 05:27:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1654745243; x=1686281243; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3Ovx0z9wWKm7JdVfNpsqMqV0U+INLC2avomm1Ecx3no=; b=ajLNH+zOPqLlZABdsSpi65NYG4X1zj5OnaTEqC7sZNwewGdj8yZ3mcQK oBiTGBfb56RAq5qSn8XO9Iw3gY8OkO0apc0gd/OjbZ0I/vybMDR/twow6 nH6HNmGMCzQItBUcr/ro+5YVyGBPZxtwiWgfJ2c34hgQTHdLue4lX94JM IUH0fhh3q26qXlaGmdCqrgy2ZxhyAT20AFU1ufP2FmAo+EsfUzKxvS1sF i1jg/byou7ypojsA4LjUhdHuowbGKtJOIGB0qiqZUR67XnAsND7LAPnNW RmA8RKxA4RGnmj9bWwN0JEUiEmIRUv4J7Ccd/5GphHwpxwX+0OToNUwRI w==; X-IronPort-AV: E=McAfee;i="6400,9594,10372"; a="341219610" X-IronPort-AV: E=Sophos;i="5.91,287,1647327600"; d="scan'208";a="341219610" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jun 2022 20:27:22 -0700 X-IronPort-AV: E=Sophos;i="5.91,287,1647327600"; d="scan'208";a="637223529" Received: from intel-cd-odc-kevin.cd.intel.com ([10.240.178.191]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jun 2022 20:27:18 -0700 From: Kevin Liu To: dev@dpdk.org Cc: Yuying.Zhang@intel.com, beilei.xing@intel.com, stevex.yang@intel.com, Robin Zhang , Kevin Liu Subject: [PATCH v3] net/i40e: add outer VLAN processing Date: Thu, 9 Jun 2022 11:26:14 +0000 Message-Id: <20220609112614.193699-1-kevinx.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220519061846.30830-1-robinx.zhang@intel.com> References: <20220519061846.30830-1-robinx.zhang@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: Robin Zhang Outer VLAN processing is supported after firmware v8.4, kernel driver also change the default behavior to support this feature. To align with kernel driver, add support for outer VLAN processing in DPDK. But it is forbidden for firmware to change the Inner/Outer VLAN configuration while there are MAC/VLAN filters in the switch table. Therefore, we need to clear the MAC table before setting config, and then restore the MAC table after setting. This will not impact on an old firmware. Signed-off-by: Robin Zhang Signed-off-by: Kevin Liu --- drivers/net/i40e/i40e_ethdev.c | 76 +++++++++++++++++++++++++++++++--- drivers/net/i40e/i40e_ethdev.h | 3 ++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 755786dc10..12c5af7919 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -3909,6 +3909,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); int qinq = dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND; + u16 sw_flags = 0, valid_flags = 0; int ret = 0; if ((vlan_type != RTE_ETH_VLAN_TYPE_INNER && @@ -3927,15 +3928,34 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev, /* 802.1ad frames ability is added in NVM API 1.7*/ if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) { if (qinq) { + if (pf->is_outer_vlan_processing) { + sw_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; + valid_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; + } if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) hw->first_tag = rte_cpu_to_le_16(tpid); else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER) hw->second_tag = rte_cpu_to_le_16(tpid); } else { - if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) - hw->second_tag = rte_cpu_to_le_16(tpid); + /*When FW > 8.3, the tpid must be set to QinQ to close extend*/ + if (tpid == RTE_ETHER_TYPE_QINQ) { + if (pf->is_outer_vlan_processing) { + sw_flags = 0; + valid_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN; + } + if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) { + if (pf->is_outer_vlan_processing) + hw->first_tag = rte_cpu_to_le_16(tpid); + else + hw->second_tag = rte_cpu_to_le_16(tpid); + } + } else { + if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER) + hw->second_tag = rte_cpu_to_le_16(tpid); + } } - ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL); + ret = i40e_aq_set_switch_config(hw, sw_flags, + valid_flags, 0, NULL); if (ret != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "Set switch config failed aq_err: %d", @@ -3987,8 +4007,12 @@ static int i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_mac_filter_info *mac_filter; struct i40e_vsi *vsi = pf->main_vsi; struct rte_eth_rxmode *rxmode; + struct i40e_mac_filter *f; + int i, num; + void *temp; rxmode = &dev->data->dev_conf.rxmode; if (mask & RTE_ETH_VLAN_FILTER_MASK) { @@ -4007,6 +4031,30 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) } if (mask & RTE_ETH_VLAN_EXTEND_MASK) { + i = 0; + num = vsi->mac_num; + mac_filter = rte_zmalloc("mac_filter_info_data", + num * sizeof(*mac_filter), 0); + if (mac_filter == NULL) { + PMD_DRV_LOG(ERR, "failed to allocate memory"); + return I40E_ERR_NO_MEMORY; + } + + /** + * Outer VLAN processing is supported after firmware v8.4, kernel driver + * also change the default behavior to support this feature. To align with + * kernel driver, set switch config in 'i40e_vlan_tpie_set' to support for + * outer VLAN processing. But it is forbidden for firmware to change the + * Inner/Outer VLAN configuration while there are MAC/VLAN filters in the + * switch table. Therefore, we need to clear the MAC table before setting + * config, and then restore the MAC table after setting. This feature is + * recommended to be used in firmware v8.6. + **/ + /* Remove all existing mac */ + RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) { + mac_filter[i] = f->mac_info; + i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr); + } if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) { i40e_vsi_config_double_vlan(vsi, TRUE); /* Set global registers with default ethertype. */ @@ -4014,9 +4062,16 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) RTE_ETHER_TYPE_VLAN); i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_INNER, RTE_ETHER_TYPE_VLAN); - } - else + } else { + if (pf->is_outer_vlan_processing) + i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_OUTER, + RTE_ETHER_TYPE_QINQ); i40e_vsi_config_double_vlan(vsi, FALSE); + } + /* Restore all mac */ + for (i = 0; i < num; i++) + i40e_vsi_add_mac(vsi, &mac_filter[i]); + rte_free(mac_filter); } if (mask & RTE_ETH_QINQ_STRIP_MASK) { @@ -4846,6 +4901,17 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev) return -EINVAL; } + /** + * Enable outer VLAN processing if firmware version is greater + * than v8.3 + */ + if (hw->aq.fw_maj_ver > 8 || + (hw->aq.fw_maj_ver == 8 && hw->aq.fw_min_ver > 3)) { + pf->is_outer_vlan_processing = true; + } else { + pf->is_outer_vlan_processing = false; + } + return 0; } diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index a1ebdc093c..531ada447d 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -1188,6 +1188,9 @@ struct i40e_pf { /* Switch Domain Id */ uint16_t switch_domain_id; + /* The enable flag for outer VLAN processing */ + bool is_outer_vlan_processing; + struct i40e_vf_msg_cfg vf_msg_cfg; uint64_t prev_rx_bytes; uint64_t prev_tx_bytes; -- 2.34.1