}
/**
- * Device status handler.
+ * Handle shared asynchronous events the NIC (removal event
+ * and link status change). Supports multiport IB device.
*
- * @param dev
- * Pointer to Ethernet device.
- * @param events
- * Pointer to event flags holder.
- *
- * @return
- * Events bitmap of callback process which can be called immediately.
+ * @param cb_arg
+ * Callback argument.
*/
-static uint32_t
-mlx5_dev_status_handler(struct rte_eth_dev *dev)
+void
+mlx5_dev_interrupt_handler(void *cb_arg)
{
- struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_ibv_shared *sh = cb_arg;
struct ibv_async_event event;
- uint32_t ret = 0;
- if (mlx5_link_update(dev, 0) == -EAGAIN) {
- usleep(0);
- return 0;
- }
- /* Read all message and acknowledge them. */
+ /* Read all message from the IB device and acknowledge them. */
for (;;) {
- if (mlx5_glue->get_async_event(priv->sh->ctx, &event))
+ 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;
+ assert(tmp && (tmp <= sh->max_port));
+ if (!tmp ||
+ tmp > sh->max_port ||
+ sh->port[tmp - 1].ih_port_id >= RTE_MAX_ETHPORTS) {
+ /*
+ * Invalid IB port index or no handler
+ * installed for this port.
+ */
+ mlx5_glue->ack_async_event(&event);
+ continue;
+ }
+ /* Retrieve ethernet device descriptor. */
+ tmp = sh->port[tmp - 1].ih_port_id;
+ dev = &rte_eth_devices[tmp];
+ tmp = 0;
+ assert(dev);
if ((event.event_type == IBV_EVENT_PORT_ACTIVE ||
- event.event_type == IBV_EVENT_PORT_ERR) &&
- (dev->data->dev_conf.intr_conf.lsc == 1))
- ret |= (1 << RTE_ETH_EVENT_INTR_LSC);
- else if (event.event_type == IBV_EVENT_DEVICE_FATAL &&
- dev->data->dev_conf.intr_conf.rmv == 1)
- ret |= (1 << RTE_ETH_EVENT_INTR_RMV);
- else
- DRV_LOG(DEBUG,
- "port %u event type %d on not handled",
- dev->data->port_id, event.event_type);
+ 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;
+ }
+ if (event.event_type == IBV_EVENT_DEVICE_FATAL &&
+ dev->data->dev_conf.intr_conf.rmv) {
+ mlx5_glue->ack_async_event(&event);
+ _rte_eth_dev_callback_process
+ (dev, RTE_ETH_EVENT_INTR_RMV, NULL);
+ continue;
+ }
+ DRV_LOG(DEBUG,
+ "port %u event type %d on not handled",
+ dev->data->port_id, event.event_type);
mlx5_glue->ack_async_event(&event);
}
- return ret;
-}
-
-/**
- * Handle interrupts from the NIC.
- *
- * @param[in] intr_handle
- * Interrupt handler.
- * @param cb_arg
- * Callback argument.
- */
-void
-mlx5_dev_interrupt_handler(void *cb_arg)
-{
- struct rte_eth_dev *dev = cb_arg;
- uint32_t events;
-
- events = mlx5_dev_status_handler(dev);
- if (events & (1 << RTE_ETH_EVENT_INTR_LSC))
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
- if (events & (1 << RTE_ETH_EVENT_INTR_RMV))
- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RMV, NULL);
-}
-
-/**
- * Handle interrupts from the socket.
- *
- * @param cb_arg
- * Callback argument.
- */
-static void
-mlx5_dev_handler_socket(void *cb_arg)
-{
- struct rte_eth_dev *dev = cb_arg;
-
- mlx5_socket_handle(dev);
}
/**
void
mlx5_dev_interrupt_handler_uninstall(struct rte_eth_dev *dev)
{
- struct mlx5_priv *priv = dev->data->dev_private;
-
mlx5_dev_shared_handler_uninstall(dev);
- if (priv->primary_socket)
- rte_intr_callback_unregister(&priv->intr_handle_socket,
- mlx5_dev_handler_socket, dev);
- priv->intr_handle_socket.fd = 0;
- priv->intr_handle_socket.type = RTE_INTR_HANDLE_UNKNOWN;
}
/**
void
mlx5_dev_interrupt_handler_install(struct rte_eth_dev *dev)
{
- struct mlx5_priv *priv = dev->data->dev_private;
- int ret;
-
mlx5_dev_shared_handler_install(dev);
- ret = mlx5_socket_init(dev);
- if (ret)
- DRV_LOG(ERR, "port %u cannot initialise socket: %s",
- dev->data->port_id, strerror(rte_errno));
- else if (priv->primary_socket) {
- priv->intr_handle_socket.fd = priv->primary_socket;
- priv->intr_handle_socket.type = RTE_INTR_HANDLE_EXT;
- rte_intr_callback_register(&priv->intr_handle_socket,
- mlx5_dev_handler_socket, dev);
- }
}
/**
uint16_t id;
unsigned int n = 0;
- RTE_ETH_FOREACH_DEV(id) {
- struct rte_eth_dev *ldev = &rte_eth_devices[id];
-
- if (ldev->device != dev)
- continue;
+ RTE_ETH_FOREACH_DEV_OF(id, dev) {
if (n < port_list_n)
port_list[n] = id;
n++;