memzone: rename address from physical to IOVA
[dpdk.git] / drivers / net / fm10k / fm10k_ethdev.c
index 95ee9d2..2d05a46 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <rte_ethdev.h>
+#include <rte_ethdev_pci.h>
 #include <rte_malloc.h>
 #include <rte_memzone.h>
 #include <rte_string_fns.h>
@@ -83,6 +84,7 @@ static void fm10k_rx_queue_release(void *queue);
 static void fm10k_set_rx_function(struct rte_eth_dev *dev);
 static void fm10k_set_tx_function(struct rte_eth_dev *dev);
 static int fm10k_check_ftag(struct rte_devargs *devargs);
+static int fm10k_link_update(struct rte_eth_dev *dev, int wait_to_complete);
 
 struct fm10k_xstats_name_off {
        char name[RTE_ETH_XSTATS_NAME_SIZE];
@@ -197,9 +199,9 @@ fm10k_tx_vec_condition_check(__rte_unused struct fm10k_tx_queue *txq)
 }
 
 uint16_t __attribute__((weak))
-fm10k_xmit_pkts_vec(__rte_unused void *tx_queue,
-               __rte_unused struct rte_mbuf **tx_pkts,
-               __rte_unused uint16_t nb_pkts)
+fm10k_xmit_fixed_burst_vec(__rte_unused void *tx_queue,
+                          __rte_unused struct rte_mbuf **tx_pkts,
+                          __rte_unused uint16_t nb_pkts)
 {
        return 0;
 }
@@ -677,7 +679,7 @@ fm10k_dev_tx_init(struct rte_eth_dev *dev)
                /* Enable use of FTAG bit in TX descriptor, PFVTCTL
                 * register is read-only for VF.
                 */
-               if (fm10k_check_ftag(dev->pci_dev->device.devargs)) {
+               if (fm10k_check_ftag(dev->device->devargs)) {
                        if (hw->mac.type == fm10k_mac_pf) {
                                FM10K_WRITE_REG(hw, FM10K_PFVTCTL(i),
                                                FM10K_PFVTCTL_FTAG_DESC_ENABLE);
@@ -711,7 +713,7 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct fm10k_macvlan_filter_info *macvlan;
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
        int i, ret;
        struct fm10k_rx_queue *rxq;
@@ -1165,6 +1167,8 @@ fm10k_dev_start(struct rte_eth_dev *dev)
        if (!(dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG))
                fm10k_vlan_filter_set(dev, hw->mac.default_vid, true);
 
+       fm10k_link_update(dev, 0);
+
        return 0;
 }
 
@@ -1172,7 +1176,7 @@ static void
 fm10k_dev_stop(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
        int i;
 
@@ -1252,14 +1256,17 @@ static int
 fm10k_link_update(struct rte_eth_dev *dev,
        __rte_unused int wait_to_complete)
 {
+       struct fm10k_dev_info *dev_info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
        PMD_INIT_FUNC_TRACE();
 
-       /* The host-interface link is always up.  The speed is ~50Gbps per Gen3
-        * x8 PCIe interface. For now, we leave the speed undefined since there
-        * is no 50Gbps Ethernet. */
+       /* The speed is ~50Gbps per Gen3 x8 PCIe interface. For now, we
+        * leave the speed undefined since there is no 50Gbps Ethernet.
+        */
        dev->data->dev_link.link_speed  = 0;
        dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-       dev->data->dev_link.link_status = ETH_LINK_UP;
+       dev->data->dev_link.link_status =
+               dev_info->sm_down ? ETH_LINK_DOWN : ETH_LINK_UP;
 
        return 0;
 }
@@ -1317,6 +1324,7 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        for (i = 0; i < FM10K_NB_HW_XSTATS; i++) {
                xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
                        fm10k_hw_stats_strings[count].offset);
+               xstats[count].id = count;
                count++;
        }
 
@@ -1326,12 +1334,14 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                        xstats[count].value =
                                *(uint64_t *)(((char *)&hw_stats->q[q]) +
                                fm10k_hw_stats_rx_q_strings[i].offset);
+                       xstats[count].id = count;
                        count++;
                }
                for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) {
                        xstats[count].value =
                                *(uint64_t *)(((char *)&hw_stats->q[q]) +
                                fm10k_hw_stats_tx_q_strings[i].offset);
+                       xstats[count].id = count;
                        count++;
                }
        }
@@ -1339,7 +1349,7 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        return FM10K_NB_XSTATS;
 }
 
-static void
+static int
 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
        uint64_t ipackets, opackets, ibytes, obytes;
@@ -1369,6 +1379,7 @@ fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        stats->opackets = opackets;
        stats->ibytes = ibytes;
        stats->obytes = obytes;
+       return 0;
 }
 
 static void
@@ -1389,10 +1400,11 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
        struct rte_eth_dev_info *dev_info)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
 
        PMD_INIT_FUNC_TRACE();
 
+       dev_info->pci_dev            = pdev;
        dev_info->min_rx_bufsize     = FM10K_MIN_RX_BUF_SIZE;
        dev_info->max_rx_pktlen      = FM10K_MAX_PKT_SIZE;
        dev_info->max_rx_queues      = hw->mac.max_queues;
@@ -1450,6 +1462,8 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
                .nb_max = FM10K_MAX_TX_DESC,
                .nb_min = FM10K_MIN_TX_DESC,
                .nb_align = FM10K_MULT_TX_DESC,
+               .nb_seg_max = FM10K_TX_MAX_SEG,
+               .nb_mtu_seg_max = FM10K_TX_MAX_MTU_SEG,
        };
 
        dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
@@ -1580,8 +1594,8 @@ fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
        return 0;
 }
 
-static void
-fm10k_vlan_offload_set(__rte_unused struct rte_eth_dev *dev, int mask)
+static int
+fm10k_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
        if (mask & ETH_VLAN_STRIP_MASK) {
                if (!dev->data->dev_conf.rxmode.hw_vlan_strip)
@@ -1599,6 +1613,8 @@ fm10k_vlan_offload_set(__rte_unused struct rte_eth_dev *dev, int mask)
                if (!dev->data->dev_conf.rxmode.hw_vlan_filter)
                        PMD_INIT_LOG(ERR, "VLAN filter is always on in fm10k");
        }
+
+       return 0;
 }
 
 /* Add/Remove a MAC address, and update filters to main VSI */
@@ -1683,7 +1699,7 @@ static void fm10k_MAC_filter_set(struct rte_eth_dev *dev,
 }
 
 /* Add a MAC address, and update filters */
-static void
+static int
 fm10k_macaddr_add(struct rte_eth_dev *dev,
                struct ether_addr *mac_addr,
                uint32_t index,
@@ -1694,6 +1710,7 @@ fm10k_macaddr_add(struct rte_eth_dev *dev,
        macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data->dev_private);
        fm10k_MAC_filter_set(dev, mac_addr->addr_bytes, TRUE, pool);
        macvlan->mac_vmdq_id[index] = pool;
+       return 0;
 }
 
 /* Remove a MAC address, and update filters */
@@ -1797,7 +1814,8 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
        const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct fm10k_dev_info *dev_info = FM10K_DEV_PRIVATE_TO_INFO(dev);
+       struct fm10k_dev_info *dev_info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
        struct fm10k_rx_queue *q;
        const struct rte_memzone *mz;
 
@@ -1875,7 +1893,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
                return -ENOMEM;
        }
        q->hw_ring = mz->addr;
-       q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+       q->hw_ring_phys_addr = mz->iova;
 
        /* Check if number of descs satisfied Vector requirement */
        if (!rte_is_power_of_2(nb_desc)) {
@@ -2035,7 +2053,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
                return -ENOMEM;
        }
        q->hw_ring = mz->addr;
-       q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+       q->hw_ring_phys_addr = mz->iova;
 
        /*
         * allocate memory for the RS bit tracker. Enough slots to hold the
@@ -2336,7 +2354,7 @@ static int
 fm10k_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
 
        /* Enable ITR */
        if (hw->mac.type == fm10k_mac_pf)
@@ -2353,7 +2371,7 @@ static int
 fm10k_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
 
        /* Disable ITR */
        if (hw->mac.type == fm10k_mac_pf)
@@ -2369,7 +2387,7 @@ static int
 fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
        uint32_t intr_vector, vec;
        uint16_t queue_id;
@@ -2535,13 +2553,15 @@ error:
  *  void
  */
 static void
-fm10k_dev_interrupt_handler_pf(
-                       struct rte_intr_handle *handle,
-                       void *param)
+fm10k_dev_interrupt_handler_pf(void *param)
 {
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t cause, status;
+       struct fm10k_dev_info *dev_info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
+       int status_mbx;
+       s32 err;
 
        if (hw->mac.type != fm10k_mac_pf)
                return;
@@ -2558,14 +2578,69 @@ fm10k_dev_interrupt_handler_pf(
        if (cause & FM10K_EICR_SWITCHNOTREADY)
                PMD_INIT_LOG(ERR, "INT: Switch is not ready");
 
-       if (cause & FM10K_EICR_SWITCHREADY)
+       if (cause & FM10K_EICR_SWITCHREADY) {
                PMD_INIT_LOG(INFO, "INT: Switch is ready");
+               if (dev_info->sm_down == 1) {
+                       fm10k_mbx_lock(hw);
+
+                       /* For recreating logical ports */
+                       status_mbx = hw->mac.ops.update_lport_state(hw,
+                                       hw->mac.dglort_map, MAX_LPORT_NUM, 1);
+                       if (status_mbx == FM10K_SUCCESS)
+                               PMD_INIT_LOG(INFO,
+                                       "INT: Recreated Logical port");
+                       else
+                               PMD_INIT_LOG(INFO,
+                                       "INT: Logical ports weren't recreated");
+
+                       status_mbx = hw->mac.ops.update_xcast_mode(hw,
+                               hw->mac.dglort_map, FM10K_XCAST_MODE_NONE);
+                       if (status_mbx != FM10K_SUCCESS)
+                               PMD_INIT_LOG(ERR, "Failed to set XCAST mode");
+
+                       fm10k_mbx_unlock(hw);
+
+                       /* first clear the internal SW recording structure */
+                       if (!(dev->data->dev_conf.rxmode.mq_mode &
+                                               ETH_MQ_RX_VMDQ_FLAG))
+                               fm10k_vlan_filter_set(dev, hw->mac.default_vid,
+                                       false);
+
+                       fm10k_MAC_filter_set(dev, hw->mac.addr, false,
+                                       MAIN_VSI_POOL_NUMBER);
+
+                       /*
+                        * Add default mac address and vlan for the logical
+                        * ports that have been created, leave to the
+                        * application to fully recover Rx filtering.
+                        */
+                       fm10k_MAC_filter_set(dev, hw->mac.addr, true,
+                                       MAIN_VSI_POOL_NUMBER);
+
+                       if (!(dev->data->dev_conf.rxmode.mq_mode &
+                                               ETH_MQ_RX_VMDQ_FLAG))
+                               fm10k_vlan_filter_set(dev, hw->mac.default_vid,
+                                       true);
+
+                       dev_info->sm_down = 0;
+                       _rte_eth_dev_callback_process(dev,
+                                       RTE_ETH_EVENT_INTR_LSC,
+                                       NULL, NULL);
+               }
+       }
 
        /* Handle mailbox message */
        fm10k_mbx_lock(hw);
-       hw->mbx.ops.process(hw, &hw->mbx);
+       err = hw->mbx.ops.process(hw, &hw->mbx);
        fm10k_mbx_unlock(hw);
 
+       if (err == FM10K_ERR_RESET_REQUESTED) {
+               PMD_INIT_LOG(INFO, "INT: Switch is down");
+               dev_info->sm_down = 1;
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+                               NULL, NULL);
+       }
+
        /* Handle SRAM error */
        if (cause & FM10K_EICR_SRAMERROR) {
                PMD_INIT_LOG(ERR, "INT: SRAM error on PEP");
@@ -2587,7 +2662,7 @@ fm10k_dev_interrupt_handler_pf(
        FM10K_WRITE_REG(hw, FM10K_ITR(0), FM10K_ITR_AUTOMASK |
                                        FM10K_ITR_MASK_CLEAR);
        /* Re-enable interrupt from host side */
-       rte_intr_enable(handle);
+       rte_intr_enable(dev->intr_handle);
 }
 
 /**
@@ -2602,12 +2677,15 @@ fm10k_dev_interrupt_handler_pf(
  *  void
  */
 static void
-fm10k_dev_interrupt_handler_vf(
-                       struct rte_intr_handle *handle,
-                       void *param)
+fm10k_dev_interrupt_handler_vf(void *param)
 {
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct fm10k_mbx_info *mbx = &hw->mbx;
+       struct fm10k_dev_info *dev_info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
+       const enum fm10k_mbx_state state = mbx->state;
+       int status_mbx;
 
        if (hw->mac.type != fm10k_mac_vf)
                return;
@@ -2617,11 +2695,54 @@ fm10k_dev_interrupt_handler_vf(
        hw->mbx.ops.process(hw, &hw->mbx);
        fm10k_mbx_unlock(hw);
 
+       if (state == FM10K_STATE_OPEN && mbx->state == FM10K_STATE_CONNECT) {
+               PMD_INIT_LOG(INFO, "INT: Switch has gone down");
+
+               fm10k_mbx_lock(hw);
+               hw->mac.ops.update_lport_state(hw, hw->mac.dglort_map,
+                               MAX_LPORT_NUM, 1);
+               fm10k_mbx_unlock(hw);
+
+               /* Setting reset flag */
+               dev_info->sm_down = 1;
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+                               NULL, NULL);
+       }
+
+       if (dev_info->sm_down == 1 &&
+                       hw->mac.dglort_map == FM10K_DGLORTMAP_ZERO) {
+               PMD_INIT_LOG(INFO, "INT: Switch has gone up");
+               fm10k_mbx_lock(hw);
+               status_mbx = hw->mac.ops.update_xcast_mode(hw,
+                               hw->mac.dglort_map, FM10K_XCAST_MODE_NONE);
+               if (status_mbx != FM10K_SUCCESS)
+                       PMD_INIT_LOG(ERR, "Failed to set XCAST mode");
+               fm10k_mbx_unlock(hw);
+
+               /* first clear the internal SW recording structure */
+               fm10k_vlan_filter_set(dev, hw->mac.default_vid, false);
+               fm10k_MAC_filter_set(dev, hw->mac.addr, false,
+                               MAIN_VSI_POOL_NUMBER);
+
+               /*
+                * Add default mac address and vlan for the logical ports that
+                * have been created, leave to the application to fully recover
+                * Rx filtering.
+                */
+               fm10k_MAC_filter_set(dev, hw->mac.addr, true,
+                               MAIN_VSI_POOL_NUMBER);
+               fm10k_vlan_filter_set(dev, hw->mac.default_vid, true);
+
+               dev_info->sm_down = 0;
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+                               NULL, NULL);
+       }
+
        /* Re-enable interrupt from device side */
        FM10K_WRITE_REG(hw, FM10K_VFITR(0), FM10K_ITR_AUTOMASK |
                                        FM10K_ITR_MASK_CLEAR);
        /* Re-enable interrupt from host side */
-       rte_intr_enable(handle);
+       rte_intr_enable(dev->intr_handle);
 }
 
 /* Mailbox message handler in VF */
@@ -2735,6 +2856,28 @@ fm10k_check_ftag(struct rte_devargs *devargs)
        return 1;
 }
 
+static uint16_t
+fm10k_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
+                   uint16_t nb_pkts)
+{
+       uint16_t nb_tx = 0;
+       struct fm10k_tx_queue *txq = (struct fm10k_tx_queue *)tx_queue;
+
+       while (nb_pkts) {
+               uint16_t ret, num;
+
+               num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
+               ret = fm10k_xmit_fixed_burst_vec(tx_queue, &tx_pkts[nb_tx],
+                                                num);
+               nb_tx += ret;
+               nb_pkts -= ret;
+               if (ret < num)
+                       break;
+       }
+
+       return nb_tx;
+}
+
 static void __attribute__((cold))
 fm10k_set_tx_function(struct rte_eth_dev *dev)
 {
@@ -2743,7 +2886,22 @@ fm10k_set_tx_function(struct rte_eth_dev *dev)
        int use_sse = 1;
        uint16_t tx_ftag_en = 0;
 
-       if (fm10k_check_ftag(dev->pci_dev->device.devargs))
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+               /* primary process has set the ftag flag and txq_flags */
+               txq = dev->data->tx_queues[0];
+               if (fm10k_tx_vec_condition_check(txq)) {
+                       dev->tx_pkt_burst = fm10k_xmit_pkts;
+                       dev->tx_pkt_prepare = fm10k_prep_pkts;
+                       PMD_INIT_LOG(DEBUG, "Use regular Tx func");
+               } else {
+                       PMD_INIT_LOG(DEBUG, "Use vector Tx func");
+                       dev->tx_pkt_burst = fm10k_xmit_pkts_vec;
+                       dev->tx_pkt_prepare = NULL;
+               }
+               return;
+       }
+
+       if (fm10k_check_ftag(dev->device->devargs))
                tx_ftag_en = 1;
 
        for (i = 0; i < dev->data->nb_tx_queues; i++) {
@@ -2761,8 +2919,10 @@ fm10k_set_tx_function(struct rte_eth_dev *dev)
                        fm10k_txq_vec_setup(txq);
                }
                dev->tx_pkt_burst = fm10k_xmit_pkts_vec;
+               dev->tx_pkt_prepare = NULL;
        } else {
                dev->tx_pkt_burst = fm10k_xmit_pkts;
+               dev->tx_pkt_prepare = fm10k_prep_pkts;
                PMD_INIT_LOG(DEBUG, "Use regular Tx func");
        }
 }
@@ -2770,11 +2930,12 @@ fm10k_set_tx_function(struct rte_eth_dev *dev)
 static void __attribute__((cold))
 fm10k_set_rx_function(struct rte_eth_dev *dev)
 {
-       struct fm10k_dev_info *dev_info = FM10K_DEV_PRIVATE_TO_INFO(dev);
+       struct fm10k_dev_info *dev_info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
        uint16_t i, rx_using_sse;
        uint16_t rx_ftag_en = 0;
 
-       if (fm10k_check_ftag(dev->pci_dev->device.devargs))
+       if (fm10k_check_ftag(dev->device->devargs))
                rx_ftag_en = 1;
 
        /* In order to allow Vector Rx there are a few configuration
@@ -2800,6 +2961,9 @@ fm10k_set_rx_function(struct rte_eth_dev *dev)
        else
                PMD_INIT_LOG(DEBUG, "Use regular Rx func");
 
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return;
+
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
                struct fm10k_rx_queue *rxq = dev->data->rx_queues[i];
 
@@ -2812,7 +2976,8 @@ static void
 fm10k_params_init(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct fm10k_dev_info *info = FM10K_DEV_PRIVATE_TO_INFO(dev);
+       struct fm10k_dev_info *info =
+               FM10K_DEV_PRIVATE_TO_INFO(dev->data->dev_private);
 
        /* Inialize bus info. Normally we would call fm10k_get_bus_info(), but
         * there is no way to get link status without reading BAR4.  Until this
@@ -2833,7 +2998,7 @@ static int
 eth_fm10k_dev_init(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
        int diag, i;
        struct fm10k_macvlan_filter_info *macvlan;
@@ -2843,10 +3008,17 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
        dev->dev_ops = &fm10k_eth_dev_ops;
        dev->rx_pkt_burst = &fm10k_recv_pkts;
        dev->tx_pkt_burst = &fm10k_xmit_pkts;
+       dev->tx_pkt_prepare = &fm10k_prep_pkts;
 
-       /* only initialize in the primary process */
-       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+       /*
+        * Primary process does the whole initialization, for secondary
+        * processes, we just select the same Rx and Tx function as primary.
+        */
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+               fm10k_set_rx_function(dev);
+               fm10k_set_tx_function(dev);
                return 0;
+       }
 
        rte_eth_copy_pci_info(dev, pdev);
 
@@ -3012,7 +3184,7 @@ static int
 eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
 {
        struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_pci_device *pdev = dev->pci_dev;
+       struct rte_pci_device *pdev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pdev->intr_handle;
        PMD_INIT_FUNC_TRACE();
 
@@ -3057,6 +3229,18 @@ eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
        return 0;
 }
 
+static int eth_fm10k_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+       struct rte_pci_device *pci_dev)
+{
+       return rte_eth_dev_pci_generic_probe(pci_dev,
+               sizeof(struct fm10k_adapter), eth_fm10k_dev_init);
+}
+
+static int eth_fm10k_pci_remove(struct rte_pci_device *pci_dev)
+{
+       return rte_eth_dev_pci_generic_remove(pci_dev, eth_fm10k_dev_uninit);
+}
+
 /*
  * The set of PCI devices this driver supports. This driver will enable both PF
  * and SRIOV-VF devices.
@@ -3068,19 +3252,14 @@ static const struct rte_pci_id pci_id_fm10k_map[] = {
        { .vendor_id = 0, /* sentinel */ },
 };
 
-static struct eth_driver rte_pmd_fm10k = {
-       .pci_drv = {
-               .id_table = pci_id_fm10k_map,
-               .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
-                       RTE_PCI_DRV_DETACHABLE,
-               .probe = rte_eth_dev_pci_probe,
-               .remove = rte_eth_dev_pci_remove,
-       },
-       .eth_dev_init = eth_fm10k_dev_init,
-       .eth_dev_uninit = eth_fm10k_dev_uninit,
-       .dev_private_size = sizeof(struct fm10k_adapter),
+static struct rte_pci_driver rte_pmd_fm10k = {
+       .id_table = pci_id_fm10k_map,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+                    RTE_PCI_DRV_IOVA_AS_VA,
+       .probe = eth_fm10k_pci_probe,
+       .remove = eth_fm10k_pci_remove,
 };
 
-RTE_PMD_REGISTER_PCI(net_fm10k, rte_pmd_fm10k.pci_drv);
+RTE_PMD_REGISTER_PCI(net_fm10k, rte_pmd_fm10k);
 RTE_PMD_REGISTER_PCI_TABLE(net_fm10k, pci_id_fm10k_map);
-RTE_PMD_REGISTER_KMOD_DEP(net_fm10k, "* igb_uio | uio_pci_generic | vfio");
+RTE_PMD_REGISTER_KMOD_DEP(net_fm10k, "* igb_uio | uio_pci_generic | vfio-pci");