net/i40e: fix request queue in VF
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index a9203fa..68b1e4f 100644 (file)
@@ -23,6 +23,7 @@
 #include <rte_bus_pci.h>
 #include <rte_branch_prediction.h>
 #include <rte_memory.h>
+#include <rte_kvargs.h>
 #include <rte_eal.h>
 #include <rte_alarm.h>
 #include <rte_ether.h>
 #define IXGBE_EXVET_VET_EXT_SHIFT              16
 #define IXGBE_DMATXCTL_VT_MASK                 0xFFFF0000
 
+#define IXGBEVF_DEVARG_PFLINK_FULLCHK          "pflink_fullchk"
+
+static const char * const ixgbevf_valid_arguments[] = {
+       IXGBEVF_DEVARG_PFLINK_FULLCHK,
+       NULL
+};
+
 static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
 static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
 static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
@@ -462,6 +470,7 @@ static const struct rte_pci_id pci_id_ixgbe_map[] = {
        { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T_L) },
        { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KX4) },
        { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KR) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_XFI) },
 #ifdef RTE_LIBRTE_IXGBE_BYPASS
        { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BYPASS) },
 #endif
@@ -1549,6 +1558,45 @@ generate_random_mac_addr(struct rte_ether_addr *mac_addr)
        memcpy(&mac_addr->addr_bytes[3], &random, 3);
 }
 
+static int
+devarg_handle_int(__rte_unused const char *key, const char *value,
+                 void *extra_args)
+{
+       uint16_t *n = extra_args;
+
+       if (value == NULL || extra_args == NULL)
+               return -EINVAL;
+
+       *n = (uint16_t)strtoul(value, NULL, 0);
+       if (*n == USHRT_MAX && errno == ERANGE)
+               return -1;
+
+       return 0;
+}
+
+static void
+ixgbevf_parse_devargs(struct ixgbe_adapter *adapter,
+                     struct rte_devargs *devargs)
+{
+       struct rte_kvargs *kvlist;
+       uint16_t pflink_fullchk;
+
+       if (devargs == NULL)
+               return;
+
+       kvlist = rte_kvargs_parse(devargs->args, ixgbevf_valid_arguments);
+       if (kvlist == NULL)
+               return;
+
+       if (rte_kvargs_count(kvlist, IXGBEVF_DEVARG_PFLINK_FULLCHK) == 1 &&
+           rte_kvargs_process(kvlist, IXGBEVF_DEVARG_PFLINK_FULLCHK,
+                              devarg_handle_int, &pflink_fullchk) == 0 &&
+           pflink_fullchk == 1)
+               adapter->pflink_fullchk = 1;
+
+       rte_kvargs_free(kvlist);
+}
+
 /*
  * Virtual Function device init
  */
@@ -1597,6 +1645,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
                return 0;
        }
 
+       ixgbevf_parse_devargs(eth_dev->data->dev_private,
+                             pci_dev->device.devargs);
+
        rte_eth_copy_pci_info(eth_dev, pci_dev);
 
        hw->device_id = pci_dev->id.device_id;
@@ -1818,8 +1869,7 @@ static int eth_ixgbe_pci_remove(struct rte_pci_device *pci_dev)
 
 static struct rte_pci_driver rte_ixgbe_pmd = {
        .id_table = pci_id_ixgbe_map,
-       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
-                    RTE_PCI_DRV_IOVA_AS_VA,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
        .probe = eth_ixgbe_pci_probe,
        .remove = eth_ixgbe_pci_remove,
 };
@@ -1841,7 +1891,7 @@ static int eth_ixgbevf_pci_remove(struct rte_pci_device *pci_dev)
  */
 static struct rte_pci_driver rte_ixgbevf_pmd = {
        .id_table = pci_id_ixgbevf_map,
-       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
        .probe = eth_ixgbevf_pci_probe,
        .remove = eth_ixgbevf_pci_remove,
 };
@@ -2407,8 +2457,7 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
 {
        struct ixgbe_interrupt *intr =
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -2816,8 +2865,7 @@ static void
 ixgbe_dev_stop(struct rte_eth_dev *dev)
 {
        struct rte_eth_link link;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_vf_info *vfinfo =
@@ -3909,6 +3957,8 @@ static int
 ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                   int *link_up, int wait_to_complete)
 {
+       struct ixgbe_adapter *adapter = container_of(hw,
+                                                    struct ixgbe_adapter, hw);
        struct ixgbe_mbx_info *mbx = &hw->mbx;
        struct ixgbe_mac_info *mac = &hw->mac;
        uint32_t links_reg, in_msg;
@@ -3969,6 +4019,15 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
        }
 
+       if (wait_to_complete == 0 && adapter->pflink_fullchk == 0) {
+               if (*speed == IXGBE_LINK_SPEED_UNKNOWN)
+                       mac->get_link_status = true;
+               else
+                       mac->get_link_status = false;
+
+               goto out;
+       }
+
        /* if the read failed it could just be a mailbox collision, best wait
         * until we are called again and don't report an error
         */
@@ -4442,7 +4501,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
 
        PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
        ixgbe_enable_intr(dev);
-       rte_intr_enable(intr_handle);
+       rte_intr_ack(intr_handle);
 }
 
 /**
@@ -4814,8 +4873,7 @@ ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
        uint8_t j, mask;
        uint32_t reta, r;
        uint16_t idx, shift;
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t reta_reg;
 
@@ -5048,8 +5106,7 @@ static int
 ixgbevf_dev_configure(struct rte_eth_dev *dev)
 {
        struct rte_eth_conf *conf = &dev->data->dev_conf;
-       struct ixgbe_adapter *adapter =
-                       (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
 
        PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
                     dev->data->port_id);
@@ -5181,8 +5238,7 @@ static void
 ixgbevf_dev_stop(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
@@ -5706,7 +5762,7 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
        RTE_SET_USED(queue_id);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, intr->mask);
 
-       rte_intr_enable(intr_handle);
+       rte_intr_ack(intr_handle);
 
        return 0;
 }
@@ -5755,7 +5811,7 @@ ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
                mask &= (1 << (queue_id - 32));
                IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
        }
-       rte_intr_enable(intr_handle);
+       rte_intr_ack(intr_handle);
 
        return 0;
 }
@@ -6666,8 +6722,8 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
        if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM)
                return -EINVAL;
 
-       if (filter->ether_type == RTE_ETHER_TYPE_IPv4 ||
-               filter->ether_type == RTE_ETHER_TYPE_IPv6) {
+       if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
+               filter->ether_type == RTE_ETHER_TYPE_IPV6) {
                PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in"
                        " ethertype filter.", filter->ether_type);
                return -EINVAL;
@@ -6944,8 +7000,7 @@ static void
 ixgbe_start_timecounters(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        struct rte_eth_link link;
        uint32_t incval = 0;
        uint32_t shift = 0;
@@ -7013,8 +7068,7 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 static int
 ixgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
 {
-       struct ixgbe_adapter *adapter =
-                       (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
 
        adapter->systime_tc.nsec += delta;
        adapter->rx_tstamp_tc.nsec += delta;
@@ -7027,8 +7081,7 @@ static int
 ixgbe_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
 {
        uint64_t ns;
-       struct ixgbe_adapter *adapter =
-                       (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
 
        ns = rte_timespec_to_ns(ts);
        /* Set the timecounters to a new value. */
@@ -7043,8 +7096,7 @@ static int
 ixgbe_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
 {
        uint64_t ns, systime_cycles;
-       struct ixgbe_adapter *adapter =
-                       (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
 
        systime_cycles = ixgbe_read_systime_cyclecounter(dev);
        ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles);
@@ -7125,8 +7177,7 @@ ixgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
                                 uint32_t flags __rte_unused)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        uint32_t tsync_rxctl;
        uint64_t rx_tstamp_cycles;
        uint64_t ns;
@@ -7147,8 +7198,7 @@ ixgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
                                 struct timespec *timestamp)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct ixgbe_adapter *adapter =
-               (struct ixgbe_adapter *)dev->data->dev_private;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        uint32_t tsync_txctl;
        uint64_t tx_tstamp_cycles;
        uint64_t ns;
@@ -8670,6 +8720,8 @@ RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio-pci");
 RTE_PMD_REGISTER_PCI(net_ixgbe_vf, rte_ixgbevf_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe_vf, pci_id_ixgbevf_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe_vf, "* igb_uio | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_ixgbe_vf,
+                             IXGBEVF_DEVARG_PFLINK_FULLCHK "=<0|1>");
 
 RTE_INIT(ixgbe_init_log)
 {