<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:DengXian;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"Microsoft YaHei";
        panose-1:2 11 5 3 2 2 4 2 2 4;}
@font-face
        {font-family:"\@Microsoft YaHei";}
@font-face
        {font-family:"\@DengXian";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi, Ben<o:p></o:p></p>
<p class="MsoNormal">This patch can only take effect after firmware v8.6. It cannot be used on firmware v8.4 and v8.5. The reason is that the firmware team gave a clear reply that there are many related bugs in firmware v8.4 and v8.5, and they were fixed in
 firmware v8.6. The firmware team recommends using v8.6.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Regards<o:p></o:p></p>
<p class="MsoNormal">Kevin<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b>From:</b> Ben Magistro <koncept1@gmail.com> <br>
<b>Sent:</b> 2022<span lang="ZH-CN" style="font-family:"Microsoft YaHei",sans-serif">年</span>6<span lang="ZH-CN" style="font-family:"Microsoft YaHei",sans-serif">月</span>10<span lang="ZH-CN" style="font-family:"Microsoft YaHei",sans-serif">日</span> 22:27<br>
<b>To:</b> Liu, KevinX <kevinx.liu@intel.com><br>
<b>Cc:</b> dev@dpdk.org; Zhang, Yuying <yuying.zhang@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Zhang, RobinX <robinx.zhang@intel.com><br>
<b>Subject:</b> Re: [PATCH v7] net/i40e: add outer VLAN processing<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">I'm trying to understand if this change is at all related to an issue we are experiencing with newer firmwares (<a href="https://mails.dpdk.org/archives/dev/2022-April/238621.html" target="_blank">https://mails.dpdk.org/archives/dev/2022-April/238621.html</a>)
 that happened to start with 8.4 and affected qinq offload processing.  I can say loading this patch and running testpmd does not seem to have any effect on the issue we are experiencing.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Side note, there is also a minor typo in the comment block "i40e_vlan_tpie_set" vs "i40e_vlan_tpid_set".<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Fri, Jun 10, 2022 at 4:30 AM Kevin Liu <<a href="mailto:kevinx.liu@intel.com" target="_blank">kevinx.liu@intel.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt">From: Robin Zhang <<a href="mailto:robinx.zhang@intel.com" target="_blank">robinx.zhang@intel.com</a>><br>
<br>
Outer VLAN processing is supported after firmware v8.4, kernel driver<br>
also change the default behavior to support this feature. To align with<br>
kernel driver, add support for outer VLAN processing in DPDK.<br>
<br>
But it is forbidden for firmware to change the Inner/Outer VLAN<br>
configuration while there are MAC/VLAN filters in the switch table.<br>
Therefore, we need to clear the MAC table before setting config,<br>
and then restore the MAC table after setting.<br>
<br>
This will not impact on an old firmware.<br>
<br>
Signed-off-by: Robin Zhang <<a href="mailto:robinx.zhang@intel.com" target="_blank">robinx.zhang@intel.com</a>><br>
Signed-off-by: Kevin Liu <<a href="mailto:kevinx.liu@intel.com" target="_blank">kevinx.liu@intel.com</a>><br>
---<br>
 drivers/net/i40e/i40e_ethdev.c | 94 ++++++++++++++++++++++++++++++++--<br>
 drivers/net/i40e/i40e_ethdev.h |  3 ++<br>
 2 files changed, 92 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c<br>
index 755786dc10..4cae163cb9 100644<br>
--- a/drivers/net/i40e/i40e_ethdev.c<br>
+++ b/drivers/net/i40e/i40e_ethdev.c<br>
@@ -2575,6 +2575,7 @@ i40e_dev_close(struct rte_eth_dev *dev)<br>
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);<br>
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);<br>
        struct rte_intr_handle *intr_handle = pci_dev->intr_handle;<br>
+       struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;<br>
        struct i40e_filter_control_settings settings;<br>
        struct rte_flow *p_flow;<br>
        uint32_t reg;<br>
@@ -2587,6 +2588,18 @@ i40e_dev_close(struct rte_eth_dev *dev)<br>
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)<br>
                return 0;<br>
<br>
+       /*<br>
+        * It is a workaround, if the double VLAN is disabled when<br>
+        * the program exits, an abnormal error will occur on the<br>
+        * NIC. Need to enable double VLAN when dev is closed.<br>
+        */<br>
+       if (pf->fw8_3gt) {<br>
+               if (!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)) {<br>
+                       rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;<br>
+                       i40e_vlan_offload_set(dev, RTE_ETH_VLAN_EXTEND_MASK);<br>
+               }<br>
+       }<br>
+<br>
        ret = rte_eth_switch_domain_free(pf->switch_domain_id);<br>
        if (ret)<br>
                PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);<br>
@@ -3909,6 +3922,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,<br>
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);<br>
        int qinq = dev->data->dev_conf.rxmode.offloads &<br>
                   RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;<br>
+       u16 sw_flags = 0, valid_flags = 0;<br>
        int ret = 0;<br>
<br>
        if ((vlan_type != RTE_ETH_VLAN_TYPE_INNER &&<br>
@@ -3927,15 +3941,32 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,<br>
        /* 802.1ad frames ability is added in NVM API 1.7*/<br>
        if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {<br>
                if (qinq) {<br>
+                       if (pf->fw8_3gt) {<br>
+                               sw_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN;<br>
+                               valid_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN;<br>
+                       }<br>
                        if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)<br>
                                hw->first_tag = rte_cpu_to_le_16(tpid);<br>
                        else if (vlan_type == RTE_ETH_VLAN_TYPE_INNER)<br>
                                hw->second_tag = rte_cpu_to_le_16(tpid);<br>
                } else {<br>
-                       if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)<br>
-                               hw->second_tag = rte_cpu_to_le_16(tpid);<br>
+                       /*<br>
+                        * If tpid is equal to 0x88A8, indicates that the<br>
+                        * disable double VLAN operation is in progress.<br>
+                        * Need set switch configuration back to default.<br>
+                        */<br>
+                       if (pf->fw8_3gt && tpid == RTE_ETHER_TYPE_QINQ) {<br>
+                               sw_flags = 0;<br>
+                               valid_flags = I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN;<br>
+                               if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)<br>
+                                       hw->first_tag = rte_cpu_to_le_16(tpid);<br>
+                       } else {<br>
+                               if (vlan_type == RTE_ETH_VLAN_TYPE_OUTER)<br>
+                                       hw->second_tag = rte_cpu_to_le_16(tpid);<br>
+                       }<br>
                }<br>
-               ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL);<br>
+               ret = i40e_aq_set_switch_config(hw, sw_flags,<br>
+                                               valid_flags, 0, NULL);<br>
                if (ret != I40E_SUCCESS) {<br>
                        PMD_DRV_LOG(ERR,<br>
                                    "Set switch config failed aq_err: %d",<br>
@@ -3987,8 +4018,13 @@ static int<br>
 i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)<br>
 {<br>
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);<br>
+       struct i40e_mac_filter_info *mac_filter;<br>
        struct i40e_vsi *vsi = pf->main_vsi;<br>
        struct rte_eth_rxmode *rxmode;<br>
+       struct i40e_mac_filter *f;<br>
+       int i, num;<br>
+       void *temp;<br>
+       int ret;<br>
<br>
        rxmode = &dev->data->dev_conf.rxmode;<br>
        if (mask & RTE_ETH_VLAN_FILTER_MASK) {<br>
@@ -4007,6 +4043,33 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)<br>
        }<br>
<br>
        if (mask & RTE_ETH_VLAN_EXTEND_MASK) {<br>
+               i = 0;<br>
+               num = vsi->mac_num;<br>
+               mac_filter = rte_zmalloc("mac_filter_info_data",<br>
+                                num * sizeof(*mac_filter), 0);<br>
+               if (mac_filter == NULL) {<br>
+                       PMD_DRV_LOG(ERR, "failed to allocate memory");<br>
+                       return I40E_ERR_NO_MEMORY;<br>
+               }<br>
+<br>
+               /*<br>
+                * Outer VLAN processing is supported after firmware v8.4, kernel driver<br>
+                * also change the default behavior to support this feature. To align with<br>
+                * kernel driver, set switch config in 'i40e_vlan_tpie_set' to support for<br>
+                * outer VLAN processing. But it is forbidden for firmware to change the<br>
+                * Inner/Outer VLAN configuration while there are MAC/VLAN filters in the<br>
+                * switch table. Therefore, we need to clear the MAC table before setting<br>
+                * config, and then restore the MAC table after setting. This feature is<br>
+                * recommended to be used in firmware v8.6.<br>
+                */<br>
+               /* Remove all existing mac */<br>
+               RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {<br>
+                       mac_filter[i] = f->mac_info;<br>
+                       ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr);<br>
+                       if (ret)<br>
+                               PMD_DRV_LOG(ERR, "i40e vsi delete mac fail.");<br>
+                       i++;<br>
+               }<br>
                if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) {<br>
                        i40e_vsi_config_double_vlan(vsi, TRUE);<br>
                        /* Set global registers with default ethertype. */<br>
@@ -4014,9 +4077,19 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)<br>
                                           RTE_ETHER_TYPE_VLAN);<br>
                        i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_INNER,<br>
                                           RTE_ETHER_TYPE_VLAN);<br>
-               }<br>
-               else<br>
+               } else {<br>
+                       if (pf->fw8_3gt)<br>
+                               i40e_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_OUTER,<br>
+                                          RTE_ETHER_TYPE_QINQ);<br>
                        i40e_vsi_config_double_vlan(vsi, FALSE);<br>
+               }<br>
+               /* Restore all mac */<br>
+               for (i = 0; i < num; i++) {<br>
+                       ret = i40e_vsi_add_mac(vsi, &mac_filter[i]);<br>
+                       if (ret)<br>
+                               PMD_DRV_LOG(ERR, "i40e vsi add mac fail.");<br>
+               }<br>
+               rte_free(mac_filter);<br>
        }<br>
<br>
        if (mask & RTE_ETH_QINQ_STRIP_MASK) {<br>
@@ -4846,6 +4919,17 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)<br>
                return -EINVAL;<br>
        }<br>
<br>
+       /**<br>
+        * Enable outer VLAN processing if firmware version is greater<br>
+        * than v8.3<br>
+        */<br>
+       if (hw->aq.fw_maj_ver > 8 ||<br>
+           (hw->aq.fw_maj_ver == 8 && hw->aq.fw_min_ver > 3)) {<br>
+               pf->fw8_3gt = true;<br>
+       } else {<br>
+               pf->fw8_3gt = false;<br>
+       }<br>
+<br>
        return 0;<br>
 }<br>
<br>
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h<br>
index a1ebdc093c..fe943a45ff 100644<br>
--- a/drivers/net/i40e/i40e_ethdev.h<br>
+++ b/drivers/net/i40e/i40e_ethdev.h<br>
@@ -1188,6 +1188,9 @@ struct i40e_pf {<br>
        /* Switch Domain Id */<br>
        uint16_t switch_domain_id;<br>
<br>
+       /* When firmware > 8.3, the enable flag for outer VLAN processing */<br>
+       bool fw8_3gt;<br>
+<br>
        struct i40e_vf_msg_cfg vf_msg_cfg;<br>
        uint64_t prev_rx_bytes;<br>
        uint64_t prev_tx_bytes;<br>
-- <br>
2.34.1<o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</body>
</html>