* [dpdk-dev] [PATCH v1 1/8] net/mlx5: remove dv dependency in mlx5_dev_ctx_shared struct
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 2/8] net/mlx5: rename ib in names Ophir Munk
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
Replace 'struct mlx5dv_devx_cmd_comp *' with 'void *' in 'struct
mlx5_dev_ctx_shared'.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/linux/mlx5_os.c | 12 +++++++-----
drivers/net/mlx5/mlx5.h | 2 +-
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 92422db..21eff38 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1944,19 +1944,21 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh)
if (sh->devx) {
#ifdef HAVE_IBV_DEVX_ASYNC
sh->intr_handle_devx.fd = -1;
- sh->devx_comp = mlx5_glue->devx_create_cmd_comp(sh->ctx);
- if (!sh->devx_comp) {
+ sh->devx_comp =
+ (void *)mlx5_glue->devx_create_cmd_comp(sh->ctx);
+ struct mlx5dv_devx_cmd_comp *devx_comp = sh->devx_comp;
+ if (!devx_comp) {
DRV_LOG(INFO, "failed to allocate devx_comp.");
return;
}
- flags = fcntl(sh->devx_comp->fd, F_GETFL);
- ret = fcntl(sh->devx_comp->fd, F_SETFL, flags | O_NONBLOCK);
+ flags = fcntl(devx_comp->fd, F_GETFL);
+ ret = fcntl(devx_comp->fd, F_SETFL, flags | O_NONBLOCK);
if (ret) {
DRV_LOG(INFO, "failed to change file descriptor"
" devx comp");
return;
}
- sh->intr_handle_devx.fd = sh->devx_comp->fd;
+ sh->intr_handle_devx.fd = devx_comp->fd;
sh->intr_handle_devx.type = RTE_INTR_HANDLE_EXT;
if (rte_intr_callback_register(&sh->intr_handle_devx,
mlx5_dev_interrupt_handler_devx, sh)) {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 8c4b234..d624740 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -567,7 +567,7 @@ struct mlx5_dev_ctx_shared {
/* Shared interrupt handler section. */
struct rte_intr_handle intr_handle; /* Interrupt handler for device. */
struct rte_intr_handle intr_handle_devx; /* DEVX interrupt handler. */
- struct mlx5dv_devx_cmd_comp *devx_comp; /* DEVX async comp obj. */
+ void *devx_comp; /* DEVX async comp obj. */
struct mlx5_devx_obj *tis; /* TIS object. */
struct mlx5_devx_obj *td; /* Transport domain. */
struct mlx5_flow_id_pool *flow_id_pool; /* Flow ID pool. */
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 2/8] net/mlx5: rename ib in names
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 1/8] net/mlx5: remove dv dependency in mlx5_dev_ctx_shared struct Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 3/8] net/mlx5: move socket files under Linux directory Ophir Munk
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
Renames in this commit:
mlx5_ibv_list -> mlx5_dev_ctx_list
mlx5_alloc_shared_ibctx -> mlx5_alloc_shared_dev_ctx
mlx5_free_shared_ibctx -> mlx5_free_shared_dev_ctx
mlx5_ibv_shared_port -> mlx5_dev_shared_port
ibv_port -> dev_port
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/linux/mlx5_os.c | 6 +++---
drivers/net/mlx5/mlx5.c | 41 +++++++++++++++++++-------------------
drivers/net/mlx5/mlx5.h | 14 ++++++-------
drivers/net/mlx5/mlx5_flow.c | 2 +-
drivers/net/mlx5/mlx5_flow_dv.c | 4 ++--
drivers/net/mlx5/mlx5_flow_verbs.c | 2 +-
drivers/net/mlx5/mlx5_rxtx.c | 2 +-
drivers/net/mlx5/mlx5_stats.c | 2 +-
drivers/net/mlx5/mlx5_trigger.c | 8 ++++----
drivers/net/mlx5/mlx5_txq.c | 2 +-
10 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 21eff38..abe9b04 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -563,7 +563,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
strerror(rte_errno));
goto error;
}
- sh = mlx5_alloc_shared_ibctx(spawn, &config);
+ sh = mlx5_alloc_shared_dev_ctx(spawn, &config);
if (!sh)
return NULL;
config.devx = sh->devx;
@@ -693,7 +693,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
goto error;
}
priv->sh = sh;
- priv->ibv_port = spawn->phys_port;
+ priv->dev_port = spawn->phys_port;
priv->pci_dev = spawn->pci_dev;
priv->mtu = RTE_ETHER_MTU;
priv->mp_id.port_id = port_id;
@@ -1188,7 +1188,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
rte_eth_dev_release_port(eth_dev);
}
if (sh)
- mlx5_free_shared_ibctx(sh);
+ mlx5_free_shared_dev_ctx(sh);
MLX5_ASSERT(err > 0);
rte_errno = err;
return NULL;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 7c5e23d..f07386d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -176,8 +176,9 @@ static struct mlx5_local_data mlx5_local_data;
/** Driver-specific log messages type. */
int mlx5_logtype;
-static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_ibv_list = LIST_HEAD_INITIALIZER();
-static pthread_mutex_t mlx5_ibv_list_mutex = PTHREAD_MUTEX_INITIALIZER;
+static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list =
+ LIST_HEAD_INITIALIZER();
+static pthread_mutex_t mlx5_dev_ctx_list_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
@@ -579,18 +580,18 @@ mlx5_flow_ipool_destroy(struct mlx5_dev_ctx_shared *sh)
}
/**
- * Allocate shared IB device context. If there is multiport device the
+ * Allocate shared device context. If there is multiport device the
* master and representors will share this context, if there is single
- * port dedicated IB device, the context will be used by only given
+ * port dedicated device, the context will be used by only given
* port due to unification.
*
- * Routine first searches the context for the specified IB device name,
+ * Routine first searches the context for the specified device name,
* if found the shared context assumed and reference counter is incremented.
* If no context found the new one is created and initialized with specified
- * IB device context and parameters.
+ * device context and parameters.
*
* @param[in] spawn
- * Pointer to the IB device attributes (name, port, etc).
+ * Pointer to the device attributes (name, port, etc).
* @param[in] config
* Pointer to device configuration structure.
*
@@ -599,8 +600,8 @@ mlx5_flow_ipool_destroy(struct mlx5_dev_ctx_shared *sh)
* otherwise NULL and rte_errno is set.
*/
struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
- const struct mlx5_dev_config *config)
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+ const struct mlx5_dev_config *config)
{
struct mlx5_dev_ctx_shared *sh;
int err = 0;
@@ -610,9 +611,9 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
MLX5_ASSERT(spawn);
/* Secondary process should not create the shared context. */
MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
- pthread_mutex_lock(&mlx5_ibv_list_mutex);
+ pthread_mutex_lock(&mlx5_dev_ctx_list_mutex);
/* Search for IB context by device name. */
- LIST_FOREACH(sh, &mlx5_ibv_list, next) {
+ LIST_FOREACH(sh, &mlx5_dev_ctx_list, next) {
if (!strcmp(sh->ibdev_name,
mlx5_os_get_dev_device_name(spawn->phys_dev))) {
sh->refcnt++;
@@ -624,7 +625,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
sh = rte_zmalloc("ethdev shared ib context",
sizeof(struct mlx5_dev_ctx_shared) +
spawn->max_port *
- sizeof(struct mlx5_ibv_shared_port),
+ sizeof(struct mlx5_dev_shared_port),
RTE_CACHE_LINE_SIZE);
if (!sh) {
DRV_LOG(ERR, "shared context allocation failure");
@@ -713,12 +714,12 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
sh, mem_event_cb);
rte_rwlock_write_unlock(&mlx5_shared_data->mem_event_rwlock);
/* Add context to the global device list. */
- LIST_INSERT_HEAD(&mlx5_ibv_list, sh, next);
+ LIST_INSERT_HEAD(&mlx5_dev_ctx_list, sh, next);
exit:
- pthread_mutex_unlock(&mlx5_ibv_list_mutex);
+ pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
return sh;
error:
- pthread_mutex_unlock(&mlx5_ibv_list_mutex);
+ pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
MLX5_ASSERT(sh);
if (sh->tis)
claim_zero(mlx5_devx_cmd_destroy(sh->tis));
@@ -744,14 +745,14 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
* Pointer to mlx5_dev_ctx_shared object to free
*/
void
-mlx5_free_shared_ibctx(struct mlx5_dev_ctx_shared *sh)
+mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)
{
- pthread_mutex_lock(&mlx5_ibv_list_mutex);
+ pthread_mutex_lock(&mlx5_dev_ctx_list_mutex);
#ifdef RTE_LIBRTE_MLX5_DEBUG
/* Check the object presence in the list. */
struct mlx5_dev_ctx_shared *lctx;
- LIST_FOREACH(lctx, &mlx5_ibv_list, next)
+ LIST_FOREACH(lctx, &mlx5_dev_ctx_list, next)
if (lctx == sh)
break;
MLX5_ASSERT(lctx);
@@ -793,7 +794,7 @@ mlx5_free_shared_ibctx(struct mlx5_dev_ctx_shared *sh)
mlx5_flow_id_pool_release(sh->flow_id_pool);
rte_free(sh);
exit:
- pthread_mutex_unlock(&mlx5_ibv_list_mutex);
+ pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
}
/**
@@ -1193,7 +1194,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
* mlx5_nl_mac_addr_flush() uses ibdev_path for retrieveing
* ifindex if Netlink fails.
*/
- mlx5_free_shared_ibctx(priv->sh);
+ mlx5_free_shared_dev_ctx(priv->sh);
if (priv->domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
unsigned int c = 0;
uint16_t port_id;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index d624740..abe5099 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -446,7 +446,7 @@ struct mlx5_flow_counter_mng {
#define MLX5_AGE_GET(age_info, BIT) \
((age_info)->flags & (1 << (BIT)))
#define GET_PORT_AGE_INFO(priv) \
- (&((priv)->sh->port[(priv)->ibv_port - 1].age_info))
+ (&((priv)->sh->port[(priv)->dev_port - 1].age_info))
/* Aging information for per port. */
struct mlx5_age_info {
@@ -456,7 +456,7 @@ struct mlx5_age_info {
};
/* Per port data of shared IB device. */
-struct mlx5_ibv_shared_port {
+struct mlx5_dev_shared_port {
uint32_t ih_port_id;
uint32_t devx_ih_port_id;
/*
@@ -571,7 +571,7 @@ struct mlx5_dev_ctx_shared {
struct mlx5_devx_obj *tis; /* TIS object. */
struct mlx5_devx_obj *td; /* Transport domain. */
struct mlx5_flow_id_pool *flow_id_pool; /* Flow ID pool. */
- struct mlx5_ibv_shared_port port[]; /* per device port data array. */
+ struct mlx5_dev_shared_port port[]; /* per device port data array. */
};
/* Per-process private structure. */
@@ -593,7 +593,7 @@ TAILQ_HEAD(mlx5_flow_meters, mlx5_flow_meter);
struct mlx5_priv {
struct rte_eth_dev_data *dev_data; /* Pointer to device data. */
struct mlx5_dev_ctx_shared *sh; /* Shared device context. */
- uint32_t ibv_port; /* IB device port number. */
+ uint32_t dev_port; /* Device port number. */
struct rte_pci_device *pci_dev; /* Backend PCI device. */
struct rte_ether_addr mac[MLX5_MAX_MAC_ADDRESSES]; /* MAC addresses. */
BITFIELD_DECLARE(mac_own, uint64_t, MLX5_MAX_MAC_ADDRESSES);
@@ -697,9 +697,9 @@ void mlx5_dev_close(struct rte_eth_dev *dev);
port_id = mlx5_eth_find_next(port_id + 1, pci_dev))
int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn,
- const struct mlx5_dev_config *config);
-void mlx5_free_shared_ibctx(struct mlx5_dev_ctx_shared *sh);
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+ const struct mlx5_dev_config *config);
+void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
void mlx5_free_table_hash_list(struct mlx5_priv *priv);
int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index e375b10..0e0b0fb 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -509,7 +509,7 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
} flow_attr = {
.attr = {
.num_of_specs = 2,
- .port = (uint8_t)priv->ibv_port,
+ .port = (uint8_t)priv->dev_port,
},
.eth = {
.type = IBV_FLOW_SPEC_ETH,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 81f5bd4..a323356 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2725,7 +2725,7 @@ flow_dv_port_id_action_resource_register
*cache_resource = *resource;
/*
* Depending on rdma_core version the glue routine calls
- * either mlx5dv_dr_action_create_dest_ib_port(domain, ibv_port)
+ * either mlx5dv_dr_action_create_dest_ib_port(domain, dev_port)
* or mlx5dv_dr_action_create_dest_vport(domain, vport_id).
*/
cache_resource->action =
@@ -7557,7 +7557,7 @@ flow_dv_translate_action_port_id(struct rte_eth_dev *dev,
* This parameter is transferred to
* mlx5dv_dr_action_create_dest_ib_port().
*/
- *dst_port_id = priv->ibv_port;
+ *dst_port_id = priv->dev_port;
#else
/*
* Legacy mode, no LAG configurations is supported.
diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c
index c266e56..150f6bb 100644
--- a/drivers/net/mlx5/mlx5_flow_verbs.c
+++ b/drivers/net/mlx5/mlx5_flow_verbs.c
@@ -1755,7 +1755,7 @@ flow_verbs_translate(struct rte_eth_dev *dev,
/* Other members of attr will be ignored. */
dev_flow->verbs.attr.priority =
mlx5_flow_adjust_priority(dev, priority, subpriority);
- dev_flow->verbs.attr.port = (uint8_t)priv->ibv_port;
+ dev_flow->verbs.attr.port = (uint8_t)priv->dev_port;
return 0;
}
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index 6a17a9a..22cdf15 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -946,7 +946,7 @@ mlx5_queue_state_modify_primary(struct rte_eth_dev *dev,
container_of(txq, struct mlx5_txq_ctrl, txq);
struct ibv_qp_attr mod = {
.qp_state = IBV_QPS_RESET,
- .port_num = (uint8_t)priv->ibv_port,
+ .port_num = (uint8_t)priv->dev_port,
};
struct ibv_qp *qp = txq_ctrl->obj->qp;
diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
index b4ca692..7999c5f 100644
--- a/drivers/net/mlx5/mlx5_stats.c
+++ b/drivers/net/mlx5/mlx5_stats.c
@@ -149,7 +149,7 @@ mlx5_read_ib_stat(struct mlx5_priv *priv, const char *ctr_name, uint64_t *stat)
if (priv->sh) {
MKSTR(path, "%s/ports/%d/hw_counters/%s",
priv->sh->ibdev_path,
- priv->ibv_port,
+ priv->dev_port,
ctr_name);
fd = open(path, O_RDONLY);
if (fd != -1) {
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index f123193..a9af2e6 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -342,7 +342,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
/* Enable datapath on secondary process. */
mlx5_mp_req_start_rxtx(dev);
if (priv->sh->intr_handle.fd >= 0) {
- priv->sh->port[priv->ibv_port - 1].ih_port_id =
+ priv->sh->port[priv->dev_port - 1].ih_port_id =
(uint32_t)dev->data->port_id;
} else {
DRV_LOG(INFO, "port %u starts without LSC and RMV interrupts.",
@@ -351,7 +351,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
dev->data->dev_conf.intr_conf.rmv = 0;
}
if (priv->sh->intr_handle_devx.fd >= 0)
- priv->sh->port[priv->ibv_port - 1].devx_ih_port_id =
+ priv->sh->port[priv->dev_port - 1].devx_ih_port_id =
(uint32_t)dev->data->port_id;
return 0;
error:
@@ -394,8 +394,8 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
/* All RX queue flags will be cleared in the flush interface. */
mlx5_flow_list_flush(dev, &priv->flows, true);
mlx5_rx_intr_vec_disable(dev);
- priv->sh->port[priv->ibv_port - 1].ih_port_id = RTE_MAX_ETHPORTS;
- priv->sh->port[priv->ibv_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS;
+ priv->sh->port[priv->dev_port - 1].ih_port_id = RTE_MAX_ETHPORTS;
+ priv->sh->port[priv->dev_port - 1].devx_ih_port_id = RTE_MAX_ETHPORTS;
mlx5_txq_stop(dev);
mlx5_rxq_stop(dev);
}
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index f7b548f..507febf 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -684,7 +684,7 @@ mlx5_txq_obj_new(struct rte_eth_dev *dev, uint16_t idx,
/* Move the QP to this state. */
.qp_state = IBV_QPS_INIT,
/* IB device port number. */
- .port_num = (uint8_t)priv->ibv_port,
+ .port_num = (uint8_t)priv->dev_port,
};
ret = mlx5_glue->modify_qp(tmpl.qp, &attr.mod,
(IBV_QP_STATE | IBV_QP_PORT));
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 3/8] net/mlx5: move socket files under Linux directory
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 1/8] net/mlx5: remove dv dependency in mlx5_dev_ctx_shared struct Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 2/8] net/mlx5: rename ib in names Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 4/8] net/mlx5: split mlx5 ethdev " Ophir Munk
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
mlx5_socket.c file is using APIs which are Linux specifics. Therefore
move it (including mlx5_socket.h) from net/mlx5 directory to
net/mlx5/linux directory. This commit also updates the Makefile and
the meson files.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/Makefile | 2 +-
drivers/net/mlx5/linux/meson.build | 1 +
drivers/net/mlx5/linux/mlx5_socket.c | 230 +++++++++++++++++++++++++++++++++++
drivers/net/mlx5/meson.build | 1 -
drivers/net/mlx5/mlx5_socket.c | 230 -----------------------------------
5 files changed, 232 insertions(+), 232 deletions(-)
create mode 100644 drivers/net/mlx5/linux/mlx5_socket.c
delete mode 100644 drivers/net/mlx5/mlx5_socket.c
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index 41ab73e..84fc9cc 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -31,7 +31,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_dv.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_verbs.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mp.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_utils.c
-SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_socket.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_os.c
# Basic CFLAGS.
diff --git a/drivers/net/mlx5/linux/meson.build b/drivers/net/mlx5/linux/meson.build
index 2ea0792..f8369cc 100644
--- a/drivers/net/mlx5/linux/meson.build
+++ b/drivers/net/mlx5/linux/meson.build
@@ -3,6 +3,7 @@
includes += include_directories('.')
sources += files(
+ 'mlx5_socket.c',
'mlx5_os.c',
)
diff --git a/drivers/net/mlx5/linux/mlx5_socket.c b/drivers/net/mlx5/linux/mlx5_socket.c
new file mode 100644
index 0000000..08af905
--- /dev/null
+++ b/drivers/net/mlx5/linux/mlx5_socket.c
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2019 Mellanox Technologies, Ltd
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "rte_eal.h"
+#include "mlx5_utils.h"
+#include "mlx5.h"
+
+/* PMD socket service for tools. */
+
+int server_socket; /* Unix socket for primary process. */
+struct rte_intr_handle server_intr_handle; /* Interrupt handler. */
+
+static void
+mlx5_pmd_make_path(struct sockaddr_un *addr, int pid)
+{
+ snprintf(addr->sun_path, sizeof(addr->sun_path), "/var/tmp/dpdk_%s_%d",
+ MLX5_DRIVER_NAME, pid);
+}
+
+/**
+ * Handle server pmd socket interrupts.
+ */
+static void
+mlx5_pmd_socket_handle(void *cb __rte_unused)
+{
+ int conn_sock;
+ int ret;
+ struct cmsghdr *cmsg = NULL;
+ int data;
+ char buf[CMSG_SPACE(sizeof(int))] = { 0 };
+ struct iovec io = {
+ .iov_base = &data,
+ .iov_len = sizeof(data),
+ };
+ struct msghdr msg = {
+ .msg_iov = &io,
+ .msg_iovlen = 1,
+ .msg_control = buf,
+ .msg_controllen = sizeof(buf),
+ };
+ uint16_t port_id;
+ int fd;
+ FILE *file = NULL;
+ struct rte_eth_dev *dev;
+
+ /* Accept the connection from the client. */
+ conn_sock = accept(server_socket, NULL, NULL);
+ if (conn_sock < 0) {
+ DRV_LOG(WARNING, "connection failed: %s", strerror(errno));
+ return;
+ }
+ ret = recvmsg(conn_sock, &msg, MSG_WAITALL);
+ if (ret < 0) {
+ DRV_LOG(WARNING, "wrong message received: %s",
+ strerror(errno));
+ goto error;
+ }
+ /* Receive file descriptor. */
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS ||
+ cmsg->cmsg_len < sizeof(int)) {
+ DRV_LOG(WARNING, "invalid file descriptor message");
+ goto error;
+ }
+ memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
+ file = fdopen(fd, "w");
+ if (!file) {
+ DRV_LOG(WARNING, "Failed to open file");
+ goto error;
+ }
+ /* Receive port number. */
+ if (msg.msg_iovlen != 1 || msg.msg_iov->iov_len < sizeof(uint16_t)) {
+ DRV_LOG(WARNING, "wrong port number message");
+ goto error;
+ }
+ memcpy(&port_id, msg.msg_iov->iov_base, sizeof(port_id));
+ if (!rte_eth_dev_is_valid_port(port_id)) {
+ DRV_LOG(WARNING, "Invalid port %u", port_id);
+ goto error;
+ }
+ /* Dump flow. */
+ dev = &rte_eth_devices[port_id];
+ ret = mlx5_flow_dev_dump(dev, file, NULL);
+ /* Set-up the ancillary data and reply. */
+ msg.msg_controllen = 0;
+ msg.msg_control = NULL;
+ msg.msg_iovlen = 1;
+ msg.msg_iov = &io;
+ data = -ret;
+ io.iov_len = sizeof(data);
+ io.iov_base = &data;
+ do {
+ ret = sendmsg(conn_sock, &msg, 0);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0)
+ DRV_LOG(WARNING, "failed to send response %s",
+ strerror(errno));
+error:
+ if (conn_sock >= 0)
+ close(conn_sock);
+ if (file)
+ fclose(file);
+}
+
+/**
+ * Install interrupt handler.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @return
+ * 0 on success, a negative errno value otherwise.
+ */
+static int
+mlx5_pmd_interrupt_handler_install(void)
+{
+ MLX5_ASSERT(server_socket);
+ server_intr_handle.fd = server_socket;
+ server_intr_handle.type = RTE_INTR_HANDLE_EXT;
+ return rte_intr_callback_register(&server_intr_handle,
+ mlx5_pmd_socket_handle, NULL);
+}
+
+/**
+ * Uninstall interrupt handler.
+ */
+static void
+mlx5_pmd_interrupt_handler_uninstall(void)
+{
+ if (server_socket) {
+ mlx5_intr_callback_unregister(&server_intr_handle,
+ mlx5_pmd_socket_handle,
+ NULL);
+ }
+ server_intr_handle.fd = 0;
+ server_intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
+}
+
+/**
+ * Initialise the socket to communicate with the secondary process
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ *
+ * @return
+ * 0 on success, a negative value otherwise.
+ */
+int
+mlx5_pmd_socket_init(void)
+{
+ struct sockaddr_un sun = {
+ .sun_family = AF_UNIX,
+ };
+ int ret;
+ int flags;
+
+ MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
+ if (server_socket)
+ return 0;
+ /*
+ * Initialize the socket to communicate with the secondary
+ * process.
+ */
+ ret = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ret < 0) {
+ DRV_LOG(WARNING, "Failed to open mlx5 socket: %s",
+ strerror(errno));
+ goto error;
+ }
+ server_socket = ret;
+ flags = fcntl(server_socket, F_GETFL, 0);
+ if (flags == -1)
+ goto error;
+ ret = fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
+ if (ret < 0)
+ goto error;
+ mlx5_pmd_make_path(&sun, getpid());
+ remove(sun.sun_path);
+ ret = bind(server_socket, (const struct sockaddr *)&sun, sizeof(sun));
+ if (ret < 0) {
+ DRV_LOG(WARNING,
+ "cannot bind mlx5 socket: %s", strerror(errno));
+ goto close;
+ }
+ ret = listen(server_socket, 0);
+ if (ret < 0) {
+ DRV_LOG(WARNING, "cannot listen on mlx5 socket: %s",
+ strerror(errno));
+ goto close;
+ }
+ if (mlx5_pmd_interrupt_handler_install()) {
+ DRV_LOG(WARNING, "cannot register interrupt handler for mlx5 socket: %s",
+ strerror(errno));
+ goto close;
+ }
+ return 0;
+close:
+ remove(sun.sun_path);
+error:
+ claim_zero(close(server_socket));
+ server_socket = 0;
+ DRV_LOG(ERR, "Cannot initialize socket: %s", strerror(errno));
+ return -errno;
+}
+
+/**
+ * Un-Initialize the pmd socket
+ */
+RTE_FINI(mlx5_pmd_socket_uninit)
+{
+ if (!server_socket)
+ return;
+ mlx5_pmd_interrupt_handler_uninstall();
+ claim_zero(close(server_socket));
+ server_socket = 0;
+ MKSTR(path, "/var/tmp/dpdk_%s_%d", MLX5_DRIVER_NAME, getpid());
+ claim_zero(remove(path));
+}
diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build
index e71b2c5..e95ce02 100644
--- a/drivers/net/mlx5/meson.build
+++ b/drivers/net/mlx5/meson.build
@@ -28,7 +28,6 @@ sources = files(
'mlx5_txq.c',
'mlx5_vlan.c',
'mlx5_utils.c',
- 'mlx5_socket.c',
)
if (dpdk_conf.has('RTE_ARCH_X86_64')
or dpdk_conf.has('RTE_ARCH_ARM64')
diff --git a/drivers/net/mlx5/mlx5_socket.c b/drivers/net/mlx5/mlx5_socket.c
deleted file mode 100644
index 08af905..0000000
--- a/drivers/net/mlx5/mlx5_socket.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright 2019 Mellanox Technologies, Ltd
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "rte_eal.h"
-#include "mlx5_utils.h"
-#include "mlx5.h"
-
-/* PMD socket service for tools. */
-
-int server_socket; /* Unix socket for primary process. */
-struct rte_intr_handle server_intr_handle; /* Interrupt handler. */
-
-static void
-mlx5_pmd_make_path(struct sockaddr_un *addr, int pid)
-{
- snprintf(addr->sun_path, sizeof(addr->sun_path), "/var/tmp/dpdk_%s_%d",
- MLX5_DRIVER_NAME, pid);
-}
-
-/**
- * Handle server pmd socket interrupts.
- */
-static void
-mlx5_pmd_socket_handle(void *cb __rte_unused)
-{
- int conn_sock;
- int ret;
- struct cmsghdr *cmsg = NULL;
- int data;
- char buf[CMSG_SPACE(sizeof(int))] = { 0 };
- struct iovec io = {
- .iov_base = &data,
- .iov_len = sizeof(data),
- };
- struct msghdr msg = {
- .msg_iov = &io,
- .msg_iovlen = 1,
- .msg_control = buf,
- .msg_controllen = sizeof(buf),
- };
- uint16_t port_id;
- int fd;
- FILE *file = NULL;
- struct rte_eth_dev *dev;
-
- /* Accept the connection from the client. */
- conn_sock = accept(server_socket, NULL, NULL);
- if (conn_sock < 0) {
- DRV_LOG(WARNING, "connection failed: %s", strerror(errno));
- return;
- }
- ret = recvmsg(conn_sock, &msg, MSG_WAITALL);
- if (ret < 0) {
- DRV_LOG(WARNING, "wrong message received: %s",
- strerror(errno));
- goto error;
- }
- /* Receive file descriptor. */
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS ||
- cmsg->cmsg_len < sizeof(int)) {
- DRV_LOG(WARNING, "invalid file descriptor message");
- goto error;
- }
- memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
- file = fdopen(fd, "w");
- if (!file) {
- DRV_LOG(WARNING, "Failed to open file");
- goto error;
- }
- /* Receive port number. */
- if (msg.msg_iovlen != 1 || msg.msg_iov->iov_len < sizeof(uint16_t)) {
- DRV_LOG(WARNING, "wrong port number message");
- goto error;
- }
- memcpy(&port_id, msg.msg_iov->iov_base, sizeof(port_id));
- if (!rte_eth_dev_is_valid_port(port_id)) {
- DRV_LOG(WARNING, "Invalid port %u", port_id);
- goto error;
- }
- /* Dump flow. */
- dev = &rte_eth_devices[port_id];
- ret = mlx5_flow_dev_dump(dev, file, NULL);
- /* Set-up the ancillary data and reply. */
- msg.msg_controllen = 0;
- msg.msg_control = NULL;
- msg.msg_iovlen = 1;
- msg.msg_iov = &io;
- data = -ret;
- io.iov_len = sizeof(data);
- io.iov_base = &data;
- do {
- ret = sendmsg(conn_sock, &msg, 0);
- } while (ret < 0 && errno == EINTR);
- if (ret < 0)
- DRV_LOG(WARNING, "failed to send response %s",
- strerror(errno));
-error:
- if (conn_sock >= 0)
- close(conn_sock);
- if (file)
- fclose(file);
-}
-
-/**
- * Install interrupt handler.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @return
- * 0 on success, a negative errno value otherwise.
- */
-static int
-mlx5_pmd_interrupt_handler_install(void)
-{
- MLX5_ASSERT(server_socket);
- server_intr_handle.fd = server_socket;
- server_intr_handle.type = RTE_INTR_HANDLE_EXT;
- return rte_intr_callback_register(&server_intr_handle,
- mlx5_pmd_socket_handle, NULL);
-}
-
-/**
- * Uninstall interrupt handler.
- */
-static void
-mlx5_pmd_interrupt_handler_uninstall(void)
-{
- if (server_socket) {
- mlx5_intr_callback_unregister(&server_intr_handle,
- mlx5_pmd_socket_handle,
- NULL);
- }
- server_intr_handle.fd = 0;
- server_intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
-}
-
-/**
- * Initialise the socket to communicate with the secondary process
- *
- * @param[in] dev
- * Pointer to Ethernet device.
- *
- * @return
- * 0 on success, a negative value otherwise.
- */
-int
-mlx5_pmd_socket_init(void)
-{
- struct sockaddr_un sun = {
- .sun_family = AF_UNIX,
- };
- int ret;
- int flags;
-
- MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
- if (server_socket)
- return 0;
- /*
- * Initialize the socket to communicate with the secondary
- * process.
- */
- ret = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ret < 0) {
- DRV_LOG(WARNING, "Failed to open mlx5 socket: %s",
- strerror(errno));
- goto error;
- }
- server_socket = ret;
- flags = fcntl(server_socket, F_GETFL, 0);
- if (flags == -1)
- goto error;
- ret = fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
- if (ret < 0)
- goto error;
- mlx5_pmd_make_path(&sun, getpid());
- remove(sun.sun_path);
- ret = bind(server_socket, (const struct sockaddr *)&sun, sizeof(sun));
- if (ret < 0) {
- DRV_LOG(WARNING,
- "cannot bind mlx5 socket: %s", strerror(errno));
- goto close;
- }
- ret = listen(server_socket, 0);
- if (ret < 0) {
- DRV_LOG(WARNING, "cannot listen on mlx5 socket: %s",
- strerror(errno));
- goto close;
- }
- if (mlx5_pmd_interrupt_handler_install()) {
- DRV_LOG(WARNING, "cannot register interrupt handler for mlx5 socket: %s",
- strerror(errno));
- goto close;
- }
- return 0;
-close:
- remove(sun.sun_path);
-error:
- claim_zero(close(server_socket));
- server_socket = 0;
- DRV_LOG(ERR, "Cannot initialize socket: %s", strerror(errno));
- return -errno;
-}
-
-/**
- * Un-Initialize the pmd socket
- */
-RTE_FINI(mlx5_pmd_socket_uninit)
-{
- if (!server_socket)
- return;
- mlx5_pmd_interrupt_handler_uninstall();
- claim_zero(close(server_socket));
- server_socket = 0;
- MKSTR(path, "/var/tmp/dpdk_%s_%d", MLX5_DRIVER_NAME, getpid());
- claim_zero(remove(path));
-}
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 4/8] net/mlx5: split mlx5 ethdev under Linux directory
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (2 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 3/8] net/mlx5: move socket files under Linux directory Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 5/8] net/mlx5: refactor eth dev ops for Linux Ophir Munk
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
File mlx5_ethdev.c is partially moved to linux/mlx5_ethdev_os.c for
functions which are Linux specific. Functions which are Linux agnostics
remain in mlx5_ethdev.c file.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/Makefile | 1 +
drivers/net/mlx5/linux/meson.build | 1 +
drivers/net/mlx5/linux/mlx5_ethdev_os.c | 1270 +++++++++++++++++++++++++++++++
drivers/net/mlx5/mlx5.h | 20 +-
drivers/net/mlx5/mlx5_ethdev.c | 1257 +-----------------------------
5 files changed, 1291 insertions(+), 1258 deletions(-)
create mode 100644 drivers/net/mlx5/linux/mlx5_ethdev_os.c
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index 84fc9cc..fada6fb 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -33,6 +33,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mp.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_utils.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_socket.c
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_os.c
+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += linux/mlx5_ethdev_os.c
# Basic CFLAGS.
CFLAGS += -O3
diff --git a/drivers/net/mlx5/linux/meson.build b/drivers/net/mlx5/linux/meson.build
index f8369cc..ad908c4 100644
--- a/drivers/net/mlx5/linux/meson.build
+++ b/drivers/net/mlx5/linux/meson.build
@@ -5,5 +5,6 @@ includes += include_directories('.')
sources += files(
'mlx5_socket.c',
'mlx5_os.c',
+ 'mlx5_ethdev_os.c',
)
diff --git a/drivers/net/mlx5/linux/mlx5_ethdev_os.c b/drivers/net/mlx5/linux/mlx5_ethdev_os.c
new file mode 100644
index 0000000..e4f1516
--- /dev/null
+++ b/drivers/net/mlx5/linux/mlx5_ethdev_os.c
@@ -0,0 +1,1270 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2015 6WIND S.A.
+ * Copyright 2015 Mellanox Technologies, Ltd
+ */
+
+#include <stddef.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <dirent.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+#include <fcntl.h>
+#include <stdalign.h>
+#include <sys/un.h>
+#include <time.h>
+
+#include <rte_atomic.h>
+#include <rte_ethdev_driver.h>
+#include <rte_bus_pci.h>
+#include <rte_mbuf.h>
+#include <rte_common.h>
+#include <rte_interrupts.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_rwlock.h>
+#include <rte_cycles.h>
+
+#include <mlx5_glue.h>
+#include <mlx5_devx_cmds.h>
+#include <mlx5_common.h>
+
+#include "mlx5.h"
+#include "mlx5_rxtx.h"
+#include "mlx5_utils.h"
+
+/* Supported speed values found in /usr/include/linux/ethtool.h */
+#ifndef HAVE_SUPPORTED_40000baseKR4_Full
+#define SUPPORTED_40000baseKR4_Full (1 << 23)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseCR4_Full
+#define SUPPORTED_40000baseCR4_Full (1 << 24)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseSR4_Full
+#define SUPPORTED_40000baseSR4_Full (1 << 25)
+#endif
+#ifndef HAVE_SUPPORTED_40000baseLR4_Full
+#define SUPPORTED_40000baseLR4_Full (1 << 26)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseKR4_Full
+#define SUPPORTED_56000baseKR4_Full (1 << 27)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseCR4_Full
+#define SUPPORTED_56000baseCR4_Full (1 << 28)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseSR4_Full
+#define SUPPORTED_56000baseSR4_Full (1 << 29)
+#endif
+#ifndef HAVE_SUPPORTED_56000baseLR4_Full
+#define SUPPORTED_56000baseLR4_Full (1 << 30)
+#endif
+
+/* Add defines in case the running kernel is not the same as user headers. */
+#ifndef ETHTOOL_GLINKSETTINGS
+struct ethtool_link_settings {
+ uint32_t cmd;
+ uint32_t speed;
+ uint8_t duplex;
+ uint8_t port;
+ uint8_t phy_address;
+ uint8_t autoneg;
+ uint8_t mdio_support;
+ uint8_t eth_to_mdix;
+ uint8_t eth_tp_mdix_ctrl;
+ int8_t link_mode_masks_nwords;
+ uint32_t reserved[8];
+ uint32_t link_mode_masks[];
+};
+
+/* The kernel values can be found in /include/uapi/linux/ethtool.h */
+#define ETHTOOL_GLINKSETTINGS 0x0000004c
+#define ETHTOOL_LINK_MODE_1000baseT_Full_BIT 5
+#define ETHTOOL_LINK_MODE_Autoneg_BIT 6
+#define ETHTOOL_LINK_MODE_1000baseKX_Full_BIT 17
+#define ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT 18
+#define ETHTOOL_LINK_MODE_10000baseKR_Full_BIT 19
+#define ETHTOOL_LINK_MODE_10000baseR_FEC_BIT 20
+#define ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT 21
+#define ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT 22
+#define ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT 23
+#define ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT 24
+#define ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT 25
+#define ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT 26
+#define ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT 27
+#define ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT 28
+#define ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT 29
+#define ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT 30
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_25G
+#define ETHTOOL_LINK_MODE_25000baseCR_Full_BIT 31
+#define ETHTOOL_LINK_MODE_25000baseKR_Full_BIT 32
+#define ETHTOOL_LINK_MODE_25000baseSR_Full_BIT 33
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_50G
+#define ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT 34
+#define ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT 35
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_100G
+#define ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT 36
+#define ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT 37
+#define ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT 38
+#define ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT 39
+#endif
+#ifndef HAVE_ETHTOOL_LINK_MODE_200G
+#define ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT 62
+#define ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT 63
+#define ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT 0 /* 64 - 64 */
+#define ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT 1 /* 65 - 64 */
+#define ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT 2 /* 66 - 64 */
+#endif
+
+/**
+ * Get master interface name from private structure.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[out] ifname
+ * Interface name output buffer.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_get_master_ifname(const char *ibdev_path, char (*ifname)[IF_NAMESIZE])
+{
+ DIR *dir;
+ struct dirent *dent;
+ unsigned int dev_type = 0;
+ unsigned int dev_port_prev = ~0u;
+ char match[IF_NAMESIZE] = "";
+
+ MLX5_ASSERT(ibdev_path);
+ {
+ MKSTR(path, "%s/device/net", ibdev_path);
+
+ dir = opendir(path);
+ if (dir == NULL) {
+ rte_errno = errno;
+ return -rte_errno;
+ }
+ }
+ while ((dent = readdir(dir)) != NULL) {
+ char *name = dent->d_name;
+ FILE *file;
+ unsigned int dev_port;
+ int r;
+
+ if ((name[0] == '.') &&
+ ((name[1] == '\0') ||
+ ((name[1] == '.') && (name[2] == '\0'))))
+ continue;
+
+ MKSTR(path, "%s/device/net/%s/%s",
+ ibdev_path, name,
+ (dev_type ? "dev_id" : "dev_port"));
+
+ file = fopen(path, "rb");
+ if (file == NULL) {
+ if (errno != ENOENT)
+ continue;
+ /*
+ * Switch to dev_id when dev_port does not exist as
+ * is the case with Linux kernel versions < 3.15.
+ */
+try_dev_id:
+ match[0] = '\0';
+ if (dev_type)
+ break;
+ dev_type = 1;
+ dev_port_prev = ~0u;
+ rewinddir(dir);
+ continue;
+ }
+ r = fscanf(file, (dev_type ? "%x" : "%u"), &dev_port);
+ fclose(file);
+ if (r != 1)
+ continue;
+ /*
+ * Switch to dev_id when dev_port returns the same value for
+ * all ports. May happen when using a MOFED release older than
+ * 3.0 with a Linux kernel >= 3.15.
+ */
+ if (dev_port == dev_port_prev)
+ goto try_dev_id;
+ dev_port_prev = dev_port;
+ if (dev_port == 0)
+ strlcpy(match, name, sizeof(match));
+ }
+ closedir(dir);
+ if (match[0] == '\0') {
+ rte_errno = ENOENT;
+ return -rte_errno;
+ }
+ strncpy(*ifname, match, sizeof(*ifname));
+ return 0;
+}
+
+/**
+ * Get interface name from private structure.
+ *
+ * This is a port representor-aware version of mlx5_get_master_ifname().
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param[out] ifname
+ * Interface name output buffer.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE])
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ unsigned int ifindex;
+
+ MLX5_ASSERT(priv);
+ MLX5_ASSERT(priv->sh);
+ ifindex = mlx5_ifindex(dev);
+ if (!ifindex) {
+ if (!priv->representor)
+ return mlx5_get_master_ifname(priv->sh->ibdev_path,
+ ifname);
+ rte_errno = ENXIO;
+ return -rte_errno;
+ }
+ if (if_indextoname(ifindex, &(*ifname)[0]))
+ return 0;
+ rte_errno = errno;
+ return -rte_errno;
+}
+
+/**
+ * Perform ifreq ioctl() on associated Ethernet device.
+ *
+ * @param[in] dev
+ * Pointer to Ethernet device.
+ * @param req
+ * Request number to pass to ioctl().
+ * @param[out] ifr
+ * Interface request structure output buffer.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr)
+{
+ int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ int ret = 0;
+
+ if (sock == -1) {
+ rte_errno = errno;
+ return -rte_errno;
+ }
+ ret = mlx5_get_ifname(dev, &ifr->ifr_name);
+ if (ret)
+ goto error;
+ ret = ioctl(sock, req, ifr);
+ if (ret == -1) {
+ rte_errno = errno;
+ goto error;
+ }
+ close(sock);
+ return 0;
+error:
+ close(sock);
+ return -rte_errno;
+}
+
+/**
+ * Get device MTU.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @param[out] mtu
+ * MTU value output buffer.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu)
+{
+ struct ifreq request;
+ int ret = mlx5_ifreq(dev, SIOCGIFMTU, &request);
+
+ if (ret)
+ return ret;
+ *mtu = request.ifr_mtu;
+ return 0;
+}
+
+/**
+ * Set device MTU.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @param mtu
+ * MTU value to set.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct ifreq request = { .ifr_mtu = mtu, };
+
+ return mlx5_ifreq(dev, SIOCSIFMTU, &request);
+}
+
+/**
+ * Set device flags.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @param keep
+ * Bitmask for flags that must remain untouched.
+ * @param flags
+ * Bitmask for flags to modify.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_set_flags(struct rte_eth_dev *dev, unsigned int keep, unsigned int flags)
+{
+ struct ifreq request;
+ int ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &request);
+
+ if (ret)
+ return ret;
+ request.ifr_flags &= keep;
+ request.ifr_flags |= flags & ~keep;
+ return mlx5_ifreq(dev, SIOCSIFFLAGS, &request);
+}
+
+/**
+ * Get device current raw clock counter
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] time
+ * Current raw clock counter of the device.
+ *
+ * @return
+ * 0 if the clock has correctly been read
+ * The value of errno in case of error
+ */
+int
+mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct ibv_context *ctx = priv->sh->ctx;
+ struct ibv_values_ex values;
+ int err = 0;
+
+ values.comp_mask = IBV_VALUES_MASK_RAW_CLOCK;
+ err = mlx5_glue->query_rt_values_ex(ctx, &values);
+ if (err != 0) {
+ DRV_LOG(WARNING, "Could not query the clock !");
+ return err;
+ }
+ *clock = values.raw_clock.tv_nsec;
+ return 0;
+}
+
+/**
+ * Retrieve the master device for representor in the same switch domain.
+ *
+ * @param dev
+ * Pointer to representor Ethernet device structure.
+ *
+ * @return
+ * Master device structure on success, NULL otherwise.
+ */
+static struct rte_eth_dev *
+mlx5_find_master_dev(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv;
+ uint16_t port_id;
+ uint16_t domain_id;
+
+ priv = dev->data->dev_private;
+ domain_id = priv->domain_id;
+ MLX5_ASSERT(priv->representor);
+ MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
+ struct mlx5_priv *opriv =
+ rte_eth_devices[port_id].data->dev_private;
+ if (opriv &&
+ opriv->master &&
+ opriv->domain_id == domain_id &&
+ opriv->sh == priv->sh)
+ return &rte_eth_devices[port_id];
+ }
+ return NULL;
+}
+
+/**
+ * DPDK callback to retrieve physical link information.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] link
+ * Storage for current link status.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct ethtool_cmd edata = {
+ .cmd = ETHTOOL_GSET /* Deprecated since Linux v4.5. */
+ };
+ struct ifreq ifr;
+ struct rte_eth_link dev_link;
+ int link_speed = 0;
+ int ret;
+
+ ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ dev_link = (struct rte_eth_link) {
+ .link_status = ((ifr.ifr_flags & IFF_UP) &&
+ (ifr.ifr_flags & IFF_RUNNING)),
+ };
+ ifr = (struct ifreq) {
+ .ifr_data = (void *)&edata,
+ };
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ if (ret == -ENOTSUP && priv->representor) {
+ struct rte_eth_dev *master;
+
+ /*
+ * For representors we can try to inherit link
+ * settings from the master device. Actually
+ * link settings do not make a lot of sense
+ * for representors due to missing physical
+ * link. The old kernel drivers supported
+ * emulated settings query for representors,
+ * the new ones do not, so we have to add
+ * this code for compatibility issues.
+ */
+ master = mlx5_find_master_dev(dev);
+ if (master) {
+ ifr = (struct ifreq) {
+ .ifr_data = (void *)&edata,
+ };
+ ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
+ }
+ }
+ if (ret) {
+ DRV_LOG(WARNING,
+ "port %u ioctl(SIOCETHTOOL,"
+ " ETHTOOL_GSET) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ }
+ link_speed = ethtool_cmd_speed(&edata);
+ if (link_speed == -1)
+ dev_link.link_speed = ETH_SPEED_NUM_NONE;
+ else
+ dev_link.link_speed = link_speed;
+ priv->link_speed_capa = 0;
+ if (edata.supported & SUPPORTED_Autoneg)
+ priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
+ if (edata.supported & (SUPPORTED_1000baseT_Full |
+ SUPPORTED_1000baseKX_Full))
+ priv->link_speed_capa |= ETH_LINK_SPEED_1G;
+ if (edata.supported & SUPPORTED_10000baseKR_Full)
+ priv->link_speed_capa |= ETH_LINK_SPEED_10G;
+ if (edata.supported & (SUPPORTED_40000baseKR4_Full |
+ SUPPORTED_40000baseCR4_Full |
+ SUPPORTED_40000baseSR4_Full |
+ SUPPORTED_40000baseLR4_Full))
+ priv->link_speed_capa |= ETH_LINK_SPEED_40G;
+ dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
+ ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
+ if (((dev_link.link_speed && !dev_link.link_status) ||
+ (!dev_link.link_speed && dev_link.link_status))) {
+ rte_errno = EAGAIN;
+ return -rte_errno;
+ }
+ *link = dev_link;
+ return 0;
+}
+
+/**
+ * Retrieve physical link information (unlocked version using new ioctl).
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] link
+ * Storage for current link status.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev,
+ struct rte_eth_link *link)
+
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct ethtool_link_settings gcmd = { .cmd = ETHTOOL_GLINKSETTINGS };
+ struct ifreq ifr;
+ struct rte_eth_link dev_link;
+ struct rte_eth_dev *master = NULL;
+ uint64_t sc;
+ int ret;
+
+ ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ dev_link = (struct rte_eth_link) {
+ .link_status = ((ifr.ifr_flags & IFF_UP) &&
+ (ifr.ifr_flags & IFF_RUNNING)),
+ };
+ ifr = (struct ifreq) {
+ .ifr_data = (void *)&gcmd,
+ };
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ if (ret == -ENOTSUP && priv->representor) {
+ /*
+ * For representors we can try to inherit link
+ * settings from the master device. Actually
+ * link settings do not make a lot of sense
+ * for representors due to missing physical
+ * link. The old kernel drivers supported
+ * emulated settings query for representors,
+ * the new ones do not, so we have to add
+ * this code for compatibility issues.
+ */
+ master = mlx5_find_master_dev(dev);
+ if (master) {
+ ifr = (struct ifreq) {
+ .ifr_data = (void *)&gcmd,
+ };
+ ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
+ }
+ }
+ if (ret) {
+ DRV_LOG(DEBUG,
+ "port %u ioctl(SIOCETHTOOL,"
+ " ETHTOOL_GLINKSETTINGS) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ }
+ gcmd.link_mode_masks_nwords = -gcmd.link_mode_masks_nwords;
+
+ alignas(struct ethtool_link_settings)
+ uint8_t data[offsetof(struct ethtool_link_settings, link_mode_masks) +
+ sizeof(uint32_t) * gcmd.link_mode_masks_nwords * 3];
+ struct ethtool_link_settings *ecmd = (void *)data;
+
+ *ecmd = gcmd;
+ ifr.ifr_data = (void *)ecmd;
+ ret = mlx5_ifreq(master ? master : dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(DEBUG,
+ "port %u ioctl(SIOCETHTOOL,"
+ "ETHTOOL_GLINKSETTINGS) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ dev_link.link_speed = (ecmd->speed == UINT32_MAX) ? ETH_SPEED_NUM_NONE :
+ ecmd->speed;
+ sc = ecmd->link_mode_masks[0] |
+ ((uint64_t)ecmd->link_mode_masks[1] << 32);
+ priv->link_speed_capa = 0;
+ if (sc & MLX5_BITSHIFT(ETHTOOL_LINK_MODE_Autoneg_BIT))
+ priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_1G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_10G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_20G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_40G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_56G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_25G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_50G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_100G;
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_200G;
+
+ sc = ecmd->link_mode_masks[2] |
+ ((uint64_t)ecmd->link_mode_masks[3] << 32);
+ if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT) |
+ MLX5_BITSHIFT
+ (ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT) |
+ MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT)))
+ priv->link_speed_capa |= ETH_LINK_SPEED_200G;
+ dev_link.link_duplex = ((ecmd->duplex == DUPLEX_HALF) ?
+ ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
+ if (((dev_link.link_speed && !dev_link.link_status) ||
+ (!dev_link.link_speed && dev_link.link_status))) {
+ rte_errno = EAGAIN;
+ return -rte_errno;
+ }
+ *link = dev_link;
+ return 0;
+}
+
+/**
+ * DPDK callback to retrieve physical link information.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param wait_to_complete
+ * Wait for request completion.
+ *
+ * @return
+ * 0 if link status was not updated, positive if it was, a negative errno
+ * value otherwise and rte_errno is set.
+ */
+int
+mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+ int ret;
+ struct rte_eth_link dev_link;
+ time_t start_time = time(NULL);
+ int retry = MLX5_GET_LINK_STATUS_RETRY_COUNT;
+
+ do {
+ ret = mlx5_link_update_unlocked_gs(dev, &dev_link);
+ if (ret == -ENOTSUP)
+ ret = mlx5_link_update_unlocked_gset(dev, &dev_link);
+ if (ret == 0)
+ break;
+ /* Handle wait to complete situation. */
+ if ((wait_to_complete || retry) && ret == -EAGAIN) {
+ if (abs((int)difftime(time(NULL), start_time)) <
+ MLX5_LINK_STATUS_TIMEOUT) {
+ usleep(0);
+ continue;
+ } else {
+ rte_errno = EBUSY;
+ return -rte_errno;
+ }
+ } else if (ret < 0) {
+ return ret;
+ }
+ } while (wait_to_complete || retry-- > 0);
+ ret = !!memcmp(&dev->data->dev_link, &dev_link,
+ sizeof(struct rte_eth_link));
+ dev->data->dev_link = dev_link;
+ return ret;
+}
+
+/**
+ * DPDK callback to get flow control status.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] fc_conf
+ * Flow control output buffer.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct ifreq ifr;
+ struct ethtool_pauseparam ethpause = {
+ .cmd = ETHTOOL_GPAUSEPARAM
+ };
+ int ret;
+
+ ifr.ifr_data = (void *)ðpause;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING,
+ "port %u ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM) failed:"
+ " %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ fc_conf->autoneg = ethpause.autoneg;
+ if (ethpause.rx_pause && ethpause.tx_pause)
+ fc_conf->mode = RTE_FC_FULL;
+ else if (ethpause.rx_pause)
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ else if (ethpause.tx_pause)
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ else
+ fc_conf->mode = RTE_FC_NONE;
+ return 0;
+}
+
+/**
+ * DPDK callback to modify flow control parameters.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[in] fc_conf
+ * Flow control parameters.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct ifreq ifr;
+ struct ethtool_pauseparam ethpause = {
+ .cmd = ETHTOOL_SPAUSEPARAM
+ };
+ int ret;
+
+ ifr.ifr_data = (void *)ðpause;
+ ethpause.autoneg = fc_conf->autoneg;
+ if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
+ (fc_conf->mode & RTE_FC_RX_PAUSE))
+ ethpause.rx_pause = 1;
+ else
+ ethpause.rx_pause = 0;
+
+ if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
+ (fc_conf->mode & RTE_FC_TX_PAUSE))
+ ethpause.tx_pause = 1;
+ else
+ ethpause.tx_pause = 0;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING,
+ "port %u ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
+ " failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ return 0;
+}
+
+/**
+ * Handle asynchronous removal event for entire multiport device.
+ *
+ * @param sh
+ * Infiniband device shared context.
+ */
+static void
+mlx5_dev_interrupt_device_fatal(struct mlx5_dev_ctx_shared *sh)
+{
+ uint32_t i;
+
+ for (i = 0; i < sh->max_port; ++i) {
+ struct rte_eth_dev *dev;
+
+ if (sh->port[i].ih_port_id >= RTE_MAX_ETHPORTS) {
+ /*
+ * Or not existing port either no
+ * handler installed for this port.
+ */
+ continue;
+ }
+ dev = &rte_eth_devices[sh->port[i].ih_port_id];
+ MLX5_ASSERT(dev);
+ if (dev->data->dev_conf.intr_conf.rmv)
+ _rte_eth_dev_callback_process
+ (dev, RTE_ETH_EVENT_INTR_RMV, NULL);
+ }
+}
+
+/**
+ * Handle shared asynchronous events the NIC (removal event
+ * and link status change). Supports multiport IB device.
+ *
+ * @param cb_arg
+ * Callback argument.
+ */
+void
+mlx5_dev_interrupt_handler(void *cb_arg)
+{
+ struct mlx5_dev_ctx_shared *sh = cb_arg;
+ struct ibv_async_event event;
+
+ /* Read all message from the IB device and acknowledge them. */
+ for (;;) {
+ struct rte_eth_dev *dev;
+ uint32_t tmp;
+
+ if (mlx5_glue->get_async_event(sh->ctx, &event))
+ break;
+ /* Retrieve and check IB port index. */
+ tmp = (uint32_t)event.element.port_num;
+ if (!tmp && event.event_type == IBV_EVENT_DEVICE_FATAL) {
+ /*
+ * The DEVICE_FATAL event is called once for
+ * entire device without port specifying.
+ * We should notify all existing ports.
+ */
+ mlx5_glue->ack_async_event(&event);
+ mlx5_dev_interrupt_device_fatal(sh);
+ continue;
+ }
+ MLX5_ASSERT(tmp && (tmp <= sh->max_port));
+ if (!tmp) {
+ /* Unsupported devive level event. */
+ mlx5_glue->ack_async_event(&event);
+ DRV_LOG(DEBUG,
+ "unsupported common event (type %d)",
+ event.event_type);
+ continue;
+ }
+ if (tmp > sh->max_port) {
+ /* Invalid IB port index. */
+ mlx5_glue->ack_async_event(&event);
+ DRV_LOG(DEBUG,
+ "cannot handle an event (type %d)"
+ "due to invalid IB port index (%u)",
+ event.event_type, tmp);
+ continue;
+ }
+ if (sh->port[tmp - 1].ih_port_id >= RTE_MAX_ETHPORTS) {
+ /* No handler installed. */
+ mlx5_glue->ack_async_event(&event);
+ DRV_LOG(DEBUG,
+ "cannot handle an event (type %d)"
+ "due to no handler installed for port %u",
+ event.event_type, tmp);
+ continue;
+ }
+ /* Retrieve ethernet device descriptor. */
+ tmp = sh->port[tmp - 1].ih_port_id;
+ dev = &rte_eth_devices[tmp];
+ MLX5_ASSERT(dev);
+ if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
+ event.event_type == IBV_EVENT_PORT_ERR) &&
+ dev->data->dev_conf.intr_conf.lsc) {
+ mlx5_glue->ack_async_event(&event);
+ if (mlx5_link_update(dev, 0) == -EAGAIN) {
+ usleep(0);
+ continue;
+ }
+ _rte_eth_dev_callback_process
+ (dev, RTE_ETH_EVENT_INTR_LSC, NULL);
+ continue;
+ }
+ DRV_LOG(DEBUG,
+ "port %u cannot handle an unknown event (type %d)",
+ dev->data->port_id, event.event_type);
+ mlx5_glue->ack_async_event(&event);
+ }
+}
+
+/*
+ * Unregister callback handler safely. The handler may be active
+ * while we are trying to unregister it, in this case code -EAGAIN
+ * is returned by rte_intr_callback_unregister(). This routine checks
+ * the return code and tries to unregister handler again.
+ *
+ * @param handle
+ * interrupt handle
+ * @param cb_fn
+ * pointer to callback routine
+ * @cb_arg
+ * opaque callback parameter
+ */
+void
+mlx5_intr_callback_unregister(const struct rte_intr_handle *handle,
+ rte_intr_callback_fn cb_fn, void *cb_arg)
+{
+ /*
+ * Try to reduce timeout management overhead by not calling
+ * the timer related routines on the first iteration. If the
+ * unregistering succeeds on first call there will be no
+ * timer calls at all.
+ */
+ uint64_t twait = 0;
+ uint64_t start = 0;
+
+ do {
+ int ret;
+
+ ret = rte_intr_callback_unregister(handle, cb_fn, cb_arg);
+ if (ret >= 0)
+ return;
+ if (ret != -EAGAIN) {
+ DRV_LOG(INFO, "failed to unregister interrupt"
+ " handler (error: %d)", ret);
+ MLX5_ASSERT(false);
+ return;
+ }
+ if (twait) {
+ struct timespec onems;
+
+ /* Wait one millisecond and try again. */
+ onems.tv_sec = 0;
+ onems.tv_nsec = NS_PER_S / MS_PER_S;
+ nanosleep(&onems, 0);
+ /* Check whether one second elapsed. */
+ if ((rte_get_timer_cycles() - start) <= twait)
+ continue;
+ } else {
+ /*
+ * We get the amount of timer ticks for one second.
+ * If this amount elapsed it means we spent one
+ * second in waiting. This branch is executed once
+ * on first iteration.
+ */
+ twait = rte_get_timer_hz();
+ MLX5_ASSERT(twait);
+ }
+ /*
+ * Timeout elapsed, show message (once a second) and retry.
+ * We have no other acceptable option here, if we ignore
+ * the unregistering return code the handler will not
+ * be unregistered, fd will be closed and we may get the
+ * crush. Hanging and messaging in the loop seems not to be
+ * the worst choice.
+ */
+ DRV_LOG(INFO, "Retrying to unregister interrupt handler");
+ start = rte_get_timer_cycles();
+ } while (true);
+}
+
+/**
+ * Handle DEVX interrupts from the NIC.
+ * This function is probably called from the DPDK host thread.
+ *
+ * @param cb_arg
+ * Callback argument.
+ */
+void
+mlx5_dev_interrupt_handler_devx(void *cb_arg)
+{
+#ifndef HAVE_IBV_DEVX_ASYNC
+ (void)cb_arg;
+ return;
+#else
+ struct mlx5_dev_ctx_shared *sh = cb_arg;
+ union {
+ struct mlx5dv_devx_async_cmd_hdr cmd_resp;
+ uint8_t buf[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
+ MLX5_ST_SZ_BYTES(traffic_counter) +
+ sizeof(struct mlx5dv_devx_async_cmd_hdr)];
+ } out;
+ uint8_t *buf = out.buf + sizeof(out.cmd_resp);
+
+ while (!mlx5_glue->devx_get_async_cmd_comp(sh->devx_comp,
+ &out.cmd_resp,
+ sizeof(out.buf)))
+ mlx5_flow_async_pool_query_handle
+ (sh, (uint64_t)out.cmd_resp.wr_id,
+ mlx5_devx_get_out_command_status(buf));
+#endif /* HAVE_IBV_DEVX_ASYNC */
+}
+
+/**
+ * DPDK callback to bring the link DOWN.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_set_link_down(struct rte_eth_dev *dev)
+{
+ return mlx5_set_flags(dev, ~IFF_UP, ~IFF_UP);
+}
+
+/**
+ * DPDK callback to bring the link UP.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_set_link_up(struct rte_eth_dev *dev)
+{
+ return mlx5_set_flags(dev, ~IFF_UP, IFF_UP);
+}
+
+/**
+ * Check if mlx5 device was removed.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * 1 when device is removed, otherwise 0.
+ */
+int
+mlx5_is_removed(struct rte_eth_dev *dev)
+{
+ struct ibv_device_attr device_attr;
+ struct mlx5_priv *priv = dev->data->dev_private;
+
+ if (mlx5_glue->query_device(priv->sh->ctx, &device_attr) == EIO)
+ return 1;
+ return 0;
+}
+
+/**
+ * Get switch information associated with network interface.
+ *
+ * @param ifindex
+ * Network interface index.
+ * @param[out] info
+ * Switch information object, populated in case of success.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_sysfs_switch_info(unsigned int ifindex, struct mlx5_switch_info *info)
+{
+ char ifname[IF_NAMESIZE];
+ char port_name[IF_NAMESIZE];
+ FILE *file;
+ struct mlx5_switch_info data = {
+ .master = 0,
+ .representor = 0,
+ .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET,
+ .port_name = 0,
+ .switch_id = 0,
+ };
+ DIR *dir;
+ bool port_switch_id_set = false;
+ bool device_dir = false;
+ char c;
+ int ret;
+
+ if (!if_indextoname(ifindex, ifname)) {
+ rte_errno = errno;
+ return -rte_errno;
+ }
+
+ MKSTR(phys_port_name, "/sys/class/net/%s/phys_port_name",
+ ifname);
+ MKSTR(phys_switch_id, "/sys/class/net/%s/phys_switch_id",
+ ifname);
+ MKSTR(pci_device, "/sys/class/net/%s/device",
+ ifname);
+
+ file = fopen(phys_port_name, "rb");
+ if (file != NULL) {
+ ret = fscanf(file, "%s", port_name);
+ fclose(file);
+ if (ret == 1)
+ mlx5_translate_port_name(port_name, &data);
+ }
+ file = fopen(phys_switch_id, "rb");
+ if (file == NULL) {
+ rte_errno = errno;
+ return -rte_errno;
+ }
+ port_switch_id_set =
+ fscanf(file, "%" SCNx64 "%c", &data.switch_id, &c) == 2 &&
+ c == '\n';
+ fclose(file);
+ dir = opendir(pci_device);
+ if (dir != NULL) {
+ closedir(dir);
+ device_dir = true;
+ }
+ if (port_switch_id_set) {
+ /* We have some E-Switch configuration. */
+ mlx5_sysfs_check_switch_info(device_dir, &data);
+ }
+ *info = data;
+ MLX5_ASSERT(!(data.master && data.representor));
+ if (data.master && data.representor) {
+ DRV_LOG(ERR, "ifindex %u device is recognized as master"
+ " and as representor", ifindex);
+ rte_errno = ENODEV;
+ return -rte_errno;
+ }
+ return 0;
+}
+
+/**
+ * Analyze gathered port parameters via sysfs to recognize master
+ * and representor devices for E-Switch configuration.
+ *
+ * @param[in] device_dir
+ * flag of presence of "device" directory under port device key.
+ * @param[inout] switch_info
+ * Port information, including port name as a number and port name
+ * type if recognized
+ *
+ * @return
+ * master and representor flags are set in switch_info according to
+ * recognized parameters (if any).
+ */
+void
+mlx5_sysfs_check_switch_info(bool device_dir,
+ struct mlx5_switch_info *switch_info)
+{
+ switch (switch_info->name_type) {
+ case MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN:
+ /*
+ * Name is not recognized, assume the master,
+ * check the device directory presence.
+ */
+ switch_info->master = device_dir;
+ break;
+ case MLX5_PHYS_PORT_NAME_TYPE_NOTSET:
+ /*
+ * Name is not set, this assumes the legacy naming
+ * schema for master, just check if there is
+ * a device directory.
+ */
+ switch_info->master = device_dir;
+ break;
+ case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
+ /* New uplink naming schema recognized. */
+ switch_info->master = 1;
+ break;
+ case MLX5_PHYS_PORT_NAME_TYPE_LEGACY:
+ /* Legacy representors naming schema. */
+ switch_info->representor = !device_dir;
+ break;
+ case MLX5_PHYS_PORT_NAME_TYPE_PFVF:
+ /* New representors naming schema. */
+ switch_info->representor = 1;
+ break;
+ }
+}
+
+/**
+ * DPDK callback to retrieve plug-in module EEPROM information (type and size).
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] modinfo
+ * Storage for plug-in module EEPROM information.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_get_module_info(struct rte_eth_dev *dev,
+ struct rte_eth_dev_module_info *modinfo)
+{
+ struct ethtool_modinfo info = {
+ .cmd = ETHTOOL_GMODULEINFO,
+ };
+ struct ifreq ifr = (struct ifreq) {
+ .ifr_data = (void *)&info,
+ };
+ int ret = 0;
+
+ if (!dev || !modinfo) {
+ DRV_LOG(WARNING, "missing argument, cannot get module info");
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ return ret;
+ }
+ modinfo->type = info.type;
+ modinfo->eeprom_len = info.eeprom_len;
+ return ret;
+}
+
+/**
+ * DPDK callback to retrieve plug-in module EEPROM data.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param[out] info
+ * Storage for plug-in module EEPROM data.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
+ struct rte_dev_eeprom_info *info)
+{
+ struct ethtool_eeprom *eeprom;
+ struct ifreq ifr;
+ int ret = 0;
+
+ if (!dev || !info) {
+ DRV_LOG(WARNING, "missing argument, cannot get module eeprom");
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ eeprom = rte_calloc(__func__, 1,
+ (sizeof(struct ethtool_eeprom) + info->length), 0);
+ if (!eeprom) {
+ DRV_LOG(WARNING, "port %u cannot allocate memory for "
+ "eeprom data", dev->data->port_id);
+ rte_errno = ENOMEM;
+ return -rte_errno;
+ }
+ eeprom->cmd = ETHTOOL_GMODULEEEPROM;
+ eeprom->offset = info->offset;
+ eeprom->len = info->length;
+ ifr = (struct ifreq) {
+ .ifr_data = (void *)eeprom,
+ };
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret)
+ DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s",
+ dev->data->port_id, strerror(rte_errno));
+ else
+ rte_memcpy(info->data, eeprom->data, info->length);
+ rte_free(eeprom);
+ return ret;
+}
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index abe5099..8aa8510 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -711,6 +711,18 @@ int mlx5_init_once(void);
/* mlx5_ethdev.c */
+int mlx5_dev_configure(struct rte_eth_dev *dev);
+int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver,
+ size_t fw_size);
+int mlx5_dev_infos_get(struct rte_eth_dev *dev,
+ struct rte_eth_dev_info *info);
+const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
+int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
+int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
+ struct rte_eth_hairpin_cap *cap);
+
+/* mlx5_ethdev_os.c */
+
int mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE]);
int mlx5_get_master_ifname(const char *ibdev_path, char (*ifname)[IF_NAMESIZE]);
unsigned int mlx5_ifindex(const struct rte_eth_dev *dev);
@@ -718,14 +730,10 @@ int mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr);
int mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu);
int mlx5_set_flags(struct rte_eth_dev *dev, unsigned int keep,
unsigned int flags);
-int mlx5_dev_configure(struct rte_eth_dev *dev);
-int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
+int mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
int mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock);
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
-const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
int mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete);
int mlx5_force_link_status_change(struct rte_eth_dev *dev, int status);
-int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev,
struct rte_eth_fc_conf *fc_conf);
int mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev,
@@ -754,8 +762,6 @@ int mlx5_get_module_info(struct rte_eth_dev *dev,
struct rte_eth_dev_module_info *modinfo);
int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
struct rte_dev_eeprom_info *info);
-int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
- struct rte_eth_hairpin_cap *cap);
int mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev);
/* mlx5_mac.c */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 6b8b303..6b4efcd 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -4,25 +4,11 @@
*/
#include <stddef.h>
-#include <inttypes.h>
#include <unistd.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
#include <string.h>
+#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
-#include <dirent.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
-#include <fcntl.h>
-#include <stdalign.h>
-#include <sys/un.h>
-#include <time.h>
#include <rte_atomic.h>
#include <rte_ethdev_driver.h>
@@ -35,219 +21,8 @@
#include <rte_rwlock.h>
#include <rte_cycles.h>
-#include <mlx5_glue.h>
-#include <mlx5_devx_cmds.h>
-#include <mlx5_common.h>
-
-#include "mlx5.h"
#include "mlx5_rxtx.h"
-#include "mlx5_utils.h"
-
-/* Supported speed values found in /usr/include/linux/ethtool.h */
-#ifndef HAVE_SUPPORTED_40000baseKR4_Full
-#define SUPPORTED_40000baseKR4_Full (1 << 23)
-#endif
-#ifndef HAVE_SUPPORTED_40000baseCR4_Full
-#define SUPPORTED_40000baseCR4_Full (1 << 24)
-#endif
-#ifndef HAVE_SUPPORTED_40000baseSR4_Full
-#define SUPPORTED_40000baseSR4_Full (1 << 25)
-#endif
-#ifndef HAVE_SUPPORTED_40000baseLR4_Full
-#define SUPPORTED_40000baseLR4_Full (1 << 26)
-#endif
-#ifndef HAVE_SUPPORTED_56000baseKR4_Full
-#define SUPPORTED_56000baseKR4_Full (1 << 27)
-#endif
-#ifndef HAVE_SUPPORTED_56000baseCR4_Full
-#define SUPPORTED_56000baseCR4_Full (1 << 28)
-#endif
-#ifndef HAVE_SUPPORTED_56000baseSR4_Full
-#define SUPPORTED_56000baseSR4_Full (1 << 29)
-#endif
-#ifndef HAVE_SUPPORTED_56000baseLR4_Full
-#define SUPPORTED_56000baseLR4_Full (1 << 30)
-#endif
-
-/* Add defines in case the running kernel is not the same as user headers. */
-#ifndef ETHTOOL_GLINKSETTINGS
-struct ethtool_link_settings {
- uint32_t cmd;
- uint32_t speed;
- uint8_t duplex;
- uint8_t port;
- uint8_t phy_address;
- uint8_t autoneg;
- uint8_t mdio_support;
- uint8_t eth_to_mdix;
- uint8_t eth_tp_mdix_ctrl;
- int8_t link_mode_masks_nwords;
- uint32_t reserved[8];
- uint32_t link_mode_masks[];
-};
-
-/* The kernel values can be found in /include/uapi/linux/ethtool.h */
-#define ETHTOOL_GLINKSETTINGS 0x0000004c
-#define ETHTOOL_LINK_MODE_1000baseT_Full_BIT 5
-#define ETHTOOL_LINK_MODE_Autoneg_BIT 6
-#define ETHTOOL_LINK_MODE_1000baseKX_Full_BIT 17
-#define ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT 18
-#define ETHTOOL_LINK_MODE_10000baseKR_Full_BIT 19
-#define ETHTOOL_LINK_MODE_10000baseR_FEC_BIT 20
-#define ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT 21
-#define ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT 22
-#define ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT 23
-#define ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT 24
-#define ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT 25
-#define ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT 26
-#define ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT 27
-#define ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT 28
-#define ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT 29
-#define ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT 30
-#endif
-#ifndef HAVE_ETHTOOL_LINK_MODE_25G
-#define ETHTOOL_LINK_MODE_25000baseCR_Full_BIT 31
-#define ETHTOOL_LINK_MODE_25000baseKR_Full_BIT 32
-#define ETHTOOL_LINK_MODE_25000baseSR_Full_BIT 33
-#endif
-#ifndef HAVE_ETHTOOL_LINK_MODE_50G
-#define ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT 34
-#define ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT 35
-#endif
-#ifndef HAVE_ETHTOOL_LINK_MODE_100G
-#define ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT 36
-#define ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT 37
-#define ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT 38
-#define ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT 39
-#endif
-#ifndef HAVE_ETHTOOL_LINK_MODE_200G
-#define ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT 62
-#define ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT 63
-#define ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT 0 /* 64 - 64 */
-#define ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT 1 /* 65 - 64 */
-#define ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT 2 /* 66 - 64 */
-#endif
-
-/**
- * Get master interface name from private structure.
- *
- * @param[in] dev
- * Pointer to Ethernet device.
- * @param[out] ifname
- * Interface name output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_get_master_ifname(const char *ibdev_path, char (*ifname)[IF_NAMESIZE])
-{
- DIR *dir;
- struct dirent *dent;
- unsigned int dev_type = 0;
- unsigned int dev_port_prev = ~0u;
- char match[IF_NAMESIZE] = "";
-
- MLX5_ASSERT(ibdev_path);
- {
- MKSTR(path, "%s/device/net", ibdev_path);
-
- dir = opendir(path);
- if (dir == NULL) {
- rte_errno = errno;
- return -rte_errno;
- }
- }
- while ((dent = readdir(dir)) != NULL) {
- char *name = dent->d_name;
- FILE *file;
- unsigned int dev_port;
- int r;
-
- if ((name[0] == '.') &&
- ((name[1] == '\0') ||
- ((name[1] == '.') && (name[2] == '\0'))))
- continue;
-
- MKSTR(path, "%s/device/net/%s/%s",
- ibdev_path, name,
- (dev_type ? "dev_id" : "dev_port"));
-
- file = fopen(path, "rb");
- if (file == NULL) {
- if (errno != ENOENT)
- continue;
- /*
- * Switch to dev_id when dev_port does not exist as
- * is the case with Linux kernel versions < 3.15.
- */
-try_dev_id:
- match[0] = '\0';
- if (dev_type)
- break;
- dev_type = 1;
- dev_port_prev = ~0u;
- rewinddir(dir);
- continue;
- }
- r = fscanf(file, (dev_type ? "%x" : "%u"), &dev_port);
- fclose(file);
- if (r != 1)
- continue;
- /*
- * Switch to dev_id when dev_port returns the same value for
- * all ports. May happen when using a MOFED release older than
- * 3.0 with a Linux kernel >= 3.15.
- */
- if (dev_port == dev_port_prev)
- goto try_dev_id;
- dev_port_prev = dev_port;
- if (dev_port == 0)
- strlcpy(match, name, sizeof(match));
- }
- closedir(dir);
- if (match[0] == '\0') {
- rte_errno = ENOENT;
- return -rte_errno;
- }
- strncpy(*ifname, match, sizeof(*ifname));
- return 0;
-}
-
-/**
- * Get interface name from private structure.
- *
- * This is a port representor-aware version of mlx5_get_master_ifname().
- *
- * @param[in] dev
- * Pointer to Ethernet device.
- * @param[out] ifname
- * Interface name output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_get_ifname(const struct rte_eth_dev *dev, char (*ifname)[IF_NAMESIZE])
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- unsigned int ifindex;
-
- MLX5_ASSERT(priv);
- MLX5_ASSERT(priv->sh);
- ifindex = mlx5_ifindex(dev);
- if (!ifindex) {
- if (!priv->representor)
- return mlx5_get_master_ifname(priv->sh->ibdev_path,
- ifname);
- rte_errno = ENXIO;
- return -rte_errno;
- }
- if (if_indextoname(ifindex, &(*ifname)[0]))
- return 0;
- rte_errno = errno;
- return -rte_errno;
-}
+#include "mlx5_autoconf.h"
/**
* Get the interface index from device name.
@@ -273,112 +48,6 @@ mlx5_ifindex(const struct rte_eth_dev *dev)
}
/**
- * Perform ifreq ioctl() on associated Ethernet device.
- *
- * @param[in] dev
- * Pointer to Ethernet device.
- * @param req
- * Request number to pass to ioctl().
- * @param[out] ifr
- * Interface request structure output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr)
-{
- int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- int ret = 0;
-
- if (sock == -1) {
- rte_errno = errno;
- return -rte_errno;
- }
- ret = mlx5_get_ifname(dev, &ifr->ifr_name);
- if (ret)
- goto error;
- ret = ioctl(sock, req, ifr);
- if (ret == -1) {
- rte_errno = errno;
- goto error;
- }
- close(sock);
- return 0;
-error:
- close(sock);
- return -rte_errno;
-}
-
-/**
- * Get device MTU.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @param[out] mtu
- * MTU value output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu)
-{
- struct ifreq request;
- int ret = mlx5_ifreq(dev, SIOCGIFMTU, &request);
-
- if (ret)
- return ret;
- *mtu = request.ifr_mtu;
- return 0;
-}
-
-/**
- * Set device MTU.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @param mtu
- * MTU value to set.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
-{
- struct ifreq request = { .ifr_mtu = mtu, };
-
- return mlx5_ifreq(dev, SIOCSIFMTU, &request);
-}
-
-/**
- * Set device flags.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @param keep
- * Bitmask for flags that must remain untouched.
- * @param flags
- * Bitmask for flags to modify.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_set_flags(struct rte_eth_dev *dev, unsigned int keep, unsigned int flags)
-{
- struct ifreq request;
- int ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &request);
-
- if (ret)
- return ret;
- request.ifr_flags &= keep;
- request.ifr_flags |= flags & ~keep;
- return mlx5_ifreq(dev, SIOCSIFFLAGS, &request);
-}
-
-/**
* DPDK callback for Ethernet device configuration.
*
* @param dev
@@ -691,36 +360,6 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
}
/**
- * Get device current raw clock counter
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] time
- * Current raw clock counter of the device.
- *
- * @return
- * 0 if the clock has correctly been read
- * The value of errno in case of error
- */
-int
-mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct ibv_context *ctx = priv->sh->ctx;
- struct ibv_values_ex values;
- int err = 0;
-
- values.comp_mask = IBV_VALUES_MASK_RAW_CLOCK;
- err = mlx5_glue->query_rt_values_ex(ctx, &values);
- if (err != 0) {
- DRV_LOG(WARNING, "Could not query the clock !");
- return err;
- }
- *clock = values.raw_clock.tv_nsec;
- return 0;
-}
-
-/**
* Get firmware version of a device.
*
* @param dev
@@ -733,7 +372,8 @@ mlx5_read_clock(struct rte_eth_dev *dev, uint64_t *clock)
* @return
* 0 on success, or the size of the non truncated string if too big.
*/
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
+int
+mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_dev_attr *attr = &priv->sh->device_attr;
@@ -784,330 +424,6 @@ mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
}
/**
- * Retrieve the master device for representor in the same switch domain.
- *
- * @param dev
- * Pointer to representor Ethernet device structure.
- *
- * @return
- * Master device structure on success, NULL otherwise.
- */
-
-static struct rte_eth_dev *
-mlx5_find_master_dev(struct rte_eth_dev *dev)
-{
- struct mlx5_priv *priv;
- uint16_t port_id;
- uint16_t domain_id;
-
- priv = dev->data->dev_private;
- domain_id = priv->domain_id;
- MLX5_ASSERT(priv->representor);
- MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
- struct mlx5_priv *opriv =
- rte_eth_devices[port_id].data->dev_private;
- if (opriv &&
- opriv->master &&
- opriv->domain_id == domain_id &&
- opriv->sh == priv->sh)
- return &rte_eth_devices[port_id];
- }
- return NULL;
-}
-
-/**
- * DPDK callback to retrieve physical link information.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] link
- * Storage for current link status.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct ethtool_cmd edata = {
- .cmd = ETHTOOL_GSET /* Deprecated since Linux v4.5. */
- };
- struct ifreq ifr;
- struct rte_eth_link dev_link;
- int link_speed = 0;
- int ret;
-
- ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link = (struct rte_eth_link) {
- .link_status = ((ifr.ifr_flags & IFF_UP) &&
- (ifr.ifr_flags & IFF_RUNNING)),
- };
- ifr = (struct ifreq) {
- .ifr_data = (void *)&edata,
- };
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- if (ret == -ENOTSUP && priv->representor) {
- struct rte_eth_dev *master;
-
- /*
- * For representors we can try to inherit link
- * settings from the master device. Actually
- * link settings do not make a lot of sense
- * for representors due to missing physical
- * link. The old kernel drivers supported
- * emulated settings query for representors,
- * the new ones do not, so we have to add
- * this code for compatibility issues.
- */
- master = mlx5_find_master_dev(dev);
- if (master) {
- ifr = (struct ifreq) {
- .ifr_data = (void *)&edata,
- };
- ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
- }
- }
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL,"
- " ETHTOOL_GSET) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- }
- link_speed = ethtool_cmd_speed(&edata);
- if (link_speed == -1)
- dev_link.link_speed = ETH_SPEED_NUM_NONE;
- else
- dev_link.link_speed = link_speed;
- priv->link_speed_capa = 0;
- if (edata.supported & SUPPORTED_Autoneg)
- priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
- if (edata.supported & (SUPPORTED_1000baseT_Full |
- SUPPORTED_1000baseKX_Full))
- priv->link_speed_capa |= ETH_LINK_SPEED_1G;
- if (edata.supported & SUPPORTED_10000baseKR_Full)
- priv->link_speed_capa |= ETH_LINK_SPEED_10G;
- if (edata.supported & (SUPPORTED_40000baseKR4_Full |
- SUPPORTED_40000baseCR4_Full |
- SUPPORTED_40000baseSR4_Full |
- SUPPORTED_40000baseLR4_Full))
- priv->link_speed_capa |= ETH_LINK_SPEED_40G;
- dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
- ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_FIXED);
- if (((dev_link.link_speed && !dev_link.link_status) ||
- (!dev_link.link_speed && dev_link.link_status))) {
- rte_errno = EAGAIN;
- return -rte_errno;
- }
- *link = dev_link;
- return 0;
-}
-
-/**
- * Retrieve physical link information (unlocked version using new ioctl).
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] link
- * Storage for current link status.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev,
- struct rte_eth_link *link)
-
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct ethtool_link_settings gcmd = { .cmd = ETHTOOL_GLINKSETTINGS };
- struct ifreq ifr;
- struct rte_eth_link dev_link;
- struct rte_eth_dev *master = NULL;
- uint64_t sc;
- int ret;
-
- ret = mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link = (struct rte_eth_link) {
- .link_status = ((ifr.ifr_flags & IFF_UP) &&
- (ifr.ifr_flags & IFF_RUNNING)),
- };
- ifr = (struct ifreq) {
- .ifr_data = (void *)&gcmd,
- };
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- if (ret == -ENOTSUP && priv->representor) {
- /*
- * For representors we can try to inherit link
- * settings from the master device. Actually
- * link settings do not make a lot of sense
- * for representors due to missing physical
- * link. The old kernel drivers supported
- * emulated settings query for representors,
- * the new ones do not, so we have to add
- * this code for compatibility issues.
- */
- master = mlx5_find_master_dev(dev);
- if (master) {
- ifr = (struct ifreq) {
- .ifr_data = (void *)&gcmd,
- };
- ret = mlx5_ifreq(master, SIOCETHTOOL, &ifr);
- }
- }
- if (ret) {
- DRV_LOG(DEBUG,
- "port %u ioctl(SIOCETHTOOL,"
- " ETHTOOL_GLINKSETTINGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
-
- }
- gcmd.link_mode_masks_nwords = -gcmd.link_mode_masks_nwords;
-
- alignas(struct ethtool_link_settings)
- uint8_t data[offsetof(struct ethtool_link_settings, link_mode_masks) +
- sizeof(uint32_t) * gcmd.link_mode_masks_nwords * 3];
- struct ethtool_link_settings *ecmd = (void *)data;
-
- *ecmd = gcmd;
- ifr.ifr_data = (void *)ecmd;
- ret = mlx5_ifreq(master ? master : dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(DEBUG,
- "port %u ioctl(SIOCETHTOOL,"
- "ETHTOOL_GLINKSETTINGS) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- dev_link.link_speed = (ecmd->speed == UINT32_MAX) ? ETH_SPEED_NUM_NONE :
- ecmd->speed;
- sc = ecmd->link_mode_masks[0] |
- ((uint64_t)ecmd->link_mode_masks[1] << 32);
- priv->link_speed_capa = 0;
- if (sc & MLX5_BITSHIFT(ETHTOOL_LINK_MODE_Autoneg_BIT))
- priv->link_speed_capa |= ETH_LINK_SPEED_AUTONEG;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseT_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_1G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_10G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_20G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_40G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_56G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_25G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_50G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_100G;
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_200G;
-
- sc = ecmd->link_mode_masks[2] |
- ((uint64_t)ecmd->link_mode_masks[3] << 32);
- if (sc & (MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT) |
- MLX5_BITSHIFT(
- ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT) |
- MLX5_BITSHIFT(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT)))
- priv->link_speed_capa |= ETH_LINK_SPEED_200G;
- dev_link.link_duplex = ((ecmd->duplex == DUPLEX_HALF) ?
- ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_FIXED);
- if (((dev_link.link_speed && !dev_link.link_status) ||
- (!dev_link.link_speed && dev_link.link_status))) {
- rte_errno = EAGAIN;
- return -rte_errno;
- }
- *link = dev_link;
- return 0;
-}
-
-/**
- * DPDK callback to retrieve physical link information.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param wait_to_complete
- * Wait for request completion.
- *
- * @return
- * 0 if link status was not updated, positive if it was, a negative errno
- * value otherwise and rte_errno is set.
- */
-int
-mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
-{
- int ret;
- struct rte_eth_link dev_link;
- time_t start_time = time(NULL);
- int retry = MLX5_GET_LINK_STATUS_RETRY_COUNT;
-
- do {
- ret = mlx5_link_update_unlocked_gs(dev, &dev_link);
- if (ret == -ENOTSUP)
- ret = mlx5_link_update_unlocked_gset(dev, &dev_link);
- if (ret == 0)
- break;
- /* Handle wait to complete situation. */
- if ((wait_to_complete || retry) && ret == -EAGAIN) {
- if (abs((int)difftime(time(NULL), start_time)) <
- MLX5_LINK_STATUS_TIMEOUT) {
- usleep(0);
- continue;
- } else {
- rte_errno = EBUSY;
- return -rte_errno;
- }
- } else if (ret < 0) {
- return ret;
- }
- } while (wait_to_complete || retry-- > 0);
- ret = !!memcmp(&dev->data->dev_link, &dev_link,
- sizeof(struct rte_eth_link));
- dev->data->dev_link = dev_link;
- return ret;
-}
-
-/**
* DPDK callback to change the MTU.
*
* @param dev
@@ -1146,335 +462,6 @@ mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
}
/**
- * DPDK callback to get flow control status.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] fc_conf
- * Flow control output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
-{
- struct ifreq ifr;
- struct ethtool_pauseparam ethpause = {
- .cmd = ETHTOOL_GPAUSEPARAM
- };
- int ret;
-
- ifr.ifr_data = (void *)ðpause;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL, ETHTOOL_GPAUSEPARAM) failed:"
- " %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- fc_conf->autoneg = ethpause.autoneg;
- if (ethpause.rx_pause && ethpause.tx_pause)
- fc_conf->mode = RTE_FC_FULL;
- else if (ethpause.rx_pause)
- fc_conf->mode = RTE_FC_RX_PAUSE;
- else if (ethpause.tx_pause)
- fc_conf->mode = RTE_FC_TX_PAUSE;
- else
- fc_conf->mode = RTE_FC_NONE;
- return 0;
-}
-
-/**
- * DPDK callback to modify flow control parameters.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[in] fc_conf
- * Flow control parameters.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
-{
- struct ifreq ifr;
- struct ethtool_pauseparam ethpause = {
- .cmd = ETHTOOL_SPAUSEPARAM
- };
- int ret;
-
- ifr.ifr_data = (void *)ðpause;
- ethpause.autoneg = fc_conf->autoneg;
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_RX_PAUSE))
- ethpause.rx_pause = 1;
- else
- ethpause.rx_pause = 0;
-
- if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) ||
- (fc_conf->mode & RTE_FC_TX_PAUSE))
- ethpause.tx_pause = 1;
- else
- ethpause.tx_pause = 0;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING,
- "port %u ioctl(SIOCETHTOOL, ETHTOOL_SPAUSEPARAM)"
- " failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- return 0;
-}
-
-/**
- * Handle asynchronous removal event for entire multiport device.
- *
- * @param sh
- * Infiniband device shared context.
- */
-static void
-mlx5_dev_interrupt_device_fatal(struct mlx5_dev_ctx_shared *sh)
-{
- uint32_t i;
-
- for (i = 0; i < sh->max_port; ++i) {
- struct rte_eth_dev *dev;
-
- if (sh->port[i].ih_port_id >= RTE_MAX_ETHPORTS) {
- /*
- * Or not existing port either no
- * handler installed for this port.
- */
- continue;
- }
- dev = &rte_eth_devices[sh->port[i].ih_port_id];
- MLX5_ASSERT(dev);
- if (dev->data->dev_conf.intr_conf.rmv)
- _rte_eth_dev_callback_process
- (dev, RTE_ETH_EVENT_INTR_RMV, NULL);
- }
-}
-
-/**
- * Handle shared asynchronous events the NIC (removal event
- * and link status change). Supports multiport IB device.
- *
- * @param cb_arg
- * Callback argument.
- */
-void
-mlx5_dev_interrupt_handler(void *cb_arg)
-{
- struct mlx5_dev_ctx_shared *sh = cb_arg;
- struct ibv_async_event event;
-
- /* Read all message from the IB device and acknowledge them. */
- for (;;) {
- struct rte_eth_dev *dev;
- uint32_t tmp;
-
- if (mlx5_glue->get_async_event(sh->ctx, &event))
- break;
- /* Retrieve and check IB port index. */
- tmp = (uint32_t)event.element.port_num;
- if (!tmp && event.event_type == IBV_EVENT_DEVICE_FATAL) {
- /*
- * The DEVICE_FATAL event is called once for
- * entire device without port specifying.
- * We should notify all existing ports.
- */
- mlx5_glue->ack_async_event(&event);
- mlx5_dev_interrupt_device_fatal(sh);
- continue;
- }
- MLX5_ASSERT(tmp && (tmp <= sh->max_port));
- if (!tmp) {
- /* Unsupported devive level event. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "unsupported common event (type %d)",
- event.event_type);
- continue;
- }
- if (tmp > sh->max_port) {
- /* Invalid IB port index. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "cannot handle an event (type %d)"
- "due to invalid IB port index (%u)",
- event.event_type, tmp);
- continue;
- }
- if (sh->port[tmp - 1].ih_port_id >= RTE_MAX_ETHPORTS) {
- /* No handler installed. */
- mlx5_glue->ack_async_event(&event);
- DRV_LOG(DEBUG,
- "cannot handle an event (type %d)"
- "due to no handler installed for port %u",
- event.event_type, tmp);
- continue;
- }
- /* Retrieve ethernet device descriptor. */
- tmp = sh->port[tmp - 1].ih_port_id;
- dev = &rte_eth_devices[tmp];
- MLX5_ASSERT(dev);
- if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
- event.event_type == IBV_EVENT_PORT_ERR) &&
- dev->data->dev_conf.intr_conf.lsc) {
- mlx5_glue->ack_async_event(&event);
- if (mlx5_link_update(dev, 0) == -EAGAIN) {
- usleep(0);
- continue;
- }
- _rte_eth_dev_callback_process
- (dev, RTE_ETH_EVENT_INTR_LSC, NULL);
- continue;
- }
- DRV_LOG(DEBUG,
- "port %u cannot handle an unknown event (type %d)",
- dev->data->port_id, event.event_type);
- mlx5_glue->ack_async_event(&event);
- }
-}
-
-/*
- * Unregister callback handler safely. The handler may be active
- * while we are trying to unregister it, in this case code -EAGAIN
- * is returned by rte_intr_callback_unregister(). This routine checks
- * the return code and tries to unregister handler again.
- *
- * @param handle
- * interrupt handle
- * @param cb_fn
- * pointer to callback routine
- * @cb_arg
- * opaque callback parameter
- */
-void
-mlx5_intr_callback_unregister(const struct rte_intr_handle *handle,
- rte_intr_callback_fn cb_fn, void *cb_arg)
-{
- /*
- * Try to reduce timeout management overhead by not calling
- * the timer related routines on the first iteration. If the
- * unregistering succeeds on first call there will be no
- * timer calls at all.
- */
- uint64_t twait = 0;
- uint64_t start = 0;
-
- do {
- int ret;
-
- ret = rte_intr_callback_unregister(handle, cb_fn, cb_arg);
- if (ret >= 0)
- return;
- if (ret != -EAGAIN) {
- DRV_LOG(INFO, "failed to unregister interrupt"
- " handler (error: %d)", ret);
- MLX5_ASSERT(false);
- return;
- }
- if (twait) {
- struct timespec onems;
-
- /* Wait one millisecond and try again. */
- onems.tv_sec = 0;
- onems.tv_nsec = NS_PER_S / MS_PER_S;
- nanosleep(&onems, 0);
- /* Check whether one second elapsed. */
- if ((rte_get_timer_cycles() - start) <= twait)
- continue;
- } else {
- /*
- * We get the amount of timer ticks for one second.
- * If this amount elapsed it means we spent one
- * second in waiting. This branch is executed once
- * on first iteration.
- */
- twait = rte_get_timer_hz();
- MLX5_ASSERT(twait);
- }
- /*
- * Timeout elapsed, show message (once a second) and retry.
- * We have no other acceptable option here, if we ignore
- * the unregistering return code the handler will not
- * be unregistered, fd will be closed and we may get the
- * crush. Hanging and messaging in the loop seems not to be
- * the worst choice.
- */
- DRV_LOG(INFO, "Retrying to unregister interrupt handler");
- start = rte_get_timer_cycles();
- } while (true);
-}
-
-/**
- * Handle DEVX interrupts from the NIC.
- * This function is probably called from the DPDK host thread.
- *
- * @param cb_arg
- * Callback argument.
- */
-void
-mlx5_dev_interrupt_handler_devx(void *cb_arg)
-{
-#ifndef HAVE_IBV_DEVX_ASYNC
- (void)cb_arg;
- return;
-#else
- struct mlx5_dev_ctx_shared *sh = cb_arg;
- union {
- struct mlx5dv_devx_async_cmd_hdr cmd_resp;
- uint8_t buf[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
- MLX5_ST_SZ_BYTES(traffic_counter) +
- sizeof(struct mlx5dv_devx_async_cmd_hdr)];
- } out;
- uint8_t *buf = out.buf + sizeof(out.cmd_resp);
-
- while (!mlx5_glue->devx_get_async_cmd_comp(sh->devx_comp,
- &out.cmd_resp,
- sizeof(out.buf)))
- mlx5_flow_async_pool_query_handle
- (sh, (uint64_t)out.cmd_resp.wr_id,
- mlx5_devx_get_out_command_status(buf));
-#endif /* HAVE_IBV_DEVX_ASYNC */
-}
-
-/**
- * DPDK callback to bring the link DOWN.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_set_link_down(struct rte_eth_dev *dev)
-{
- return mlx5_set_flags(dev, ~IFF_UP, ~IFF_UP);
-}
-
-/**
- * DPDK callback to bring the link UP.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_set_link_up(struct rte_eth_dev *dev)
-{
- return mlx5_set_flags(dev, ~IFF_UP, IFF_UP);
-}
-
-/**
* Configure the RX function to use.
*
* @param dev
@@ -1500,26 +487,6 @@ mlx5_select_rx_function(struct rte_eth_dev *dev)
}
/**
- * Check if mlx5 device was removed.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- *
- * @return
- * 1 when device is removed, otherwise 0.
- */
-int
-mlx5_is_removed(struct rte_eth_dev *dev)
-{
- struct ibv_device_attr device_attr;
- struct mlx5_priv *priv = dev->data->dev_private;
-
- if (mlx5_glue->query_device(priv->sh->ctx, &device_attr) == EIO)
- return 1;
- return 0;
-}
-
-/**
* Get the E-Switch parameters by port id.
*
* @param[in] port
@@ -1588,219 +555,6 @@ mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
}
/**
- * Get switch information associated with network interface.
- *
- * @param ifindex
- * Network interface index.
- * @param[out] info
- * Switch information object, populated in case of success.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_sysfs_switch_info(unsigned int ifindex, struct mlx5_switch_info *info)
-{
- char ifname[IF_NAMESIZE];
- char port_name[IF_NAMESIZE];
- FILE *file;
- struct mlx5_switch_info data = {
- .master = 0,
- .representor = 0,
- .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET,
- .port_name = 0,
- .switch_id = 0,
- };
- DIR *dir;
- bool port_switch_id_set = false;
- bool device_dir = false;
- char c;
- int ret;
-
- if (!if_indextoname(ifindex, ifname)) {
- rte_errno = errno;
- return -rte_errno;
- }
-
- MKSTR(phys_port_name, "/sys/class/net/%s/phys_port_name",
- ifname);
- MKSTR(phys_switch_id, "/sys/class/net/%s/phys_switch_id",
- ifname);
- MKSTR(pci_device, "/sys/class/net/%s/device",
- ifname);
-
- file = fopen(phys_port_name, "rb");
- if (file != NULL) {
- ret = fscanf(file, "%s", port_name);
- fclose(file);
- if (ret == 1)
- mlx5_translate_port_name(port_name, &data);
- }
- file = fopen(phys_switch_id, "rb");
- if (file == NULL) {
- rte_errno = errno;
- return -rte_errno;
- }
- port_switch_id_set =
- fscanf(file, "%" SCNx64 "%c", &data.switch_id, &c) == 2 &&
- c == '\n';
- fclose(file);
- dir = opendir(pci_device);
- if (dir != NULL) {
- closedir(dir);
- device_dir = true;
- }
- if (port_switch_id_set) {
- /* We have some E-Switch configuration. */
- mlx5_sysfs_check_switch_info(device_dir, &data);
- }
- *info = data;
- MLX5_ASSERT(!(data.master && data.representor));
- if (data.master && data.representor) {
- DRV_LOG(ERR, "ifindex %u device is recognized as master"
- " and as representor", ifindex);
- rte_errno = ENODEV;
- return -rte_errno;
- }
- return 0;
-}
-
-/**
- * Analyze gathered port parameters via sysfs to recognize master
- * and representor devices for E-Switch configuration.
- *
- * @param[in] device_dir
- * flag of presence of "device" directory under port device key.
- * @param[inout] switch_info
- * Port information, including port name as a number and port name
- * type if recognized
- *
- * @return
- * master and representor flags are set in switch_info according to
- * recognized parameters (if any).
- */
-void
-mlx5_sysfs_check_switch_info(bool device_dir,
- struct mlx5_switch_info *switch_info)
-{
- switch (switch_info->name_type) {
- case MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN:
- /*
- * Name is not recognized, assume the master,
- * check the device directory presence.
- */
- switch_info->master = device_dir;
- break;
- case MLX5_PHYS_PORT_NAME_TYPE_NOTSET:
- /*
- * Name is not set, this assumes the legacy naming
- * schema for master, just check if there is
- * a device directory.
- */
- switch_info->master = device_dir;
- break;
- case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
- /* New uplink naming schema recognized. */
- switch_info->master = 1;
- break;
- case MLX5_PHYS_PORT_NAME_TYPE_LEGACY:
- /* Legacy representors naming schema. */
- switch_info->representor = !device_dir;
- break;
- case MLX5_PHYS_PORT_NAME_TYPE_PFVF:
- /* New representors naming schema. */
- switch_info->representor = 1;
- break;
- }
-}
-
-/**
- * DPDK callback to retrieve plug-in module EEPROM information (type and size).
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] modinfo
- * Storage for plug-in module EEPROM information.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int
-mlx5_get_module_info(struct rte_eth_dev *dev,
- struct rte_eth_dev_module_info *modinfo)
-{
- struct ethtool_modinfo info = {
- .cmd = ETHTOOL_GMODULEINFO,
- };
- struct ifreq ifr = (struct ifreq) {
- .ifr_data = (void *)&info,
- };
- int ret = 0;
-
- if (!dev || !modinfo) {
- DRV_LOG(WARNING, "missing argument, cannot get module info");
- rte_errno = EINVAL;
- return -rte_errno;
- }
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- return ret;
- }
- modinfo->type = info.type;
- modinfo->eeprom_len = info.eeprom_len;
- return ret;
-}
-
-/**
- * DPDK callback to retrieve plug-in module EEPROM data.
- *
- * @param dev
- * Pointer to Ethernet device structure.
- * @param[out] info
- * Storage for plug-in module EEPROM data.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
- struct rte_dev_eeprom_info *info)
-{
- struct ethtool_eeprom *eeprom;
- struct ifreq ifr;
- int ret = 0;
-
- if (!dev || !info) {
- DRV_LOG(WARNING, "missing argument, cannot get module eeprom");
- rte_errno = EINVAL;
- return -rte_errno;
- }
- eeprom = rte_calloc(__func__, 1,
- (sizeof(struct ethtool_eeprom) + info->length), 0);
- if (!eeprom) {
- DRV_LOG(WARNING, "port %u cannot allocate memory for "
- "eeprom data", dev->data->port_id);
- rte_errno = ENOMEM;
- return -rte_errno;
- }
- eeprom->cmd = ETHTOOL_GMODULEEEPROM;
- eeprom->offset = info->offset;
- eeprom->len = info->length;
- ifr = (struct ifreq) {
- .ifr_data = (void *)eeprom,
- };
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret)
- DRV_LOG(WARNING, "port %u ioctl(SIOCETHTOOL) failed: %s",
- dev->data->port_id, strerror(rte_errno));
- else
- rte_memcpy(info->data, eeprom->data, info->length);
- rte_free(eeprom);
- return ret;
-}
-
-/**
* DPDK callback to retrieve hairpin capabilities.
*
* @param dev
@@ -1811,7 +565,8 @@ int mlx5_get_module_eeprom(struct rte_eth_dev *dev,
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
-int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
+int
+mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
struct rte_eth_hairpin_cap *cap)
{
struct mlx5_priv *priv = dev->data->dev_private;
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 5/8] net/mlx5: refactor eth dev ops for Linux
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (3 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 4/8] net/mlx5: split mlx5 ethdev " Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 6/8] common/mlx5: exclude ibv dependent calls in devx commands Ophir Munk
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
There are three types of eth_dev_ops: primary, secondary and isolate.
Their function calls assignments are moved from common file
mlx5.c to the Linux specific file linux/mlx5_os.c.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/linux/mlx5_os.c | 135 ++++++++++++++++++++++++++++++++++++++-
drivers/net/mlx5/mlx5.c | 131 -------------------------------------
drivers/net/mlx5/mlx5.h | 11 +++-
drivers/net/mlx5/mlx5_flow.c | 8 +--
4 files changed, 144 insertions(+), 141 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index abe9b04..2888234 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -524,7 +524,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
return NULL;
}
eth_dev->device = dpdk_dev;
- eth_dev->dev_ops = &mlx5_dev_sec_ops;
+ eth_dev->dev_ops = &mlx5_os_dev_sec_ops;
err = mlx5_proc_priv_init(eth_dev);
if (err)
return NULL;
@@ -1043,7 +1043,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
/* Initialize burst functions to prevent crashes before link-up. */
eth_dev->rx_pkt_burst = removed_rx_burst;
eth_dev->tx_pkt_burst = removed_tx_burst;
- eth_dev->dev_ops = &mlx5_dev_ops;
+ eth_dev->dev_ops = &mlx5_os_dev_ops;
/* Register MAC address. */
claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
if (config.vf && config.vf_nl_en)
@@ -1992,3 +1992,134 @@ mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh)
mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp);
#endif
}
+
+const struct eth_dev_ops mlx5_os_dev_ops = {
+ .dev_configure = mlx5_dev_configure,
+ .dev_start = mlx5_dev_start,
+ .dev_stop = mlx5_dev_stop,
+ .dev_set_link_down = mlx5_set_link_down,
+ .dev_set_link_up = mlx5_set_link_up,
+ .dev_close = mlx5_dev_close,
+ .promiscuous_enable = mlx5_promiscuous_enable,
+ .promiscuous_disable = mlx5_promiscuous_disable,
+ .allmulticast_enable = mlx5_allmulticast_enable,
+ .allmulticast_disable = mlx5_allmulticast_disable,
+ .link_update = mlx5_link_update,
+ .stats_get = mlx5_stats_get,
+ .stats_reset = mlx5_stats_reset,
+ .xstats_get = mlx5_xstats_get,
+ .xstats_reset = mlx5_xstats_reset,
+ .xstats_get_names = mlx5_xstats_get_names,
+ .fw_version_get = mlx5_fw_version_get,
+ .dev_infos_get = mlx5_dev_infos_get,
+ .read_clock = mlx5_read_clock,
+ .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
+ .vlan_filter_set = mlx5_vlan_filter_set,
+ .rx_queue_setup = mlx5_rx_queue_setup,
+ .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
+ .tx_queue_setup = mlx5_tx_queue_setup,
+ .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
+ .rx_queue_release = mlx5_rx_queue_release,
+ .tx_queue_release = mlx5_tx_queue_release,
+ .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
+ .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
+ .mac_addr_remove = mlx5_mac_addr_remove,
+ .mac_addr_add = mlx5_mac_addr_add,
+ .mac_addr_set = mlx5_mac_addr_set,
+ .set_mc_addr_list = mlx5_set_mc_addr_list,
+ .mtu_set = mlx5_dev_set_mtu,
+ .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
+ .vlan_offload_set = mlx5_vlan_offload_set,
+ .reta_update = mlx5_dev_rss_reta_update,
+ .reta_query = mlx5_dev_rss_reta_query,
+ .rss_hash_update = mlx5_rss_hash_update,
+ .rss_hash_conf_get = mlx5_rss_hash_conf_get,
+ .filter_ctrl = mlx5_dev_filter_ctrl,
+ .rx_descriptor_status = mlx5_rx_descriptor_status,
+ .tx_descriptor_status = mlx5_tx_descriptor_status,
+ .rxq_info_get = mlx5_rxq_info_get,
+ .txq_info_get = mlx5_txq_info_get,
+ .rx_burst_mode_get = mlx5_rx_burst_mode_get,
+ .tx_burst_mode_get = mlx5_tx_burst_mode_get,
+ .rx_queue_count = mlx5_rx_queue_count,
+ .rx_queue_intr_enable = mlx5_rx_intr_enable,
+ .rx_queue_intr_disable = mlx5_rx_intr_disable,
+ .is_removed = mlx5_is_removed,
+ .udp_tunnel_port_add = mlx5_udp_tunnel_port_add,
+ .get_module_info = mlx5_get_module_info,
+ .get_module_eeprom = mlx5_get_module_eeprom,
+ .hairpin_cap_get = mlx5_hairpin_cap_get,
+ .mtr_ops_get = mlx5_flow_meter_ops_get,
+};
+
+/* Available operations from secondary process. */
+const struct eth_dev_ops mlx5_os_dev_sec_ops = {
+ .stats_get = mlx5_stats_get,
+ .stats_reset = mlx5_stats_reset,
+ .xstats_get = mlx5_xstats_get,
+ .xstats_reset = mlx5_xstats_reset,
+ .xstats_get_names = mlx5_xstats_get_names,
+ .fw_version_get = mlx5_fw_version_get,
+ .dev_infos_get = mlx5_dev_infos_get,
+ .rx_descriptor_status = mlx5_rx_descriptor_status,
+ .tx_descriptor_status = mlx5_tx_descriptor_status,
+ .rxq_info_get = mlx5_rxq_info_get,
+ .txq_info_get = mlx5_txq_info_get,
+ .rx_burst_mode_get = mlx5_rx_burst_mode_get,
+ .tx_burst_mode_get = mlx5_tx_burst_mode_get,
+ .get_module_info = mlx5_get_module_info,
+ .get_module_eeprom = mlx5_get_module_eeprom,
+};
+
+/* Available operations in flow isolated mode. */
+const struct eth_dev_ops mlx5_os_dev_ops_isolate = {
+ .dev_configure = mlx5_dev_configure,
+ .dev_start = mlx5_dev_start,
+ .dev_stop = mlx5_dev_stop,
+ .dev_set_link_down = mlx5_set_link_down,
+ .dev_set_link_up = mlx5_set_link_up,
+ .dev_close = mlx5_dev_close,
+ .promiscuous_enable = mlx5_promiscuous_enable,
+ .promiscuous_disable = mlx5_promiscuous_disable,
+ .allmulticast_enable = mlx5_allmulticast_enable,
+ .allmulticast_disable = mlx5_allmulticast_disable,
+ .link_update = mlx5_link_update,
+ .stats_get = mlx5_stats_get,
+ .stats_reset = mlx5_stats_reset,
+ .xstats_get = mlx5_xstats_get,
+ .xstats_reset = mlx5_xstats_reset,
+ .xstats_get_names = mlx5_xstats_get_names,
+ .fw_version_get = mlx5_fw_version_get,
+ .dev_infos_get = mlx5_dev_infos_get,
+ .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
+ .vlan_filter_set = mlx5_vlan_filter_set,
+ .rx_queue_setup = mlx5_rx_queue_setup,
+ .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
+ .tx_queue_setup = mlx5_tx_queue_setup,
+ .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
+ .rx_queue_release = mlx5_rx_queue_release,
+ .tx_queue_release = mlx5_tx_queue_release,
+ .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
+ .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
+ .mac_addr_remove = mlx5_mac_addr_remove,
+ .mac_addr_add = mlx5_mac_addr_add,
+ .mac_addr_set = mlx5_mac_addr_set,
+ .set_mc_addr_list = mlx5_set_mc_addr_list,
+ .mtu_set = mlx5_dev_set_mtu,
+ .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
+ .vlan_offload_set = mlx5_vlan_offload_set,
+ .filter_ctrl = mlx5_dev_filter_ctrl,
+ .rx_descriptor_status = mlx5_rx_descriptor_status,
+ .tx_descriptor_status = mlx5_tx_descriptor_status,
+ .rxq_info_get = mlx5_rxq_info_get,
+ .txq_info_get = mlx5_txq_info_get,
+ .rx_burst_mode_get = mlx5_rx_burst_mode_get,
+ .tx_burst_mode_get = mlx5_tx_burst_mode_get,
+ .rx_queue_intr_enable = mlx5_rx_intr_enable,
+ .rx_queue_intr_disable = mlx5_rx_intr_disable,
+ .is_removed = mlx5_is_removed,
+ .get_module_info = mlx5_get_module_info,
+ .get_module_eeprom = mlx5_get_module_eeprom,
+ .hairpin_cap_get = mlx5_hairpin_cap_get,
+ .mtr_ops_get = mlx5_flow_meter_ops_get,
+};
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index f07386d..c15426c 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1223,137 +1223,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
dev->data->mac_addrs = NULL;
}
-const struct eth_dev_ops mlx5_dev_ops = {
- .dev_configure = mlx5_dev_configure,
- .dev_start = mlx5_dev_start,
- .dev_stop = mlx5_dev_stop,
- .dev_set_link_down = mlx5_set_link_down,
- .dev_set_link_up = mlx5_set_link_up,
- .dev_close = mlx5_dev_close,
- .promiscuous_enable = mlx5_promiscuous_enable,
- .promiscuous_disable = mlx5_promiscuous_disable,
- .allmulticast_enable = mlx5_allmulticast_enable,
- .allmulticast_disable = mlx5_allmulticast_disable,
- .link_update = mlx5_link_update,
- .stats_get = mlx5_stats_get,
- .stats_reset = mlx5_stats_reset,
- .xstats_get = mlx5_xstats_get,
- .xstats_reset = mlx5_xstats_reset,
- .xstats_get_names = mlx5_xstats_get_names,
- .fw_version_get = mlx5_fw_version_get,
- .dev_infos_get = mlx5_dev_infos_get,
- .read_clock = mlx5_read_clock,
- .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
- .vlan_filter_set = mlx5_vlan_filter_set,
- .rx_queue_setup = mlx5_rx_queue_setup,
- .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
- .tx_queue_setup = mlx5_tx_queue_setup,
- .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
- .rx_queue_release = mlx5_rx_queue_release,
- .tx_queue_release = mlx5_tx_queue_release,
- .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
- .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
- .mac_addr_remove = mlx5_mac_addr_remove,
- .mac_addr_add = mlx5_mac_addr_add,
- .mac_addr_set = mlx5_mac_addr_set,
- .set_mc_addr_list = mlx5_set_mc_addr_list,
- .mtu_set = mlx5_dev_set_mtu,
- .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
- .vlan_offload_set = mlx5_vlan_offload_set,
- .reta_update = mlx5_dev_rss_reta_update,
- .reta_query = mlx5_dev_rss_reta_query,
- .rss_hash_update = mlx5_rss_hash_update,
- .rss_hash_conf_get = mlx5_rss_hash_conf_get,
- .filter_ctrl = mlx5_dev_filter_ctrl,
- .rx_descriptor_status = mlx5_rx_descriptor_status,
- .tx_descriptor_status = mlx5_tx_descriptor_status,
- .rxq_info_get = mlx5_rxq_info_get,
- .txq_info_get = mlx5_txq_info_get,
- .rx_burst_mode_get = mlx5_rx_burst_mode_get,
- .tx_burst_mode_get = mlx5_tx_burst_mode_get,
- .rx_queue_count = mlx5_rx_queue_count,
- .rx_queue_intr_enable = mlx5_rx_intr_enable,
- .rx_queue_intr_disable = mlx5_rx_intr_disable,
- .is_removed = mlx5_is_removed,
- .udp_tunnel_port_add = mlx5_udp_tunnel_port_add,
- .get_module_info = mlx5_get_module_info,
- .get_module_eeprom = mlx5_get_module_eeprom,
- .hairpin_cap_get = mlx5_hairpin_cap_get,
- .mtr_ops_get = mlx5_flow_meter_ops_get,
-};
-
-/* Available operations from secondary process. */
-const struct eth_dev_ops mlx5_dev_sec_ops = {
- .stats_get = mlx5_stats_get,
- .stats_reset = mlx5_stats_reset,
- .xstats_get = mlx5_xstats_get,
- .xstats_reset = mlx5_xstats_reset,
- .xstats_get_names = mlx5_xstats_get_names,
- .fw_version_get = mlx5_fw_version_get,
- .dev_infos_get = mlx5_dev_infos_get,
- .rx_descriptor_status = mlx5_rx_descriptor_status,
- .tx_descriptor_status = mlx5_tx_descriptor_status,
- .rxq_info_get = mlx5_rxq_info_get,
- .txq_info_get = mlx5_txq_info_get,
- .rx_burst_mode_get = mlx5_rx_burst_mode_get,
- .tx_burst_mode_get = mlx5_tx_burst_mode_get,
- .get_module_info = mlx5_get_module_info,
- .get_module_eeprom = mlx5_get_module_eeprom,
-};
-
-/* Available operations in flow isolated mode. */
-const struct eth_dev_ops mlx5_dev_ops_isolate = {
- .dev_configure = mlx5_dev_configure,
- .dev_start = mlx5_dev_start,
- .dev_stop = mlx5_dev_stop,
- .dev_set_link_down = mlx5_set_link_down,
- .dev_set_link_up = mlx5_set_link_up,
- .dev_close = mlx5_dev_close,
- .promiscuous_enable = mlx5_promiscuous_enable,
- .promiscuous_disable = mlx5_promiscuous_disable,
- .allmulticast_enable = mlx5_allmulticast_enable,
- .allmulticast_disable = mlx5_allmulticast_disable,
- .link_update = mlx5_link_update,
- .stats_get = mlx5_stats_get,
- .stats_reset = mlx5_stats_reset,
- .xstats_get = mlx5_xstats_get,
- .xstats_reset = mlx5_xstats_reset,
- .xstats_get_names = mlx5_xstats_get_names,
- .fw_version_get = mlx5_fw_version_get,
- .dev_infos_get = mlx5_dev_infos_get,
- .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
- .vlan_filter_set = mlx5_vlan_filter_set,
- .rx_queue_setup = mlx5_rx_queue_setup,
- .rx_hairpin_queue_setup = mlx5_rx_hairpin_queue_setup,
- .tx_queue_setup = mlx5_tx_queue_setup,
- .tx_hairpin_queue_setup = mlx5_tx_hairpin_queue_setup,
- .rx_queue_release = mlx5_rx_queue_release,
- .tx_queue_release = mlx5_tx_queue_release,
- .flow_ctrl_get = mlx5_dev_get_flow_ctrl,
- .flow_ctrl_set = mlx5_dev_set_flow_ctrl,
- .mac_addr_remove = mlx5_mac_addr_remove,
- .mac_addr_add = mlx5_mac_addr_add,
- .mac_addr_set = mlx5_mac_addr_set,
- .set_mc_addr_list = mlx5_set_mc_addr_list,
- .mtu_set = mlx5_dev_set_mtu,
- .vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
- .vlan_offload_set = mlx5_vlan_offload_set,
- .filter_ctrl = mlx5_dev_filter_ctrl,
- .rx_descriptor_status = mlx5_rx_descriptor_status,
- .tx_descriptor_status = mlx5_tx_descriptor_status,
- .rxq_info_get = mlx5_rxq_info_get,
- .txq_info_get = mlx5_txq_info_get,
- .rx_burst_mode_get = mlx5_rx_burst_mode_get,
- .tx_burst_mode_get = mlx5_tx_burst_mode_get,
- .rx_queue_intr_enable = mlx5_rx_intr_enable,
- .rx_queue_intr_disable = mlx5_rx_intr_disable,
- .is_removed = mlx5_is_removed,
- .get_module_info = mlx5_get_module_info,
- .get_module_eeprom = mlx5_get_module_eeprom,
- .hairpin_cap_get = mlx5_hairpin_cap_get,
- .mtr_ops_get = mlx5_flow_meter_ops_get,
-};
-
/**
* Verify and store value for device argument.
*
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 8aa8510..fcce9a8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -132,8 +132,9 @@ extern struct mlx5_shared_data *mlx5_shared_data;
extern struct rte_pci_driver mlx5_driver;
/* Dev ops structs */
-extern const struct eth_dev_ops mlx5_dev_sec_ops;
-extern const struct eth_dev_ops mlx5_dev_ops;
+extern const struct eth_dev_ops mlx5_os_dev_ops;
+extern const struct eth_dev_ops mlx5_os_dev_sec_ops;
+extern const struct eth_dev_ops mlx5_os_dev_ops_isolate;
struct mlx5_counter_ctrl {
/* Name of the counter. */
@@ -708,6 +709,12 @@ void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
struct mlx5_dev_config *config);
int mlx5_init_once(void);
+int mlx5_dev_configure(struct rte_eth_dev *dev);
+int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
+int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
+int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
+int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
+ struct rte_eth_hairpin_cap *cap);
/* mlx5_ethdev.c */
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 0e0b0fb..ac9af08 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -38,10 +38,6 @@
#include "mlx5_flow.h"
#include "mlx5_rxtx.h"
-/* Dev ops structure defined in mlx5.c */
-extern const struct eth_dev_ops mlx5_dev_ops;
-extern const struct eth_dev_ops mlx5_dev_ops_isolate;
-
/** Device flow drivers. */
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
extern const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops;
@@ -5042,9 +5038,9 @@ mlx5_flow_isolate(struct rte_eth_dev *dev,
}
priv->isolated = !!enable;
if (enable)
- dev->dev_ops = &mlx5_dev_ops_isolate;
+ dev->dev_ops = &mlx5_os_dev_ops_isolate;
else
- dev->dev_ops = &mlx5_dev_ops;
+ dev->dev_ops = &mlx5_os_dev_ops;
return 0;
}
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 6/8] common/mlx5: exclude ibv dependent calls in devx commands
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (4 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 5/8] net/mlx5: refactor eth dev ops for Linux Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency " Ophir Munk
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
Function mlx5_devx_cmd_qp_query_tis_td() receives as parameter a pointer
to verbs QP returned by ibv_create_qp. Therefore support it only if
HAVE_IBV_FLOW_DV_SUPPORT is defined. Otherwise return an error ENOTSUP.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/common/mlx5/mlx5_devx_cmds.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index fba485e..091a825 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -577,6 +577,7 @@ int
mlx5_devx_cmd_qp_query_tis_td(void *qp, uint32_t tis_num,
uint32_t *tis_td)
{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
uint32_t in[MLX5_ST_SZ_DW(query_tis_in)] = {0};
uint32_t out[MLX5_ST_SZ_DW(query_tis_out)] = {0};
int rc;
@@ -592,6 +593,12 @@ mlx5_devx_cmd_qp_query_tis_td(void *qp, uint32_t tis_num,
tis_ctx = MLX5_ADDR_OF(query_tis_out, out, tis_context);
*tis_td = MLX5_GET(tisc, tis_ctx, transport_domain);
return 0;
+#else
+ (void)qp;
+ (void)tis_num;
+ (void)tis_td;
+ return -ENOTSUP;
+#endif
}
/**
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency in devx commands
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (5 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 6/8] common/mlx5: exclude ibv dependent calls in devx commands Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-18 22:47 ` Thomas Monjalon
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 8/8] net/mlx5: refactor statistics Ophir Munk
2020-06-14 8:21 ` [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Matan Azrad
8 siblings, 1 reply; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
Shared function mlx5_devx_cmd_mkey_create() reads the OS pagesize by
calling a Linux API: 'sysconf(_SC_PAGESIZE)'. Wrap this call with a
shared API 'mlx5_os_get_page_size()' which contains the specific OS
implementation.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/common/mlx5/linux/mlx5_common_os.c | 12 ++++++++++++
drivers/common/mlx5/mlx5_common.h | 1 +
drivers/common/mlx5/mlx5_devx_cmds.c | 2 +-
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c
index 4e04d70..1b71347 100644
--- a/drivers/common/mlx5/linux/mlx5_common_os.c
+++ b/drivers/common/mlx5/linux/mlx5_common_os.c
@@ -125,6 +125,18 @@ mlx5_translate_port_name(const char *port_name_in,
port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN;
}
+/**
+ * Get OS page size
+ *
+ * @return
+ * OS pagesize
+ */
+size_t
+mlx5_os_get_page_size(void)
+{
+ return sysconf(_SC_PAGESIZE);
+}
+
#ifdef MLX5_GLUE
/**
diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index 8e679c6..77f10e6 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -213,6 +213,7 @@ __rte_internal
void mlx5_translate_port_name(const char *port_name_in,
struct mlx5_switch_info *port_info_out);
void mlx5_glue_constructor(void);
+size_t mlx5_os_get_page_size(void);
extern uint8_t haswell_broadwell_cpu;
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 091a825..ccba1c1 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -158,7 +158,7 @@ mlx5_devx_cmd_mkey_create(void *ctx,
return NULL;
}
memset(in, 0, in_size_dw * 4);
- pgsize = sysconf(_SC_PAGESIZE);
+ pgsize = mlx5_os_get_page_size();
MLX5_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY);
mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
if (klm_num > 0) {
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency in devx commands
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency " Ophir Munk
@ 2020-06-18 22:47 ` Thomas Monjalon
2020-06-18 22:48 ` Thomas Monjalon
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Monjalon @ 2020-06-18 22:47 UTC (permalink / raw)
To: Ophir Munk; +Cc: dev, Matan Azrad, Raslan Darawsheh
10/06/2020 11:32, Ophir Munk:
> Shared function mlx5_devx_cmd_mkey_create() reads the OS pagesize by
> calling a Linux API: 'sysconf(_SC_PAGESIZE)'. Wrap this call with a
> shared API 'mlx5_os_get_page_size()' which contains the specific OS
> implementation.
>
> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Sorry, I drop this patch while pulling next-net.
> +/**
> + * Get OS page size
> + *
> + * @return
> + * OS pagesize
> + */
> +size_t
> +mlx5_os_get_page_size(void)
> +{
> + return sysconf(_SC_PAGESIZE);
> +}
The same purpose is achieved with rte_mem_page_size(),
which was added in EAL recently for Windows memory management.
In general, such basic need should not be implemented in a PMD.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency in devx commands
2020-06-18 22:47 ` Thomas Monjalon
@ 2020-06-18 22:48 ` Thomas Monjalon
0 siblings, 0 replies; 13+ messages in thread
From: Thomas Monjalon @ 2020-06-18 22:48 UTC (permalink / raw)
To: Ophir Munk; +Cc: dev, Matan Azrad, Raslan Darawsheh, ferruh.yigit
+Cc Ferruh for info
19/06/2020 00:47, Thomas Monjalon:
> 10/06/2020 11:32, Ophir Munk:
> > Shared function mlx5_devx_cmd_mkey_create() reads the OS pagesize by
> > calling a Linux API: 'sysconf(_SC_PAGESIZE)'. Wrap this call with a
> > shared API 'mlx5_os_get_page_size()' which contains the specific OS
> > implementation.
> >
> > Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
>
> Sorry, I drop this patch while pulling next-net.
>
> > +/**
> > + * Get OS page size
> > + *
> > + * @return
> > + * OS pagesize
> > + */
> > +size_t
> > +mlx5_os_get_page_size(void)
> > +{
> > + return sysconf(_SC_PAGESIZE);
> > +}
>
> The same purpose is achieved with rte_mem_page_size(),
> which was added in EAL recently for Windows memory management.
>
> In general, such basic need should not be implemented in a PMD.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [dpdk-dev] [PATCH v1 8/8] net/mlx5: refactor statistics
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (6 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 7/8] common/mlx5: exclude OS dependency " Ophir Munk
@ 2020-06-10 9:32 ` Ophir Munk
2020-06-14 8:21 ` [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Matan Azrad
8 siblings, 0 replies; 13+ messages in thread
From: Ophir Munk @ 2020-06-10 9:32 UTC (permalink / raw)
To: dev, Matan Azrad, Raslan Darawsheh; +Cc: Ophir Munk
mlx5 statistics are calculated by several methods:
1. In software when packets go through datapath.
2. Calling ioctl with ETHTOOL command (Linux specific).
3. Reading counters from SYSFS device path (Linux specific).
The Linux related functions are moved to file linux/mlx5_os.c.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
drivers/net/mlx5/linux/mlx5_os.c | 328 ++++++++++++++++++++++++++++++++++++++
drivers/net/mlx5/mlx5.h | 8 +-
drivers/net/mlx5/mlx5_stats.c | 332 ++-------------------------------------
drivers/net/mlx5/mlx5_trigger.c | 2 +-
4 files changed, 344 insertions(+), 326 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 2888234..6187c2b 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -12,6 +12,8 @@
#include <net/if.h>
#include <sys/mman.h>
#include <linux/rtnetlink.h>
+#include <linux/sockios.h>
+#include <linux/ethtool.h>
#include <fcntl.h>
/* Verbs header. */
@@ -1993,6 +1995,332 @@ mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh)
#endif
}
+/**
+ * Read statistics by a named counter.
+ *
+ * @param[in] priv
+ * Pointer to the private device data structure.
+ * @param[in] ctr_name
+ * Pointer to the name of the statistic counter to read
+ * @param[out] stat
+ * Pointer to read statistic value.
+ * @return
+ * 0 on success and stat is valud, 1 if failed to read the value
+ * rte_errno is set.
+ *
+ */
+int
+mlx5_os_read_dev_stat(struct mlx5_priv *priv, const char *ctr_name,
+ uint64_t *stat)
+{
+ int fd;
+
+ if (priv->sh) {
+ MKSTR(path, "%s/ports/%d/hw_counters/%s",
+ priv->sh->ibdev_path,
+ priv->dev_port,
+ ctr_name);
+ fd = open(path, O_RDONLY);
+ if (fd != -1) {
+ char buf[21] = {'\0'};
+ ssize_t n = read(fd, buf, sizeof(buf));
+
+ close(fd);
+ if (n != -1) {
+ *stat = strtoull(buf, NULL, 10);
+ return 0;
+ }
+ }
+ }
+ *stat = 0;
+ return 1;
+}
+
+/**
+ * Read device counters table.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ * @param[out] stats
+ * Counters table output buffer.
+ *
+ * @return
+ * 0 on success and stats is filled, negative errno value otherwise and
+ * rte_errno is set.
+ */
+int
+mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
+ unsigned int i;
+ struct ifreq ifr;
+ unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t);
+ unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz];
+ struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf;
+ int ret;
+
+ et_stats->cmd = ETHTOOL_GSTATS;
+ et_stats->n_stats = xstats_ctrl->stats_n;
+ ifr.ifr_data = (caddr_t)et_stats;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING,
+ "port %u unable to read statistic values from device",
+ dev->data->port_id);
+ return ret;
+ }
+ for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
+ if (xstats_ctrl->info[i].dev) {
+ ret = mlx5_os_read_dev_stat(priv,
+ xstats_ctrl->info[i].ctr_name,
+ &stats[i]);
+ /* return last xstats counter if fail to read. */
+ if (ret == 0)
+ xstats_ctrl->xstats[i] = stats[i];
+ else
+ stats[i] = xstats_ctrl->xstats[i];
+ } else {
+ stats[i] = (uint64_t)
+ et_stats->data[xstats_ctrl->dev_table_idx[i]];
+ }
+ }
+ return 0;
+}
+
+/**
+ * Query the number of statistics provided by ETHTOOL.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ *
+ * @return
+ * Number of statistics on success, negative errno value otherwise and
+ * rte_errno is set.
+ */
+int
+mlx5_os_get_stats_n(struct rte_eth_dev *dev)
+{
+ struct ethtool_drvinfo drvinfo;
+ struct ifreq ifr;
+ int ret;
+
+ drvinfo.cmd = ETHTOOL_GDRVINFO;
+ ifr.ifr_data = (caddr_t)&drvinfo;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u unable to query number of statistics",
+ dev->data->port_id);
+ return ret;
+ }
+ return drvinfo.n_stats;
+}
+
+static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
+ {
+ .dpdk_name = "rx_port_unicast_bytes",
+ .ctr_name = "rx_vport_unicast_bytes",
+ },
+ {
+ .dpdk_name = "rx_port_multicast_bytes",
+ .ctr_name = "rx_vport_multicast_bytes",
+ },
+ {
+ .dpdk_name = "rx_port_broadcast_bytes",
+ .ctr_name = "rx_vport_broadcast_bytes",
+ },
+ {
+ .dpdk_name = "rx_port_unicast_packets",
+ .ctr_name = "rx_vport_unicast_packets",
+ },
+ {
+ .dpdk_name = "rx_port_multicast_packets",
+ .ctr_name = "rx_vport_multicast_packets",
+ },
+ {
+ .dpdk_name = "rx_port_broadcast_packets",
+ .ctr_name = "rx_vport_broadcast_packets",
+ },
+ {
+ .dpdk_name = "tx_port_unicast_bytes",
+ .ctr_name = "tx_vport_unicast_bytes",
+ },
+ {
+ .dpdk_name = "tx_port_multicast_bytes",
+ .ctr_name = "tx_vport_multicast_bytes",
+ },
+ {
+ .dpdk_name = "tx_port_broadcast_bytes",
+ .ctr_name = "tx_vport_broadcast_bytes",
+ },
+ {
+ .dpdk_name = "tx_port_unicast_packets",
+ .ctr_name = "tx_vport_unicast_packets",
+ },
+ {
+ .dpdk_name = "tx_port_multicast_packets",
+ .ctr_name = "tx_vport_multicast_packets",
+ },
+ {
+ .dpdk_name = "tx_port_broadcast_packets",
+ .ctr_name = "tx_vport_broadcast_packets",
+ },
+ {
+ .dpdk_name = "rx_wqe_err",
+ .ctr_name = "rx_wqe_err",
+ },
+ {
+ .dpdk_name = "rx_crc_errors_phy",
+ .ctr_name = "rx_crc_errors_phy",
+ },
+ {
+ .dpdk_name = "rx_in_range_len_errors_phy",
+ .ctr_name = "rx_in_range_len_errors_phy",
+ },
+ {
+ .dpdk_name = "rx_symbol_err_phy",
+ .ctr_name = "rx_symbol_err_phy",
+ },
+ {
+ .dpdk_name = "tx_errors_phy",
+ .ctr_name = "tx_errors_phy",
+ },
+ {
+ .dpdk_name = "rx_out_of_buffer",
+ .ctr_name = "out_of_buffer",
+ .dev = 1,
+ },
+ {
+ .dpdk_name = "tx_packets_phy",
+ .ctr_name = "tx_packets_phy",
+ },
+ {
+ .dpdk_name = "rx_packets_phy",
+ .ctr_name = "rx_packets_phy",
+ },
+ {
+ .dpdk_name = "tx_discards_phy",
+ .ctr_name = "tx_discards_phy",
+ },
+ {
+ .dpdk_name = "rx_discards_phy",
+ .ctr_name = "rx_discards_phy",
+ },
+ {
+ .dpdk_name = "tx_bytes_phy",
+ .ctr_name = "tx_bytes_phy",
+ },
+ {
+ .dpdk_name = "rx_bytes_phy",
+ .ctr_name = "rx_bytes_phy",
+ },
+ /* Representor only */
+ {
+ .dpdk_name = "rx_packets",
+ .ctr_name = "vport_rx_packets",
+ },
+ {
+ .dpdk_name = "rx_bytes",
+ .ctr_name = "vport_rx_bytes",
+ },
+ {
+ .dpdk_name = "tx_packets",
+ .ctr_name = "vport_tx_packets",
+ },
+ {
+ .dpdk_name = "tx_bytes",
+ .ctr_name = "vport_tx_bytes",
+ },
+};
+
+static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init);
+
+/**
+ * Init the structures to read device counters.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ */
+void
+mlx5_os_stats_init(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
+ struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
+ unsigned int i;
+ unsigned int j;
+ struct ifreq ifr;
+ struct ethtool_gstrings *strings = NULL;
+ unsigned int dev_stats_n;
+ unsigned int str_sz;
+ int ret;
+
+ /* So that it won't aggregate for each init. */
+ xstats_ctrl->mlx5_stats_n = 0;
+ ret = mlx5_os_get_stats_n(dev);
+ if (ret < 0) {
+ DRV_LOG(WARNING, "port %u no extended statistics available",
+ dev->data->port_id);
+ return;
+ }
+ dev_stats_n = ret;
+ /* Allocate memory to grab stat names and values. */
+ str_sz = dev_stats_n * ETH_GSTRING_LEN;
+ strings = (struct ethtool_gstrings *)
+ rte_malloc("xstats_strings",
+ str_sz + sizeof(struct ethtool_gstrings), 0);
+ if (!strings) {
+ DRV_LOG(WARNING, "port %u unable to allocate memory for xstats",
+ dev->data->port_id);
+ return;
+ }
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = ETH_SS_STATS;
+ strings->len = dev_stats_n;
+ ifr.ifr_data = (caddr_t)strings;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u unable to get statistic names",
+ dev->data->port_id);
+ goto free;
+ }
+ for (i = 0; i != dev_stats_n; ++i) {
+ const char *curr_string = (const char *)
+ &strings->data[i * ETH_GSTRING_LEN];
+
+ for (j = 0; j != xstats_n; ++j) {
+ if (!strcmp(mlx5_counters_init[j].ctr_name,
+ curr_string)) {
+ unsigned int idx = xstats_ctrl->mlx5_stats_n++;
+
+ xstats_ctrl->dev_table_idx[idx] = i;
+ xstats_ctrl->info[idx] = mlx5_counters_init[j];
+ break;
+ }
+ }
+ }
+ /* Add dev counters. */
+ for (i = 0; i != xstats_n; ++i) {
+ if (mlx5_counters_init[i].dev) {
+ unsigned int idx = xstats_ctrl->mlx5_stats_n++;
+
+ xstats_ctrl->info[idx] = mlx5_counters_init[i];
+ xstats_ctrl->hw_stats[idx] = 0;
+ }
+ }
+ MLX5_ASSERT(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS);
+ xstats_ctrl->stats_n = dev_stats_n;
+ /* Copy to base at first time. */
+ ret = mlx5_os_read_dev_counters(dev, xstats_ctrl->base);
+ if (ret)
+ DRV_LOG(ERR, "port %u cannot read device counters: %s",
+ dev->data->port_id, strerror(rte_errno));
+ mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
+ stats_ctrl->imissed = 0;
+free:
+ rte_free(strings);
+}
+
const struct eth_dev_ops mlx5_os_dev_ops = {
.dev_configure = mlx5_dev_configure,
.dev_start = mlx5_dev_start,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index fcce9a8..94a3667 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -141,7 +141,7 @@ struct mlx5_counter_ctrl {
char dpdk_name[RTE_ETH_XSTATS_NAME_SIZE];
/* Name of the counter on the device table. */
char ctr_name[RTE_ETH_XSTATS_NAME_SIZE];
- uint32_t ib:1; /**< Nonzero for IB counters. */
+ uint32_t dev:1; /**< Nonzero for dev counters. */
};
struct mlx5_xstats_ctrl {
@@ -807,7 +807,6 @@ int mlx5_allmulticast_disable(struct rte_eth_dev *dev);
/* mlx5_stats.c */
-void mlx5_stats_init(struct rte_eth_dev *dev);
int mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
int mlx5_stats_reset(struct rte_eth_dev *dev);
int mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
@@ -936,4 +935,9 @@ int mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev);
void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh);
void mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh);
+int mlx5_os_read_dev_stat(struct mlx5_priv *priv,
+ const char *ctr_name, uint64_t *stat);
+int mlx5_os_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats);
+int mlx5_os_get_stats_n(struct rte_eth_dev *dev);
+void mlx5_os_stats_init(struct rte_eth_dev *dev);
#endif /* RTE_PMD_MLX5_H_ */
diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
index 7999c5f..a9b33ee 100644
--- a/drivers/net/mlx5/mlx5_stats.c
+++ b/drivers/net/mlx5/mlx5_stats.c
@@ -3,10 +3,7 @@
* Copyright 2015 Mellanox Technologies, Ltd
*/
-#include <fcntl.h>
#include <inttypes.h>
-#include <linux/sockios.h>
-#include <linux/ethtool.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
@@ -21,317 +18,6 @@
#include "mlx5.h"
#include "mlx5_rxtx.h"
-
-static const struct mlx5_counter_ctrl mlx5_counters_init[] = {
- {
- .dpdk_name = "rx_port_unicast_bytes",
- .ctr_name = "rx_vport_unicast_bytes",
- },
- {
- .dpdk_name = "rx_port_multicast_bytes",
- .ctr_name = "rx_vport_multicast_bytes",
- },
- {
- .dpdk_name = "rx_port_broadcast_bytes",
- .ctr_name = "rx_vport_broadcast_bytes",
- },
- {
- .dpdk_name = "rx_port_unicast_packets",
- .ctr_name = "rx_vport_unicast_packets",
- },
- {
- .dpdk_name = "rx_port_multicast_packets",
- .ctr_name = "rx_vport_multicast_packets",
- },
- {
- .dpdk_name = "rx_port_broadcast_packets",
- .ctr_name = "rx_vport_broadcast_packets",
- },
- {
- .dpdk_name = "tx_port_unicast_bytes",
- .ctr_name = "tx_vport_unicast_bytes",
- },
- {
- .dpdk_name = "tx_port_multicast_bytes",
- .ctr_name = "tx_vport_multicast_bytes",
- },
- {
- .dpdk_name = "tx_port_broadcast_bytes",
- .ctr_name = "tx_vport_broadcast_bytes",
- },
- {
- .dpdk_name = "tx_port_unicast_packets",
- .ctr_name = "tx_vport_unicast_packets",
- },
- {
- .dpdk_name = "tx_port_multicast_packets",
- .ctr_name = "tx_vport_multicast_packets",
- },
- {
- .dpdk_name = "tx_port_broadcast_packets",
- .ctr_name = "tx_vport_broadcast_packets",
- },
- {
- .dpdk_name = "rx_wqe_err",
- .ctr_name = "rx_wqe_err",
- },
- {
- .dpdk_name = "rx_crc_errors_phy",
- .ctr_name = "rx_crc_errors_phy",
- },
- {
- .dpdk_name = "rx_in_range_len_errors_phy",
- .ctr_name = "rx_in_range_len_errors_phy",
- },
- {
- .dpdk_name = "rx_symbol_err_phy",
- .ctr_name = "rx_symbol_err_phy",
- },
- {
- .dpdk_name = "tx_errors_phy",
- .ctr_name = "tx_errors_phy",
- },
- {
- .dpdk_name = "rx_out_of_buffer",
- .ctr_name = "out_of_buffer",
- .ib = 1,
- },
- {
- .dpdk_name = "tx_packets_phy",
- .ctr_name = "tx_packets_phy",
- },
- {
- .dpdk_name = "rx_packets_phy",
- .ctr_name = "rx_packets_phy",
- },
- {
- .dpdk_name = "tx_discards_phy",
- .ctr_name = "tx_discards_phy",
- },
- {
- .dpdk_name = "rx_discards_phy",
- .ctr_name = "rx_discards_phy",
- },
- {
- .dpdk_name = "tx_bytes_phy",
- .ctr_name = "tx_bytes_phy",
- },
- {
- .dpdk_name = "rx_bytes_phy",
- .ctr_name = "rx_bytes_phy",
- },
- /* Representor only */
- {
- .dpdk_name = "rx_packets",
- .ctr_name = "vport_rx_packets",
- },
- {
- .dpdk_name = "rx_bytes",
- .ctr_name = "vport_rx_bytes",
- },
- {
- .dpdk_name = "tx_packets",
- .ctr_name = "vport_tx_packets",
- },
- {
- .dpdk_name = "tx_bytes",
- .ctr_name = "vport_tx_bytes",
- },
-};
-
-static const unsigned int xstats_n = RTE_DIM(mlx5_counters_init);
-
-static inline int
-mlx5_read_ib_stat(struct mlx5_priv *priv, const char *ctr_name, uint64_t *stat)
-{
- int fd;
-
- if (priv->sh) {
- MKSTR(path, "%s/ports/%d/hw_counters/%s",
- priv->sh->ibdev_path,
- priv->dev_port,
- ctr_name);
- fd = open(path, O_RDONLY);
- if (fd != -1) {
- char buf[21] = {'\0'};
- ssize_t n = read(fd, buf, sizeof(buf));
-
- close(fd);
- if (n != -1) {
- *stat = strtoull(buf, NULL, 10);
- return 0;
- }
- }
- }
- *stat = 0;
- return 1;
-}
-
-/**
- * Read device counters table.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @param[out] stats
- * Counters table output buffer.
- *
- * @return
- * 0 on success and stats is filled, negative errno value otherwise and
- * rte_errno is set.
- */
-static int
-mlx5_read_dev_counters(struct rte_eth_dev *dev, uint64_t *stats)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
- unsigned int i;
- struct ifreq ifr;
- unsigned int stats_sz = xstats_ctrl->stats_n * sizeof(uint64_t);
- unsigned char et_stat_buf[sizeof(struct ethtool_stats) + stats_sz];
- struct ethtool_stats *et_stats = (struct ethtool_stats *)et_stat_buf;
- int ret;
-
- et_stats->cmd = ETHTOOL_GSTATS;
- et_stats->n_stats = xstats_ctrl->stats_n;
- ifr.ifr_data = (caddr_t)et_stats;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING,
- "port %u unable to read statistic values from device",
- dev->data->port_id);
- return ret;
- }
- for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {
- if (xstats_ctrl->info[i].ib) {
- ret = mlx5_read_ib_stat(priv,
- xstats_ctrl->info[i].ctr_name,
- &stats[i]);
- /* return last xstats counter if fail to read. */
- if (ret == 0)
- xstats_ctrl->xstats[i] = stats[i];
- else
- stats[i] = xstats_ctrl->xstats[i];
- } else {
- stats[i] = (uint64_t)
- et_stats->data[xstats_ctrl->dev_table_idx[i]];
- }
- }
- return 0;
-}
-
-/**
- * Query the number of statistics provided by ETHTOOL.
- *
- * @param dev
- * Pointer to Ethernet device.
- *
- * @return
- * Number of statistics on success, negative errno value otherwise and
- * rte_errno is set.
- */
-static int
-mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) {
- struct ethtool_drvinfo drvinfo;
- struct ifreq ifr;
- int ret;
-
- drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr.ifr_data = (caddr_t)&drvinfo;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u unable to query number of statistics",
- dev->data->port_id);
- return ret;
- }
- return drvinfo.n_stats;
-}
-
-/**
- * Init the structures to read device counters.
- *
- * @param dev
- * Pointer to Ethernet device.
- */
-void
-mlx5_stats_init(struct rte_eth_dev *dev)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
- struct mlx5_stats_ctrl *stats_ctrl = &priv->stats_ctrl;
- unsigned int i;
- unsigned int j;
- struct ifreq ifr;
- struct ethtool_gstrings *strings = NULL;
- unsigned int dev_stats_n;
- unsigned int str_sz;
- int ret;
-
- /* So that it won't aggregate for each init. */
- xstats_ctrl->mlx5_stats_n = 0;
- ret = mlx5_ethtool_get_stats_n(dev);
- if (ret < 0) {
- DRV_LOG(WARNING, "port %u no extended statistics available",
- dev->data->port_id);
- return;
- }
- dev_stats_n = ret;
- /* Allocate memory to grab stat names and values. */
- str_sz = dev_stats_n * ETH_GSTRING_LEN;
- strings = (struct ethtool_gstrings *)
- rte_malloc("xstats_strings",
- str_sz + sizeof(struct ethtool_gstrings), 0);
- if (!strings) {
- DRV_LOG(WARNING, "port %u unable to allocate memory for xstats",
- dev->data->port_id);
- return;
- }
- strings->cmd = ETHTOOL_GSTRINGS;
- strings->string_set = ETH_SS_STATS;
- strings->len = dev_stats_n;
- ifr.ifr_data = (caddr_t)strings;
- ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
- if (ret) {
- DRV_LOG(WARNING, "port %u unable to get statistic names",
- dev->data->port_id);
- goto free;
- }
- for (i = 0; i != dev_stats_n; ++i) {
- const char *curr_string = (const char *)
- &strings->data[i * ETH_GSTRING_LEN];
-
- for (j = 0; j != xstats_n; ++j) {
- if (!strcmp(mlx5_counters_init[j].ctr_name,
- curr_string)) {
- unsigned int idx = xstats_ctrl->mlx5_stats_n++;
-
- xstats_ctrl->dev_table_idx[idx] = i;
- xstats_ctrl->info[idx] = mlx5_counters_init[j];
- break;
- }
- }
- }
- /* Add IB counters. */
- for (i = 0; i != xstats_n; ++i) {
- if (mlx5_counters_init[i].ib) {
- unsigned int idx = xstats_ctrl->mlx5_stats_n++;
-
- xstats_ctrl->info[idx] = mlx5_counters_init[i];
- xstats_ctrl->hw_stats[idx] = 0;
- }
- }
- MLX5_ASSERT(xstats_ctrl->mlx5_stats_n <= MLX5_MAX_XSTATS);
- xstats_ctrl->stats_n = dev_stats_n;
- /* Copy to base at first time. */
- ret = mlx5_read_dev_counters(dev, xstats_ctrl->base);
- if (ret)
- DRV_LOG(ERR, "port %u cannot read device counters: %s",
- dev->data->port_id, strerror(rte_errno));
- mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
- stats_ctrl->imissed = 0;
-free:
- rte_free(strings);
-}
-
/**
* DPDK callback to get extended device statistics.
*
@@ -360,17 +46,17 @@ mlx5_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
int stats_n;
int ret;
- stats_n = mlx5_ethtool_get_stats_n(dev);
+ stats_n = mlx5_os_get_stats_n(dev);
if (stats_n < 0)
return stats_n;
if (xstats_ctrl->stats_n != stats_n)
- mlx5_stats_init(dev);
- ret = mlx5_read_dev_counters(dev, counters);
+ mlx5_os_stats_init(dev);
+ ret = mlx5_os_read_dev_counters(dev, counters);
if (ret)
return ret;
for (i = 0; i != mlx5_stats_n; ++i) {
stats[i].id = i;
- if (xstats_ctrl->info[i].ib) {
+ if (xstats_ctrl->info[i].dev) {
uint64_t wrap_n;
uint64_t hw_stat = xstats_ctrl->hw_stats[i];
@@ -456,7 +142,7 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
#endif
tmp.oerrors += txq->stats.oerrors;
}
- ret = mlx5_read_ib_stat(priv, "out_of_buffer", &tmp.imissed);
+ ret = mlx5_os_read_dev_stat(priv, "out_of_buffer", &tmp.imissed);
if (ret == 0) {
tmp.imissed = (tmp.imissed - stats_ctrl->imissed_base) &
(uint64_t)UINT32_MAX;
@@ -503,7 +189,7 @@ mlx5_stats_reset(struct rte_eth_dev *dev)
memset(&(*priv->txqs)[i]->stats, 0,
sizeof(struct mlx5_txq_stats));
}
- mlx5_read_ib_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
+ mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
stats_ctrl->imissed = 0;
#ifndef MLX5_PMD_SOFT_COUNTERS
/* FIXME: reset hardware counters. */
@@ -533,15 +219,15 @@ mlx5_xstats_reset(struct rte_eth_dev *dev)
uint64_t counters[n];
int ret;
- stats_n = mlx5_ethtool_get_stats_n(dev);
+ stats_n = mlx5_os_get_stats_n(dev);
if (stats_n < 0) {
DRV_LOG(ERR, "port %u cannot get stats: %s", dev->data->port_id,
strerror(-stats_n));
return stats_n;
}
if (xstats_ctrl->stats_n != stats_n)
- mlx5_stats_init(dev);
- ret = mlx5_read_dev_counters(dev, counters);
+ mlx5_os_stats_init(dev);
+ ret = mlx5_os_read_dev_counters(dev, counters);
if (ret) {
DRV_LOG(ERR, "port %u cannot read device counters: %s",
dev->data->port_id, strerror(rte_errno));
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index a9af2e6..c7c2ee6 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -316,7 +316,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
dev->data->port_id);
goto error;
}
- mlx5_stats_init(dev);
+ mlx5_os_stats_init(dev);
ret = mlx5_traffic_enable(dev);
if (ret) {
DRV_LOG(ERR, "port %u failed to set defaults flows",
--
2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2
2020-06-10 9:32 [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Ophir Munk
` (7 preceding siblings ...)
2020-06-10 9:32 ` [dpdk-dev] [PATCH v1 8/8] net/mlx5: refactor statistics Ophir Munk
@ 2020-06-14 8:21 ` Matan Azrad
2020-06-15 6:58 ` Raslan Darawsheh
8 siblings, 1 reply; 13+ messages in thread
From: Matan Azrad @ 2020-06-14 8:21 UTC (permalink / raw)
To: Ophir Munk, dev, Raslan Darawsheh
From: Ophir Munk:
> This patch series is part of preparing mlx5 PMD to compile and run under
> multiple OSs. Part #2
>
> v1:
> Initial release
>
> Ophir Munk (8):
> net/mlx5: remove dv dependency in mlx5_dev_ctx_shared struct
> net/mlx5: rename ib in names
> net/mlx5: move socket files under Linux directory
> net/mlx5: split mlx5 ethdev under Linux directory
> net/mlx5: refactor eth dev ops for Linux
> common/mlx5: exclude ibv dependent calls in devx commands
> common/mlx5: exclude OS dependency in devx commands
> net/mlx5: refactor statistics
Series-acked-by: Matan Azrad <matan@mellanox.com>
> drivers/common/mlx5/linux/mlx5_common_os.c | 12 +
> drivers/common/mlx5/mlx5_common.h | 1 +
> drivers/common/mlx5/mlx5_devx_cmds.c | 9 +-
> drivers/net/mlx5/Makefile | 3 +-
> drivers/net/mlx5/linux/meson.build | 2 +
> drivers/net/mlx5/linux/mlx5_ethdev_os.c | 1270
> ++++++++++++++++++++++++++++
> drivers/net/mlx5/linux/mlx5_os.c | 481 ++++++++++-
> drivers/net/mlx5/linux/mlx5_socket.c | 230 +++++
> drivers/net/mlx5/meson.build | 1 -
> drivers/net/mlx5/mlx5.c | 172 +---
> drivers/net/mlx5/mlx5.h | 55 +-
> drivers/net/mlx5/mlx5_ethdev.c | 1257 +--------------------------
> drivers/net/mlx5/mlx5_flow.c | 10 +-
> drivers/net/mlx5/mlx5_flow_dv.c | 4 +-
> drivers/net/mlx5/mlx5_flow_verbs.c | 2 +-
> drivers/net/mlx5/mlx5_rxtx.c | 2 +-
> drivers/net/mlx5/mlx5_socket.c | 230 -----
> drivers/net/mlx5/mlx5_stats.c | 332 +-------
> drivers/net/mlx5/mlx5_trigger.c | 10 +-
> drivers/net/mlx5/mlx5_txq.c | 2 +-
> 20 files changed, 2081 insertions(+), 2004 deletions(-) create mode 100644
> drivers/net/mlx5/linux/mlx5_ethdev_os.c
> create mode 100644 drivers/net/mlx5/linux/mlx5_socket.c
> delete mode 100644 drivers/net/mlx5/mlx5_socket.c
>
> --
> 2.8.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2
2020-06-14 8:21 ` [dpdk-dev] [PATCH v1 0/8] mlx5 PMD multi OS support - part #2 Matan Azrad
@ 2020-06-15 6:58 ` Raslan Darawsheh
0 siblings, 0 replies; 13+ messages in thread
From: Raslan Darawsheh @ 2020-06-15 6:58 UTC (permalink / raw)
To: Matan Azrad, Ophir Munk, dev
Hi,
> -----Original Message-----
> From: Matan Azrad <matan@mellanox.com>
> Sent: Sunday, June 14, 2020 11:21 AM
> To: Ophir Munk <ophirmu@mellanox.com>; dev@dpdk.org; Raslan
> Darawsheh <rasland@mellanox.com>
> Subject: RE: [PATCH v1 0/8] mlx5 PMD multi OS support - part #2
>
>
>
> From: Ophir Munk:
> > This patch series is part of preparing mlx5 PMD to compile and run under
> > multiple OSs. Part #2
> >
> > v1:
> > Initial release
> >
> > Ophir Munk (8):
> > net/mlx5: remove dv dependency in mlx5_dev_ctx_shared struct
> > net/mlx5: rename ib in names
> > net/mlx5: move socket files under Linux directory
> > net/mlx5: split mlx5 ethdev under Linux directory
> > net/mlx5: refactor eth dev ops for Linux
> > common/mlx5: exclude ibv dependent calls in devx commands
> > common/mlx5: exclude OS dependency in devx commands
> > net/mlx5: refactor statistics
>
> Series-acked-by: Matan Azrad <matan@mellanox.com>
>
> > drivers/common/mlx5/linux/mlx5_common_os.c | 12 +
> > drivers/common/mlx5/mlx5_common.h | 1 +
> > drivers/common/mlx5/mlx5_devx_cmds.c | 9 +-
> > drivers/net/mlx5/Makefile | 3 +-
> > drivers/net/mlx5/linux/meson.build | 2 +
> > drivers/net/mlx5/linux/mlx5_ethdev_os.c | 1270
> > ++++++++++++++++++++++++++++
> > drivers/net/mlx5/linux/mlx5_os.c | 481 ++++++++++-
> > drivers/net/mlx5/linux/mlx5_socket.c | 230 +++++
> > drivers/net/mlx5/meson.build | 1 -
> > drivers/net/mlx5/mlx5.c | 172 +---
> > drivers/net/mlx5/mlx5.h | 55 +-
> > drivers/net/mlx5/mlx5_ethdev.c | 1257 +--------------------------
> > drivers/net/mlx5/mlx5_flow.c | 10 +-
> > drivers/net/mlx5/mlx5_flow_dv.c | 4 +-
> > drivers/net/mlx5/mlx5_flow_verbs.c | 2 +-
> > drivers/net/mlx5/mlx5_rxtx.c | 2 +-
> > drivers/net/mlx5/mlx5_socket.c | 230 -----
> > drivers/net/mlx5/mlx5_stats.c | 332 +-------
> > drivers/net/mlx5/mlx5_trigger.c | 10 +-
> > drivers/net/mlx5/mlx5_txq.c | 2 +-
> > 20 files changed, 2081 insertions(+), 2004 deletions(-) create mode 100644
> > drivers/net/mlx5/linux/mlx5_ethdev_os.c
> > create mode 100644 drivers/net/mlx5/linux/mlx5_socket.c
> > delete mode 100644 drivers/net/mlx5/mlx5_socket.c
> >
> > --
> > 2.8.4
Series applied to next-net-mlx,
Kindest regards,
Raslan Darawsheh
^ permalink raw reply [flat|nested] 13+ messages in thread