net/mlx5: fix dynamic inline hint handling
[dpdk.git] / drivers / net / i40e / i40e_ethdev_vf.c
index bb5d28a..69cab8e 100644 (file)
@@ -91,7 +91,8 @@ static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
                                  uint16_t vlan_id, int on);
 static int i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 static void i40evf_dev_close(struct rte_eth_dev *dev);
-static int  i40evf_dev_reset(struct rte_eth_dev *dev);
+static int i40evf_dev_reset(struct rte_eth_dev *dev);
+static int i40evf_check_vf_reset_done(struct rte_eth_dev *dev);
 static int i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev);
@@ -519,10 +520,19 @@ i40evf_config_promisc(struct rte_eth_dev *dev,
 
        err = i40evf_execute_vf_cmd(dev, &args);
 
-       if (err)
+       if (err) {
                PMD_DRV_LOG(ERR, "fail to execute command "
                            "CONFIG_PROMISCUOUS_MODE");
-       return err;
+
+               if (err == I40E_NOT_SUPPORTED)
+                       return -ENOTSUP;
+
+               return -EAGAIN;
+       }
+
+       vf->promisc_unicast_enabled = enable_unicast;
+       vf->promisc_multicast_enabled = enable_multicast;
+       return 0;
 }
 
 static int
@@ -789,7 +799,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev)
        for (i = 0; i < dev->data->nb_tx_queues; i++) {
                if (i40evf_dev_tx_queue_stop(dev, i) != 0) {
                        PMD_DRV_LOG(ERR, "Fail to stop queue %u", i);
-                       return -1;
                }
        }
 
@@ -797,7 +806,6 @@ i40evf_stop_queues(struct rte_eth_dev *dev)
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
                if (i40evf_dev_rx_queue_stop(dev, i) != 0) {
                        PMD_DRV_LOG(ERR, "Fail to stop queue %u", i);
-                       return -1;
                }
        }
 
@@ -1083,12 +1091,28 @@ i40evf_request_queues(struct rte_eth_dev *dev, uint16_t num)
        args.out_size = I40E_AQ_BUF_SZ;
 
        rte_eal_alarm_cancel(i40evf_dev_alarm_handler, dev);
+
        err = i40evf_execute_vf_cmd(dev, &args);
-       if (err)
+
+       rte_eal_alarm_set(I40EVF_ALARM_INTERVAL, i40evf_dev_alarm_handler, dev);
+
+       if (err != I40E_SUCCESS) {
                PMD_DRV_LOG(ERR, "fail to execute command OP_REQUEST_QUEUES");
+               return err;
+       }
+
+       /* The PF will issue a reset to the VF when change the number of
+        * queues. The PF will set I40E_VFGEN_RSTAT to COMPLETE first, then
+        * wait 10ms and set it to ACTIVE. In this duration, vf may not catch
+        * the moment that COMPLETE is set. So, for vf, we'll try to wait a
+        * long time.
+        */
+       rte_delay_ms(100);
+
+       err = i40evf_check_vf_reset_done(dev);
+       if (err)
+               PMD_DRV_LOG(ERR, "VF is still resetting");
 
-       rte_eal_alarm_set(I40EVF_ALARM_INTERVAL,
-                         i40evf_dev_alarm_handler, dev);
        return err;
 }
 
@@ -1516,7 +1540,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
        hw->bus.device = pci_dev->addr.devid;
        hw->bus.func = pci_dev->addr.function;
        hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
-       hw->adapter_stopped = 0;
+       hw->adapter_stopped = 1;
        hw->adapter_closed = 0;
 
        /* Pass the information to the rte_eth_dev_close() that it should also
@@ -1612,7 +1636,20 @@ i40evf_dev_configure(struct rte_eth_dev *dev)
        ad->tx_vec_allowed = true;
 
        if (num_queue_pairs > vf->vsi_res->num_queue_pairs) {
-               int ret = 0;
+               struct i40e_hw *hw;
+               int ret;
+
+               if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+                       PMD_DRV_LOG(ERR,
+                                   "For secondary processes, change queue pairs is not supported!");
+                       return -ENOTSUP;
+               }
+
+               hw  = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+               if (!hw->adapter_stopped) {
+                       PMD_DRV_LOG(ERR, "Device must be stopped first!");
+                       return -EBUSY;
+               }
 
                PMD_DRV_LOG(INFO, "change queue pairs from %u to %u",
                            vf->vsi_res->num_queue_pairs, num_queue_pairs);
@@ -2184,68 +2221,32 @@ static int
 i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-       int ret;
 
-       ret = i40evf_config_promisc(dev, 1, vf->promisc_multicast_enabled);
-       if (ret == 0)
-               vf->promisc_unicast_enabled = TRUE;
-       else if (ret == I40E_NOT_SUPPORTED)
-               ret = -ENOTSUP;
-       else
-               ret = -EAGAIN;
-
-       return ret;
+       return i40evf_config_promisc(dev, true, vf->promisc_multicast_enabled);
 }
 
 static int
 i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-       int ret;
-
-       ret = i40evf_config_promisc(dev, 0, vf->promisc_multicast_enabled);
-       if (ret == 0)
-               vf->promisc_unicast_enabled = FALSE;
-       else if (ret == I40E_NOT_SUPPORTED)
-               ret = -ENOTSUP;
-       else
-               ret = -EAGAIN;
 
-       return ret;
+       return i40evf_config_promisc(dev, false, vf->promisc_multicast_enabled);
 }
 
 static int
 i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev)
 {
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-       int ret;
-
-       ret = i40evf_config_promisc(dev, vf->promisc_unicast_enabled, 1);
-       if (ret == 0)
-               vf->promisc_multicast_enabled = TRUE;
-       else if (ret == I40E_NOT_SUPPORTED)
-               ret = -ENOTSUP;
-       else
-               ret = -EAGAIN;
 
-       return ret;
+       return i40evf_config_promisc(dev, vf->promisc_unicast_enabled, true);
 }
 
 static int
 i40evf_dev_allmulticast_disable(struct rte_eth_dev *dev)
 {
        struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-       int ret;
-
-       ret = i40evf_config_promisc(dev, vf->promisc_unicast_enabled, 0);
-       if (ret == 0)
-               vf->promisc_multicast_enabled = FALSE;
-       else if (ret == I40E_NOT_SUPPORTED)
-               ret = -ENOTSUP;
-       else
-               ret = -EAGAIN;
 
-       return ret;
+       return i40evf_config_promisc(dev, vf->promisc_unicast_enabled, false);
 }
 
 static int
@@ -2367,8 +2368,9 @@ i40evf_dev_close(struct rte_eth_dev *dev)
         * it is a workaround solution when work with kernel driver
         * and it is not the normal way
         */
-       i40evf_dev_promiscuous_disable(dev);
-       i40evf_dev_allmulticast_disable(dev);
+       if (vf->promisc_unicast_enabled || vf->promisc_multicast_enabled)
+               i40evf_config_promisc(dev, false, false);
+
        rte_eal_alarm_cancel(i40evf_dev_alarm_handler, dev);
 
        i40evf_reset_vf(dev);