return -ENOMEM;
}
DEBUG("using driver device index %d", idx);
-
/* Save PCI address. */
mlx5_dev[idx].pci_addr = pci_dev->addr;
list = mlx5_glue->get_device_list(&i);
return -err;
}
ibv_dev = list[i];
-
DEBUG("device opened");
/*
* Multi-packet send is supported by ConnectX-4 Lx PF as well
if (mlx5_glue->query_device_ex(attr_ctx, NULL, &device_attr))
goto error;
INFO("%u port(s) detected", device_attr.orig_attr.phys_port_cnt);
-
for (i = 0; i < device_attr.orig_attr.phys_port_cnt; i++) {
char name[RTE_ETH_NAME_MAX_LEN];
int len;
pci_dev->addr.devid, pci_dev->addr.function);
if (device_attr.orig_attr.phys_port_cnt > 1)
snprintf(name + len, sizeof(name), " port %u", i);
-
mlx5_dev[idx].ports |= test;
-
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
eth_dev = rte_eth_dev_attach_secondary(name);
if (eth_dev == NULL) {
priv_select_tx_function(priv, eth_dev);
continue;
}
-
DEBUG("using port %u (%08" PRIx32 ")", port, test);
-
ctx = mlx5_glue->open_device(ibv_dev);
if (ctx == NULL) {
err = ENODEV;
goto port_error;
}
-
mlx5_glue->query_device_ex(ctx, NULL, &device_attr);
/* Check port status. */
err = mlx5_glue->query_port(ctx, port, &port_attr);
ERROR("port query failed: %s", strerror(err));
goto port_error;
}
-
if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
ERROR("port %d is not configured in Ethernet mode",
port);
err = EINVAL;
goto port_error;
}
-
if (port_attr.state != IBV_PORT_ACTIVE)
DEBUG("port %d is not active: \"%s\" (%d)",
port, mlx5_glue->port_state_str(port_attr.state),
port_attr.state);
-
/* Allocate protection domain. */
pd = mlx5_glue->alloc_pd(ctx);
if (pd == NULL) {
err = ENOMEM;
goto port_error;
}
-
mlx5_dev[idx].ports |= test;
-
/* from rte_ethdev.c */
priv = rte_zmalloc("ethdev private structure",
sizeof(*priv),
err = ENOMEM;
goto port_error;
}
-
priv->ctx = ctx;
strncpy(priv->ibdev_path, priv->ctx->device->ibdev_path,
sizeof(priv->ibdev_path));
ERROR("ibv_query_device_ex() failed");
goto port_error;
}
-
config.hw_csum = !!(device_attr_ex.device_cap_flags_ex &
IBV_DEVICE_RAW_IP_CSUM);
DEBUG("checksum offloading is %ssupported",
#endif
DEBUG("hardware RX end alignment padding is %ssupported",
(config.hw_padding ? "" : "not "));
-
config.tso = ((device_attr_ex.tso_caps.max_tso > 0) &&
(device_attr_ex.tso_caps.supported_qpts &
(1 << IBV_QPT_RAW_PACKET)));
/* Get actual MTU if possible. */
priv_get_mtu(priv, &priv->mtu);
DEBUG("port %u MTU is %u", priv->port, priv->mtu);
-
eth_dev = rte_eth_dev_allocate(name);
if (eth_dev == NULL) {
ERROR("can not allocate rte ethdev");
claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
TAILQ_INIT(&priv->flows);
TAILQ_INIT(&priv->ctrl_flows);
-
/* Hint libmlx5 to use PMD allocator for data plane resources */
struct mlx5dv_ctx_allocators alctr = {
.alloc = &mlx5_alloc_verbs_buf,
/* Store device configuration on private structure. */
priv->config = config;
continue;
-
port_error:
if (priv)
rte_free(priv);
claim_zero(mlx5_glue->close_device(ctx));
break;
}
-
/*
* XXX if something went wrong in the loop above, there is a resource
* leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
* long as the dpdk does not provide a way to deallocate a ethdev and a
* way to enumerate the registered ethdevs to free the previous ones.
*/
-
/* no port found, complain */
if (!mlx5_dev[idx].ports) {
err = ENODEV;
goto error;
}
-
error:
if (attr_ctx)
claim_zero(mlx5_glue->close_device(attr_ctx));
char ifname[IF_NAMESIZE];
info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
-
priv_lock(priv);
/* FIXME: we should ask the device for these values. */
info->min_rx_bufsize = 32;
int link_speed = 0;
/* priv_lock() is not taken to allow concurrent calls. */
-
if (priv_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
return -1;
strerror(ret));
goto out;
}
-
fc_conf->autoneg = ethpause.autoneg;
if (ethpause.rx_pause && ethpause.tx_pause)
fc_conf->mode = RTE_FC_FULL;
else
fc_conf->mode = RTE_FC_NONE;
ret = 0;
-
out:
priv_unlock(priv);
assert(ret >= 0);
ethpause.tx_pause = 1;
else
ethpause.tx_pause = 0;
-
priv_lock(priv);
if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
ret = errno;
goto out;
}
ret = 0;
-
out:
priv_unlock(priv);
assert(ret >= 0);
rte_intr_callback_register(&priv->intr_handle,
mlx5_dev_interrupt_handler, dev);
}
-
rc = priv_socket_init(priv);
if (!rc && priv->primary_socket) {
priv->intr_handle_socket.fd = priv->primary_socket;
.flags_mask = IBV_WQ_FLAGS_CVLAN_STRIPPING,
.flags = vlan_offloads,
};
-
err = mlx5_glue->modify_wq(rxq_ctrl->ibv->wq, &mod);
if (err) {
ERROR("%p: failed to modified stripping mode: %s",
(void *)priv, strerror(err));
return;
}
-
/* Update related bits in RX queue. */
rxq->vlan_strip = !!on;
}
ERROR("VLAN stripping is not supported");
return;
}
-
/* Validate queue number */
if (queue >= priv->rxqs_n) {
ERROR("VLAN stripping, invalid queue number %d", queue);
return;
}
-
priv_lock(priv);
priv_vlan_strip_queue_set(priv, queue, on);
priv_unlock(priv);
ERROR("VLAN stripping is not supported");
return 0;
}
-
/* Run on every RX queue and set/reset VLAN stripping. */
priv_lock(priv);
for (i = 0; (i != priv->rxqs_n); i++)
priv_vlan_strip_queue_set(priv, i, hw_vlan_strip);
priv_unlock(priv);
}
-
return 0;
}