net/i40e: fix VF add/del MAC
authorJeff Guo <jia.guo@intel.com>
Wed, 19 Jul 2017 09:01:11 +0000 (17:01 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Jul 2017 13:25:43 +0000 (16:25 +0300)
i40e VF close would stop the VF first, if VF already stopped this
result duplicate add/del MAC address which cause failure in executing
admin command.

Fix this by adding VF stop status check and sync up VF MAC address count
during add/del.

Fixes: d42aaf30008b ("i40e: support port hotplug")
Cc: stable@dpdk.org
Signed-off-by: Jeff Guo <jia.guo@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
drivers/net/i40e/i40e_ethdev.c
drivers/net/i40e/i40e_ethdev_vf.c

index 306988a..9fcccda 100644 (file)
@@ -2051,12 +2051,15 @@ static void
 i40e_dev_stop(struct rte_eth_dev *dev)
 {
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_vsi *main_vsi = pf->main_vsi;
        struct i40e_mirror_rule *p_mirror;
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        int i;
 
+       if (hw->adapter_stopped == 1)
+               return;
        /* Disable all queues */
        i40e_dev_switch_queues(pf, FALSE);
 
@@ -2101,6 +2104,8 @@ i40e_dev_stop(struct rte_eth_dev *dev)
 
        /* reset hierarchy commit */
        pf->tm_conf.committed = false;
+
+       hw->adapter_stopped = 1;
 }
 
 static void
@@ -2116,7 +2121,6 @@ i40e_dev_close(struct rte_eth_dev *dev)
        PMD_INIT_FUNC_TRACE();
 
        i40e_dev_stop(dev);
-       hw->adapter_stopped = 1;
        i40e_dev_free_queues(dev);
 
        /* Disable interrupt */
index 62dea59..f6d8293 100644 (file)
@@ -911,6 +911,8 @@ i40evf_add_mac_addr(struct rte_eth_dev *dev,
        if (err)
                PMD_DRV_LOG(ERR, "fail to execute command "
                            "OP_ADD_ETHER_ADDRESS");
+       else
+               vf->vsi.mac_num++;
 
        return err;
 }
@@ -949,6 +951,8 @@ i40evf_del_mac_addr_by_addr(struct rte_eth_dev *dev,
        if (err)
                PMD_DRV_LOG(ERR, "fail to execute command "
                            "OP_DEL_ETHER_ADDRESS");
+       else
+               vf->vsi.mac_num--;
        return;
 }
 
@@ -2063,10 +2067,16 @@ i40evf_add_del_all_mac_addr(struct rte_eth_dev *dev, bool add)
                args.out_buffer = vf->aq_resp;
                args.out_size = I40E_AQ_BUF_SZ;
                err = i40evf_execute_vf_cmd(dev, &args);
-               if (err)
+               if (err) {
                        PMD_DRV_LOG(ERR, "fail to execute command %s",
                                    add ? "OP_ADD_ETHER_ADDRESS" :
                                    "OP_DEL_ETHER_ADDRESS");
+               } else {
+                       if (add)
+                               vf->vsi.mac_num++;
+                       else
+                               vf->vsi.mac_num--;
+               }
                rte_free(list);
                begin = next_begin;
        } while (begin < I40E_NUM_MACADDR_MAX);
@@ -2145,9 +2155,12 @@ i40evf_dev_stop(struct rte_eth_dev *dev)
 {
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev);
 
        PMD_INIT_FUNC_TRACE();
 
+       if (hw->adapter_stopped == 1)
+               return;
        i40evf_stop_queues(dev);
        i40evf_disable_queues_intr(dev);
        i40e_dev_clear_queues(dev);
@@ -2160,6 +2173,7 @@ i40evf_dev_stop(struct rte_eth_dev *dev)
        }
        /* remove all mac addrs */
        i40evf_add_del_all_mac_addr(dev, FALSE);
+       hw->adapter_stopped = 1;
 
 }
 
@@ -2347,7 +2361,6 @@ i40evf_dev_close(struct rte_eth_dev *dev)
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
        i40evf_dev_stop(dev);
-       hw->adapter_stopped = 1;
        i40e_dev_free_queues(dev);
        i40evf_reset_vf(hw);
        i40e_shutdown_adminq(hw);