From 1859934202497edc27fba6f8c5c6f6e03213430a Mon Sep 17 00:00:00 2001 From: Jeff Guo Date: Wed, 19 Jul 2017 17:01:11 +0800 Subject: [PATCH] net/i40e: fix VF add/del MAC 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 Acked-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.c | 6 +++++- drivers/net/i40e/i40e_ethdev_vf.c | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 306988a8a1..9fcccdaaed 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -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 */ diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 62dea59f4b..f6d8293473 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -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); -- 2.20.1