* [PATCH] net/enic: add support for TSO
From: John Daley @ 2017-01-07 4:45 UTC (permalink / raw)
To: bruce.richardson; +Cc: dev, John Daley
The enic TSO implementation requires that the length of the Eth/IP/TCP
headers be passed to the NIC. Other than that, it's just a matter of
setting the mss and offload mode on a per packet basis.
In TSO mode, IP and TCP checksums are offloaded even if not requested
with mb->ol_flags.
Signed-off-by: John Daley <johndale@cisco.com>
---
drivers/net/enic/enic_ethdev.c | 3 +-
drivers/net/enic/enic_rxtx.c | 93 ++++++++++++++++++++++++++++++++++++------
2 files changed, 83 insertions(+), 13 deletions(-)
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index e5ceb98..c3ba2aa 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -475,7 +475,8 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
- DEV_TX_OFFLOAD_TCP_CKSUM;
+ DEV_TX_OFFLOAD_TCP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_TSO;
device_info->default_rxconf = (struct rte_eth_rxconf) {
.rx_free_thresh = ENIC_DEFAULT_RX_FREE_THRESH
};
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index f762a26..ed2b721 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -37,6 +37,9 @@
#include "enic_compat.h"
#include "rq_enet_desc.h"
#include "enic.h"
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
#define RTE_PMD_USE_PREFETCH
@@ -129,6 +132,60 @@ enic_cq_rx_desc_n_bytes(struct cq_desc *cqd)
CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
}
+/* Find the offset to L5. This is needed by enic TSO implementation.
+ * Return 0 if not a TCP packet or can't figure out the length.
+ */
+static inline uint8_t tso_header_len(struct rte_mbuf *mbuf)
+{
+ struct ether_hdr *eh;
+ struct vlan_hdr *vh;
+ struct ipv4_hdr *ip4;
+ struct ipv6_hdr *ip6;
+ struct tcp_hdr *th;
+ uint8_t hdr_len;
+ uint16_t ether_type;
+
+ /* offset past Ethernet header */
+ eh = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
+ ether_type = eh->ether_type;
+ hdr_len = sizeof(struct ether_hdr);
+ if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_VLAN)) {
+ vh = rte_pktmbuf_mtod_offset(mbuf, struct vlan_hdr *, hdr_len);
+ ether_type = vh->eth_proto;
+ hdr_len += sizeof(struct vlan_hdr);
+ }
+
+ /* offset past IP header */
+ switch (rte_be_to_cpu_16(ether_type)) {
+ case ETHER_TYPE_IPv4:
+ ip4 = rte_pktmbuf_mtod_offset(mbuf, struct ipv4_hdr *, hdr_len);
+ if (ip4->next_proto_id != IPPROTO_TCP)
+ return 0;
+ hdr_len += (ip4->version_ihl & 0xf) * 4;
+ break;
+ case ETHER_TYPE_IPv6:
+ ip6 = rte_pktmbuf_mtod_offset(mbuf, struct ipv6_hdr *, hdr_len);
+ if (ip6->proto != IPPROTO_TCP)
+ return 0;
+ hdr_len += sizeof(struct ipv6_hdr);
+ break;
+ default:
+ return 0;
+ }
+
+ if ((hdr_len + sizeof(struct tcp_hdr)) > mbuf->pkt_len)
+ return 0;
+
+ /* offset past TCP header */
+ th = rte_pktmbuf_mtod_offset(mbuf, struct tcp_hdr *, hdr_len);
+ hdr_len += (th->data_off >> 4) * 4;
+
+ if (hdr_len > mbuf->pkt_len)
+ return 0;
+
+ return hdr_len;
+}
+
static inline uint8_t
enic_cq_rx_check_err(struct cq_desc *cqd)
{
@@ -462,10 +519,12 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
struct vnic_wq_buf *buf;
unsigned int desc_count;
struct wq_enet_desc *descs, *desc_p, desc_tmp;
- uint16_t mss;
+ uint16_t mss = 0;
uint8_t vlan_tag_insert;
uint8_t eop;
uint64_t bus_addr;
+ uint8_t offload_mode;
+ uint16_t header_len;
enic_cleanup_wq(enic, wq);
wq_desc_avail = vnic_wq_desc_avail(wq);
@@ -487,7 +546,6 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
pkt_len = tx_pkt->pkt_len;
data_len = tx_pkt->data_len;
ol_flags = tx_pkt->ol_flags;
- mss = 0;
vlan_id = 0;
vlan_tag_insert = 0;
bus_addr = (dma_addr_t)
@@ -497,13 +555,17 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
desc_p = descs + head_idx;
eop = (data_len == pkt_len);
-
- if (ol_flags & ol_flags_mask) {
- if (ol_flags & PKT_TX_VLAN_PKT) {
- vlan_tag_insert = 1;
- vlan_id = tx_pkt->vlan_tci;
+ offload_mode = WQ_ENET_OFFLOAD_MODE_CSUM;
+ header_len = 0;
+
+ if (tx_pkt->tso_segsz) {
+ header_len = tso_header_len(tx_pkt);
+ if (header_len) {
+ offload_mode = WQ_ENET_OFFLOAD_MODE_TSO;
+ mss = tx_pkt->tso_segsz;
}
-
+ }
+ if ((ol_flags & ol_flags_mask) && (header_len == 0)) {
if (ol_flags & PKT_TX_IP_CKSUM)
mss |= ENIC_CALC_IP_CKSUM;
@@ -516,8 +578,14 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
}
}
- wq_enet_desc_enc(&desc_tmp, bus_addr, data_len, mss, 0, 0, eop,
- eop, 0, vlan_tag_insert, vlan_id, 0);
+ if (ol_flags & PKT_TX_VLAN_PKT) {
+ vlan_tag_insert = 1;
+ vlan_id = tx_pkt->vlan_tci;
+ }
+
+ wq_enet_desc_enc(&desc_tmp, bus_addr, data_len, mss, header_len,
+ offload_mode, eop, eop, 0, vlan_tag_insert,
+ vlan_id, 0);
*desc_p = desc_tmp;
buf = &wq->bufs[head_idx];
@@ -537,8 +605,9 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ tx_pkt->data_off);
wq_enet_desc_enc((struct wq_enet_desc *)
&desc_tmp, bus_addr, data_len,
- mss, 0, 0, eop, eop, 0,
- vlan_tag_insert, vlan_id, 0);
+ mss, 0, offload_mode, eop, eop,
+ 0, vlan_tag_insert, vlan_id,
+ 0);
*desc_p = desc_tmp;
buf = &wq->bufs[head_idx];
--
2.10.0
^ permalink raw reply related
* [PATCH] doc: fix a typo in testpmd application guide.
From: Rami Rosen @ 2017-01-07 14:08 UTC (permalink / raw)
To: dev; +Cc: Rami Rosen
This patch fixes a trivial typo in testpmd application guide.
Signed-off-by: Rami Rosen <rami.rosen@intel.com>
---
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index c611dc5..123af7f 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -841,7 +841,7 @@ Where:
* ``mac_ctrl_frame_fwd``: Enable receiving MAC control frames.
-* ``autoneg``: Change the auto-negotiation para mete.
+* ``autoneg``: Change the auto-negotiation parameter.
set pfc_ctrl rx
~~~~~~~~~~~~~~~
--
1.9.1
^ permalink raw reply related
* [PATCH v2 0/8] device abstraction and VMBUS support infrastructure
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Revised version of earlier VMBUS patches. Changes are:
1. don't add dependency on libuuid unless VMBUS is enabled
2. Fix nfp and qat drivers dependendency on pci_drv pointer
in device structure
3. Shutup some checkpatch noise
4. Fix bug in sysfs uuid parsing
Stephen Hemminger (8):
ethdev: increase length ethernet device internal name
i40e: don't refer to eth_dev->pci_dev
vmxnet3: don't refer to eth_dev->pci_dev
cxgbe: don't refer to eth_dev->pci_dev
nfp: don't refer to eth_dev->pci_dev
qat: don't refer to eth_dev->pci_dev
ethdev: break ethernet driver and pci_driver connection
eal: VMBUS infrastructure
app/test/virtual_pmd.c | 22 +-
doc/guides/rel_notes/deprecation.rst | 3 +
drivers/crypto/qat/qat_qp.c | 6 +-
drivers/net/bnx2x/bnx2x_ethdev.c | 16 +-
drivers/net/bnxt/bnxt_ethdev.c | 22 +-
drivers/net/cxgbe/cxgbe_ethdev.c | 8 +-
drivers/net/cxgbe/sge.c | 9 +-
drivers/net/e1000/em_ethdev.c | 10 +-
drivers/net/e1000/igb_ethdev.c | 20 +-
drivers/net/ena/ena_ethdev.c | 8 +-
drivers/net/enic/enic_ethdev.c | 8 +-
drivers/net/fm10k/fm10k_ethdev.c | 10 +-
drivers/net/i40e/i40e_ethdev.c | 10 +-
drivers/net/i40e/i40e_ethdev_vf.c | 10 +-
drivers/net/i40e/i40e_fdir.c | 3 +-
drivers/net/ixgbe/ixgbe_ethdev.c | 20 +-
drivers/net/mlx4/mlx4.c | 8 +-
drivers/net/mlx5/mlx5.c | 8 +-
drivers/net/nfp/nfp_net.c | 12 +-
drivers/net/qede/qede_ethdev.c | 42 +-
drivers/net/szedata2/rte_eth_szedata2.c | 10 +-
drivers/net/thunderx/nicvf_ethdev.c | 8 +-
drivers/net/virtio/virtio_ethdev.c | 10 +-
drivers/net/vmxnet3/vmxnet3_ethdev.c | 10 +-
drivers/net/vmxnet3/vmxnet3_rxtx.c | 5 +-
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_devargs.c | 7 +
lib/librte_eal/common/eal_common_options.c | 38 ++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 6 +
lib/librte_eal/common/eal_private.h | 5 +
lib/librte_eal/common/include/rte_devargs.h | 8 +
lib/librte_eal/common/include/rte_vmbus.h | 249 ++++++++
lib/librte_eal/linuxapp/eal/Makefile | 6 +
lib/librte_eal/linuxapp/eal/eal.c | 13 +
lib/librte_eal/linuxapp/eal/eal_vmbus.c | 911 ++++++++++++++++++++++++++++
lib/librte_ether/rte_ethdev.c | 99 ++-
lib/librte_ether/rte_ethdev.h | 55 +-
mk/rte.app.mk | 1 +
39 files changed, 1557 insertions(+), 142 deletions(-)
create mode 100644 lib/librte_eal/common/include/rte_vmbus.h
create mode 100644 lib/librte_eal/linuxapp/eal/eal_vmbus.c
--
2.11.0
^ permalink raw reply
* [PATCH 1/8] ethdev: increase length ethernet device internal name
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Allow sufficicent space for UUID in string form (36+1).
Needed to use UUID with Hyper-V
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
doc/guides/rel_notes/deprecation.rst | 3 +++
lib/librte_ether/rte_ethdev.h | 6 +++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1438c777..69669e44 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -58,6 +58,9 @@ Deprecation Notices
``port`` field, may be moved or removed as part of this mbuf work. A
``timestamp`` will also be added.
+* ethdev: for 17.02 the size of internal device name will be increased
+ to 40 characters to allow for storing UUID.
+
* The mbuf flags PKT_RX_VLAN_PKT and PKT_RX_QINQ_PKT are deprecated and
are respectively replaced by PKT_RX_VLAN_STRIPPED and
PKT_RX_QINQ_STRIPPED, that are better described. The old flags and
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1c356c1b..b4168830 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1682,7 +1682,11 @@ struct rte_eth_dev_sriov {
};
#define RTE_ETH_DEV_SRIOV(dev) ((dev)->data->sriov)
-#define RTE_ETH_NAME_MAX_LEN (32)
+/*
+ * Internal identifier length
+ * Sufficiently large to allow for UUID or PCI address
+ */
+#define RTE_ETH_NAME_MAX_LEN 40
/**
* @internal
--
2.11.0
^ permalink raw reply related
* [PATCH 2/8] i40e: don't refer to eth_dev->pci_dev
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Later patches remove pci_dev from the ethernet device structure.
Fix the i40e code to just use it's own name when forming zone name.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/i40e/i40e_fdir.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 335bf15c..68a2523c 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -250,8 +250,7 @@ i40e_fdir_setup(struct i40e_pf *pf)
}
/* reserve memory for the fdir programming packet */
- snprintf(z_name, sizeof(z_name), "%s_%s_%d",
- eth_dev->driver->pci_drv.driver.name,
+ snprintf(z_name, sizeof(z_name), "i40e_%s_%d",
I40E_FDIR_MZ_NAME,
eth_dev->data->port_id);
mz = i40e_memzone_reserve(z_name, I40E_FDIR_PKT_LEN, SOCKET_ID_ANY);
--
2.11.0
^ permalink raw reply related
* [PATCH 3/8] vmxnet3: don't refer to eth_dev->pci_dev
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Fix the vmxnet3 code to just use it's own name when forming zone name.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/vmxnet3/vmxnet3_rxtx.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index 36513693..8df4c8ea 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -849,9 +849,8 @@ ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name,
char z_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
- snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- dev->driver->pci_drv.driver.name, ring_name,
- dev->data->port_id, queue_id);
+ snprintf(z_name, sizeof(z_name), "vmxnet3_%s_%d_%d",
+ ring_name, dev->data->port_id, queue_id);
mz = rte_memzone_lookup(z_name);
if (mz)
--
2.11.0
^ permalink raw reply related
* [PATCH 4/8] cxgbe: don't refer to eth_dev->pci_dev
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Later patches remove pci_dev from the ethernet device structure.
Fix the cxgbe code to just use it's own name when forming zone name.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/cxgbe/sge.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 736f08ce..e935dc42 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1644,8 +1644,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
/* Size needs to be multiple of 16, including status entry. */
iq->size = cxgbe_roundup(iq->size, 16);
- snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- eth_dev->driver->pci_drv.driver.name,
+ snprintf(z_name, sizeof(z_name), "cxgbe_%s_%d_%d",
fwevtq ? "fwq_ring" : "rx_ring",
eth_dev->data->port_id, queue_id);
snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
@@ -1697,8 +1696,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
fl->size = s->fl_starve_thres - 1 + 2 * 8;
fl->size = cxgbe_roundup(fl->size, 8);
- snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- eth_dev->driver->pci_drv.driver.name,
+ snprintf(z_name, sizeof(z_name), "cxgbe_%s_%d_%d",
fwevtq ? "fwq_ring" : "fl_ring",
eth_dev->data->port_id, queue_id);
snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
@@ -1893,8 +1891,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
/* Add status entries */
nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
- snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- eth_dev->driver->pci_drv.driver.name, "tx_ring",
+ snprintf(z_name, sizeof(z_name), "cxgbe_%d_%d",
eth_dev->data->port_id, queue_id);
snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
--
2.11.0
^ permalink raw reply related
* [PATCH 5/8] nfp: don't refer to eth_dev->pci_dev
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Later patches remove pci_dev from the ethernet device structure.
Fix the nfp code to just use it's own name when forming zone name.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/net/nfp/nfp_net.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index e85315f1..970b5c84 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -213,8 +213,7 @@ ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name,
char z_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
- snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- dev->driver->pci_drv.driver.name,
+ snprintf(z_name, sizeof(z_name), "nfp_%s_%u_%u",
ring_name, dev->data->port_id, queue_id);
mz = rte_memzone_lookup(z_name);
@@ -1009,7 +1008,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->pci_dev = RTE_DEV_TO_PCI(dev->device);
- 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;
--
2.11.0
^ permalink raw reply related
* [PATCH 6/8] qat: don't refer to eth_dev->pci_dev
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Later patches remove pci_dev from the ethernet device structure.
Fix the quick assist code to just use it's own name when forming zone name.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
drivers/crypto/qat/qat_qp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 2e7188bd..fe76e04a 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -299,9 +299,9 @@ qat_queue_create(struct rte_cryptodev *dev, struct qat_queue *queue,
/*
* Allocate a memzone for the queue - create a unique name.
*/
- snprintf(queue->memz_name, sizeof(queue->memz_name), "%s_%s_%d_%d_%d",
- dev->driver->pci_drv.driver.name, "qp_mem", dev->data->dev_id,
- queue->hw_bundle_number, queue->hw_queue_number);
+ snprintf(queue->memz_name, sizeof(queue->memz_name),
+ "qat_qp_mem_%d_%u_%u", dev->data->dev_id,
+ queue->hw_bundle_number, queue->hw_queue_number);
qp_mz = queue_dma_zone_reserve(queue->memz_name, queue_size_bytes,
socket_id);
if (qp_mz == NULL) {
--
2.11.0
^ permalink raw reply related
* [PATCH 7/8] ethdev: break ethernet driver and pci_driver connection
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
There are multiple buses and device types now. Therefore it no longer
makes sense that PCI driver information is part of the Ethernet driver
structure.
This patch removes pci_driver from eth_driver and introduces a
new combined structure for use in all existing PMD's. The rationale
is that although all existing PCI drivers are Ethernet drivers,
it make sense that future projects may want to support PCI devices
that are not Ethernet.
It also removes the requirement that driver is first element in
PCI driver structure.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
app/test/virtual_pmd.c | 22 ++++++++---------
drivers/net/bnx2x/bnx2x_ethdev.c | 16 ++++++++-----
drivers/net/bnxt/bnxt_ethdev.c | 22 +++++++++--------
drivers/net/cxgbe/cxgbe_ethdev.c | 8 ++++---
drivers/net/e1000/em_ethdev.c | 10 ++++----
drivers/net/e1000/igb_ethdev.c | 20 +++++++++-------
drivers/net/ena/ena_ethdev.c | 8 ++++---
drivers/net/enic/enic_ethdev.c | 8 ++++---
drivers/net/fm10k/fm10k_ethdev.c | 10 ++++----
drivers/net/i40e/i40e_ethdev.c | 10 ++++----
drivers/net/i40e/i40e_ethdev_vf.c | 10 ++++----
drivers/net/ixgbe/ixgbe_ethdev.c | 20 +++++++++-------
drivers/net/mlx4/mlx4.c | 8 ++++---
drivers/net/mlx5/mlx5.c | 8 ++++---
drivers/net/nfp/nfp_net.c | 8 ++++---
drivers/net/qede/qede_ethdev.c | 42 +++++++++++++++++----------------
drivers/net/szedata2/rte_eth_szedata2.c | 10 ++++----
drivers/net/thunderx/nicvf_ethdev.c | 8 ++++---
drivers/net/virtio/virtio_ethdev.c | 10 ++++----
drivers/net/vmxnet3/vmxnet3_ethdev.c | 10 ++++----
lib/librte_ether/rte_ethdev.c | 9 +++----
lib/librte_ether/rte_ethdev.h | 18 +++++++++-----
22 files changed, 172 insertions(+), 123 deletions(-)
diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index 6e4dcd8f..e7f56527 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -533,7 +533,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
struct rte_pci_device *pci_dev = NULL;
struct rte_eth_dev *eth_dev = NULL;
struct eth_driver *eth_drv = NULL;
- struct rte_pci_driver *pci_drv = NULL;
+ struct rte_pci_eth_driver *pci_eth_drv = NULL;
struct rte_pci_id *id_table = NULL;
struct virtual_ethdev_private *dev_private = NULL;
char name_buf[RTE_RING_NAMESIZE];
@@ -554,8 +554,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
if (eth_drv == NULL)
goto err;
- pci_drv = rte_zmalloc_socket(name, sizeof(*pci_drv), 0, socket_id);
- if (pci_drv == NULL)
+ pci_eth_drv = rte_zmalloc_socket(name, sizeof(*pci_eth_drv), 0, socket_id);
+ if (pci_eth_drv == NULL)
goto err;
id_table = rte_zmalloc_socket(name, sizeof(*id_table), 0, socket_id);
@@ -585,17 +585,15 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
goto err;
pci_dev->device.numa_node = socket_id;
- pci_drv->driver.name = virtual_ethdev_driver_name;
- pci_drv->id_table = id_table;
+ pci_eth_drv->pci_drv.driver.name = virtual_ethdev_driver_name;
+ pci_eth_drv->pci_drv.id_table = id_table;
if (isr_support)
- pci_drv->drv_flags |= RTE_PCI_DRV_INTR_LSC;
+ pci_eth_drv->pci_drv.drv_flags |= RTE_PCI_DRV_INTR_LSC;
else
- pci_drv->drv_flags &= ~RTE_PCI_DRV_INTR_LSC;
+ pci_eth_drv->pci_drv.drv_flags &= ~RTE_PCI_DRV_INTR_LSC;
-
- eth_drv->pci_drv = (struct rte_pci_driver)(*pci_drv);
- eth_dev->driver = eth_drv;
+ eth_dev->driver = &pci_eth_drv->eth_drv;
eth_dev->data->nb_rx_queues = (uint16_t)1;
eth_dev->data->nb_tx_queues = (uint16_t)1;
@@ -622,7 +620,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
dev_private->dev_ops = virtual_ethdev_default_dev_ops;
eth_dev->dev_ops = &dev_private->dev_ops;
- pci_dev->device.driver = ð_drv->pci_drv.driver;
+ pci_dev->device.driver = &pci_eth_drv->pci_drv.driver;
eth_dev->device = &pci_dev->device;
eth_dev->rx_pkt_burst = virtual_ethdev_rx_burst_success;
@@ -632,7 +630,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
err:
rte_free(pci_dev);
- rte_free(pci_drv);
+ rte_free(pci_eth_drv);
rte_free(eth_drv);
rte_free(id_table);
rte_free(dev_private);
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 7140118f..ef704d72 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -618,29 +618,33 @@ eth_bnx2xvf_dev_init(struct rte_eth_dev *eth_dev)
return bnx2x_common_dev_init(eth_dev, 1);
}
-static struct eth_driver rte_bnx2x_pmd = {
+static struct rte_pci_eth_driver rte_bnx2x_pmd = {
.pci_drv = {
.id_table = pci_id_bnx2x_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_bnx2x_dev_init,
- .dev_private_size = sizeof(struct bnx2x_softc),
+ eth_drv = {
+ .eth_dev_init = eth_bnx2x_dev_init,
+ .dev_private_size = sizeof(struct bnx2x_softc),
+ },
};
/*
* virtual function driver struct
*/
-static struct eth_driver rte_bnx2xvf_pmd = {
+static struct rte_pci_eth_driver rte_bnx2xvf_pmd = {
.pci_drv = {
.id_table = pci_id_bnx2xvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_bnx2xvf_dev_init,
- .dev_private_size = sizeof(struct bnx2x_softc),
+ eth_drv = {
+ .eth_dev_init = eth_bnx2xvf_dev_init,
+ .dev_private_size = sizeof(struct bnx2x_softc),
+ },
};
RTE_PMD_REGISTER_PCI(net_bnx2x, rte_bnx2x_pmd.pci_drv);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7518b6b7..9017825b 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1164,17 +1164,19 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
return rc;
}
-static struct eth_driver bnxt_rte_pmd = {
+static struct rte_pci_eth_driver bnxt_rte_pmd = {
.pci_drv = {
- .id_table = bnxt_pci_id_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
- RTE_PCI_DRV_DETACHABLE | RTE_PCI_DRV_INTR_LSC,
- .probe = rte_eth_dev_pci_probe,
- .remove = rte_eth_dev_pci_remove
- },
- .eth_dev_init = bnxt_dev_init,
- .eth_dev_uninit = bnxt_dev_uninit,
- .dev_private_size = sizeof(struct bnxt),
+ .id_table = bnxt_pci_id_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
+ RTE_PCI_DRV_DETACHABLE | RTE_PCI_DRV_INTR_LSC,
+ .probe = rte_eth_dev_pci_probe,
+ .remove = rte_eth_dev_pci_remove
+ },
+ .eth_drv = {
+ .eth_dev_init = bnxt_dev_init,
+ .eth_dev_uninit = bnxt_dev_uninit,
+ .dev_private_size = sizeof(struct bnxt),
+ },
};
RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd.pci_drv);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 64345e37..ccf93904 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1039,15 +1039,17 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
return err;
}
-static struct eth_driver rte_cxgbe_pmd = {
+static struct rte_pci_eth_driver rte_cxgbe_pmd = {
.pci_drv = {
.id_table = cxgb4_pci_tbl,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_cxgbe_dev_init,
- .dev_private_size = sizeof(struct port_info),
+ .eth_drv = {
+ .eth_dev_init = eth_cxgbe_dev_init,
+ .dev_private_size = sizeof(struct port_info),
+ },
};
RTE_PMD_REGISTER_PCI(net_cxgbe, rte_cxgbe_pmd.pci_drv);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 5f6e66dd..5b87d729 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -389,7 +389,7 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static struct eth_driver rte_em_pmd = {
+static struct rte_pci_eth_driver rte_em_pmd = {
.pci_drv = {
.id_table = pci_id_em_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -397,9 +397,11 @@ static struct eth_driver rte_em_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_em_dev_init,
- .eth_dev_uninit = eth_em_dev_uninit,
- .dev_private_size = sizeof(struct e1000_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_em_dev_init,
+ .eth_dev_uninit = eth_em_dev_uninit,
+ .dev_private_size = sizeof(struct e1000_adapter),
+ },
};
static int
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2bb57f54..4a2d3b3f 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1082,7 +1082,7 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static struct eth_driver rte_igb_pmd = {
+static struct rte_pci_eth_driver rte_igb_pmd = {
.pci_drv = {
.id_table = pci_id_igb_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -1090,24 +1090,28 @@ static struct eth_driver rte_igb_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_igb_dev_init,
- .eth_dev_uninit = eth_igb_dev_uninit,
- .dev_private_size = sizeof(struct e1000_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_igb_dev_init,
+ .eth_dev_uninit = eth_igb_dev_uninit,
+ .dev_private_size = sizeof(struct e1000_adapter),
+ },
};
/*
* virtual function driver struct
*/
-static struct eth_driver rte_igbvf_pmd = {
+static struct rte_pci_eth_driver rte_igbvf_pmd = {
.pci_drv = {
.id_table = pci_id_igbvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_igbvf_dev_init,
- .eth_dev_uninit = eth_igbvf_dev_uninit,
- .dev_private_size = sizeof(struct e1000_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_igbvf_dev_init,
+ .eth_dev_uninit = eth_igbvf_dev_uninit,
+ .dev_private_size = sizeof(struct e1000_adapter),
+ },
};
static void
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index e99bf299..d6406fa1 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1756,15 +1756,17 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
return sent_idx;
}
-static struct eth_driver rte_ena_pmd = {
+static struct rte_pci_eth_driver rte_ena_pmd = {
.pci_drv = {
.id_table = pci_id_ena_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_ena_dev_init,
- .dev_private_size = sizeof(struct ena_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_ena_dev_init,
+ .dev_private_size = sizeof(struct ena_adapter),
+ },
};
RTE_PMD_REGISTER_PCI(net_ena, rte_ena_pmd.pci_drv);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index e5ceb98e..b47975d1 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -633,15 +633,17 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
return enic_probe(enic);
}
-static struct eth_driver rte_enic_pmd = {
+static struct rte_pci_eth_driver rte_enic_pmd = {
.pci_drv = {
.id_table = pci_id_enic_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_enicpmd_dev_init,
- .dev_private_size = sizeof(struct enic),
+ .eth_drv = {
+ .eth_dev_init = eth_enicpmd_dev_init,
+ .dev_private_size = sizeof(struct enic),
+ },
};
RTE_PMD_REGISTER_PCI(net_enic, rte_enic_pmd.pci_drv);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index d8353e9d..4dea1fd6 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -3077,7 +3077,7 @@ static const struct rte_pci_id pci_id_fm10k_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
-static struct eth_driver rte_pmd_fm10k = {
+static struct rte_pci_eth_driver rte_pmd_fm10k = {
.pci_drv = {
.id_table = pci_id_fm10k_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -3085,9 +3085,11 @@ static struct eth_driver rte_pmd_fm10k = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_fm10k_dev_init,
- .eth_dev_uninit = eth_fm10k_dev_uninit,
- .dev_private_size = sizeof(struct fm10k_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_fm10k_dev_init,
+ .eth_dev_uninit = eth_fm10k_dev_uninit,
+ .dev_private_size = sizeof(struct fm10k_adapter),
+ },
};
RTE_PMD_REGISTER_PCI(net_fm10k, rte_pmd_fm10k.pci_drv);
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 0eb4c990..8b4c6079 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -668,7 +668,7 @@ static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = {
#define I40E_NB_TXQ_PRIO_XSTATS (sizeof(rte_i40e_txq_prio_strings) / \
sizeof(rte_i40e_txq_prio_strings[0]))
-static struct eth_driver rte_i40e_pmd = {
+static struct rte_pci_eth_driver rte_i40e_pmd = {
.pci_drv = {
.id_table = pci_id_i40e_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -676,9 +676,11 @@ static struct eth_driver rte_i40e_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_i40e_dev_init,
- .eth_dev_uninit = eth_i40e_dev_uninit,
- .dev_private_size = sizeof(struct i40e_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_i40e_dev_init,
+ .eth_dev_uninit = eth_i40e_dev_uninit,
+ .dev_private_size = sizeof(struct i40e_adapter),
+ },
};
static inline int
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 0dc0af52..6dbcc88c 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1526,16 +1526,18 @@ i40evf_dev_uninit(struct rte_eth_dev *eth_dev)
/*
* virtual function driver struct
*/
-static struct eth_driver rte_i40evf_pmd = {
+static struct rte_pci_eth_driver rte_i40evf_pmd = {
.pci_drv = {
.id_table = pci_id_i40evf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = i40evf_dev_init,
- .eth_dev_uninit = i40evf_dev_uninit,
- .dev_private_size = sizeof(struct i40e_adapter),
+ .eth_drv = {
+ .eth_dev_init = i40evf_dev_init,
+ .eth_dev_uninit = i40evf_dev_uninit,
+ .dev_private_size = sizeof(struct i40e_adapter),
+ },
};
RTE_PMD_REGISTER_PCI(net_i40e_vf, rte_i40evf_pmd.pci_drv);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 060772d4..6fdf227e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1563,7 +1563,7 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static struct eth_driver rte_ixgbe_pmd = {
+static struct rte_pci_eth_driver rte_ixgbe_pmd = {
.pci_drv = {
.id_table = pci_id_ixgbe_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -1571,24 +1571,28 @@ static struct eth_driver rte_ixgbe_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_ixgbe_dev_init,
- .eth_dev_uninit = eth_ixgbe_dev_uninit,
- .dev_private_size = sizeof(struct ixgbe_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_ixgbe_dev_init,
+ .eth_dev_uninit = eth_ixgbe_dev_uninit,
+ .dev_private_size = sizeof(struct ixgbe_adapter),
+ },
};
/*
* virtual function driver struct
*/
-static struct eth_driver rte_ixgbevf_pmd = {
+static struct rte_pci_eth_driver rte_ixgbevf_pmd = {
.pci_drv = {
.id_table = pci_id_ixgbevf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_ixgbevf_dev_init,
- .eth_dev_uninit = eth_ixgbevf_dev_uninit,
- .dev_private_size = sizeof(struct ixgbe_adapter),
+ .eth_drv = {
+ .eth_dev_init = eth_ixgbevf_dev_init,
+ .eth_dev_uninit = eth_ixgbevf_dev_uninit,
+ .dev_private_size = sizeof(struct ixgbe_adapter),
+ },
};
static int
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index eb06f56a..7b184019 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5524,7 +5524,7 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev)
}
}
-static struct eth_driver mlx4_driver;
+static struct rte_pci_eth_driver mlx4_driver;
/**
* DPDK callback to register a PCI device.
@@ -5903,7 +5903,7 @@ static const struct rte_pci_id mlx4_pci_id_map[] = {
}
};
-static struct eth_driver mlx4_driver = {
+static struct rte_pci_eth_driver mlx4_driver = {
.pci_drv = {
.driver = {
.name = MLX4_DRIVER_NAME
@@ -5912,7 +5912,9 @@ static struct eth_driver mlx4_driver = {
.probe = mlx4_pci_probe,
.drv_flags = RTE_PCI_DRV_INTR_LSC,
},
- .dev_private_size = sizeof(struct priv)
+ .eth_drv = {
+ .dev_private_size = sizeof(struct priv),
+ },
};
/**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b97b6d16..efc0430c 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -338,7 +338,7 @@ mlx5_args(struct priv *priv, struct rte_devargs *devargs)
return 0;
}
-static struct eth_driver mlx5_driver;
+static struct rte_pci_eth_driver mlx5_driver;
/**
* DPDK callback to register a PCI device.
@@ -723,7 +723,7 @@ static const struct rte_pci_id mlx5_pci_id_map[] = {
}
};
-static struct eth_driver mlx5_driver = {
+static struct rte_pci_eth_driver mlx5_driver = {
.pci_drv = {
.driver = {
.name = MLX5_DRIVER_NAME
@@ -732,7 +732,9 @@ static struct eth_driver mlx5_driver = {
.probe = mlx5_pci_probe,
.drv_flags = RTE_PCI_DRV_INTR_LSC,
},
- .dev_private_size = sizeof(struct priv)
+ .eth_drv = {
+ .dev_private_size = sizeof(struct priv),
+ },
};
/**
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 970b5c84..f5c6634f 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -2470,7 +2470,7 @@ static struct rte_pci_id pci_id_nfp_net_map[] = {
},
};
-static struct eth_driver rte_nfp_net_pmd = {
+static struct rte_pci_eth_driver rte_nfp_net_pmd = {
.pci_drv = {
.id_table = pci_id_nfp_net_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
@@ -2478,8 +2478,10 @@ static struct eth_driver rte_nfp_net_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = nfp_net_init,
- .dev_private_size = sizeof(struct nfp_net_adapter),
+ .eth_drv = {
+ .eth_dev_init = nfp_net_init,
+ .dev_private_size = sizeof(struct nfp_net_adapter),
+ },
};
RTE_PMD_REGISTER_PCI(net_nfp, rte_nfp_net_pmd.pci_drv);
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index edc5b43b..13d76a6d 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1643,30 +1643,32 @@ static struct rte_pci_id pci_id_qede_map[] = {
{.vendor_id = 0,}
};
-static struct eth_driver rte_qedevf_pmd = {
+static struct rte_pci_eth_driver rte_qedevf_pmd = {
.pci_drv = {
- .id_table = pci_id_qedevf_map,
- .drv_flags =
- RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
- .probe = rte_eth_dev_pci_probe,
- .remove = rte_eth_dev_pci_remove,
- },
- .eth_dev_init = qedevf_eth_dev_init,
- .eth_dev_uninit = qedevf_eth_dev_uninit,
- .dev_private_size = sizeof(struct qede_dev),
+ .id_table = pci_id_qedevf_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+ .probe = rte_eth_dev_pci_probe,
+ .remove = rte_eth_dev_pci_remove,
+ },
+ .eth_drv = {
+ .eth_dev_init = qedevf_eth_dev_init,
+ .eth_dev_uninit = qedevf_eth_dev_uninit,
+ .dev_private_size = sizeof(struct qede_dev),
+ },
};
-static struct eth_driver rte_qede_pmd = {
+static struct rte_pci_eth_driver rte_qede_pmd = {
.pci_drv = {
- .id_table = pci_id_qede_map,
- .drv_flags =
- RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
- .probe = rte_eth_dev_pci_probe,
- .remove = rte_eth_dev_pci_remove,
- },
- .eth_dev_init = qede_eth_dev_init,
- .eth_dev_uninit = qede_eth_dev_uninit,
- .dev_private_size = sizeof(struct qede_dev),
+ .id_table = pci_id_qede_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+ .probe = rte_eth_dev_pci_probe,
+ .remove = rte_eth_dev_pci_remove,
+ },
+ .eth_drv = {
+ .eth_dev_init = qede_eth_dev_init,
+ .eth_dev_uninit = qede_eth_dev_uninit,
+ .dev_private_size = sizeof(struct qede_dev),
+ },
};
RTE_PMD_REGISTER_PCI(net_qede, rte_qede_pmd.pci_drv);
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index fe7a6b3b..b9054671 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1587,15 +1587,17 @@ static const struct rte_pci_id rte_szedata2_pci_id_table[] = {
}
};
-static struct eth_driver szedata2_eth_driver = {
+static struct rte_pci_eth_driver szedata2_eth_driver = {
.pci_drv = {
.id_table = rte_szedata2_pci_id_table,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = rte_szedata2_eth_dev_init,
- .eth_dev_uninit = rte_szedata2_eth_dev_uninit,
- .dev_private_size = sizeof(struct pmd_internals),
+ .eth_drv = {
+ .eth_dev_init = rte_szedata2_eth_dev_init,
+ .eth_dev_uninit = rte_szedata2_eth_dev_uninit,
+ .dev_private_size = sizeof(struct pmd_internals),
+ },
};
RTE_PMD_REGISTER_PCI(RTE_SZEDATA2_DRIVER_NAME, szedata2_eth_driver.pci_drv);
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 10603197..f13fad90 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -2111,15 +2111,17 @@ static const struct rte_pci_id pci_id_nicvf_map[] = {
},
};
-static struct eth_driver rte_nicvf_pmd = {
+static struct rte_pci_eth_driver rte_nicvf_pmd = {
.pci_drv = {
.id_table = pci_id_nicvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = nicvf_eth_dev_init,
- .dev_private_size = sizeof(struct nicvf),
+ .eth_drv = {
+ .eth_dev_init = nicvf_eth_dev_init,
+ .dev_private_size = sizeof(struct nicvf),
+ },
};
RTE_PMD_REGISTER_PCI(net_thunderx, rte_nicvf_pmd.pci_drv);
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 54ea7d77..e6f241ad 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1377,7 +1377,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static struct eth_driver rte_virtio_pmd = {
+static struct rte_pci_eth_driver rte_virtio_pmd = {
.pci_drv = {
.driver = {
.name = "net_virtio",
@@ -1387,9 +1387,11 @@ static struct eth_driver rte_virtio_pmd = {
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_virtio_dev_init,
- .eth_dev_uninit = eth_virtio_dev_uninit,
- .dev_private_size = sizeof(struct virtio_hw),
+ .eth_drv = {
+ .eth_dev_init = eth_virtio_dev_init,
+ .eth_dev_uninit = eth_virtio_dev_uninit,
+ .dev_private_size = sizeof(struct virtio_hw),
+ },
};
RTE_INIT(rte_virtio_pmd_init);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 54533ca5..cb9221e6 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -337,16 +337,18 @@ eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static struct eth_driver rte_vmxnet3_pmd = {
+static struct rte_pci_eth_driver rte_vmxnet3_pmd = {
.pci_drv = {
.id_table = pci_id_vmxnet3_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
- .eth_dev_init = eth_vmxnet3_dev_init,
- .eth_dev_uninit = eth_vmxnet3_dev_uninit,
- .dev_private_size = sizeof(struct vmxnet3_hw),
+ .eth_drv = {
+ .eth_dev_init = eth_vmxnet3_dev_init,
+ .eth_dev_uninit = eth_vmxnet3_dev_uninit,
+ .dev_private_size = sizeof(struct vmxnet3_hw),
+ },
};
static int
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 9dea1f15..7c212096 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -239,13 +239,14 @@ int
rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
struct rte_pci_device *pci_dev)
{
- struct eth_driver *eth_drv;
+ const struct rte_pci_eth_driver *pci_eth_drv;
+ const struct eth_driver *eth_drv;
struct rte_eth_dev *eth_dev;
char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-
int diag;
- eth_drv = (struct eth_driver *)pci_drv;
+ pci_eth_drv = container_of(pci_drv, struct rte_pci_eth_driver, pci_drv);
+ eth_drv = &pci_eth_drv->eth_drv;
rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
sizeof(ethdev_name));
@@ -263,7 +264,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
}
eth_dev->device = &pci_dev->device;
eth_dev->intr_handle = &pci_dev->intr_handle;
- eth_dev->driver = eth_drv;
+ eth_dev->driver = &pci_eth_drv->eth_drv;
/* Invoke PMD device initialization function */
diag = (*eth_drv->eth_dev_init)(eth_dev);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index b4168830..1a62a322 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1884,25 +1884,31 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
* @internal
* The structure associated with a PMD Ethernet driver.
*
- * Each Ethernet driver acts as a PCI driver and is represented by a generic
+ * Each Ethernet driver acts is represented by a generic
* *eth_driver* structure that holds:
*
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - The *eth_dev_init* function invoked for each matching device.
*
- * - The *eth_dev_init* function invoked for each matching PCI device.
- *
- * - The *eth_dev_uninit* function invoked for each matching PCI device.
+ * - The *eth_dev_uninit* function invoked for each matching device.
*
* - The size of the private data to allocate for each matching device.
*/
struct eth_driver {
- struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
eth_dev_init_t eth_dev_init; /**< Device init function. */
eth_dev_uninit_t eth_dev_uninit; /**< Device uninit function. */
unsigned int dev_private_size; /**< Size of device private data. */
};
/**
+ * @internal
+ * The structure associated with a PMD PCI Ethernet driver.
+ */
+struct rte_pci_eth_driver {
+ struct rte_pci_driver pci_drv; /**< Underlying PCI driver. */
+ struct eth_driver eth_drv; /**< Ethernet driver. */
+};
+
+/**
* Convert a numerical speed in Mbps to a bitmap flag that can be used in
* the bitmap link_speeds of the struct rte_eth_conf
*
--
2.11.0
^ permalink raw reply related
* [PATCH 8/8] eal: VMBUS infrastructure
From: Stephen Hemminger @ 2017-01-07 18:17 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20170107181756.1944-1-sthemmin@microsoft.com>
Add support for VMBUS on Hyper-V/Azure. VMBUS is similar to PCI
but has different addressing and internal API's.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_devargs.c | 7 +
lib/librte_eal/common/eal_common_options.c | 38 ++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 6 +
lib/librte_eal/common/eal_private.h | 5 +
lib/librte_eal/common/include/rte_devargs.h | 8 +
lib/librte_eal/common/include/rte_vmbus.h | 249 ++++++++
lib/librte_eal/linuxapp/eal/Makefile | 6 +
lib/librte_eal/linuxapp/eal/eal.c | 13 +
lib/librte_eal/linuxapp/eal/eal_vmbus.c | 911 ++++++++++++++++++++++++++++
lib/librte_ether/rte_ethdev.c | 90 +++
lib/librte_ether/rte_ethdev.h | 31 +
mk/rte.app.mk | 1 +
14 files changed, 1367 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_eal/common/include/rte_vmbus.h
create mode 100644 lib/librte_eal/linuxapp/eal/eal_vmbus.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 09a3d3af..ceb77bed 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h rte_vmbus.h
INC += rte_per_lcore.h rte_random.h
INC += rte_tailq.h rte_interrupts.h rte_alarm.h
INC += rte_string_fns.h rte_version.h
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717b..934ca840 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -113,6 +113,13 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
goto fail;
break;
+ case RTE_DEVTYPE_WHITELISTED_VMBUS:
+ case RTE_DEVTYPE_BLACKLISTED_VMBUS:
+#ifdef RTE_LIBRTE_HV_PMD
+ if (uuid_parse(buf, devargs->uuid) == 0)
+ break;
+#endif
+ goto fail;
}
free(buf);
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index f36bc556..1a2b418c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -95,6 +95,11 @@ eal_long_options[] = {
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
{OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
+#ifdef RTE_LIBRTE_HV_PMD
+ {OPT_NO_VMBUS, 0, NULL, OPT_NO_VMBUS_NUM },
+ {OPT_VMBUS_BLACKLIST, 1, NULL, OPT_VMBUS_BLACKLIST_NUM },
+ {OPT_VMBUS_WHITELIST, 1, NULL, OPT_VMBUS_WHITELIST_NUM },
+#endif
{0, 0, NULL, 0 }
};
@@ -858,6 +863,21 @@ eal_parse_common_option(int opt, const char *optarg,
conf->no_pci = 1;
break;
+#ifdef RTE_LIBRTE_HV_PMD
+ case OPT_NO_VMBUS_NUM:
+ conf->no_vmbus = 1;
+ break;
+ case OPT_VMBUS_BLACKLIST_NUM:
+ if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_VMBUS,
+ optarg) < 0)
+ return -1;
+ break;
+ case OPT_VMBUS_WHITELIST_NUM:
+ if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_VMBUS,
+ optarg) < 0)
+ return -1;
+ break;
+#endif
case OPT_NO_HPET_NUM:
conf->no_hpet = 1;
break;
@@ -1017,6 +1037,14 @@ eal_check_common_options(struct internal_config *internal_cfg)
return -1;
}
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_VMBUS) != 0 &&
+ rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_VMBUS) != 0) {
+ RTE_LOG(ERR, EAL, "Options vmbus blacklist and whitelist "
+ "cannot be used at the same time\n");
+ return -1;
+ }
+#endif
return 0;
}
@@ -1066,5 +1094,15 @@ eal_common_usage(void)
" --"OPT_NO_PCI" Disable PCI\n"
" --"OPT_NO_HPET" Disable HPET\n"
" --"OPT_NO_SHCONF" No shared config (mmap'd files)\n"
+#ifdef RTE_LIBRTE_HV_PMD
+ " --"OPT_NO_VMBUS" Disable VMBUS\n"
+ " --"OPT_VMBUS_BLACKLIST" Add a VMBUS device to black list.\n"
+ " Prevent EAL from using this PCI device. The argument\n"
+ " format is device UUID.\n"
+ " --"OPT_VMBUS_WHITELIST" Add a VMBUS device to white list.\n"
+ " Only use the specified VMBUS devices. The argument format\n"
+ " is device UUID This option can be present\n"
+ " several times (once per device).\n"
+#endif
"\n", RTE_MAX_LCORE);
}
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367eb..4b6af937 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
unsigned hugepage_unlink; /**< true to unlink backing files */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
+ volatile unsigned no_vmbus; /**< true to disable VMBUS */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62e..156727e7 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -83,6 +83,12 @@ enum {
OPT_VMWARE_TSC_MAP_NUM,
#define OPT_XEN_DOM0 "xen-dom0"
OPT_XEN_DOM0_NUM,
+#define OPT_NO_VMBUS "no-vmbus"
+ OPT_NO_VMBUS_NUM,
+#define OPT_VMBUS_BLACKLIST "vmbus-blacklist"
+ OPT_VMBUS_BLACKLIST_NUM,
+#define OPT_VMBUS_WHITELIST "vmbus-whitelist"
+ OPT_VMBUS_WHITELIST_NUM,
OPT_LONG_MAX_NUM
};
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6b..c856c63e 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -210,6 +210,11 @@ int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
struct mapped_pci_resource *uio_res, int map_idx);
/**
+ * VMBUS related functions and structures
+ */
+int rte_eal_vmbus_init(void);
+
+/**
* Init tail queues for non-EAL library structures. This is to allow
* the rings, mempools, etc. lists to be shared among multiple processes
*
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1c..c079d289 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,9 @@ extern "C" {
#include <stdio.h>
#include <sys/queue.h>
#include <rte_pci.h>
+#ifdef RTE_LIBRTE_HV_PMD
+#include <uuid/uuid.h>
+#endif
/**
* Type of generic device
@@ -59,6 +62,8 @@ enum rte_devtype {
RTE_DEVTYPE_WHITELISTED_PCI,
RTE_DEVTYPE_BLACKLISTED_PCI,
RTE_DEVTYPE_VIRTUAL,
+ RTE_DEVTYPE_WHITELISTED_VMBUS,
+ RTE_DEVTYPE_BLACKLISTED_VMBUS,
};
/**
@@ -88,6 +93,9 @@ struct rte_devargs {
/** Driver name. */
char drv_name[32];
} virt;
+#ifdef RTE_LIBRTE_HV_PMD
+ uuid_t uuid;
+#endif
};
/** Arguments string as given by user or "" for no argument. */
char *args;
diff --git a/lib/librte_eal/common/include/rte_vmbus.h b/lib/librte_eal/common/include/rte_vmbus.h
new file mode 100644
index 00000000..f96d753e
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vmbus.h
@@ -0,0 +1,249 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013-2016 Brocade Communications Systems, Inc.
+ * Copyright(c) 2016 Microsoft Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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 _RTE_VMBUS_H_
+#define _RTE_VMBUS_H_
+
+/**
+ * @file
+ *
+ * RTE VMBUS Interface
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include <uuid/uuid.h>
+#include <sys/queue.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <rte_debug.h>
+#include <rte_interrupts.h>
+#include <rte_dev.h>
+
+TAILQ_HEAD(vmbus_device_list, rte_vmbus_device);
+TAILQ_HEAD(vmbus_driver_list, rte_vmbus_driver);
+
+extern struct vmbus_driver_list vmbus_driver_list;
+extern struct vmbus_device_list vmbus_device_list;
+
+/** Pathname of VMBUS devices directory. */
+#define SYSFS_VMBUS_DEVICES "/sys/bus/vmbus/devices"
+
+#define UUID_BUF_SZ (36 + 1)
+
+
+/** Maximum number of VMBUS resources. */
+#define VMBUS_MAX_RESOURCE 7
+
+/**
+ * A structure describing a VMBUS device.
+ */
+struct rte_vmbus_device {
+ TAILQ_ENTRY(rte_vmbus_device) next; /**< Next probed VMBUS device. */
+ struct rte_device device; /**< Inherit core device */
+ uuid_t device_id; /**< VMBUS device id */
+ uuid_t class_id; /**< VMBUS device type */
+ uint32_t relid; /**< VMBUS id for notification */
+ uint8_t monitor_id;
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
+ const struct rte_vmbus_driver *driver; /**< Associated driver */
+
+ struct rte_mem_resource mem_resource[VMBUS_MAX_RESOURCE];
+ /**< VMBUS Memory Resource */
+ char sysfs_name[]; /**< Name in sysfs bus directory */
+};
+
+struct rte_vmbus_driver;
+
+/**
+ * Initialisation function for the driver called during VMBUS probing.
+ */
+typedef int (vmbus_probe_t)(struct rte_vmbus_driver *,
+ struct rte_vmbus_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (vmbus_remove_t)(struct rte_vmbus_device *);
+
+/**
+ * A structure describing a VMBUS driver.
+ */
+struct rte_vmbus_driver {
+ TAILQ_ENTRY(rte_vmbus_driver) next; /**< Next in list. */
+ struct rte_driver driver;
+ vmbus_probe_t *probe; /**< Device Probe function. */
+ vmbus_remove_t *remove; /**< Device Remove function. */
+
+ const uuid_t *id_table; /**< ID table. */
+};
+
+struct vmbus_map {
+ void *addr;
+ char *path;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t phaddr;
+};
+
+/*
+ * For multi-process we need to reproduce all vmbus mappings in secondary
+ * processes, so save them in a tailq.
+ */
+struct mapped_vmbus_resource {
+ TAILQ_ENTRY(mapped_vmbus_resource) next;
+
+ uuid_t uuid;
+ char path[PATH_MAX];
+ int nb_maps;
+ struct vmbus_map maps[VMBUS_MAX_RESOURCE];
+};
+
+TAILQ_HEAD(mapped_vmbus_res_list, mapped_vmbus_resource);
+
+/**
+ * Scan the content of the VMBUS bus, and the devices in the devices list
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_eal_vmbus_scan(void);
+
+/**
+ * Probe the VMBUS bus for registered drivers.
+ *
+ * Scan the content of the VMBUS bus, and call the probe() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int rte_eal_vmbus_probe(void);
+
+/**
+ * Map the VMBUS device resources in user space virtual memory address
+ *
+ * @param dev
+ * A pointer to a rte_vmbus_device structure describing the device
+ * to use
+ *
+ * @return
+ * 0 on success, negative on error and positive if no driver
+ * is found for the device.
+ */
+int rte_eal_vmbus_map_device(struct rte_vmbus_device *dev);
+
+/**
+ * Unmap this device
+ *
+ * @param dev
+ * A pointer to a rte_vmbus_device structure describing the device
+ * to use
+ */
+void rte_eal_vmbus_unmap_device(struct rte_vmbus_device *dev);
+
+/**
+ * Probe the single VMBUS device.
+ *
+ * Scan the content of the VMBUS bus, and find the vmbus device
+ * specified by device uuid, then call the probe() function for
+ * registered driver that has a matching entry in its id_table for
+ * discovered device.
+ *
+ * @param id
+ * The VMBUS device uuid.
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int rte_eal_vmbus_probe_one(uuid_t id);
+
+/**
+ * Close the single VMBUS device.
+ *
+ * Scan the content of the VMBUS bus, and find the vmbus device id,
+ * then call the remove() function for registered driver that has a
+ * matching entry in its id_table for discovered device.
+ *
+ * @param id
+ * The VMBUS device uuid.
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int rte_eal_vmbus_detach(uuid_t id);
+
+/**
+ * Register a VMBUS driver.
+ *
+ * @param driver
+ * A pointer to a rte_vmbus_driver structure describing the driver
+ * to be registered.
+ */
+void rte_eal_vmbus_register(struct rte_vmbus_driver *driver);
+
+/** Helper for VMBUS device registration from driver nstance */
+#define RTE_PMD_REGISTER_VMBUS(nm, vmbus_drv) \
+RTE_INIT(vmbusinitfn_ ##nm); \
+static void vmbusinitfn_ ##nm(void) \
+{\
+ (vmbus_drv).driver.name = RTE_STR(nm);\
+ (vmbus_drv).driver.type = PMD_VMBUS; \
+ rte_eal_vmbus_register(&vmbus_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a VMBUS driver.
+ *
+ * @param driver
+ * A pointer to a rte_vmbus_driver structure describing the driver
+ * to be unregistered.
+ */
+void rte_eal_vmbus_unregister(struct rte_vmbus_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_VMBUS_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f09..f6ca3848 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -71,6 +71,11 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_interrupts.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_alarm.c
+ifeq ($(CONFIG_RTE_LIBRTE_HV_PMD),y)
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vmbus.c
+LDLIBS += -luuid
+endif
+
# from common dir
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
@@ -114,6 +119,7 @@ CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE
CFLAGS_eal_pci.o := -D_GNU_SOURCE
CFLAGS_eal_pci_uio.o := -D_GNU_SOURCE
CFLAGS_eal_pci_vfio.o := -D_GNU_SOURCE
+CFLAGS_eal_vmbux.o := -D_GNU_SOURCE
CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE
CFLAGS_eal_common_options.o := -D_GNU_SOURCE
CFLAGS_eal_common_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 16dd5b9c..1bc0814a 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,9 @@
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#ifdef RTE_LIBRTE_HV_PMD
+#include <rte_vmbus.h>
+#endif
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_common.h>
@@ -830,6 +833,11 @@ rte_eal_init(int argc, char **argv)
eal_check_mem_on_local_socket();
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_init() < 0)
+ RTE_LOG(ERR, EAL, "Cannot init VMBUS\n");
+#endif
+
if (eal_plugins_init() < 0)
rte_panic("Cannot init plugins\n");
@@ -884,6 +892,11 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+#ifdef RTE_LIBRTE_HV_PMD
+ if (rte_eal_vmbus_probe() < 0)
+ rte_panic("Cannot probe VMBUS\n");
+#endif
+
if (rte_eal_dev_init() < 0)
rte_panic("Cannot init pmd devices\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_vmbus.c b/lib/librte_eal/linuxapp/eal/eal_vmbus.c
new file mode 100644
index 00000000..729f93a9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_vmbus.c
@@ -0,0 +1,911 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013-2016 Brocade Communications Systems, Inc.
+ * Copyright(c) 2016 Microsoft Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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 <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <rte_eal.h>
+#include <rte_tailq.h>
+#include <rte_log.h>
+#include <rte_devargs.h>
+#include <rte_vmbus.h>
+#include <rte_malloc.h>
+
+#include "eal_private.h"
+#include "eal_pci_init.h"
+#include "eal_filesystem.h"
+
+struct vmbus_driver_list vmbus_driver_list =
+ TAILQ_HEAD_INITIALIZER(vmbus_driver_list);
+struct vmbus_device_list vmbus_device_list =
+ TAILQ_HEAD_INITIALIZER(vmbus_device_list);
+
+static void *vmbus_map_addr;
+
+static struct rte_tailq_elem rte_vmbus_uio_tailq = {
+ .name = "UIO_RESOURCE_LIST",
+};
+EAL_REGISTER_TAILQ(rte_vmbus_uio_tailq);
+
+/*
+ * parse a sysfs file containing one integer value
+ * different to the eal version, as it needs to work with 64-bit values
+ */
+static int
+vmbus_get_sysfs_uuid(const char *filename, uuid_t uu)
+{
+ char buf[BUFSIZ];
+ char *cp, *in = buf;
+ FILE *f;
+
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
+ __func__, filename);
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+
+ cp = strchr(buf, '\n');
+ if (cp)
+ *cp = '\0';
+
+ /* strip { } notation */
+ if (buf[0] == '{') {
+ in = buf + 1;
+ cp = strchr(in, '}');
+ if (cp)
+ *cp = '\0';
+ }
+
+ if (uuid_parse(in, uu) < 0) {
+ RTE_LOG(ERR, EAL, "%s %s not a valid UUID\n",
+ filename, buf);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* map a particular resource from a file */
+static void *
+vmbus_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+ int flags)
+{
+ void *mapaddr;
+
+ /* Map the memory resource of device */
+ mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | flags, fd, offset);
+ if (mapaddr == MAP_FAILED ||
+ (requested_addr != NULL && mapaddr != requested_addr)) {
+ RTE_LOG(ERR, EAL,
+ "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s)\n",
+ __func__, fd, requested_addr,
+ (unsigned long)size, (unsigned long)offset,
+ strerror(errno));
+ } else
+ RTE_LOG(DEBUG, EAL, " VMBUS memory mapped at %p\n", mapaddr);
+
+ return mapaddr;
+}
+
+/* unmap a particular resource */
+static void
+vmbus_unmap_resource(void *requested_addr, size_t size)
+{
+ if (requested_addr == NULL)
+ return;
+
+ /* Unmap the VMBUS memory resource of device */
+ if (munmap(requested_addr, size)) {
+ RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+ __func__, requested_addr, (unsigned long)size,
+ strerror(errno));
+ } else
+ RTE_LOG(DEBUG, EAL, " VMBUS memory unmapped at %p\n",
+ requested_addr);
+}
+
+/* Only supports current kernel version
+ * Unlike PCI there is no option (or need) to create UIO device.
+ */
+static int vmbus_get_uio_dev(const char *name,
+ char *dstbuf, size_t buflen)
+{
+ char dirname[PATH_MAX];
+ unsigned int uio_num;
+ struct dirent *e;
+ DIR *dir;
+
+ snprintf(dirname, sizeof(dirname),
+ "/sys/bus/vmbus/devices/%s/uio", name);
+
+ dir = opendir(dirname);
+ if (dir == NULL) {
+ RTE_LOG(ERR, EAL, "Cannot map uio resources for %s: %s\n",
+ name, strerror(errno));
+ return -1;
+ }
+
+ /* take the first file starting with "uio" */
+ while ((e = readdir(dir)) != NULL) {
+ if (sscanf(e->d_name, "uio%u", &uio_num) != 1)
+ continue;
+
+ snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio_num);
+ break;
+ }
+ closedir(dir);
+
+ return e ? (int) uio_num : -1;
+}
+
+/*
+ * parse a sysfs file containing one integer value
+ * different to the eal version, as it needs to work with 64-bit values
+ */
+static int
+vmbus_parse_sysfs_value(const char *dir, const char *name,
+ uint64_t *val)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+ char buf[BUFSIZ];
+ char *end = NULL;
+
+ snprintf(filename, sizeof(filename), "%s/%s", dir, name);
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
+ __func__, filename);
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+
+ *val = strtoull(buf, &end, 0);
+ if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
+ __func__, filename);
+ return -1;
+ }
+ return 0;
+}
+
+/* Get mappings out of values provided by uio */
+static int
+vmbus_uio_get_mappings(const char *uioname,
+ struct vmbus_map maps[])
+{
+ int i;
+
+ for (i = 0; i != VMBUS_MAX_RESOURCE; i++) {
+ struct vmbus_map *map = &maps[i];
+ char dirname[PATH_MAX];
+
+ /* check if map directory exists */
+ snprintf(dirname, sizeof(dirname),
+ "%s/maps/map%d", uioname, i);
+
+ if (access(dirname, F_OK) != 0)
+ break;
+
+ /* get mapping offset */
+ if (vmbus_parse_sysfs_value(dirname, "offset",
+ &map->offset) < 0)
+ return -1;
+
+ /* get mapping size */
+ if (vmbus_parse_sysfs_value(dirname, "size",
+ &map->size) < 0)
+ return -1;
+
+ /* get mapping physical address */
+ if (vmbus_parse_sysfs_value(dirname, "addr",
+ &maps->phaddr) < 0)
+ return -1;
+ }
+
+ return i;
+}
+
+static void
+vmbus_uio_free_resource(struct rte_vmbus_device *dev,
+ struct mapped_vmbus_resource *uio_res)
+{
+ rte_free(uio_res);
+
+ if (dev->intr_handle.fd) {
+ close(dev->intr_handle.fd);
+ dev->intr_handle.fd = -1;
+ dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+ }
+}
+
+static struct mapped_vmbus_resource *
+vmbus_uio_alloc_resource(struct rte_vmbus_device *dev)
+{
+ struct mapped_vmbus_resource *uio_res;
+ char dirname[PATH_MAX], devname[PATH_MAX];
+ int uio_num, nb_maps;
+
+ uio_num = vmbus_get_uio_dev(dev->sysfs_name, dirname, sizeof(dirname));
+ if (uio_num < 0) {
+ RTE_LOG(WARNING, EAL,
+ " %s not managed by UIO driver, skipping\n",
+ dev->sysfs_name);
+ return NULL;
+ }
+
+ /* allocate the mapping details for secondary processes*/
+ uio_res = rte_zmalloc("UIO_RES", sizeof(*uio_res), 0);
+ if (uio_res == NULL) {
+ RTE_LOG(ERR, EAL,
+ "%s(): cannot store uio mmap details\n", __func__);
+ goto error;
+ }
+
+ snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
+ dev->intr_handle.fd = open(devname, O_RDWR);
+ if (dev->intr_handle.fd < 0) {
+ RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+ devname, strerror(errno));
+ goto error;
+ }
+
+ dev->intr_handle.type = RTE_INTR_HANDLE_UIO_INTX;
+
+ snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
+ uuid_copy(uio_res->uuid, dev->device_id);
+
+ nb_maps = vmbus_uio_get_mappings(dirname, uio_res->maps);
+ if (nb_maps < 0)
+ goto error;
+
+ RTE_LOG(DEBUG, EAL, "Found %d memory maps for device %s\n",
+ nb_maps, dev->sysfs_name);
+
+ return uio_res;
+
+ error:
+ vmbus_uio_free_resource(dev, uio_res);
+ return NULL;
+}
+
+static int
+vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev,
+ unsigned int res_idx,
+ struct mapped_vmbus_resource *uio_res,
+ unsigned int map_idx)
+{
+ struct vmbus_map *maps = uio_res->maps;
+ char devname[PATH_MAX];
+ void *mapaddr;
+ int fd;
+
+ snprintf(devname, sizeof(devname),
+ "/sys/bus/vmbus/%s/resource%u", dev->sysfs_name, res_idx);
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+ devname, strerror(errno));
+ return -1;
+ }
+
+ /* allocate memory to keep path */
+ maps[map_idx].path = rte_malloc(NULL, strlen(devname) + 1, 0);
+ if (maps[map_idx].path == NULL) {
+ RTE_LOG(ERR, EAL, "Cannot allocate memory for path: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ /* try mapping somewhere close to the end of hugepages */
+ if (vmbus_map_addr == NULL)
+ vmbus_map_addr = pci_find_max_end_va();
+
+ mapaddr = vmbus_map_resource(vmbus_map_addr, fd, 0,
+ dev->mem_resource[res_idx].len, 0);
+ close(fd);
+ if (mapaddr == MAP_FAILED) {
+ rte_free(maps[map_idx].path);
+ return -1;
+ }
+
+ vmbus_map_addr = RTE_PTR_ADD(mapaddr,
+ dev->mem_resource[res_idx].len);
+
+ maps[map_idx].phaddr = dev->mem_resource[res_idx].phys_addr;
+ maps[map_idx].size = dev->mem_resource[res_idx].len;
+ maps[map_idx].addr = mapaddr;
+ maps[map_idx].offset = 0;
+ strcpy(maps[map_idx].path, devname);
+ dev->mem_resource[res_idx].addr = mapaddr;
+
+ return 0;
+}
+
+static void
+vmbus_uio_unmap(struct mapped_vmbus_resource *uio_res)
+{
+ int i;
+
+ if (uio_res == NULL)
+ return;
+
+ for (i = 0; i != uio_res->nb_maps; i++) {
+ vmbus_unmap_resource(uio_res->maps[i].addr,
+ uio_res->maps[i].size);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(uio_res->maps[i].path);
+ }
+}
+
+static struct mapped_vmbus_resource *
+vmbus_uio_find_resource(struct rte_vmbus_device *dev)
+{
+ struct mapped_vmbus_resource *uio_res;
+ struct mapped_vmbus_res_list *uio_res_list =
+ RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
+ mapped_vmbus_res_list);
+
+ if (dev == NULL)
+ return NULL;
+
+ TAILQ_FOREACH(uio_res, uio_res_list, next) {
+ if (uuid_compare(uio_res->uuid, dev->device_id) == 0)
+ return uio_res;
+ }
+ return NULL;
+}
+
+/* unmap the VMBUS resource of a VMBUS device in virtual memory */
+static void
+vmbus_uio_unmap_resource(struct rte_vmbus_device *dev)
+{
+ struct mapped_vmbus_resource *uio_res;
+ struct mapped_vmbus_res_list *uio_res_list =
+ RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
+ mapped_vmbus_res_list);
+
+ if (dev == NULL)
+ return;
+
+ /* find an entry for the device */
+ uio_res = vmbus_uio_find_resource(dev);
+ if (uio_res == NULL)
+ return;
+
+ /* secondary processes - just free maps */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return vmbus_uio_unmap(uio_res);
+
+ TAILQ_REMOVE(uio_res_list, uio_res, next);
+
+ /* unmap all resources */
+ vmbus_uio_unmap(uio_res);
+
+ /* free uio resource */
+ rte_free(uio_res);
+
+ /* close fd if in primary process */
+ close(dev->intr_handle.fd);
+ if (dev->intr_handle.uio_cfg_fd >= 0) {
+ close(dev->intr_handle.uio_cfg_fd);
+ dev->intr_handle.uio_cfg_fd = -1;
+ }
+
+ dev->intr_handle.fd = -1;
+ dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
+
+static int
+vmbus_uio_map_secondary(struct rte_vmbus_device *dev)
+{
+ struct mapped_vmbus_resource *uio_res;
+ struct mapped_vmbus_res_list *uio_res_list =
+ RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head,
+ mapped_vmbus_res_list);
+
+ TAILQ_FOREACH(uio_res, uio_res_list, next) {
+ int i;
+
+ /* skip this element if it doesn't match our id */
+ if (uuid_compare(uio_res->uuid, dev->device_id))
+ continue;
+
+ for (i = 0; i != uio_res->nb_maps; i++) {
+ void *mapaddr;
+ int fd;
+
+ fd = open(uio_res->maps[i].path, O_RDWR);
+ if (fd < 0) {
+ RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
+ uio_res->maps[i].path, strerror(errno));
+ return -1;
+ }
+
+ mapaddr = vmbus_map_resource(uio_res->maps[i].addr, fd,
+ uio_res->maps[i].offset,
+ uio_res->maps[i].size, 0);
+ /* fd is not needed in slave process, close it */
+ close(fd);
+
+ if (mapaddr == uio_res->maps[i].addr)
+ continue;
+
+ RTE_LOG(ERR, EAL,
+ "Cannot mmap device resource file %s to address: %p\n",
+ uio_res->maps[i].path,
+ uio_res->maps[i].addr);
+
+ /* unmap addrs correctly mapped */
+ while (i != 0) {
+ --i;
+ vmbus_unmap_resource(uio_res->maps[i].addr,
+ uio_res->maps[i].size);
+ }
+ return -1;
+
+ }
+ return 0;
+ }
+
+ RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
+ return 1;
+}
+
+/* map the resources of a vmbus device in virtual memory */
+int
+rte_eal_vmbus_map_device(struct rte_vmbus_device *dev)
+{
+ struct mapped_vmbus_resource *uio_res;
+ struct mapped_vmbus_res_list *uio_res_list =
+ RTE_TAILQ_CAST(rte_vmbus_uio_tailq.head, mapped_vmbus_res_list);
+ int i, ret, map_idx = 0;
+
+ dev->intr_handle.fd = -1;
+ dev->intr_handle.uio_cfg_fd = -1;
+ dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+
+ /* secondary processes - use already recorded details */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return vmbus_uio_map_secondary(dev);
+
+ /* allocate uio resource */
+ uio_res = vmbus_uio_alloc_resource(dev);
+ if (uio_res == NULL)
+ return -1;
+
+ /* Map all BARs */
+ for (i = 0; i != VMBUS_MAX_RESOURCE; i++) {
+ uint64_t phaddr;
+
+ /* skip empty BAR */
+ phaddr = dev->mem_resource[i].phys_addr;
+ if (phaddr == 0)
+ continue;
+
+ ret = vmbus_uio_map_resource_by_index(dev, i,
+ uio_res, map_idx);
+ if (ret)
+ goto error;
+
+ map_idx++;
+ }
+
+ uio_res->nb_maps = map_idx;
+
+ TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
+
+ return 0;
+error:
+ for (i = 0; i < map_idx; i++) {
+ vmbus_unmap_resource(uio_res->maps[i].addr,
+ uio_res->maps[i].size);
+ rte_free(uio_res->maps[i].path);
+ }
+ vmbus_uio_free_resource(dev, uio_res);
+ return -1;
+}
+
+/* Scan one vmbus sysfs entry, and fill the devices list from it. */
+static int
+vmbus_scan_one(const char *name)
+{
+ struct rte_vmbus_device *dev, *dev2;
+ char filename[PATH_MAX];
+ char dirname[PATH_MAX];
+ unsigned long tmp;
+
+ dev = malloc(sizeof(*dev) + strlen(name) + 1);
+ if (dev == NULL)
+ return -1;
+
+ memset(dev, 0, sizeof(*dev));
+ strcpy(dev->sysfs_name, name);
+ if (dev->sysfs_name == NULL)
+ goto error;
+
+ /* sysfs base directory
+ * /sys/bus/vmbus/devices/7a08391f-f5a0-4ac0-9802-d13fd964f8df
+ * or on older kernel
+ * /sys/bus/vmbus/devices/vmbus_1
+ */
+ snprintf(dirname, sizeof(dirname), "%s/%s",
+ SYSFS_VMBUS_DEVICES, name);
+
+ /* get device id */
+ snprintf(filename, sizeof(filename), "%s/device_id", dirname);
+ if (vmbus_get_sysfs_uuid(filename, dev->device_id) < 0)
+ goto error;
+
+ /* get device class */
+ snprintf(filename, sizeof(filename), "%s/class_id", dirname);
+ if (vmbus_get_sysfs_uuid(filename, dev->class_id) < 0)
+ goto error;
+
+ /* get relid */
+ snprintf(filename, sizeof(filename), "%s/id", dirname);
+ if (eal_parse_sysfs_value(filename, &tmp) < 0)
+ goto error;
+ dev->relid = tmp;
+
+ /* get monitor id */
+ snprintf(filename, sizeof(filename), "%s/monitor_id", dirname);
+ if (eal_parse_sysfs_value(filename, &tmp) < 0)
+ goto error;
+ dev->monitor_id = tmp;
+
+ /* get numa node */
+ snprintf(filename, sizeof(filename), "%s/numa_node",
+ dirname);
+ if (eal_parse_sysfs_value(filename, &tmp) < 0)
+ /* if no NUMA support, set default to 0 */
+ dev->device.numa_node = 0;
+ else
+ dev->device.numa_node = tmp;
+
+ /* device is valid, add in list (sorted) */
+ RTE_LOG(DEBUG, EAL, "Adding vmbus device %s\n", name);
+
+ TAILQ_FOREACH(dev2, &vmbus_device_list, next) {
+ int ret;
+
+ ret = uuid_compare(dev->device_id, dev->device_id);
+ if (ret > 0)
+ continue;
+
+ if (ret < 0) {
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ rte_eal_device_insert(&dev->device);
+ } else { /* already registered */
+ memmove(dev2->mem_resource, dev->mem_resource,
+ sizeof(dev->mem_resource));
+ free(dev);
+ }
+ return 0;
+ }
+
+ rte_eal_device_insert(&dev->device);
+ TAILQ_INSERT_TAIL(&vmbus_device_list, dev, next);
+
+ return 0;
+error:
+ free(dev);
+ return -1;
+}
+
+/*
+ * Scan the content of the vmbus, and the devices in the devices list
+ */
+static int
+vmbus_scan(void)
+{
+ struct dirent *e;
+ DIR *dir;
+
+ dir = opendir(SYSFS_VMBUS_DEVICES);
+ if (dir == NULL) {
+ if (errno == ENOENT)
+ return 0;
+
+ RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ while ((e = readdir(dir)) != NULL) {
+ if (e->d_name[0] == '.')
+ continue;
+
+ if (vmbus_scan_one(e->d_name) < 0)
+ goto error;
+ }
+ closedir(dir);
+ return 0;
+
+error:
+ closedir(dir);
+ return -1;
+}
+
+/* Init the VMBUS EAL subsystem */
+int rte_eal_vmbus_init(void)
+{
+ /* VMBUS can be disabled */
+ if (internal_config.no_vmbus)
+ return 0;
+
+ if (vmbus_scan() < 0) {
+ RTE_LOG(ERR, EAL, "%s(): Cannot scan vmbus\n", __func__);
+ return -1;
+ }
+ return 0;
+}
+
+/* Below is PROBE part of eal_vmbus library */
+
+/*
+ * If device ID match, call the devinit() function of the driver.
+ */
+static int
+rte_eal_vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
+ struct rte_vmbus_device *dev)
+{
+ const uuid_t *id_table;
+
+ RTE_LOG(DEBUG, EAL, " probe driver: %s\n", dr->driver.name);
+
+ for (id_table = dr->id_table; !uuid_is_null(*id_table); ++id_table) {
+ struct rte_devargs *args;
+ char guid[UUID_BUF_SZ];
+ int ret;
+
+ /* skip devices not assocaited with this device class */
+ if (uuid_compare(*id_table, dev->class_id) != 0)
+ continue;
+
+ uuid_unparse(dev->device_id, guid);
+ RTE_LOG(INFO, EAL, "VMBUS device %s on NUMA socket %i\n",
+ guid, dev->device.numa_node);
+
+ /* no initialization when blacklisted, return without error */
+ args = dev->device.devargs;
+ if (args && args->type == RTE_DEVTYPE_BLACKLISTED_VMBUS) {
+ RTE_LOG(INFO, EAL, " Device is blacklisted, not initializing\n");
+ return 1;
+ }
+
+ RTE_LOG(INFO, EAL, " probe driver: %s\n", dr->driver.name);
+
+ /* map resources for device */
+ ret = rte_eal_vmbus_map_device(dev);
+ if (ret != 0)
+ return ret;
+
+ /* reference driver structure */
+ dev->driver = dr;
+
+ /* call the driver probe() function */
+ ret = dr->probe(dr, dev);
+ if (ret)
+ dev->driver = NULL;
+
+ return ret;
+ }
+
+ /* return positive value if driver doesn't support this device */
+ return 1;
+}
+
+
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+vmbus_detach_dev(struct rte_vmbus_driver *dr,
+ struct rte_vmbus_device *dev)
+{
+ const uuid_t *id_table;
+
+ for (id_table = dr->id_table; !uuid_is_null(*id_table); ++id_table) {
+ char guid[UUID_BUF_SZ];
+
+ /* skip devices not assocaited with this device class */
+ if (uuid_compare(*id_table, dev->class_id) != 0)
+ continue;
+
+ uuid_unparse(dev->device_id, guid);
+ RTE_LOG(INFO, EAL, "VMBUS device %s on NUMA socket %i\n",
+ guid, dev->device.numa_node);
+
+ RTE_LOG(DEBUG, EAL, " remove driver: %s\n", dr->driver.name);
+
+ if (dr->remove && (dr->remove(dev) < 0))
+ return -1; /* negative value is an error */
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ vmbus_uio_unmap_resource(dev);
+ return 0;
+ }
+
+ /* return positive value if driver doesn't support this device */
+ return 1;
+}
+
+/*
+ * call the devinit() function of all
+ * registered drivers for the vmbus device. Return -1 if no driver is
+ * found for this class of vmbus device.
+ * The present assumption is that we have drivers only for vmbus network
+ * devices. That's why we don't check driver's id_table now.
+ */
+static int
+vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
+{
+ struct rte_vmbus_driver *dr = NULL;
+ int ret;
+
+ TAILQ_FOREACH(dr, &vmbus_driver_list, next) {
+ ret = rte_eal_vmbus_probe_one_driver(dr, dev);
+ if (ret < 0) {
+ /* negative value is an error */
+ RTE_LOG(ERR, EAL, "Failed to probe driver %s\n",
+ dr->driver.name);
+ return -1;
+ }
+ /* positive value means driver doesn't support it */
+ if (ret > 0)
+ continue;
+
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*
+ * If device ID matches, call the remove() function of all
+ * registered driver for the given device. Return -1 if initialization
+ * failed, return 1 if no driver is found for this device.
+ */
+static int
+vmbus_detach_all_drivers(struct rte_vmbus_device *dev)
+{
+ struct rte_vmbus_driver *dr;
+ int rc = 0;
+
+ if (dev == NULL)
+ return -1;
+
+ TAILQ_FOREACH(dr, &vmbus_driver_list, next) {
+ rc = vmbus_detach_dev(dr, dev);
+ if (rc < 0)
+ /* negative value is an error */
+ return -1;
+ if (rc > 0)
+ /* positive value means driver doesn't support it */
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+/* Detach device specified by its VMBUS id */
+int
+rte_eal_vmbus_detach(uuid_t device_id)
+{
+ struct rte_vmbus_device *dev;
+ char ubuf[UUID_BUF_SZ];
+
+ TAILQ_FOREACH(dev, &vmbus_device_list, next) {
+ if (uuid_compare(dev->device_id, device_id) != 0)
+ continue;
+
+ if (vmbus_detach_all_drivers(dev) < 0)
+ goto err_return;
+
+ TAILQ_REMOVE(&vmbus_device_list, dev, next);
+ free(dev);
+ return 0;
+ }
+ return -1;
+
+err_return:
+ uuid_unparse(device_id, ubuf);
+ RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+ ubuf);
+ return -1;
+}
+
+/*
+ * Scan the vmbus, and call the devinit() function for
+ * all registered drivers that have a matching entry in its id_table
+ * for discovered devices.
+ */
+int
+rte_eal_vmbus_probe(void)
+{
+ struct rte_vmbus_device *dev = NULL;
+
+ TAILQ_FOREACH(dev, &vmbus_device_list, next) {
+ char ubuf[UUID_BUF_SZ];
+
+ uuid_unparse(dev->device_id, ubuf);
+
+ RTE_LOG(DEBUG, EAL, "Probing driver for device %s ...\n",
+ ubuf);
+ vmbus_probe_all_drivers(dev);
+ }
+ return 0;
+}
+
+/* register vmbus driver */
+void
+rte_eal_vmbus_register(struct rte_vmbus_driver *driver)
+{
+ TAILQ_INSERT_TAIL(&vmbus_driver_list, driver, next);
+}
+
+/* unregister vmbus driver */
+void
+rte_eal_vmbus_unregister(struct rte_vmbus_driver *driver)
+{
+ TAILQ_REMOVE(&vmbus_driver_list, driver, next);
+}
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 7c212096..b69af0f0 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3334,3 +3334,93 @@ rte_eth_dev_l2_tunnel_offload_set(uint8_t port_id,
-ENOTSUP);
return (*dev->dev_ops->l2_tunnel_offload_set)(dev, l2_tunnel, mask, en);
}
+
+
+#ifdef RTE_LIBRTE_HV_PMD
+int
+rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
+ struct rte_vmbus_device *vmbus_dev)
+{
+ struct eth_driver *eth_drv = (struct eth_driver *)vmbus_drv;
+ struct rte_eth_dev *eth_dev;
+ char ustr[UUID_BUF_SZ];
+ int diag;
+
+ uuid_unparse(vmbus_dev->device_id, ustr);
+
+ eth_dev = rte_eth_dev_allocate(ustr);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
+ eth_drv->dev_private_size,
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private port data\n");
+ }
+
+ eth_dev->device = &vmbus_dev->device;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ /*
+ * Set the default maximum frame size.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = (*eth_drv->eth_dev_init)(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+ vmbus_drv->driver.name, ustr);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ return diag;
+}
+
+int
+rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev)
+{
+ const struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ustr[UUID_BUF_SZ];
+ int ret;
+
+ if (vmbus_dev == NULL)
+ return -EINVAL;
+
+ uuid_unparse(vmbus_dev->device_id, ustr);
+ eth_dev = rte_eth_dev_allocated(ustr);
+ if (eth_dev == NULL)
+ return -ENODEV;
+
+ eth_drv = (const struct eth_driver *)vmbus_dev->driver;
+
+ /* Invoke PMD device uninit function */
+ if (*eth_drv->eth_dev_uninit) {
+ ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+ if (ret)
+ return ret;
+ }
+
+ /* free ether device */
+ rte_eth_dev_release_port(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ eth_dev->device = NULL;
+ eth_dev->driver = NULL;
+ eth_dev->data = NULL;
+
+ return 0;
+}
+#endif
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1a62a322..2a8c1eed 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,9 @@ extern "C" {
#include <rte_log.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#ifdef RTE_LIBRTE_HV_PMD
+#include <rte_vmbus.h>
+#endif
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_errno.h>
@@ -1908,6 +1911,17 @@ struct rte_pci_eth_driver {
struct eth_driver eth_drv; /**< Ethernet driver. */
};
+#ifdef RTE_LIBRTE_HV_PMD
+/**
+ * @internal
+ * The structure associated with a PMD VMBUS Ethernet driver.
+ */
+struct rte_vmbus_eth_driver {
+ struct rte_vmbus_driver vmbus_drv; /**< Underlying VMBUS driver. */
+ struct eth_driver eth_drv; /**< Ethernet driver. */
+};
+#endif
+
/**
* Convert a numerical speed in Mbps to a bitmap flag that can be used in
* the bitmap link_speeds of the struct rte_eth_conf
@@ -4543,6 +4557,23 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
*/
int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
+#ifdef RTE_LIBRTE_HV_PMD
+/**
+ * @internal
+ * Wrapper for use by vmbus drivers as a .probe function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_vmbus_probe(struct rte_vmbus_driver *vmbus_drv,
+ struct rte_vmbus_device *vmbus_dev);
+
+/**
+ * @internal
+ * Wrapper for use by vmbus drivers as a .remove function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_vmbus_remove(struct rte_vmbus_device *vmbus_dev);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f75f0e24..6b304084 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -130,6 +130,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
endif # $(CONFIG_RTE_LIBRTE_VHOST)
_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+_LDLIBS-$(CONFIG_RTE_LIBRTE_HV_PMD) += -luuid
ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v4 1/5] ethdev: add firmware version get
From: Yang, Qiming @ 2017-01-08 3:09 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev@dpdk.org, Yigit, Ferruh, Zhang, Helin, Horton, Remy
In-Reply-To: <2775891.n5HL0JQtYk@xps13>
-----Original Message-----
From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
Sent: Thursday, January 5, 2017 9:45 PM
To: Yang, Qiming <qiming.yang@intel.com>
Cc: dev@dpdk.org; Yigit, Ferruh <ferruh.yigit@intel.com>; Zhang, Helin <helin.zhang@intel.com>; Horton, Remy <remy.horton@intel.com>
Subject: Re: [dpdk-dev] [PATCH v4 1/5] ethdev: add firmware version get
2017-01-04 20:03, Qiming Yang:
> This patch adds a new API 'rte_eth_dev_fw_version_get' for fetching
> firmware version related information by a given device.
[...]
> /**
> + * Retrieve the firmware version of a device.
> + *
> + * @param port_id
> + * The port identifier of the device.
> + * @param fw_major
> + * A pointer to store the major firmware version of a device.
> + * @param fw_minor
> + * A pointer to store the minor firmware version of a device.
> + * @param fw_patch
> + * A pointer to store the firmware patch number of a device.
> + * @param etrack_id
> + * A pointer to store the nvm version of a device.
> + */
> +void rte_eth_dev_fw_version_get(uint8_t port_id, uint32_t *fw_major,
> + uint32_t *fw_minor, uint32_t *fw_patch, uint32_t *etrack_id);
After reading few comments, I think it should just fill a string.
There is no way the firmware version can be generalized or standardized.
If the application wants to do some processing like number comparisons, it has to be aware of the specific firmware version string format.
If you want to help the application to parse this string, it should be a PMD specific API.
Qiming: I agree with you.
^ permalink raw reply
* [PATCH v5 0/5] new API 'rte_eth_dev_fw_version_get'
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483531428-14481-1-git-send-email-qiming.yang@intel.com>
Now, the example ethtool can only show the driver information. From
customers' point of view, it should be better if we can have the same
way that the Linux kernel ethtool does to show firmware version.
These five patches added a new function ``rte_eth_dev_fw_version_get()``
to fetch firmware version related information and implement the
display in example ethtool.
Qiming Yang (5):
ethdev: add firmware version get
net/e1000: add firmware version get
net/ixgbe: add firmware version get
net/i40e: add firmware version get
ethtool: display firmware version
doc/guides/nics/features/default.ini | 1 +
doc/guides/nics/features/i40e.ini | 1 +
doc/guides/nics/features/igb.ini | 1 +
doc/guides/nics/features/ixgbe.ini | 1 +
doc/guides/rel_notes/deprecation.rst | 4 ---
doc/guides/rel_notes/release_17_02.rst | 3 +++
drivers/net/e1000/igb_ethdev.c | 46 ++++++++++++++++++++++++++++++++++
drivers/net/i40e/i40e_ethdev.c | 15 +++++++++++
drivers/net/ixgbe/ixgbe_ethdev.c | 18 +++++++++++++
examples/ethtool/ethtool-app/ethapp.c | 1 +
examples/ethtool/lib/rte_ethtool.c | 3 +++
lib/librte_ether/rte_ethdev.c | 12 +++++++++
lib/librte_ether/rte_ethdev.h | 20 +++++++++++++++
lib/librte_ether/rte_ether_version.map | 1 +
14 files changed, 123 insertions(+), 4 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v5 1/5] ethdev: add firmware version get
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483848695-44643-1-git-send-email-qiming.yang@intel.com>
This patch adds a new API 'rte_eth_dev_fw_version_get' for
fetching firmware version by a given device.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---
v2 changes:
* modified some comment statements.
v3 changes:
* change API, use rte_eth_dev_fw_info_get(uint8_t port_id,
uint32_t *fw_major, uint32_t *fw_minor, uint32_t *fw_patch,
uint32_t *etrack_id) instead of rte_eth_dev_fwver_get(uint8_t port_id,
char *fw_version, int fw_length).
Add statusment in /doc/guides/nics/features/default.ini and
release_17_02.rst.
v4 changes:
* remove deprecation notice, rename API as rte_eth_dev_fw_version_get.
v5 changes:
* change API, use rte_eth_dev_fw_version_get(uint8_t port_id,
char *fw_version, int fw_length).
---
---
doc/guides/nics/features/default.ini | 1 +
doc/guides/rel_notes/deprecation.rst | 4 ----
doc/guides/rel_notes/release_17_02.rst | 3 +++
lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
lib/librte_ether/rte_ethdev.h | 20 ++++++++++++++++++++
lib/librte_ether/rte_ether_version.map | 1 +
6 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index f1bf9bf..ae40d57 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -50,6 +50,7 @@ Timesync =
Basic stats =
Extended stats =
Stats per queue =
+FW version =
EEPROM dump =
Registers dump =
Multiprocess aware =
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1438c77..291e03d 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -30,10 +30,6 @@ Deprecation Notices
``nb_seg_max`` and ``nb_mtu_seg_max`` providing information about number of
segments limit to be transmitted by device for TSO/non-TSO packets.
-* In 17.02 ABI change is planned: the ``rte_eth_dev_info`` structure
- will be extended with a new member ``fw_version`` in order to store
- the NIC firmware version.
-
* ethdev: an API change is planned for 17.02 for the function
``_rte_eth_dev_callback_process``. In 17.02 the function will return an ``int``
instead of ``void`` and a fourth parameter ``void *ret_param`` will be added.
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 180af82..260033d 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -52,6 +52,9 @@ New Features
See the :ref:`Generic flow API <Generic_flow_API>` documentation for more
information.
+* **Added firmware version get API.**
+ Added a new function ``rte_eth_dev_fw_version_get()`` to fetch firmware
+ version by a given device.
Resolved Issues
---------------
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 280f0db..cb80476 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1586,6 +1586,18 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id,
}
void
+rte_eth_dev_fw_version_get(uint8_t port_id, char *fw_version, int fw_length)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ dev = &rte_eth_devices[port_id];
+
+ RTE_FUNC_PTR_OR_RET(*dev->dev_ops->fw_version_get);
+ (*dev->dev_ops->fw_version_get)(dev, fw_version, fw_length);
+}
+
+void
rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
{
struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index fb51754..2be31d2 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1150,6 +1150,10 @@ typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
/**< @internal Check DD bit of specific RX descriptor */
+typedef void (*eth_fw_version_get_t)(struct rte_eth_dev *dev,
+ char *fw_version, int fw_length);
+/**< @internal Get firmware information of an Ethernet device. */
+
typedef void (*eth_rxq_info_get_t)(struct rte_eth_dev *dev,
uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo);
@@ -1455,6 +1459,7 @@ struct eth_dev_ops {
eth_dev_infos_get_t dev_infos_get; /**< Get device info. */
eth_rxq_info_get_t rxq_info_get; /**< retrieve RX queue information. */
eth_txq_info_get_t txq_info_get; /**< retrieve TX queue information. */
+ eth_fw_version_get_t fw_version_get; /**< Get firmware version. */
eth_dev_supported_ptypes_get_t dev_supported_ptypes_get;
/**< Get packet types supported and identified by device. */
@@ -2395,6 +2400,21 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
/**
+ * Retrieve the firmware version of a device.
+ *
+ * @param port_id
+ * The port identifier of the device.
+ * @param fw_version
+ * A array pointer to store the firmware version of a device,
+ * allocated by caller.
+ * @param fw_length
+ * The size of the array pointed by fw_version, which should be
+ * large enough to store firmware version of the device.
+ */
+void rte_eth_dev_fw_version_get(uint8_t port_id,
+ char *fw_version, int fw_length);
+
+/**
* Retrieve the supported packet types of an Ethernet device.
*
* When a packet type is announced as supported, it *must* be recognized by
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index a021781..0cf94ed 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -151,6 +151,7 @@ DPDK_17.02 {
global:
_rte_eth_dev_reset;
+ rte_eth_dev_fw_version_get;
rte_flow_create;
rte_flow_destroy;
rte_flow_flush;
--
2.7.4
^ permalink raw reply related
* [PATCH v5 2/5] net/e1000: add firmware version get
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483848695-44643-1-git-send-email-qiming.yang@intel.com>
This patch adds a new function eth_igb_fw_version_get.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---
v3 changes:
* use eth_igb_fw_version_get(struct rte_eth_dev *dev, u32 *fw_major,
u32 *fw_minor, u32 *fw_minor, u32 *fw_patch, u32 *etrack_id) instead
of eth_igb_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
int fw_length). Add statusment in /doc/guides/nics/features/igb.ini.
v5 changes:
* use the function interface in patch v2.
---
---
doc/guides/nics/features/igb.ini | 1 +
drivers/net/e1000/igb_ethdev.c | 46 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/doc/guides/nics/features/igb.ini b/doc/guides/nics/features/igb.ini
index 9fafe72..26ae008 100644
--- a/doc/guides/nics/features/igb.ini
+++ b/doc/guides/nics/features/igb.ini
@@ -35,6 +35,7 @@ Packet type parsing = Y
Timesync = Y
Basic stats = Y
Extended stats = Y
+FW version = Y
EEPROM dump = Y
Registers dump = Y
BSD nic_uio = Y
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4a15447..2bdcf39 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -120,6 +120,8 @@ static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
unsigned limit);
static void eth_igb_stats_reset(struct rte_eth_dev *dev);
static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
+static void eth_igb_fw_version_get(struct rte_eth_dev *dev,
+ char *fw_version, int fw_length);
static void eth_igb_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
static const uint32_t *eth_igb_supported_ptypes_get(struct rte_eth_dev *dev);
@@ -389,6 +391,7 @@ static const struct eth_dev_ops eth_igb_ops = {
.xstats_get_names = eth_igb_xstats_get_names,
.stats_reset = eth_igb_stats_reset,
.xstats_reset = eth_igb_xstats_reset,
+ .fw_version_get = eth_igb_fw_version_get,
.dev_infos_get = eth_igb_infos_get,
.dev_supported_ptypes_get = eth_igb_supported_ptypes_get,
.mtu_set = eth_igb_mtu_set,
@@ -1981,6 +1984,49 @@ eth_igbvf_stats_reset(struct rte_eth_dev *dev)
}
static void
+eth_igb_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
+ int fw_length)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct e1000_fw_version fw;
+
+ e1000_get_fw_version(hw, &fw);
+
+ switch (hw->mac.type) {
+ case e1000_i210:
+ case e1000_i211:
+ if (!(e1000_get_flash_presence_i210(hw))) {
+ snprintf(fw_version, fw_length,
+ "%2d.%2d-%d",
+ fw.invm_major, fw.invm_minor,
+ fw.invm_img_type);
+ break;
+ }
+ /* fall through */
+ default:
+ /* if option rom is valid, display its version too*/
+ if (fw.or_valid) {
+ snprintf(fw_version, fw_length,
+ "%d.%d, 0x%08x, %d.%d.%d",
+ fw.eep_major, fw.eep_minor, fw.etrack_id,
+ fw.or_major, fw.or_build, fw.or_patch);
+ /* no option rom */
+ } else {
+ if (fw.etrack_id != 0X0000) {
+ snprintf(fw_version, fw_length,
+ "%d.%d, 0x%08x",
+ fw.eep_major, fw.eep_minor, fw.etrack_id);
+ } else {
+ snprintf(fw_version, fw_length,
+ "%d.%d.%d",
+ fw.eep_major, fw.eep_minor, fw.eep_build);
+ }
+ }
+ break;
+ }
+}
+
+static void
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);
--
2.7.4
^ permalink raw reply related
* [PATCH v5 3/5] net/ixgbe: add firmware version get
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483848695-44643-1-git-send-email-qiming.yang@intel.com>
This patch adds a new function ixgbe_fw_version_get.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---
v3 changes:
* use ixgbe_fw_version_get(struct rte_eth_dev *dev,
__rte_unused u32 *fw_major, __rte_unused u32 *fw_minor,
__rte_unused u32 *fw_patch, u32 *etrack_id) instead of
ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
int fw_length). Add statusment
in /doc/guides/nics/features/ixgbe.ini.
v5 changes:
* use the function interface in patch v2.
---
---
doc/guides/nics/features/ixgbe.ini | 1 +
drivers/net/ixgbe/ixgbe_ethdev.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/doc/guides/nics/features/ixgbe.ini b/doc/guides/nics/features/ixgbe.ini
index 4a5667f..e7104c2 100644
--- a/doc/guides/nics/features/ixgbe.ini
+++ b/doc/guides/nics/features/ixgbe.ini
@@ -43,6 +43,7 @@ Timesync = Y
Basic stats = Y
Extended stats = Y
Stats per queue = Y
+FW version = Y
EEPROM dump = Y
Registers dump = Y
Multiprocess aware = Y
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ec2edad..407f398 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -193,6 +193,8 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
uint16_t queue_id,
uint8_t stat_idx,
uint8_t is_rx);
+static void ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
+ int fw_length);
static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
@@ -538,6 +540,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
+ .fw_version_get = ixgbe_fw_version_get,
.dev_infos_get = ixgbe_dev_info_get,
.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
.mtu_set = ixgbe_dev_mtu_set,
@@ -3029,6 +3032,21 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
}
static void
+ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, int fw_length)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ u16 eeprom_verh, eeprom_verl;
+ u32 etrack_id;
+
+ ixgbe_read_eeprom(hw, 0x2e, &eeprom_verh);
+ ixgbe_read_eeprom(hw, 0x2d, &eeprom_verl);
+
+ etrack_id = (eeprom_verh << 16) | eeprom_verl;
+ snprintf(fw_version, fw_length,
+ "0x%08x", etrack_id);
+}
+
+static void
ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH v5 4/5] net/i40e: add firmware version get
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483848695-44643-1-git-send-email-qiming.yang@intel.com>
This patch add a new function i40e_fw_version_get.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---
v3 changes:
* use i40e_fw_version_get(struct rte_eth_dev *dev, u32 *fw_major,
u32 *fw_minor, __rte_unused u32 *fw_patch, u32 *etrack_id)
instead of i40e_fw_version_get(struct rte_eth_dev *dev,
char *fw_version, int fw_length). Add statusment in
/doc/guides/nics/features/i40e.ini.
v5 changes:
* use the function interface in patch v2.
---
---
doc/guides/nics/features/i40e.ini | 1 +
drivers/net/i40e/i40e_ethdev.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/doc/guides/nics/features/i40e.ini b/doc/guides/nics/features/i40e.ini
index 0d143bc..0dbc3c3 100644
--- a/doc/guides/nics/features/i40e.ini
+++ b/doc/guides/nics/features/i40e.ini
@@ -39,6 +39,7 @@ Packet type parsing = Y
Timesync = Y
Basic stats = Y
Extended stats = Y
+FW version = Y
Multiprocess aware = Y
BSD nic_uio = Y
Linux UIO = Y
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8f63044..ff6f106 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -324,6 +324,8 @@ static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
uint16_t queue_id,
uint8_t stat_idx,
uint8_t is_rx);
+static void i40e_fw_version_get(struct rte_eth_dev *dev,
+ char *fw_version, int fw_length);
static void i40e_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
@@ -503,6 +505,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
.stats_reset = i40e_dev_stats_reset,
.xstats_reset = i40e_dev_stats_reset,
.queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set,
+ .fw_version_get = i40e_fw_version_get,
.dev_infos_get = i40e_dev_info_get,
.dev_supported_ptypes_get = i40e_dev_supported_ptypes_get,
.vlan_filter_set = i40e_vlan_filter_set,
@@ -2590,6 +2593,18 @@ i40e_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *dev,
}
static void
+i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, int fw_length)
+{
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ snprintf(fw_version, fw_length,
+ "%d.%d%d 0x%08x",
+ ((hw->nvm.version >> 12) & 0xf),
+ ((hw->nvm.version >> 4) & 0xff),
+ (hw->nvm.version & 0xf), hw->nvm.eetrack);
+}
+
+static void
i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
--
2.7.4
^ permalink raw reply related
* [PATCH v5 5/5] ethtool: display firmware version
From: Qiming Yang @ 2017-01-08 4:11 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, helin.zhang, remy.horton, Qiming Yang
In-Reply-To: <1483848695-44643-1-git-send-email-qiming.yang@intel.com>
This patch enhances the ethtool example to support to show
firmware version, in the same way that the Linux kernel
ethtool does.
Signed-off-by: Qiming Yang <qiming.yang@intel.com>
Acked-by: Remy Horton <remy.horton@intel.com>
---
v4 changes:
* split bus info print from this patch set
---
---
examples/ethtool/ethtool-app/ethapp.c | 1 +
examples/ethtool/lib/rte_ethtool.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethtool-app/ethapp.c
index 6aeaa06..85c31ac 100644
--- a/examples/ethtool/ethtool-app/ethapp.c
+++ b/examples/ethtool/ethtool-app/ethapp.c
@@ -185,6 +185,7 @@ pcmd_drvinfo_callback(__rte_unused void *ptr_params,
printf("Port %i driver: %s (ver: %s)\n",
id_port, info.driver, info.version
);
+ printf("firmware-version: %s\n", info.fw_version);
}
}
diff --git a/examples/ethtool/lib/rte_ethtool.c b/examples/ethtool/lib/rte_ethtool.c
index 6f0ce84..36f4ae8 100644
--- a/examples/ethtool/lib/rte_ethtool.c
+++ b/examples/ethtool/lib/rte_ethtool.c
@@ -54,6 +54,9 @@ rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ rte_eth_dev_fw_version_get(port_id, drvinfo->fw_version,
+ sizeof(drvinfo->fw_version));
+
memset(&dev_info, 0, sizeof(dev_info));
rte_eth_dev_info_get(port_id, &dev_info);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v5 1/5] ethdev: add firmware version get
From: Andrew Rybchenko @ 2017-01-08 6:38 UTC (permalink / raw)
To: Qiming Yang, dev; +Cc: ferruh.yigit, helin.zhang, remy.horton
In-Reply-To: <1483848695-44643-2-git-send-email-qiming.yang@intel.com>
On 01/08/2017 07:11 AM, Qiming Yang wrote:
> This patch adds a new API 'rte_eth_dev_fw_version_get' for
> fetching firmware version by a given device.
>
> Signed-off-by: Qiming Yang <qiming.yang@intel.com>
> Acked-by: Remy Horton <remy.horton@intel.com>
> ---
> v2 changes:
> * modified some comment statements.
> v3 changes:
> * change API, use rte_eth_dev_fw_info_get(uint8_t port_id,
> uint32_t *fw_major, uint32_t *fw_minor, uint32_t *fw_patch,
> uint32_t *etrack_id) instead of rte_eth_dev_fwver_get(uint8_t port_id,
> char *fw_version, int fw_length).
> Add statusment in /doc/guides/nics/features/default.ini and
> release_17_02.rst.
> v4 changes:
> * remove deprecation notice, rename API as rte_eth_dev_fw_version_get.
> v5 changes:
> * change API, use rte_eth_dev_fw_version_get(uint8_t port_id,
> char *fw_version, int fw_length).
> ---
> ---
> doc/guides/nics/features/default.ini | 1 +
> doc/guides/rel_notes/deprecation.rst | 4 ----
> doc/guides/rel_notes/release_17_02.rst | 3 +++
> lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
> lib/librte_ether/rte_ethdev.h | 20 ++++++++++++++++++++
> lib/librte_ether/rte_ether_version.map | 1 +
> 6 files changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
> index f1bf9bf..ae40d57 100644
> --- a/doc/guides/nics/features/default.ini
> +++ b/doc/guides/nics/features/default.ini
> @@ -50,6 +50,7 @@ Timesync =
> Basic stats =
> Extended stats =
> Stats per queue =
> +FW version =
> EEPROM dump =
> Registers dump =
> Multiprocess aware =
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 1438c77..291e03d 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -30,10 +30,6 @@ Deprecation Notices
> ``nb_seg_max`` and ``nb_mtu_seg_max`` providing information about number of
> segments limit to be transmitted by device for TSO/non-TSO packets.
>
> -* In 17.02 ABI change is planned: the ``rte_eth_dev_info`` structure
> - will be extended with a new member ``fw_version`` in order to store
> - the NIC firmware version.
> -
> * ethdev: an API change is planned for 17.02 for the function
> ``_rte_eth_dev_callback_process``. In 17.02 the function will return an ``int``
> instead of ``void`` and a fourth parameter ``void *ret_param`` will be added.
> diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
> index 180af82..260033d 100644
> --- a/doc/guides/rel_notes/release_17_02.rst
> +++ b/doc/guides/rel_notes/release_17_02.rst
> @@ -52,6 +52,9 @@ New Features
> See the :ref:`Generic flow API <Generic_flow_API>` documentation for more
> information.
>
> +* **Added firmware version get API.**
> + Added a new function ``rte_eth_dev_fw_version_get()`` to fetch firmware
> + version by a given device.
>
> Resolved Issues
> ---------------
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 280f0db..cb80476 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1586,6 +1586,18 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id,
> }
>
> void
> +rte_eth_dev_fw_version_get(uint8_t port_id, char *fw_version, int fw_length)
May be size_t should be used for fw_length? Corresponding argument of
the snprintf()
has size_t type, sizeof(drvinfo.fw_version) is used as value of the
parameter.
Also the prototype does not provide a way to communicate that fw_length
is insufficient
to store firmware version. I'd suggest snprintf()-like return value. It
is pretty easy for PMD
to provide and convenient for the API function caller to handle.
> +{
> + struct rte_eth_dev *dev;
> +
> + RTE_ETH_VALID_PORTID_OR_RET(port_id);
> + dev = &rte_eth_devices[port_id];
> +
> + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->fw_version_get);
> + (*dev->dev_ops->fw_version_get)(dev, fw_version, fw_length);
> +}
> +
> +void
> rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> {
> struct rte_eth_dev *dev;
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index fb51754..2be31d2 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1150,6 +1150,10 @@ typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
> typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
> /**< @internal Check DD bit of specific RX descriptor */
>
> +typedef void (*eth_fw_version_get_t)(struct rte_eth_dev *dev,
> + char *fw_version, int fw_length);
> +/**< @internal Get firmware information of an Ethernet device. */
> +
> typedef void (*eth_rxq_info_get_t)(struct rte_eth_dev *dev,
> uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo);
>
> @@ -1455,6 +1459,7 @@ struct eth_dev_ops {
> eth_dev_infos_get_t dev_infos_get; /**< Get device info. */
> eth_rxq_info_get_t rxq_info_get; /**< retrieve RX queue information. */
> eth_txq_info_get_t txq_info_get; /**< retrieve TX queue information. */
> + eth_fw_version_get_t fw_version_get; /**< Get firmware version. */
> eth_dev_supported_ptypes_get_t dev_supported_ptypes_get;
> /**< Get packet types supported and identified by device. */
>
> @@ -2395,6 +2400,21 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
> void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
>
> /**
> + * Retrieve the firmware version of a device.
> + *
> + * @param port_id
> + * The port identifier of the device.
> + * @param fw_version
> + * A array pointer to store the firmware version of a device,
> + * allocated by caller.
> + * @param fw_length
> + * The size of the array pointed by fw_version, which should be
> + * large enough to store firmware version of the device.
> + */
> +void rte_eth_dev_fw_version_get(uint8_t port_id,
> + char *fw_version, int fw_length);
> +
> +/**
> * Retrieve the supported packet types of an Ethernet device.
> *
> * When a packet type is announced as supported, it *must* be recognized by
> diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
> index a021781..0cf94ed 100644
> --- a/lib/librte_ether/rte_ether_version.map
> +++ b/lib/librte_ether/rte_ether_version.map
> @@ -151,6 +151,7 @@ DPDK_17.02 {
> global:
>
> _rte_eth_dev_reset;
> + rte_eth_dev_fw_version_get;
> rte_flow_create;
> rte_flow_destroy;
> rte_flow_flush;
^ permalink raw reply
* Re: [PATCH v5 04/12] eal: integrate bus scan and probe with EAL
From: Rosen, Rami @ 2017-01-08 12:21 UTC (permalink / raw)
To: Shreyansh Jain, david.marchand@6wind.com
Cc: dev@dpdk.org, thomas.monjalon@6wind.com
In-Reply-To: <1482758645-23057-5-git-send-email-shreyansh.jain@nxp.com>
Hi,
...
...
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c index 2206277..2c223de 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
...
+/* Scan all the buses for registering devices */ int
+rte_eal_bus_scan(void)
+{
+ int ret;
+ struct rte_bus *bus = NULL;
+
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ ret = bus->scan(bus);
+ if (ret) {
+ RTE_LOG(ERR, EAL, "Scan for (%s) bus failed.\n",
+ bus->name);
+ /* TODO: Should error on a particular bus block scan
+ * for all others?
+ */
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
Nitpick - the return type of rte_eal_bus_scan() is int and not void:
* Scan all the buses attached to the framework.
+ *
+ * @param void
+ * @return void
+ */
+int rte_eal_bus_scan(void);
Rami Rosen
^ permalink raw reply
* Re: [PATCH v5 3/8] ethdev: reserve capability flags for PMD-specific API
From: Ananyev, Konstantin @ 2017-01-08 12:39 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: Bie, Tiwei, dev@dpdk.org, Lu, Wenzhuo, Mcnamara, John,
olivier.matz@6wind.com, thomas.monjalon@6wind.com, Zhang, Helin,
Dai, Wei, Wang, Xiao W
In-Reply-To: <20170105182141.GS12822@6wind.com>
Hi Adrien,
>
> Hi Konstantin,
>
> On Thu, Jan 05, 2017 at 11:32:38AM +0000, Ananyev, Konstantin wrote:
> > Hi Adrien,
> >
> > >
> > > On Thu, Jan 05, 2017 at 07:56:08AM +0800, Tiwei Bie wrote:
> > > > On Thu, Jan 05, 2017 at 01:44:18AM +0800, Ananyev, Konstantin wrote:
> > > > [...]
> > > > > > >
> > > > > > > I understand that.
> > > > > > > My question was: suppose user would like to create a bonded device over 2 NICs.
> > > > > > > One of them is ixgbe, while other would be some other type.
> > > > > > > In future get_dev_info() for each of them might return DEV_RX_OFFLOAD_RESERVED_0 bit as set.
> > > > > > > But it would mean completely different thing.
> > > > > > > How bonded device would know that to deal properly?
> > > > > > >
> > > > > > > Another example - user has 2 NICs of different type and would like to send the same packet on both of them simultaneously.
> > > > > > > As PKT_TX_RESERVED might mean different things for these devices, and user would like to use let say
> > > > > > > PKT_TX_IXGBE_MACSEC on one of them, he would need to do a copy of them, instead just increment a refcnt.
> > > > > > >
> > > > > > > Similar issues might arise at RX handling: user got a packet with PKT_RX_RESERVED_0 set.
> > > > > > > What does it really mean if there are different NIC types in the system?
> > > > > > > The only way to answer that question, as I can see, is to keep track from what NIC that packet was received.
> > > > > > > Which I suppose, is not always convenient.
> > > > > > >
> > > > > >
> > > > > > The main purpose is to put the PMD-specific APIs in a separate
> > > > > > namespace instead of mixing the PMD-specific APIs and global APIs
> > > > > > up, and also save the bits in mbuf.ol_flags.
> > > > > >
> > > > > > There are other ways to achieve this goal, such as introducing
> > > > > > the PMD specific ol_flags in mbuf second cache line as you said.
> > > > > > I just thought defining some reserved bits seems to be the most
> > > > > > simple way which won't introduce many changes.
> > > > > >
> > > > > > What's your suggestions? Should I just revert the changes and
> > > > > > define the generic flags directly?
> > > > >
> > > > > Yes, that would be my preference.
> > > > > As I said above - spending extra bit in ol_flags doesn't look like a big problem to me.
> > > > > In return there would be no need to consider how to handle all that confusing scenarios in future.
> > > >
> > > > Okay. I'll update my patches. Thanks a lot for your comments.
> > >
> > > Well, I do not agree with Konstantin (no one saw this coming eh?)
> >
> > :)
> >
> > >and do not think you need to update your series again.
> > >
> > > PMD-specific symbols have nothing to do in the global namespace in my
> > > opinion, they are not versioned and may evolve without notice. Neither
> > > applications nor the bonding PMD can rely on them. That's the trade-off.
> >
> > Not sure I do understand your reasoning.
> > For me MACSEC offload is just one of many HW offloads that we support
> > and should be treated in exactly the same way.
> > Applications should be able to use it in a transparent and reliable way,
> > not only under some limited conditions.
> > Otherwise what is the point to introduce it at all?
>
> Well my first reply to this thread was asking why isn't the whole API global
> from the start then?
That's good question, and my preference would always be to have the
API to configure this feature as generic one.
I guess the main reason why it is not right now we don't reach an agreement
how this API should look like:
http://dpdk.org/ml/archives/dev/2016-September/047810.html
But I'll leave it to the author to provide the real reason here.
>
> Given there are valid reasons for it not to and no plan to make it so in the
> near future, applications must be aware that they are including
> rte_pmd_ixgbe.h to use it. That in itself is a limiting condition, right?
Yes, it is definitely a limiting factor.
Though even if API to configure device to use macsec would be PMD specific right now,
The API to query that capability and the API to use it at datapath (mbuf.ol_flags) still
can be (and I think should be) device independent and transparent to use.
>
> > Yes, right now it is supported only by ixgbe PMD, but why that should be the
> > reason to treat is as second-class citizen?
> > Let say PKT_TX_TUNNEL_* offloads also are supported only by one PMD right now.
>
> You are right about PKT_TX_TUNNEL_*, however these flags exist on their own
> and are not tied to any API function calls, unlike in this series where
> PKT_TX_MACSEC can only be used if the DEV_TX_OFFLOAD_MACSEC_INSERT
> capability is present
I don't think PKT_TX_TUNNEL_* 'exists on its own'.
To use it well behaving app have to:
1) Query that device does provide that capability: DEV_TX_OFFLOAD_*_TNL_TSO
2) configure PMD( & device) to use that capability
3) use that offload at run-time TX code (mb->ol_flags |= ...; mb->tx_offload = ...)
For PKT_TX_TUNNEL_* 2) is pretty simple - user just need to make sure
that full-featured TX function will be selected:
txconf.txq_flags = 0; ...; rte_eth_tx_queue_setup(..., &txconf);
For TX_MACSEC, as I understand 2) will be more complicated and
right now is PMD specific, but anyway the main pattern remains the same.
So at least 1) and 3) could be kept device neutral.
>and the whole thing was configured through
> rte_pmd_ixgbe_macsec_*() calls after including rte_pmd_ixgbe.h.
>
> To be clear it is not about MACsec per se (as a standardized protocol, I
> think related definitions for offloads have their place), but it has to do
> with the fact that the rest of the API is PMD-specific and there is a
> dependency between them.
>
> > > Therefore until APIs are made global, the safe compromise is to define
> > > neutral, reserved symbols that any PMD can use to implement their own
> > > temporary APIs for testing purposes. These can be renamed later without
> > > changing their value as long as a single PMD uses them.
> >
> > Ok, so what we'll gain by introducing PKT_TX_RESERVED instead of PKT_TX_MACSEC?
> > As I said in my previous mail the redefinition for the same ol_flag bit (and dev capabilities)
> > by different PMD might create a lot of confusion in future.
> > Does the potential saving of 1 bit really worth it?
>
> That is one benefit, but my point is mainly to keep applications aware that
> they are using an API defined by a single PMD, which may be temporary and
> whose symbols are not versioned.
As applications have to use PMD specific functions to configure it they definitely are aware.
>
> Consider this:
>
> rte_mbuf.h:
>
> #define PKT_TX_RESERVED_0 (1 << 42)
>
> rte_pmd_ixgbe.h:
>
> #define PKT_TX_MACSEC PKT_TX_RESERVED_0
>
> That way, applications have to get the PKT_TX_MACSEC definition where the
> rest of the API is also defined.
>
> Other PMDs may reuse PKT_TX_RESERVED_0 and other reserved flags to implement
> their own experimental APIs.
That's the main thing I am opposed to.
I think that by allowing PMD to redefine meaning of
mbuf.ol_flags and dev_info.(rx| tx)_offload_capa
we just asking for trouble.
Let say tomorrow, i40e will redefine DEV_TX_OFFLOAD_RESERVED_0 and PKT_TX_RESERVED_0
to implement new specific TX offload (PKT_TX_FEATURE_X).
Now let say we have an application that works over both ixgbe and i40e
and would like to use both TX_MACSEC and TC_FEATURE_X offloads whenever they are available.
As I can see, with the approach you proposed the only way for the application to make it
is to support 2 different TX code paths (or at least some parts of it).
To me that way looks inconvenient to the users and source of future troubles.
Same for RX: somewhere at upper layer user got a packet with PKT_RX_RESERVED_0 set.
What does it really mean if there are different NIC types in the system?
>
> Applications and the bonding PMD can easily be made aware that such reserved
> flags cannot be shared between ports unless they know what the underlying
> PMD is, which is already a requirement to use this API in the first place
> (for instance, calling rte_pmd_ixgbe_macsec_*() functions with another
> vendor's port_id may crash the application).
I am talking about that code:
rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
{
...
/* Take the first dev's offload capabilities */
internals->rx_offload_capa = dev_info.rx_offload_capa;
internals->tx_offload_capa = dev_info.tx_offload_capa;
...
internals->rx_offload_capa &= dev_info.rx_offload_capa;
internals->tx_offload_capa &= dev_info.tx_offload_capa;
Obviously with what you are suggesting it is not valid any more.
Bonded device need to support a MASK of all device reserved offloads to exclude
them from common subset.
Any user app(/lib) that does similar thing would also have to be changed.
>
> So the idea if/when the API is made global is to rename PKT_TX_RESERVED_0 to
> PKT_TX_MACSEC and keep its original value.
>
> If other PMDs also implemented PKT_TX_RESERVED_0 in the meantime, it is
> redefined using a different value. If there is no room left to do so, these
> PMDs are out of luck I guess, and their specific API is disabled/removed
> until something gets re-designed.
>
> How about this?
I still think that we shouldn't allow PMDs to redefine mbuf.olflags and
dev_info.(rx|tx)_offload_capa.
See above for my reasons.
Konstantin
^ permalink raw reply
* Port stats zero when using MLX5 DPDK driver
From: george.dit @ 2017-01-08 13:38 UTC (permalink / raw)
To: dev
Hi,
I have a simple setup with a machine that contains a dual port 10 GbE Intel
82599ES NIC and another dual port 100 GbE Mellanox ConnectX-4 NIC. The
Intel ports are 0 and 1, while the Mellanox ones are 2 and 3.
I properly compiled DPDK 16.11 and test-pmd works just fine for all 4 ports.
Then, I ran a simple primary application that forwards packets from 0 <-->
1 and 2 <--> 3 and started dpdk-procinfo -- --stats (or --xstats) as a
secondary monitoring process, while sending some traffic to all 4 ports.
The problem I see is that the statistics reported by the Mellanox NICs are
always zero (Intel ports report just fine).
What is the reason behind this behavior? Is there a bug in the driver
(maybe recently fixed by DPDK 17.02 rc?) or is it simply a lack of this
functionality?
Thanks and best regards,
--
Georgios Katsikas
Ph.D. Student and Research Assistant
Network Systems Lab (NSL)
*E-Mail:* george <george.katsikas@imdea.org>.dit@gmail.com
*Web Site:* http://www.di.uoa.gr/~katsikas/
<http://people.networks.imdea.org/~george_katsikas/index.html>
^ permalink raw reply
* Re: A question
From: Zhang, Helin @ 2017-01-08 15:17 UTC (permalink / raw)
To: kamiar kanani; +Cc: dev@dpdk.org
In-Reply-To: <CAKp2q1dY_oQ2Moi02TNZkd6c11vBxsRdadN0CBkOaeb=fNELig@mail.gmail.com>
Hi Kanani
Within around one year, we have implemented input set to reconfigure some registers to select which field to be used for hash calculation.
So I think it should work quite better now with using X710 or XL710. What’s your issue here?
Could you help to have a try and tell me the real issue in your side? Hopefully I can help a little bit.
Regards,
Helin
From: kamiar kanani [mailto:kamiar.kanani@gmail.com]
Sent: Sunday, January 8, 2017 8:04 PM
To: Zhang, Helin <helin.zhang@intel.com>
Subject: A question
Hi Helin
I read a post from you in one of the DPDK mailing list about a problem with XL710 symmetric RSS configuration.
the problem states limitation in the XL710's capability of redirecting fragmented packets. the link is:
http://dpdk.org/ml/archives/dev/2015-July/022453.html
I searched through internet but I didn't find any thing better. It would be a great help to me if you could
give me any hint about what can be done for the problem, if there is any update.
thanks a lot
^ permalink raw reply
* [PATCH 1/5] net/mlx5: last WQE no room inline
From: Elad Persiko @ 2017-01-08 15:41 UTC (permalink / raw)
To: dev; +Cc: Elad Persiko
Prior to this patch, when sending a packet and the following
conditions were reached:
1. last working queue element is used.
2. inline was requested by the user
3. no room for inline packet.
then the inline request was ignored and the packet was sent
by pointer completely.
This patch handles this scenario. In this case the last
work queue element is turned to be a null work queue element and
the packet is being sent after the wrap around.
Signed-off-by: Elad Persiko <eladpe@mellanox.com>
---
drivers/net/mlx5/mlx5_rxtx.c | 12 ++++++++++++
drivers/net/mlx5/mlx5_txq.c | 8 ++++++--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index e0ee2f2..be38aed 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -481,6 +481,17 @@
pkt_inline_sz += copy_b;
/* Sanity check. */
assert(addr <= addr_end);
+ } else {
+ wqe->ctrl = (rte_v128u32_t){
+ htonl(txq->wqe_ci << 8),
+ htonl(txq->qp_num_8s | 1),
+ 0,
+ 0,
+ };
+ length = 0;
+ buf = *(pkts--);
+ ds = 1;
+ goto next_pkt_part;
}
/*
* 2 DWORDs consumed by the WQE header + ETH segment +
@@ -577,6 +588,7 @@
0,
0,
};
+next_pkt_part:
wqe->eseg = (rte_v128u32_t){
0,
cs_flags,
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 949035b..951e50a 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -314,8 +314,12 @@
/* CQ to be associated with the receive queue. */
.recv_cq = tmpl.cq,
.cap = {
- /* Max number of outstanding WRs. */
- .max_send_wr = ((priv->device_attr.max_qp_wr < desc) ?
+ /*
+ * Max number of outstanding WRs.
+ * "+1" for null WQE place holder.
+ */
+ .max_send_wr = ((priv->device_attr.max_qp_wr <
+ (desc + 1)) ?
priv->device_attr.max_qp_wr :
desc),
/*
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/5] net/mlx5: remove unessecary goto label
From: Elad Persiko @ 2017-01-08 15:42 UTC (permalink / raw)
To: dev; +Cc: Elad Persiko
In-Reply-To: <1483890123-4854-1-git-send-email-eladpe@mellanox.com>
use_dseg label can be deleted as it happens without goto.
Signed-off-by: Elad Persiko <eladpe@mellanox.com>
---
drivers/net/mlx5/mlx5_rxtx.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index be38aed..1560530 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -505,7 +505,6 @@
if ((uintptr_t)dseg >= end)
dseg = (volatile rte_v128u32_t *)
txq->wqes;
- goto use_dseg;
} else if (!segs_n) {
goto next_pkt;
} else {
@@ -523,19 +522,18 @@
dseg = (volatile rte_v128u32_t *)
((uintptr_t)wqe + (3 * MLX5_WQE_DWORD_SIZE));
ds = 3;
-use_dseg:
- /* Add the remaining packet as a simple ds. */
- addr = htonll(addr);
- *dseg = (rte_v128u32_t){
- htonl(length),
- txq_mp2mr(txq, txq_mb2mp(buf)),
- addr,
- addr >> 32,
- };
- ++ds;
- if (!segs_n)
- goto next_pkt;
}
+ /* Add the remaining packet as a simple ds. */
+ addr = htonll(addr);
+ *dseg = (rte_v128u32_t){
+ htonl(length),
+ txq_mp2mr(txq, txq_mb2mp(buf)),
+ addr,
+ addr >> 32,
+ };
+ ++ds;
+ if (!segs_n)
+ goto next_pkt;
next_seg:
assert(buf);
assert(ds);
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox