net/mlx5: add flow validation of eCPRI header
[dpdk.git] / drivers / net / i40e / i40e_ethdev_vf.c
index c34f520..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;
 }
 
@@ -1309,10 +1333,8 @@ i40evf_init_vf(struct rte_eth_dev *dev)
        vf->vsi.adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
        /* Store the MAC address configured by host, or generate random one */
-       if (rte_is_valid_assigned_ether_addr(
+       if (!rte_is_valid_assigned_ether_addr(
                        (struct rte_ether_addr *)hw->mac.addr))
-               vf->flags |= I40E_FLAG_VF_MAC_BY_PF;
-       else
                rte_eth_random_addr(hw->mac.addr); /* Generate a random one */
 
        I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
@@ -1518,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
@@ -1614,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);
@@ -2186,60 +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
-               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
-               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
-               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
-               ret = -EAGAIN;
-
-       return ret;
+       return i40evf_config_promisc(dev, vf->promisc_unicast_enabled, false);
 }
 
 static int
@@ -2361,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);
@@ -2772,7 +2780,6 @@ static int
 i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
                            struct rte_ether_addr *mac_addr)
 {
-       struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
@@ -2780,9 +2787,6 @@ i40evf_set_default_mac_addr(struct rte_eth_dev *dev,
                return -EINVAL;
        }
 
-       if (vf->flags & I40E_FLAG_VF_MAC_BY_PF)
-               return -EPERM;
-
        i40evf_del_mac_addr_by_addr(dev, (struct rte_ether_addr *)hw->mac.addr);
 
        if (i40evf_add_mac_addr(dev, mac_addr, 0, 0) != 0)