Other kdrv = Y
ARMv8 = Y
Power8 = Y
-x86-32 = Y
x86-64 = Y
Usage doc = Y
This library basically implements send/receive calls to the hardware
queues.
-- **Kernel modules** (mlnx-ofed-kernel)
+- **Kernel modules**
They provide the kernel-side Verbs API and low level device drivers that
manage actual hardware initialization and resources sharing with user
Both libraries are BSD and GPL licensed. Linux kernel modules are GPL
licensed.
-Currently supported by DPDK:
+Installation
+~~~~~~~~~~~~
-- Mellanox OFED version: **4.1**.
+Either RDMA Core library with a recent enough Linux kernel release
+(recommended) or Mellanox OFED, which provides compatibility with older
+releases.
+
+RMDA Core with Linux Kernel
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Minimal kernel version : 4.13-rc4 (see `Linux installation documentation`_)
+- Minimal rdma-core version: v15 (see `RDMA Core installation documentation`_)
+
+.. _`Linux installation documentation`: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/plain/Documentation/admin-guide/README.rst
+.. _`RDMA Core installation documentation`: https://raw.githubusercontent.com/linux-rdma/rdma-core/master/README.md
+
+Mellanox OFED
+^^^^^^^^^^^^^
+
+- Mellanox OFED version: **4.2**.
- firmware version:
- ConnectX-4: **12.20.1010** and above.
- ConnectX-5: **16.20.1010** and above.
- ConnectX-5 Ex: **16.20.1010** and above.
-Getting Mellanox OFED
-~~~~~~~~~~~~~~~~~~~~~
-
While these libraries and kernel modules are available on OpenFabrics
Alliance's `website <https://www.openfabrics.org/>`__ and provided by package
managers on most distributions, this PMD requires Ethernet extensions that
* Mellanox(R) ConnectX(R)-5 100G MCX556A-ECAT (2x100G)
* Mellanox(R) ConnectX(R)-5 Ex EN 100G MCX516A-CDAT (2x100G)
-Quick Start Guide
------------------
+Quick Start Guide on OFED
+-------------------------
1. Download latest Mellanox OFED. For more info check the `prerequisites`_.
CFLAGS += -D_XOPEN_SOURCE=600
CFLAGS += $(WERROR_FLAGS)
CFLAGS += -Wno-strict-prototypes
-LDLIBS += -libverbs
+LDLIBS += -libverbs -lmlx5
# A few warnings cannot be avoided in external headers.
CFLAGS += -Wno-error=cast-qual
mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
$Q $(RM) -f -- '$@'
$Q sh -- '$<' '$@' \
- HAVE_VERBS_IBV_EXP_CQ_COMPRESSED_CQE \
- infiniband/verbs_exp.h \
- enum IBV_EXP_CQ_COMPRESSED_CQE \
+ HAVE_IBV_DEVICE_VXLAN_SUPPORT \
+ infiniband/verbs.h \
+ enum IBV_DEVICE_VXLAN_SUPPORT \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
- HAVE_VERBS_MLX5_ETH_VLAN_INLINE_HEADER_SIZE \
- infiniband/mlx5_hw.h \
- enum MLX5_ETH_VLAN_INLINE_HEADER_SIZE \
+ HAVE_IBV_WQ_FLAG_RX_END_PADDING \
+ infiniband/verbs.h \
+ enum IBV_WQ_FLAG_RX_END_PADDING \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
- HAVE_VERBS_MLX5_OPCODE_TSO \
- infiniband/mlx5_hw.h \
- enum MLX5_OPCODE_TSO \
+ HAVE_IBV_MLX5_MOD_MPW \
+ infiniband/mlx5dv.h \
+ enum MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED \
$(AUTOCONF_OUTPUT)
$Q sh -- '$<' '$@' \
HAVE_ETHTOOL_LINK_MODE_25G \
/usr/include/linux/ethtool.h \
enum ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT \
$(AUTOCONF_OUTPUT)
- $Q sh -- '$<' '$@' \
- HAVE_UPDATE_CQ_CI \
- infiniband/mlx5_hw.h \
- func ibv_mlx5_exp_update_cq_ci \
- $(AUTOCONF_OUTPUT)
# Create mlx5_autoconf.h or update it in case it differs from the new one.
/* Default PMD specific parameter value. */
#define MLX5_ARG_UNSET (-1)
+#ifndef HAVE_IBV_MLX5_MOD_MPW
+#define MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED (1 << 2)
+#define MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW (1 << 3)
+#endif
+
struct mlx5_args {
int cqe_comp;
int txq_inline;
.filter_ctrl = mlx5_dev_filter_ctrl,
.rx_descriptor_status = mlx5_rx_descriptor_status,
.tx_descriptor_status = mlx5_tx_descriptor_status,
-#ifdef HAVE_UPDATE_CQ_CI
.rx_queue_intr_enable = mlx5_rx_intr_enable,
.rx_queue_intr_disable = mlx5_rx_intr_disable,
-#endif
};
static struct {
struct ibv_device *ibv_dev;
int err = 0;
struct ibv_context *attr_ctx = NULL;
- struct ibv_device_attr device_attr;
+ struct ibv_device_attr_ex device_attr;
unsigned int sriov;
unsigned int mps;
unsigned int tunnel_en = 0;
int idx;
int i;
+ struct mlx5dv_context attrs_out;
(void)pci_drv;
assert(pci_drv == &mlx5_driver);
PCI_DEVICE_ID_MELLANOX_CONNECTX5VF) ||
(pci_dev->id.device_id ==
PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF));
- /*
- * Multi-packet send is supported by ConnectX-4 Lx PF as well
- * as all ConnectX-5 devices.
- */
switch (pci_dev->id.device_id) {
case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
tunnel_en = 1;
- mps = MLX5_MPW_DISABLED;
break;
case PCI_DEVICE_ID_MELLANOX_CONNECTX4LX:
- tunnel_en = 1;
- mps = MLX5_MPW;
- break;
case PCI_DEVICE_ID_MELLANOX_CONNECTX5:
case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
case PCI_DEVICE_ID_MELLANOX_CONNECTX5EX:
case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
tunnel_en = 1;
- mps = MLX5_MPW_ENHANCED;
break;
default:
- mps = MLX5_MPW_DISABLED;
+ break;
}
INFO("PCI information matches, using device \"%s\""
- " (SR-IOV: %s, %sMPS: %s)",
+ " (SR-IOV: %s)",
list[i]->name,
- sriov ? "true" : "false",
- mps == MLX5_MPW_ENHANCED ? "Enhanced " : "",
- mps != MLX5_MPW_DISABLED ? "true" : "false");
+ sriov ? "true" : "false");
attr_ctx = ibv_open_device(list[i]);
err = errno;
break;
ibv_dev = list[i];
DEBUG("device opened");
- if (ibv_query_device(attr_ctx, &device_attr))
+ /*
+ * Multi-packet send is supported by ConnectX-4 Lx PF as well
+ * as all ConnectX-5 devices.
+ */
+ mlx5dv_query_device(attr_ctx, &attrs_out);
+ if (attrs_out.flags & (MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW |
+ MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED)) {
+ INFO("Enhanced MPW is detected\n");
+ mps = MLX5_MPW_ENHANCED;
+ } else if (attrs_out.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+ INFO("MPW is detected\n");
+ mps = MLX5_MPW;
+ } else {
+ INFO("MPW is disabled\n");
+ mps = MLX5_MPW_DISABLED;
+ }
+ if (ibv_query_device_ex(attr_ctx, NULL, &device_attr))
goto error;
- INFO("%u port(s) detected", device_attr.phys_port_cnt);
+ INFO("%u port(s) detected", device_attr.orig_attr.phys_port_cnt);
- for (i = 0; i < device_attr.phys_port_cnt; i++) {
+ for (i = 0; i < device_attr.orig_attr.phys_port_cnt; i++) {
uint32_t port = i + 1; /* ports are indexed from one */
uint32_t test = (1 << i);
struct ibv_context *ctx = NULL;
struct ibv_pd *pd = NULL;
struct priv *priv = NULL;
struct rte_eth_dev *eth_dev;
- struct ibv_exp_device_attr exp_device_attr;
+ struct ibv_device_attr_ex device_attr_ex;
struct ether_addr mac;
uint16_t num_vfs = 0;
struct mlx5_args args = {
.rx_vec_en = MLX5_ARG_UNSET,
};
- exp_device_attr.comp_mask =
- IBV_EXP_DEVICE_ATTR_EXP_CAP_FLAGS |
- IBV_EXP_DEVICE_ATTR_RX_HASH |
- IBV_EXP_DEVICE_ATTR_VLAN_OFFLOADS |
- IBV_EXP_DEVICE_ATTR_RX_PAD_END_ALIGN |
- IBV_EXP_DEVICE_ATTR_TSO_CAPS |
- 0;
-
DEBUG("using port %u (%08" PRIx32 ")", port, test);
ctx = ibv_open_device(ibv_dev);
goto port_error;
}
mlx5_args_assign(priv, &args);
- if (ibv_exp_query_device(ctx, &exp_device_attr)) {
- ERROR("ibv_exp_query_device() failed");
- err = ENODEV;
+ if (ibv_query_device_ex(ctx, NULL, &device_attr_ex)) {
+ ERROR("ibv_query_device_ex() failed");
goto port_error;
}
priv->hw_csum =
- ((exp_device_attr.exp_device_cap_flags &
- IBV_EXP_DEVICE_RX_CSUM_TCP_UDP_PKT) &&
- (exp_device_attr.exp_device_cap_flags &
- IBV_EXP_DEVICE_RX_CSUM_IP_PKT));
+ !!(device_attr_ex.device_cap_flags_ex &
+ IBV_DEVICE_RAW_IP_CSUM);
DEBUG("checksum offloading is %ssupported",
(priv->hw_csum ? "" : "not "));
+#ifdef HAVE_IBV_DEVICE_VXLAN_SUPPORT
priv->hw_csum_l2tun = !!(exp_device_attr.exp_device_cap_flags &
- IBV_EXP_DEVICE_VXLAN_SUPPORT);
+ IBV_DEVICE_VXLAN_SUPPORT);
+#endif
DEBUG("L2 tunnel checksum offloads are %ssupported",
(priv->hw_csum_l2tun ? "" : "not "));
- priv->ind_table_max_size = exp_device_attr.rx_hash_caps.max_rwq_indirection_table_size;
+ priv->ind_table_max_size =
+ device_attr_ex.rss_caps.max_rwq_indirection_table_size;
/* Remove this check once DPDK supports larger/variable
* indirection tables. */
if (priv->ind_table_max_size >
priv->ind_table_max_size = ETH_RSS_RETA_SIZE_512;
DEBUG("maximum RX indirection table size is %u",
priv->ind_table_max_size);
- priv->hw_vlan_strip = !!(exp_device_attr.wq_vlan_offloads_cap &
- IBV_EXP_RECEIVE_WQ_CVLAN_STRIP);
+ priv->hw_vlan_strip = !!(device_attr_ex.raw_packet_caps &
+ IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
DEBUG("VLAN stripping is %ssupported",
(priv->hw_vlan_strip ? "" : "not "));
- priv->hw_fcs_strip = !!(exp_device_attr.exp_device_cap_flags &
- IBV_EXP_DEVICE_SCATTER_FCS);
+ priv->hw_fcs_strip =
+ !!(device_attr_ex.orig_attr.device_cap_flags &
+ IBV_WQ_FLAGS_SCATTER_FCS);
DEBUG("FCS stripping configuration is %ssupported",
(priv->hw_fcs_strip ? "" : "not "));
- priv->hw_padding = !!exp_device_attr.rx_pad_end_addr_align;
+#ifdef HAVE_IBV_WQ_FLAG_RX_END_PADDING
+ priv->hw_padding = !!device_attr_ex.rx_pad_end_addr_align;
+#endif
DEBUG("hardware RX end alignment padding is %ssupported",
(priv->hw_padding ? "" : "not "));
priv_get_num_vfs(priv, &num_vfs);
priv->sriov = (num_vfs || sriov);
priv->tso = ((priv->tso) &&
- (exp_device_attr.tso_caps.max_tso > 0) &&
- (exp_device_attr.tso_caps.supported_qpts &
- (1 << IBV_QPT_RAW_ETH)));
+ (device_attr_ex.tso_caps.max_tso > 0) &&
+ (device_attr_ex.tso_caps.supported_qpts &
+ (1 << IBV_QPT_RAW_PACKET)));
if (priv->tso)
priv->max_tso_payload_sz =
- exp_device_attr.tso_caps.max_tso;
+ device_attr_ex.tso_caps.max_tso;
if (priv->mps && !mps) {
ERROR("multi-packet send not supported on this device"
" (" MLX5_TXQ_MPW_EN ")");
struct priv {
struct rte_eth_dev *dev; /* Ethernet device. */
struct ibv_context *ctx; /* Verbs context. */
- struct ibv_device_attr device_attr; /* Device properties. */
+ struct ibv_device_attr_ex device_attr; /* Device properties. */
struct ibv_pd *pd; /* Protection Domain. */
/*
* MAC addresses array and configuration bit-field.
struct rxq *(*rxqs)[]; /* RX queues. */
struct txq *(*txqs)[]; /* TX queues. */
/* Indirection tables referencing all RX WQs. */
- struct ibv_exp_rwq_ind_table *(*ind_tables)[];
+ struct ibv_rwq_ind_table *(*ind_tables)[];
unsigned int ind_tables_n; /* Number of indirection tables. */
unsigned int ind_table_max_size; /* Maximum indirection table size. */
/* Hash RX QPs feeding the indirection table. */
* Since we need one CQ per QP, the limit is the minimum number
* between the two values.
*/
- max = ((priv->device_attr.max_cq > priv->device_attr.max_qp) ?
- priv->device_attr.max_qp : priv->device_attr.max_cq);
+ max = RTE_MIN(priv->device_attr.orig_attr.max_cq,
+ priv->device_attr.orig_attr.max_qp);
/* If max >= 65535 then max = 0, max_rx_queues is uint16_t. */
if (max >= 65535)
max = 65535;
uint16_t queue; /* Queue assigned to if FDIR match. */
enum rte_eth_fdir_behavior behavior;
struct fdir_flow_desc desc;
- struct ibv_exp_flow *flow;
+ struct ibv_flow *flow;
};
LIST_HEAD(fdir_filter_list, mlx5_fdir_filter);
struct mlx5_fdir_filter *mlx5_fdir_filter,
struct fdir_queue *fdir_queue)
{
- struct ibv_exp_flow *flow;
+ struct ibv_flow *flow;
struct fdir_flow_desc *desc = &mlx5_fdir_filter->desc;
enum rte_fdir_mode fdir_mode =
priv->dev->data->dev_conf.fdir_conf.mode;
struct rte_eth_fdir_masks *mask =
&priv->dev->data->dev_conf.fdir_conf.mask;
FLOW_ATTR_SPEC_ETH(data, priv_flow_attr(priv, NULL, 0, desc->type));
- struct ibv_exp_flow_attr *attr = &data->attr;
+ struct ibv_flow_attr *attr = &data->attr;
uintptr_t spec_offset = (uintptr_t)&data->spec;
- struct ibv_exp_flow_spec_eth *spec_eth;
- struct ibv_exp_flow_spec_ipv4 *spec_ipv4;
- struct ibv_exp_flow_spec_ipv6 *spec_ipv6;
- struct ibv_exp_flow_spec_tcp_udp *spec_tcp_udp;
+ struct ibv_flow_spec_eth *spec_eth;
+ struct ibv_flow_spec_ipv4 *spec_ipv4;
+ struct ibv_flow_spec_ipv6 *spec_ipv6;
+ struct ibv_flow_spec_tcp_udp *spec_tcp_udp;
struct mlx5_fdir_filter *iter_fdir_filter;
unsigned int i;
priv_flow_attr(priv, attr, sizeof(data), desc->type);
/* Set Ethernet spec */
- spec_eth = (struct ibv_exp_flow_spec_eth *)spec_offset;
+ spec_eth = (struct ibv_flow_spec_eth *)spec_offset;
/* The first specification must be Ethernet. */
- assert(spec_eth->type == IBV_EXP_FLOW_SPEC_ETH);
+ assert(spec_eth->type == IBV_FLOW_SPEC_ETH);
assert(spec_eth->size == sizeof(*spec_eth));
/* VLAN ID */
spec_offset += spec_eth->size;
/* Set IP spec */
- spec_ipv4 = (struct ibv_exp_flow_spec_ipv4 *)spec_offset;
+ spec_ipv4 = (struct ibv_flow_spec_ipv4 *)spec_offset;
/* The second specification must be IP. */
- assert(spec_ipv4->type == IBV_EXP_FLOW_SPEC_IPV4);
+ assert(spec_ipv4->type == IBV_FLOW_SPEC_IPV4);
assert(spec_ipv4->size == sizeof(*spec_ipv4));
spec_ipv4->val.src_ip =
spec_offset += spec_eth->size;
/* Set IP spec */
- spec_ipv6 = (struct ibv_exp_flow_spec_ipv6 *)spec_offset;
+ spec_ipv6 = (struct ibv_flow_spec_ipv6 *)spec_offset;
/* The second specification must be IP. */
- assert(spec_ipv6->type == IBV_EXP_FLOW_SPEC_IPV6);
+ assert(spec_ipv6->type == IBV_FLOW_SPEC_IPV6);
assert(spec_ipv6->size == sizeof(*spec_ipv6));
for (i = 0; i != RTE_DIM(desc->src_ip); ++i) {
}
/* Set TCP/UDP flow specification. */
- spec_tcp_udp = (struct ibv_exp_flow_spec_tcp_udp *)spec_offset;
+ spec_tcp_udp = (struct ibv_flow_spec_tcp_udp *)spec_offset;
/* The third specification must be TCP/UDP. */
- assert(spec_tcp_udp->type == IBV_EXP_FLOW_SPEC_TCP ||
- spec_tcp_udp->type == IBV_EXP_FLOW_SPEC_UDP);
+ assert(spec_tcp_udp->type == IBV_FLOW_SPEC_TCP ||
+ spec_tcp_udp->type == IBV_FLOW_SPEC_UDP);
assert(spec_tcp_udp->size == sizeof(*spec_tcp_udp));
spec_tcp_udp->val.src_port = desc->src_port & mask->src_port_mask;
create_flow:
errno = 0;
- flow = ibv_exp_create_flow(fdir_queue->qp, attr);
+ flow = ibv_create_flow(fdir_queue->qp, attr);
if (flow == NULL) {
/* It's not clear whether errno is always set in this case. */
ERROR("%p: flow director configuration failed, errno=%d: %s",
assert(idx < priv->rxqs_n);
if (fdir_queue == rxq_ctrl->fdir_queue &&
fdir_filter->flow != NULL) {
- claim_zero(ibv_exp_destroy_flow(fdir_filter->flow));
+ claim_zero(ibv_destroy_flow(fdir_filter->flow));
fdir_filter->flow = NULL;
}
}
assert(fdir_queue->qp);
claim_zero(ibv_destroy_qp(fdir_queue->qp));
assert(fdir_queue->ind_table);
- claim_zero(ibv_exp_destroy_rwq_ind_table(fdir_queue->ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(fdir_queue->ind_table));
if (fdir_queue->wq)
- claim_zero(ibv_exp_destroy_wq(fdir_queue->wq));
+ claim_zero(ibv_destroy_wq(fdir_queue->wq));
if (fdir_queue->cq)
claim_zero(ibv_destroy_cq(fdir_queue->cq));
#ifndef NDEBUG
* Related flow director queue on success, NULL otherwise.
*/
static struct fdir_queue *
-priv_fdir_queue_create(struct priv *priv, struct ibv_exp_wq *wq,
+priv_fdir_queue_create(struct priv *priv, struct ibv_wq *wq,
unsigned int socket)
{
struct fdir_queue *fdir_queue;
assert(priv->pd);
assert(priv->ctx);
if (!wq) {
- fdir_queue->cq = ibv_exp_create_cq(
- priv->ctx, 1, NULL, NULL, 0,
- &(struct ibv_exp_cq_init_attr){
- .comp_mask = 0,
- });
+ fdir_queue->cq = ibv_create_cq(
+ priv->ctx, 1, NULL, NULL, 0);
if (!fdir_queue->cq) {
ERROR("cannot create flow director CQ");
goto error;
}
- fdir_queue->wq = ibv_exp_create_wq(
+ fdir_queue->wq = ibv_create_wq(
priv->ctx,
- &(struct ibv_exp_wq_init_attr){
- .wq_type = IBV_EXP_WQT_RQ,
- .max_recv_wr = 1,
- .max_recv_sge = 1,
+ &(struct ibv_wq_init_attr){
+ .wq_type = IBV_WQT_RQ,
+ .max_wr = 1,
+ .max_sge = 1,
.pd = priv->pd,
.cq = fdir_queue->cq,
});
}
wq = fdir_queue->wq;
}
- fdir_queue->ind_table = ibv_exp_create_rwq_ind_table(
+ fdir_queue->ind_table = ibv_create_rwq_ind_table(
priv->ctx,
- &(struct ibv_exp_rwq_ind_table_init_attr){
- .pd = priv->pd,
+ &(struct ibv_rwq_ind_table_init_attr){
.log_ind_tbl_size = 0,
.ind_tbl = &wq,
.comp_mask = 0,
ERROR("cannot create flow director indirection table");
goto error;
}
- fdir_queue->qp = ibv_exp_create_qp(
+ fdir_queue->qp = ibv_create_qp_ex(
priv->ctx,
- &(struct ibv_exp_qp_init_attr){
+ &(struct ibv_qp_init_attr_ex){
.qp_type = IBV_QPT_RAW_PACKET,
.comp_mask =
- IBV_EXP_QP_INIT_ATTR_PD |
- IBV_EXP_QP_INIT_ATTR_PORT |
- IBV_EXP_QP_INIT_ATTR_RX_HASH,
- .pd = priv->pd,
- .rx_hash_conf = &(struct ibv_exp_rx_hash_conf){
+ IBV_QP_INIT_ATTR_PD |
+ IBV_QP_INIT_ATTR_IND_TABLE |
+ IBV_QP_INIT_ATTR_RX_HASH,
+ .rx_hash_conf = (struct ibv_rx_hash_conf){
.rx_hash_function =
- IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
+ IBV_RX_HASH_FUNC_TOEPLITZ,
.rx_hash_key_len = rss_hash_default_key_len,
.rx_hash_key = rss_hash_default_key,
.rx_hash_fields_mask = 0,
- .rwq_ind_tbl = fdir_queue->ind_table,
},
- .port_num = priv->port,
+ .rwq_ind_tbl = fdir_queue->ind_table,
+ .pd = priv->pd,
});
if (!fdir_queue->qp) {
ERROR("cannot create flow director hash RX QP");
assert(fdir_queue);
assert(!fdir_queue->qp);
if (fdir_queue->ind_table)
- claim_zero(ibv_exp_destroy_rwq_ind_table
+ claim_zero(ibv_destroy_rwq_ind_table
(fdir_queue->ind_table));
if (fdir_queue->wq)
- claim_zero(ibv_exp_destroy_wq(fdir_queue->wq));
+ claim_zero(ibv_destroy_wq(fdir_queue->wq));
if (fdir_queue->cq)
claim_zero(ibv_destroy_cq(fdir_queue->cq));
rte_free(fdir_queue);
struct mlx5_fdir_filter *mlx5_fdir_filter;
while ((mlx5_fdir_filter = LIST_FIRST(priv->fdir_filter_list))) {
- struct ibv_exp_flow *flow = mlx5_fdir_filter->flow;
+ struct ibv_flow *flow = mlx5_fdir_filter->flow;
DEBUG("%p: flushing flow director filter %p",
(void *)priv, (void *)mlx5_fdir_filter);
LIST_REMOVE(mlx5_fdir_filter, next);
if (flow != NULL)
- claim_zero(ibv_exp_destroy_flow(flow));
+ claim_zero(ibv_destroy_flow(flow));
rte_free(mlx5_fdir_filter);
}
}
/* Run on every flow director filter and destroy flow handle. */
LIST_FOREACH(mlx5_fdir_filter, priv->fdir_filter_list, next) {
- struct ibv_exp_flow *flow;
+ struct ibv_flow *flow;
/* Only valid elements should be in the list */
assert(mlx5_fdir_filter != NULL);
/* Destroy flow handle */
if (flow != NULL) {
- claim_zero(ibv_exp_destroy_flow(flow));
+ claim_zero(ibv_destroy_flow(flow));
mlx5_fdir_filter->flow = NULL;
}
}
mlx5_fdir_filter = priv_find_filter_in_list(priv, fdir_filter);
if (mlx5_fdir_filter != NULL) {
- struct ibv_exp_flow *flow = mlx5_fdir_filter->flow;
+ struct ibv_flow *flow = mlx5_fdir_filter->flow;
int err = 0;
/* Update queue number. */
/* Destroy flow handle. */
if (flow != NULL) {
- claim_zero(ibv_exp_destroy_flow(flow));
+ claim_zero(ibv_destroy_flow(flow));
mlx5_fdir_filter->flow = NULL;
}
DEBUG("%p: flow director filter %p updated",
mlx5_fdir_filter = priv_find_filter_in_list(priv, fdir_filter);
if (mlx5_fdir_filter != NULL) {
- struct ibv_exp_flow *flow = mlx5_fdir_filter->flow;
+ struct ibv_flow *flow = mlx5_fdir_filter->flow;
/* Remove element from list. */
LIST_REMOVE(mlx5_fdir_filter, next);
/* Destroy flow handle. */
if (flow != NULL) {
- claim_zero(ibv_exp_destroy_flow(flow));
+ claim_zero(ibv_destroy_flow(flow));
mlx5_fdir_filter->flow = NULL;
}
struct rte_flow {
TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
- struct ibv_exp_flow_attr *ibv_attr; /**< Pointer to Verbs attributes. */
- struct ibv_exp_rwq_ind_table *ind_table; /**< Indirection table. */
+ struct ibv_flow_attr *ibv_attr; /**< Pointer to Verbs attributes. */
+ struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
struct ibv_qp *qp; /**< Verbs queue pair. */
- struct ibv_exp_flow *ibv_flow; /**< Verbs flow. */
- struct ibv_exp_wq *wq; /**< Verbs work queue. */
+ struct ibv_flow *ibv_flow; /**< Verbs flow. */
+ struct ibv_wq *wq; /**< Verbs work queue. */
struct ibv_cq *cq; /**< Verbs completion queue. */
uint16_t rxqs_n; /**< Number of queues in this flow, 0 if drop queue. */
uint32_t mark:1; /**< Set if the flow is marked. */
.default_mask = &rte_flow_item_eth_mask,
.mask_sz = sizeof(struct rte_flow_item_eth),
.convert = mlx5_flow_create_eth,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_eth),
+ .dst_sz = sizeof(struct ibv_flow_spec_eth),
},
[RTE_FLOW_ITEM_TYPE_VLAN] = {
.items = ITEMS(RTE_FLOW_ITEM_TYPE_IPV4,
.default_mask = &rte_flow_item_ipv4_mask,
.mask_sz = sizeof(struct rte_flow_item_ipv4),
.convert = mlx5_flow_create_ipv4,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_ipv4_ext),
+ .dst_sz = sizeof(struct ibv_flow_spec_ipv4_ext),
},
[RTE_FLOW_ITEM_TYPE_IPV6] = {
.items = ITEMS(RTE_FLOW_ITEM_TYPE_UDP,
.default_mask = &rte_flow_item_ipv6_mask,
.mask_sz = sizeof(struct rte_flow_item_ipv6),
.convert = mlx5_flow_create_ipv6,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_ipv6_ext),
+ .dst_sz = sizeof(struct ibv_flow_spec_ipv6),
},
[RTE_FLOW_ITEM_TYPE_UDP] = {
.items = ITEMS(RTE_FLOW_ITEM_TYPE_VXLAN),
.default_mask = &rte_flow_item_udp_mask,
.mask_sz = sizeof(struct rte_flow_item_udp),
.convert = mlx5_flow_create_udp,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_tcp_udp),
+ .dst_sz = sizeof(struct ibv_flow_spec_tcp_udp),
},
[RTE_FLOW_ITEM_TYPE_TCP] = {
.actions = valid_actions,
.default_mask = &rte_flow_item_tcp_mask,
.mask_sz = sizeof(struct rte_flow_item_tcp),
.convert = mlx5_flow_create_tcp,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_tcp_udp),
+ .dst_sz = sizeof(struct ibv_flow_spec_tcp_udp),
},
[RTE_FLOW_ITEM_TYPE_VXLAN] = {
.items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH),
.default_mask = &rte_flow_item_vxlan_mask,
.mask_sz = sizeof(struct rte_flow_item_vxlan),
.convert = mlx5_flow_create_vxlan,
- .dst_sz = sizeof(struct ibv_exp_flow_spec_tunnel),
+ .dst_sz = sizeof(struct ibv_flow_spec_tunnel),
},
};
/** Structure to pass to the conversion function. */
struct mlx5_flow {
- struct ibv_exp_flow_attr *ibv_attr; /**< Verbs attribute. */
+ struct ibv_flow_attr *ibv_attr; /**< Verbs attribute. */
unsigned int offset; /**< Offset in bytes in the ibv_attr buffer. */
uint32_t inner; /**< Set once VXLAN is encountered. */
uint64_t hash_fields; /**< Fields that participate in the hash. */
/** Structure for Drop queue. */
struct rte_flow_drop {
- struct ibv_exp_rwq_ind_table *ind_table; /**< Indirection table. */
+ struct ibv_rwq_ind_table *ind_table; /**< Indirection table. */
struct ibv_qp *qp; /**< Verbs queue pair. */
- struct ibv_exp_wq *wq; /**< Verbs work queue. */
+ struct ibv_wq *wq; /**< Verbs work queue. */
struct ibv_cq *cq; /**< Verbs completion queue. */
};
}
}
if (action->mark && !flow->ibv_attr && !action->drop)
- flow->offset += sizeof(struct ibv_exp_flow_spec_action_tag);
+ flow->offset += sizeof(struct ibv_flow_spec_action_tag);
if (!flow->ibv_attr && action->drop)
- flow->offset += sizeof(struct ibv_exp_flow_spec_action_drop);
+ flow->offset += sizeof(struct ibv_flow_spec_action_drop);
if (!action->queue && !action->drop) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
NULL, "no valid action");
{
struct priv *priv = dev->data->dev_private;
int ret;
- struct mlx5_flow flow = { .offset = sizeof(struct ibv_exp_flow_attr) };
+ struct mlx5_flow flow = { .offset = sizeof(struct ibv_flow_attr) };
struct mlx5_flow_action action = {
.queue = 0,
.drop = 0,
const struct rte_flow_item_eth *spec = item->spec;
const struct rte_flow_item_eth *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_eth *eth;
- const unsigned int eth_size = sizeof(struct ibv_exp_flow_spec_eth);
+ struct ibv_flow_spec_eth *eth;
+ const unsigned int eth_size = sizeof(struct ibv_flow_spec_eth);
unsigned int i;
++flow->ibv_attr->num_of_specs;
flow->ibv_attr->priority = 2;
flow->hash_fields = 0;
eth = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *eth = (struct ibv_exp_flow_spec_eth) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_ETH,
+ *eth = (struct ibv_flow_spec_eth) {
+ .type = flow->inner | IBV_FLOW_SPEC_ETH,
.size = eth_size,
};
if (!spec)
const struct rte_flow_item_vlan *spec = item->spec;
const struct rte_flow_item_vlan *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_eth *eth;
- const unsigned int eth_size = sizeof(struct ibv_exp_flow_spec_eth);
+ struct ibv_flow_spec_eth *eth;
+ const unsigned int eth_size = sizeof(struct ibv_flow_spec_eth);
eth = (void *)((uintptr_t)flow->ibv_attr + flow->offset - eth_size);
if (!spec)
const struct rte_flow_item_ipv4 *spec = item->spec;
const struct rte_flow_item_ipv4 *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_ipv4_ext *ipv4;
- unsigned int ipv4_size = sizeof(struct ibv_exp_flow_spec_ipv4_ext);
+ struct ibv_flow_spec_ipv4_ext *ipv4;
+ unsigned int ipv4_size = sizeof(struct ibv_flow_spec_ipv4_ext);
++flow->ibv_attr->num_of_specs;
flow->ibv_attr->priority = 1;
- flow->hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
- IBV_EXP_RX_HASH_DST_IPV4);
+ flow->hash_fields = (IBV_RX_HASH_SRC_IPV4 |
+ IBV_RX_HASH_DST_IPV4);
ipv4 = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *ipv4 = (struct ibv_exp_flow_spec_ipv4_ext) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_IPV4_EXT,
+ *ipv4 = (struct ibv_flow_spec_ipv4_ext) {
+ .type = flow->inner | IBV_FLOW_SPEC_IPV4_EXT,
.size = ipv4_size,
};
if (!spec)
return 0;
if (!mask)
mask = default_mask;
- ipv4->val = (struct ibv_exp_flow_ipv4_ext_filter){
+ ipv4->val = (struct ibv_flow_ipv4_ext_filter){
.src_ip = spec->hdr.src_addr,
.dst_ip = spec->hdr.dst_addr,
.proto = spec->hdr.next_proto_id,
.tos = spec->hdr.type_of_service,
};
- ipv4->mask = (struct ibv_exp_flow_ipv4_ext_filter){
+ ipv4->mask = (struct ibv_flow_ipv4_ext_filter){
.src_ip = mask->hdr.src_addr,
.dst_ip = mask->hdr.dst_addr,
.proto = mask->hdr.next_proto_id,
const struct rte_flow_item_ipv6 *spec = item->spec;
const struct rte_flow_item_ipv6 *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_ipv6_ext *ipv6;
- unsigned int ipv6_size = sizeof(struct ibv_exp_flow_spec_ipv6_ext);
+ struct ibv_flow_spec_ipv6 *ipv6;
+ unsigned int ipv6_size = sizeof(struct ibv_flow_spec_ipv6);
unsigned int i;
++flow->ibv_attr->num_of_specs;
flow->ibv_attr->priority = 1;
- flow->hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
- IBV_EXP_RX_HASH_DST_IPV6);
+ flow->hash_fields = (IBV_RX_HASH_SRC_IPV6 |
+ IBV_RX_HASH_DST_IPV6);
ipv6 = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *ipv6 = (struct ibv_exp_flow_spec_ipv6_ext) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_IPV6_EXT,
+ *ipv6 = (struct ibv_flow_spec_ipv6) {
+ .type = flow->inner | IBV_FLOW_SPEC_IPV6,
.size = ipv6_size,
};
if (!spec)
const struct rte_flow_item_udp *spec = item->spec;
const struct rte_flow_item_udp *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_tcp_udp *udp;
- unsigned int udp_size = sizeof(struct ibv_exp_flow_spec_tcp_udp);
+ struct ibv_flow_spec_tcp_udp *udp;
+ unsigned int udp_size = sizeof(struct ibv_flow_spec_tcp_udp);
++flow->ibv_attr->num_of_specs;
flow->ibv_attr->priority = 0;
- flow->hash_fields |= (IBV_EXP_RX_HASH_SRC_PORT_UDP |
- IBV_EXP_RX_HASH_DST_PORT_UDP);
+ flow->hash_fields |= (IBV_RX_HASH_SRC_PORT_UDP |
+ IBV_RX_HASH_DST_PORT_UDP);
udp = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *udp = (struct ibv_exp_flow_spec_tcp_udp) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_UDP,
+ *udp = (struct ibv_flow_spec_tcp_udp) {
+ .type = flow->inner | IBV_FLOW_SPEC_UDP,
.size = udp_size,
};
if (!spec)
const struct rte_flow_item_tcp *spec = item->spec;
const struct rte_flow_item_tcp *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_tcp_udp *tcp;
- unsigned int tcp_size = sizeof(struct ibv_exp_flow_spec_tcp_udp);
+ struct ibv_flow_spec_tcp_udp *tcp;
+ unsigned int tcp_size = sizeof(struct ibv_flow_spec_tcp_udp);
++flow->ibv_attr->num_of_specs;
flow->ibv_attr->priority = 0;
- flow->hash_fields |= (IBV_EXP_RX_HASH_SRC_PORT_TCP |
- IBV_EXP_RX_HASH_DST_PORT_TCP);
+ flow->hash_fields |= (IBV_RX_HASH_SRC_PORT_TCP |
+ IBV_RX_HASH_DST_PORT_TCP);
tcp = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *tcp = (struct ibv_exp_flow_spec_tcp_udp) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_TCP,
+ *tcp = (struct ibv_flow_spec_tcp_udp) {
+ .type = flow->inner | IBV_FLOW_SPEC_TCP,
.size = tcp_size,
};
if (!spec)
const struct rte_flow_item_vxlan *spec = item->spec;
const struct rte_flow_item_vxlan *mask = item->mask;
struct mlx5_flow *flow = (struct mlx5_flow *)data;
- struct ibv_exp_flow_spec_tunnel *vxlan;
- unsigned int size = sizeof(struct ibv_exp_flow_spec_tunnel);
+ struct ibv_flow_spec_tunnel *vxlan;
+ unsigned int size = sizeof(struct ibv_flow_spec_tunnel);
union vni {
uint32_t vlan_id;
uint8_t vni[4];
flow->ibv_attr->priority = 0;
id.vni[0] = 0;
vxlan = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *vxlan = (struct ibv_exp_flow_spec_tunnel) {
- .type = flow->inner | IBV_EXP_FLOW_SPEC_VXLAN_TUNNEL,
+ *vxlan = (struct ibv_flow_spec_tunnel) {
+ .type = flow->inner | IBV_FLOW_SPEC_VXLAN_TUNNEL,
.size = size,
};
- flow->inner = IBV_EXP_FLOW_SPEC_INNER;
+ flow->inner = IBV_FLOW_SPEC_INNER;
if (!spec)
return 0;
if (!mask)
static int
mlx5_flow_create_flag_mark(struct mlx5_flow *flow, uint32_t mark_id)
{
- struct ibv_exp_flow_spec_action_tag *tag;
- unsigned int size = sizeof(struct ibv_exp_flow_spec_action_tag);
+ struct ibv_flow_spec_action_tag *tag;
+ unsigned int size = sizeof(struct ibv_flow_spec_action_tag);
tag = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *tag = (struct ibv_exp_flow_spec_action_tag){
- .type = IBV_EXP_FLOW_SPEC_ACTION_TAG,
+ *tag = (struct ibv_flow_spec_action_tag){
+ .type = IBV_FLOW_SPEC_ACTION_TAG,
.size = size,
.tag_id = mlx5_flow_mark_set(mark_id),
};
struct rte_flow_error *error)
{
struct rte_flow *rte_flow;
- struct ibv_exp_flow_spec_action_drop *drop;
- unsigned int size = sizeof(struct ibv_exp_flow_spec_action_drop);
+ struct ibv_flow_spec_action_drop *drop;
+ unsigned int size = sizeof(struct ibv_flow_spec_action_drop);
assert(priv->pd);
assert(priv->ctx);
}
rte_flow->drop = 1;
drop = (void *)((uintptr_t)flow->ibv_attr + flow->offset);
- *drop = (struct ibv_exp_flow_spec_action_drop){
- .type = IBV_EXP_FLOW_SPEC_ACTION_DROP,
+ *drop = (struct ibv_flow_spec_action_drop){
+ .type = IBV_FLOW_SPEC_ACTION_DROP,
.size = size,
};
++flow->ibv_attr->num_of_specs;
- flow->offset += sizeof(struct ibv_exp_flow_spec_action_drop);
+ flow->offset += sizeof(struct ibv_flow_spec_action_drop);
rte_flow->ibv_attr = flow->ibv_attr;
if (!priv->started)
return rte_flow;
rte_flow->qp = priv->flow_drop_queue->qp;
- rte_flow->ibv_flow = ibv_exp_create_flow(rte_flow->qp,
- rte_flow->ibv_attr);
+ rte_flow->ibv_flow = ibv_create_flow(rte_flow->qp,
+ rte_flow->ibv_attr);
if (!rte_flow->ibv_flow) {
rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
NULL, "flow rule creation failure");
unsigned int i;
unsigned int j;
const unsigned int wqs_n = 1 << log2above(action->queues_n);
- struct ibv_exp_wq *wqs[wqs_n];
+ struct ibv_wq *wqs[wqs_n];
assert(priv->pd);
assert(priv->ctx);
rte_flow->mark = action->mark;
rte_flow->ibv_attr = flow->ibv_attr;
rte_flow->hash_fields = flow->hash_fields;
- rte_flow->ind_table = ibv_exp_create_rwq_ind_table(
+ rte_flow->ind_table = ibv_create_rwq_ind_table(
priv->ctx,
- &(struct ibv_exp_rwq_ind_table_init_attr){
- .pd = priv->pd,
+ &(struct ibv_rwq_ind_table_init_attr){
.log_ind_tbl_size = log2above(action->queues_n),
.ind_tbl = wqs,
.comp_mask = 0,
NULL, "cannot allocate indirection table");
goto error;
}
- rte_flow->qp = ibv_exp_create_qp(
+ rte_flow->qp = ibv_create_qp_ex(
priv->ctx,
- &(struct ibv_exp_qp_init_attr){
+ &(struct ibv_qp_init_attr_ex){
.qp_type = IBV_QPT_RAW_PACKET,
.comp_mask =
- IBV_EXP_QP_INIT_ATTR_PD |
- IBV_EXP_QP_INIT_ATTR_PORT |
- IBV_EXP_QP_INIT_ATTR_RX_HASH,
- .pd = priv->pd,
- .rx_hash_conf = &(struct ibv_exp_rx_hash_conf){
+ IBV_QP_INIT_ATTR_PD |
+ IBV_QP_INIT_ATTR_IND_TABLE |
+ IBV_QP_INIT_ATTR_RX_HASH,
+ .rx_hash_conf = (struct ibv_rx_hash_conf){
.rx_hash_function =
- IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
+ IBV_RX_HASH_FUNC_TOEPLITZ,
.rx_hash_key_len = rss_hash_default_key_len,
.rx_hash_key = rss_hash_default_key,
.rx_hash_fields_mask = rte_flow->hash_fields,
- .rwq_ind_tbl = rte_flow->ind_table,
},
- .port_num = priv->port,
+ .rwq_ind_tbl = rte_flow->ind_table,
+ .pd = priv->pd
});
if (!rte_flow->qp) {
rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
}
if (!priv->started)
return rte_flow;
- rte_flow->ibv_flow = ibv_exp_create_flow(rte_flow->qp,
- rte_flow->ibv_attr);
+ rte_flow->ibv_flow = ibv_create_flow(rte_flow->qp,
+ rte_flow->ibv_attr);
if (!rte_flow->ibv_flow) {
rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
NULL, "flow rule creation failure");
if (rte_flow->qp)
ibv_destroy_qp(rte_flow->qp);
if (rte_flow->ind_table)
- ibv_exp_destroy_rwq_ind_table(rte_flow->ind_table);
+ ibv_destroy_rwq_ind_table(rte_flow->ind_table);
rte_free(rte_flow);
return NULL;
}
struct rte_flow_error *error)
{
struct rte_flow *rte_flow;
- struct mlx5_flow flow = { .offset = sizeof(struct ibv_exp_flow_attr), };
+ struct mlx5_flow flow = { .offset = sizeof(struct ibv_flow_attr), };
struct mlx5_flow_action action = {
.queue = 0,
.drop = 0,
if (err)
goto exit;
flow.ibv_attr = rte_malloc(__func__, flow.offset, 0);
- flow.offset = sizeof(struct ibv_exp_flow_attr);
+ flow.offset = sizeof(struct ibv_flow_attr);
if (!flow.ibv_attr) {
rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
NULL, "cannot allocate ibv_attr memory");
goto exit;
}
- *flow.ibv_attr = (struct ibv_exp_flow_attr){
- .type = IBV_EXP_FLOW_ATTR_NORMAL,
- .size = sizeof(struct ibv_exp_flow_attr),
+ *flow.ibv_attr = (struct ibv_flow_attr){
+ .type = IBV_FLOW_ATTR_NORMAL,
+ .size = sizeof(struct ibv_flow_attr),
.priority = attr->priority,
.num_of_specs = 0,
.port = 0,
.flags = 0,
- .reserved = 0,
};
flow.inner = 0;
flow.hash_fields = 0;
error, &flow, &action));
if (action.mark && !action.drop) {
mlx5_flow_create_flag_mark(&flow, action.mark_id);
- flow.offset += sizeof(struct ibv_exp_flow_spec_action_tag);
+ flow.offset += sizeof(struct ibv_flow_spec_action_tag);
}
if (action.drop)
rte_flow =
{
TAILQ_REMOVE(&priv->flows, flow, next);
if (flow->ibv_flow)
- claim_zero(ibv_exp_destroy_flow(flow->ibv_flow));
+ claim_zero(ibv_destroy_flow(flow->ibv_flow));
if (flow->drop)
goto free;
if (flow->qp)
claim_zero(ibv_destroy_qp(flow->qp));
if (flow->ind_table)
- claim_zero(ibv_exp_destroy_rwq_ind_table(flow->ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(flow->ind_table));
if (flow->mark) {
struct rte_flow *tmp;
struct rxq *rxq;
WARN("cannot allocate memory for drop queue");
goto error;
}
- fdq->cq = ibv_exp_create_cq(priv->ctx, 1, NULL, NULL, 0,
- &(struct ibv_exp_cq_init_attr){
- .comp_mask = 0,
- });
+ fdq->cq = ibv_create_cq(priv->ctx, 1, NULL, NULL, 0);
if (!fdq->cq) {
WARN("cannot allocate CQ for drop queue");
goto error;
}
- fdq->wq = ibv_exp_create_wq(priv->ctx,
- &(struct ibv_exp_wq_init_attr){
- .wq_type = IBV_EXP_WQT_RQ,
- .max_recv_wr = 1,
- .max_recv_sge = 1,
+ fdq->wq = ibv_create_wq(priv->ctx,
+ &(struct ibv_wq_init_attr){
+ .wq_type = IBV_WQT_RQ,
+ .max_wr = 1,
+ .max_sge = 1,
.pd = priv->pd,
.cq = fdq->cq,
});
WARN("cannot allocate WQ for drop queue");
goto error;
}
- fdq->ind_table = ibv_exp_create_rwq_ind_table(priv->ctx,
- &(struct ibv_exp_rwq_ind_table_init_attr){
- .pd = priv->pd,
+ fdq->ind_table = ibv_create_rwq_ind_table(priv->ctx,
+ &(struct ibv_rwq_ind_table_init_attr){
.log_ind_tbl_size = 0,
.ind_tbl = &fdq->wq,
.comp_mask = 0,
WARN("cannot allocate indirection table for drop queue");
goto error;
}
- fdq->qp = ibv_exp_create_qp(priv->ctx,
- &(struct ibv_exp_qp_init_attr){
+ fdq->qp = ibv_create_qp_ex(priv->ctx,
+ &(struct ibv_qp_init_attr_ex){
.qp_type = IBV_QPT_RAW_PACKET,
.comp_mask =
- IBV_EXP_QP_INIT_ATTR_PD |
- IBV_EXP_QP_INIT_ATTR_PORT |
- IBV_EXP_QP_INIT_ATTR_RX_HASH,
- .pd = priv->pd,
- .rx_hash_conf = &(struct ibv_exp_rx_hash_conf){
+ IBV_QP_INIT_ATTR_PD |
+ IBV_QP_INIT_ATTR_IND_TABLE |
+ IBV_QP_INIT_ATTR_RX_HASH,
+ .rx_hash_conf = (struct ibv_rx_hash_conf){
.rx_hash_function =
- IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
+ IBV_RX_HASH_FUNC_TOEPLITZ,
.rx_hash_key_len = rss_hash_default_key_len,
.rx_hash_key = rss_hash_default_key,
.rx_hash_fields_mask = 0,
- .rwq_ind_tbl = fdq->ind_table,
},
- .port_num = priv->port,
- });
+ .rwq_ind_tbl = fdq->ind_table,
+ .pd = priv->pd
+ });
if (!fdq->qp) {
WARN("cannot allocate QP for drop queue");
goto error;
if (fdq->qp)
claim_zero(ibv_destroy_qp(fdq->qp));
if (fdq->ind_table)
- claim_zero(ibv_exp_destroy_rwq_ind_table(fdq->ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(fdq->ind_table));
if (fdq->wq)
- claim_zero(ibv_exp_destroy_wq(fdq->wq));
+ claim_zero(ibv_destroy_wq(fdq->wq));
if (fdq->cq)
claim_zero(ibv_destroy_cq(fdq->cq));
if (fdq)
if (fdq->qp)
claim_zero(ibv_destroy_qp(fdq->qp));
if (fdq->ind_table)
- claim_zero(ibv_exp_destroy_rwq_ind_table(fdq->ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(fdq->ind_table));
if (fdq->wq)
- claim_zero(ibv_exp_destroy_wq(fdq->wq));
+ claim_zero(ibv_destroy_wq(fdq->wq));
if (fdq->cq)
claim_zero(ibv_destroy_cq(fdq->cq));
rte_free(fdq);
struct rte_flow *flow;
TAILQ_FOREACH_REVERSE(flow, &priv->flows, mlx5_flows, next) {
- claim_zero(ibv_exp_destroy_flow(flow->ibv_flow));
+ claim_zero(ibv_destroy_flow(flow->ibv_flow));
flow->ibv_flow = NULL;
if (flow->mark) {
unsigned int n;
qp = priv->flow_drop_queue->qp;
else
qp = flow->qp;
- flow->ibv_flow = ibv_exp_create_flow(qp, flow->ibv_attr);
+ flow->ibv_flow = ibv_create_flow(qp, flow->ibv_attr);
if (!flow->ibv_flow) {
DEBUG("Flow %p cannot be applied", (void *)flow);
rte_errno = EINVAL;
(*mac)[0], (*mac)[1], (*mac)[2], (*mac)[3], (*mac)[4], (*mac)[5],
mac_index,
vlan_index);
- claim_zero(ibv_exp_destroy_flow(hash_rxq->mac_flow
- [mac_index][vlan_index]));
+ claim_zero(ibv_destroy_flow(hash_rxq->mac_flow
+ [mac_index][vlan_index]));
hash_rxq->mac_flow[mac_index][vlan_index] = NULL;
}
hash_rxq_add_mac_flow(struct hash_rxq *hash_rxq, unsigned int mac_index,
unsigned int vlan_index)
{
- struct ibv_exp_flow *flow;
+ struct ibv_flow *flow;
struct priv *priv = hash_rxq->priv;
const uint8_t (*mac)[ETHER_ADDR_LEN] =
(const uint8_t (*)[ETHER_ADDR_LEN])
priv->mac[mac_index].addr_bytes;
FLOW_ATTR_SPEC_ETH(data, priv_flow_attr(priv, NULL, 0, hash_rxq->type));
- struct ibv_exp_flow_attr *attr = &data->attr;
- struct ibv_exp_flow_spec_eth *spec = &data->spec;
+ struct ibv_flow_attr *attr = &data->attr;
+ struct ibv_flow_spec_eth *spec = &data->spec;
unsigned int vlan_enabled = !!priv->vlan_filter_n;
unsigned int vlan_id = priv->vlan_filter[vlan_index];
assert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec);
priv_flow_attr(priv, attr, sizeof(data), hash_rxq->type);
/* The first specification must be Ethernet. */
- assert(spec->type == IBV_EXP_FLOW_SPEC_ETH);
+ assert(spec->type == IBV_FLOW_SPEC_ETH);
assert(spec->size == sizeof(*spec));
- *spec = (struct ibv_exp_flow_spec_eth){
- .type = IBV_EXP_FLOW_SPEC_ETH,
+ *spec = (struct ibv_flow_spec_eth){
+ .type = IBV_FLOW_SPEC_ETH,
.size = sizeof(*spec),
.val = {
.dst_mac = {
vlan_id);
/* Create related flow. */
errno = 0;
- flow = ibv_exp_create_flow(hash_rxq->qp, attr);
+ flow = ibv_create_flow(hash_rxq->qp, attr);
if (flow == NULL) {
/* It's not clear whether errno is always set in this case. */
ERROR("%p: flow configuration failed, errno=%d: %s",
#ifdef PEDANTIC
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
-#include <infiniband/mlx5_hw.h>
+#include <infiniband/mlx5dv.h>
#ifdef PEDANTIC
#pragma GCC diagnostic error "-Wpedantic"
#endif
uint8_t op_own;
};
+/* Adding direct verbs to data-path. */
+
+/* CQ sequence number mask. */
+#define MLX5_CQ_SQN_MASK 0x3
+
+/* CQ sequence number index. */
+#define MLX5_CQ_SQN_OFFSET 28
+
+/* CQ doorbell index mask. */
+#define MLX5_CI_MASK 0xffffff
+
+/* CQ doorbell offset. */
+#define MLX5_CQ_ARM_DB 1
+
+/* CQ doorbell offset*/
+#define MLX5_CQ_DOORBELL 0x20
+
+/* CQE format value. */
+#define MLX5_COMPRESSED 0x3
+
+/* CQE format mask. */
+#define MLX5E_CQE_FORMAT_MASK 0xc
+
+/* MPW opcode. */
+#define MLX5_OPC_MOD_MPW 0x01
+
+/* Compressed Rx CQE structure. */
+struct mlx5_mini_cqe8 {
+ union {
+ uint32_t rx_hash_result;
+ uint32_t checksum;
+ struct {
+ uint16_t wqe_counter;
+ uint8_t s_wqe_opcode;
+ uint8_t reserved;
+ } s_wqe_info;
+ };
+ uint32_t byte_cnt;
+};
+
/**
* Convert a user mark to flow mark.
*
unsigned int vlan_index)
{
struct priv *priv = hash_rxq->priv;
- struct ibv_exp_flow *flow;
+ struct ibv_flow *flow;
FLOW_ATTR_SPEC_ETH(data, priv_flow_attr(priv, NULL, 0, hash_rxq->type));
- struct ibv_exp_flow_attr *attr = &data->attr;
- struct ibv_exp_flow_spec_eth *spec = &data->spec;
+ struct ibv_flow_attr *attr = &data->attr;
+ struct ibv_flow_spec_eth *spec = &data->spec;
const uint8_t *mac;
const uint8_t *mask;
unsigned int vlan_enabled = (priv->vlan_filter_n &&
assert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec);
priv_flow_attr(priv, attr, sizeof(data), hash_rxq->type);
/* The first specification must be Ethernet. */
- assert(spec->type == IBV_EXP_FLOW_SPEC_ETH);
+ assert(spec->type == IBV_FLOW_SPEC_ETH);
assert(spec->size == sizeof(*spec));
mac = special_flow_init[flow_type].dst_mac_val;
mask = special_flow_init[flow_type].dst_mac_mask;
- *spec = (struct ibv_exp_flow_spec_eth){
- .type = IBV_EXP_FLOW_SPEC_ETH,
+ *spec = (struct ibv_flow_spec_eth){
+ .type = IBV_FLOW_SPEC_ETH,
.size = sizeof(*spec),
.val = {
.dst_mac = {
};
errno = 0;
- flow = ibv_exp_create_flow(hash_rxq->qp, attr);
+ flow = ibv_create_flow(hash_rxq->qp, attr);
if (flow == NULL) {
/* It's not clear whether errno is always set in this case. */
ERROR("%p: flow configuration failed, errno=%d: %s",
enum hash_rxq_flow_type flow_type,
unsigned int vlan_index)
{
- struct ibv_exp_flow *flow =
+ struct ibv_flow *flow =
hash_rxq->special_flow[flow_type][vlan_index];
if (flow == NULL)
return;
- claim_zero(ibv_exp_destroy_flow(flow));
+ claim_zero(ibv_destroy_flow(flow));
hash_rxq->special_flow[flow_type][vlan_index] = NULL;
DEBUG("%p: special flow %s (index %d) VLAN %u (index %u) disabled",
(void *)hash_rxq, hash_rxq_flow_type_str(flow_type), flow_type,
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <infiniband/verbs.h>
-#include <infiniband/arch.h>
-#include <infiniband/mlx5_hw.h>
+#include <infiniband/mlx5dv.h>
#ifdef PEDANTIC
#pragma GCC diagnostic error "-Wpedantic"
#endif
#include <rte_common.h>
#include <rte_interrupts.h>
#include <rte_debug.h>
+#include <rte_io.h>
#include "mlx5.h"
#include "mlx5_rxtx.h"
/* Initialization data for hash RX queues. */
const struct hash_rxq_init hash_rxq_init[] = {
[HASH_RXQ_TCPV4] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
- IBV_EXP_RX_HASH_DST_IPV4 |
- IBV_EXP_RX_HASH_SRC_PORT_TCP |
- IBV_EXP_RX_HASH_DST_PORT_TCP),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
+ IBV_RX_HASH_DST_IPV4 |
+ IBV_RX_HASH_SRC_PORT_TCP |
+ IBV_RX_HASH_DST_PORT_TCP),
.dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_TCP,
.flow_priority = 0,
.flow_spec.tcp_udp = {
- .type = IBV_EXP_FLOW_SPEC_TCP,
+ .type = IBV_FLOW_SPEC_TCP,
.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
},
.underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
},
[HASH_RXQ_UDPV4] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
- IBV_EXP_RX_HASH_DST_IPV4 |
- IBV_EXP_RX_HASH_SRC_PORT_UDP |
- IBV_EXP_RX_HASH_DST_PORT_UDP),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
+ IBV_RX_HASH_DST_IPV4 |
+ IBV_RX_HASH_SRC_PORT_UDP |
+ IBV_RX_HASH_DST_PORT_UDP),
.dpdk_rss_hf = ETH_RSS_NONFRAG_IPV4_UDP,
.flow_priority = 0,
.flow_spec.tcp_udp = {
- .type = IBV_EXP_FLOW_SPEC_UDP,
+ .type = IBV_FLOW_SPEC_UDP,
.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
},
.underlayer = &hash_rxq_init[HASH_RXQ_IPV4],
},
[HASH_RXQ_IPV4] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |
- IBV_EXP_RX_HASH_DST_IPV4),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV4 |
+ IBV_RX_HASH_DST_IPV4),
.dpdk_rss_hf = (ETH_RSS_IPV4 |
ETH_RSS_FRAG_IPV4),
.flow_priority = 1,
.flow_spec.ipv4 = {
- .type = IBV_EXP_FLOW_SPEC_IPV4,
+ .type = IBV_FLOW_SPEC_IPV4,
.size = sizeof(hash_rxq_init[0].flow_spec.ipv4),
},
.underlayer = &hash_rxq_init[HASH_RXQ_ETH],
},
[HASH_RXQ_TCPV6] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
- IBV_EXP_RX_HASH_DST_IPV6 |
- IBV_EXP_RX_HASH_SRC_PORT_TCP |
- IBV_EXP_RX_HASH_DST_PORT_TCP),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
+ IBV_RX_HASH_DST_IPV6 |
+ IBV_RX_HASH_SRC_PORT_TCP |
+ IBV_RX_HASH_DST_PORT_TCP),
.dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_TCP,
.flow_priority = 0,
.flow_spec.tcp_udp = {
- .type = IBV_EXP_FLOW_SPEC_TCP,
+ .type = IBV_FLOW_SPEC_TCP,
.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
},
.underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
},
[HASH_RXQ_UDPV6] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
- IBV_EXP_RX_HASH_DST_IPV6 |
- IBV_EXP_RX_HASH_SRC_PORT_UDP |
- IBV_EXP_RX_HASH_DST_PORT_UDP),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
+ IBV_RX_HASH_DST_IPV6 |
+ IBV_RX_HASH_SRC_PORT_UDP |
+ IBV_RX_HASH_DST_PORT_UDP),
.dpdk_rss_hf = ETH_RSS_NONFRAG_IPV6_UDP,
.flow_priority = 0,
.flow_spec.tcp_udp = {
- .type = IBV_EXP_FLOW_SPEC_UDP,
+ .type = IBV_FLOW_SPEC_UDP,
.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),
},
.underlayer = &hash_rxq_init[HASH_RXQ_IPV6],
},
[HASH_RXQ_IPV6] = {
- .hash_fields = (IBV_EXP_RX_HASH_SRC_IPV6 |
- IBV_EXP_RX_HASH_DST_IPV6),
+ .hash_fields = (IBV_RX_HASH_SRC_IPV6 |
+ IBV_RX_HASH_DST_IPV6),
.dpdk_rss_hf = (ETH_RSS_IPV6 |
ETH_RSS_FRAG_IPV6),
.flow_priority = 1,
.flow_spec.ipv6 = {
- .type = IBV_EXP_FLOW_SPEC_IPV6,
+ .type = IBV_FLOW_SPEC_IPV6,
.size = sizeof(hash_rxq_init[0].flow_spec.ipv6),
},
.underlayer = &hash_rxq_init[HASH_RXQ_ETH],
.dpdk_rss_hf = 0,
.flow_priority = 2,
.flow_spec.eth = {
- .type = IBV_EXP_FLOW_SPEC_ETH,
+ .type = IBV_FLOW_SPEC_ETH,
.size = sizeof(hash_rxq_init[0].flow_spec.eth),
},
.underlayer = NULL,
* Total size of the flow attribute buffer. No errors are defined.
*/
size_t
-priv_flow_attr(struct priv *priv, struct ibv_exp_flow_attr *flow_attr,
+priv_flow_attr(struct priv *priv, struct ibv_flow_attr *flow_attr,
size_t flow_attr_size, enum hash_rxq_type type)
{
size_t offset = sizeof(*flow_attr);
return offset;
flow_attr_size = offset;
init = &hash_rxq_init[type];
- *flow_attr = (struct ibv_exp_flow_attr){
- .type = IBV_EXP_FLOW_ATTR_NORMAL,
+ *flow_attr = (struct ibv_flow_attr){
+ .type = IBV_FLOW_ATTR_NORMAL,
/* Priorities < 3 are reserved for flow director. */
.priority = init->flow_priority + 3,
.num_of_specs = 0,
int
priv_create_hash_rxqs(struct priv *priv)
{
- struct ibv_exp_wq *wqs[priv->reta_idx_n];
+ struct ibv_wq *wqs[priv->reta_idx_n];
struct ind_table_init ind_table_init[IND_TABLE_INIT_N];
unsigned int ind_tables_n =
priv_make_ind_table_init(priv, &ind_table_init);
unsigned int hash_rxqs_n = 0;
struct hash_rxq (*hash_rxqs)[] = NULL;
- struct ibv_exp_rwq_ind_table *(*ind_tables)[] = NULL;
+ struct ibv_rwq_ind_table *(*ind_tables)[] = NULL;
unsigned int i;
unsigned int j;
unsigned int k;
goto error;
}
for (i = 0; (i != ind_tables_n); ++i) {
- struct ibv_exp_rwq_ind_table_init_attr ind_init_attr = {
- .pd = priv->pd,
+ struct ibv_rwq_ind_table_init_attr ind_init_attr = {
.log_ind_tbl_size = 0, /* Set below. */
.ind_tbl = wqs,
.comp_mask = 0,
};
unsigned int ind_tbl_size = ind_table_init[i].max_size;
- struct ibv_exp_rwq_ind_table *ind_table;
+ struct ibv_rwq_ind_table *ind_table;
if (priv->reta_idx_n < ind_tbl_size)
ind_tbl_size = priv->reta_idx_n;
ind_init_attr.log_ind_tbl_size = log2above(ind_tbl_size);
errno = 0;
- ind_table = ibv_exp_create_rwq_ind_table(priv->ctx,
- &ind_init_attr);
+ ind_table = ibv_create_rwq_ind_table(priv->ctx,
+ &ind_init_attr);
if (ind_table != NULL) {
(*ind_tables)[i] = ind_table;
continue;
hash_rxq_type_from_pos(&ind_table_init[j], k);
struct rte_eth_rss_conf *priv_rss_conf =
(*priv->rss_conf)[type];
- struct ibv_exp_rx_hash_conf hash_conf = {
- .rx_hash_function = IBV_EXP_RX_HASH_FUNC_TOEPLITZ,
+ struct ibv_rx_hash_conf hash_conf = {
+ .rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
.rx_hash_key_len = (priv_rss_conf ?
priv_rss_conf->rss_key_len :
rss_hash_default_key_len),
priv_rss_conf->rss_key :
rss_hash_default_key),
.rx_hash_fields_mask = hash_rxq_init[type].hash_fields,
- .rwq_ind_tbl = (*ind_tables)[j],
};
- struct ibv_exp_qp_init_attr qp_init_attr = {
- .max_inl_recv = 0, /* Currently not supported. */
+ struct ibv_qp_init_attr_ex qp_init_attr = {
.qp_type = IBV_QPT_RAW_PACKET,
- .comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |
- IBV_EXP_QP_INIT_ATTR_RX_HASH),
+ .comp_mask = (IBV_QP_INIT_ATTR_PD |
+ IBV_QP_INIT_ATTR_IND_TABLE |
+ IBV_QP_INIT_ATTR_RX_HASH),
+ .rx_hash_conf = hash_conf,
+ .rwq_ind_tbl = (*ind_tables)[j],
.pd = priv->pd,
- .rx_hash_conf = &hash_conf,
- .port_num = priv->port,
};
DEBUG("using indirection table %u for hash RX queue %u type %d",
j, i, type);
*hash_rxq = (struct hash_rxq){
.priv = priv,
- .qp = ibv_exp_create_qp(priv->ctx, &qp_init_attr),
+ .qp = ibv_create_qp_ex(priv->ctx, &qp_init_attr),
.type = type,
};
if (hash_rxq->qp == NULL) {
}
if (ind_tables != NULL) {
for (j = 0; (j != ind_tables_n); ++j) {
- struct ibv_exp_rwq_ind_table *ind_table =
+ struct ibv_rwq_ind_table *ind_table =
(*ind_tables)[j];
if (ind_table == NULL)
continue;
- claim_zero(ibv_exp_destroy_rwq_ind_table(ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(ind_table));
}
rte_free(ind_tables);
}
rte_free(priv->hash_rxqs);
priv->hash_rxqs = NULL;
for (i = 0; (i != priv->ind_tables_n); ++i) {
- struct ibv_exp_rwq_ind_table *ind_table =
+ struct ibv_rwq_ind_table *ind_table =
(*priv->ind_tables)[i];
assert(ind_table != NULL);
- claim_zero(ibv_exp_destroy_rwq_ind_table(ind_table));
+ claim_zero(ibv_destroy_rwq_ind_table(ind_table));
}
priv->ind_tables_n = 0;
rte_free(priv->ind_tables);
if (rxq_ctrl->fdir_queue != NULL)
priv_fdir_queue_destroy(rxq_ctrl->priv, rxq_ctrl->fdir_queue);
if (rxq_ctrl->wq != NULL)
- claim_zero(ibv_exp_destroy_wq(rxq_ctrl->wq));
+ claim_zero(ibv_destroy_wq(rxq_ctrl->wq));
if (rxq_ctrl->cq != NULL)
claim_zero(ibv_destroy_cq(rxq_ctrl->cq));
if (rxq_ctrl->channel != NULL)
rxq_setup(struct rxq_ctrl *tmpl)
{
struct ibv_cq *ibcq = tmpl->cq;
- struct ibv_mlx5_cq_info cq_info;
- struct mlx5_rwq *rwq = container_of(tmpl->wq, struct mlx5_rwq, wq);
+ struct mlx5dv_cq cq_info;
+ struct mlx5dv_rwq rwq;
const uint16_t desc_n =
(1 << tmpl->rxq.elts_n) + tmpl->priv->rx_vec_en *
MLX5_VPMD_DESCS_PER_LOOP;
struct rte_mbuf *(*elts)[desc_n] =
rte_calloc_socket("RXQ", 1, sizeof(*elts), 0, tmpl->socket);
- if (ibv_mlx5_exp_get_cq_info(ibcq, &cq_info)) {
- ERROR("Unable to query CQ info. check your OFED.");
- return ENOTSUP;
+ struct mlx5dv_obj obj;
+ int ret = 0;
+
+ obj.cq.in = ibcq;
+ obj.cq.out = &cq_info;
+ obj.rwq.in = tmpl->wq;
+ obj.rwq.out = &rwq;
+ ret = mlx5dv_init_obj(&obj, MLX5DV_OBJ_CQ | MLX5DV_OBJ_RWQ);
+ if (ret != 0) {
+ return -EINVAL;
}
if (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {
ERROR("Wrong MLX5_CQE_SIZE environment variable value: "
}
if (elts == NULL)
return ENOMEM;
- tmpl->rxq.rq_db = rwq->rq.db;
+ tmpl->rxq.rq_db = rwq.dbrec;
tmpl->rxq.cqe_n = log2above(cq_info.cqe_cnt);
tmpl->rxq.cq_ci = 0;
tmpl->rxq.rq_ci = 0;
tmpl->rxq.cq_db = cq_info.dbrec;
tmpl->rxq.wqes =
(volatile struct mlx5_wqe_data_seg (*)[])
- (uintptr_t)rwq->rq.buff;
+ (uintptr_t)rwq.buf;
tmpl->rxq.cqes =
(volatile struct mlx5_cqe (*)[])
(uintptr_t)cq_info.buf;
tmpl->rxq.elts = elts;
+ tmpl->rxq.cq_uar = cq_info.cq_uar;
+ tmpl->rxq.cqn = cq_info.cqn;
+ tmpl->rxq.cq_arm_sn = 0;
return 0;
}
.rss_hash = priv->rxqs_n > 1,
},
};
- struct ibv_exp_wq_attr mod;
+ struct ibv_wq_attr mod;
union {
- struct ibv_exp_cq_init_attr cq;
- struct ibv_exp_wq_init_attr wq;
- struct ibv_exp_cq_attr cq_attr;
+ struct ibv_cq_init_attr_ex cq;
+ struct ibv_wq_init_attr wq;
+ struct ibv_cq_ex cq_attr;
} attr;
unsigned int mb_len = rte_pktmbuf_data_room_size(mp);
unsigned int cqe_n = desc - 1;
goto error;
}
}
- attr.cq = (struct ibv_exp_cq_init_attr){
+ attr.cq = (struct ibv_cq_init_attr_ex){
.comp_mask = 0,
};
if (priv->cqe_comp) {
- attr.cq.comp_mask |= IBV_EXP_CQ_INIT_ATTR_FLAGS;
- attr.cq.flags |= IBV_EXP_CQ_COMPRESSED_CQE;
+ attr.cq.comp_mask |= IBV_CQ_INIT_ATTR_MASK_FLAGS;
+ attr.cq.flags |= MLX5DV_CQ_INIT_ATTR_MASK_COMPRESSED_CQE;
/*
* For vectorized Rx, it must not be doubled in order to
* make cq_ci and rq_ci aligned.
if (rxq_check_vec_support(&tmpl.rxq) < 0)
cqe_n = (desc * 2) - 1; /* Double the number of CQEs. */
}
- tmpl.cq = ibv_exp_create_cq(priv->ctx, cqe_n, NULL, tmpl.channel, 0,
- &attr.cq);
+ tmpl.cq = ibv_create_cq(priv->ctx, cqe_n, NULL, tmpl.channel, 0);
if (tmpl.cq == NULL) {
ret = ENOMEM;
ERROR("%p: CQ creation failure: %s",
goto error;
}
DEBUG("priv->device_attr.max_qp_wr is %d",
- priv->device_attr.max_qp_wr);
+ priv->device_attr.orig_attr.max_qp_wr);
DEBUG("priv->device_attr.max_sge is %d",
- priv->device_attr.max_sge);
+ priv->device_attr.orig_attr.max_sge);
/* Configure VLAN stripping. */
tmpl.rxq.vlan_strip = (priv->hw_vlan_strip &&
!!dev->data->dev_conf.rxmode.hw_vlan_strip);
- attr.wq = (struct ibv_exp_wq_init_attr){
+ attr.wq = (struct ibv_wq_init_attr){
.wq_context = NULL, /* Could be useful in the future. */
- .wq_type = IBV_EXP_WQT_RQ,
+ .wq_type = IBV_WQT_RQ,
/* Max number of outstanding WRs. */
- .max_recv_wr = desc >> tmpl.rxq.sges_n,
+ .max_wr = desc >> tmpl.rxq.sges_n,
/* Max number of scatter/gather elements in a WR. */
- .max_recv_sge = 1 << tmpl.rxq.sges_n,
+ .max_sge = 1 << tmpl.rxq.sges_n,
.pd = priv->pd,
.cq = tmpl.cq,
.comp_mask =
- IBV_EXP_CREATE_WQ_VLAN_OFFLOADS |
+ IBV_WQ_FLAGS_CVLAN_STRIPPING |
0,
- .vlan_offloads = (tmpl.rxq.vlan_strip ?
- IBV_EXP_RECEIVE_WQ_CVLAN_STRIP :
- 0),
+ .create_flags = (tmpl.rxq.vlan_strip ?
+ IBV_WQ_FLAGS_CVLAN_STRIPPING :
+ 0),
};
/* By default, FCS (CRC) is stripped by hardware. */
if (dev->data->dev_conf.rxmode.hw_strip_crc) {
tmpl.rxq.crc_present = 0;
} else if (priv->hw_fcs_strip) {
/* Ask HW/Verbs to leave CRC in place when supported. */
- attr.wq.flags |= IBV_EXP_CREATE_WQ_FLAG_SCATTER_FCS;
- attr.wq.comp_mask |= IBV_EXP_CREATE_WQ_FLAGS;
+ attr.wq.create_flags |= IBV_WQ_FLAGS_SCATTER_FCS;
+ attr.wq.comp_mask |= IBV_WQ_INIT_ATTR_FLAGS;
tmpl.rxq.crc_present = 1;
} else {
WARN("%p: CRC stripping has been disabled but will still"
(void *)dev,
tmpl.rxq.crc_present ? "disabled" : "enabled",
tmpl.rxq.crc_present << 2);
+#ifdef HAVE_IBV_WQ_FLAG_RX_END_PADDING
if (!mlx5_getenv_int("MLX5_PMD_ENABLE_PADDING"))
; /* Nothing else to do. */
else if (priv->hw_padding) {
INFO("%p: enabling packet padding on queue %p",
(void *)dev, (void *)rxq_ctrl);
- attr.wq.flags |= IBV_EXP_CREATE_WQ_FLAG_RX_END_PADDING;
- attr.wq.comp_mask |= IBV_EXP_CREATE_WQ_FLAGS;
+ attr.wq.create_flags |= IBV_WQ_FLAG_RX_END_PADDING;
+ attr.wq.comp_mask |= IBV_WQ_INIT_ATTR_FLAGS;
} else
WARN("%p: packet padding has been requested but is not"
" supported, make sure MLNX_OFED and firmware are"
" up to date",
(void *)dev);
+#endif
- tmpl.wq = ibv_exp_create_wq(priv->ctx, &attr.wq);
+ tmpl.wq = ibv_create_wq(priv->ctx, &attr.wq);
if (tmpl.wq == NULL) {
ret = (errno ? errno : EINVAL);
ERROR("%p: WQ creation failure: %s",
* Make sure number of WRs*SGEs match expectations since a queue
* cannot allocate more than "desc" buffers.
*/
- if (((int)attr.wq.max_recv_wr != (desc >> tmpl.rxq.sges_n)) ||
- ((int)attr.wq.max_recv_sge != (1 << tmpl.rxq.sges_n))) {
+ if (((int)attr.wq.max_wr != (desc >> tmpl.rxq.sges_n)) ||
+ ((int)attr.wq.max_sge != (1 << tmpl.rxq.sges_n))) {
ERROR("%p: requested %u*%u but got %u*%u WRs*SGEs",
(void *)dev,
(desc >> tmpl.rxq.sges_n), (1 << tmpl.rxq.sges_n),
- attr.wq.max_recv_wr, attr.wq.max_recv_sge);
+ attr.wq.max_wr, attr.wq.max_sge);
ret = EINVAL;
goto error;
}
tmpl.rxq.port_id = dev->data->port_id;
DEBUG("%p: RTE port ID: %u", (void *)rxq_ctrl, tmpl.rxq.port_id);
/* Change queue state to ready. */
- mod = (struct ibv_exp_wq_attr){
- .attr_mask = IBV_EXP_WQ_ATTR_STATE,
- .wq_state = IBV_EXP_WQS_RDY,
+ mod = (struct ibv_wq_attr){
+ .attr_mask = IBV_WQ_ATTR_STATE,
+ .wq_state = IBV_WQS_RDY,
};
- ret = ibv_exp_modify_wq(tmpl.wq, &mod);
+ ret = ibv_modify_wq(tmpl.wq, &mod);
if (ret) {
- ERROR("%p: WQ state to IBV_EXP_WQS_RDY failed: %s",
+ ERROR("%p: WQ state to IBV_WQS_RDY failed: %s",
(void *)dev, strerror(ret));
goto error;
}
intr_handle->intr_vec = NULL;
}
-#ifdef HAVE_UPDATE_CQ_CI
+/**
+ * MLX5 CQ notification .
+ *
+ * @param rxq
+ * Pointer to receive queue structure.
+ * @param sq_n_rxq
+ * Sequence number per receive queue .
+ */
+static inline void
+mlx5_arm_cq(struct rxq *rxq, int sq_n_rxq)
+{
+ int sq_n = 0;
+ uint32_t doorbell_hi;
+ uint64_t doorbell;
+ void *cq_db_reg = (char *)rxq->cq_uar + MLX5_CQ_DOORBELL;
+
+ sq_n = sq_n_rxq & MLX5_CQ_SQN_MASK;
+ doorbell_hi = sq_n << MLX5_CQ_SQN_OFFSET | (rxq->cq_ci & MLX5_CI_MASK);
+ doorbell = (uint64_t)doorbell_hi << 32;
+ doorbell |= rxq->cqn;
+ rxq->cq_db[MLX5_CQ_ARM_DB] = rte_cpu_to_be_32(doorbell_hi);
+ rte_wmb();
+ rte_write64(rte_cpu_to_be_64(doorbell), cq_db_reg);
+}
/**
* DPDK callback for Rx queue interrupt enable.
struct priv *priv = mlx5_get_priv(dev);
struct rxq *rxq = (*priv->rxqs)[rx_queue_id];
struct rxq_ctrl *rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
- int ret;
+ int ret = 0;
if (!rxq || !rxq_ctrl->channel) {
ret = EINVAL;
} else {
- ibv_mlx5_exp_update_cq_ci(rxq_ctrl->cq, rxq->cq_ci);
- ret = ibv_req_notify_cq(rxq_ctrl->cq, 0);
+ mlx5_arm_cq(rxq, rxq->cq_arm_sn);
}
if (ret)
WARN("unable to arm interrupt on rx queue %d", rx_queue_id);
ret = EINVAL;
} else {
ret = ibv_get_cq_event(rxq_ctrl->cq->channel, &ev_cq, &ev_ctx);
+ rxq->cq_arm_sn++;
if (ret || ev_cq != rxq_ctrl->cq)
ret = EINVAL;
}
ibv_ack_cq_events(rxq_ctrl->cq, 1);
return -ret;
}
-
-#endif /* HAVE_UPDATE_CQ_CI */
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <infiniband/verbs.h>
-#include <infiniband/mlx5_hw.h>
-#include <infiniband/arch.h>
+#include <infiniband/mlx5dv.h>
#ifdef PEDANTIC
#pragma GCC diagnostic error "-Wpedantic"
#endif
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <infiniband/verbs.h>
-#include <infiniband/mlx5_hw.h>
+#include <infiniband/mlx5dv.h>
#ifdef PEDANTIC
#pragma GCC diagnostic error "-Wpedantic"
#endif
/* Flow director queue structure. */
struct fdir_queue {
struct ibv_qp *qp; /* Associated RX QP. */
- struct ibv_exp_rwq_ind_table *ind_table; /* Indirection table. */
- struct ibv_exp_wq *wq; /* Work queue. */
+ struct ibv_rwq_ind_table *ind_table; /* Indirection table. */
+ struct ibv_wq *wq; /* Work queue. */
struct ibv_cq *cq; /* Completion queue. */
};
struct mlx5_rxq_stats stats;
uint64_t mbuf_initializer; /* Default rearm_data for vectorized Rx. */
struct rte_mbuf fake_mbuf; /* elts padding for vectorized Rx. */
+ void *cq_uar; /* CQ user access region. */
+ uint32_t cqn; /* CQ number. */
+ uint8_t cq_arm_sn; /* CQ arm seq number. */
} __rte_cache_aligned;
/* RX queue control descriptor. */
struct rxq_ctrl {
struct priv *priv; /* Back pointer to private data. */
struct ibv_cq *cq; /* Completion Queue. */
- struct ibv_exp_wq *wq; /* Work Queue. */
+ struct ibv_wq *wq; /* Work Queue. */
struct fdir_queue *fdir_queue; /* Flow director queue. */
struct ibv_mr *mr; /* Memory Region (for mp). */
struct ibv_comp_channel *channel;
/* Flow structure with Ethernet specification. It is packed to prevent padding
* between attr and spec as this layout is expected by libibverbs. */
struct flow_attr_spec_eth {
- struct ibv_exp_flow_attr attr;
- struct ibv_exp_flow_spec_eth spec;
+ struct ibv_flow_attr attr;
+ struct ibv_flow_spec_eth spec;
} __attribute__((packed));
/* Define a struct flow_attr_spec_eth object as an array of at least
unsigned int flow_priority; /* Flow priority to use. */
union {
struct {
- enum ibv_exp_flow_spec_type type;
+ enum ibv_flow_spec_type type;
uint16_t size;
} hdr;
- struct ibv_exp_flow_spec_tcp_udp tcp_udp;
- struct ibv_exp_flow_spec_ipv4 ipv4;
- struct ibv_exp_flow_spec_ipv6 ipv6;
- struct ibv_exp_flow_spec_eth eth;
+ struct ibv_flow_spec_tcp_udp tcp_udp;
+ struct ibv_flow_spec_ipv4 ipv4;
+ struct ibv_flow_spec_ipv6 ipv6;
+ struct ibv_flow_spec_eth eth;
} flow_spec; /* Flow specification template. */
const struct hash_rxq_init *underlayer; /* Pointer to underlayer. */
};
struct ibv_qp *qp; /* Hash RX QP. */
enum hash_rxq_type type; /* Hash RX queue type. */
/* MAC flow steering rules, one per VLAN ID. */
- struct ibv_exp_flow *mac_flow
+ struct ibv_flow *mac_flow
[MLX5_MAX_MAC_ADDRESSES][MLX5_MAX_VLAN_IDS];
- struct ibv_exp_flow *special_flow
+ struct ibv_flow *special_flow
[MLX5_MAX_SPECIAL_FLOWS][MLX5_MAX_VLAN_IDS];
};
extern uint8_t rss_hash_default_key[];
extern const size_t rss_hash_default_key_len;
-size_t priv_flow_attr(struct priv *, struct ibv_exp_flow_attr *,
+size_t priv_flow_attr(struct priv *, struct ibv_flow_attr *,
size_t, enum hash_rxq_type);
int priv_create_hash_rxqs(struct priv *);
void priv_destroy_hash_rxqs(struct priv *);
void mlx5_rx_queue_release(void *);
int priv_rx_intr_vec_enable(struct priv *priv);
void priv_rx_intr_vec_disable(struct priv *priv);
-#ifdef HAVE_UPDATE_CQ_CI
int mlx5_rx_intr_enable(struct rte_eth_dev *dev, uint16_t rx_queue_id);
int mlx5_rx_intr_disable(struct rte_eth_dev *dev, uint16_t rx_queue_id);
-#endif /* HAVE_UPDATE_CQ_CI */
/* mlx5_txq.c */
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <infiniband/verbs.h>
-#include <infiniband/mlx5_hw.h>
-#include <infiniband/arch.h>
+#include <infiniband/mlx5dv.h>
#ifdef PEDANTIC
#pragma GCC diagnostic error "-Wpedantic"
#endif
static inline int
txq_setup(struct txq_ctrl *tmpl, struct txq_ctrl *txq_ctrl)
{
- struct mlx5_qp *qp = to_mqp(tmpl->qp);
+ struct mlx5dv_qp qp;
struct ibv_cq *ibcq = tmpl->cq;
- struct ibv_mlx5_cq_info cq_info;
+ struct mlx5dv_cq cq_info;
+ struct mlx5dv_obj obj;
+ int ret = 0;
- if (ibv_mlx5_exp_get_cq_info(ibcq, &cq_info)) {
- ERROR("Unable to query CQ info. check your OFED.");
- return ENOTSUP;
+ obj.cq.in = ibcq;
+ obj.cq.out = &cq_info;
+ obj.qp.in = tmpl->qp;
+ obj.qp.out = &qp;
+ ret = mlx5dv_init_obj(&obj, MLX5DV_OBJ_CQ | MLX5DV_OBJ_QP);
+ if (ret != 0) {
+ return -EINVAL;
}
if (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {
ERROR("Wrong MLX5_CQE_SIZE environment variable value: "
return EINVAL;
}
tmpl->txq.cqe_n = log2above(cq_info.cqe_cnt);
- tmpl->txq.qp_num_8s = qp->ctrl_seg.qp_num << 8;
- tmpl->txq.wqes = qp->gen_data.sqstart;
- tmpl->txq.wqe_n = log2above(qp->sq.wqe_cnt);
- tmpl->txq.qp_db = &qp->gen_data.db[MLX5_SND_DBR];
- tmpl->txq.bf_reg = qp->gen_data.bf->reg;
+ tmpl->txq.qp_num_8s = tmpl->qp->qp_num << 8;
+ tmpl->txq.wqes = qp.sq.buf;
+ tmpl->txq.wqe_n = log2above(qp.sq.wqe_cnt);
+ tmpl->txq.qp_db = &qp.dbrec[MLX5_SND_DBR];
+ tmpl->txq.bf_reg = qp.bf.reg;
tmpl->txq.cq_db = cq_info.dbrec;
tmpl->txq.cqes =
(volatile struct mlx5_cqe (*)[])
.socket = socket,
};
union {
- struct ibv_exp_qp_init_attr init;
- struct ibv_exp_cq_init_attr cq;
- struct ibv_exp_qp_attr mod;
- struct ibv_exp_cq_attr cq_attr;
+ struct ibv_qp_init_attr_ex init;
+ struct ibv_cq_init_attr_ex cq;
+ struct ibv_qp_attr mod;
+ struct ibv_cq_ex cq_attr;
} attr;
unsigned int cqe_n;
const unsigned int max_tso_inline = ((MLX5_MAX_TSO_HEADER +
if (priv->mps == MLX5_MPW_ENHANCED)
tmpl.txq.mpw_hdr_dseg = priv->mpw_hdr_dseg;
/* MRs will be registered in mp2mr[] later. */
- attr.cq = (struct ibv_exp_cq_init_attr){
+ attr.cq = (struct ibv_cq_init_attr_ex){
.comp_mask = 0,
};
cqe_n = ((desc / MLX5_TX_COMP_THRESH) - 1) ?
((desc / MLX5_TX_COMP_THRESH) - 1) : 1;
if (priv->mps == MLX5_MPW_ENHANCED)
cqe_n += MLX5_TX_COMP_THRESH_INLINE_DIV;
- tmpl.cq = ibv_exp_create_cq(priv->ctx,
- cqe_n,
- NULL, NULL, 0, &attr.cq);
+ tmpl.cq = ibv_create_cq(priv->ctx,
+ cqe_n,
+ NULL, NULL, 0);
if (tmpl.cq == NULL) {
ret = ENOMEM;
ERROR("%p: CQ creation failure: %s",
goto error;
}
DEBUG("priv->device_attr.max_qp_wr is %d",
- priv->device_attr.max_qp_wr);
+ priv->device_attr.orig_attr.max_qp_wr);
DEBUG("priv->device_attr.max_sge is %d",
- priv->device_attr.max_sge);
- attr.init = (struct ibv_exp_qp_init_attr){
+ priv->device_attr.orig_attr.max_sge);
+ attr.init = (struct ibv_qp_init_attr_ex){
/* CQ to be associated with the send queue. */
.send_cq = tmpl.cq,
/* CQ to be associated with the receive queue. */
.recv_cq = tmpl.cq,
.cap = {
/* Max number of outstanding WRs. */
- .max_send_wr = ((priv->device_attr.max_qp_wr < desc) ?
- priv->device_attr.max_qp_wr :
- desc),
+ .max_send_wr =
+ ((priv->device_attr.orig_attr.max_qp_wr < desc) ?
+ priv->device_attr.orig_attr.max_qp_wr :
+ desc),
/*
* Max number of scatter/gather elements in a WR,
* must be 1 to prevent libmlx5 from trying to affect
* TX burst. */
.sq_sig_all = 0,
.pd = priv->pd,
- .comp_mask = IBV_EXP_QP_INIT_ATTR_PD,
+ .comp_mask = IBV_QP_INIT_ATTR_PD,
};
if (priv->txq_inline && (priv->txqs_n >= priv->txqs_inline)) {
unsigned int ds_cnt;
if (priv->tso) {
attr.init.max_tso_header =
max_tso_inline * RTE_CACHE_LINE_SIZE;
- attr.init.comp_mask |= IBV_EXP_QP_INIT_ATTR_MAX_TSO_HEADER;
+ attr.init.comp_mask |= IBV_QP_INIT_ATTR_MAX_TSO_HEADER;
tmpl.txq.max_inline = RTE_MAX(tmpl.txq.max_inline,
max_tso_inline);
tmpl.txq.tso_en = 1;
}
if (priv->tunnel_en)
tmpl.txq.tunnel_en = 1;
- tmpl.qp = ibv_exp_create_qp(priv->ctx, &attr.init);
+ tmpl.qp = ibv_create_qp_ex(priv->ctx, &attr.init);
if (tmpl.qp == NULL) {
ret = (errno ? errno : EINVAL);
ERROR("%p: QP creation failure: %s",
attr.init.cap.max_send_wr,
attr.init.cap.max_send_sge,
attr.init.cap.max_inline_data);
- attr.mod = (struct ibv_exp_qp_attr){
+ attr.mod = (struct ibv_qp_attr){
/* Move the QP to this state. */
.qp_state = IBV_QPS_INIT,
/* Primary port number. */
.port_num = priv->port
};
- ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod,
- (IBV_EXP_QP_STATE | IBV_EXP_QP_PORT));
+ ret = ibv_modify_qp(tmpl.qp, &attr.mod,
+ (IBV_QP_STATE | IBV_QP_PORT));
if (ret) {
ERROR("%p: QP state to IBV_QPS_INIT failed: %s",
(void *)dev, strerror(ret));
goto error;
}
txq_alloc_elts(&tmpl, desc);
- attr.mod = (struct ibv_exp_qp_attr){
+ attr.mod = (struct ibv_qp_attr){
.qp_state = IBV_QPS_RTR
};
- ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+ ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
if (ret) {
ERROR("%p: QP state to IBV_QPS_RTR failed: %s",
(void *)dev, strerror(ret));
goto error;
}
attr.mod.qp_state = IBV_QPS_RTS;
- ret = ibv_exp_modify_qp(tmpl.qp, &attr.mod, IBV_EXP_QP_STATE);
+ ret = ibv_modify_qp(tmpl.qp, &attr.mod, IBV_QP_STATE);
if (ret) {
ERROR("%p: QP state to IBV_QPS_RTS failed: %s",
(void *)dev, strerror(ret));
{
struct rxq *rxq = (*priv->rxqs)[idx];
struct rxq_ctrl *rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
- struct ibv_exp_wq_attr mod;
+ struct ibv_wq_attr mod;
uint16_t vlan_offloads =
- (on ? IBV_EXP_RECEIVE_WQ_CVLAN_STRIP : 0) |
+ (on ? IBV_WQ_FLAGS_CVLAN_STRIPPING : 0) |
0;
int err;
DEBUG("set VLAN offloads 0x%x for port %d queue %d",
vlan_offloads, rxq->port_id, idx);
- mod = (struct ibv_exp_wq_attr){
- .attr_mask = IBV_EXP_WQ_ATTR_VLAN_OFFLOADS,
- .vlan_offloads = vlan_offloads,
+ mod = (struct ibv_wq_attr){
+ .attr_mask = IBV_WQ_ATTR_FLAGS,
+ .flags_mask = IBV_WQ_FLAGS_CVLAN_STRIPPING,
+ .flags = vlan_offloads,
};
- err = ibv_exp_modify_wq(rxq_ctrl->wq, &mod);
+ err = ibv_modify_wq(rxq_ctrl->wq, &mod);
if (err) {
ERROR("%p: failed to modified stripping mode: %s",
(void *)priv, strerror(err));
endif
_LDLIBS-$(CONFIG_RTE_LIBRTE_LIO_PMD) += -lrte_pmd_lio
_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4 -libverbs
-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 -libverbs
+_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 -libverbs -lmlx5
_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += -lrte_pmd_null
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap