DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] eal: postpone vdev initialization
From: Ferruh Yigit @ 2016-11-21 17:35 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <20161121170202.GB5717@svelivela-lt.caveonetworks.com>

On 11/21/2016 5:02 PM, Jerin Jacob wrote:
> On Mon, Nov 21, 2016 at 09:54:57AM +0000, Ferruh Yigit wrote:
>> On 11/20/2016 8:00 AM, Jerin Jacob wrote:
>>> Some platform like octeontx may use pci and
>>> vdev based combined device to represent a logical
>>> dpdk functional device.In such case, postponing the
>>> vdev initialization after pci device
>>> initialization will provide the better view of
>>> the pci device resources in the system in
>>> vdev's probe function, and it allows better
>>> functional subsystem registration in vdev probe
>>> function.
>>>
>>> As a bonus, This patch fixes a bond device
>>> initialization use case.
>>>
>>> example command to reproduce the issue:
>>> ./testpmd -c 0x2  --vdev 'eth_bond0,mode=0,
>>> slave=0000:02:00.0,slave=0000:03:00.0' --
>>> --port-topology=chained
>>>
>>> root cause:
>>> In existing case(vdev initialization and then pci
>>> initialization), creates three Ethernet ports with
>>> following port ids
>>> 0 - Bond device
>>> 1 - PCI device 0
>>> 2 - PCI devive 1
>>>
>>> Since testpmd, calls the configure/start on all the ports on
>>> start up,it will translate to following illegal setup sequence
>>>
>>> 1)bond device configure/start
>>> 1.1) pci device0 stop/configure/start
>>> 1.2) pci device1 stop/configure/start
>>> 2)pci device 0 configure(illegal setup case,
>>> as device in start state)
>>>
>>> The fix changes the initialization sequence and
>>> allow initialization in following valid setup order
>>> 1) pcie device 0 configure/start
>>> 2) pcie device 1 configure/start
>>> 3) bond device 2 configure/start
>>> 3.1) pcie device 0/stop/configure/start
>>> 3.2) pcie device 1/stop/configure/start
>>>
>>> Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>>> ---
>>
>> This changes the port id assignments to the devices, right?
>>
>> Previously virtual devices get first available port ids (0..N1), later
>> physical devices (N1..N2). Now this becomes reverse.
>>
>> Can this change break some existing user applications?
> 
> I guess it may be effected only to ethdev bond pmd based application,
> which is broken anyway.

My concern is, this may effect the applications that use "--vdev" eal
parameter and has an assumption about port assignment.

And if this breaks any userspace application, does it require a
deprecation notice?

> Let me know what it takes to make forward progress on this patch. I can
> fix the same in v2.
> 
> Jerin
> 

^ permalink raw reply

* Re: [PATCH] eal: postpone vdev initialization
From: Jerin Jacob @ 2016-11-21 17:02 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <2bc2559f-5e83-5deb-65f9-750b78a0254a@intel.com>

On Mon, Nov 21, 2016 at 09:54:57AM +0000, Ferruh Yigit wrote:
> On 11/20/2016 8:00 AM, Jerin Jacob wrote:
> > Some platform like octeontx may use pci and
> > vdev based combined device to represent a logical
> > dpdk functional device.In such case, postponing the
> > vdev initialization after pci device
> > initialization will provide the better view of
> > the pci device resources in the system in
> > vdev's probe function, and it allows better
> > functional subsystem registration in vdev probe
> > function.
> > 
> > As a bonus, This patch fixes a bond device
> > initialization use case.
> > 
> > example command to reproduce the issue:
> > ./testpmd -c 0x2  --vdev 'eth_bond0,mode=0,
> > slave=0000:02:00.0,slave=0000:03:00.0' --
> > --port-topology=chained
> > 
> > root cause:
> > In existing case(vdev initialization and then pci
> > initialization), creates three Ethernet ports with
> > following port ids
> > 0 - Bond device
> > 1 - PCI device 0
> > 2 - PCI devive 1
> > 
> > Since testpmd, calls the configure/start on all the ports on
> > start up,it will translate to following illegal setup sequence
> > 
> > 1)bond device configure/start
> > 1.1) pci device0 stop/configure/start
> > 1.2) pci device1 stop/configure/start
> > 2)pci device 0 configure(illegal setup case,
> > as device in start state)
> > 
> > The fix changes the initialization sequence and
> > allow initialization in following valid setup order
> > 1) pcie device 0 configure/start
> > 2) pcie device 1 configure/start
> > 3) bond device 2 configure/start
> > 3.1) pcie device 0/stop/configure/start
> > 3.2) pcie device 1/stop/configure/start
> > 
> > Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > ---
> 
> This changes the port id assignments to the devices, right?
> 
> Previously virtual devices get first available port ids (0..N1), later
> physical devices (N1..N2). Now this becomes reverse.
> 
> Can this change break some existing user applications?

I guess it may be effected only to ethdev bond pmd based application,
which is broken anyway.
Let me know what it takes to make forward progress on this patch. I can
fix the same in v2.

Jerin

^ permalink raw reply

* Re: [PATCH 2/7] eal: Helper to convert to struct rte_pci_device
From: Jan Blunck @ 2016-11-21 16:57 UTC (permalink / raw)
  To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUvju4tv6Z5WXXpYzZkWis3qqH0vOqwYtvvJG3sFYhekmg@mail.gmail.com>

On Sun, Nov 20, 2016 at 4:20 PM, David Marchand
<david.marchand@6wind.com> wrote:
> Hello Jan,
>
> On Sun, Nov 20, 2016 at 11:05 AM, Jan Blunck <jblunck@infradead.org> wrote:
>> Signed-off-by: Jan Blunck <jblunck@infradead.org>
>> ---
>>  lib/librte_eal/common/include/rte_pci.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
>> index 9ce8847..0376160 100644
>> --- a/lib/librte_eal/common/include/rte_pci.h
>> +++ b/lib/librte_eal/common/include/rte_pci.h
>> @@ -160,6 +160,8 @@ struct rte_pci_device {
>>         enum rte_kernel_driver kdrv;            /**< Kernel driver passthrough */
>>  };
>>
>> +#define ETH_DEV_PCI_DEV(ptr) ((ptr)->pci_dev)
>> +
>>  /** Any PCI device identifier (vendor, device, ...) */
>>  #define PCI_ANY_ID (0xffff)
>>  #define RTE_CLASS_ANY_ID (0xffffff)
>
> This should come from ethdev, not eal.
>

Fixed in v2.

Thanks,
Jan

^ permalink raw reply

* [PATCH v2 8/8] ethdev: Decouple interrupt handling from PCI device
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

The struct rte_intr_handle is an abstraction layer for different types of
interrupt mechanisms. It is embedded in the low-level device (e.g. PCI).
On allocation of a struct rte_eth_dev a reference to the intr_handle
should be stored for devices supporting interrupts.

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 lib/librte_ether/rte_ethdev.c | 18 ++++++++++++++++--
 lib/librte_ether/rte_ethdev.h |  1 +
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4288577..4ecea50 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -258,6 +258,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
 			rte_panic("Cannot allocate memzone for private port data\n");
 	}
 	eth_dev->pci_dev = pci_dev;
+	eth_dev->intr_handle = &pci_dev->intr_handle;
 	eth_dev->driver = eth_drv;
 	eth_dev->data->rx_mbuf_alloc_failed = 0;
 
@@ -2543,7 +2544,13 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
 	dev = &rte_eth_devices[port_id];
-	intr_handle = &dev->pci_dev->intr_handle;
+
+	if (!dev->intr_handle) {
+		RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+		return -ENOTSUP;
+	}
+
+	intr_handle = dev->intr_handle;
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -2603,7 +2610,12 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
 		return -EINVAL;
 	}
 
-	intr_handle = &dev->pci_dev->intr_handle;
+	if (!dev->intr_handle) {
+		RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+		return -ENOTSUP;
+	}
+
+	intr_handle = dev->intr_handle;
 	if (!intr_handle->intr_vec) {
 		RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
 		return -EPERM;
@@ -3205,6 +3217,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
 		return;
 	}
 
+	eth_dev->intr_handle = &pci_dev->intr_handle;
+
 	eth_dev->data->dev_flags = 0;
 	if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 3adbb2b..f1f656a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1629,6 +1629,7 @@ struct rte_eth_dev {
 	const struct eth_driver *driver;/**< Driver for this device */
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
 	/** User application callbacks for NIC interrupts */
 	struct rte_eth_dev_cb_list link_intr_cbs;
 	/**
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 7/8] ethdev: Move filling of rte_eth_dev_info->pci_dev to dev_infos_get()
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

Only the device itself can decide its PCI or not.

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 drivers/net/bnx2x/bnx2x_ethdev.c        | 1 +
 drivers/net/bnxt/bnxt_ethdev.c          | 2 ++
 drivers/net/cxgbe/cxgbe_ethdev.c        | 2 ++
 drivers/net/e1000/em_ethdev.c           | 1 +
 drivers/net/e1000/igb_ethdev.c          | 2 ++
 drivers/net/ena/ena_ethdev.c            | 2 ++
 drivers/net/enic/enic_ethdev.c          | 1 +
 drivers/net/fm10k/fm10k_ethdev.c        | 1 +
 drivers/net/i40e/i40e_ethdev.c          | 1 +
 drivers/net/i40e/i40e_ethdev_vf.c       | 1 +
 drivers/net/ixgbe/ixgbe_ethdev.c        | 2 ++
 drivers/net/mlx4/mlx4.c                 | 2 ++
 drivers/net/mlx5/mlx5_ethdev.c          | 2 ++
 drivers/net/nfp/nfp_net.c               | 1 +
 drivers/net/qede/qede_ethdev.c          | 1 +
 drivers/net/szedata2/rte_eth_szedata2.c | 1 +
 drivers/net/thunderx/nicvf_ethdev.c     | 2 ++
 drivers/net/virtio/virtio_ethdev.c      | 1 +
 drivers/net/vmxnet3/vmxnet3_ethdev.c    | 2 ++
 lib/librte_ether/rte_ethdev.c           | 1 -
 20 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 0eae433..06453fe 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -431,6 +431,7 @@ static void
 bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_info *dev_info)
 {
 	struct bnx2x_softc *sc = dev->data->dev_private;
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->max_rx_queues  = sc->max_rx_queues;
 	dev_info->max_tx_queues  = sc->max_tx_queues;
 	dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index cd50f11..bf39fbe 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -303,6 +303,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	uint16_t max_vnics, i, j, vpool, vrxq;
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+
 	/* MAC Specifics */
 	dev_info->max_mac_addrs = MAX_NUM_MAC_ADDR;
 	dev_info->max_hash_mac_addrs = 0;
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8bfdda8..8938b08 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -147,6 +147,8 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 		.nb_align = 1,
 	};
 
+	device_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+
 	device_info->min_rx_bufsize = CXGBE_MIN_RX_BUFSIZE;
 	device_info->max_rx_pktlen = CXGBE_MAX_RX_PKTLEN;
 	device_info->max_rx_queues = max_queues;
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 7f2f521..3d34e5b 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1048,6 +1048,7 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
 	dev_info->max_rx_pktlen = em_get_max_pktlen(hw);
 	dev_info->max_mac_addrs = hw->mac.rar_entry_count;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index b25c66e..7d77561 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1983,6 +1983,7 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
 	dev_info->max_rx_pktlen  = 0x3FFF; /* See RLPML register. */
 	dev_info->max_mac_addrs = hw->mac.rar_entry_count;
@@ -2111,6 +2112,7 @@ eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
 	dev_info->max_rx_pktlen  = 0x3FFF; /* See RLPML register. */
 	dev_info->max_mac_addrs = hw->mac.rar_entry_count;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index c17d969..051275e 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1436,6 +1436,8 @@ static void ena_infos_get(struct rte_eth_dev *dev,
 	ena_dev = &adapter->ena_dev;
 	ena_assert_msg(ena_dev != NULL, "Uninitialized device");
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
 	dev_info->speed_capa =
 			ETH_LINK_SPEED_1G   |
 			ETH_LINK_SPEED_2_5G |
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 553a88e..bb5dfe6 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -459,6 +459,7 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 	struct enic *enic = pmd_priv(eth_dev);
 
 	ENICPMD_FUNC_TRACE();
+	device_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	/* Scattered Rx uses two receive queues per rx queue exposed to dpdk */
 	device_info->max_rx_queues = enic->conf_rq_count / 2;
 	device_info->max_tx_queues = enic->conf_wq_count;
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e1250f6..5d0bce5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1392,6 +1392,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
+	dev_info->pci_dev            = ETH_DEV_PCI_DEV(dev);
 	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;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8a63a8c..29c0277 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2583,6 +2583,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *vsi = pf->main_vsi;
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->max_rx_queues = vsi->nb_qps;
 	dev_info->max_tx_queues = vsi->nb_qps;
 	dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 781e658..caef72c 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2217,6 +2217,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	memset(dev_info, 0, sizeof(*dev_info));
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;
 	dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
 	dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index f17da46..c88b7bf 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3043,6 +3043,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
 	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
 	if (RTE_ETH_DEV_SRIOV(dev).active == 0) {
@@ -3175,6 +3176,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
 	dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL reg */
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index da61a85..5455fea 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4421,6 +4421,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	unsigned int max;
 	char ifname[IF_NAMESIZE];
 
+	info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
 	if (priv == NULL)
 		return;
 	priv_lock(priv);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index c0f73e9..489a4f6 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -562,6 +562,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	unsigned int max;
 	char ifname[IF_NAMESIZE];
 
+	info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
 	priv_lock(priv);
 	/* FIXME: we should ask the device for these values. */
 	info->min_rx_bufsize = 32;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index c6b1587..41eaf90 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1006,6 +1006,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->driver_name = dev->driver->pci_drv.driver.name;
 	dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 959ff0f..2c4de92 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -652,6 +652,7 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	PMD_INIT_FUNC_TRACE(edev);
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	dev_info->min_rx_bufsize = (uint32_t)(ETHER_MIN_MTU +
 					      QEDE_ETH_OVERHEAD);
 	dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN;
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index f3cd52d..585087a 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1030,6 +1030,7 @@ eth_dev_info(struct rte_eth_dev *dev,
 		struct rte_eth_dev_info *dev_info)
 {
 	struct pmd_internals *internals = dev->data->dev_private;
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
 	dev_info->if_index = 0;
 	dev_info->max_mac_addrs = 1;
 	dev_info->max_rx_pktlen = (uint32_t)-1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 466e49c..42ad340 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -1338,6 +1338,8 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	PMD_INIT_FUNC_TRACE();
 
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
 	dev_info->min_rx_bufsize = ETHER_MIN_MTU;
 	dev_info->max_rx_pktlen = NIC_HW_MAX_FRS;
 	dev_info->max_rx_queues =
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 023101d..2eb6a06 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1625,6 +1625,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	uint64_t tso_mask;
 	struct virtio_hw *hw = dev->data->dev_private;
 
+	dev_info->pci_dev = hw->dev;
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
 	dev_info->max_tx_queues =
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index bcb3751..f7c0382 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -709,6 +709,8 @@ static void
 vmxnet3_dev_info_get(__rte_unused struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
 {
+	dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
 	dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
 	dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
 	dev_info->min_rx_bufsize = 1518 + RTE_PKTMBUF_HEADROOM;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..4288577 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1556,7 +1556,6 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 
 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
-	dev_info->pci_dev = dev->pci_dev;
 	dev_info->driver_name = dev->data->drv_name;
 	dev_info->nb_rx_queues = dev->data->nb_rx_queues;
 	dev_info->nb_tx_queues = dev->data->nb_tx_queues;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 6/8] virtio: Don't depend on struct rte_eth_dev's pci_dev
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

We don't need to depend on rte_eth_dev->pci_dev to differentiate between
the virtio_user and the virtio_pci case. Instead we can use the private
virtio_hw struct to get that information.

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 drivers/net/virtio/virtio_ethdev.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index da9668e..023101d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -483,11 +483,11 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
 		hw->cvq = cvq;
 	}
 
-	/* For virtio_user case (that is when dev->pci_dev is NULL), we use
+	/* For virtio_user case (that is when hw->dev is NULL), we use
 	 * virtual address. And we need properly set _offset_, please see
 	 * VIRTIO_MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
 	 */
-	if (dev->pci_dev)
+	if (hw->dev)
 		vq->offset = offsetof(struct rte_mbuf, buf_physaddr);
 	else {
 		vq->vq_ring_mem = (uintptr_t)mz->addr;
@@ -1190,7 +1190,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 	struct virtio_net_config *config;
 	struct virtio_net_config local_config;
-	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+	struct rte_pci_device *pci_dev = hw->dev;
 	int ret;
 
 	/* Reset the device although not necessary at startup */
@@ -1294,7 +1294,6 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
-	struct rte_pci_device *pci_dev;
 	uint32_t dev_flags = RTE_ETH_DEV_DETACHABLE;
 	int ret;
 
@@ -1317,10 +1316,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 		return -ENOMEM;
 	}
 
-	pci_dev = eth_dev->pci_dev;
-
-	if (pci_dev) {
-		ret = vtpci_init(pci_dev, hw, &dev_flags);
+	/* For virtio_user case the hw->virtio_user_dev is populated by
+	 * virtio_user_eth_dev_alloc() before eth_virtio_dev_init() is called.
+	 */
+	if (!hw->virtio_user_dev) {
+		ret = vtpci_init(ETH_DEV_PCI_DEV(eth_dev), hw, &dev_flags);
 		if (ret)
 			return ret;
 	}
@@ -1343,7 +1343,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 static int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
-	struct rte_pci_device *pci_dev;
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1353,7 +1352,6 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	virtio_dev_stop(eth_dev);
 	virtio_dev_close(eth_dev);
-	pci_dev = eth_dev->pci_dev;
 
 	eth_dev->dev_ops = NULL;
 	eth_dev->tx_pkt_burst = NULL;
@@ -1367,7 +1365,8 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 		rte_intr_callback_unregister(vtpci_intr_handle(hw),
 						virtio_interrupt_handler,
 						eth_dev);
-	rte_eal_pci_unmap_device(pci_dev);
+	if (hw->dev)
+		rte_eal_pci_unmap_device(hw->dev);
 
 	PMD_INIT_LOG(DEBUG, "dev_uninit completed");
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 5/8] virtio: Add vtpci_intr_handle() helper to get rte_intr_handle
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

This adds a helper to get the rte_intr_handle from the virtio_hw. This is
safe to do since the usage of the helper is guarded by RTE_ETH_DEV_INTR_LSC
which is only set if we found a PCI device during initialization.

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 drivers/net/virtio/virtio_ethdev.c | 12 +++++++-----
 drivers/net/virtio/virtio_pci.h    |  6 ++++++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 741688e..da9668e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1162,7 +1162,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
 	isr = vtpci_isr(hw);
 	PMD_DRV_LOG(INFO, "interrupt status = %#x", isr);
 
-	if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0)
+	if (rte_intr_enable(vtpci_intr_handle(hw)) < 0)
 		PMD_DRV_LOG(ERR, "interrupt enable failed");
 
 	if (isr & VIRTIO_PCI_ISR_CONFIG) {
@@ -1334,7 +1334,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 	/* Setup interrupt callback  */
 	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		rte_intr_callback_register(&pci_dev->intr_handle,
+		rte_intr_callback_register(vtpci_intr_handle(hw),
 			virtio_interrupt_handler, eth_dev);
 
 	return 0;
@@ -1344,6 +1344,7 @@ static int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev;
+	struct virtio_hw *hw = eth_dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1363,7 +1364,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 
 	/* reset interrupt callback  */
 	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		rte_intr_callback_unregister(&pci_dev->intr_handle,
+		rte_intr_callback_unregister(vtpci_intr_handle(hw),
 						virtio_interrupt_handler,
 						eth_dev);
 	rte_eal_pci_unmap_device(pci_dev);
@@ -1481,7 +1482,7 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			return -ENOTSUP;
 		}
 
-		if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
+		if (rte_intr_enable(vtpci_intr_handle(hw)) < 0) {
 			PMD_DRV_LOG(ERR, "interrupt enable failed");
 			return -EIO;
 		}
@@ -1573,12 +1574,13 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
+	struct virtio_hw *hw = dev->data->dev_private;
 	struct rte_eth_link link;
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
 	if (dev->data->dev_conf.intr_conf.lsc)
-		rte_intr_disable(&dev->pci_dev->intr_handle);
+		rte_intr_disable(vtpci_intr_handle(hw));
 
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index de271bf..5373e39 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -317,4 +317,10 @@ uint8_t vtpci_isr(struct virtio_hw *);
 
 uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
 
+static inline struct rte_intr_handle *
+vtpci_intr_handle(struct virtio_hw *hw)
+{
+	return hw->dev ? &hw->dev->intr_handle : NULL;
+}
+
 #endif /* _VIRTIO_PCI_H_ */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/8] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

This is overwritten in rte_eth_dev_info_get().

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 drivers/net/virtio/virtio_ethdev.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..741688e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	uint64_t tso_mask;
 	struct virtio_hw *hw = dev->data->dev_private;
 
-	if (dev->pci_dev)
-		dev_info->driver_name = dev->driver->pci_drv.driver.name;
-	else
-		dev_info->driver_name = "virtio_user PMD";
 	dev_info->max_rx_queues =
 		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
 	dev_info->max_tx_queues =
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/8] drivers: Use ETH_DEV_PCI_DEV() helper
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

The drivers should not directly access the rte_eth_dev->pci_dev but use
a macro instead. This is a preparation for replacing the pci_dev with
a struct rte_device member in the future.

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 drivers/net/bnxt/bnxt_ethdev.c       | 19 ++++++-----
 drivers/net/bnxt/bnxt_ring.c         | 11 +++---
 drivers/net/cxgbe/cxgbe_ethdev.c     |  2 +-
 drivers/net/e1000/em_ethdev.c        | 20 ++++++-----
 drivers/net/e1000/igb_ethdev.c       | 50 +++++++++++++++------------
 drivers/net/e1000/igb_pf.c           |  3 +-
 drivers/net/ena/ena_ethdev.c         |  2 +-
 drivers/net/enic/enic_ethdev.c       |  2 +-
 drivers/net/fm10k/fm10k_ethdev.c     | 49 ++++++++++++++-------------
 drivers/net/i40e/i40e_ethdev.c       | 44 ++++++++++++------------
 drivers/net/i40e/i40e_ethdev.h       |  4 +++
 drivers/net/i40e/i40e_ethdev_vf.c    | 38 ++++++++++-----------
 drivers/net/ixgbe/ixgbe_ethdev.c     | 65 +++++++++++++++++++++---------------
 drivers/net/ixgbe/ixgbe_pf.c         |  2 +-
 drivers/net/qede/qede_ethdev.c       | 17 +++++-----
 drivers/net/vmxnet3/vmxnet3_ethdev.c |  4 +--
 16 files changed, 185 insertions(+), 147 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 035fe07..cd50f11 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -743,6 +743,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	/* Retrieve from the default VNIC */
 	if (!vnic)
@@ -759,7 +760,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
 	/* EW - need to revisit here copying from u64 to u16 */
 	memcpy(reta_conf, vnic->rss_table, reta_size);
 
-	if (rte_intr_allow_others(&eth_dev->pci_dev->intr_handle)) {
+	if (rte_intr_allow_others(&pci_dev->intr_handle)) {
 		if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
 			bnxt_dev_lsc_intr_setup(eth_dev);
 	}
@@ -1011,9 +1012,10 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 {
 	int rc;
 	struct bnxt *bp = eth_dev->data->dev_private;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
-	if (!eth_dev->pci_dev->mem_resource[0].addr) {
+	if (!pci_dev->mem_resource[0].addr) {
 		RTE_LOG(ERR, PMD,
 			"Cannot find PCI device base address, aborting\n");
 		rc = -ENODEV;
@@ -1021,9 +1023,9 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 	}
 
 	bp->eth_dev = eth_dev;
-	bp->pdev = eth_dev->pci_dev;
+	bp->pdev = pci_dev;
 
-	bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+	bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
 	if (!bp->bar0) {
 		RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
 		rc = -ENOMEM;
@@ -1043,6 +1045,7 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	static int version_printed;
 	struct bnxt *bp;
 	int rc;
@@ -1050,10 +1053,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (version_printed++ == 0)
 		RTE_LOG(INFO, PMD, "%s", bnxt_version);
 
-	rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	bp = eth_dev->data->dev_private;
 
-	if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
+	if (bnxt_vf_pciid(pci_dev->id.device_id))
 		bp->flags |= BNXT_FLAG_VF;
 
 	rc = bnxt_init_board(eth_dev);
@@ -1121,8 +1124,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 
 	RTE_LOG(INFO, PMD,
 		DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
-		eth_dev->pci_dev->mem_resource[0].phys_addr,
-		eth_dev->pci_dev->mem_resource[0].addr);
+		pci_dev->mem_resource[0].phys_addr,
+		pci_dev->mem_resource[0].addr);
 
 	bp->dev_stopped = 0;
 
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 3f81ffc..6793d75 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -209,6 +209,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
  */
 int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 {
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(bp->eth_dev);
 	unsigned int i;
 	int rc = 0;
 
@@ -223,7 +224,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell =
-		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr;
+		    (char *)pci_dev->mem_resource[2].addr;
 		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 		bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
 	}
@@ -243,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell =
-		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+		    (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
 		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
 		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -256,7 +257,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 			goto err_out;
 		rxr->rx_prod = 0;
 		rxr->rx_doorbell =
-		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+		    (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
 		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -284,7 +285,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 			goto err_out;
 
 		cpr->cp_doorbell =
-		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+		    (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
 		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
 		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -297,7 +298,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 			goto err_out;
 
 		txr->tx_doorbell =
-		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+		    (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
 	}
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index b7f28eb..8bfdda8 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1005,7 +1005,7 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
 	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..7f2f521 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -295,7 +295,7 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
 	struct e1000_vfta * shadow_vfta =
 		E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	eth_dev->dev_ops = &eth_em_ops;
 	eth_dev->rx_pkt_burst = (eth_rx_burst_t)&eth_em_recv_pkts;
@@ -369,7 +369,7 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	if (adapter->stopped == 0)
 		eth_em_close(eth_dev);
@@ -556,7 +556,8 @@ eth_em_start(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE(dev->data->dev_private);
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t *speeds;
@@ -738,7 +739,8 @@ eth_em_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
 	em_rxq_intr_disable(hw);
 	em_lsc_intr_disable(hw);
@@ -999,9 +1001,10 @@ static int
 eth_em_rx_queue_intr_enable(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	em_rxq_intr_enable(hw);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(&pci_dev->intr_handle);
 
 	return 0;
 }
@@ -1542,6 +1545,7 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 	uint32_t tctl, rctl;
 	struct rte_eth_link link;
 	int ret;
@@ -1550,7 +1554,7 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
 		return -1;
 
 	intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
-	rte_intr_enable(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(&pci_dev->intr_handle);
 
 	/* set get_link_status to check register later */
 	hw->mac.get_link_status = 1;
@@ -1571,8 +1575,8 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
 		PMD_INIT_LOG(INFO, " Port %d: Link Down", dev->data->port_id);
 	}
 	PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
-		     dev->pci_dev->addr.domain, dev->pci_dev->addr.bus,
-		     dev->pci_dev->addr.devid, dev->pci_dev->addr.function);
+		     pci_dev->addr.domain, pci_dev->addr.bus,
+		     pci_dev->addr.devid, pci_dev->addr.function);
 
 	tctl = E1000_READ_REG(hw, E1000_TCTL);
 	rctl = E1000_READ_REG(hw, E1000_RCTL);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..b25c66e 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -672,11 +672,11 @@ igb_identify_hardware(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw =
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-
-	hw->vendor_id = dev->pci_dev->id.vendor_id;
-	hw->device_id = dev->pci_dev->id.device_id;
-	hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
-	hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+	hw->vendor_id = pci_dev->id.vendor_id;
+	hw->device_id = pci_dev->id.device_id;
+	hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+	hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
 
 	e1000_set_mac_type(hw);
 
@@ -755,7 +755,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
 
 	uint32_t ctrl_ext;
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	eth_dev->dev_ops = &eth_igb_ops;
 	eth_dev->rx_pkt_burst = &eth_igb_recv_pkts;
@@ -918,7 +918,7 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev)
 		return -EPERM;
 
 	hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	if (adapter->stopped == 0)
 		eth_igb_close(eth_dev);
@@ -973,7 +973,7 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
@@ -1050,7 +1050,7 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct e1000_adapter *adapter =
 		E1000_DEV_PRIVATE(eth_dev->data->dev_private);
-	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1217,7 +1217,8 @@ eth_igb_start(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct e1000_adapter *adapter =
 		E1000_DEV_PRIVATE(dev->data->dev_private);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle =
+		&ETH_DEV_PCI_DEV(dev)->intr_handle;
 	int ret, mask;
 	uint32_t intr_vector = 0;
 	uint32_t ctrl_ext;
@@ -1429,7 +1430,8 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	struct e1000_flex_filter *p_flex;
 	struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
 	struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle =
+		&ETH_DEV_PCI_DEV(dev)->intr_handle;
 
 	igb_intr_disable(hw);
 
@@ -1549,7 +1551,7 @@ eth_igb_close(struct rte_eth_dev *dev)
 
 	igb_dev_free_queues(dev);
 
-	pci_dev = dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(dev);
 	if (pci_dev->intr_handle.intr_vec) {
 		rte_free(pci_dev->intr_handle.intr_vec);
 		pci_dev->intr_handle.intr_vec = NULL;
@@ -2639,6 +2641,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
 		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct e1000_interrupt *intr =
 		E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 	uint32_t tctl, rctl;
 	struct rte_eth_link link;
 	int ret;
@@ -2649,7 +2652,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
 	}
 
 	igb_intr_enable(dev);
-	rte_intr_enable(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(&pci_dev->intr_handle);
 
 	if (intr->flags & E1000_FLAG_NEED_LINK_UPDATE) {
 		intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
@@ -2677,10 +2680,10 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
 		}
 
 		PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
-			     dev->pci_dev->addr.domain,
-			     dev->pci_dev->addr.bus,
-			     dev->pci_dev->addr.devid,
-			     dev->pci_dev->addr.function);
+			     pci_dev->addr.domain,
+			     pci_dev->addr.bus,
+			     pci_dev->addr.devid,
+			     pci_dev->addr.function);
 		tctl = E1000_READ_REG(hw, E1000_TCTL);
 		rctl = E1000_READ_REG(hw, E1000_RCTL);
 		if (link.link_status) {
@@ -2770,7 +2773,7 @@ eth_igbvf_interrupt_action(struct rte_eth_dev *dev)
 	}
 
 	igbvf_intr_enable(dev);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(&ETH_DEV_PCI_DEV(dev)->intr_handle);
 
 	return 0;
 }
@@ -3056,7 +3059,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
 	struct e1000_adapter *adapter =
 		E1000_DEV_PRIVATE(dev->data->dev_private);
 	int ret;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle =
+		&ETH_DEV_PCI_DEV(dev)->intr_handle;
 	uint32_t intr_vector = 0;
 
 	PMD_INIT_FUNC_TRACE();
@@ -3110,7 +3114,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
 static void
 igbvf_dev_stop(struct rte_eth_dev *dev)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle =
+		&ETH_DEV_PCI_DEV(dev)->intr_handle;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -5102,7 +5107,7 @@ eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 	E1000_WRITE_REG(hw, E1000_EIMS, regval | mask);
 	E1000_WRITE_FLUSH(hw);
 
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(&ETH_DEV_PCI_DEV(dev)->intr_handle);
 
 	return 0;
 }
@@ -5167,7 +5172,8 @@ eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
 	uint32_t base = E1000_MISC_VEC_ID;
 	uint32_t misc_shift = 0;
 
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle =
+		&ETH_DEV_PCI_DEV(dev)->intr_handle;
 
 	/* won't configure msix register if no mapping is done
 	 * between intr vector and event fd
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 5845bc2..6a72ee1 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -57,7 +57,8 @@
 static inline uint16_t
 dev_num_vf(struct rte_eth_dev *eth_dev)
 {
-	return eth_dev->pci_dev->max_vfs;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+	return pci_dev->max_vfs;
 }
 
 static inline
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index ab9a178..c17d969 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1278,7 +1278,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	adapter->pdev = pci_dev;
 
 	PMD_INIT_LOG(INFO, "Initializing %x:%x:%x.%d\n",
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2b154ec..553a88e 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -621,7 +621,7 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_pkt_burst = &enic_recv_pkts;
 	eth_dev->tx_pkt_burst = &enic_xmit_pkts;
 
-	pdev = eth_dev->pci_dev;
+	pdev = ETH_DEV_PCI_DEV(eth_dev);
 	rte_eth_copy_pci_info(eth_dev, pdev);
 	enic->pdev = pdev;
 	addr = &pdev->addr;
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 923690c..e1250f6 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -59,7 +59,8 @@
 #define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1)
 
 /* default 1:1 map from queue ID to interrupt vector ID */
-#define Q2V(dev, queue_id) (dev->pci_dev->intr_handle.intr_vec[queue_id])
+#define D2IH(dev) (&ETH_DEV_PCI_DEV(dev)->intr_handle)
+#define Q2V(dev, queue_id) (D2IH(dev)->intr_vec[queue_id])
 
 /* First 64 Logical ports for PF/VMDQ, second 64 for Flow director */
 #define MAX_LPORT_NUM    128
@@ -711,7 +712,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_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = D2IH(dev);
 	int i, ret;
 	struct fm10k_rx_queue *rxq;
 	uint64_t base_addr;
@@ -1171,7 +1172,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_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = D2IH(dev);
 	int i;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1387,6 +1388,7 @@ 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 *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1396,7 +1398,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	dev_info->max_tx_queues      = hw->mac.max_queues;
 	dev_info->max_mac_addrs      = FM10K_MAX_MACADDR_NUM;
 	dev_info->max_hash_mac_addrs = 0;
-	dev_info->max_vfs            = dev->pci_dev->max_vfs;
+	dev_info->max_vfs            = pci_dev->max_vfs;
 	dev_info->vmdq_pool_base     = 0;
 	dev_info->vmdq_queue_base    = 0;
 	dev_info->max_vmdq_pools     = ETH_32_POOLS;
@@ -2341,7 +2343,7 @@ fm10k_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 	else
 		FM10K_WRITE_REG(hw, FM10K_VFITR(Q2V(dev, queue_id)),
 			FM10K_ITR_AUTOMASK | FM10K_ITR_MASK_CLEAR);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(D2IH(dev));
 	return 0;
 }
 
@@ -2364,7 +2366,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_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = D2IH(dev);
 	uint32_t intr_vector, vec;
 	uint16_t queue_id;
 	int result = 0;
@@ -2380,7 +2382,7 @@ fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
 	intr_vector = dev->data->nb_rx_queues;
 
 	/* disable interrupt first */
-	rte_intr_disable(&dev->pci_dev->intr_handle);
+	rte_intr_disable(intr_handle);
 	if (hw->mac.type == fm10k_mac_pf)
 		fm10k_dev_disable_intr_pf(dev);
 	else
@@ -2415,7 +2417,7 @@ fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
 		fm10k_dev_enable_intr_pf(dev);
 	else
 		fm10k_dev_enable_intr_vf(dev);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(intr_handle);
 	hw->mac.ops.update_int_moderator(hw);
 	return result;
 }
@@ -2581,7 +2583,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(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(D2IH(dev));
 }
 
 /**
@@ -2615,7 +2617,7 @@ fm10k_dev_interrupt_handler_vf(
 	FM10K_WRITE_REG(hw, FM10K_VFITR(0), FM10K_ITR_AUTOMASK |
 					FM10K_ITR_MASK_CLEAR);
 	/* Re-enable interrupt from host side */
-	rte_intr_enable(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(D2IH(dev));
 }
 
 /* Mailbox message handler in VF */
@@ -2827,6 +2829,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 *pci_dev = ETH_DEV_PCI_DEV(dev);
 	int diag, i;
 	struct fm10k_macvlan_filter_info *macvlan;
 
@@ -2840,18 +2843,18 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	rte_eth_copy_pci_info(dev, dev->pci_dev);
+	rte_eth_copy_pci_info(dev, pci_dev);
 
 	macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data->dev_private);
 	memset(macvlan, 0, sizeof(*macvlan));
 	/* Vendor and Device ID need to be set before init of shared code */
 	memset(hw, 0, sizeof(*hw));
-	hw->device_id = dev->pci_dev->id.device_id;
-	hw->vendor_id = dev->pci_dev->id.vendor_id;
-	hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
-	hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
+	hw->device_id = pci_dev->id.device_id;
+	hw->vendor_id = pci_dev->id.vendor_id;
+	hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+	hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
 	hw->revision_id = 0;
-	hw->hw_addr = (void *)dev->pci_dev->mem_resource[0].addr;
+	hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
 	if (hw->hw_addr == NULL) {
 		PMD_INIT_LOG(ERR, "Bad mem resource."
 			" Try to blacklist unused devices.");
@@ -2921,20 +2924,20 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
 	/*PF/VF has different interrupt handling mechanism */
 	if (hw->mac.type == fm10k_mac_pf) {
 		/* register callback func to eal lib */
-		rte_intr_callback_register(&(dev->pci_dev->intr_handle),
+		rte_intr_callback_register(D2IH(dev),
 			fm10k_dev_interrupt_handler_pf, (void *)dev);
 
 		/* enable MISC interrupt */
 		fm10k_dev_enable_intr_pf(dev);
 	} else { /* VF */
-		rte_intr_callback_register(&(dev->pci_dev->intr_handle),
+		rte_intr_callback_register(D2IH(dev),
 			fm10k_dev_interrupt_handler_vf, (void *)dev);
 
 		fm10k_dev_enable_intr_vf(dev);
 	}
 
 	/* Enable intr after callback registered */
-	rte_intr_enable(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(D2IH(dev));
 
 	hw->mac.ops.update_int_moderator(hw);
 
@@ -3004,7 +3007,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_intr_handle *intr_handle = D2IH(dev);
 	PMD_INIT_FUNC_TRACE();
 
 	/* only uninitialize in the primary process */
@@ -3019,7 +3022,7 @@ eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
 	dev->tx_pkt_burst = NULL;
 
 	/* disable uio/vfio intr */
-	rte_intr_disable(&(dev->pci_dev->intr_handle));
+	rte_intr_disable(intr_handle);
 
 	/*PF/VF has different interrupt handling mechanism */
 	if (hw->mac.type == fm10k_mac_pf) {
@@ -3027,13 +3030,13 @@ eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
 		fm10k_dev_disable_intr_pf(dev);
 
 		/* unregister callback func to eal lib */
-		rte_intr_callback_unregister(&(dev->pci_dev->intr_handle),
+		rte_intr_callback_unregister(intr_handle,
 			fm10k_dev_interrupt_handler_pf, (void *)dev);
 	} else {
 		/* disable interrupt */
 		fm10k_dev_disable_intr_vf(dev);
 
-		rte_intr_callback_unregister(&(dev->pci_dev->intr_handle),
+		rte_intr_callback_unregister(intr_handle,
 			fm10k_dev_interrupt_handler_vf, (void *)dev);
 	}
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..8a63a8c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -907,7 +907,7 @@ is_floating_veb_supported(struct rte_devargs *devargs)
 static void
 config_floating_veb(struct rte_eth_dev *dev)
 {
-	struct rte_pci_device *pci_dev = dev->pci_dev;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_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);
 
@@ -952,7 +952,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
 		i40e_set_tx_function(dev);
 		return 0;
 	}
-	pci_dev = dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	rte_eth_copy_pci_info(dev, pci_dev);
 
@@ -1215,7 +1215,7 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
 		return 0;
 
 	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	pci_dev = dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	if (hw->adapter_stopped == 0)
 		i40e_dev_close(dev);
@@ -1335,7 +1335,7 @@ void
 i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
 {
 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
 	uint16_t msix_vect = vsi->msix_intr;
 	uint16_t i;
@@ -1448,7 +1448,7 @@ void
 i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi)
 {
 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
 	uint16_t msix_vect = vsi->msix_intr;
 	uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
@@ -1519,7 +1519,7 @@ static void
 i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
 {
 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
 	uint16_t interval = i40e_calc_itr_interval(\
 		RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1550,7 +1550,7 @@ static void
 i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
 {
 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
 	uint16_t msix_intr, i;
 
@@ -1675,7 +1675,7 @@ i40e_dev_start(struct rte_eth_dev *dev)
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vsi *main_vsi = pf->main_vsi;
 	int ret, i;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	uint32_t intr_vector = 0;
 
 	hw->adapter_stopped = 0;
@@ -1808,7 +1808,7 @@ i40e_dev_stop(struct rte_eth_dev *dev)
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_vsi *main_vsi = pf->main_vsi;
 	struct i40e_mirror_rule *p_mirror;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	int i;
 
 	/* Disable all queues */
@@ -1870,7 +1870,7 @@ i40e_dev_close(struct rte_eth_dev *dev)
 
 	/* Disable interrupt */
 	i40e_pf_disable_irq0(hw);
-	rte_intr_disable(&(dev->pci_dev->intr_handle));
+	rte_intr_disable(ETH_DEV_TO_INTR_HANDLE(dev));
 
 	/* shutdown and destroy the HMC */
 	i40e_shutdown_lan_hmc(hw);
@@ -2588,7 +2588,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
 	dev_info->max_mac_addrs = vsi->max_macaddrs;
-	dev_info->max_vfs = dev->pci_dev->max_vfs;
+	dev_info->max_vfs = ETH_DEV_PCI_DEV(dev)->max_vfs;
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_VLAN_STRIP |
 		DEV_RX_OFFLOAD_QINQ_STRIP |
@@ -3488,11 +3488,12 @@ i40e_get_cap(struct i40e_hw *hw)
 static int
 i40e_pf_parameter_init(struct rte_eth_dev *dev)
 {
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
 	uint16_t qp_count = 0, vsi_count = 0;
 
-	if (dev->pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
+	if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
 		PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV");
 		return -EINVAL;
 	}
@@ -3533,10 +3534,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
 
 	/* VF queue/VSI allocation */
 	pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps;
-	if (hw->func_caps.sr_iov_1_1 && dev->pci_dev->max_vfs) {
+	if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) {
 		pf->flags |= I40E_FLAG_SRIOV;
 		pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
-		pf->vf_num = dev->pci_dev->max_vfs;
+		pf->vf_num = pci_dev->max_vfs;
 		PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, "
 			    "in total %u queues", pf->vf_num, pf->vf_nb_qps,
 			    pf->vf_nb_qps * pf->vf_num);
@@ -5573,7 +5574,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
 done:
 	/* Enable interrupt */
 	i40e_pf_enable_irq0(hw);
-	rte_intr_enable(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 }
 
 static int
@@ -8124,10 +8125,11 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void
 i40e_enable_extended_tag(struct rte_eth_dev *dev)
 {
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 	uint32_t buf = 0;
 	int ret;
 
-	ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+	ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
 				      PCI_DEV_CAP_REG);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8140,7 +8142,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
 	}
 
 	buf = 0;
-	ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+	ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
 				      PCI_DEV_CTRL_REG);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8152,7 +8154,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
 		return;
 	}
 	buf |= PCI_DEV_CTRL_EXT_TAG_MASK;
-	ret = rte_eal_pci_write_config(dev->pci_dev, &buf, sizeof(buf),
+	ret = rte_eal_pci_write_config(pci_dev, &buf, sizeof(buf),
 				       PCI_DEV_CTRL_REG);
 	if (ret < 0) {
 		PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x",
@@ -9555,7 +9557,7 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
 static int
 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t interval =
 		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -9580,7 +9582,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 				I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
 
 	I40E_WRITE_FLUSH(hw);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 
 	return 0;
 }
@@ -9588,7 +9590,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 static int
 i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t msix_intr;
 
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 298cef4..9d4bea7 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -671,6 +671,10 @@ i40e_get_vsi_from_adapter(struct i40e_adapter *adapter)
 #define I40E_VF_TO_HW(vf) \
 	(&(((struct i40e_vf *)vf)->adapter->hw))
 
+/* ETH_DEV_TO_INTR_HANDLE */
+#define ETH_DEV_TO_INTR_HANDLE(ptr) \
+	(&(ETH_DEV_PCI_DEV(ptr)->intr_handle))
+
 static inline void
 i40e_init_adminq_parameter(struct i40e_hw *hw)
 {
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..781e658 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -718,7 +718,7 @@ i40evf_config_irq_map(struct rte_eth_dev *dev)
 	uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_irq_map_info) + \
 		sizeof(struct i40e_virtchnl_vector_map)];
 	struct i40e_virtchnl_irq_map_info *map_info;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	uint32_t vector_id;
 	int i, err;
 
@@ -1431,7 +1431,7 @@ i40evf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
 
 done:
 	i40evf_enable_irq0(hw);
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 }
 
 static int
@@ -1439,7 +1439,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(\
 			eth_dev->data->dev_private);
-	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1458,15 +1458,15 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
-	hw->vendor_id = eth_dev->pci_dev->id.vendor_id;
-	hw->device_id = eth_dev->pci_dev->id.device_id;
-	hw->subsystem_vendor_id = eth_dev->pci_dev->id.subsystem_vendor_id;
-	hw->subsystem_device_id = eth_dev->pci_dev->id.subsystem_device_id;
-	hw->bus.device = eth_dev->pci_dev->addr.devid;
-	hw->bus.func = eth_dev->pci_dev->addr.function;
-	hw->hw_addr = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+	hw->vendor_id = pci_dev->id.vendor_id;
+	hw->device_id = pci_dev->id.device_id;
+	hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+	hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+	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;
 
 	if(i40evf_init_vf(eth_dev) != 0) {
@@ -1853,7 +1853,7 @@ i40evf_enable_queues_intr(struct rte_eth_dev *dev)
 {
 	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);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 
 	if (!rte_intr_allow_others(intr_handle)) {
 		I40E_WRITE_REG(hw,
@@ -1885,7 +1885,7 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
 {
 	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);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 
 	if (!rte_intr_allow_others(intr_handle)) {
 		I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
@@ -1911,7 +1911,7 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
 static int
 i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t interval =
 		i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1937,7 +1937,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 
 	I40EVF_WRITE_FLUSH(hw);
 
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 
 	return 0;
 }
@@ -1945,7 +1945,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 static int
 i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint16_t msix_intr;
 
@@ -2025,7 +2025,7 @@ i40evf_dev_start(struct rte_eth_dev *dev)
 {
 	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);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	uint32_t intr_vector = 0;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2090,7 +2090,7 @@ i40evf_dev_start(struct rte_eth_dev *dev)
 static void
 i40evf_dev_stop(struct rte_eth_dev *dev)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -2285,7 +2285,7 @@ static void
 i40evf_dev_close(struct rte_eth_dev *dev)
 {
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct rte_pci_device *pci_dev = dev->pci_dev;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	i40evf_dev_stop(dev);
 	hw->adapter_stopped = 1;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..f17da46 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -427,6 +427,9 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 		(r) = (h)->bitmap[idx] >> bit & 1;\
 	} while (0)
 
+#define ETH_DEV_TO_INTR_HANDLE(ptr)			\
+	(&(ETH_DEV_PCI_DEV(ptr)->intr_handle))
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -1127,7 +1130,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 
 		return 0;
 	}
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
@@ -1302,7 +1305,7 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 		return -EPERM;
 
 	hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	if (hw->adapter_stopped == 0)
 		ixgbe_dev_close(eth_dev);
@@ -1419,7 +1422,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
@@ -1532,7 +1535,9 @@ static int
 eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct ixgbe_hw *hw;
-	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+	struct rte_pci_device *pci_dev;
+
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1960,7 +1965,8 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
 	}
 
 	RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
-	RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = dev->pci_dev->max_vfs * nb_rx_q;
+	RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx =
+		ETH_DEV_PCI_DEV(dev)->max_vfs * nb_rx_q;
 
 	return 0;
 }
@@ -2191,7 +2197,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	uint32_t intr_vector = 0;
 	int err, link_up = 0, negotiate = 0;
 	uint32_t speed = 0;
@@ -2291,7 +2298,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 
 	/* Restore vf rate limit */
 	if (vfinfo != NULL) {
-		for (vf = 0; vf < dev->pci_dev->max_vfs; vf++)
+		for (vf = 0; vf < pci_dev->max_vfs; vf++)
 			for (idx = 0; idx < IXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
 				if (vfinfo[vf].tx_rate[idx] != 0)
 					ixgbe_set_vf_rate_limit(dev, vf,
@@ -2408,7 +2415,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 	struct ixgbe_filter_info *filter_info =
 		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 	int vf;
 
 	PMD_INIT_FUNC_TRACE();
@@ -2424,7 +2432,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 	ixgbe_stop_adapter(hw);
 
 	for (vf = 0; vfinfo != NULL &&
-		     vf < dev->pci_dev->max_vfs; vf++)
+		     vf < pci_dev->max_vfs; vf++)
 		vfinfo[vf].clear_to_send = false;
 
 	if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
@@ -3033,6 +3041,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
@@ -3049,7 +3058,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */
 	dev_info->max_mac_addrs = hw->mac.num_rar_entries;
 	dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
-	dev_info->max_vfs = dev->pci_dev->max_vfs;
+	dev_info->max_vfs = pci_dev->max_vfs;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		dev_info->max_vmdq_pools = ETH_16_POOLS;
 	else
@@ -3164,6 +3173,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
@@ -3171,7 +3181,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 	dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS reg */
 	dev_info->max_mac_addrs = hw->mac.num_rar_entries;
 	dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
-	dev_info->max_vfs = dev->pci_dev->max_vfs;
+	dev_info->max_vfs = pci_dev->max_vfs;
 	if (hw->mac.type == ixgbe_mac_82598EB)
 		dev_info->max_vmdq_pools = ETH_16_POOLS;
 	else
@@ -3434,6 +3444,7 @@ static void
 ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
 	memset(&link, 0, sizeof(link));
 	rte_ixgbe_dev_atomic_read_link_status(dev, &link);
@@ -3448,10 +3459,10 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
 				(int)(dev->data->port_id));
 	}
 	PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
-				dev->pci_dev->addr.domain,
-				dev->pci_dev->addr.bus,
-				dev->pci_dev->addr.devid,
-				dev->pci_dev->addr.function);
+				pci_dev->addr.domain,
+				pci_dev->addr.bus,
+				pci_dev->addr.devid,
+				pci_dev->addr.function);
 }
 
 /*
@@ -3515,7 +3526,7 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
 	} else {
 		PMD_DRV_LOG(DEBUG, "enable intr immediately");
 		ixgbe_enable_intr(dev);
-		rte_intr_enable(&(dev->pci_dev->intr_handle));
+		rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 	}
 
 
@@ -3564,7 +3575,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(&(dev->pci_dev->intr_handle));
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 }
 
 /**
@@ -4196,7 +4207,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint32_t intr_vector = 0;
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 
 	int err, mask = 0;
 
@@ -4259,7 +4270,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 rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -5070,7 +5081,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, mask);
 
-	rte_intr_enable(&dev->pci_dev->intr_handle);
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 
 	return 0;
 }
@@ -5112,7 +5123,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(&dev->pci_dev->intr_handle);
+	rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
 
 	return 0;
 }
@@ -5216,7 +5227,7 @@ ixgbe_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
 static void
 ixgbevf_configure_msix(struct rte_eth_dev *dev)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint32_t q_idx;
@@ -5249,7 +5260,7 @@ ixgbevf_configure_msix(struct rte_eth_dev *dev)
 static void
 ixgbe_configure_msix(struct rte_eth_dev *dev)
 {
-	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
 	struct ixgbe_hw *hw =
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	uint32_t queue_id, base = IXGBE_MISC_VEC_ID;
@@ -5381,7 +5392,8 @@ static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
 		return -EINVAL;
 
 	if (vfinfo != NULL) {
-		for (vf_idx = 0; vf_idx < dev->pci_dev->max_vfs; vf_idx++) {
+		for (vf_idx = 0; vf_idx < ETH_DEV_PCI_DEV(dev)->max_vfs;
+		     vf_idx++) {
 			if (vf_idx == vf)
 				continue;
 			for (idx = 0; idx < RTE_DIM(vfinfo[vf_idx].tx_rate);
@@ -7197,12 +7209,13 @@ ixgbe_e_tag_insertion_en_dis(struct rte_eth_dev *dev,
 	int ret = 0;
 	uint32_t vmtir, vmvir;
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
 
-	if (l2_tunnel->vf_id >= dev->pci_dev->max_vfs) {
+	if (l2_tunnel->vf_id >= pci_dev->max_vfs) {
 		PMD_DRV_LOG(ERR,
 			    "VF id %u should be less than %u",
 			    l2_tunnel->vf_id,
-			    dev->pci_dev->max_vfs);
+			    pci_dev->max_vfs);
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 26395e4..139d816 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -61,7 +61,7 @@
 static inline uint16_t
 dev_num_vf(struct rte_eth_dev *eth_dev)
 {
-	return eth_dev->pci_dev->max_vfs;
+	return ETH_DEV_PCI_DEV(eth_dev)->max_vfs;
 }
 
 static inline
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index d106dd0..959ff0f 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -178,11 +178,12 @@ static void
 qede_interrupt_handler(__rte_unused struct rte_intr_handle *handle, void *param)
 {
 	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 
 	qede_interrupt_action(ECORE_LEADING_HWFN(edev));
-	if (rte_intr_enable(&eth_dev->pci_dev->intr_handle))
+	if (rte_intr_enable(&pci_dev->intr_handle))
 		DP_ERR(edev, "rte_intr_enable failed\n");
 }
 
@@ -809,6 +810,7 @@ static void qede_poll_sp_sb_cb(void *param)
 
 static void qede_dev_close(struct rte_eth_dev *eth_dev)
 {
+	struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	int rc;
@@ -835,9 +837,9 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
 
 	qdev->ops->common->remove(edev);
 
-	rte_intr_disable(&eth_dev->pci_dev->intr_handle);
+	rte_intr_disable(&pci_dev->intr_handle);
 
-	rte_intr_callback_unregister(&eth_dev->pci_dev->intr_handle,
+	rte_intr_callback_unregister(&pci_dev->intr_handle,
 				     qede_interrupt_handler, (void *)eth_dev);
 
 	if (edev->num_hwfns > 1)
@@ -1403,7 +1405,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 	/* Extract key data structures */
 	adapter = eth_dev->data->dev_private;
 	edev = &adapter->edev;
-	pci_addr = eth_dev->pci_dev->addr;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+	pci_addr = pci_dev->addr;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -1420,8 +1423,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 		return 0;
 	}
 
-	pci_dev = eth_dev->pci_dev;
-
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
 	qed_ops = qed_get_eth_ops();
@@ -1442,10 +1443,10 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 
 	qede_update_pf_params(edev);
 
-	rte_intr_callback_register(&eth_dev->pci_dev->intr_handle,
+	rte_intr_callback_register(&pci_dev->intr_handle,
 				   qede_interrupt_handler, (void *)eth_dev);
 
-	if (rte_intr_enable(&eth_dev->pci_dev->intr_handle)) {
+	if (rte_intr_enable(&pci_dev->intr_handle)) {
 		DP_ERR(edev, "rte_intr_enable() failed\n");
 		return -ENODEV;
 	}
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 8bb13e5..bcb3751 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -138,7 +138,7 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
 	const struct rte_memzone *mz;
 
 	snprintf(z_name, sizeof(z_name), "%s_%d_%s",
-		 dev->driver->pci_drv.driver.name, dev->data->port_id, post_string);
+		 dev->data->drv_name, dev->data->port_id, post_string);
 
 	mz = rte_memzone_lookup(z_name);
 	if (!reuse) {
@@ -237,7 +237,7 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
 	eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
 	eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
-	pci_dev = eth_dev->pci_dev;
+	pci_dev = ETH_DEV_PCI_DEV(eth_dev);
 
 	/*
 	 * for secondary processes, we don't initialize any further as primary
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/8] ethdev: Helper to convert to struct rte_pci_device
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>

Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 lib/librte_ether/rte_ethdev.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9678179..3adbb2b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1644,6 +1644,12 @@ struct rte_eth_dev {
 	uint8_t attached; /**< Flag indicating the port is attached */
 } __rte_cache_aligned;
 
+/**
+ * @internal
+ * Helper for drivers that need to convert from rte_eth_dev to rte_pci_device.
+ */
+#define ETH_DEV_PCI_DEV(ptr) ((ptr)->pci_dev)
+
 struct rte_eth_dev_sriov {
 	uint8_t active;               /**< SRIOV is active with 16, 32 or 64 pools */
 	uint8_t nb_q_per_pool;        /**< rx queue number per pool */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 1/8] eal: define container_of macro
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
  To: dev; +Cc: shreyansh.jain, david.marchand, Jan Viktorin

This macro is based on Jan Viktorin's original patch but also checks the
type of the passed pointer against the type of the member.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
[jblunck@infradead.org: add type checking and __extension__]
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
 lib/librte_eal/common/include/rte_common.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8dda3e2 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,26 @@ rte_bsf32(uint32_t v)
 #define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
 #endif
 
+/**
+ * Return pointer to the wrapping struct instance.
+ *
+ * Example:
+ *
+ *  struct wrapper {
+ *      ...
+ *      struct child c;
+ *      ...
+ *  };
+ *
+ *  struct child *x = obtain(...);
+ *  struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(ptr, type, member)	__extension__ ({		\
+			typeof(((type *)0)->member) *_ptr = (ptr);	\
+			(type *)(((char *)_ptr) - offsetof(type, member)); })
+#endif
+
 #define _RTE_STR(x) #x
 /** Take a macro value and get a string version of it */
 #define RTE_STR(x) _RTE_STR(x)
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH] eal: postpone vdev initialization
From: Jerin Jacob @ 2016-11-21 16:56 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <8457ded8-e9ee-76ba-671e-a76aed08f6d0@nxp.com>

On Mon, Nov 21, 2016 at 10:39:00AM +0530, Shreyansh Jain wrote:
> On Sunday 20 November 2016 01:30 PM, Jerin Jacob wrote:
> > Some platform like octeontx may use pci and
> > vdev based combined device to represent a logical
> > dpdk functional device.In such case, postponing the
> > vdev initialization after pci device
> > initialization will provide the better view of
> > the pci device resources in the system in
> > vdev's probe function, and it allows better
> > functional subsystem registration in vdev probe
> > function.
> > 
> > As a bonus, This patch fixes a bond device
> > initialization use case.
> > 
> > example command to reproduce the issue:
> > ../testpmd -c 0x2  --vdev 'eth_bond0,mode=0,
> > slave=0000:02:00.0,slave=0000:03:00.0' --
> > --port-topology=chained
> > 
> > root cause:
> > In existing case(vdev initialization and then pci
> > initialization), creates three Ethernet ports with
> > following port ids
> > 0 - Bond device
> > 1 - PCI device 0
> > 2 - PCI devive 1
> > 
> > Since testpmd, calls the configure/start on all the ports on
> > start up,it will translate to following illegal setup sequence
> > 
> > 1)bond device configure/start
> > 1.1) pci device0 stop/configure/start
> > 1.2) pci device1 stop/configure/start
> > 2)pci device 0 configure(illegal setup case,
> > as device in start state)
> > 
> > The fix changes the initialization sequence and
> > allow initialization in following valid setup order
> > 1) pcie device 0 configure/start
> > 2) pcie device 1 configure/start
> > 3) bond device 2 configure/start
> > 3.1) pcie device 0/stop/configure/start
> > 3.2) pcie device 1/stop/configure/start
> > 
> > Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > ---
> >  lib/librte_eal/bsdapp/eal/eal.c   | 6 +++---
> >  lib/librte_eal/linuxapp/eal/eal.c | 6 +++---
> >  2 files changed, 6 insertions(+), 6 deletions(-)
> > 
> > diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
> > index 35e3117..2206277 100644
> > --- a/lib/librte_eal/bsdapp/eal/eal.c
> > +++ b/lib/librte_eal/bsdapp/eal/eal.c
> > @@ -577,9 +577,6 @@ rte_eal_init(int argc, char **argv)
> >  		rte_config.master_lcore, thread_id, cpuset,
> >  		ret == 0 ? "" : "...");
> > 
> > -	if (rte_eal_dev_init() < 0)
> > -		rte_panic("Cannot init pmd devices\n");
> > -
> >  	RTE_LCORE_FOREACH_SLAVE(i) {
> > 
> >  		/*
> > @@ -616,6 +613,9 @@ rte_eal_init(int argc, char **argv)
> >  	if (rte_eal_pci_probe())
> >  		rte_panic("Cannot probe PCI\n");
> > 
> > +	if (rte_eal_dev_init() < 0)
> > +		rte_panic("Cannot init pmd devices\n");
> > +
> >  	rte_eal_mcfg_complete();
> > 
> >  	return fctret;
> > diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> > index 2075282..16dd5b9 100644
> > --- a/lib/librte_eal/linuxapp/eal/eal.c
> > +++ b/lib/librte_eal/linuxapp/eal/eal.c
> > @@ -841,9 +841,6 @@ rte_eal_init(int argc, char **argv)
> >  		rte_config.master_lcore, (int)thread_id, cpuset,
> >  		ret == 0 ? "" : "...");
> > 
> > -	if (rte_eal_dev_init() < 0)
> > -		rte_panic("Cannot init pmd devices\n");
> > -
> >  	if (rte_eal_intr_init() < 0)
> >  		rte_panic("Cannot init interrupt-handling thread\n");
> > 
> > @@ -887,6 +884,9 @@ rte_eal_init(int argc, char **argv)
> >  	if (rte_eal_pci_probe())
> >  		rte_panic("Cannot probe PCI\n");
> > 
> > +	if (rte_eal_dev_init() < 0)
> > +		rte_panic("Cannot init pmd devices\n");
> > +
> >  	rte_eal_mcfg_complete();
> > 
> >  	return fctret;
> > 
> 
> Movement looks fine to me.
> 
> IMO, rte_eal_dev_init() is a misleading name. It actually performs a
> driver->probe for vdev - which is parallel to rte_eal_pci_probe.

Looks good to me. If there are no objection, I can change to rte_eal_vdev_probe()
as a separate patch in v2. Let the order change patch be separate.


> 
> -
> Shreyansh

^ permalink raw reply

* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:52 UTC (permalink / raw)
  To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUsR1Gmtmtx94K7PDB7rf_==bAdSTCJYdiPZPsjgisiXQg@mail.gmail.com>

On Mon, Nov 21, 2016 at 5:49 PM, David Marchand
<david.marchand@6wind.com> wrote:
> On Mon, Nov 21, 2016 at 5:34 PM, Jan Blunck <jblunck@infradead.org> wrote:
>> On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
>>> I posted something similar [1], so looks good to me :-)
>>>
>>> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>>>
>>
>> Thanks for reviewing. Do we go with your proposal then? Do you plan to
>> follow up on the comments?
>
> Yes will do.
> Out of curiosity how did you catch the qede driver ? Did you check all
> other drivers ?
>

$ grep drivername -r drivers/

^ permalink raw reply

* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: David Marchand @ 2016-11-21 16:49 UTC (permalink / raw)
  To: Jan Blunck; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALe+Z015KyNZKrasimQCuM6V6ggfSgDJJO4y00K-Zx32kUT0EQ@mail.gmail.com>

On Mon, Nov 21, 2016 at 5:34 PM, Jan Blunck <jblunck@infradead.org> wrote:
> On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
>> I posted something similar [1], so looks good to me :-)
>>
>> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>>
>
> Thanks for reviewing. Do we go with your proposal then? Do you plan to
> follow up on the comments?

Yes will do.
Out of curiosity how did you catch the qede driver ? Did you check all
other drivers ?


-- 
David Marchand

^ permalink raw reply

* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:34 UTC (permalink / raw)
  To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUt0d+s9hBCX-TcL-Fms-v7ozqEg7zOYy6NsJsV5rUHRGA@mail.gmail.com>

On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
<david.marchand@6wind.com> wrote:
> On Sun, Nov 20, 2016 at 11:05 AM, Jan Blunck <jblunck@infradead.org> wrote:
>> This is overwritten in rte_eth_dev_info_get().
>>
>> Signed-off-by: Jan Blunck <jblunck@infradead.org>
>> ---
>>  drivers/net/virtio/virtio_ethdev.c | 4 ----
>>  1 file changed, 4 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
>> index 079fd6c..741688e 100644
>> --- a/drivers/net/virtio/virtio_ethdev.c
>> +++ b/drivers/net/virtio/virtio_ethdev.c
>> @@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>>         uint64_t tso_mask;
>>         struct virtio_hw *hw = dev->data->dev_private;
>>
>> -       if (dev->pci_dev)
>> -               dev_info->driver_name = dev->driver->pci_drv.driver.name;
>> -       else
>> -               dev_info->driver_name = "virtio_user PMD";
>>         dev_info->max_rx_queues =
>>                 RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
>>         dev_info->max_tx_queues =
>> --
>> 2.7.4
>>
>
> I posted something similar [1], so looks good to me :-)
>
> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>

Thanks for reviewing. Do we go with your proposal then? Do you plan to
follow up on the comments?

^ permalink raw reply

* Re: [PATCH 1/2] net: remove dead driver names
From: Jan Blunck @ 2016-11-21 16:31 UTC (permalink / raw)
  To: David Marchand
  Cc: Thomas Monjalon, dev, linville, Declan Doherty, zlu, lsun,
	alejandro.lucero, mtetsuyah, nicolas.pernas.maradei, Ferruh Yigit,
	harish.patil, rasesh.mody, sony.chacko, Bruce Richardson,
	huawei.xie, Yuanhan Liu, jianfeng.tan
In-Reply-To: <1478785884-29273-1-git-send-email-david.marchand@6wind.com>

On Thu, Nov 10, 2016 at 2:51 PM, David Marchand
<david.marchand@6wind.com> wrote:
> Since b1fb53a39d88 ("ethdev: remove some PCI specific handling"),

Please fix this checkpatch finding.

> rte_eth_dev_info_get() relies on dev->data->drv_name to report the driver
> name to caller.
>
> Having the pmds set driver_info->driver_name in the pmds is useless,
> since ethdev overwrites it right after.
> The only thing the pmd must do is:
> - for pci drivers, call rte_eth_copy_pci_info() which then sets
>   data->drv_name
> - for vdev drivers, manually set data->drv_name
>
> At this stage, virtio-user does not properly report a driver name (fixed in
> next commit).
>
> Signed-off-by: David Marchand <david.marchand@6wind.com>
> ---
>  drivers/net/af_packet/rte_eth_af_packet.c | 5 +----
>  drivers/net/nfp/nfp_net.c                 | 1 -
>  drivers/net/null/rte_eth_null.c           | 4 +---
>  drivers/net/pcap/rte_eth_pcap.c           | 4 +---
>  drivers/net/qede/qede_ethdev.c            | 1 -

There is another stale variable drivername in qede_ethdev.c. Might be
the right time to remove it.

Thanks,
Jan

>  drivers/net/ring/rte_eth_ring.c           | 4 +---
>  drivers/net/vhost/rte_eth_vhost.c         | 3 ---
>  drivers/net/virtio/virtio_ethdev.c        | 4 ----
>  drivers/net/xenvirt/rte_eth_xenvirt.c     | 5 +----
>  9 files changed, 5 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
> index ff45068..a66a657 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -115,8 +115,6 @@ static const char *valid_arguments[] = {
>         NULL
>  };
>
> -static const char *drivername = "AF_PACKET PMD";
> -
>  static struct rte_eth_link pmd_link = {
>         .link_speed = ETH_SPEED_NUM_10G,
>         .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -280,7 +278,6 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  {
>         struct pmd_internals *internals = dev->data->dev_private;
>
> -       dev_info->driver_name = drivername;
>         dev_info->if_index = internals->if_index;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t)ETH_FRAME_LEN;
> @@ -693,7 +690,7 @@ rte_pmd_init_internals(const char *name,
>         (*eth_dev)->dev_ops = &ops;
>         (*eth_dev)->driver = NULL;
>         (*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
> -       (*eth_dev)->data->drv_name = drivername;
> +       (*eth_dev)->data->drv_name = "AF_PACKET PMD";
>         (*eth_dev)->data->kdrv = RTE_KDRV_NONE;
>         (*eth_dev)->data->numa_node = numa_node;
>
> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
> index c6b1587..0c342ab 100644
> --- a/drivers/net/nfp/nfp_net.c
> +++ b/drivers/net/nfp/nfp_net.c
> @@ -1006,7 +1006,6 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>
>         hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>
> -       dev_info->driver_name = dev->driver->pci_drv.driver.name;
>         dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
>         dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
>         dev_info->min_rx_bufsize = ETHER_MIN_MTU;
> diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
> index 836d982..09d77fd 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -88,7 +88,6 @@ struct pmd_internals {
>
>
>  static struct ether_addr eth_addr = { .addr_bytes = {0} };
> -static const char *drivername = "Null PMD";
>  static struct rte_eth_link pmd_link = {
>         .link_speed = ETH_SPEED_NUM_10G,
>         .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -295,7 +294,6 @@ eth_dev_info(struct rte_eth_dev *dev,
>                 return;
>
>         internals = dev->data->dev_private;
> -       dev_info->driver_name = drivername;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t)-1;
>         dev_info->max_rx_queues = RTE_DIM(internals->rx_null_queues);
> @@ -555,7 +553,7 @@ eth_dev_null_create(const char *name,
>         eth_dev->driver = NULL;
>         data->dev_flags = RTE_ETH_DEV_DETACHABLE;
>         data->kdrv = RTE_KDRV_NONE;
> -       data->drv_name = drivername;
> +       data->drv_name = "Null PMD";
>         data->numa_node = numa_node;
>
>         /* finally assign rx and tx ops */
> diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
> index 0162f44..8b4fba7 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -119,7 +119,6 @@ static struct ether_addr eth_addr = {
>         .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 }
>  };
>
> -static const char *drivername = "Pcap PMD";
>  static struct rte_eth_link pmd_link = {
>                 .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -552,7 +551,6 @@ eth_dev_info(struct rte_eth_dev *dev,
>  {
>         struct pmd_internals *internals = dev->data->dev_private;
>
> -       dev_info->driver_name = drivername;
>         dev_info->if_index = internals->if_index;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t) -1;
> @@ -842,7 +840,7 @@ pmd_init_internals(const char *name, const unsigned int nb_rx_queues,
>         (*eth_dev)->driver = NULL;
>         data->dev_flags = RTE_ETH_DEV_DETACHABLE;
>         data->kdrv = RTE_KDRV_NONE;
> -       data->drv_name = drivername;
> +       data->drv_name = "Pcap PMD";
>         data->numa_node = numa_node;
>
>         return 0;
> diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
> index 59129f2..a56ba90 100644
> --- a/drivers/net/qede/qede_ethdev.c
> +++ b/drivers/net/qede/qede_ethdev.c
> @@ -662,7 +662,6 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
>                 dev_info->max_vfs = 0;
>         else
>                 dev_info->max_vfs = (uint16_t)NUM_OF_VFS(&qdev->edev);
> -       dev_info->driver_name = qdev->drv_ver;
>         dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
>         dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL;
>
> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> index c1767c4..56afaf2 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -75,7 +75,6 @@ struct pmd_internals {
>  };
>
>
> -static const char *drivername = "Rings PMD";
>  static struct rte_eth_link pmd_link = {
>                 .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -173,7 +172,6 @@ eth_dev_info(struct rte_eth_dev *dev,
>                 struct rte_eth_dev_info *dev_info)
>  {
>         struct pmd_internals *internals = dev->data->dev_private;
> -       dev_info->driver_name = drivername;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t)-1;
>         dev_info->max_rx_queues = (uint16_t)internals->max_rx_queues;
> @@ -343,7 +341,7 @@ do_eth_dev_ring_create(const char *name,
>         eth_dev->dev_ops = &ops;
>         data->dev_flags = RTE_ETH_DEV_DETACHABLE;
>         data->kdrv = RTE_KDRV_NONE;
> -       data->drv_name = drivername;
> +       data->drv_name = "Rings PMD";
>         data->numa_node = numa_node;
>
>         TAILQ_INIT(&(eth_dev->link_intr_cbs));
> diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
> index 766d4ef..96bf391 100644
> --- a/drivers/net/vhost/rte_eth_vhost.c
> +++ b/drivers/net/vhost/rte_eth_vhost.c
> @@ -53,8 +53,6 @@
>  #define ETH_VHOST_CLIENT_ARG           "client"
>  #define ETH_VHOST_DEQUEUE_ZERO_COPY    "dequeue-zero-copy"
>
> -static const char *drivername = "VHOST PMD";
> -
>  static const char *valid_arguments[] = {
>         ETH_VHOST_IFACE_ARG,
>         ETH_VHOST_QUEUES_ARG,
> @@ -861,7 +859,6 @@ eth_dev_info(struct rte_eth_dev *dev,
>                 return;
>         }
>
> -       dev_info->driver_name = drivername;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t)-1;
>         dev_info->max_rx_queues = internal->max_queues;
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 079fd6c..741688e 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>         uint64_t tso_mask;
>         struct virtio_hw *hw = dev->data->dev_private;
>
> -       if (dev->pci_dev)
> -               dev_info->driver_name = dev->driver->pci_drv.driver.name;
> -       else
> -               dev_info->driver_name = "virtio_user PMD";
>         dev_info->max_rx_queues =
>                 RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
>         dev_info->max_tx_queues =
> diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
> index c08a056..f74d72c 100644
> --- a/drivers/net/xenvirt/rte_eth_xenvirt.c
> +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
> @@ -70,8 +70,6 @@
>  /* virtio_idx is increased after new device is created.*/
>  static int virtio_idx = 0;
>
> -static const char *drivername = "xen virtio PMD";
> -
>  static struct rte_eth_link pmd_link = {
>                 .link_speed = ETH_SPEED_NUM_10G,
>                 .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -331,7 +329,6 @@ eth_dev_info(struct rte_eth_dev *dev,
>         struct pmd_internals *internals = dev->data->dev_private;
>
>         RTE_SET_USED(internals);
> -       dev_info->driver_name = drivername;
>         dev_info->max_mac_addrs = 1;
>         dev_info->max_rx_pktlen = (uint32_t)2048;
>         dev_info->max_rx_queues = (uint16_t)1;
> @@ -675,7 +672,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
>
>         eth_dev->data->dev_flags = RTE_PCI_DRV_DETACHABLE;
>         eth_dev->data->kdrv = RTE_KDRV_NONE;
> -       eth_dev->data->drv_name = drivername;
> +       eth_dev->data->drv_name = "xen virtio PMD";
>         eth_dev->driver = NULL;
>         eth_dev->data->numa_node = numa_node;
>
> --
> 2.7.4
>

^ permalink raw reply

* Re: Adding API to force freeing consumed buffers in TX ring
From: Bruce Richardson @ 2016-11-21 15:25 UTC (permalink / raw)
  To: Olivier Matz; +Cc: Wiles, Keith, Damjan Marion (damarion), dev@dpdk.org
In-Reply-To: <aae1d111-4be0-4d5a-d436-6795cf18155e@6wind.com>

On Mon, Nov 21, 2016 at 04:06:32PM +0100, Olivier Matz wrote:
> Hi,
> 
> On 11/21/2016 03:33 PM, Wiles, Keith wrote:
> > 
> >> On Nov 21, 2016, at 4:48 AM, Damjan Marion (damarion) <damarion@cisco.com> wrote:
> >>
> >>
> >> Hi,
> >>
> >> Currently in VPP we do memcpy of whole packet when we need to do 
> >> replication as we cannot know if specific buffer is transmitted
> >> from tx ring before we update it again (i.e. l2 header rewrite).
> >>
> >> Unless there is already a way to address this issue in DPDK which I’m not aware
> >> of my proposal is that we provide mechanism for polling TX ring 
> >> for consumed buffers. This can be either completely new API or 
> >> extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).
> >>
> >> This will allows us to start polling tx ring when we expect some 
> >> mbuf back, instead of waiting for next tx burst (which we don’t know
> >> when it will happen) and hoping that we will reach free_threshold soon.
> > 
> > +1
> > 
> > In Pktgen I have the problem of not being able to reclaim all of the TX mbufs to update them for the next set of packets to send. I know this is not a common case, but I do see the case where the application needs its mbufs freed off the TX ring. Currently you need to have at least a TX ring size of mbufs on hand to make sure you can send to a TX ring. If you allocate too few you run into a deadlock case as the number of mbufs  on a TX ring does not hit the flush mark. If you are sending to multiple TX rings on the same numa node from the a single TX pool you have to understand the total number of mbufs you need to have allocated to hit the TX flush on each ring. Not a clean way to handle the problems as you may have limited memory or require some logic to add more mbufs for dynamic po
 rts.
> > 
> > Anyway it would be great to require a way to clean up the TX done ring, using nb_pkts == 0 is the simplest way, but a new API is fine too.
> >>
> >> Any thoughts?
> 
> Yes, it looks useful to have a such API.
> 
> I would prefer another function instead of diverting the meaning of
> nb_pkts. Maybe this?
> 
>   void rte_eth_tx_free_bufs(uint8_t port_id, uint16_t queue_id);
> 

Third parameter for a limit(hint) of the number of bufs to free? If the
TX ring is big, we might not want to stall other work for a long time
while we free a huge number of buffers.

	/Bruce

^ permalink raw reply

* Re: Solarflare PMD submission question
From: Andrew Rybchenko @ 2016-11-21 15:03 UTC (permalink / raw)
  To: Ferruh Yigit, Thomas Monjalon; +Cc: dev
In-Reply-To: <f0a999ba-6170-816a-7a5f-1763bc1179e8@intel.com>

On 11/21/2016 01:30 PM, Ferruh Yigit wrote:
> On 11/21/2016 8:59 AM, Thomas Monjalon wrote:
>> 2016-11-21 11:46, Andrew Rybchenko:
>>> On 11/21/2016 11:19 AM, Thomas Monjalon wrote:
>>>>> Before submitting 56 patches I'd like to double-check that checkpatch.pl
>>>>> errors (for example, because of assignments in the 'if' condition,
>>>>> parenthesis around return value) is not a show-stopper for base driver
>>>>> import.
>>>> You can run checkpatches.sh or send the patches to checkpatch@dpdk.org.
>>>> The script check-git-log.sh can also guide you for the expected formatting.
>>> Yes, I did it and it helped me to find and fix some coding standard
>>> violations.
>>>
>>> The problem with libefx (base driver) is that it is existing code which
>>> follows FreeBSD and illumos coding conventions which contradict to
>>> checkpatches.sh sometimes (e.g. require parenthesis around return
>>> value). Other example of error produced by checkpatches.sh is assign in
>>> if. It is widely used in the code to assign return code value and
>>> compare it vs 0 in one line. It is not a coding standard conflict, but
>>> it is very wide-spread in the code (so changing it will produce too many
>>> changes not strictly required/useful).
>>>
>>> So, may I repeat my question if it is a show-stopper for base driver or
>>> acceptable.
>> I would vote to accept these minor style warnings for the base driver.
>> Ferruh, any comment?
>>
> For _base driver_, I am also OK for having checkpatch warnings.

In term of checkpatshes.sh return value in parenthesis is an error (not 
warning). Hopefully it changes nothing.

Andrew.

^ permalink raw reply

* Re: Adding API to force freeing consumed buffers in TX ring
From: Olivier Matz @ 2016-11-21 15:06 UTC (permalink / raw)
  To: Wiles, Keith, Damjan Marion (damarion); +Cc: dev@dpdk.org
In-Reply-To: <27853C4C-2482-49E0-8F60-178473276CF5@intel.com>

Hi,

On 11/21/2016 03:33 PM, Wiles, Keith wrote:
> 
>> On Nov 21, 2016, at 4:48 AM, Damjan Marion (damarion) <damarion@cisco.com> wrote:
>>
>>
>> Hi,
>>
>> Currently in VPP we do memcpy of whole packet when we need to do 
>> replication as we cannot know if specific buffer is transmitted
>> from tx ring before we update it again (i.e. l2 header rewrite).
>>
>> Unless there is already a way to address this issue in DPDK which I’m not aware
>> of my proposal is that we provide mechanism for polling TX ring 
>> for consumed buffers. This can be either completely new API or 
>> extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).
>>
>> This will allows us to start polling tx ring when we expect some 
>> mbuf back, instead of waiting for next tx burst (which we don’t know
>> when it will happen) and hoping that we will reach free_threshold soon.
> 
> +1
> 
> In Pktgen I have the problem of not being able to reclaim all of the TX mbufs to update them for the next set of packets to send. I know this is not a common case, but I do see the case where the application needs its mbufs freed off the TX ring. Currently you need to have at least a TX ring size of mbufs on hand to make sure you can send to a TX ring. If you allocate too few you run into a deadlock case as the number of mbufs  on a TX ring does not hit the flush mark. If you are sending to multiple TX rings on the same numa node from the a single TX pool you have to understand the total number of mbufs you need to have allocated to hit the TX flush on each ring. Not a clean way to handle the problems as you may have limited memory or require some logic to add more mbufs for dynamic port
 s.
> 
> Anyway it would be great to require a way to clean up the TX done ring, using nb_pkts == 0 is the simplest way, but a new API is fine too.
>>
>> Any thoughts?

Yes, it looks useful to have a such API.

I would prefer another function instead of diverting the meaning of
nb_pkts. Maybe this?

  void rte_eth_tx_free_bufs(uint8_t port_id, uint16_t queue_id);


Regards,
Olivier

^ permalink raw reply

* [PATCH 54/56] net/sfc: add callbacks to set up and release Tx queues
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <ivan.malov@oktetlabs.ru>

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/sfc_ethdev.c |  58 ++++++++++++++
 drivers/net/sfc/efx/sfc_ev.h     |   2 +
 drivers/net/sfc/efx/sfc_tx.c     | 167 +++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/sfc_tx.h     |  36 +++++++++
 4 files changed, 263 insertions(+)

diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index 4afd30c..98e5d83 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -39,6 +39,7 @@
 #include "sfc_kvargs.h"
 #include "sfc_ev.h"
 #include "sfc_rx.h"
+#include "sfc_tx.h"
 
 
 static void
@@ -266,6 +267,61 @@ sfc_rx_queue_release(void *queue)
 	sfc_adapter_unlock(sa);
 }
 
+static int
+sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+		   uint16_t nb_tx_desc, unsigned int socket_id,
+		   const struct rte_eth_txconf *tx_conf)
+{
+	struct sfc_adapter *sa = dev->data->dev_private;
+	int rc;
+
+	sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
+		     tx_queue_id, nb_tx_desc, socket_id);
+
+	sfc_adapter_lock(sa);
+
+	rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+	if (rc != 0)
+		goto fail_tx_qinit;
+
+	dev->data->tx_queues[tx_queue_id] = sa->txq_info[tx_queue_id].txq;
+
+	sfc_adapter_unlock(sa);
+	return 0;
+
+fail_tx_qinit:
+	sfc_adapter_unlock(sa);
+	SFC_ASSERT(rc > 0);
+	return -rc;
+}
+
+static void
+sfc_tx_queue_release(void *queue)
+{
+	struct sfc_txq *txq = queue;
+	unsigned int sw_index;
+	struct sfc_adapter *sa;
+
+	if (txq == NULL)
+		return;
+
+	sw_index = sfc_txq_sw_index(txq);
+
+	SFC_ASSERT(txq->evq != NULL);
+	sa = txq->evq->sa;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	sfc_adapter_lock(sa);
+
+	SFC_ASSERT(sw_index < sa->eth_dev->data->nb_tx_queues);
+	sa->eth_dev->data->tx_queues[sw_index] = NULL;
+
+	sfc_tx_qfini(sa, sw_index);
+
+	sfc_adapter_unlock(sa);
+}
+
 static const struct eth_dev_ops sfc_eth_dev_ops = {
 	.dev_configure			= sfc_dev_configure,
 	.dev_start			= sfc_dev_start,
@@ -275,6 +331,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
 	.dev_infos_get			= sfc_dev_infos_get,
 	.rx_queue_setup			= sfc_rx_queue_setup,
 	.rx_queue_release		= sfc_rx_queue_release,
+	.tx_queue_setup			= sfc_tx_queue_setup,
+	.tx_queue_release		= sfc_tx_queue_release,
 };
 
 static int
diff --git a/drivers/net/sfc/efx/sfc_ev.h b/drivers/net/sfc/efx/sfc_ev.h
index d053182..71e51a5 100644
--- a/drivers/net/sfc/efx/sfc_ev.h
+++ b/drivers/net/sfc/efx/sfc_ev.h
@@ -41,6 +41,7 @@ extern "C" {
 
 struct sfc_adapter;
 struct sfc_rxq;
+struct sfc_txq;
 
 enum sfc_evq_state {
 	SFC_EVQ_UNINITIALIZED = 0,
@@ -58,6 +59,7 @@ struct sfc_evq {
 	boolean_t		exception;
 	efsys_mem_t		mem;
 	struct sfc_rxq		*rxq;
+	struct sfc_txq		*txq;
 
 	/* Not used on datapath */
 	struct sfc_adapter	*sa;
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
index fecd058..a4ffe9c 100644
--- a/drivers/net/sfc/efx/sfc_tx.c
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -33,6 +33,165 @@
 #include "sfc_tx.h"
 
 static int
+sfc_tx_qcheck_conf(struct sfc_adapter *sa,
+		   const struct rte_eth_txconf *tx_conf)
+{
+	unsigned int flags = tx_conf->txq_flags;
+	int rc = 0;
+
+	if (tx_conf->tx_rs_thresh != 0) {
+		sfc_err(sa, "RS bit in transmit descriptor is not supported");
+		rc = EINVAL;
+	}
+
+	if (tx_conf->tx_free_thresh != 0) {
+		sfc_err(sa,
+			"setting explicit TX free threshold is not supported");
+		rc = EINVAL;
+	}
+
+	if (tx_conf->tx_deferred_start != 0) {
+		sfc_err(sa, "TX queue deferred start is not supported (yet)");
+		rc = EINVAL;
+	}
+
+	if (tx_conf->tx_thresh.pthresh != 0 ||
+	    tx_conf->tx_thresh.hthresh != 0 ||
+	    tx_conf->tx_thresh.wthresh != 0) {
+		sfc_err(sa,
+			"prefetch/host/writeback thresholds are not supported");
+		rc = EINVAL;
+	}
+
+	if ((flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
+		sfc_err(sa, "VLAN offload is not supported");
+		rc = EINVAL;
+	}
+
+	if ((flags & ETH_TXQ_FLAGS_NOXSUMSCTP) == 0) {
+		sfc_err(sa, "SCTP offload is not supported");
+		rc = EINVAL;
+	}
+
+	/* We either perform both TCP and UDP offload, or no offload at all */
+	if (((flags & ETH_TXQ_FLAGS_NOXSUMTCP) == 0) !=
+	    ((flags & ETH_TXQ_FLAGS_NOXSUMUDP) == 0)) {
+		sfc_err(sa, "TCP and UDP offloads can't be set independently");
+		rc = EINVAL;
+	}
+
+	return rc;
+}
+
+int
+sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+	     uint16_t nb_tx_desc, unsigned int socket_id,
+	     const struct rte_eth_txconf *tx_conf)
+{
+	struct sfc_txq_info *txq_info;
+	struct sfc_evq *evq;
+	struct sfc_txq *txq;
+	unsigned int evq_index = sfc_evq_index_by_txq_sw_index(sa, sw_index);
+	int rc = 0;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	rc = sfc_tx_qcheck_conf(sa, tx_conf);
+	if (rc != 0)
+		goto fail_bad_conf;
+
+	SFC_ASSERT(sw_index < sa->txq_count);
+	txq_info = &sa->txq_info[sw_index];
+
+	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
+	txq_info->entries = nb_tx_desc;
+
+	rc = sfc_ev_qinit(sa, evq_index, txq_info->entries, socket_id);
+	if (rc != 0)
+		goto fail_ev_qinit;
+
+	evq = sa->evq_info[evq_index].evq;
+
+	rc = ENOMEM;
+	txq = rte_zmalloc_socket("sfc-txq", sizeof(*txq), 0, socket_id);
+	if (txq == NULL)
+		goto fail_txq_alloc;
+
+	rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
+			   socket_id, &txq->mem);
+	if (rc != 0)
+		goto fail_dma_alloc;
+
+	rc = ENOMEM;
+	txq->pend_desc = rte_calloc_socket("sfc-txq-pend-desc",
+					   EFX_TXQ_LIMIT(txq_info->entries),
+					   sizeof(efx_desc_t), 0, socket_id);
+	if (txq->pend_desc == NULL)
+		goto fail_pend_desc_alloc;
+
+	rc = ENOMEM;
+	txq->sw_ring = rte_calloc_socket("sfc-txq-desc", txq_info->entries,
+					 sizeof(*txq->sw_ring), 0, socket_id);
+	if (txq->sw_ring == NULL)
+		goto fail_desc_alloc;
+
+	txq->state = SFC_TXQ_INITIALIZED;
+	txq->ptr_mask = txq_info->entries - 1;
+	txq->hw_index = sw_index;
+	txq->flags = tx_conf->txq_flags;
+	txq->evq = evq;
+
+	evq->txq = txq;
+
+	txq_info->txq = txq;
+
+	return 0;
+
+fail_desc_alloc:
+	rte_free(txq->pend_desc);
+
+fail_pend_desc_alloc:
+	sfc_dma_free(sa, &txq->mem);
+
+fail_dma_alloc:
+	rte_free(txq);
+
+fail_txq_alloc:
+	sfc_ev_qfini(sa, evq_index);
+
+fail_ev_qinit:
+	txq_info->entries = 0;
+
+fail_bad_conf:
+	sfc_log_init(sa, "failed (TxQ = %u, rc = %d)", sw_index, rc);
+	return rc;
+}
+
+void
+sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
+{
+	struct sfc_txq_info *txq_info;
+	struct sfc_txq *txq;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	SFC_ASSERT(sw_index < sa->txq_count);
+	txq_info = &sa->txq_info[sw_index];
+
+	txq = txq_info->txq;
+	SFC_ASSERT(txq != NULL);
+	SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+
+	txq_info->txq = NULL;
+	txq_info->entries = 0;
+
+	rte_free(txq->sw_ring);
+	rte_free(txq->pend_desc);
+	sfc_dma_free(sa, &txq->mem);
+	rte_free(txq);
+}
+
+static int
 sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
 {
 	struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
@@ -121,6 +280,14 @@ sfc_tx_init(struct sfc_adapter *sa)
 void
 sfc_tx_fini(struct sfc_adapter *sa)
 {
+	int sw_index;
+
+	sw_index = sa->txq_count;
+	while (--sw_index >= 0) {
+		if (sa->txq_info[sw_index].txq != NULL)
+			sfc_tx_qfini(sa, sw_index);
+	}
+
 	rte_free(sa->txq_info);
 	sa->txq_info = NULL;
 	sa->txq_count = 0;
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
index b2d4875..3278797 100644
--- a/drivers/net/sfc/efx/sfc_tx.h
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -40,13 +40,49 @@ extern "C" {
 #endif
 
 struct sfc_adapter;
+struct sfc_evq;
+
+struct sfc_tx_sw_desc {
+	struct rte_mbuf		*mbuf;
+};
+
+enum sfc_txq_state_bit {
+	SFC_TXQ_INITIALIZED_BIT = 0,
+#define	SFC_TXQ_INITIALIZED	(1 << SFC_TXQ_INITIALIZED_BIT)
+};
+
+struct sfc_txq {
+	struct sfc_evq		*evq;
+	struct sfc_tx_sw_desc	*sw_ring;
+	unsigned int		state;
+	unsigned int		ptr_mask;
+	efx_desc_t		*pend_desc;
+	efx_txq_t		*common;
+	efsys_mem_t		mem;
+
+	unsigned int		hw_index;
+	unsigned int		flags;
+};
+
+static inline unsigned int
+sfc_txq_sw_index(const struct sfc_txq *txq)
+{
+	return txq->hw_index;
+}
 
 struct sfc_txq_info {
+	unsigned int		entries;
+	struct sfc_txq		*txq;
 };
 
 int sfc_tx_init(struct sfc_adapter *sa);
 void sfc_tx_fini(struct sfc_adapter *sa);
 
+int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+		 uint16_t nb_tx_desc, unsigned int socket_id,
+		 const struct rte_eth_txconf *tx_conf);
+void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.5.5

^ permalink raw reply related

* [PATCH 30/56] net/sfc: include libefx in build
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev; +Cc: Artem Andreev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Artem Andreev <Artem.Andreev@oktetlabs.ru>

Implement efsys.h for the PMD.

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/Makefile |  54 +++
 drivers/net/sfc/efx/efsys.h  | 767 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 821 insertions(+)
 create mode 100644 drivers/net/sfc/efx/efsys.h

diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
index 71f07ca..de95ea8 100644
--- a/drivers/net/sfc/efx/Makefile
+++ b/drivers/net/sfc/efx/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_sfc_efx.a
 
+CFLAGS += -I$(SRCDIR)/base/
+CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3
 
 # Enable basic warnings but disable some which are accepted
@@ -60,6 +62,17 @@ CFLAGS += -Wstrict-prototypes
 CFLAGS += -Wundef
 CFLAGS += -Wwrite-strings
 
+# Extra CFLAGS for base driver files
+CFLAGS_BASE_DRIVER += -Wno-unused-variable
+CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable
+
+#
+# List of base driver object files for which
+# special CFLAGS above should be applied
+#
+BASE_DRIVER_OBJS=$(patsubst %.c,%.o,$(notdir $(wildcard $(SRCDIR)/base/*.c)))
+$(foreach obj, $(BASE_DRIVER_OBJS), $(eval CFLAGS+=$(CFLAGS_BASE_DRIVER)))
+
 EXPORT_MAP := rte_pmd_sfc_efx_version.map
 
 LIBABIVER := 1
@@ -70,6 +83,47 @@ LIBABIVER := 1
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_kvargs.c
 
+VPATH += $(SRCDIR)/base
+
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_bootcfg.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_crc32.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_ev.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_hash.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_lic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mon.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_port.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_sram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += mcdi_mon.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_sram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_ev.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += hunt_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += medford_nic.c
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_eal
diff --git a/drivers/net/sfc/efx/efsys.h b/drivers/net/sfc/efx/efsys.h
new file mode 100644
index 0000000..2eef996
--- /dev/null
+++ b/drivers/net/sfc/efx/efsys.h
@@ -0,0 +1,767 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_COMMON_EFSYS_H
+#define	_SFC_COMMON_EFSYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_spinlock.h>
+#include <rte_byteorder.h>
+#include <rte_debug.h>
+#include <rte_memzone.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_cycles.h>
+#include <rte_prefetch.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_log.h>
+
+#include "sfc_debug.h"
+
+
+#define	EFSYS_HAS_UINT64 1
+#define	EFSYS_USE_UINT64 1
+#define	EFSYS_HAS_SSE2_M128 1
+
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+#define	EFSYS_IS_BIG_ENDIAN 1
+#define	EFSYS_IS_LITTLE_ENDIAN 0
+#elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define	EFSYS_IS_BIG_ENDIAN 0
+#define	EFSYS_IS_LITTLE_ENDIAN 1
+#else
+#error "Cannot determine system endianness"
+#endif
+#include "efx_types.h"
+
+
+#ifndef _NOTE
+#define	_NOTE(s)
+#endif
+
+typedef uint8_t boolean_t;
+
+#ifndef B_FALSE
+#define	B_FALSE	0
+#endif
+#ifndef B_TRUE
+#define	B_TRUE	1
+#endif
+
+/*
+ * RTE_MAX() and RTE_MIN() cannot be used since braced-group within
+ * expression allowed only inside a function, but MAX() is used as
+ * a number of elements in array.
+ */
+#ifndef MAX
+#define	MAX(v1, v2)	((v1) > (v2) ? (v1) : (v2))
+#endif
+#ifndef MIN
+#define	MIN(v1, v2)	((v1) < (v2) ? (v1) : (v2))
+#endif
+
+/* There are macros for alignment in DPDK, but we need to make a proper
+ * correspondence here, if we want to re-use them at all
+ */
+#ifndef IS_P2ALIGNED
+#define	IS_P2ALIGNED(v, a)	((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
+#endif
+
+#ifndef P2ROUNDUP
+#define	P2ROUNDUP(x, align)	(-(-(x) & -(align)))
+#endif
+
+#ifndef P2ALIGN
+#define	P2ALIGN(_x, _a)		((_x) & -(_a))
+#endif
+
+#ifndef IS2P
+#define	ISP2(x)			rte_is_power_of_2(x)
+#endif
+
+#define	ENOTACTIVE	ENOTCONN
+
+static inline void
+prefetch_read_many(const volatile void *addr)
+{
+	rte_prefetch0(addr);
+}
+
+static inline void
+prefetch_read_once(const volatile void *addr)
+{
+	rte_prefetch_non_temporal(addr);
+}
+
+/* Modifiers used for Windows builds */
+#define	__in
+#define	__in_opt
+#define	__in_ecount(_n)
+#define	__in_ecount_opt(_n)
+#define	__in_bcount(_n)
+#define	__in_bcount_opt(_n)
+
+#define	__out
+#define	__out_opt
+#define	__out_ecount(_n)
+#define	__out_ecount_opt(_n)
+#define	__out_bcount(_n)
+#define	__out_bcount_opt(_n)
+
+#define	__deref_out
+
+#define	__inout
+#define	__inout_opt
+#define	__inout_ecount(_n)
+#define	__inout_ecount_opt(_n)
+#define	__inout_bcount(_n)
+#define	__inout_bcount_opt(_n)
+#define	__inout_bcount_full_opt(_n)
+
+#define	__deref_out_bcount_opt(n)
+
+#define	__checkReturn
+#define	__success(_x)
+
+#define	__drv_when(_p, _c)
+
+/* Code inclusion options */
+
+
+#define	EFSYS_OPT_NAMES 0
+
+#define	EFSYS_OPT_SIENA 0
+#define	EFSYS_OPT_HUNTINGTON 1
+#define	EFSYS_OPT_MEDFORD 1
+#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
+#define	EFSYS_OPT_CHECK_REG 1
+#else
+#define	EFSYS_OPT_CHECK_REG 0
+#endif
+
+#define	EFSYS_OPT_MCDI 1
+#define	EFSYS_OPT_MCDI_LOGGING 0
+#define	EFSYS_OPT_MCDI_PROXY_AUTH 0
+
+#define	EFSYS_OPT_MAC_STATS 0
+
+#define	EFSYS_OPT_LOOPBACK 0
+
+#define	EFSYS_OPT_MON_MCDI 0
+#define	EFSYS_OPT_MON_STATS 0
+
+#define	EFSYS_OPT_PHY_STATS 0
+#define	EFSYS_OPT_BIST 0
+#define	EFSYS_OPT_PHY_LED_CONTROL 0
+#define	EFSYS_OPT_PHY_FLAGS 0
+
+#define	EFSYS_OPT_VPD 0
+#define	EFSYS_OPT_NVRAM 0
+#define	EFSYS_OPT_BOOTCFG 0
+
+#define	EFSYS_OPT_DIAG 0
+#define	EFSYS_OPT_RX_SCALE 0
+#define	EFSYS_OPT_QSTATS 0
+#define	EFSYS_OPT_FILTER 1
+#define	EFSYS_OPT_RX_SCATTER 0
+
+#define	EFSYS_OPT_EV_PREFETCH 0
+
+#define	EFSYS_OPT_DECODE_INTR_FATAL 0
+
+#define	EFSYS_OPT_LICENSING 0
+
+#define	EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0
+
+#define	EFSYS_OPT_RX_PACKED_STREAM 0
+
+/* ID */
+
+typedef struct __efsys_identifier_s efsys_identifier_t;
+
+
+#define	EFSYS_PROBE(_name)						\
+	do { } while (0)
+
+#define	EFSYS_PROBE1(_name, _type1, _arg1)				\
+	do { } while (0)
+
+#define	EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)		\
+	do { } while (0)
+
+#define	EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,		\
+		     _type3, _arg3)					\
+	do { } while (0)
+
+#define	EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,		\
+		     _type3, _arg3, _type4, _arg4)			\
+	do { } while (0)
+
+#define	EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,		\
+		     _type3, _arg3, _type4, _arg4, _type5, _arg5)	\
+	do { } while (0)
+
+#define	EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,		\
+		     _type3, _arg3, _type4, _arg4, _type5, _arg5,	\
+		     _type6, _arg6)					\
+	do { } while (0)
+
+#define	EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,		\
+		     _type3, _arg3, _type4, _arg4, _type5, _arg5,	\
+		     _type6, _arg6, _type7, _arg7)			\
+	do { } while (0)
+
+
+/* DMA */
+
+typedef phys_addr_t efsys_dma_addr_t;
+
+typedef struct efsys_mem_s {
+	const struct rte_memzone	*esm_mz;
+	/*
+	 * Ideally it should have volatile qualifier to denote that
+	 * the memory may be updated by someone else. However, it adds
+	 * qualifier discard warnings when the pointer or its derivative
+	 * is passed to memset() or rte_mov16().
+	 * So, skip the qualifier here, but make sure that it is added
+	 * below in access macros.
+	 */
+	void				*esm_base;
+	efsys_dma_addr_t		esm_addr;
+} efsys_mem_t;
+
+
+#define	EFSYS_MEM_ZERO(_esmp, _size)					\
+	do {								\
+		(void)memset((void *)(_esmp)->esm_base, 0, (_size));	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_MEM_READD(_esmp, _offset, _edp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esmp)->esm_base;		\
+		volatile uint32_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t)));	\
+									\
+		_addr = (volatile uint32_t *)(_base + (_offset));	\
+		(_edp)->ed_u32[0] = _addr[0];				\
+									\
+		EFSYS_PROBE2(mem_readl, unsigned int, (_offset),	\
+					 uint32_t, (_edp)->ed_u32[0]);	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_MEM_READQ(_esmp, _offset, _eqp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esmp)->esm_base;		\
+		volatile uint64_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t)));	\
+									\
+		_addr = (volatile uint64_t *)(_base + (_offset));	\
+		(_eqp)->eq_u64[0] = _addr[0];				\
+									\
+		EFSYS_PROBE3(mem_readq, unsigned int, (_offset),	\
+					 uint32_t, (_eqp)->eq_u32[1],	\
+					 uint32_t, (_eqp)->eq_u32[0]);	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_MEM_READO(_esmp, _offset, _eop)				\
+	do {								\
+		volatile uint8_t *_base = (_esmp)->esm_base;		\
+		volatile __m128i *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t)));	\
+									\
+		_addr = (volatile __m128i *)(_base + (_offset));	\
+		(_eop)->eo_u128[0] = _addr[0];				\
+									\
+		EFSYS_PROBE5(mem_reado, unsigned int, (_offset),	\
+					 uint32_t, (_eop)->eo_u32[3],	\
+					 uint32_t, (_eop)->eo_u32[2],	\
+					 uint32_t, (_eop)->eo_u32[1],	\
+					 uint32_t, (_eop)->eo_u32[0]);	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+
+#define	EFSYS_MEM_WRITED(_esmp, _offset, _edp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esmp)->esm_base;		\
+		volatile uint32_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t)));	\
+									\
+		EFSYS_PROBE2(mem_writed, unsigned int, (_offset),	\
+					 uint32_t, (_edp)->ed_u32[0]);	\
+									\
+		_addr = (volatile uint32_t *)(_base + (_offset));	\
+		_addr[0] = (_edp)->ed_u32[0];				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esmp)->esm_base;		\
+		volatile uint64_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t)));	\
+									\
+		EFSYS_PROBE3(mem_writeq, unsigned int, (_offset),	\
+					 uint32_t, (_eqp)->eq_u32[1],	\
+					 uint32_t, (_eqp)->eq_u32[0]);	\
+									\
+		_addr = (volatile uint64_t *)(_base + (_offset));	\
+		_addr[0] = (_eqp)->eq_u64[0];				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_MEM_WRITEO(_esmp, _offset, _eop)				\
+	do {								\
+		volatile uint8_t *_base = (_esmp)->esm_base;		\
+		volatile __m128i *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t)));	\
+									\
+									\
+		EFSYS_PROBE5(mem_writeo, unsigned int, (_offset),	\
+					 uint32_t, (_eop)->eo_u32[3],	\
+					 uint32_t, (_eop)->eo_u32[2],	\
+					 uint32_t, (_eop)->eo_u32[1],	\
+					 uint32_t, (_eop)->eo_u32[0]);	\
+									\
+		_addr = (volatile __m128i *)(_base + (_offset));	\
+		_addr[0] = (_eop)->eo_u128[0];				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+
+#define	EFSYS_MEM_ADDR(_esmp)						\
+	((_esmp)->esm_addr)
+
+#define	EFSYS_MEM_IS_NULL(_esmp)					\
+	((_esmp)->esm_base == NULL)
+
+#define	EFSYS_MEM_PREFETCH(_esmp, _offset)				\
+	do {								\
+		volatile uint8_t *_base = (_esmp)->esm_base;		\
+									\
+		rte_prefetch0(_base + (_offset));			\
+	} while (0)
+
+
+/* BAR */
+
+typedef struct efsys_bar_s {
+	rte_spinlock_t		esb_lock;
+	int			esb_rid;
+	struct rte_pci_device	*esb_dev;
+	/*
+	 * Ideally it should have volatile qualifier to denote that
+	 * the memory may be updated by someone else. However, it adds
+	 * qualifier discard warnings when the pointer or its derivative
+	 * is passed to memset() or rte_mov16().
+	 * So, skip the qualifier here, but make sure that it is added
+	 * below in access macros.
+	 */
+	void			*esb_base;
+} efsys_bar_t;
+
+#define	SFC_BAR_LOCK_INIT(_esbp, _ifname)				\
+	do {								\
+		rte_spinlock_init(&(_esbp)->esb_lock);			\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+#define	SFC_BAR_LOCK_DESTROY(_esbp)	((void)0)
+#define	SFC_BAR_LOCK(_esbp)		rte_spinlock_lock(&(_esbp)->esb_lock)
+#define	SFC_BAR_UNLOCK(_esbp)		rte_spinlock_unlock(&(_esbp)->esb_lock)
+
+#define	EFSYS_BAR_READD(_esbp, _offset, _edp, _lock)			\
+	do {								\
+		volatile uint8_t  *_base = (_esbp)->esb_base;		\
+		volatile uint32_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t)));	\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_LOCK(_esbp);				\
+									\
+		_addr = (volatile uint32_t *)(_base + (_offset));	\
+		rte_rmb();						\
+		(_edp)->ed_u32[0] = _addr[0];				\
+									\
+		EFSYS_PROBE2(bar_readd, unsigned int, (_offset),	\
+					 uint32_t, (_edp)->ed_u32[0]);	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_UNLOCK(_esbp);				\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_BAR_READQ(_esbp, _offset, _eqp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esbp)->esb_base;		\
+		volatile uint64_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t)));	\
+									\
+		SFC_BAR_LOCK(_esbp);					\
+									\
+		_addr = (volatile uint64_t *)(_base + (_offset));	\
+		rte_rmb();						\
+		(_eqp)->eq_u64[0] = _addr[0];				\
+									\
+		EFSYS_PROBE3(bar_readq, unsigned int, (_offset),	\
+					 uint32_t, (_eqp)->eq_u32[1],	\
+					 uint32_t, (_eqp)->eq_u32[0]);	\
+									\
+		SFC_BAR_UNLOCK(_esbp);					\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)			\
+	do {								\
+		volatile uint8_t *_base = (_esbp)->esb_base;		\
+		volatile __m128i *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t)));	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_LOCK(_esbp);				\
+									\
+		_addr = (volatile __m128i *)(_base + (_offset));	\
+		rte_rmb();						\
+		(_eop)->eo_u128[0] = _addr[0];				\
+									\
+		EFSYS_PROBE5(bar_reado, unsigned int, (_offset),	\
+					 uint32_t, (_eop)->eo_u32[3],	\
+					 uint32_t, (_eop)->eo_u32[2],	\
+					 uint32_t, (_eop)->eo_u32[1],	\
+					 uint32_t, (_eop)->eo_u32[0]);	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_UNLOCK(_esbp);				\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+
+#define	EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock)			\
+	do {								\
+		volatile uint8_t  *_base = (_esbp)->esb_base;		\
+		volatile uint32_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t)));	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_LOCK(_esbp);				\
+									\
+		EFSYS_PROBE2(bar_writed, unsigned int, (_offset),	\
+					 uint32_t, (_edp)->ed_u32[0]);	\
+									\
+		_addr = (volatile uint32_t *)(_base + (_offset));	\
+		_addr[0] = (_edp)->ed_u32[0];				\
+		rte_wmb();						\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_UNLOCK(_esbp);				\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)				\
+	do {								\
+		volatile uint8_t  *_base = (_esbp)->esb_base;		\
+		volatile uint64_t *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t)));	\
+									\
+		SFC_BAR_LOCK(_esbp);					\
+									\
+		EFSYS_PROBE3(bar_writeq, unsigned int, (_offset),	\
+					 uint32_t, (_eqp)->eq_u32[1],	\
+					 uint32_t, (_eqp)->eq_u32[0]);	\
+									\
+		_addr = (volatile uint64_t *)(_base + (_offset));	\
+		_addr[0] = (_eqp)->eq_u64[0];				\
+		rte_wmb();						\
+									\
+		SFC_BAR_UNLOCK(_esbp);					\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/*
+ * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
+ * (required by PIO hardware).
+ *
+ * Neither VFIO, nor UIO, nor NIC UIO (on FreeBSD) support
+ * write-combined memory mapped to user-land, so just abort if used.
+ */
+#define	EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp)			\
+	do {								\
+		rte_panic("Write-combined BAR access not supported");	\
+	} while (B_FALSE)
+
+#define	EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)			\
+	do {								\
+		volatile uint8_t *_base = (_esbp)->esb_base;		\
+		volatile __m128i *_addr;				\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t)));	\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_LOCK(_esbp);				\
+									\
+		EFSYS_PROBE5(bar_writeo, unsigned int, (_offset),	\
+					 uint32_t, (_eop)->eo_u32[3],	\
+					 uint32_t, (_eop)->eo_u32[2],	\
+					 uint32_t, (_eop)->eo_u32[1],	\
+					 uint32_t, (_eop)->eo_u32[0]);	\
+									\
+		_addr = (volatile __m128i *)(_base + (_offset));	\
+		_addr[0] = (_eop)->eo_u128[0];				\
+		rte_wmb();						\
+									\
+		_NOTE(CONSTANTCONDITION);				\
+		if (_lock)						\
+			SFC_BAR_UNLOCK(_esbp);				\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/* Use the standard octo-word write for doorbell writes */
+#define	EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop)			\
+	do {								\
+		EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE);	\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/* SPIN */
+
+#define	EFSYS_SPIN(_us)							\
+	do {								\
+		rte_delay_us(_us);					\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_SLEEP EFSYS_SPIN
+
+/* BARRIERS */
+
+#define	EFSYS_MEM_READ_BARRIER()	rte_rmb()
+#define	EFSYS_PIO_WRITE_BARRIER()	rte_wmb()
+
+/* DMA SYNC */
+
+/*
+ * DPDK does not provide any DMA syncing API, and no PMD drivers
+ * have any traces of explicit DMA syncing.
+ * DMA mapping is assumed to be coherent.
+ */
+
+#define	EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size)	((void)0)
+#define	EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size)	((void)0)
+
+/* TIMESTAMP */
+
+typedef uint64_t efsys_timestamp_t;
+
+#define	EFSYS_TIMESTAMP(_usp)						\
+	do {								\
+		*(_usp) = rte_get_timer_cycles() * 1000000 /		\
+			rte_get_timer_hz();				\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/* KMEM */
+
+#define	EFSYS_KMEM_ALLOC(_esip, _size, _p)				\
+	do {								\
+		(_esip) = (_esip);					\
+		(_p) = rte_zmalloc("sfc", (_size), 0);			\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_KMEM_FREE(_esip, _size, _p)				\
+	do {								\
+		(void)(_esip);						\
+		(void)(_size);						\
+		rte_free((_p));						\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/* LOCK */
+
+typedef rte_spinlock_t efsys_lock_t;
+
+#define	SFC_EFSYS_LOCK_INIT(_eslp, _ifname, _label)	\
+	rte_spinlock_init((_eslp))
+#define	SFC_EFSYS_LOCK_DESTROY(_eslp) ((void)0)
+#define	SFC_EFSYS_LOCK(_eslp)				\
+	rte_spinlock_lock((_eslp))
+#define	SFC_EFSYS_UNLOCK(_eslp)				\
+	rte_spinlock_unlock((_eslp))
+#define	SFC_EFSYS_LOCK_ASSERT_OWNED(_eslp)		\
+	SFC_ASSERT(rte_spinlock_is_locked((_eslp)))
+
+typedef int efsys_lock_state_t;
+
+#define	EFSYS_LOCK_MAGIC	0x000010c4
+
+#define	EFSYS_LOCK(_lockp, _state)				\
+	do {							\
+		SFC_EFSYS_LOCK(_lockp);				\
+		(_state) = EFSYS_LOCK_MAGIC;			\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_UNLOCK(_lockp, _state)				\
+	do {							\
+		SFC_ASSERT((_state) == EFSYS_LOCK_MAGIC);	\
+		SFC_EFSYS_UNLOCK(_lockp);			\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+/* STAT */
+
+typedef uint64_t	efsys_stat_t;
+
+#define	EFSYS_STAT_INCR(_knp, _delta)				\
+	do {							\
+		*(_knp) += (_delta);				\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_DECR(_knp, _delta)				\
+	do {							\
+		*(_knp) -= (_delta);				\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_SET(_knp, _val)				\
+	do {							\
+		*(_knp) = (_val);				\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_SET_QWORD(_knp, _valp)			\
+	do {							\
+		*(_knp) = rte_le_to_cpu_64((_valp)->eq_u64[0]);	\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_SET_DWORD(_knp, _valp)			\
+	do {							\
+		*(_knp) = rte_le_to_cpu_32((_valp)->ed_u32[0]);	\
+		_NOTE(CONSTANTCONDITION);			\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_INCR_QWORD(_knp, _valp)				\
+	do {								\
+		*(_knp) += rte_le_to_cpu_64((_valp)->eq_u64[0]);	\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+#define	EFSYS_STAT_SUBR_QWORD(_knp, _valp)				\
+	do {								\
+		*(_knp) -= rte_le_to_cpu_64((_valp)->eq_u64[0]);	\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+
+/* ERR */
+
+#if EFSYS_OPT_DECODE_INTR_FATAL
+#define	EFSYS_ERR(_esip, _code, _dword0, _dword1)			\
+	do {								\
+		(void)(_esip);						\
+		RTE_LOG(ERR, PMD, "FATAL ERROR #%u (0x%08x%08x)\n",	\
+			(_code), (_dword0), (_dword1));			\
+		_NOTE(CONSTANTCONDITION);				\
+	} while (B_FALSE)
+#endif
+
+/* ASSERT */
+
+/* RTE_VERIFY from DPDK treats expressions with % operator incorrectly,
+ * so we re-implement it here
+ */
+#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
+#define	EFSYS_ASSERT(_exp)						\
+	do {								\
+		if (unlikely(!(_exp)))					\
+			rte_panic("line %d\tassert \"%s\" failed\n",	\
+				  __LINE__, (#_exp));			\
+	} while (0)
+#else
+#define	EFSYS_ASSERT(_exp)		(void)(_exp)
+#endif
+
+#define	EFSYS_ASSERT3(_x, _op, _y, _t)	EFSYS_ASSERT((_t)(_x) _op (_t)(_y))
+
+#define	EFSYS_ASSERT3U(_x, _op, _y)	EFSYS_ASSERT3(_x, _op, _y, uint64_t)
+#define	EFSYS_ASSERT3S(_x, _op, _y)	EFSYS_ASSERT3(_x, _op, _y, int64_t)
+#define	EFSYS_ASSERT3P(_x, _op, _y)	EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
+
+/* ROTATE */
+
+#define	EFSYS_HAS_ROTL_DWORD	0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _SFC_COMMON_EFSYS_H */
-- 
2.5.5

^ permalink raw reply related

* [PATCH 52/56] net/sfc: provide basic stubs for Tx subsystem
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <ivan.malov@oktetlabs.ru>

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/nics/features/sfc_efx.ini |  2 +
 doc/guides/nics/sfc_efx.rst          |  2 +
 drivers/net/sfc/efx/Makefile         |  1 +
 drivers/net/sfc/efx/sfc.c            | 14 ++++++
 drivers/net/sfc/efx/sfc.h            |  6 +++
 drivers/net/sfc/efx/sfc_ethdev.c     | 17 ++++++++
 drivers/net/sfc/efx/sfc_tx.c         | 85 ++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/sfc_tx.h         | 53 ++++++++++++++++++++++
 8 files changed, 180 insertions(+)
 create mode 100644 drivers/net/sfc/efx/sfc_tx.c
 create mode 100644 drivers/net/sfc/efx/sfc_tx.h

diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 7dc2e92..67df1c6 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,8 @@
 ;
 [Features]
 Link status          = Y
+L3 checksum offload  = P
+L4 checksum offload  = P
 BSD nic_uio          = Y
 Linux UIO            = Y
 Linux VFIO           = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 8145a6b..aadd775 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -46,6 +46,8 @@ SFC EFX PMD has support for:
 
 - Link state information
 
+- IPv4/IPv6 TCP/UDP transmit checksum offload
+
 
 Non-supported Features
 ----------------------
diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
index eb82c89..8ecca83 100644
--- a/drivers/net/sfc/efx/Makefile
+++ b/drivers/net/sfc/efx/Makefile
@@ -88,6 +88,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_intr.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ev.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_port.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_tx.c
 
 VPATH += $(SRCDIR)/base
 
diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
index 1c0f59d..6990ccd 100644
--- a/drivers/net/sfc/efx/sfc.c
+++ b/drivers/net/sfc/efx/sfc.c
@@ -38,6 +38,7 @@
 #include "sfc_log.h"
 #include "sfc_ev.h"
 #include "sfc_rx.h"
+#include "sfc_tx.h"
 
 
 int
@@ -362,10 +363,17 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_rx_init;
 
+	rc = sfc_tx_init(sa);
+	if (rc != 0)
+		goto fail_tx_init;
+
 	sa->state = SFC_ADAPTER_CONFIGURED;
 	sfc_log_init(sa, "done");
 	return 0;
 
+fail_tx_init:
+	sfc_rx_fini(sa);
+
 fail_rx_init:
 	sfc_port_fini(sa);
 
@@ -392,6 +400,7 @@ sfc_close(struct sfc_adapter *sa)
 	SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
 	sa->state = SFC_ADAPTER_CLOSING;
 
+	sfc_tx_fini(sa);
 	sfc_rx_fini(sa);
 	sfc_port_fini(sa);
 	sfc_ev_fini(sa);
@@ -438,6 +447,7 @@ int
 sfc_attach(struct sfc_adapter *sa)
 {
 	struct rte_pci_device *pci_dev = sa->eth_dev->pci_dev;
+	const efx_nic_cfg_t *encp;
 	efx_nic_t *enp;
 	int rc;
 
@@ -488,6 +498,10 @@ sfc_attach(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_estimate_rsrc_limits;
 
+	encp = efx_nic_cfg_get(sa->nic);
+	sa->txq_max_entries = encp->enc_txq_max_ndescs;
+	SFC_ASSERT(rte_is_power_of_2(sa->txq_max_entries));
+
 	rc = sfc_intr_attach(sa);
 	if (rc != 0)
 		goto fail_intr_attach;
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index a592b53..de0395e 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -115,6 +115,7 @@ struct sfc_intr {
 
 struct sfc_evq_info;
 struct sfc_rxq_info;
+struct sfc_txq_info;
 
 struct sfc_port {
 	unsigned int			flow_ctrl;
@@ -148,6 +149,8 @@ struct sfc_adapter {
 	unsigned int			rxq_max;
 	unsigned int			txq_max;
 
+	unsigned int			txq_max_entries;
+
 	unsigned int			evq_count;
 	struct sfc_evq_info		*evq_info;
 
@@ -156,6 +159,9 @@ struct sfc_adapter {
 
 	unsigned int			rxq_count;
 	struct sfc_rxq_info		*rxq_info;
+
+	unsigned int			txq_count;
+	struct sfc_txq_info		*txq_info;
 };
 
 /*
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index 61ae1bd..4afd30c 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -51,16 +51,33 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
 
 	dev_info->max_rx_queues = sa->rxq_max;
+	dev_info->max_tx_queues = sa->txq_max;
 
 	/* By default packets are dropped if no descriptors are available */
 	dev_info->default_rxconf.rx_drop_en = 1;
 
+	dev_info->tx_offload_capa =
+		DEV_TX_OFFLOAD_IPV4_CKSUM |
+		DEV_TX_OFFLOAD_UDP_CKSUM |
+		DEV_TX_OFFLOAD_TCP_CKSUM;
+
+	dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOVLANOFFL |
+					     ETH_TXQ_FLAGS_NOXSUMSCTP;
+
 	dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
 	dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
 	/* The RXQ hardware requires that the descriptor count is a power
 	 * of 2, but rx_desc_lim cannot properly describe that constraint.
 	 */
 	dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
+
+	dev_info->tx_desc_lim.nb_max = sa->txq_max_entries;
+	dev_info->tx_desc_lim.nb_min = EFX_TXQ_MINNDESCS;
+	/*
+	 * The TXQ hardware requires that the descriptor count is a power
+	 * of 2, but tx_desc_lim cannot properly describe that constraint
+	 */
+	dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
 }
 
 static int
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
new file mode 100644
index 0000000..c418185
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sfc.h"
+#include "sfc_log.h"
+#include "sfc_ev.h"
+#include "sfc_tx.h"
+
+static int
+sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
+{
+	struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
+	int rc = 0;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	return 0;
+}
+
+int
+sfc_tx_init(struct sfc_adapter *sa)
+{
+	int sw_index;
+	int rc = 0;
+
+	sa->txq_count = sa->eth_dev->data->nb_tx_queues;
+
+	sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
+					 sizeof(sa->txq_info[0]), 0,
+					 sa->socket_id);
+	if (sa->txq_info == NULL)
+		goto fail_txqs_alloc;
+
+	for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
+		rc = sfc_tx_qinit_info(sa, sw_index);
+		if (rc != 0)
+			goto fail_tx_qinit_info;
+	}
+
+	return 0;
+
+fail_tx_qinit_info:
+	rte_free(sa->txq_info);
+	sa->txq_info = NULL;
+
+fail_txqs_alloc:
+	sa->txq_count = 0;
+
+	sfc_log_init(sa, "failed (rc = %d)", rc);
+	return rc;
+}
+
+void
+sfc_tx_fini(struct sfc_adapter *sa)
+{
+	rte_free(sa->txq_info);
+	sa->txq_info = NULL;
+	sa->txq_count = 0;
+}
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
new file mode 100644
index 0000000..b2d4875
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_TX_H
+#define	_SFC_TX_H
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+
+#include "efx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sfc_adapter;
+
+struct sfc_txq_info {
+};
+
+int sfc_tx_init(struct sfc_adapter *sa);
+void sfc_tx_fini(struct sfc_adapter *sa);
+
+#ifdef __cplusplus
+}
+#endif
+#endif	/* _SFC_TX_H */
-- 
2.5.5

^ permalink raw reply related

* [PATCH 55/56] net/sfc: implement transmit path start / stop
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <ivan.malov@oktetlabs.ru>

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/sfc.c    |   8 ++
 drivers/net/sfc/efx/sfc_ev.c |  12 ++-
 drivers/net/sfc/efx/sfc_tx.c | 237 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efx/sfc_tx.h |  17 ++++
 4 files changed, 271 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
index 6990ccd..ef9e0d4 100644
--- a/drivers/net/sfc/efx/sfc.c
+++ b/drivers/net/sfc/efx/sfc.c
@@ -276,10 +276,17 @@ sfc_start(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_rx_start;
 
+	rc = sfc_tx_start(sa);
+	if (rc != 0)
+		goto fail_tx_start;
+
 	sa->state = SFC_ADAPTER_STARTED;
 	sfc_log_init(sa, "done");
 	return 0;
 
+fail_tx_start:
+	sfc_rx_stop(sa);
+
 fail_rx_start:
 	sfc_port_stop(sa);
 
@@ -321,6 +328,7 @@ sfc_stop(struct sfc_adapter *sa)
 
 	sa->state = SFC_ADAPTER_STOPPING;
 
+	sfc_tx_stop(sa);
 	sfc_rx_stop(sa);
 	sfc_port_stop(sa);
 	sfc_ev_stop(sa);
diff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c
index 8f260e7..b3cecbb 100644
--- a/drivers/net/sfc/efx/sfc_ev.c
+++ b/drivers/net/sfc/efx/sfc_ev.c
@@ -38,6 +38,7 @@
 #include "sfc_log.h"
 #include "sfc_ev.h"
 #include "sfc_rx.h"
+#include "sfc_tx.h"
 
 
 /* Initial delay when waiting for event queue init complete event */
@@ -206,10 +207,15 @@ static boolean_t
 sfc_ev_txq_flush_done(void *arg, uint32_t txq_hw_index)
 {
 	struct sfc_evq *evq = arg;
+	struct sfc_txq *txq;
 
-	sfc_err(evq->sa, "EVQ %u unexpected Tx flush done event",
-		evq->evq_index);
-	return B_TRUE;
+	txq = evq->txq;
+	SFC_ASSERT(txq != NULL);
+	SFC_ASSERT(txq->hw_index == txq_hw_index);
+	SFC_ASSERT(txq->evq == evq);
+	sfc_tx_qflush_done(txq);
+
+	return B_FALSE;
 }
 
 static boolean_t
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
index a4ffe9c..99d845a 100644
--- a/drivers/net/sfc/efx/sfc_tx.c
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -28,10 +28,30 @@
  */
 
 #include "sfc.h"
+#include "sfc_debug.h"
 #include "sfc_log.h"
 #include "sfc_ev.h"
 #include "sfc_tx.h"
 
+/*
+ * Maximum number of TX queue flush attempts in case of
+ * failure or flush timeout
+ */
+#define	SFC_TX_QFLUSH_ATTEMPTS		(3)
+
+/*
+ * Time to wait between event queue polling attempts when waiting for TX
+ * queue flush done or flush failed events
+ */
+#define	SFC_TX_QFLUSH_POLL_WAIT_MS	(1)
+
+/*
+ * Maximum number of event queue polling attempts when wating for TX queue
+ * flush done or flush failed events; it defines TX queue flush attempt timeout
+ * together with SFC_TX_QFLUSH_POLL_WAIT_MS
+ */
+#define	SFC_TX_QFLUSH_POLL_ATTEMPTS	(2000)
+
 static int
 sfc_tx_qcheck_conf(struct sfc_adapter *sa,
 		   const struct rte_eth_txconf *tx_conf)
@@ -83,6 +103,36 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa,
 	return rc;
 }
 
+void
+sfc_tx_qflush_done(struct sfc_txq *txq)
+{
+	txq->state |= SFC_TXQ_FLUSHED;
+	txq->state &= ~SFC_TXQ_FLUSHING;
+}
+
+static void
+sfc_tx_reap(struct sfc_txq *txq)
+{
+	unsigned int    completed;
+
+
+	sfc_ev_qpoll(txq->evq);
+
+	for (completed = txq->completed;
+	     completed != txq->pending; completed++) {
+		struct sfc_tx_sw_desc *txd;
+
+		txd = &txq->sw_ring[completed & txq->ptr_mask];
+
+		if (txd->mbuf != NULL) {
+			rte_pktmbuf_free(txd->mbuf);
+			txd->mbuf = NULL;
+		}
+	}
+
+	txq->completed = completed;
+}
+
 int
 sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     uint16_t nb_tx_desc, unsigned int socket_id,
@@ -292,3 +342,190 @@ sfc_tx_fini(struct sfc_adapter *sa)
 	sa->txq_info = NULL;
 	sa->txq_count = 0;
 }
+
+int
+sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
+{
+	struct rte_eth_dev_data *dev_data;
+	struct sfc_txq_info *txq_info;
+	struct sfc_txq *txq;
+	struct sfc_evq *evq;
+	uint16_t flags;
+	unsigned int desc_index;
+	int rc = 0;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	SFC_ASSERT(sw_index < sa->txq_count);
+	txq_info = &sa->txq_info[sw_index];
+
+	txq = txq_info->txq;
+
+	SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+
+	evq = txq->evq;
+
+	rc = sfc_ev_qstart(sa, evq->evq_index);
+	if (rc != 0)
+		goto fail_ev_qstart;
+
+	/*
+	 * It seems that DPDK has no controls regarding IPv4 offloads,
+	 * hence, we always enable it here
+	 */
+	if ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||
+	    (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP))
+		flags = EFX_TXQ_CKSUM_IPV4;
+	else
+		flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
+
+	rc = efx_tx_qcreate(sa->nic, sw_index, 0, &txq->mem,
+			    txq_info->entries, 0 /* not used on EF10 */,
+			    flags, evq->common,
+			    &txq->common, &desc_index);
+	if (rc != 0)
+		goto fail_tx_qcreate;
+
+	txq->added = txq->pending = txq->completed = desc_index;
+
+	efx_tx_qenable(txq->common);
+
+	txq->state |= (SFC_TXQ_STARTED | SFC_TXQ_RUNNING);
+
+	/*
+	 * It seems to be used by DPDK for debug purposes only ('rte_ether')
+	 */
+	dev_data = sa->eth_dev->data;
+	dev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STARTED;
+
+	return 0;
+
+fail_tx_qcreate:
+	sfc_ev_qstop(sa, evq->evq_index);
+
+fail_ev_qstart:
+	return rc;
+}
+
+void
+sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
+{
+	struct rte_eth_dev_data *dev_data;
+	struct sfc_txq_info *txq_info;
+	struct sfc_txq *txq;
+	unsigned int retry_count;
+	unsigned int wait_count;
+	unsigned int txds;
+
+	sfc_log_init(sa, "TxQ = %u", sw_index);
+
+	SFC_ASSERT(sw_index < sa->txq_count);
+	txq_info = &sa->txq_info[sw_index];
+
+	txq = txq_info->txq;
+
+	SFC_ASSERT(txq->state & SFC_TXQ_STARTED);
+
+	txq->state &= ~SFC_TXQ_RUNNING;
+
+	/*
+	 * Retry TX queue flushing in case of flush failed or
+	 * timeout; in the worst case it can delay for 6 seconds
+	 */
+	for (retry_count = 0;
+	     ((txq->state & SFC_TXQ_FLUSHED) == 0) &&
+	     (retry_count < SFC_TX_QFLUSH_ATTEMPTS);
+	     ++retry_count) {
+		if (efx_tx_qflush(txq->common) != 0) {
+			txq->state |= SFC_TXQ_FLUSHING;
+			break;
+		}
+
+		/*
+		 * Wait for TX queue flush done or flush failed event at least
+		 * SFC_TX_QFLUSH_POLL_WAIT_MS milliseconds and not more
+		 * than 2 seconds (SFC_TX_QFLUSH_POLL_WAIT_MS multiplied
+		 * by SFC_TX_QFLUSH_POLL_ATTEMPTS)
+		 */
+		wait_count = 0;
+		do {
+			rte_delay_ms(SFC_TX_QFLUSH_POLL_WAIT_MS);
+			sfc_ev_qpoll(txq->evq);
+		} while ((txq->state & SFC_TXQ_FLUSHING) &&
+			 wait_count++ < SFC_TX_QFLUSH_POLL_ATTEMPTS);
+
+		if (txq->state & SFC_TXQ_FLUSHING)
+			sfc_err(sa, "TxQ %u flush timed out", sw_index);
+
+		if (txq->state & SFC_TXQ_FLUSHED)
+			sfc_info(sa, "TxQ %u flushed", sw_index);
+	}
+
+	sfc_tx_reap(txq);
+
+	for (txds = 0; txds < txq_info->entries; txds++) {
+		if (txq->sw_ring[txds].mbuf != NULL) {
+			rte_pktmbuf_free(txq->sw_ring[txds].mbuf);
+			txq->sw_ring[txds].mbuf = NULL;
+		}
+	}
+
+	txq->state = SFC_TXQ_INITIALIZED;
+
+	efx_tx_qdestroy(txq->common);
+
+	sfc_ev_qstop(sa, txq->evq->evq_index);
+
+	/*
+	 * It seems to be used by DPDK for debug purposes only ('rte_ether')
+	 */
+	dev_data = sa->eth_dev->data;
+	dev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STOPPED;
+}
+
+int
+sfc_tx_start(struct sfc_adapter *sa)
+{
+	int sw_index;
+	int rc = 0;
+
+	sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+
+	rc = efx_tx_init(sa->nic);
+	if (rc != 0)
+		goto fail_efx_tx_init;
+
+	for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
+		rc = sfc_tx_qstart(sa, sw_index);
+		if (rc != 0)
+			goto fail_tx_qstart;
+	}
+
+	return 0;
+
+fail_tx_qstart:
+	while (--sw_index >= 0)
+		sfc_tx_qstop(sa, sw_index);
+
+	efx_tx_fini(sa->nic);
+
+fail_efx_tx_init:
+	sfc_log_init(sa, "failed (rc = %d)", rc);
+	return rc;
+}
+
+void
+sfc_tx_stop(struct sfc_adapter *sa)
+{
+	int sw_index;
+
+	sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+
+	sw_index = sa->txq_count;
+	while (--sw_index >= 0) {
+		if (sa->txq_info[sw_index].txq != NULL)
+			sfc_tx_qstop(sa, sw_index);
+	}
+
+	efx_tx_fini(sa->nic);
+}
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
index 3278797..47970f9 100644
--- a/drivers/net/sfc/efx/sfc_tx.h
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -49,6 +49,14 @@ struct sfc_tx_sw_desc {
 enum sfc_txq_state_bit {
 	SFC_TXQ_INITIALIZED_BIT = 0,
 #define	SFC_TXQ_INITIALIZED	(1 << SFC_TXQ_INITIALIZED_BIT)
+	SFC_TXQ_STARTED_BIT,
+#define	SFC_TXQ_STARTED		(1 << SFC_TXQ_STARTED_BIT)
+	SFC_TXQ_RUNNING_BIT,
+#define	SFC_TXQ_RUNNING		(1 << SFC_TXQ_RUNNING_BIT)
+	SFC_TXQ_FLUSHING_BIT,
+#define	SFC_TXQ_FLUSHING	(1 << SFC_TXQ_FLUSHING_BIT)
+	SFC_TXQ_FLUSHED_BIT,
+#define	SFC_TXQ_FLUSHED		(1 << SFC_TXQ_FLUSHED_BIT)
 };
 
 struct sfc_txq {
@@ -59,6 +67,9 @@ struct sfc_txq {
 	efx_desc_t		*pend_desc;
 	efx_txq_t		*common;
 	efsys_mem_t		mem;
+	unsigned int		added;
+	unsigned int		pending;
+	unsigned int		completed;
 
 	unsigned int		hw_index;
 	unsigned int		flags;
@@ -83,6 +94,12 @@ int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 const struct rte_eth_txconf *tx_conf);
 void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 
+void sfc_tx_qflush_done(struct sfc_txq *txq);
+int sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
+void sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
+int sfc_tx_start(struct sfc_adapter *sa);
+void sfc_tx_stop(struct sfc_adapter *sa);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.5.5

^ permalink raw reply related

* [PATCH 43/56] net/sfc: implement device operation to retrieve link info
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
  To: dev; +Cc: Artem Andreev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Artem Andreev <Artem.Andreev@oktetlabs.ru>

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/nics/features/sfc_efx.ini |  1 +
 doc/guides/nics/sfc_efx.rst          |  2 ++
 drivers/net/sfc/efx/sfc.h            |  3 ++
 drivers/net/sfc/efx/sfc_ethdev.c     | 42 ++++++++++++++++++++++++++
 drivers/net/sfc/efx/sfc_ev.c         | 12 ++++++--
 drivers/net/sfc/efx/sfc_port.c       | 58 ++++++++++++++++++++++++++++++++++++
 6 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 59eb830..7dc2e92 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Link status          = Y
 BSD nic_uio          = Y
 Linux UIO            = Y
 Linux VFIO           = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 271c8c6..46c892b 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -44,6 +44,8 @@ SFC EFX PMD has support for:
 
 - Multiple transmit and receive queues
 
+- Link state information
+
 
 Non-supported Features
 ----------------------
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index ab867da..f328482 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -215,6 +215,9 @@ int sfc_port_init(struct sfc_adapter *sa);
 void sfc_port_fini(struct sfc_adapter *sa);
 int sfc_port_start(struct sfc_adapter *sa);
 void sfc_port_stop(struct sfc_adapter *sa);
+void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+				struct rte_eth_link *link_info);
+
 
 #ifdef __cplusplus
 }
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index a328232..a8a6a17 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -37,6 +37,7 @@
 #include "sfc_debug.h"
 #include "sfc_log.h"
 #include "sfc_kvargs.h"
+#include "sfc_ev.h"
 
 
 static void
@@ -98,6 +99,46 @@ sfc_dev_start(struct rte_eth_dev *dev)
 	return -rc;
 }
 
+static int
+sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+	struct sfc_adapter *sa = dev->data->dev_private;
+	struct rte_eth_link *dev_link = &dev->data->dev_link;
+	struct rte_eth_link old_link;
+	struct rte_eth_link current_link;
+
+	sfc_log_init(sa, "entry");
+
+	if (sa->state != SFC_ADAPTER_STARTED)
+		return 0;
+
+retry:
+	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
+	*(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
+
+	if (wait_to_complete) {
+		efx_link_mode_t link_mode;
+
+		efx_port_poll(sa->nic, &link_mode);
+		sfc_port_link_mode_to_info(link_mode, &current_link);
+
+		if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
+					 *(uint64_t *)&old_link,
+					 *(uint64_t *)&current_link))
+			goto retry;
+	} else {
+		sfc_ev_mgmt_qpoll(sa);
+		*(int64_t *)&current_link =
+			rte_atomic64_read((rte_atomic64_t *)dev_link);
+	}
+
+	if (old_link.link_status != current_link.link_status)
+		sfc_info(sa, "Link status is %s",
+			 current_link.link_status ? "UP" : "DOWN");
+
+	return old_link.link_status == current_link.link_status ? 0 : -1;
+}
+
 static void
 sfc_dev_stop(struct rte_eth_dev *dev)
 {
@@ -145,6 +186,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
 	.dev_start			= sfc_dev_start,
 	.dev_stop			= sfc_dev_stop,
 	.dev_close			= sfc_dev_close,
+	.link_update			= sfc_dev_link_update,
 	.dev_infos_get			= sfc_dev_infos_get,
 };
 
diff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c
index 1cb9771..8e2fc94 100644
--- a/drivers/net/sfc/efx/sfc_ev.c
+++ b/drivers/net/sfc/efx/sfc_ev.c
@@ -182,10 +182,16 @@ static boolean_t
 sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
 {
 	struct sfc_evq *evq = arg;
+	struct sfc_adapter *sa = evq->sa;
+	struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
+	struct rte_eth_link new_link;
 
-	sfc_err(evq->sa, "EVQ %u unexpected link change",
-		evq->evq_index);
-	return B_TRUE;
+	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
+
+	sfc_port_link_mode_to_info(link_mode, &new_link);
+	rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
+
+	return B_FALSE;
 }
 
 static const efx_ev_callbacks_t sfc_ev_callbacks = {
diff --git a/drivers/net/sfc/efx/sfc_port.c b/drivers/net/sfc/efx/sfc_port.c
index 844363c..c124181 100644
--- a/drivers/net/sfc/efx/sfc_port.c
+++ b/drivers/net/sfc/efx/sfc_port.c
@@ -129,3 +129,61 @@ sfc_port_fini(struct sfc_adapter *sa)
 
 	sfc_log_init(sa, "done");
 }
+
+void
+sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+			   struct rte_eth_link *link_info)
+{
+	SFC_ASSERT(link_mode < EFX_LINK_NMODES);
+
+	memset(link_info, 0, sizeof(*link_info));
+	if ((link_mode == EFX_LINK_DOWN) || (link_mode == EFX_LINK_UNKNOWN))
+		link_info->link_status = ETH_LINK_DOWN;
+	else
+		link_info->link_status = ETH_LINK_UP;
+
+	switch (link_mode) {
+	case EFX_LINK_10HDX:
+		link_info->link_speed  = ETH_SPEED_NUM_10M;
+		link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+		break;
+	case EFX_LINK_10FDX:
+		link_info->link_speed  = ETH_SPEED_NUM_10M;
+		link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case EFX_LINK_100HDX:
+		link_info->link_speed  = ETH_SPEED_NUM_100M;
+		link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+		break;
+	case EFX_LINK_100FDX:
+		link_info->link_speed  = ETH_SPEED_NUM_100M;
+		link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case EFX_LINK_1000HDX:
+		link_info->link_speed  = ETH_SPEED_NUM_1G;
+		link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+		break;
+	case EFX_LINK_1000FDX:
+		link_info->link_speed  = ETH_SPEED_NUM_1G;
+		link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case EFX_LINK_10000FDX:
+		link_info->link_speed  = ETH_SPEED_NUM_10G;
+		link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case EFX_LINK_40000FDX:
+		link_info->link_speed  = ETH_SPEED_NUM_40G;
+		link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	default:
+		SFC_ASSERT(B_FALSE);
+		/* FALLTHROUGH */
+	case EFX_LINK_UNKNOWN:
+	case EFX_LINK_DOWN:
+		link_info->link_speed  = ETH_SPEED_NUM_NONE;
+		link_info->link_duplex = 0;
+		break;
+	}
+
+	link_info->link_autoneg = ETH_LINK_AUTONEG;
+}
-- 
2.5.5

^ permalink raw reply related

* [PATCH 53/56] net/sfc: add function to check configured Tx mode
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <ivan.malov@oktetlabs.ru>

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/sfc_tx.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
index c418185..fecd058 100644
--- a/drivers/net/sfc/efx/sfc_tx.c
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -43,12 +43,53 @@ sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
 	return 0;
 }
 
+static int
+sfc_tx_check_mode(struct sfc_adapter *sa, const struct rte_eth_txmode *txmode)
+{
+	int rc = 0;
+
+	switch (txmode->mq_mode) {
+	case ETH_MQ_TX_NONE:
+		break;
+	default:
+		sfc_err(sa, "Tx multi-queue mode %u not supported",
+			txmode->mq_mode);
+		rc = EINVAL;
+	}
+
+	/*
+	 * These features are claimed to be i40e-specific,
+	 * but it does make sense to double-check their absence
+	 */
+	if (txmode->hw_vlan_reject_tagged) {
+		sfc_err(sa, "Rejecting tagged packets not supported");
+		rc = EINVAL;
+	}
+
+	if (txmode->hw_vlan_reject_untagged) {
+		sfc_err(sa, "Rejecting untagged packets not supported");
+		rc = EINVAL;
+	}
+
+	if (txmode->hw_vlan_insert_pvid) {
+		sfc_err(sa, "Port-based VLAN insertion not supported");
+		rc = EINVAL;
+	}
+
+	return rc;
+}
+
 int
 sfc_tx_init(struct sfc_adapter *sa)
 {
+	const struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf;
 	int sw_index;
 	int rc = 0;
 
+	rc = sfc_tx_check_mode(sa, &dev_conf->txmode);
+	if (rc != 0)
+		goto fail_check_mode;
+
 	sa->txq_count = sa->eth_dev->data->nb_tx_queues;
 
 	sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
@@ -72,6 +113,7 @@ sfc_tx_init(struct sfc_adapter *sa)
 fail_txqs_alloc:
 	sa->txq_count = 0;
 
+fail_check_mode:
 	sfc_log_init(sa, "failed (rc = %d)", rc);
 	return rc;
 }
-- 
2.5.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox