return ret;
}
-/**
- * Create the Tx queue DevX/Verbs object.
- *
- * @param dev
- * Pointer to Ethernet device.
- * @param idx
- * Queue index in DPDK Tx queue array.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
-static int
-mlx5_os_txq_obj_new(struct rte_eth_dev *dev, uint16_t idx)
-{
- struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_txq_data *txq_data = (*priv->txqs)[idx];
- struct mlx5_txq_ctrl *txq_ctrl =
- container_of(txq_data, struct mlx5_txq_ctrl, txq);
-
- if (txq_ctrl->type == MLX5_TXQ_TYPE_HAIRPIN)
- return mlx5_txq_devx_obj_new(dev, idx);
-#ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
- if (!priv->config.dv_esw_en)
- return mlx5_txq_devx_obj_new(dev, idx);
-#endif
- return mlx5_txq_ibv_obj_new(dev, idx);
-}
-
-/**
- * Release an Tx DevX/verbs queue object.
- *
- * @param txq_obj
- * DevX/Verbs Tx queue object.
- */
-static void
-mlx5_os_txq_obj_release(struct mlx5_txq_obj *txq_obj)
-{
- if (txq_obj->txq_ctrl->type == MLX5_TXQ_TYPE_HAIRPIN) {
- mlx5_txq_devx_obj_release(txq_obj);
- return;
- }
-#ifdef HAVE_MLX5DV_DEVX_UAR_OFFSET
- if (!txq_obj->txq_ctrl->priv->config.dv_esw_en) {
- mlx5_txq_devx_obj_release(txq_obj);
- return;
- }
-#endif
- mlx5_txq_ibv_obj_release(txq_obj);
-}
-
/**
* DV flow counter mode detect and config.
*
return false;
}
-
/**
* Spawn an Ethernet device from Verbs information.
*
{
const struct mlx5_switch_info *switch_info = &spawn->info;
struct mlx5_dev_ctx_shared *sh = NULL;
- struct ibv_port_attr port_attr;
+ struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
struct mlx5dv_context dv_attr = { .comp_mask = 0 };
struct rte_eth_dev *eth_dev = NULL;
struct mlx5_priv *priv = NULL;
int own_domain_id = 0;
uint16_t port_id;
struct mlx5_port_info vport_info = { .query_flags = 0 };
+ int nl_rdma = -1;
int i;
/* Determine if this port representor is supposed to be spawned. */
" old OFED/rdma-core version or firmware configuration");
#endif
config->mpls_en = mpls_en;
+ nl_rdma = mlx5_nl_init(NETLINK_RDMA);
/* Check port status. */
- err = mlx5_glue->query_port(sh->cdev->ctx, spawn->phys_port,
- &port_attr);
- if (err) {
- DRV_LOG(ERR, "port query failed: %s", strerror(err));
- goto error;
- }
- if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
- DRV_LOG(ERR, "port is not configured in Ethernet mode");
- err = EINVAL;
- goto error;
+ if (spawn->phys_port <= UINT8_MAX) {
+ /* Legacy Verbs api only support u8 port number. */
+ err = mlx5_glue->query_port(sh->cdev->ctx, spawn->phys_port,
+ &port_attr);
+ if (err) {
+ DRV_LOG(ERR, "port query failed: %s", strerror(err));
+ goto error;
+ }
+ if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
+ DRV_LOG(ERR, "port is not configured in Ethernet mode");
+ err = EINVAL;
+ goto error;
+ }
+ } else if (nl_rdma >= 0) {
+ /* IB doesn't allow more than 255 ports, must be Ethernet. */
+ err = mlx5_nl_port_state(nl_rdma,
+ spawn->phys_dev_name,
+ spawn->phys_port);
+ if (err < 0) {
+ DRV_LOG(INFO, "Failed to get netlink port state: %s",
+ strerror(rte_errno));
+ err = -rte_errno;
+ goto error;
+ }
+ port_attr.state = (enum ibv_port_state)err;
}
if (port_attr.state != IBV_PORT_ACTIVE)
- DRV_LOG(DEBUG, "port is not active: \"%s\" (%d)",
+ DRV_LOG(INFO, "port is not active: \"%s\" (%d)",
mlx5_glue->port_state_str(port_attr.state),
port_attr.state);
/* Allocate private eth device data. */
priv->pci_dev = spawn->pci_dev;
priv->mtu = RTE_ETHER_MTU;
/* Some internal functions rely on Netlink sockets, open them now. */
- priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA);
+ priv->nl_socket_rdma = nl_rdma;
priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE);
priv->representor = !!switch_info->representor;
priv->master = !!switch_info->master;
config->dv_flow_en = 0;
}
#endif
- if (spawn->max_port > UINT8_MAX) {
- /* Verbs can't support ports larger than 255 by design. */
- DRV_LOG(ERR, "can't support IB ports > UINT8_MAX");
- err = EINVAL;
- goto error;
- }
config->ind_table_max_size =
sh->device_attr.max_rwq_indirection_table_size;
/*
* Remove this check once DPDK supports larger/variable
* indirection tables.
*/
- if (config->ind_table_max_size > (unsigned int)ETH_RSS_RETA_SIZE_512)
- config->ind_table_max_size = ETH_RSS_RETA_SIZE_512;
+ if (config->ind_table_max_size > (unsigned int)RTE_ETH_RSS_RETA_SIZE_512)
+ config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
config->ind_table_max_size);
config->hw_vlan_strip = !!(sh->device_attr.raw_packet_caps &
/*
* If HW has bug working with tunnel packet decapsulation and
* scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
- * bit. Then DEV_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
+ * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
*/
if (config->hca_attr.scatter_fcs_w_decap_disable && config->decap_en)
config->hw_fcs_strip = 0;
*/
MLX5_ASSERT(spawn->ifindex);
priv->if_index = spawn->ifindex;
+ priv->lag_affinity_idx = sh->refcnt - 1;
eth_dev->data->dev_private = priv;
priv->dev_data = eth_dev->data;
eth_dev->data->mac_addrs = priv->mac;
ibv_obj_ops.drop_action_create;
priv->obj_ops.drop_action_destroy =
ibv_obj_ops.drop_action_destroy;
-#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET
- priv->obj_ops.txq_obj_modify = ibv_obj_ops.txq_obj_modify;
-#else
- if (config->dv_esw_en)
- priv->obj_ops.txq_obj_modify =
- ibv_obj_ops.txq_obj_modify;
-#endif
- /* Use specific wrappers for Tx object. */
- priv->obj_ops.txq_obj_new = mlx5_os_txq_obj_new;
- priv->obj_ops.txq_obj_release = mlx5_os_txq_obj_release;
mlx5_queue_counter_id_prepare(eth_dev);
priv->obj_ops.lb_dummy_queue_create =
mlx5_rxq_ibv_obj_dummy_lb_create;
priv->obj_ops.lb_dummy_queue_release =
mlx5_rxq_ibv_obj_dummy_lb_release;
+ } else if (spawn->max_port > UINT8_MAX) {
+ /* Verbs can't support ports larger than 255 by design. */
+ DRV_LOG(ERR, "must enable DV and ESW when RDMA link ports > 255");
+ err = ENOTSUP;
+ goto error;
} else {
priv->obj_ops = ibv_obj_ops;
}
if (config->tx_pp &&
(priv->config.dv_esw_en ||
- priv->obj_ops.txq_obj_new != mlx5_os_txq_obj_new)) {
+ priv->obj_ops.txq_obj_new != mlx5_txq_devx_obj_new)) {
/*
* HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support
* packet pacing and already checked above.
mlx5_os_free_shared_dr(priv);
if (priv->nl_socket_route >= 0)
close(priv->nl_socket_route);
- if (priv->nl_socket_rdma >= 0)
- close(priv->nl_socket_rdma);
if (priv->vmwa_context)
mlx5_vlan_vmwa_exit(priv->vmwa_context);
if (eth_dev && priv->drop_queue.hrxq)
}
if (sh)
mlx5_free_shared_dev_ctx(sh);
+ if (nl_rdma >= 0)
+ close(nl_rdma);
MLX5_ASSERT(err > 0);
rte_errno = err;
return NULL;
* Representor interrupts handle is released in mlx5_dev_stop().
*/
if (list[i].info.representor) {
- struct rte_intr_handle *intr_handle;
- intr_handle = mlx5_malloc(MLX5_MEM_SYS | MLX5_MEM_ZERO,
- sizeof(*intr_handle), 0,
- SOCKET_ID_ANY);
- if (!intr_handle) {
+ struct rte_intr_handle *intr_handle =
+ rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
+ if (intr_handle == NULL) {
DRV_LOG(ERR,
"port %u failed to allocate memory for interrupt handler "
"Rx interrupts will not be supported",
if (eth_dev == NULL)
return -rte_errno;
/* Post create. */
- eth_dev->intr_handle = &adev->intr_handle;
+ eth_dev->intr_handle = adev->intr_handle;
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV;
return mlx5_os_auxiliary_probe(cdev);
}
+/**
+ * Cleanup resources when the last device is closed.
+ */
+void
+mlx5_os_net_cleanup(void)
+{
+ mlx5_pmd_socket_uninit();
+}
+
/**
* Install shared asynchronous device events handler.
* This function is implemented to support event sharing
int flags;
struct ibv_context *ctx = sh->cdev->ctx;
- sh->intr_handle.fd = -1;
+ sh->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
+ if (sh->intr_handle == NULL) {
+ DRV_LOG(ERR, "Fail to allocate intr_handle");
+ rte_errno = ENOMEM;
+ return;
+ }
+ rte_intr_fd_set(sh->intr_handle, -1);
+
flags = fcntl(ctx->async_fd, F_GETFL);
ret = fcntl(ctx->async_fd, F_SETFL, flags | O_NONBLOCK);
if (ret) {
DRV_LOG(INFO, "failed to change file descriptor async event"
" queue");
} else {
- sh->intr_handle.fd = ctx->async_fd;
- sh->intr_handle.type = RTE_INTR_HANDLE_EXT;
- if (rte_intr_callback_register(&sh->intr_handle,
+ rte_intr_fd_set(sh->intr_handle, ctx->async_fd);
+ rte_intr_type_set(sh->intr_handle, RTE_INTR_HANDLE_EXT);
+ if (rte_intr_callback_register(sh->intr_handle,
mlx5_dev_interrupt_handler, sh)) {
DRV_LOG(INFO, "Fail to install the shared interrupt.");
- sh->intr_handle.fd = -1;
+ rte_intr_fd_set(sh->intr_handle, -1);
}
}
if (sh->devx) {
#ifdef HAVE_IBV_DEVX_ASYNC
- sh->intr_handle_devx.fd = -1;
+ sh->intr_handle_devx =
+ rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
+ if (!sh->intr_handle_devx) {
+ DRV_LOG(ERR, "Fail to allocate intr_handle");
+ rte_errno = ENOMEM;
+ return;
+ }
+ rte_intr_fd_set(sh->intr_handle_devx, -1);
sh->devx_comp = (void *)mlx5_glue->devx_create_cmd_comp(ctx);
struct mlx5dv_devx_cmd_comp *devx_comp = sh->devx_comp;
if (!devx_comp) {
" devx comp");
return;
}
- 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,
+ rte_intr_fd_set(sh->intr_handle_devx, devx_comp->fd);
+ rte_intr_type_set(sh->intr_handle_devx,
+ RTE_INTR_HANDLE_EXT);
+ if (rte_intr_callback_register(sh->intr_handle_devx,
mlx5_dev_interrupt_handler_devx, sh)) {
DRV_LOG(INFO, "Fail to install the devx shared"
" interrupt.");
- sh->intr_handle_devx.fd = -1;
+ rte_intr_fd_set(sh->intr_handle_devx, -1);
}
#endif /* HAVE_IBV_DEVX_ASYNC */
}
void
mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh)
{
- if (sh->intr_handle.fd >= 0)
- mlx5_intr_callback_unregister(&sh->intr_handle,
+ if (rte_intr_fd_get(sh->intr_handle) >= 0)
+ mlx5_intr_callback_unregister(sh->intr_handle,
mlx5_dev_interrupt_handler, sh);
+ rte_intr_instance_free(sh->intr_handle);
#ifdef HAVE_IBV_DEVX_ASYNC
- if (sh->intr_handle_devx.fd >= 0)
- rte_intr_callback_unregister(&sh->intr_handle_devx,
+ if (rte_intr_fd_get(sh->intr_handle_devx) >= 0)
+ rte_intr_callback_unregister(sh->intr_handle_devx,
mlx5_dev_interrupt_handler_devx, sh);
+ rte_intr_instance_free(sh->intr_handle_devx);
if (sh->devx_comp)
mlx5_glue->devx_destroy_cmd_comp(sh->devx_comp);
#endif