From patchwork Wed Jan 29 12:38:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65309 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id CC971A052F; Wed, 29 Jan 2020 13:39:11 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A1BE81BFC7; Wed, 29 Jan 2020 13:39:11 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id D8DF71BFC7 for ; Wed, 29 Jan 2020 13:39:09 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:02 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1Z018914; Wed, 29 Jan 2020 14:39:02 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:26 +0000 Message-Id: <1580301530-6643-2-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 01/25] net/mlx5: separate DevX commands interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The DevX commands interface is included in the mlx5.h file with a lot of other PMD interfaces. As an arrangement to make the DevX commands shared with different PMDs, this patch moves the DevX interface to a new file called mlx5_devx_cmds.h. Also remove shared device structure dependency on DevX commands. Replace the DevX commands log mechanism from the mlx5 driver log mechanism to the EAL log mechanism. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.c | 1 + drivers/net/mlx5/mlx5.h | 221 +----------------------------------- drivers/net/mlx5/mlx5_devx_cmds.c | 33 +++--- drivers/net/mlx5/mlx5_devx_cmds.h | 231 ++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_ethdev.c | 1 + drivers/net/mlx5/mlx5_flow.c | 5 +- drivers/net/mlx5/mlx5_flow_dv.c | 1 + drivers/net/mlx5/mlx5_rxq.c | 1 + drivers/net/mlx5/mlx5_rxtx.c | 1 + drivers/net/mlx5/mlx5_txq.c | 1 + drivers/net/mlx5/mlx5_vlan.c | 1 + 11 files changed, 263 insertions(+), 234 deletions(-) create mode 100644 drivers/net/mlx5/mlx5_devx_cmds.h diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 2049370..7126edf 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -46,6 +46,7 @@ #include "mlx5_glue.h" #include "mlx5_mr.h" #include "mlx5_flow.h" +#include "mlx5_devx_cmds.h" /* Device parameter to enable RX completion queue compression. */ #define MLX5_RXQ_CQE_COMP_EN "rxq_cqe_comp_en" diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 5818349..4d0485d 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -38,6 +38,7 @@ #include "mlx5_defs.h" #include "mlx5_glue.h" #include "mlx5_prm.h" +#include "mlx5_devx_cmds.h" enum { PCI_VENDOR_ID_MELLANOX = 0x15b3, @@ -156,62 +157,6 @@ struct mlx5_stats_ctrl { uint64_t imissed_base; }; -/* devX creation object */ -struct mlx5_devx_obj { - struct mlx5dv_devx_obj *obj; /* The DV object. */ - int id; /* The object ID. */ -}; - -struct mlx5_devx_mkey_attr { - uint64_t addr; - uint64_t size; - uint32_t umem_id; - uint32_t pd; -}; - -/* HCA qos attributes. */ -struct mlx5_hca_qos_attr { - uint32_t sup:1; /* Whether QOS is supported. */ - uint32_t srtcm_sup:1; /* Whether srTCM mode is supported. */ - uint32_t flow_meter_reg_share:1; - /* Whether reg_c share is supported. */ - uint8_t log_max_flow_meter; - /* Power of the maximum supported meters. */ - uint8_t flow_meter_reg_c_ids; - /* Bitmap of the reg_Cs available for flow meter to use. */ - -}; - -/* HCA supports this number of time periods for LRO. */ -#define MLX5_LRO_NUM_SUPP_PERIODS 4 - -/* HCA attributes. */ -struct mlx5_hca_attr { - uint32_t eswitch_manager:1; - uint32_t flow_counters_dump:1; - uint8_t flow_counter_bulk_alloc_bitmap; - uint32_t eth_net_offloads:1; - uint32_t eth_virt:1; - uint32_t wqe_vlan_insert:1; - uint32_t wqe_inline_mode:2; - uint32_t vport_inline_mode:3; - uint32_t tunnel_stateless_geneve_rx:1; - uint32_t geneve_max_opt_len:1; /* 0x0: 14DW, 0x1: 63DW */ - uint32_t tunnel_stateless_gtp:1; - uint32_t lro_cap:1; - uint32_t tunnel_lro_gre:1; - uint32_t tunnel_lro_vxlan:1; - uint32_t lro_max_msg_sz_mode:2; - uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; - uint32_t flex_parser_protocols; - uint32_t hairpin:1; - uint32_t log_max_hairpin_queues:5; - uint32_t log_max_hairpin_wq_data_sz:5; - uint32_t log_max_hairpin_num_packets:5; - uint32_t vhca_id:16; - struct mlx5_hca_qos_attr qos; -}; - /* Flow list . */ TAILQ_HEAD(mlx5_flows, rte_flow); @@ -291,133 +236,6 @@ struct mlx5_dev_config { struct mlx5_lro_config lro; /* LRO configuration. */ }; -struct mlx5_devx_wq_attr { - uint32_t wq_type:4; - uint32_t wq_signature:1; - uint32_t end_padding_mode:2; - uint32_t cd_slave:1; - uint32_t hds_skip_first_sge:1; - uint32_t log2_hds_buf_size:3; - uint32_t page_offset:5; - uint32_t lwm:16; - uint32_t pd:24; - uint32_t uar_page:24; - uint64_t dbr_addr; - uint32_t hw_counter; - uint32_t sw_counter; - uint32_t log_wq_stride:4; - uint32_t log_wq_pg_sz:5; - uint32_t log_wq_sz:5; - uint32_t dbr_umem_valid:1; - uint32_t wq_umem_valid:1; - uint32_t log_hairpin_num_packets:5; - uint32_t log_hairpin_data_sz:5; - uint32_t single_wqe_log_num_of_strides:4; - uint32_t two_byte_shift_en:1; - uint32_t single_stride_log_num_of_bytes:3; - uint32_t dbr_umem_id; - uint32_t wq_umem_id; - uint64_t wq_umem_offset; -}; - -/* Create RQ attributes structure, used by create RQ operation. */ -struct mlx5_devx_create_rq_attr { - uint32_t rlky:1; - uint32_t delay_drop_en:1; - uint32_t scatter_fcs:1; - uint32_t vsd:1; - uint32_t mem_rq_type:4; - uint32_t state:4; - uint32_t flush_in_error_en:1; - uint32_t hairpin:1; - uint32_t user_index:24; - uint32_t cqn:24; - uint32_t counter_set_id:8; - uint32_t rmpn:24; - struct mlx5_devx_wq_attr wq_attr; -}; - -/* Modify RQ attributes structure, used by modify RQ operation. */ -struct mlx5_devx_modify_rq_attr { - uint32_t rqn:24; - uint32_t rq_state:4; /* Current RQ state. */ - uint32_t state:4; /* Required RQ state. */ - uint32_t scatter_fcs:1; - uint32_t vsd:1; - uint32_t counter_set_id:8; - uint32_t hairpin_peer_sq:24; - uint32_t hairpin_peer_vhca:16; - uint64_t modify_bitmask; - uint32_t lwm:16; /* Contained WQ lwm. */ -}; - -struct mlx5_rx_hash_field_select { - uint32_t l3_prot_type:1; - uint32_t l4_prot_type:1; - uint32_t selected_fields:30; -}; - -/* TIR attributes structure, used by TIR operations. */ -struct mlx5_devx_tir_attr { - uint32_t disp_type:4; - uint32_t lro_timeout_period_usecs:16; - uint32_t lro_enable_mask:4; - uint32_t lro_max_msg_sz:8; - uint32_t inline_rqn:24; - uint32_t rx_hash_symmetric:1; - uint32_t tunneled_offload_en:1; - uint32_t indirect_table:24; - uint32_t rx_hash_fn:4; - uint32_t self_lb_block:2; - uint32_t transport_domain:24; - uint32_t rx_hash_toeplitz_key[10]; - struct mlx5_rx_hash_field_select rx_hash_field_selector_outer; - struct mlx5_rx_hash_field_select rx_hash_field_selector_inner; -}; - -/* RQT attributes structure, used by RQT operations. */ -struct mlx5_devx_rqt_attr { - uint32_t rqt_max_size:16; - uint32_t rqt_actual_size:16; - uint32_t rq_list[]; -}; - -/* TIS attributes structure. */ -struct mlx5_devx_tis_attr { - uint32_t strict_lag_tx_port_affinity:1; - uint32_t tls_en:1; - uint32_t lag_tx_port_affinity:4; - uint32_t prio:4; - uint32_t transport_domain:24; -}; - -/* SQ attributes structure, used by SQ create operation. */ -struct mlx5_devx_create_sq_attr { - uint32_t rlky:1; - uint32_t cd_master:1; - uint32_t fre:1; - uint32_t flush_in_error_en:1; - uint32_t allow_multi_pkt_send_wqe:1; - uint32_t min_wqe_inline_mode:3; - uint32_t state:4; - uint32_t reg_umr:1; - uint32_t allow_swp:1; - uint32_t hairpin:1; - uint32_t user_index:24; - uint32_t cqn:24; - uint32_t packet_pacing_rate_limit_index:16; - uint32_t tis_lst_sz:16; - uint32_t tis_num:24; - struct mlx5_devx_wq_attr wq_attr; -}; - -/* SQ attributes structure, used by SQ modify operation. */ -struct mlx5_devx_modify_sq_attr { - uint32_t sq_state:4; - uint32_t state:4; - uint32_t hairpin_peer_rq:24; - uint32_t hairpin_peer_vhca:16; -}; /** * Type of object being allocated. @@ -1026,43 +844,6 @@ void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, struct mlx5_vf_vlan *vf_vlan); -/* mlx5_devx_cmds.c */ - -struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, - uint32_t bulk_sz); -int mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj); -int mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, - int clear, uint32_t n_counters, - uint64_t *pkts, uint64_t *bytes, - uint32_t mkey, void *addr, - struct mlx5dv_devx_cmd_comp *cmd_comp, - uint64_t async_id); -int mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, - struct mlx5_hca_attr *attr); -struct mlx5_devx_obj *mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, - struct mlx5_devx_mkey_attr *attr); -int mlx5_devx_get_out_command_status(void *out); -int mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, - uint32_t *tis_td); -struct mlx5_devx_obj *mlx5_devx_cmd_create_rq(struct ibv_context *ctx, - struct mlx5_devx_create_rq_attr *rq_attr, - int socket); -int mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, - struct mlx5_devx_modify_rq_attr *rq_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_tir(struct ibv_context *ctx, - struct mlx5_devx_tir_attr *tir_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, - struct mlx5_devx_rqt_attr *rqt_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_sq - (struct ibv_context *ctx, struct mlx5_devx_create_sq_attr *sq_attr); -int mlx5_devx_cmd_modify_sq - (struct mlx5_devx_obj *sq, struct mlx5_devx_modify_sq_attr *sq_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_tis - (struct ibv_context *ctx, struct mlx5_devx_tis_attr *tis_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_td(struct ibv_context *ctx); - -int mlx5_devx_cmd_flow_dump(struct mlx5_ibv_shared *sh, FILE *file); - /* mlx5_flow_meter.c */ int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg); diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c b/drivers/net/mlx5/mlx5_devx_cmds.c index 282d501..62ca590 100644 --- a/drivers/net/mlx5/mlx5_devx_cmds.c +++ b/drivers/net/mlx5/mlx5_devx_cmds.c @@ -1,13 +1,15 @@ // SPDX-License-Identifier: BSD-3-Clause /* Copyright 2018 Mellanox Technologies, Ltd */ +#include + #include #include -#include -#include "mlx5.h" -#include "mlx5_glue.h" #include "mlx5_prm.h" +#include "mlx5_devx_cmds.h" +#include "mlx5_utils.h" + /** * Allocate flow counters via devx interface. @@ -936,8 +938,12 @@ struct mlx5_devx_obj * /** * Dump all flows to file. * - * @param[in] sh - * Pointer to context. + * @param[in] fdb_domain + * FDB domain. + * @param[in] rx_domain + * RX domain. + * @param[in] tx_domain + * TX domain. * @param[out] file * Pointer to file stream. * @@ -945,23 +951,24 @@ struct mlx5_devx_obj * * 0 on success, a nagative value otherwise. */ int -mlx5_devx_cmd_flow_dump(struct mlx5_ibv_shared *sh __rte_unused, - FILE *file __rte_unused) +mlx5_devx_cmd_flow_dump(void *fdb_domain __rte_unused, + void *rx_domain __rte_unused, + void *tx_domain __rte_unused, FILE *file __rte_unused) { int ret = 0; #ifdef HAVE_MLX5_DR_FLOW_DUMP - if (sh->fdb_domain) { - ret = mlx5_glue->dr_dump_domain(file, sh->fdb_domain); + if (fdb_domain) { + ret = mlx5_glue->dr_dump_domain(file, fdb_domain); if (ret) return ret; } - assert(sh->rx_domain); - ret = mlx5_glue->dr_dump_domain(file, sh->rx_domain); + assert(rx_domain); + ret = mlx5_glue->dr_dump_domain(file, rx_domain); if (ret) return ret; - assert(sh->tx_domain); - ret = mlx5_glue->dr_dump_domain(file, sh->tx_domain); + assert(tx_domain); + ret = mlx5_glue->dr_dump_domain(file, tx_domain); #else ret = ENOTSUP; #endif diff --git a/drivers/net/mlx5/mlx5_devx_cmds.h b/drivers/net/mlx5/mlx5_devx_cmds.h new file mode 100644 index 0000000..2d58d96 --- /dev/null +++ b/drivers/net/mlx5/mlx5_devx_cmds.h @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_DEVX_CMDS_H_ +#define RTE_PMD_MLX5_DEVX_CMDS_H_ + +#include "mlx5_glue.h" + + +/* devX creation object */ +struct mlx5_devx_obj { + struct mlx5dv_devx_obj *obj; /* The DV object. */ + int id; /* The object ID. */ +}; + +struct mlx5_devx_mkey_attr { + uint64_t addr; + uint64_t size; + uint32_t umem_id; + uint32_t pd; +}; + +/* HCA qos attributes. */ +struct mlx5_hca_qos_attr { + uint32_t sup:1; /* Whether QOS is supported. */ + uint32_t srtcm_sup:1; /* Whether srTCM mode is supported. */ + uint32_t flow_meter_reg_share:1; + /* Whether reg_c share is supported. */ + uint8_t log_max_flow_meter; + /* Power of the maximum supported meters. */ + uint8_t flow_meter_reg_c_ids; + /* Bitmap of the reg_Cs available for flow meter to use. */ + +}; + +/* HCA supports this number of time periods for LRO. */ +#define MLX5_LRO_NUM_SUPP_PERIODS 4 + +/* HCA attributes. */ +struct mlx5_hca_attr { + uint32_t eswitch_manager:1; + uint32_t flow_counters_dump:1; + uint8_t flow_counter_bulk_alloc_bitmap; + uint32_t eth_net_offloads:1; + uint32_t eth_virt:1; + uint32_t wqe_vlan_insert:1; + uint32_t wqe_inline_mode:2; + uint32_t vport_inline_mode:3; + uint32_t tunnel_stateless_geneve_rx:1; + uint32_t geneve_max_opt_len:1; /* 0x0: 14DW, 0x1: 63DW */ + uint32_t tunnel_stateless_gtp:1; + uint32_t lro_cap:1; + uint32_t tunnel_lro_gre:1; + uint32_t tunnel_lro_vxlan:1; + uint32_t lro_max_msg_sz_mode:2; + uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; + uint32_t flex_parser_protocols; + uint32_t hairpin:1; + uint32_t log_max_hairpin_queues:5; + uint32_t log_max_hairpin_wq_data_sz:5; + uint32_t log_max_hairpin_num_packets:5; + uint32_t vhca_id:16; + struct mlx5_hca_qos_attr qos; +}; + +struct mlx5_devx_wq_attr { + uint32_t wq_type:4; + uint32_t wq_signature:1; + uint32_t end_padding_mode:2; + uint32_t cd_slave:1; + uint32_t hds_skip_first_sge:1; + uint32_t log2_hds_buf_size:3; + uint32_t page_offset:5; + uint32_t lwm:16; + uint32_t pd:24; + uint32_t uar_page:24; + uint64_t dbr_addr; + uint32_t hw_counter; + uint32_t sw_counter; + uint32_t log_wq_stride:4; + uint32_t log_wq_pg_sz:5; + uint32_t log_wq_sz:5; + uint32_t dbr_umem_valid:1; + uint32_t wq_umem_valid:1; + uint32_t log_hairpin_num_packets:5; + uint32_t log_hairpin_data_sz:5; + uint32_t single_wqe_log_num_of_strides:4; + uint32_t two_byte_shift_en:1; + uint32_t single_stride_log_num_of_bytes:3; + uint32_t dbr_umem_id; + uint32_t wq_umem_id; + uint64_t wq_umem_offset; +}; + +/* Create RQ attributes structure, used by create RQ operation. */ +struct mlx5_devx_create_rq_attr { + uint32_t rlky:1; + uint32_t delay_drop_en:1; + uint32_t scatter_fcs:1; + uint32_t vsd:1; + uint32_t mem_rq_type:4; + uint32_t state:4; + uint32_t flush_in_error_en:1; + uint32_t hairpin:1; + uint32_t user_index:24; + uint32_t cqn:24; + uint32_t counter_set_id:8; + uint32_t rmpn:24; + struct mlx5_devx_wq_attr wq_attr; +}; + +/* Modify RQ attributes structure, used by modify RQ operation. */ +struct mlx5_devx_modify_rq_attr { + uint32_t rqn:24; + uint32_t rq_state:4; /* Current RQ state. */ + uint32_t state:4; /* Required RQ state. */ + uint32_t scatter_fcs:1; + uint32_t vsd:1; + uint32_t counter_set_id:8; + uint32_t hairpin_peer_sq:24; + uint32_t hairpin_peer_vhca:16; + uint64_t modify_bitmask; + uint32_t lwm:16; /* Contained WQ lwm. */ +}; + +struct mlx5_rx_hash_field_select { + uint32_t l3_prot_type:1; + uint32_t l4_prot_type:1; + uint32_t selected_fields:30; +}; + +/* TIR attributes structure, used by TIR operations. */ +struct mlx5_devx_tir_attr { + uint32_t disp_type:4; + uint32_t lro_timeout_period_usecs:16; + uint32_t lro_enable_mask:4; + uint32_t lro_max_msg_sz:8; + uint32_t inline_rqn:24; + uint32_t rx_hash_symmetric:1; + uint32_t tunneled_offload_en:1; + uint32_t indirect_table:24; + uint32_t rx_hash_fn:4; + uint32_t self_lb_block:2; + uint32_t transport_domain:24; + uint32_t rx_hash_toeplitz_key[10]; + struct mlx5_rx_hash_field_select rx_hash_field_selector_outer; + struct mlx5_rx_hash_field_select rx_hash_field_selector_inner; +}; + +/* RQT attributes structure, used by RQT operations. */ +struct mlx5_devx_rqt_attr { + uint32_t rqt_max_size:16; + uint32_t rqt_actual_size:16; + uint32_t rq_list[]; +}; + +/* TIS attributes structure. */ +struct mlx5_devx_tis_attr { + uint32_t strict_lag_tx_port_affinity:1; + uint32_t tls_en:1; + uint32_t lag_tx_port_affinity:4; + uint32_t prio:4; + uint32_t transport_domain:24; +}; + +/* SQ attributes structure, used by SQ create operation. */ +struct mlx5_devx_create_sq_attr { + uint32_t rlky:1; + uint32_t cd_master:1; + uint32_t fre:1; + uint32_t flush_in_error_en:1; + uint32_t allow_multi_pkt_send_wqe:1; + uint32_t min_wqe_inline_mode:3; + uint32_t state:4; + uint32_t reg_umr:1; + uint32_t allow_swp:1; + uint32_t hairpin:1; + uint32_t user_index:24; + uint32_t cqn:24; + uint32_t packet_pacing_rate_limit_index:16; + uint32_t tis_lst_sz:16; + uint32_t tis_num:24; + struct mlx5_devx_wq_attr wq_attr; +}; + +/* SQ attributes structure, used by SQ modify operation. */ +struct mlx5_devx_modify_sq_attr { + uint32_t sq_state:4; + uint32_t state:4; + uint32_t hairpin_peer_rq:24; + uint32_t hairpin_peer_vhca:16; +}; + +/* mlx5_devx_cmds.c */ + +struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, + uint32_t bulk_sz); +int mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj); +int mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, + int clear, uint32_t n_counters, + uint64_t *pkts, uint64_t *bytes, + uint32_t mkey, void *addr, + struct mlx5dv_devx_cmd_comp *cmd_comp, + uint64_t async_id); +int mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + struct mlx5_hca_attr *attr); +struct mlx5_devx_obj *mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, + struct mlx5_devx_mkey_attr *attr); +int mlx5_devx_get_out_command_status(void *out); +int mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, + uint32_t *tis_td); +struct mlx5_devx_obj *mlx5_devx_cmd_create_rq(struct ibv_context *ctx, + struct mlx5_devx_create_rq_attr *rq_attr, + int socket); +int mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, + struct mlx5_devx_modify_rq_attr *rq_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_tir(struct ibv_context *ctx, + struct mlx5_devx_tir_attr *tir_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, + struct mlx5_devx_rqt_attr *rqt_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_sq(struct ibv_context *ctx, + struct mlx5_devx_create_sq_attr *sq_attr); +int mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, + struct mlx5_devx_modify_sq_attr *sq_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_tis(struct ibv_context *ctx, + struct mlx5_devx_tis_attr *tis_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_td(struct ibv_context *ctx); +int mlx5_devx_cmd_flow_dump(void *fdb_domain, void *rx_domain, void *tx_domain, + FILE *file); +#endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 3b4c5db..ce0109c 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -38,6 +38,7 @@ #include "mlx5.h" #include "mlx5_glue.h" +#include "mlx5_devx_cmds.h" #include "mlx5_rxtx.h" #include "mlx5_utils.h" diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 5c9fea6..983b1c3 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -31,6 +31,7 @@ #include "mlx5_defs.h" #include "mlx5_flow.h" #include "mlx5_glue.h" +#include "mlx5_devx_cmds.h" #include "mlx5_prm.h" #include "mlx5_rxtx.h" @@ -5692,6 +5693,8 @@ struct mlx5_flow_counter * struct rte_flow_error *error __rte_unused) { struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_ibv_shared *sh = priv->sh; - return mlx5_devx_cmd_flow_dump(priv->sh, file); + return mlx5_devx_cmd_flow_dump(sh->fdb_domain, sh->rx_domain, + sh->tx_domain, file); } diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index b90734e..653d649 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -32,6 +32,7 @@ #include "mlx5.h" #include "mlx5_defs.h" #include "mlx5_glue.h" +#include "mlx5_devx_cmds.h" #include "mlx5_flow.h" #include "mlx5_prm.h" #include "mlx5_rxtx.h" diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index 4092cb7..371b996 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -37,6 +37,7 @@ #include "mlx5_defs.h" #include "mlx5_glue.h" #include "mlx5_flow.h" +#include "mlx5_devx_cmds.h" /* Default RSS hash key also used for ConnectX-3. */ uint8_t rss_hash_default_key[] = { diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index 5e31f01..5a03556 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -29,6 +29,7 @@ #include #include "mlx5.h" +#include "mlx5_devx_cmds.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index 1a76f6e..5adb4dc 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -34,6 +34,7 @@ #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" #include "mlx5_glue.h" +#include "mlx5_devx_cmds.h" /** * Allocate TX queue elements. diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index 5f6554a..feac0f1 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -30,6 +30,7 @@ #include "mlx5.h" #include "mlx5_autoconf.h" #include "mlx5_glue.h" +#include "mlx5_devx_cmds.h" #include "mlx5_rxtx.h" #include "mlx5_utils.h" From patchwork Wed Jan 29 12:38:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65335 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 78516A052F; Wed, 29 Jan 2020 14:06:34 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EF7F71BFFA; Wed, 29 Jan 2020 14:06:05 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 91EA31BFC8 for ; Wed, 29 Jan 2020 13:39:09 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:07 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1a018914; Wed, 29 Jan 2020 14:39:07 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:27 +0000 Message-Id: <1580301530-6643-3-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> X-Mailman-Approved-At: Wed, 29 Jan 2020 14:06:00 +0100 Subject: [dpdk-dev] [PATCH v4 02/25] drivers: introduce mlx5 common library X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" A new Mellanox vdpa PMD will be added to support vdpa operations by Mellanox adapters. This vdpa PMD design includes mlx5_glue and mlx5_devx operations and large parts of them are shared with the net/mlx5 PMD. Create a new common library in drivers/common for mlx5 PMDs. Move mlx5_glue, mlx5_devx_cmds and their dependencies to the new mlx5 common library in drivers/common. The files mlx5_devx_cmds.c, mlx5_devx_cmds.h, mlx5_glue.c, mlx5_glue.h and mlx5_prm.h are moved as is from drivers/net/mlx5 to drivers/common/mlx5. Share the log mechanism macros. Separate also the log mechanism to allow different log level control to the common library. Build files and version files are adjusted accordingly. Include lines are adjusted accordingly. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- MAINTAINERS | 1 + drivers/common/Makefile | 4 + drivers/common/meson.build | 2 +- drivers/common/mlx5/Makefile | 331 ++++ drivers/common/mlx5/meson.build | 205 +++ drivers/common/mlx5/mlx5_common.c | 17 + drivers/common/mlx5/mlx5_common.h | 87 ++ drivers/common/mlx5/mlx5_common_utils.h | 20 + drivers/common/mlx5/mlx5_devx_cmds.c | 976 ++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 231 +++ drivers/common/mlx5/mlx5_glue.c | 1138 ++++++++++++++ drivers/common/mlx5/mlx5_glue.h | 265 ++++ drivers/common/mlx5/mlx5_prm.h | 1889 +++++++++++++++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 20 + drivers/net/mlx5/Makefile | 309 +--- drivers/net/mlx5/meson.build | 256 +-- drivers/net/mlx5/mlx5.c | 7 +- drivers/net/mlx5/mlx5.h | 9 +- drivers/net/mlx5/mlx5_devx_cmds.c | 976 ------------ drivers/net/mlx5/mlx5_devx_cmds.h | 231 --- drivers/net/mlx5/mlx5_ethdev.c | 5 +- drivers/net/mlx5/mlx5_flow.c | 9 +- drivers/net/mlx5/mlx5_flow.h | 3 +- drivers/net/mlx5/mlx5_flow_dv.c | 9 +- drivers/net/mlx5/mlx5_flow_meter.c | 2 + drivers/net/mlx5/mlx5_flow_verbs.c | 7 +- drivers/net/mlx5/mlx5_glue.c | 1150 -------------- drivers/net/mlx5/mlx5_glue.h | 264 ---- drivers/net/mlx5/mlx5_mac.c | 2 +- drivers/net/mlx5/mlx5_mr.c | 3 +- drivers/net/mlx5/mlx5_prm.h | 1888 ---------------------- drivers/net/mlx5/mlx5_rss.c | 2 +- drivers/net/mlx5/mlx5_rxq.c | 8 +- drivers/net/mlx5/mlx5_rxtx.c | 7 +- drivers/net/mlx5/mlx5_rxtx.h | 7 +- drivers/net/mlx5/mlx5_rxtx_vec.c | 5 +- drivers/net/mlx5/mlx5_rxtx_vec.h | 3 +- drivers/net/mlx5/mlx5_rxtx_vec_altivec.h | 5 +- drivers/net/mlx5/mlx5_rxtx_vec_neon.h | 5 +- drivers/net/mlx5/mlx5_rxtx_vec_sse.h | 5 +- drivers/net/mlx5/mlx5_stats.c | 2 +- drivers/net/mlx5/mlx5_txq.c | 7 +- drivers/net/mlx5/mlx5_utils.h | 79 +- drivers/net/mlx5/mlx5_vlan.c | 5 +- mk/rte.app.mk | 1 + 45 files changed, 5313 insertions(+), 5144 deletions(-) create mode 100644 drivers/common/mlx5/Makefile create mode 100644 drivers/common/mlx5/meson.build create mode 100644 drivers/common/mlx5/mlx5_common.c create mode 100644 drivers/common/mlx5/mlx5_common.h create mode 100644 drivers/common/mlx5/mlx5_common_utils.h create mode 100644 drivers/common/mlx5/mlx5_devx_cmds.c create mode 100644 drivers/common/mlx5/mlx5_devx_cmds.h create mode 100644 drivers/common/mlx5/mlx5_glue.c create mode 100644 drivers/common/mlx5/mlx5_glue.h create mode 100644 drivers/common/mlx5/mlx5_prm.h create mode 100644 drivers/common/mlx5/rte_common_mlx5_version.map delete mode 100644 drivers/net/mlx5/mlx5_devx_cmds.c delete mode 100644 drivers/net/mlx5/mlx5_devx_cmds.h delete mode 100644 drivers/net/mlx5/mlx5_glue.c delete mode 100644 drivers/net/mlx5/mlx5_glue.h delete mode 100644 drivers/net/mlx5/mlx5_prm.h diff --git a/MAINTAINERS b/MAINTAINERS index 94bccae..150d507 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -737,6 +737,7 @@ M: Matan Azrad M: Shahaf Shuler M: Viacheslav Ovsiienko T: git://dpdk.org/next/dpdk-next-net-mlx +F: drivers/common/mlx5/ F: drivers/net/mlx5/ F: buildtools/options-ibverbs-static.sh F: doc/guides/nics/mlx5.rst diff --git a/drivers/common/Makefile b/drivers/common/Makefile index 3254c52..4775d4b 100644 --- a/drivers/common/Makefile +++ b/drivers/common/Makefile @@ -35,4 +35,8 @@ ifneq (,$(findstring y,$(IAVF-y))) DIRS-y += iavf endif +ifeq ($(CONFIG_RTE_LIBRTE_MLX5_PMD),y) +DIRS-y += mlx5 +endif + include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/drivers/common/meson.build b/drivers/common/meson.build index fc620f7..ffd06e2 100644 --- a/drivers/common/meson.build +++ b/drivers/common/meson.build @@ -2,6 +2,6 @@ # Copyright(c) 2018 Cavium, Inc std_deps = ['eal'] -drivers = ['cpt', 'dpaax', 'iavf', 'mvep', 'octeontx', 'octeontx2', 'qat'] +drivers = ['cpt', 'dpaax', 'iavf', 'mlx5', 'mvep', 'octeontx', 'octeontx2', 'qat'] config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON' driver_name_fmt = 'rte_common_@0@' diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile new file mode 100644 index 0000000..b94d3c0 --- /dev/null +++ b/drivers/common/mlx5/Makefile @@ -0,0 +1,331 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 Mellanox Technologies, Ltd + +include $(RTE_SDK)/mk/rte.vars.mk + +# Library name. +LIB = librte_common_mlx5.a +LIB_GLUE = $(LIB_GLUE_BASE).$(LIB_GLUE_VERSION) +LIB_GLUE_BASE = librte_pmd_mlx5_glue.so +LIB_GLUE_VERSION = 20.02.0 + +# Sources. +ifneq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_glue.c +endif +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_devx_cmds.c +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_common.c + +ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) +INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE) +endif + +# Basic CFLAGS. +CFLAGS += -O3 +CFLAGS += -std=c11 -Wall -Wextra +CFLAGS += -g +CFLAGS += -I. +CFLAGS += -D_BSD_SOURCE +CFLAGS += -D_DEFAULT_SOURCE +CFLAGS += -D_XOPEN_SOURCE=600 +CFLAGS += $(WERROR_FLAGS) +CFLAGS += -Wno-strict-prototypes +ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) +CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' +CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' +CFLAGS_mlx5_glue.o += -fPIC +LDLIBS += -ldl +else ifeq ($(CONFIG_RTE_IBVERBS_LINK_STATIC),y) +LDLIBS += $(shell $(RTE_SDK)/buildtools/options-ibverbs-static.sh) +else +LDLIBS += -libverbs -lmlx5 +endif + +LDLIBS += -lrte_eal + +# A few warnings cannot be avoided in external headers. +CFLAGS += -Wno-error=cast-qual -DNDEBUG -UPEDANTIC + +EXPORT_MAP := rte_common_mlx5_version.map + +include $(RTE_SDK)/mk/rte.lib.mk + +# Generate and clean-up mlx5_autoconf.h. + +export CC CFLAGS CPPFLAGS EXTRA_CFLAGS EXTRA_CPPFLAGS +export AUTO_CONFIG_CFLAGS = -Wno-error + +ifndef V +AUTOCONF_OUTPUT := >/dev/null +endif + +mlx5_autoconf.h.new: FORCE + +mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh + $Q $(RM) -f -- '$@' + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT \ + infiniband/mlx5dv.h \ + enum MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_TUNNEL_SUPPORT \ + infiniband/mlx5dv.h \ + enum MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_MPLS_SUPPORT \ + infiniband/verbs.h \ + enum IBV_FLOW_SPEC_MPLS \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING \ + infiniband/verbs.h \ + enum IBV_WQ_FLAGS_PCI_WRITE_END_PADDING \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_WQ_FLAG_RX_END_PADDING \ + infiniband/verbs.h \ + enum IBV_WQ_FLAG_RX_END_PADDING \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_MLX5_MOD_SWP \ + infiniband/mlx5dv.h \ + type 'struct mlx5dv_sw_parsing_caps' \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_MLX5_MOD_MPW \ + infiniband/mlx5dv.h \ + enum MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_MLX5_MOD_CQE_128B_COMP \ + infiniband/mlx5dv.h \ + enum MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_MLX5_MOD_CQE_128B_PAD \ + infiniband/mlx5dv.h \ + enum MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_FLOW_DV_SUPPORT \ + infiniband/mlx5dv.h \ + func mlx5dv_create_flow_action_packet_reformat \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR \ + infiniband/mlx5dv.h \ + enum MLX5DV_DR_DOMAIN_TYPE_NIC_RX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR_ESWITCH \ + infiniband/mlx5dv.h \ + enum MLX5DV_DR_DOMAIN_TYPE_FDB \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR_VLAN \ + infiniband/mlx5dv.h \ + func mlx5dv_dr_action_create_push_vlan \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR_DEVX_PORT \ + infiniband/mlx5dv.h \ + func mlx5dv_query_devx_port \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVX_OBJ \ + infiniband/mlx5dv.h \ + func mlx5dv_devx_obj_create \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_FLOW_DEVX_COUNTERS \ + infiniband/mlx5dv.h \ + enum MLX5DV_FLOW_ACTION_COUNTERS_DEVX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVX_ASYNC \ + infiniband/mlx5dv.h \ + func mlx5dv_devx_obj_query_async \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR \ + infiniband/mlx5dv.h \ + func mlx5dv_dr_action_create_dest_devx_tir \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER \ + infiniband/mlx5dv.h \ + func mlx5dv_dr_action_create_flow_meter \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5_DR_FLOW_DUMP \ + infiniband/mlx5dv.h \ + func mlx5dv_dump_dr_domain \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD \ + infiniband/mlx5dv.h \ + enum MLX5_MMAP_GET_NC_PAGES_CMD \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_ETHTOOL_LINK_MODE_25G \ + /usr/include/linux/ethtool.h \ + enum ETHTOOL_LINK_MODE_25000baseCR_Full_BIT \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_ETHTOOL_LINK_MODE_50G \ + /usr/include/linux/ethtool.h \ + enum ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_ETHTOOL_LINK_MODE_100G \ + /usr/include/linux/ethtool.h \ + enum ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_COUNTERS_SET_V42 \ + infiniband/verbs.h \ + type 'struct ibv_counter_set_init_attr' \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVICE_COUNTERS_SET_V45 \ + infiniband/verbs.h \ + type 'struct ibv_counters_init_attr' \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NL_NLDEV \ + rdma/rdma_netlink.h \ + enum RDMA_NL_NLDEV \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_CMD_GET \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_CMD_GET \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_CMD_PORT_GET \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_CMD_PORT_GET \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_ATTR_DEV_INDEX \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_ATTR_DEV_INDEX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_ATTR_DEV_NAME \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_ATTR_DEV_NAME \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_ATTR_PORT_INDEX \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_ATTR_PORT_INDEX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX \ + rdma/rdma_netlink.h \ + enum RDMA_NLDEV_ATTR_NDEV_INDEX \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IFLA_NUM_VF \ + linux/if_link.h \ + enum IFLA_NUM_VF \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IFLA_EXT_MASK \ + linux/if_link.h \ + enum IFLA_EXT_MASK \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IFLA_PHYS_SWITCH_ID \ + linux/if_link.h \ + enum IFLA_PHYS_SWITCH_ID \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_IFLA_PHYS_PORT_NAME \ + linux/if_link.h \ + enum IFLA_PHYS_PORT_NAME \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_40000baseKR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_40000baseKR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_40000baseCR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_40000baseCR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_40000baseSR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_40000baseSR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_40000baseLR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_40000baseLR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_56000baseKR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_56000baseKR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_56000baseCR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_56000baseCR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_56000baseSR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_56000baseSR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_SUPPORTED_56000baseLR4_Full \ + /usr/include/linux/ethtool.h \ + define SUPPORTED_56000baseLR4_Full \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ + HAVE_STATIC_ASSERT \ + /usr/include/assert.h \ + define static_assert \ + $(AUTOCONF_OUTPUT) + +# Create mlx5_autoconf.h or update it in case it differs from the new one. + +mlx5_autoconf.h: mlx5_autoconf.h.new + $Q [ -f '$@' ] && \ + cmp '$<' '$@' $(AUTOCONF_OUTPUT) || \ + mv '$<' '$@' + +$(SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD):.c=.o): mlx5_autoconf.h + +# Generate dependency plug-in for rdma-core when the PMD must not be linked +# directly, so that applications do not inherit this dependency. + +ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) + +$(LIB): $(LIB_GLUE) + +ifeq ($(LINK_USING_CC),1) +GLUE_LDFLAGS := $(call linkerprefix,$(LDFLAGS)) +else +GLUE_LDFLAGS := $(LDFLAGS) +endif +$(LIB_GLUE): mlx5_glue.o + $Q $(LD) $(GLUE_LDFLAGS) $(EXTRA_LDFLAGS) \ + -Wl,-h,$(LIB_GLUE) \ + -shared -o $@ $< -libverbs -lmlx5 + +mlx5_glue.o: mlx5_autoconf.h + +endif + +clean_mlx5: FORCE + $Q rm -f -- mlx5_autoconf.h mlx5_autoconf.h.new + $Q rm -f -- mlx5_glue.o $(LIB_GLUE_BASE)* + +clean: clean_mlx5 diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build new file mode 100644 index 0000000..718cef2 --- /dev/null +++ b/drivers/common/mlx5/meson.build @@ -0,0 +1,205 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 Mellanox Technologies, Ltd + +if not is_linux + build = false + reason = 'only supported on Linux' + subdir_done() +endif +build = true + +pmd_dlopen = (get_option('ibverbs_link') == 'dlopen') +LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so' +LIB_GLUE_VERSION = '20.02.0' +LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION +if pmd_dlopen + dpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1) + cflags += [ + '-DMLX5_GLUE="@0@"'.format(LIB_GLUE), + '-DMLX5_GLUE_VERSION="@0@"'.format(LIB_GLUE_VERSION), + ] +endif + +libnames = [ 'mlx5', 'ibverbs' ] +libs = [] +foreach libname:libnames + lib = dependency('lib' + libname, required:false) + if not lib.found() + lib = cc.find_library(libname, required:false) + endif + if lib.found() + libs += lib + else + build = false + reason = 'missing dependency, "' + libname + '"' + endif +endforeach + +if build + allow_experimental_apis = true + deps += ['hash', 'pci', 'net', 'eal'] + ext_deps += libs + sources = files( + 'mlx5_devx_cmds.c', + 'mlx5_common.c', + ) + if not pmd_dlopen + sources += files('mlx5_glue.c') + endif + cflags_options = [ + '-std=c11', + '-Wno-strict-prototypes', + '-D_BSD_SOURCE', + '-D_DEFAULT_SOURCE', + '-D_XOPEN_SOURCE=600' + ] + foreach option:cflags_options + if cc.has_argument(option) + cflags += option + endif + endforeach + if get_option('buildtype').contains('debug') + cflags += [ '-pedantic', '-UNDEBUG', '-DPEDANTIC' ] + else + cflags += [ '-DNDEBUG', '-UPEDANTIC' ] + endif + # To maintain the compatibility with the make build system + # mlx5_autoconf.h file is still generated. + # input array for meson member search: + # [ "MACRO to define if found", "header for the search", + # "symbol to search", "struct member to search" ] + has_member_args = [ + [ 'HAVE_IBV_MLX5_MOD_SWP', 'infiniband/mlx5dv.h', + 'struct mlx5dv_sw_parsing_caps', 'sw_parsing_offloads' ], + [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V42', 'infiniband/verbs.h', + 'struct ibv_counter_set_init_attr', 'counter_set_id' ], + [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V45', 'infiniband/verbs.h', + 'struct ibv_counters_init_attr', 'comp_mask' ], + ] + # input array for meson symbol search: + # [ "MACRO to define if found", "header for the search", + # "symbol to search" ] + has_sym_args = [ + [ 'HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT', 'infiniband/mlx5dv.h', + 'MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX' ], + [ 'HAVE_IBV_DEVICE_TUNNEL_SUPPORT', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS' ], + [ 'HAVE_IBV_MLX5_MOD_MPW', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED' ], + [ 'HAVE_IBV_MLX5_MOD_CQE_128B_COMP', 'infiniband/mlx5dv.h', + 'MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP' ], + [ 'HAVE_IBV_MLX5_MOD_CQE_128B_PAD', 'infiniband/mlx5dv.h', + 'MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD' ], + [ 'HAVE_IBV_FLOW_DV_SUPPORT', 'infiniband/mlx5dv.h', + 'mlx5dv_create_flow_action_packet_reformat' ], + [ 'HAVE_IBV_DEVICE_MPLS_SUPPORT', 'infiniband/verbs.h', + 'IBV_FLOW_SPEC_MPLS' ], + [ 'HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING', 'infiniband/verbs.h', + 'IBV_WQ_FLAGS_PCI_WRITE_END_PADDING' ], + [ 'HAVE_IBV_WQ_FLAG_RX_END_PADDING', 'infiniband/verbs.h', + 'IBV_WQ_FLAG_RX_END_PADDING' ], + [ 'HAVE_MLX5DV_DR_DEVX_PORT', 'infiniband/mlx5dv.h', + 'mlx5dv_query_devx_port' ], + [ 'HAVE_IBV_DEVX_OBJ', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_obj_create' ], + [ 'HAVE_IBV_FLOW_DEVX_COUNTERS', 'infiniband/mlx5dv.h', + 'MLX5DV_FLOW_ACTION_COUNTERS_DEVX' ], + [ 'HAVE_IBV_DEVX_ASYNC', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_obj_query_async' ], + [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_dest_devx_tir' ], + [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_flow_meter' ], + [ 'HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD', 'infiniband/mlx5dv.h', + 'MLX5_MMAP_GET_NC_PAGES_CMD' ], + [ 'HAVE_MLX5DV_DR', 'infiniband/mlx5dv.h', + 'MLX5DV_DR_DOMAIN_TYPE_NIC_RX' ], + [ 'HAVE_MLX5DV_DR_ESWITCH', 'infiniband/mlx5dv.h', + 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], + [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', + 'mlx5dv_dr_action_create_push_vlan' ], + [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseKR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseCR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseSR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseSR4_Full' ], + [ 'HAVE_SUPPORTED_40000baseLR4_Full', 'linux/ethtool.h', + 'SUPPORTED_40000baseLR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseKR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseKR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseCR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseCR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseSR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseSR4_Full' ], + [ 'HAVE_SUPPORTED_56000baseLR4_Full', 'linux/ethtool.h', + 'SUPPORTED_56000baseLR4_Full' ], + [ 'HAVE_ETHTOOL_LINK_MODE_25G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_25000baseCR_Full_BIT' ], + [ 'HAVE_ETHTOOL_LINK_MODE_50G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT' ], + [ 'HAVE_ETHTOOL_LINK_MODE_100G', 'linux/ethtool.h', + 'ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT' ], + [ 'HAVE_IFLA_NUM_VF', 'linux/if_link.h', + 'IFLA_NUM_VF' ], + [ 'HAVE_IFLA_EXT_MASK', 'linux/if_link.h', + 'IFLA_EXT_MASK' ], + [ 'HAVE_IFLA_PHYS_SWITCH_ID', 'linux/if_link.h', + 'IFLA_PHYS_SWITCH_ID' ], + [ 'HAVE_IFLA_PHYS_PORT_NAME', 'linux/if_link.h', + 'IFLA_PHYS_PORT_NAME' ], + [ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h', + 'RDMA_NL_NLDEV' ], + [ 'HAVE_RDMA_NLDEV_CMD_GET', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_CMD_GET' ], + [ 'HAVE_RDMA_NLDEV_CMD_PORT_GET', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_CMD_PORT_GET' ], + [ 'HAVE_RDMA_NLDEV_ATTR_DEV_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_DEV_INDEX' ], + [ 'HAVE_RDMA_NLDEV_ATTR_DEV_NAME', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_DEV_NAME' ], + [ 'HAVE_RDMA_NLDEV_ATTR_PORT_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_PORT_INDEX' ], + [ 'HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX', 'rdma/rdma_netlink.h', + 'RDMA_NLDEV_ATTR_NDEV_INDEX' ], + [ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h', + 'mlx5dv_dump_dr_domain'], + ] + config = configuration_data() + foreach arg:has_sym_args + config.set(arg[0], cc.has_header_symbol(arg[1], arg[2], + dependencies: libs)) + endforeach + foreach arg:has_member_args + file_prefix = '#include <' + arg[1] + '>' + config.set(arg[0], cc.has_member(arg[2], arg[3], + prefix : file_prefix, dependencies: libs)) + endforeach + configure_file(output : 'mlx5_autoconf.h', configuration : config) +endif +# Build Glue Library +if pmd_dlopen and build + dlopen_name = 'mlx5_glue' + dlopen_lib_name = driver_name_fmt.format(dlopen_name) + dlopen_so_version = LIB_GLUE_VERSION + dlopen_sources = files('mlx5_glue.c') + dlopen_install_dir = [ eal_pmd_path + '-glue' ] + dlopen_includes = [global_inc] + dlopen_includes += include_directories( + '../../../lib/librte_eal/common/include/generic', + ) + shared_lib = shared_library( + dlopen_lib_name, + dlopen_sources, + include_directories: dlopen_includes, + c_args: cflags, + dependencies: libs, + link_args: [ + '-Wl,-export-dynamic', + '-Wl,-h,@0@'.format(LIB_GLUE), + ], + soversion: dlopen_so_version, + install: true, + install_dir: dlopen_install_dir, + ) +endif diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c new file mode 100644 index 0000000..14ebd30 --- /dev/null +++ b/drivers/common/mlx5/mlx5_common.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#include "mlx5_common.h" + + +int mlx5_common_logtype; + + +RTE_INIT(rte_mlx5_common_pmd_init) +{ + /* Initialize driver log type. */ + mlx5_common_logtype = rte_log_register("pmd.common.mlx5"); + if (mlx5_common_logtype >= 0) + rte_log_set_level(mlx5_common_logtype, RTE_LOG_NOTICE); +} diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h new file mode 100644 index 0000000..9f10def --- /dev/null +++ b/drivers/common/mlx5/mlx5_common.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_COMMON_H_ +#define RTE_PMD_MLX5_COMMON_H_ + +#include + +#include + + +/* + * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant + * manner. + */ +#define PMD_DRV_LOG_STRIP(a, b) a +#define PMD_DRV_LOG_OPAREN ( +#define PMD_DRV_LOG_CPAREN ) +#define PMD_DRV_LOG_COMMA , + +/* Return the file name part of a path. */ +static inline const char * +pmd_drv_log_basename(const char *s) +{ + const char *n = s; + + while (*n) + if (*(n++) == '/') + s = n; + return s; +} + +#define PMD_DRV_LOG___(level, type, name, ...) \ + rte_log(RTE_LOG_ ## level, \ + type, \ + RTE_FMT(name ": " \ + RTE_FMT_HEAD(__VA_ARGS__,), \ + RTE_FMT_TAIL(__VA_ARGS__,))) + +/* + * When debugging is enabled (NDEBUG not defined), file, line and function + * information replace the driver name (MLX5_DRIVER_NAME) in log messages. + */ +#ifndef NDEBUG + +#define PMD_DRV_LOG__(level, type, name, ...) \ + PMD_DRV_LOG___(level, type, name, "%s:%u: %s(): " __VA_ARGS__) +#define PMD_DRV_LOG_(level, type, name, s, ...) \ + PMD_DRV_LOG__(level, type, name,\ + s "\n" PMD_DRV_LOG_COMMA \ + pmd_drv_log_basename(__FILE__) PMD_DRV_LOG_COMMA \ + __LINE__ PMD_DRV_LOG_COMMA \ + __func__, \ + __VA_ARGS__) + +#else /* NDEBUG */ +#define PMD_DRV_LOG__(level, type, name, ...) \ + PMD_DRV_LOG___(level, type, name, __VA_ARGS__) +#define PMD_DRV_LOG_(level, type, name, s, ...) \ + PMD_DRV_LOG__(level, type, name, s "\n", __VA_ARGS__) + +#endif /* NDEBUG */ + +/* claim_zero() does not perform any check when debugging is disabled. */ +#ifndef NDEBUG + +#define DEBUG(...) DRV_LOG(DEBUG, __VA_ARGS__) +#define claim_zero(...) assert((__VA_ARGS__) == 0) +#define claim_nonzero(...) assert((__VA_ARGS__) != 0) + +#else /* NDEBUG */ + +#define DEBUG(...) (void)0 +#define claim_zero(...) (__VA_ARGS__) +#define claim_nonzero(...) (__VA_ARGS__) + +#endif /* NDEBUG */ + +/* Allocate a buffer on the stack and fill it with a printf format string. */ +#define MKSTR(name, ...) \ + int mkstr_size_##name = snprintf(NULL, 0, "" __VA_ARGS__); \ + char name[mkstr_size_##name + 1]; \ + \ + snprintf(name, sizeof(name), "" __VA_ARGS__) + +#endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/common/mlx5/mlx5_common_utils.h b/drivers/common/mlx5/mlx5_common_utils.h new file mode 100644 index 0000000..32c3adf --- /dev/null +++ b/drivers/common/mlx5/mlx5_common_utils.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_COMMON_UTILS_H_ +#define RTE_PMD_MLX5_COMMON_UTILS_H_ + +#include "mlx5_common.h" + + +extern int mlx5_common_logtype; + +#define MLX5_COMMON_LOG_PREFIX "common_mlx5" +/* Generic printf()-like logging macro with automatic line feed. */ +#define DRV_LOG(level, ...) \ + PMD_DRV_LOG_(level, mlx5_common_logtype, MLX5_COMMON_LOG_PREFIX, \ + __VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \ + PMD_DRV_LOG_CPAREN) + +#endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */ diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c new file mode 100644 index 0000000..4d94f92 --- /dev/null +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -0,0 +1,976 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2018 Mellanox Technologies, Ltd */ + +#include + +#include +#include + +#include "mlx5_prm.h" +#include "mlx5_devx_cmds.h" +#include "mlx5_common_utils.h" + + +/** + * Allocate flow counters via devx interface. + * + * @param[in] ctx + * ibv contexts returned from mlx5dv_open_device. + * @param dcs + * Pointer to counters properties structure to be filled by the routine. + * @param bulk_n_128 + * Bulk counter numbers in 128 counters units. + * + * @return + * Pointer to counter object on success, a negative value otherwise and + * rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, uint32_t bulk_n_128) +{ + struct mlx5_devx_obj *dcs = rte_zmalloc("dcs", sizeof(*dcs), 0); + uint32_t in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0}; + + if (!dcs) { + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(alloc_flow_counter_in, in, opcode, + MLX5_CMD_OP_ALLOC_FLOW_COUNTER); + MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, bulk_n_128); + dcs->obj = mlx5_glue->devx_obj_create(ctx, in, + sizeof(in), out, sizeof(out)); + if (!dcs->obj) { + DRV_LOG(ERR, "Can't allocate counters - error %d", errno); + rte_errno = errno; + rte_free(dcs); + return NULL; + } + dcs->id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id); + return dcs; +} + +/** + * Query flow counters values. + * + * @param[in] dcs + * devx object that was obtained from mlx5_devx_cmd_fc_alloc. + * @param[in] clear + * Whether hardware should clear the counters after the query or not. + * @param[in] n_counters + * 0 in case of 1 counter to read, otherwise the counter number to read. + * @param pkts + * The number of packets that matched the flow. + * @param bytes + * The number of bytes that matched the flow. + * @param mkey + * The mkey key for batch query. + * @param addr + * The address in the mkey range for batch query. + * @param cmd_comp + * The completion object for asynchronous batch query. + * @param async_id + * The ID to be returned in the asynchronous batch query response. + * + * @return + * 0 on success, a negative value otherwise. + */ +int +mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, + int clear, uint32_t n_counters, + uint64_t *pkts, uint64_t *bytes, + uint32_t mkey, void *addr, + struct mlx5dv_devx_cmd_comp *cmd_comp, + uint64_t async_id) +{ + int out_len = MLX5_ST_SZ_BYTES(query_flow_counter_out) + + MLX5_ST_SZ_BYTES(traffic_counter); + uint32_t out[out_len]; + uint32_t in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0}; + void *stats; + int rc; + + MLX5_SET(query_flow_counter_in, in, opcode, + MLX5_CMD_OP_QUERY_FLOW_COUNTER); + MLX5_SET(query_flow_counter_in, in, op_mod, 0); + MLX5_SET(query_flow_counter_in, in, flow_counter_id, dcs->id); + MLX5_SET(query_flow_counter_in, in, clear, !!clear); + + if (n_counters) { + MLX5_SET(query_flow_counter_in, in, num_of_counters, + n_counters); + MLX5_SET(query_flow_counter_in, in, dump_to_memory, 1); + MLX5_SET(query_flow_counter_in, in, mkey, mkey); + MLX5_SET64(query_flow_counter_in, in, address, + (uint64_t)(uintptr_t)addr); + } + if (!cmd_comp) + rc = mlx5_glue->devx_obj_query(dcs->obj, in, sizeof(in), out, + out_len); + else + rc = mlx5_glue->devx_obj_query_async(dcs->obj, in, sizeof(in), + out_len, async_id, + cmd_comp); + if (rc) { + DRV_LOG(ERR, "Failed to query devx counters with rc %d", rc); + rte_errno = rc; + return -rc; + } + if (!n_counters) { + stats = MLX5_ADDR_OF(query_flow_counter_out, + out, flow_statistics); + *pkts = MLX5_GET64(traffic_counter, stats, packets); + *bytes = MLX5_GET64(traffic_counter, stats, octets); + } + return 0; +} + +/** + * Create a new mkey. + * + * @param[in] ctx + * ibv contexts returned from mlx5dv_open_device. + * @param[in] attr + * Attributes of the requested mkey. + * + * @return + * Pointer to Devx mkey on success, a negative value otherwise and rte_errno + * is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, + struct mlx5_devx_mkey_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_mkey_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_mkey_out)] = {0}; + void *mkc; + struct mlx5_devx_obj *mkey = rte_zmalloc("mkey", sizeof(*mkey), 0); + size_t pgsize; + uint32_t translation_size; + + if (!mkey) { + rte_errno = ENOMEM; + return NULL; + } + pgsize = sysconf(_SC_PAGESIZE); + translation_size = (RTE_ALIGN(attr->size, pgsize) * 8) / 16; + MLX5_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY); + MLX5_SET(create_mkey_in, in, translations_octword_actual_size, + translation_size); + MLX5_SET(create_mkey_in, in, mkey_umem_id, attr->umem_id); + mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); + MLX5_SET(mkc, mkc, lw, 0x1); + MLX5_SET(mkc, mkc, lr, 0x1); + MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT); + MLX5_SET(mkc, mkc, qpn, 0xffffff); + MLX5_SET(mkc, mkc, pd, attr->pd); + MLX5_SET(mkc, mkc, mkey_7_0, attr->umem_id & 0xFF); + MLX5_SET(mkc, mkc, translations_octword_size, translation_size); + MLX5_SET64(mkc, mkc, start_addr, attr->addr); + MLX5_SET64(mkc, mkc, len, attr->size); + MLX5_SET(mkc, mkc, log_page_size, rte_log2_u32(pgsize)); + mkey->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!mkey->obj) { + DRV_LOG(ERR, "Can't create mkey - error %d", errno); + rte_errno = errno; + rte_free(mkey); + return NULL; + } + mkey->id = MLX5_GET(create_mkey_out, out, mkey_index); + mkey->id = (mkey->id << 8) | (attr->umem_id & 0xFF); + return mkey; +} + +/** + * Get status of devx command response. + * Mainly used for asynchronous commands. + * + * @param[in] out + * The out response buffer. + * + * @return + * 0 on success, non-zero value otherwise. + */ +int +mlx5_devx_get_out_command_status(void *out) +{ + int status; + + if (!out) + return -EINVAL; + status = MLX5_GET(query_flow_counter_out, out, status); + if (status) { + int syndrome = MLX5_GET(query_flow_counter_out, out, syndrome); + + DRV_LOG(ERR, "Bad devX status %x, syndrome = %x", status, + syndrome); + } + return status; +} + +/** + * Destroy any object allocated by a Devx API. + * + * @param[in] obj + * Pointer to a general object. + * + * @return + * 0 on success, a negative value otherwise. + */ +int +mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj) +{ + int ret; + + if (!obj) + return 0; + ret = mlx5_glue->devx_obj_destroy(obj->obj); + rte_free(obj); + return ret; +} + +/** + * Query NIC vport context. + * Fills minimal inline attribute. + * + * @param[in] ctx + * ibv contexts returned from mlx5dv_open_device. + * @param[in] vport + * vport index + * @param[out] attr + * Attributes device values. + * + * @return + * 0 on success, a negative value otherwise. + */ +static int +mlx5_devx_cmd_query_nic_vport_context(struct ibv_context *ctx, + unsigned int vport, + struct mlx5_hca_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0}; + void *vctx; + int status, syndrome, rc; + + /* Query NIC vport context to determine inline mode. */ + MLX5_SET(query_nic_vport_context_in, in, opcode, + MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT); + MLX5_SET(query_nic_vport_context_in, in, vport_number, vport); + if (vport) + MLX5_SET(query_nic_vport_context_in, in, other_vport, 1); + rc = mlx5_glue->devx_general_cmd(ctx, + in, sizeof(in), + out, sizeof(out)); + if (rc) + goto error; + status = MLX5_GET(query_nic_vport_context_out, out, status); + syndrome = MLX5_GET(query_nic_vport_context_out, out, syndrome); + if (status) { + DRV_LOG(DEBUG, "Failed to query NIC vport context, " + "status %x, syndrome = %x", + status, syndrome); + return -1; + } + vctx = MLX5_ADDR_OF(query_nic_vport_context_out, out, + nic_vport_context); + attr->vport_inline_mode = MLX5_GET(nic_vport_context, vctx, + min_wqe_inline_mode); + return 0; +error: + rc = (rc > 0) ? -rc : rc; + return rc; +} + +/** + * Query HCA attributes. + * Using those attributes we can check on run time if the device + * is having the required capabilities. + * + * @param[in] ctx + * ibv contexts returned from mlx5dv_open_device. + * @param[out] attr + * Attributes device values. + * + * @return + * 0 on success, a negative value otherwise. + */ +int +mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + struct mlx5_hca_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; + void *hcattr; + int status, syndrome, rc; + + MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE | + MLX5_HCA_CAP_OPMOD_GET_CUR); + + rc = mlx5_glue->devx_general_cmd(ctx, + in, sizeof(in), out, sizeof(out)); + if (rc) + goto error; + status = MLX5_GET(query_hca_cap_out, out, status); + syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); + if (status) { + DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, " + "status %x, syndrome = %x", + status, syndrome); + return -1; + } + hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); + attr->flow_counter_bulk_alloc_bitmap = + MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc); + attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, + flow_counters_dump); + attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager); + attr->hairpin = MLX5_GET(cmd_hca_cap, hcattr, hairpin); + attr->log_max_hairpin_queues = MLX5_GET(cmd_hca_cap, hcattr, + log_max_hairpin_queues); + attr->log_max_hairpin_wq_data_sz = MLX5_GET(cmd_hca_cap, hcattr, + log_max_hairpin_wq_data_sz); + attr->log_max_hairpin_num_packets = MLX5_GET + (cmd_hca_cap, hcattr, log_min_hairpin_wq_data_sz); + attr->vhca_id = MLX5_GET(cmd_hca_cap, hcattr, vhca_id); + attr->eth_net_offloads = MLX5_GET(cmd_hca_cap, hcattr, + eth_net_offloads); + attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); + attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, + flex_parser_protocols); + attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); + if (attr->qos.sup) { + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | + MLX5_HCA_CAP_OPMOD_GET_CUR); + rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), + out, sizeof(out)); + if (rc) + goto error; + if (status) { + DRV_LOG(DEBUG, "Failed to query devx QOS capabilities," + " status %x, syndrome = %x", + status, syndrome); + return -1; + } + hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); + attr->qos.srtcm_sup = + MLX5_GET(qos_cap, hcattr, flow_meter_srtcm); + attr->qos.log_max_flow_meter = + MLX5_GET(qos_cap, hcattr, log_max_flow_meter); + attr->qos.flow_meter_reg_c_ids = + MLX5_GET(qos_cap, hcattr, flow_meter_reg_id); + attr->qos.flow_meter_reg_share = + MLX5_GET(qos_cap, hcattr, flow_meter_reg_share); + } + if (!attr->eth_net_offloads) + return 0; + + /* Query HCA offloads for Ethernet protocol. */ + memset(in, 0, sizeof(in)); + memset(out, 0, sizeof(out)); + MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS | + MLX5_HCA_CAP_OPMOD_GET_CUR); + + rc = mlx5_glue->devx_general_cmd(ctx, + in, sizeof(in), + out, sizeof(out)); + if (rc) { + attr->eth_net_offloads = 0; + goto error; + } + status = MLX5_GET(query_hca_cap_out, out, status); + syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); + if (status) { + DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, " + "status %x, syndrome = %x", + status, syndrome); + attr->eth_net_offloads = 0; + return -1; + } + hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); + attr->wqe_vlan_insert = MLX5_GET(per_protocol_networking_offload_caps, + hcattr, wqe_vlan_insert); + attr->lro_cap = MLX5_GET(per_protocol_networking_offload_caps, hcattr, + lro_cap); + attr->tunnel_lro_gre = MLX5_GET(per_protocol_networking_offload_caps, + hcattr, tunnel_lro_gre); + attr->tunnel_lro_vxlan = MLX5_GET(per_protocol_networking_offload_caps, + hcattr, tunnel_lro_vxlan); + attr->lro_max_msg_sz_mode = MLX5_GET + (per_protocol_networking_offload_caps, + hcattr, lro_max_msg_sz_mode); + for (int i = 0 ; i < MLX5_LRO_NUM_SUPP_PERIODS ; i++) { + attr->lro_timer_supported_periods[i] = + MLX5_GET(per_protocol_networking_offload_caps, hcattr, + lro_timer_supported_periods[i]); + } + attr->tunnel_stateless_geneve_rx = + MLX5_GET(per_protocol_networking_offload_caps, + hcattr, tunnel_stateless_geneve_rx); + attr->geneve_max_opt_len = + MLX5_GET(per_protocol_networking_offload_caps, + hcattr, max_geneve_opt_len); + attr->wqe_inline_mode = MLX5_GET(per_protocol_networking_offload_caps, + hcattr, wqe_inline_mode); + attr->tunnel_stateless_gtp = MLX5_GET + (per_protocol_networking_offload_caps, + hcattr, tunnel_stateless_gtp); + if (attr->wqe_inline_mode != MLX5_CAP_INLINE_MODE_VPORT_CONTEXT) + return 0; + if (attr->eth_virt) { + rc = mlx5_devx_cmd_query_nic_vport_context(ctx, 0, attr); + if (rc) { + attr->eth_virt = 0; + goto error; + } + } + return 0; +error: + rc = (rc > 0) ? -rc : rc; + return rc; +} + +/** + * Query TIS transport domain from QP verbs object using DevX API. + * + * @param[in] qp + * Pointer to verbs QP returned by ibv_create_qp . + * @param[in] tis_num + * TIS number of TIS to query. + * @param[out] tis_td + * Pointer to TIS transport domain variable, to be set by the routine. + * + * @return + * 0 on success, a negative value otherwise. + */ +int +mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, + uint32_t *tis_td) +{ + uint32_t in[MLX5_ST_SZ_DW(query_tis_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_tis_out)] = {0}; + int rc; + void *tis_ctx; + + MLX5_SET(query_tis_in, in, opcode, MLX5_CMD_OP_QUERY_TIS); + MLX5_SET(query_tis_in, in, tisn, tis_num); + rc = mlx5_glue->devx_qp_query(qp, in, sizeof(in), out, sizeof(out)); + if (rc) { + DRV_LOG(ERR, "Failed to query QP using DevX"); + return -rc; + }; + tis_ctx = MLX5_ADDR_OF(query_tis_out, out, tis_context); + *tis_td = MLX5_GET(tisc, tis_ctx, transport_domain); + return 0; +} + +/** + * Fill WQ data for DevX API command. + * Utility function for use when creating DevX objects containing a WQ. + * + * @param[in] wq_ctx + * Pointer to WQ context to fill with data. + * @param [in] wq_attr + * Pointer to WQ attributes structure to fill in WQ context. + */ +static void +devx_cmd_fill_wq_data(void *wq_ctx, struct mlx5_devx_wq_attr *wq_attr) +{ + MLX5_SET(wq, wq_ctx, wq_type, wq_attr->wq_type); + MLX5_SET(wq, wq_ctx, wq_signature, wq_attr->wq_signature); + MLX5_SET(wq, wq_ctx, end_padding_mode, wq_attr->end_padding_mode); + MLX5_SET(wq, wq_ctx, cd_slave, wq_attr->cd_slave); + MLX5_SET(wq, wq_ctx, hds_skip_first_sge, wq_attr->hds_skip_first_sge); + MLX5_SET(wq, wq_ctx, log2_hds_buf_size, wq_attr->log2_hds_buf_size); + MLX5_SET(wq, wq_ctx, page_offset, wq_attr->page_offset); + MLX5_SET(wq, wq_ctx, lwm, wq_attr->lwm); + MLX5_SET(wq, wq_ctx, pd, wq_attr->pd); + MLX5_SET(wq, wq_ctx, uar_page, wq_attr->uar_page); + MLX5_SET64(wq, wq_ctx, dbr_addr, wq_attr->dbr_addr); + MLX5_SET(wq, wq_ctx, hw_counter, wq_attr->hw_counter); + MLX5_SET(wq, wq_ctx, sw_counter, wq_attr->sw_counter); + MLX5_SET(wq, wq_ctx, log_wq_stride, wq_attr->log_wq_stride); + MLX5_SET(wq, wq_ctx, log_wq_pg_sz, wq_attr->log_wq_pg_sz); + MLX5_SET(wq, wq_ctx, log_wq_sz, wq_attr->log_wq_sz); + MLX5_SET(wq, wq_ctx, dbr_umem_valid, wq_attr->dbr_umem_valid); + MLX5_SET(wq, wq_ctx, wq_umem_valid, wq_attr->wq_umem_valid); + MLX5_SET(wq, wq_ctx, log_hairpin_num_packets, + wq_attr->log_hairpin_num_packets); + MLX5_SET(wq, wq_ctx, log_hairpin_data_sz, wq_attr->log_hairpin_data_sz); + MLX5_SET(wq, wq_ctx, single_wqe_log_num_of_strides, + wq_attr->single_wqe_log_num_of_strides); + MLX5_SET(wq, wq_ctx, two_byte_shift_en, wq_attr->two_byte_shift_en); + MLX5_SET(wq, wq_ctx, single_stride_log_num_of_bytes, + wq_attr->single_stride_log_num_of_bytes); + MLX5_SET(wq, wq_ctx, dbr_umem_id, wq_attr->dbr_umem_id); + MLX5_SET(wq, wq_ctx, wq_umem_id, wq_attr->wq_umem_id); + MLX5_SET64(wq, wq_ctx, wq_umem_offset, wq_attr->wq_umem_offset); +} + +/** + * Create RQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] rq_attr + * Pointer to create RQ attributes structure. + * @param [in] socket + * CPU socket ID for allocations. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_rq(struct ibv_context *ctx, + struct mlx5_devx_create_rq_attr *rq_attr, + int socket) +{ + uint32_t in[MLX5_ST_SZ_DW(create_rq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_rq_out)] = {0}; + void *rq_ctx, *wq_ctx; + struct mlx5_devx_wq_attr *wq_attr; + struct mlx5_devx_obj *rq = NULL; + + rq = rte_calloc_socket(__func__, 1, sizeof(*rq), 0, socket); + if (!rq) { + DRV_LOG(ERR, "Failed to allocate RQ data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ); + rq_ctx = MLX5_ADDR_OF(create_rq_in, in, ctx); + MLX5_SET(rqc, rq_ctx, rlky, rq_attr->rlky); + MLX5_SET(rqc, rq_ctx, delay_drop_en, rq_attr->delay_drop_en); + MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); + MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); + MLX5_SET(rqc, rq_ctx, mem_rq_type, rq_attr->mem_rq_type); + MLX5_SET(rqc, rq_ctx, state, rq_attr->state); + MLX5_SET(rqc, rq_ctx, flush_in_error_en, rq_attr->flush_in_error_en); + MLX5_SET(rqc, rq_ctx, hairpin, rq_attr->hairpin); + MLX5_SET(rqc, rq_ctx, user_index, rq_attr->user_index); + MLX5_SET(rqc, rq_ctx, cqn, rq_attr->cqn); + MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); + MLX5_SET(rqc, rq_ctx, rmpn, rq_attr->rmpn); + wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); + wq_attr = &rq_attr->wq_attr; + devx_cmd_fill_wq_data(wq_ctx, wq_attr); + rq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!rq->obj) { + DRV_LOG(ERR, "Failed to create RQ using DevX"); + rte_errno = errno; + rte_free(rq); + return NULL; + } + rq->id = MLX5_GET(create_rq_out, out, rqn); + return rq; +} + +/** + * Modify RQ using DevX API. + * + * @param[in] rq + * Pointer to RQ object structure. + * @param [in] rq_attr + * Pointer to modify RQ attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, + struct mlx5_devx_modify_rq_attr *rq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(modify_rq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(modify_rq_out)] = {0}; + void *rq_ctx, *wq_ctx; + int ret; + + MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ); + MLX5_SET(modify_rq_in, in, rq_state, rq_attr->rq_state); + MLX5_SET(modify_rq_in, in, rqn, rq->id); + MLX5_SET64(modify_rq_in, in, modify_bitmask, rq_attr->modify_bitmask); + rq_ctx = MLX5_ADDR_OF(modify_rq_in, in, ctx); + MLX5_SET(rqc, rq_ctx, state, rq_attr->state); + if (rq_attr->modify_bitmask & + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS) + MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); + if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD) + MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); + if (rq_attr->modify_bitmask & + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID) + MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); + MLX5_SET(rqc, rq_ctx, hairpin_peer_sq, rq_attr->hairpin_peer_sq); + MLX5_SET(rqc, rq_ctx, hairpin_peer_vhca, rq_attr->hairpin_peer_vhca); + if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM) { + wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); + MLX5_SET(wq, wq_ctx, lwm, rq_attr->lwm); + } + ret = mlx5_glue->devx_obj_modify(rq->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify RQ using DevX"); + rte_errno = errno; + return -errno; + } + return ret; +} + +/** + * Create TIR using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] tir_attr + * Pointer to TIR attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_tir(struct ibv_context *ctx, + struct mlx5_devx_tir_attr *tir_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_tir_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_tir_out)] = {0}; + void *tir_ctx, *outer, *inner; + struct mlx5_devx_obj *tir = NULL; + int i; + + tir = rte_calloc(__func__, 1, sizeof(*tir), 0); + if (!tir) { + DRV_LOG(ERR, "Failed to allocate TIR data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); + tir_ctx = MLX5_ADDR_OF(create_tir_in, in, ctx); + MLX5_SET(tirc, tir_ctx, disp_type, tir_attr->disp_type); + MLX5_SET(tirc, tir_ctx, lro_timeout_period_usecs, + tir_attr->lro_timeout_period_usecs); + MLX5_SET(tirc, tir_ctx, lro_enable_mask, tir_attr->lro_enable_mask); + MLX5_SET(tirc, tir_ctx, lro_max_msg_sz, tir_attr->lro_max_msg_sz); + MLX5_SET(tirc, tir_ctx, inline_rqn, tir_attr->inline_rqn); + MLX5_SET(tirc, tir_ctx, rx_hash_symmetric, tir_attr->rx_hash_symmetric); + MLX5_SET(tirc, tir_ctx, tunneled_offload_en, + tir_attr->tunneled_offload_en); + MLX5_SET(tirc, tir_ctx, indirect_table, tir_attr->indirect_table); + MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn); + MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block); + MLX5_SET(tirc, tir_ctx, transport_domain, tir_attr->transport_domain); + for (i = 0; i < 10; i++) { + MLX5_SET(tirc, tir_ctx, rx_hash_toeplitz_key[i], + tir_attr->rx_hash_toeplitz_key[i]); + } + outer = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_outer); + MLX5_SET(rx_hash_field_select, outer, l3_prot_type, + tir_attr->rx_hash_field_selector_outer.l3_prot_type); + MLX5_SET(rx_hash_field_select, outer, l4_prot_type, + tir_attr->rx_hash_field_selector_outer.l4_prot_type); + MLX5_SET(rx_hash_field_select, outer, selected_fields, + tir_attr->rx_hash_field_selector_outer.selected_fields); + inner = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_inner); + MLX5_SET(rx_hash_field_select, inner, l3_prot_type, + tir_attr->rx_hash_field_selector_inner.l3_prot_type); + MLX5_SET(rx_hash_field_select, inner, l4_prot_type, + tir_attr->rx_hash_field_selector_inner.l4_prot_type); + MLX5_SET(rx_hash_field_select, inner, selected_fields, + tir_attr->rx_hash_field_selector_inner.selected_fields); + tir->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!tir->obj) { + DRV_LOG(ERR, "Failed to create TIR using DevX"); + rte_errno = errno; + rte_free(tir); + return NULL; + } + tir->id = MLX5_GET(create_tir_out, out, tirn); + return tir; +} + +/** + * Create RQT using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] rqt_attr + * Pointer to RQT attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, + struct mlx5_devx_rqt_attr *rqt_attr) +{ + uint32_t *in = NULL; + uint32_t inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + + rqt_attr->rqt_actual_size * sizeof(uint32_t); + uint32_t out[MLX5_ST_SZ_DW(create_rqt_out)] = {0}; + void *rqt_ctx; + struct mlx5_devx_obj *rqt = NULL; + int i; + + in = rte_calloc(__func__, 1, inlen, 0); + if (!in) { + DRV_LOG(ERR, "Failed to allocate RQT IN data"); + rte_errno = ENOMEM; + return NULL; + } + rqt = rte_calloc(__func__, 1, sizeof(*rqt), 0); + if (!rqt) { + DRV_LOG(ERR, "Failed to allocate RQT data"); + rte_errno = ENOMEM; + rte_free(in); + return NULL; + } + MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT); + rqt_ctx = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); + MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size); + MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size); + for (i = 0; i < rqt_attr->rqt_actual_size; i++) + MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]); + rqt->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out)); + rte_free(in); + if (!rqt->obj) { + DRV_LOG(ERR, "Failed to create RQT using DevX"); + rte_errno = errno; + rte_free(rqt); + return NULL; + } + rqt->id = MLX5_GET(create_rqt_out, out, rqtn); + return rqt; +} + +/** + * Create SQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] sq_attr + * Pointer to SQ attributes structure. + * @param [in] socket + * CPU socket ID for allocations. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + **/ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_sq(struct ibv_context *ctx, + struct mlx5_devx_create_sq_attr *sq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0}; + void *sq_ctx; + void *wq_ctx; + struct mlx5_devx_wq_attr *wq_attr; + struct mlx5_devx_obj *sq = NULL; + + sq = rte_calloc(__func__, 1, sizeof(*sq), 0); + if (!sq) { + DRV_LOG(ERR, "Failed to allocate SQ data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ); + sq_ctx = MLX5_ADDR_OF(create_sq_in, in, ctx); + MLX5_SET(sqc, sq_ctx, rlky, sq_attr->rlky); + MLX5_SET(sqc, sq_ctx, cd_master, sq_attr->cd_master); + MLX5_SET(sqc, sq_ctx, fre, sq_attr->fre); + MLX5_SET(sqc, sq_ctx, flush_in_error_en, sq_attr->flush_in_error_en); + MLX5_SET(sqc, sq_ctx, allow_multi_pkt_send_wqe, + sq_attr->flush_in_error_en); + MLX5_SET(sqc, sq_ctx, min_wqe_inline_mode, + sq_attr->min_wqe_inline_mode); + MLX5_SET(sqc, sq_ctx, state, sq_attr->state); + MLX5_SET(sqc, sq_ctx, reg_umr, sq_attr->reg_umr); + MLX5_SET(sqc, sq_ctx, allow_swp, sq_attr->allow_swp); + MLX5_SET(sqc, sq_ctx, hairpin, sq_attr->hairpin); + MLX5_SET(sqc, sq_ctx, user_index, sq_attr->user_index); + MLX5_SET(sqc, sq_ctx, cqn, sq_attr->cqn); + MLX5_SET(sqc, sq_ctx, packet_pacing_rate_limit_index, + sq_attr->packet_pacing_rate_limit_index); + MLX5_SET(sqc, sq_ctx, tis_lst_sz, sq_attr->tis_lst_sz); + MLX5_SET(sqc, sq_ctx, tis_num_0, sq_attr->tis_num); + wq_ctx = MLX5_ADDR_OF(sqc, sq_ctx, wq); + wq_attr = &sq_attr->wq_attr; + devx_cmd_fill_wq_data(wq_ctx, wq_attr); + sq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!sq->obj) { + DRV_LOG(ERR, "Failed to create SQ using DevX"); + rte_errno = errno; + rte_free(sq); + return NULL; + } + sq->id = MLX5_GET(create_sq_out, out, sqn); + return sq; +} + +/** + * Modify SQ using DevX API. + * + * @param[in] sq + * Pointer to SQ object structure. + * @param [in] sq_attr + * Pointer to SQ attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, + struct mlx5_devx_modify_sq_attr *sq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0}; + void *sq_ctx; + int ret; + + MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); + MLX5_SET(modify_sq_in, in, sq_state, sq_attr->sq_state); + MLX5_SET(modify_sq_in, in, sqn, sq->id); + sq_ctx = MLX5_ADDR_OF(modify_sq_in, in, ctx); + MLX5_SET(sqc, sq_ctx, state, sq_attr->state); + MLX5_SET(sqc, sq_ctx, hairpin_peer_rq, sq_attr->hairpin_peer_rq); + MLX5_SET(sqc, sq_ctx, hairpin_peer_vhca, sq_attr->hairpin_peer_vhca); + ret = mlx5_glue->devx_obj_modify(sq->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify SQ using DevX"); + rte_errno = errno; + return -errno; + } + return ret; +} + +/** + * Create TIS using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] tis_attr + * Pointer to TIS attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_tis(struct ibv_context *ctx, + struct mlx5_devx_tis_attr *tis_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_tis_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_tis_out)] = {0}; + struct mlx5_devx_obj *tis = NULL; + void *tis_ctx; + + tis = rte_calloc(__func__, 1, sizeof(*tis), 0); + if (!tis) { + DRV_LOG(ERR, "Failed to allocate TIS object"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS); + tis_ctx = MLX5_ADDR_OF(create_tis_in, in, ctx); + MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, + tis_attr->strict_lag_tx_port_affinity); + MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, + tis_attr->strict_lag_tx_port_affinity); + MLX5_SET(tisc, tis_ctx, prio, tis_attr->prio); + MLX5_SET(tisc, tis_ctx, transport_domain, + tis_attr->transport_domain); + tis->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!tis->obj) { + DRV_LOG(ERR, "Failed to create TIS using DevX"); + rte_errno = errno; + rte_free(tis); + return NULL; + } + tis->id = MLX5_GET(create_tis_out, out, tisn); + return tis; +} + +/** + * Create transport domain using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_td(struct ibv_context *ctx) +{ + uint32_t in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0}; + struct mlx5_devx_obj *td = NULL; + + td = rte_calloc(__func__, 1, sizeof(*td), 0); + if (!td) { + DRV_LOG(ERR, "Failed to allocate TD object"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(alloc_transport_domain_in, in, opcode, + MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN); + td->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!td->obj) { + DRV_LOG(ERR, "Failed to create TIS using DevX"); + rte_errno = errno; + rte_free(td); + return NULL; + } + td->id = MLX5_GET(alloc_transport_domain_out, out, + transport_domain); + return td; +} + +/** + * Dump all flows to file. + * + * @param[in] fdb_domain + * FDB domain. + * @param[in] rx_domain + * RX domain. + * @param[in] tx_domain + * TX domain. + * @param[out] file + * Pointer to file stream. + * + * @return + * 0 on success, a nagative value otherwise. + */ +int +mlx5_devx_cmd_flow_dump(void *fdb_domain __rte_unused, + void *rx_domain __rte_unused, + void *tx_domain __rte_unused, FILE *file __rte_unused) +{ + int ret = 0; + +#ifdef HAVE_MLX5_DR_FLOW_DUMP + if (fdb_domain) { + ret = mlx5_glue->dr_dump_domain(file, fdb_domain); + if (ret) + return ret; + } + assert(rx_domain); + ret = mlx5_glue->dr_dump_domain(file, rx_domain); + if (ret) + return ret; + assert(tx_domain); + ret = mlx5_glue->dr_dump_domain(file, tx_domain); +#else + ret = ENOTSUP; +#endif + return -ret; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h new file mode 100644 index 0000000..2d58d96 --- /dev/null +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_DEVX_CMDS_H_ +#define RTE_PMD_MLX5_DEVX_CMDS_H_ + +#include "mlx5_glue.h" + + +/* devX creation object */ +struct mlx5_devx_obj { + struct mlx5dv_devx_obj *obj; /* The DV object. */ + int id; /* The object ID. */ +}; + +struct mlx5_devx_mkey_attr { + uint64_t addr; + uint64_t size; + uint32_t umem_id; + uint32_t pd; +}; + +/* HCA qos attributes. */ +struct mlx5_hca_qos_attr { + uint32_t sup:1; /* Whether QOS is supported. */ + uint32_t srtcm_sup:1; /* Whether srTCM mode is supported. */ + uint32_t flow_meter_reg_share:1; + /* Whether reg_c share is supported. */ + uint8_t log_max_flow_meter; + /* Power of the maximum supported meters. */ + uint8_t flow_meter_reg_c_ids; + /* Bitmap of the reg_Cs available for flow meter to use. */ + +}; + +/* HCA supports this number of time periods for LRO. */ +#define MLX5_LRO_NUM_SUPP_PERIODS 4 + +/* HCA attributes. */ +struct mlx5_hca_attr { + uint32_t eswitch_manager:1; + uint32_t flow_counters_dump:1; + uint8_t flow_counter_bulk_alloc_bitmap; + uint32_t eth_net_offloads:1; + uint32_t eth_virt:1; + uint32_t wqe_vlan_insert:1; + uint32_t wqe_inline_mode:2; + uint32_t vport_inline_mode:3; + uint32_t tunnel_stateless_geneve_rx:1; + uint32_t geneve_max_opt_len:1; /* 0x0: 14DW, 0x1: 63DW */ + uint32_t tunnel_stateless_gtp:1; + uint32_t lro_cap:1; + uint32_t tunnel_lro_gre:1; + uint32_t tunnel_lro_vxlan:1; + uint32_t lro_max_msg_sz_mode:2; + uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; + uint32_t flex_parser_protocols; + uint32_t hairpin:1; + uint32_t log_max_hairpin_queues:5; + uint32_t log_max_hairpin_wq_data_sz:5; + uint32_t log_max_hairpin_num_packets:5; + uint32_t vhca_id:16; + struct mlx5_hca_qos_attr qos; +}; + +struct mlx5_devx_wq_attr { + uint32_t wq_type:4; + uint32_t wq_signature:1; + uint32_t end_padding_mode:2; + uint32_t cd_slave:1; + uint32_t hds_skip_first_sge:1; + uint32_t log2_hds_buf_size:3; + uint32_t page_offset:5; + uint32_t lwm:16; + uint32_t pd:24; + uint32_t uar_page:24; + uint64_t dbr_addr; + uint32_t hw_counter; + uint32_t sw_counter; + uint32_t log_wq_stride:4; + uint32_t log_wq_pg_sz:5; + uint32_t log_wq_sz:5; + uint32_t dbr_umem_valid:1; + uint32_t wq_umem_valid:1; + uint32_t log_hairpin_num_packets:5; + uint32_t log_hairpin_data_sz:5; + uint32_t single_wqe_log_num_of_strides:4; + uint32_t two_byte_shift_en:1; + uint32_t single_stride_log_num_of_bytes:3; + uint32_t dbr_umem_id; + uint32_t wq_umem_id; + uint64_t wq_umem_offset; +}; + +/* Create RQ attributes structure, used by create RQ operation. */ +struct mlx5_devx_create_rq_attr { + uint32_t rlky:1; + uint32_t delay_drop_en:1; + uint32_t scatter_fcs:1; + uint32_t vsd:1; + uint32_t mem_rq_type:4; + uint32_t state:4; + uint32_t flush_in_error_en:1; + uint32_t hairpin:1; + uint32_t user_index:24; + uint32_t cqn:24; + uint32_t counter_set_id:8; + uint32_t rmpn:24; + struct mlx5_devx_wq_attr wq_attr; +}; + +/* Modify RQ attributes structure, used by modify RQ operation. */ +struct mlx5_devx_modify_rq_attr { + uint32_t rqn:24; + uint32_t rq_state:4; /* Current RQ state. */ + uint32_t state:4; /* Required RQ state. */ + uint32_t scatter_fcs:1; + uint32_t vsd:1; + uint32_t counter_set_id:8; + uint32_t hairpin_peer_sq:24; + uint32_t hairpin_peer_vhca:16; + uint64_t modify_bitmask; + uint32_t lwm:16; /* Contained WQ lwm. */ +}; + +struct mlx5_rx_hash_field_select { + uint32_t l3_prot_type:1; + uint32_t l4_prot_type:1; + uint32_t selected_fields:30; +}; + +/* TIR attributes structure, used by TIR operations. */ +struct mlx5_devx_tir_attr { + uint32_t disp_type:4; + uint32_t lro_timeout_period_usecs:16; + uint32_t lro_enable_mask:4; + uint32_t lro_max_msg_sz:8; + uint32_t inline_rqn:24; + uint32_t rx_hash_symmetric:1; + uint32_t tunneled_offload_en:1; + uint32_t indirect_table:24; + uint32_t rx_hash_fn:4; + uint32_t self_lb_block:2; + uint32_t transport_domain:24; + uint32_t rx_hash_toeplitz_key[10]; + struct mlx5_rx_hash_field_select rx_hash_field_selector_outer; + struct mlx5_rx_hash_field_select rx_hash_field_selector_inner; +}; + +/* RQT attributes structure, used by RQT operations. */ +struct mlx5_devx_rqt_attr { + uint32_t rqt_max_size:16; + uint32_t rqt_actual_size:16; + uint32_t rq_list[]; +}; + +/* TIS attributes structure. */ +struct mlx5_devx_tis_attr { + uint32_t strict_lag_tx_port_affinity:1; + uint32_t tls_en:1; + uint32_t lag_tx_port_affinity:4; + uint32_t prio:4; + uint32_t transport_domain:24; +}; + +/* SQ attributes structure, used by SQ create operation. */ +struct mlx5_devx_create_sq_attr { + uint32_t rlky:1; + uint32_t cd_master:1; + uint32_t fre:1; + uint32_t flush_in_error_en:1; + uint32_t allow_multi_pkt_send_wqe:1; + uint32_t min_wqe_inline_mode:3; + uint32_t state:4; + uint32_t reg_umr:1; + uint32_t allow_swp:1; + uint32_t hairpin:1; + uint32_t user_index:24; + uint32_t cqn:24; + uint32_t packet_pacing_rate_limit_index:16; + uint32_t tis_lst_sz:16; + uint32_t tis_num:24; + struct mlx5_devx_wq_attr wq_attr; +}; + +/* SQ attributes structure, used by SQ modify operation. */ +struct mlx5_devx_modify_sq_attr { + uint32_t sq_state:4; + uint32_t state:4; + uint32_t hairpin_peer_rq:24; + uint32_t hairpin_peer_vhca:16; +}; + +/* mlx5_devx_cmds.c */ + +struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, + uint32_t bulk_sz); +int mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj); +int mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, + int clear, uint32_t n_counters, + uint64_t *pkts, uint64_t *bytes, + uint32_t mkey, void *addr, + struct mlx5dv_devx_cmd_comp *cmd_comp, + uint64_t async_id); +int mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, + struct mlx5_hca_attr *attr); +struct mlx5_devx_obj *mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, + struct mlx5_devx_mkey_attr *attr); +int mlx5_devx_get_out_command_status(void *out); +int mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, + uint32_t *tis_td); +struct mlx5_devx_obj *mlx5_devx_cmd_create_rq(struct ibv_context *ctx, + struct mlx5_devx_create_rq_attr *rq_attr, + int socket); +int mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, + struct mlx5_devx_modify_rq_attr *rq_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_tir(struct ibv_context *ctx, + struct mlx5_devx_tir_attr *tir_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, + struct mlx5_devx_rqt_attr *rqt_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_sq(struct ibv_context *ctx, + struct mlx5_devx_create_sq_attr *sq_attr); +int mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, + struct mlx5_devx_modify_sq_attr *sq_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_tis(struct ibv_context *ctx, + struct mlx5_devx_tis_attr *tis_attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_td(struct ibv_context *ctx); +int mlx5_devx_cmd_flow_dump(void *fdb_domain, void *rx_domain, void *tx_domain, + FILE *file); +#endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c new file mode 100644 index 0000000..d5bc84e --- /dev/null +++ b/drivers/common/mlx5/mlx5_glue.c @@ -0,0 +1,1138 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include +#include +/* + * Not needed by this file; included to work around the lack of off_t + * definition for mlx5dv.h with unpatched rdma-core versions. + */ +#include + +#include + +#include "mlx5_glue.h" + +static int +mlx5_glue_fork_init(void) +{ + return ibv_fork_init(); +} + +static struct ibv_pd * +mlx5_glue_alloc_pd(struct ibv_context *context) +{ + return ibv_alloc_pd(context); +} + +static int +mlx5_glue_dealloc_pd(struct ibv_pd *pd) +{ + return ibv_dealloc_pd(pd); +} + +static struct ibv_device ** +mlx5_glue_get_device_list(int *num_devices) +{ + return ibv_get_device_list(num_devices); +} + +static void +mlx5_glue_free_device_list(struct ibv_device **list) +{ + ibv_free_device_list(list); +} + +static struct ibv_context * +mlx5_glue_open_device(struct ibv_device *device) +{ + return ibv_open_device(device); +} + +static int +mlx5_glue_close_device(struct ibv_context *context) +{ + return ibv_close_device(context); +} + +static int +mlx5_glue_query_device(struct ibv_context *context, + struct ibv_device_attr *device_attr) +{ + return ibv_query_device(context, device_attr); +} + +static int +mlx5_glue_query_device_ex(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr) +{ + return ibv_query_device_ex(context, input, attr); +} + +static int +mlx5_glue_query_rt_values_ex(struct ibv_context *context, + struct ibv_values_ex *values) +{ + return ibv_query_rt_values_ex(context, values); +} + +static int +mlx5_glue_query_port(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr) +{ + return ibv_query_port(context, port_num, port_attr); +} + +static struct ibv_comp_channel * +mlx5_glue_create_comp_channel(struct ibv_context *context) +{ + return ibv_create_comp_channel(context); +} + +static int +mlx5_glue_destroy_comp_channel(struct ibv_comp_channel *channel) +{ + return ibv_destroy_comp_channel(channel); +} + +static struct ibv_cq * +mlx5_glue_create_cq(struct ibv_context *context, int cqe, void *cq_context, + struct ibv_comp_channel *channel, int comp_vector) +{ + return ibv_create_cq(context, cqe, cq_context, channel, comp_vector); +} + +static int +mlx5_glue_destroy_cq(struct ibv_cq *cq) +{ + return ibv_destroy_cq(cq); +} + +static int +mlx5_glue_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, + void **cq_context) +{ + return ibv_get_cq_event(channel, cq, cq_context); +} + +static void +mlx5_glue_ack_cq_events(struct ibv_cq *cq, unsigned int nevents) +{ + ibv_ack_cq_events(cq, nevents); +} + +static struct ibv_rwq_ind_table * +mlx5_glue_create_rwq_ind_table(struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr) +{ + return ibv_create_rwq_ind_table(context, init_attr); +} + +static int +mlx5_glue_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) +{ + return ibv_destroy_rwq_ind_table(rwq_ind_table); +} + +static struct ibv_wq * +mlx5_glue_create_wq(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr) +{ + return ibv_create_wq(context, wq_init_attr); +} + +static int +mlx5_glue_destroy_wq(struct ibv_wq *wq) +{ + return ibv_destroy_wq(wq); +} +static int +mlx5_glue_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr) +{ + return ibv_modify_wq(wq, wq_attr); +} + +static struct ibv_flow * +mlx5_glue_create_flow(struct ibv_qp *qp, struct ibv_flow_attr *flow) +{ + return ibv_create_flow(qp, flow); +} + +static int +mlx5_glue_destroy_flow(struct ibv_flow *flow_id) +{ + return ibv_destroy_flow(flow_id); +} + +static int +mlx5_glue_destroy_flow_action(void *action) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_destroy(action); +#else + struct mlx5dv_flow_action_attr *attr = action; + int res = 0; + switch (attr->type) { + case MLX5DV_FLOW_ACTION_TAG: + break; + default: + res = ibv_destroy_flow_action(attr->action); + break; + } + free(action); + return res; +#endif +#else + (void)action; + return ENOTSUP; +#endif +} + +static struct ibv_qp * +mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) +{ + return ibv_create_qp(pd, qp_init_attr); +} + +static struct ibv_qp * +mlx5_glue_create_qp_ex(struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex) +{ + return ibv_create_qp_ex(context, qp_init_attr_ex); +} + +static int +mlx5_glue_destroy_qp(struct ibv_qp *qp) +{ + return ibv_destroy_qp(qp); +} + +static int +mlx5_glue_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) +{ + return ibv_modify_qp(qp, attr, attr_mask); +} + +static struct ibv_mr * +mlx5_glue_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access) +{ + return ibv_reg_mr(pd, addr, length, access); +} + +static int +mlx5_glue_dereg_mr(struct ibv_mr *mr) +{ + return ibv_dereg_mr(mr); +} + +static struct ibv_counter_set * +mlx5_glue_create_counter_set(struct ibv_context *context, + struct ibv_counter_set_init_attr *init_attr) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)context; + (void)init_attr; + return NULL; +#else + return ibv_create_counter_set(context, init_attr); +#endif +} + +static int +mlx5_glue_destroy_counter_set(struct ibv_counter_set *cs) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)cs; + return ENOTSUP; +#else + return ibv_destroy_counter_set(cs); +#endif +} + +static int +mlx5_glue_describe_counter_set(struct ibv_context *context, + uint16_t counter_set_id, + struct ibv_counter_set_description *cs_desc) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)context; + (void)counter_set_id; + (void)cs_desc; + return ENOTSUP; +#else + return ibv_describe_counter_set(context, counter_set_id, cs_desc); +#endif +} + +static int +mlx5_glue_query_counter_set(struct ibv_query_counter_set_attr *query_attr, + struct ibv_counter_set_data *cs_data) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 + (void)query_attr; + (void)cs_data; + return ENOTSUP; +#else + return ibv_query_counter_set(query_attr, cs_data); +#endif +} + +static struct ibv_counters * +mlx5_glue_create_counters(struct ibv_context *context, + struct ibv_counters_init_attr *init_attr) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)context; + (void)init_attr; + errno = ENOTSUP; + return NULL; +#else + return ibv_create_counters(context, init_attr); +#endif +} + +static int +mlx5_glue_destroy_counters(struct ibv_counters *counters) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + return ENOTSUP; +#else + return ibv_destroy_counters(counters); +#endif +} + +static int +mlx5_glue_attach_counters(struct ibv_counters *counters, + struct ibv_counter_attach_attr *attr, + struct ibv_flow *flow) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + (void)attr; + (void)flow; + return ENOTSUP; +#else + return ibv_attach_counters_point_flow(counters, attr, flow); +#endif +} + +static int +mlx5_glue_query_counters(struct ibv_counters *counters, + uint64_t *counters_value, + uint32_t ncounters, + uint32_t flags) +{ +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 + (void)counters; + (void)counters_value; + (void)ncounters; + (void)flags; + return ENOTSUP; +#else + return ibv_read_counters(counters, counters_value, ncounters, flags); +#endif +} + +static void +mlx5_glue_ack_async_event(struct ibv_async_event *event) +{ + ibv_ack_async_event(event); +} + +static int +mlx5_glue_get_async_event(struct ibv_context *context, + struct ibv_async_event *event) +{ + return ibv_get_async_event(context, event); +} + +static const char * +mlx5_glue_port_state_str(enum ibv_port_state port_state) +{ + return ibv_port_state_str(port_state); +} + +static struct ibv_cq * +mlx5_glue_cq_ex_to_cq(struct ibv_cq_ex *cq) +{ + return ibv_cq_ex_to_cq(cq); +} + +static void * +mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_dest_table(tbl); +#else + (void)tbl; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_dest_port(void *domain, uint32_t port) +{ +#ifdef HAVE_MLX5DV_DR_DEVX_PORT + return mlx5dv_dr_action_create_dest_ib_port(domain, port); +#else +#ifdef HAVE_MLX5DV_DR_ESWITCH + return mlx5dv_dr_action_create_dest_vport(domain, port); +#else + (void)domain; + (void)port; + errno = ENOTSUP; + return NULL; +#endif +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_drop(void) +{ +#ifdef HAVE_MLX5DV_DR_ESWITCH + return mlx5dv_dr_action_create_drop(); +#else + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_push_vlan(struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_push_vlan(domain, vlan_tag); +#else + (void)domain; + (void)vlan_tag; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_action_pop_vlan(void) +{ +#ifdef HAVE_MLX5DV_DR_VLAN + return mlx5dv_dr_action_create_pop_vlan(); +#else + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_table_create(domain, level); +#else + (void)domain; + (void)level; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dr_destroy_flow_tbl(void *tbl) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_table_destroy(tbl); +#else + (void)tbl; + errno = ENOTSUP; + return errno; +#endif +} + +static void * +mlx5_glue_dr_create_domain(struct ibv_context *ctx, + enum mlx5dv_dr_domain_type domain) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_domain_create(ctx, domain); +#else + (void)ctx; + (void)domain; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dr_destroy_domain(void *domain) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_domain_destroy(domain); +#else + (void)domain; + errno = ENOTSUP; + return errno; +#endif +} + +static struct ibv_cq_ex * +mlx5_glue_dv_create_cq(struct ibv_context *context, + struct ibv_cq_init_attr_ex *cq_attr, + struct mlx5dv_cq_init_attr *mlx5_cq_attr) +{ + return mlx5dv_create_cq(context, cq_attr, mlx5_cq_attr); +} + +static struct ibv_wq * +mlx5_glue_dv_create_wq(struct ibv_context *context, + struct ibv_wq_init_attr *wq_attr, + struct mlx5dv_wq_init_attr *mlx5_wq_attr) +{ +#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT + (void)context; + (void)wq_attr; + (void)mlx5_wq_attr; + errno = ENOTSUP; + return NULL; +#else + return mlx5dv_create_wq(context, wq_attr, mlx5_wq_attr); +#endif +} + +static int +mlx5_glue_dv_query_device(struct ibv_context *ctx, + struct mlx5dv_context *attrs_out) +{ + return mlx5dv_query_device(ctx, attrs_out); +} + +static int +mlx5_glue_dv_set_context_attr(struct ibv_context *ibv_ctx, + enum mlx5dv_set_ctx_attr_type type, void *attr) +{ + return mlx5dv_set_context_attr(ibv_ctx, type, attr); +} + +static int +mlx5_glue_dv_init_obj(struct mlx5dv_obj *obj, uint64_t obj_type) +{ + return mlx5dv_init_obj(obj, obj_type); +} + +static struct ibv_qp * +mlx5_glue_dv_create_qp(struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex, + struct mlx5dv_qp_init_attr *dv_qp_init_attr) +{ +#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT + return mlx5dv_create_qp(context, qp_init_attr_ex, dv_qp_init_attr); +#else + (void)context; + (void)qp_init_attr_ex; + (void)dv_qp_init_attr; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_matcher(struct ibv_context *context, + struct mlx5dv_flow_matcher_attr *matcher_attr, + void *tbl) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)context; + return mlx5dv_dr_matcher_create(tbl, matcher_attr->priority, + matcher_attr->match_criteria_enable, + matcher_attr->match_mask); +#else + (void)tbl; + return mlx5dv_create_flow_matcher(context, matcher_attr); +#endif +#else + (void)context; + (void)matcher_attr; + (void)tbl; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow(void *matcher, + void *match_value, + size_t num_actions, + void *actions[]) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_rule_create(matcher, match_value, num_actions, + (struct mlx5dv_dr_action **)actions); +#else + struct mlx5dv_flow_action_attr actions_attr[8]; + + if (num_actions > 8) + return NULL; + for (size_t i = 0; i < num_actions; i++) + actions_attr[i] = + *((struct mlx5dv_flow_action_attr *)(actions[i])); + return mlx5dv_create_flow(matcher, match_value, + num_actions, actions_attr); +#endif +#else + (void)matcher; + (void)match_value; + (void)num_actions; + (void)actions; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_counter(void *counter_obj, uint32_t offset) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_flow_counter(counter_obj, offset); +#else + struct mlx5dv_flow_action_attr *action; + + (void)offset; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_COUNTERS_DEVX; + action->obj = counter_obj; + return action; +#endif +#else + (void)counter_obj; + (void)offset; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_dest_ibv_qp(void *qp) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_dest_ibv_qp(qp); +#else + struct mlx5dv_flow_action_attr *action; + + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_DEST_IBV_QP; + action->obj = qp; + return action; +#endif +#else + (void)qp; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_dest_devx_tir(void *tir) +{ +#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR + return mlx5dv_dr_action_create_dest_devx_tir(tir); +#else + (void)tir; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_modify_header + (struct ibv_context *ctx, + enum mlx5dv_flow_table_type ft_type, + void *domain, uint64_t flags, + size_t actions_sz, + uint64_t actions[]) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)ctx; + (void)ft_type; + return mlx5dv_dr_action_create_modify_header(domain, flags, actions_sz, + (__be64 *)actions); +#else + struct mlx5dv_flow_action_attr *action; + + (void)domain; + (void)flags; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + action->action = mlx5dv_create_flow_action_modify_header + (ctx, actions_sz, actions, ft_type); + return action; +#endif +#else + (void)ctx; + (void)ft_type; + (void)domain; + (void)flags; + (void)actions_sz; + (void)actions; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_packet_reformat + (struct ibv_context *ctx, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type, + struct mlx5dv_dr_domain *domain, + uint32_t flags, size_t data_sz, void *data) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + (void)ctx; + (void)ft_type; + return mlx5dv_dr_action_create_packet_reformat(domain, flags, + reformat_type, data_sz, + data); +#else + (void)domain; + (void)flags; + struct mlx5dv_flow_action_attr *action; + + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + action->action = mlx5dv_create_flow_action_packet_reformat + (ctx, data_sz, data, reformat_type, ft_type); + return action; +#endif +#else + (void)ctx; + (void)reformat_type; + (void)ft_type; + (void)domain; + (void)flags; + (void)data_sz; + (void)data; + errno = ENOTSUP; + return NULL; +#endif +} + +static void * +mlx5_glue_dv_create_flow_action_tag(uint32_t tag) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_action_create_tag(tag); +#else + struct mlx5dv_flow_action_attr *action; + action = malloc(sizeof(*action)); + if (!action) + return NULL; + action->type = MLX5DV_FLOW_ACTION_TAG; + action->tag_value = tag; + return action; +#endif +#endif + (void)tag; + errno = ENOTSUP; + return NULL; +} + +static void * +mlx5_glue_dv_create_flow_action_meter(struct mlx5dv_dr_flow_meter_attr *attr) +{ +#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) + return mlx5dv_dr_action_create_flow_meter(attr); +#else + (void)attr; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_dv_modify_flow_action_meter(void *action, + struct mlx5dv_dr_flow_meter_attr *attr, + uint64_t modify_bits) +{ +#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) + return mlx5dv_dr_action_modify_flow_meter(action, attr, modify_bits); +#else + (void)action; + (void)attr; + (void)modify_bits; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_dv_destroy_flow(void *flow_id) +{ +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_rule_destroy(flow_id); +#else + return ibv_destroy_flow(flow_id); +#endif +} + +static int +mlx5_glue_dv_destroy_flow_matcher(void *matcher) +{ +#ifdef HAVE_IBV_FLOW_DV_SUPPORT +#ifdef HAVE_MLX5DV_DR + return mlx5dv_dr_matcher_destroy(matcher); +#else + return mlx5dv_destroy_flow_matcher(matcher); +#endif +#else + (void)matcher; + errno = ENOTSUP; + return errno; +#endif +} + +static struct ibv_context * +mlx5_glue_dv_open_device(struct ibv_device *device) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_open_device(device, + &(struct mlx5dv_context_attr){ + .flags = MLX5DV_CONTEXT_FLAGS_DEVX, + }); +#else + (void)device; + errno = ENOTSUP; + return NULL; +#endif +} + +static struct mlx5dv_devx_obj * +mlx5_glue_devx_obj_create(struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_create(ctx, in, inlen, out, outlen); +#else + (void)ctx; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + errno = ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_devx_obj_destroy(struct mlx5dv_devx_obj *obj) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_destroy(obj); +#else + (void)obj; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_query(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_query(obj, in, inlen, out, outlen); +#else + (void)obj; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_modify(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_obj_modify(obj, in, inlen, out, outlen); +#else + (void)obj; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_general_cmd(struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_general_cmd(ctx, in, inlen, out, outlen); +#else + (void)ctx; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + return -ENOTSUP; +#endif +} + +static struct mlx5dv_devx_cmd_comp * +mlx5_glue_devx_create_cmd_comp(struct ibv_context *ctx) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_create_cmd_comp(ctx); +#else + (void)ctx; + errno = -ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_destroy_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + mlx5dv_devx_destroy_cmd_comp(cmd_comp); +#else + (void)cmd_comp; + errno = -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_obj_query_async(struct mlx5dv_devx_obj *obj, const void *in, + size_t inlen, size_t outlen, uint64_t wr_id, + struct mlx5dv_devx_cmd_comp *cmd_comp) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_obj_query_async(obj, in, inlen, outlen, wr_id, + cmd_comp); +#else + (void)obj; + (void)in; + (void)inlen; + (void)outlen; + (void)wr_id; + (void)cmd_comp; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_get_async_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp, + struct mlx5dv_devx_async_cmd_hdr *cmd_resp, + size_t cmd_resp_len) +{ +#ifdef HAVE_IBV_DEVX_ASYNC + return mlx5dv_devx_get_async_cmd_comp(cmd_comp, cmd_resp, + cmd_resp_len); +#else + (void)cmd_comp; + (void)cmd_resp; + (void)cmd_resp_len; + return -ENOTSUP; +#endif +} + +static struct mlx5dv_devx_umem * +mlx5_glue_devx_umem_reg(struct ibv_context *context, void *addr, size_t size, + uint32_t access) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_umem_reg(context, addr, size, access); +#else + (void)context; + (void)addr; + (void)size; + (void)access; + errno = -ENOTSUP; + return NULL; +#endif +} + +static int +mlx5_glue_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_umem_dereg(dv_devx_umem); +#else + (void)dv_devx_umem; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_qp_query(struct ibv_qp *qp, + const void *in, size_t inlen, + void *out, size_t outlen) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_qp_query(qp, in, inlen, out, outlen); +#else + (void)qp; + (void)in; + (void)inlen; + (void)out; + (void)outlen; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_devx_port_query(struct ibv_context *ctx, + uint32_t port_num, + struct mlx5dv_devx_port *mlx5_devx_port) +{ +#ifdef HAVE_MLX5DV_DR_DEVX_PORT + return mlx5dv_query_devx_port(ctx, port_num, mlx5_devx_port); +#else + (void)ctx; + (void)port_num; + (void)mlx5_devx_port; + errno = ENOTSUP; + return errno; +#endif +} + +static int +mlx5_glue_dr_dump_domain(FILE *file, void *domain) +{ +#ifdef HAVE_MLX5_DR_FLOW_DUMP + return mlx5dv_dump_dr_domain(file, domain); +#else + RTE_SET_USED(file); + RTE_SET_USED(domain); + return -ENOTSUP; +#endif +} + +alignas(RTE_CACHE_LINE_SIZE) +const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ + .version = MLX5_GLUE_VERSION, + .fork_init = mlx5_glue_fork_init, + .alloc_pd = mlx5_glue_alloc_pd, + .dealloc_pd = mlx5_glue_dealloc_pd, + .get_device_list = mlx5_glue_get_device_list, + .free_device_list = mlx5_glue_free_device_list, + .open_device = mlx5_glue_open_device, + .close_device = mlx5_glue_close_device, + .query_device = mlx5_glue_query_device, + .query_device_ex = mlx5_glue_query_device_ex, + .query_rt_values_ex = mlx5_glue_query_rt_values_ex, + .query_port = mlx5_glue_query_port, + .create_comp_channel = mlx5_glue_create_comp_channel, + .destroy_comp_channel = mlx5_glue_destroy_comp_channel, + .create_cq = mlx5_glue_create_cq, + .destroy_cq = mlx5_glue_destroy_cq, + .get_cq_event = mlx5_glue_get_cq_event, + .ack_cq_events = mlx5_glue_ack_cq_events, + .create_rwq_ind_table = mlx5_glue_create_rwq_ind_table, + .destroy_rwq_ind_table = mlx5_glue_destroy_rwq_ind_table, + .create_wq = mlx5_glue_create_wq, + .destroy_wq = mlx5_glue_destroy_wq, + .modify_wq = mlx5_glue_modify_wq, + .create_flow = mlx5_glue_create_flow, + .destroy_flow = mlx5_glue_destroy_flow, + .destroy_flow_action = mlx5_glue_destroy_flow_action, + .create_qp = mlx5_glue_create_qp, + .create_qp_ex = mlx5_glue_create_qp_ex, + .destroy_qp = mlx5_glue_destroy_qp, + .modify_qp = mlx5_glue_modify_qp, + .reg_mr = mlx5_glue_reg_mr, + .dereg_mr = mlx5_glue_dereg_mr, + .create_counter_set = mlx5_glue_create_counter_set, + .destroy_counter_set = mlx5_glue_destroy_counter_set, + .describe_counter_set = mlx5_glue_describe_counter_set, + .query_counter_set = mlx5_glue_query_counter_set, + .create_counters = mlx5_glue_create_counters, + .destroy_counters = mlx5_glue_destroy_counters, + .attach_counters = mlx5_glue_attach_counters, + .query_counters = mlx5_glue_query_counters, + .ack_async_event = mlx5_glue_ack_async_event, + .get_async_event = mlx5_glue_get_async_event, + .port_state_str = mlx5_glue_port_state_str, + .cq_ex_to_cq = mlx5_glue_cq_ex_to_cq, + .dr_create_flow_action_dest_flow_tbl = + mlx5_glue_dr_create_flow_action_dest_flow_tbl, + .dr_create_flow_action_dest_port = + mlx5_glue_dr_create_flow_action_dest_port, + .dr_create_flow_action_drop = + mlx5_glue_dr_create_flow_action_drop, + .dr_create_flow_action_push_vlan = + mlx5_glue_dr_create_flow_action_push_vlan, + .dr_create_flow_action_pop_vlan = + mlx5_glue_dr_create_flow_action_pop_vlan, + .dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl, + .dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl, + .dr_create_domain = mlx5_glue_dr_create_domain, + .dr_destroy_domain = mlx5_glue_dr_destroy_domain, + .dv_create_cq = mlx5_glue_dv_create_cq, + .dv_create_wq = mlx5_glue_dv_create_wq, + .dv_query_device = mlx5_glue_dv_query_device, + .dv_set_context_attr = mlx5_glue_dv_set_context_attr, + .dv_init_obj = mlx5_glue_dv_init_obj, + .dv_create_qp = mlx5_glue_dv_create_qp, + .dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher, + .dv_create_flow = mlx5_glue_dv_create_flow, + .dv_create_flow_action_counter = + mlx5_glue_dv_create_flow_action_counter, + .dv_create_flow_action_dest_ibv_qp = + mlx5_glue_dv_create_flow_action_dest_ibv_qp, + .dv_create_flow_action_dest_devx_tir = + mlx5_glue_dv_create_flow_action_dest_devx_tir, + .dv_create_flow_action_modify_header = + mlx5_glue_dv_create_flow_action_modify_header, + .dv_create_flow_action_packet_reformat = + mlx5_glue_dv_create_flow_action_packet_reformat, + .dv_create_flow_action_tag = mlx5_glue_dv_create_flow_action_tag, + .dv_create_flow_action_meter = mlx5_glue_dv_create_flow_action_meter, + .dv_modify_flow_action_meter = mlx5_glue_dv_modify_flow_action_meter, + .dv_destroy_flow = mlx5_glue_dv_destroy_flow, + .dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher, + .dv_open_device = mlx5_glue_dv_open_device, + .devx_obj_create = mlx5_glue_devx_obj_create, + .devx_obj_destroy = mlx5_glue_devx_obj_destroy, + .devx_obj_query = mlx5_glue_devx_obj_query, + .devx_obj_modify = mlx5_glue_devx_obj_modify, + .devx_general_cmd = mlx5_glue_devx_general_cmd, + .devx_create_cmd_comp = mlx5_glue_devx_create_cmd_comp, + .devx_destroy_cmd_comp = mlx5_glue_devx_destroy_cmd_comp, + .devx_obj_query_async = mlx5_glue_devx_obj_query_async, + .devx_get_async_cmd_comp = mlx5_glue_devx_get_async_cmd_comp, + .devx_umem_reg = mlx5_glue_devx_umem_reg, + .devx_umem_dereg = mlx5_glue_devx_umem_dereg, + .devx_qp_query = mlx5_glue_devx_qp_query, + .devx_port_query = mlx5_glue_devx_port_query, + .dr_dump_domain = mlx5_glue_dr_dump_domain, +}; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h new file mode 100644 index 0000000..f4c3180 --- /dev/null +++ b/drivers/common/mlx5/mlx5_glue.h @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#ifndef MLX5_GLUE_H_ +#define MLX5_GLUE_H_ + +#include +#include +/* Verbs headers do not support -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include + +#include "mlx5_autoconf.h" + +#ifndef MLX5_GLUE_VERSION +#define MLX5_GLUE_VERSION "" +#endif + +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 +struct ibv_counter_set; +struct ibv_counter_set_data; +struct ibv_counter_set_description; +struct ibv_counter_set_init_attr; +struct ibv_query_counter_set_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 +struct ibv_counters; +struct ibv_counters_init_attr; +struct ibv_counter_attach_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_TUNNEL_SUPPORT +struct mlx5dv_qp_init_attr; +#endif + +#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT +struct mlx5dv_wq_init_attr; +#endif + +#ifndef HAVE_IBV_FLOW_DV_SUPPORT +struct mlx5dv_flow_matcher; +struct mlx5dv_flow_matcher_attr; +struct mlx5dv_flow_action_attr; +struct mlx5dv_flow_match_parameters; +struct mlx5dv_dr_flow_meter_attr; +struct ibv_flow_action; +enum mlx5dv_flow_action_packet_reformat_type { packet_reformat_type = 0, }; +enum mlx5dv_flow_table_type { flow_table_type = 0, }; +#endif + +#ifndef HAVE_IBV_FLOW_DEVX_COUNTERS +#define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0 +#endif + +#ifndef HAVE_IBV_DEVX_OBJ +struct mlx5dv_devx_obj; +struct mlx5dv_devx_umem { uint32_t umem_id; }; +#endif + +#ifndef HAVE_IBV_DEVX_ASYNC +struct mlx5dv_devx_cmd_comp; +struct mlx5dv_devx_async_cmd_hdr; +#endif + +#ifndef HAVE_MLX5DV_DR +enum mlx5dv_dr_domain_type { unused, }; +struct mlx5dv_dr_domain; +#endif + +#ifndef HAVE_MLX5DV_DR_DEVX_PORT +struct mlx5dv_devx_port; +#endif + +#ifndef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER +struct mlx5dv_dr_flow_meter_attr; +#endif + +/* LIB_GLUE_VERSION must be updated every time this structure is modified. */ +struct mlx5_glue { + const char *version; + int (*fork_init)(void); + struct ibv_pd *(*alloc_pd)(struct ibv_context *context); + int (*dealloc_pd)(struct ibv_pd *pd); + struct ibv_device **(*get_device_list)(int *num_devices); + void (*free_device_list)(struct ibv_device **list); + struct ibv_context *(*open_device)(struct ibv_device *device); + int (*close_device)(struct ibv_context *context); + int (*query_device)(struct ibv_context *context, + struct ibv_device_attr *device_attr); + int (*query_device_ex)(struct ibv_context *context, + const struct ibv_query_device_ex_input *input, + struct ibv_device_attr_ex *attr); + int (*query_rt_values_ex)(struct ibv_context *context, + struct ibv_values_ex *values); + int (*query_port)(struct ibv_context *context, uint8_t port_num, + struct ibv_port_attr *port_attr); + struct ibv_comp_channel *(*create_comp_channel) + (struct ibv_context *context); + int (*destroy_comp_channel)(struct ibv_comp_channel *channel); + struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, + void *cq_context, + struct ibv_comp_channel *channel, + int comp_vector); + int (*destroy_cq)(struct ibv_cq *cq); + int (*get_cq_event)(struct ibv_comp_channel *channel, + struct ibv_cq **cq, void **cq_context); + void (*ack_cq_events)(struct ibv_cq *cq, unsigned int nevents); + struct ibv_rwq_ind_table *(*create_rwq_ind_table) + (struct ibv_context *context, + struct ibv_rwq_ind_table_init_attr *init_attr); + int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); + struct ibv_wq *(*create_wq)(struct ibv_context *context, + struct ibv_wq_init_attr *wq_init_attr); + int (*destroy_wq)(struct ibv_wq *wq); + int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); + struct ibv_flow *(*create_flow)(struct ibv_qp *qp, + struct ibv_flow_attr *flow); + int (*destroy_flow)(struct ibv_flow *flow_id); + int (*destroy_flow_action)(void *action); + struct ibv_qp *(*create_qp)(struct ibv_pd *pd, + struct ibv_qp_init_attr *qp_init_attr); + struct ibv_qp *(*create_qp_ex) + (struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex); + int (*destroy_qp)(struct ibv_qp *qp); + int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, + int attr_mask); + struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, + size_t length, int access); + int (*dereg_mr)(struct ibv_mr *mr); + struct ibv_counter_set *(*create_counter_set) + (struct ibv_context *context, + struct ibv_counter_set_init_attr *init_attr); + int (*destroy_counter_set)(struct ibv_counter_set *cs); + int (*describe_counter_set) + (struct ibv_context *context, + uint16_t counter_set_id, + struct ibv_counter_set_description *cs_desc); + int (*query_counter_set)(struct ibv_query_counter_set_attr *query_attr, + struct ibv_counter_set_data *cs_data); + struct ibv_counters *(*create_counters) + (struct ibv_context *context, + struct ibv_counters_init_attr *init_attr); + int (*destroy_counters)(struct ibv_counters *counters); + int (*attach_counters)(struct ibv_counters *counters, + struct ibv_counter_attach_attr *attr, + struct ibv_flow *flow); + int (*query_counters)(struct ibv_counters *counters, + uint64_t *counters_value, + uint32_t ncounters, + uint32_t flags); + void (*ack_async_event)(struct ibv_async_event *event); + int (*get_async_event)(struct ibv_context *context, + struct ibv_async_event *event); + const char *(*port_state_str)(enum ibv_port_state port_state); + struct ibv_cq *(*cq_ex_to_cq)(struct ibv_cq_ex *cq); + void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); + void *(*dr_create_flow_action_dest_port)(void *domain, + uint32_t port); + void *(*dr_create_flow_action_drop)(); + void *(*dr_create_flow_action_push_vlan) + (struct mlx5dv_dr_domain *domain, + rte_be32_t vlan_tag); + void *(*dr_create_flow_action_pop_vlan)(); + void *(*dr_create_flow_tbl)(void *domain, uint32_t level); + int (*dr_destroy_flow_tbl)(void *tbl); + void *(*dr_create_domain)(struct ibv_context *ctx, + enum mlx5dv_dr_domain_type domain); + int (*dr_destroy_domain)(void *domain); + struct ibv_cq_ex *(*dv_create_cq) + (struct ibv_context *context, + struct ibv_cq_init_attr_ex *cq_attr, + struct mlx5dv_cq_init_attr *mlx5_cq_attr); + struct ibv_wq *(*dv_create_wq) + (struct ibv_context *context, + struct ibv_wq_init_attr *wq_attr, + struct mlx5dv_wq_init_attr *mlx5_wq_attr); + int (*dv_query_device)(struct ibv_context *ctx_in, + struct mlx5dv_context *attrs_out); + int (*dv_set_context_attr)(struct ibv_context *ibv_ctx, + enum mlx5dv_set_ctx_attr_type type, + void *attr); + int (*dv_init_obj)(struct mlx5dv_obj *obj, uint64_t obj_type); + struct ibv_qp *(*dv_create_qp) + (struct ibv_context *context, + struct ibv_qp_init_attr_ex *qp_init_attr_ex, + struct mlx5dv_qp_init_attr *dv_qp_init_attr); + void *(*dv_create_flow_matcher) + (struct ibv_context *context, + struct mlx5dv_flow_matcher_attr *matcher_attr, + void *tbl); + void *(*dv_create_flow)(void *matcher, void *match_value, + size_t num_actions, void *actions[]); + void *(*dv_create_flow_action_counter)(void *obj, uint32_t offset); + void *(*dv_create_flow_action_dest_ibv_qp)(void *qp); + void *(*dv_create_flow_action_dest_devx_tir)(void *tir); + void *(*dv_create_flow_action_modify_header) + (struct ibv_context *ctx, enum mlx5dv_flow_table_type ft_type, + void *domain, uint64_t flags, size_t actions_sz, + uint64_t actions[]); + void *(*dv_create_flow_action_packet_reformat) + (struct ibv_context *ctx, + enum mlx5dv_flow_action_packet_reformat_type reformat_type, + enum mlx5dv_flow_table_type ft_type, + struct mlx5dv_dr_domain *domain, + uint32_t flags, size_t data_sz, void *data); + void *(*dv_create_flow_action_tag)(uint32_t tag); + void *(*dv_create_flow_action_meter) + (struct mlx5dv_dr_flow_meter_attr *attr); + int (*dv_modify_flow_action_meter)(void *action, + struct mlx5dv_dr_flow_meter_attr *attr, uint64_t modify_bits); + int (*dv_destroy_flow)(void *flow); + int (*dv_destroy_flow_matcher)(void *matcher); + struct ibv_context *(*dv_open_device)(struct ibv_device *device); + struct mlx5dv_devx_obj *(*devx_obj_create) + (struct ibv_context *ctx, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_obj_destroy)(struct mlx5dv_devx_obj *obj); + int (*devx_obj_query)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_obj_modify)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_general_cmd)(struct ibv_context *context, + const void *in, size_t inlen, + void *out, size_t outlen); + struct mlx5dv_devx_cmd_comp *(*devx_create_cmd_comp) + (struct ibv_context *context); + void (*devx_destroy_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp); + int (*devx_obj_query_async)(struct mlx5dv_devx_obj *obj, + const void *in, size_t inlen, + size_t outlen, uint64_t wr_id, + struct mlx5dv_devx_cmd_comp *cmd_comp); + int (*devx_get_async_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp, + struct mlx5dv_devx_async_cmd_hdr *resp, + size_t cmd_resp_len); + struct mlx5dv_devx_umem *(*devx_umem_reg)(struct ibv_context *context, + void *addr, size_t size, + uint32_t access); + int (*devx_umem_dereg)(struct mlx5dv_devx_umem *dv_devx_umem); + int (*devx_qp_query)(struct ibv_qp *qp, + const void *in, size_t inlen, + void *out, size_t outlen); + int (*devx_port_query)(struct ibv_context *ctx, + uint32_t port_num, + struct mlx5dv_devx_port *mlx5_devx_port); + int (*dr_dump_domain)(FILE *file, void *domain); +}; + +const struct mlx5_glue *mlx5_glue; + +#endif /* MLX5_GLUE_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h new file mode 100644 index 0000000..5730ad1 --- /dev/null +++ b/drivers/common/mlx5/mlx5_prm.h @@ -0,0 +1,1889 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2016 6WIND S.A. + * Copyright 2016 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_PRM_H_ +#define RTE_PMD_MLX5_PRM_H_ + +#include +/* Verbs header. */ +/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +#include +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +#include +#include + +#include "mlx5_autoconf.h" + +/* RSS hash key size. */ +#define MLX5_RSS_HASH_KEY_LEN 40 + +/* Get CQE owner bit. */ +#define MLX5_CQE_OWNER(op_own) ((op_own) & MLX5_CQE_OWNER_MASK) + +/* Get CQE format. */ +#define MLX5_CQE_FORMAT(op_own) (((op_own) & MLX5E_CQE_FORMAT_MASK) >> 2) + +/* Get CQE opcode. */ +#define MLX5_CQE_OPCODE(op_own) (((op_own) & 0xf0) >> 4) + +/* Get CQE solicited event. */ +#define MLX5_CQE_SE(op_own) (((op_own) >> 1) & 1) + +/* Invalidate a CQE. */ +#define MLX5_CQE_INVALIDATE (MLX5_CQE_INVALID << 4) + +/* WQE Segment sizes in bytes. */ +#define MLX5_WSEG_SIZE 16u +#define MLX5_WQE_CSEG_SIZE sizeof(struct mlx5_wqe_cseg) +#define MLX5_WQE_DSEG_SIZE sizeof(struct mlx5_wqe_dseg) +#define MLX5_WQE_ESEG_SIZE sizeof(struct mlx5_wqe_eseg) + +/* WQE/WQEBB size in bytes. */ +#define MLX5_WQE_SIZE sizeof(struct mlx5_wqe) + +/* + * Max size of a WQE session. + * Absolute maximum size is 63 (MLX5_DSEG_MAX) segments, + * the WQE size field in Control Segment is 6 bits wide. + */ +#define MLX5_WQE_SIZE_MAX (60 * MLX5_WSEG_SIZE) + +/* + * Default minimum number of Tx queues for inlining packets. + * If there are less queues as specified we assume we have + * no enough CPU resources (cycles) to perform inlining, + * the PCIe throughput is not supposed as bottleneck and + * inlining is disabled. + */ +#define MLX5_INLINE_MAX_TXQS 8u +#define MLX5_INLINE_MAX_TXQS_BLUEFIELD 16u + +/* + * Default packet length threshold to be inlined with + * enhanced MPW. If packet length exceeds the threshold + * the data are not inlined. Should be aligned in WQEBB + * boundary with accounting the title Control and Ethernet + * segments. + */ +#define MLX5_EMPW_DEF_INLINE_LEN (4u * MLX5_WQE_SIZE + \ + MLX5_DSEG_MIN_INLINE_SIZE) +/* + * Maximal inline data length sent with enhanced MPW. + * Is based on maximal WQE size. + */ +#define MLX5_EMPW_MAX_INLINE_LEN (MLX5_WQE_SIZE_MAX - \ + MLX5_WQE_CSEG_SIZE - \ + MLX5_WQE_ESEG_SIZE - \ + MLX5_WQE_DSEG_SIZE + \ + MLX5_DSEG_MIN_INLINE_SIZE) +/* + * Minimal amount of packets to be sent with EMPW. + * This limits the minimal required size of sent EMPW. + * If there are no enough resources to built minimal + * EMPW the sending loop exits. + */ +#define MLX5_EMPW_MIN_PACKETS (2u + 3u * 4u) +/* + * Maximal amount of packets to be sent with EMPW. + * This value is not recommended to exceed MLX5_TX_COMP_THRESH, + * otherwise there might be up to MLX5_EMPW_MAX_PACKETS mbufs + * without CQE generation request, being multiplied by + * MLX5_TX_COMP_MAX_CQE it may cause significant latency + * in tx burst routine at the moment of freeing multiple mbufs. + */ +#define MLX5_EMPW_MAX_PACKETS MLX5_TX_COMP_THRESH +#define MLX5_MPW_MAX_PACKETS 6 +#define MLX5_MPW_INLINE_MAX_PACKETS 2 + +/* + * Default packet length threshold to be inlined with + * ordinary SEND. Inlining saves the MR key search + * and extra PCIe data fetch transaction, but eats the + * CPU cycles. + */ +#define MLX5_SEND_DEF_INLINE_LEN (5U * MLX5_WQE_SIZE + \ + MLX5_ESEG_MIN_INLINE_SIZE - \ + MLX5_WQE_CSEG_SIZE - \ + MLX5_WQE_ESEG_SIZE - \ + MLX5_WQE_DSEG_SIZE) +/* + * Maximal inline data length sent with ordinary SEND. + * Is based on maximal WQE size. + */ +#define MLX5_SEND_MAX_INLINE_LEN (MLX5_WQE_SIZE_MAX - \ + MLX5_WQE_CSEG_SIZE - \ + MLX5_WQE_ESEG_SIZE - \ + MLX5_WQE_DSEG_SIZE + \ + MLX5_ESEG_MIN_INLINE_SIZE) + +/* Missed in mlv5dv.h, should define here. */ +#define MLX5_OPCODE_ENHANCED_MPSW 0x29u + +/* CQE value to inform that VLAN is stripped. */ +#define MLX5_CQE_VLAN_STRIPPED (1u << 0) + +/* IPv4 options. */ +#define MLX5_CQE_RX_IP_EXT_OPTS_PACKET (1u << 1) + +/* IPv6 packet. */ +#define MLX5_CQE_RX_IPV6_PACKET (1u << 2) + +/* IPv4 packet. */ +#define MLX5_CQE_RX_IPV4_PACKET (1u << 3) + +/* TCP packet. */ +#define MLX5_CQE_RX_TCP_PACKET (1u << 4) + +/* UDP packet. */ +#define MLX5_CQE_RX_UDP_PACKET (1u << 5) + +/* IP is fragmented. */ +#define MLX5_CQE_RX_IP_FRAG_PACKET (1u << 7) + +/* L2 header is valid. */ +#define MLX5_CQE_RX_L2_HDR_VALID (1u << 8) + +/* L3 header is valid. */ +#define MLX5_CQE_RX_L3_HDR_VALID (1u << 9) + +/* L4 header is valid. */ +#define MLX5_CQE_RX_L4_HDR_VALID (1u << 10) + +/* Outer packet, 0 IPv4, 1 IPv6. */ +#define MLX5_CQE_RX_OUTER_PACKET (1u << 1) + +/* Tunnel packet bit in the CQE. */ +#define MLX5_CQE_RX_TUNNEL_PACKET (1u << 0) + +/* Mask for LRO push flag in the CQE lro_tcppsh_abort_dupack field. */ +#define MLX5_CQE_LRO_PUSH_MASK 0x40 + +/* Mask for L4 type in the CQE hdr_type_etc field. */ +#define MLX5_CQE_L4_TYPE_MASK 0x70 + +/* The bit index of L4 type in CQE hdr_type_etc field. */ +#define MLX5_CQE_L4_TYPE_SHIFT 0x4 + +/* L4 type to indicate TCP packet without acknowledgment. */ +#define MLX5_L4_HDR_TYPE_TCP_EMPTY_ACK 0x3 + +/* L4 type to indicate TCP packet with acknowledgment. */ +#define MLX5_L4_HDR_TYPE_TCP_WITH_ACL 0x4 + +/* Inner L3 checksum offload (Tunneled packets only). */ +#define MLX5_ETH_WQE_L3_INNER_CSUM (1u << 4) + +/* Inner L4 checksum offload (Tunneled packets only). */ +#define MLX5_ETH_WQE_L4_INNER_CSUM (1u << 5) + +/* Outer L4 type is TCP. */ +#define MLX5_ETH_WQE_L4_OUTER_TCP (0u << 5) + +/* Outer L4 type is UDP. */ +#define MLX5_ETH_WQE_L4_OUTER_UDP (1u << 5) + +/* Outer L3 type is IPV4. */ +#define MLX5_ETH_WQE_L3_OUTER_IPV4 (0u << 4) + +/* Outer L3 type is IPV6. */ +#define MLX5_ETH_WQE_L3_OUTER_IPV6 (1u << 4) + +/* Inner L4 type is TCP. */ +#define MLX5_ETH_WQE_L4_INNER_TCP (0u << 1) + +/* Inner L4 type is UDP. */ +#define MLX5_ETH_WQE_L4_INNER_UDP (1u << 1) + +/* Inner L3 type is IPV4. */ +#define MLX5_ETH_WQE_L3_INNER_IPV4 (0u << 0) + +/* Inner L3 type is IPV6. */ +#define MLX5_ETH_WQE_L3_INNER_IPV6 (1u << 0) + +/* VLAN insertion flag. */ +#define MLX5_ETH_WQE_VLAN_INSERT (1u << 31) + +/* Data inline segment flag. */ +#define MLX5_ETH_WQE_DATA_INLINE (1u << 31) + +/* Is flow mark valid. */ +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN +#define MLX5_FLOW_MARK_IS_VALID(val) ((val) & 0xffffff00) +#else +#define MLX5_FLOW_MARK_IS_VALID(val) ((val) & 0xffffff) +#endif + +/* INVALID is used by packets matching no flow rules. */ +#define MLX5_FLOW_MARK_INVALID 0 + +/* Maximum allowed value to mark a packet. */ +#define MLX5_FLOW_MARK_MAX 0xfffff0 + +/* Default mark value used when none is provided. */ +#define MLX5_FLOW_MARK_DEFAULT 0xffffff + +/* Default mark mask for metadata legacy mode. */ +#define MLX5_FLOW_MARK_MASK 0xffffff + +/* Maximum number of DS in WQE. Limited by 6-bit field. */ +#define MLX5_DSEG_MAX 63 + +/* The completion mode offset in the WQE control segment line 2. */ +#define MLX5_COMP_MODE_OFFSET 2 + +/* Amount of data bytes in minimal inline data segment. */ +#define MLX5_DSEG_MIN_INLINE_SIZE 12u + +/* Amount of data bytes in minimal inline eth segment. */ +#define MLX5_ESEG_MIN_INLINE_SIZE 18u + +/* Amount of data bytes after eth data segment. */ +#define MLX5_ESEG_EXTRA_DATA_SIZE 32u + +/* The maximum log value of segments per RQ WQE. */ +#define MLX5_MAX_LOG_RQ_SEGS 5u + +/* The alignment needed for WQ buffer. */ +#define MLX5_WQE_BUF_ALIGNMENT 512 + +/* Completion mode. */ +enum mlx5_completion_mode { + MLX5_COMP_ONLY_ERR = 0x0, + MLX5_COMP_ONLY_FIRST_ERR = 0x1, + MLX5_COMP_ALWAYS = 0x2, + MLX5_COMP_CQE_AND_EQE = 0x3, +}; + +/* MPW mode. */ +enum mlx5_mpw_mode { + MLX5_MPW_DISABLED, + MLX5_MPW, + MLX5_MPW_ENHANCED, /* Enhanced Multi-Packet Send WQE, a.k.a MPWv2. */ +}; + +/* WQE Control segment. */ +struct mlx5_wqe_cseg { + uint32_t opcode; + uint32_t sq_ds; + uint32_t flags; + uint32_t misc; +} __rte_packed __rte_aligned(MLX5_WSEG_SIZE); + +/* Header of data segment. Minimal size Data Segment */ +struct mlx5_wqe_dseg { + uint32_t bcount; + union { + uint8_t inline_data[MLX5_DSEG_MIN_INLINE_SIZE]; + struct { + uint32_t lkey; + uint64_t pbuf; + } __rte_packed; + }; +} __rte_packed; + +/* Subset of struct WQE Ethernet Segment. */ +struct mlx5_wqe_eseg { + union { + struct { + uint32_t swp_offs; + uint8_t cs_flags; + uint8_t swp_flags; + uint16_t mss; + uint32_t metadata; + uint16_t inline_hdr_sz; + union { + uint16_t inline_data; + uint16_t vlan_tag; + }; + } __rte_packed; + struct { + uint32_t offsets; + uint32_t flags; + uint32_t flow_metadata; + uint32_t inline_hdr; + } __rte_packed; + }; +} __rte_packed; + +/* The title WQEBB, header of WQE. */ +struct mlx5_wqe { + union { + struct mlx5_wqe_cseg cseg; + uint32_t ctrl[4]; + }; + struct mlx5_wqe_eseg eseg; + union { + struct mlx5_wqe_dseg dseg[2]; + uint8_t data[MLX5_ESEG_EXTRA_DATA_SIZE]; + }; +} __rte_packed; + +/* WQE for Multi-Packet RQ. */ +struct mlx5_wqe_mprq { + struct mlx5_wqe_srq_next_seg next_seg; + struct mlx5_wqe_data_seg dseg; +}; + +#define MLX5_MPRQ_LEN_MASK 0x000ffff +#define MLX5_MPRQ_LEN_SHIFT 0 +#define MLX5_MPRQ_STRIDE_NUM_MASK 0x3fff0000 +#define MLX5_MPRQ_STRIDE_NUM_SHIFT 16 +#define MLX5_MPRQ_FILLER_MASK 0x80000000 +#define MLX5_MPRQ_FILLER_SHIFT 31 + +#define MLX5_MPRQ_STRIDE_SHIFT_BYTE 2 + +/* CQ element structure - should be equal to the cache line size */ +struct mlx5_cqe { +#if (RTE_CACHE_LINE_SIZE == 128) + uint8_t padding[64]; +#endif + uint8_t pkt_info; + uint8_t rsvd0; + uint16_t wqe_id; + uint8_t lro_tcppsh_abort_dupack; + uint8_t lro_min_ttl; + uint16_t lro_tcp_win; + uint32_t lro_ack_seq_num; + uint32_t rx_hash_res; + uint8_t rx_hash_type; + uint8_t rsvd1[3]; + uint16_t csum; + uint8_t rsvd2[6]; + uint16_t hdr_type_etc; + uint16_t vlan_info; + uint8_t lro_num_seg; + uint8_t rsvd3[3]; + uint32_t flow_table_metadata; + uint8_t rsvd4[4]; + uint32_t byte_cnt; + uint64_t timestamp; + uint32_t sop_drop_qpn; + uint16_t wqe_counter; + uint8_t rsvd5; + 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 + +/* Action type of header modification. */ +enum { + MLX5_MODIFICATION_TYPE_SET = 0x1, + MLX5_MODIFICATION_TYPE_ADD = 0x2, + MLX5_MODIFICATION_TYPE_COPY = 0x3, +}; + +/* The field of packet to be modified. */ +enum mlx5_modification_field { + MLX5_MODI_OUT_NONE = -1, + MLX5_MODI_OUT_SMAC_47_16 = 1, + MLX5_MODI_OUT_SMAC_15_0, + MLX5_MODI_OUT_ETHERTYPE, + MLX5_MODI_OUT_DMAC_47_16, + MLX5_MODI_OUT_DMAC_15_0, + MLX5_MODI_OUT_IP_DSCP, + MLX5_MODI_OUT_TCP_FLAGS, + MLX5_MODI_OUT_TCP_SPORT, + MLX5_MODI_OUT_TCP_DPORT, + MLX5_MODI_OUT_IPV4_TTL, + MLX5_MODI_OUT_UDP_SPORT, + MLX5_MODI_OUT_UDP_DPORT, + MLX5_MODI_OUT_SIPV6_127_96, + MLX5_MODI_OUT_SIPV6_95_64, + MLX5_MODI_OUT_SIPV6_63_32, + MLX5_MODI_OUT_SIPV6_31_0, + MLX5_MODI_OUT_DIPV6_127_96, + MLX5_MODI_OUT_DIPV6_95_64, + MLX5_MODI_OUT_DIPV6_63_32, + MLX5_MODI_OUT_DIPV6_31_0, + MLX5_MODI_OUT_SIPV4, + MLX5_MODI_OUT_DIPV4, + MLX5_MODI_OUT_FIRST_VID, + MLX5_MODI_IN_SMAC_47_16 = 0x31, + MLX5_MODI_IN_SMAC_15_0, + MLX5_MODI_IN_ETHERTYPE, + MLX5_MODI_IN_DMAC_47_16, + MLX5_MODI_IN_DMAC_15_0, + MLX5_MODI_IN_IP_DSCP, + MLX5_MODI_IN_TCP_FLAGS, + MLX5_MODI_IN_TCP_SPORT, + MLX5_MODI_IN_TCP_DPORT, + MLX5_MODI_IN_IPV4_TTL, + MLX5_MODI_IN_UDP_SPORT, + MLX5_MODI_IN_UDP_DPORT, + MLX5_MODI_IN_SIPV6_127_96, + MLX5_MODI_IN_SIPV6_95_64, + MLX5_MODI_IN_SIPV6_63_32, + MLX5_MODI_IN_SIPV6_31_0, + MLX5_MODI_IN_DIPV6_127_96, + MLX5_MODI_IN_DIPV6_95_64, + MLX5_MODI_IN_DIPV6_63_32, + MLX5_MODI_IN_DIPV6_31_0, + MLX5_MODI_IN_SIPV4, + MLX5_MODI_IN_DIPV4, + MLX5_MODI_OUT_IPV6_HOPLIMIT, + MLX5_MODI_IN_IPV6_HOPLIMIT, + MLX5_MODI_META_DATA_REG_A, + MLX5_MODI_META_DATA_REG_B = 0x50, + MLX5_MODI_META_REG_C_0, + MLX5_MODI_META_REG_C_1, + MLX5_MODI_META_REG_C_2, + MLX5_MODI_META_REG_C_3, + MLX5_MODI_META_REG_C_4, + MLX5_MODI_META_REG_C_5, + MLX5_MODI_META_REG_C_6, + MLX5_MODI_META_REG_C_7, + MLX5_MODI_OUT_TCP_SEQ_NUM, + MLX5_MODI_IN_TCP_SEQ_NUM, + MLX5_MODI_OUT_TCP_ACK_NUM, + MLX5_MODI_IN_TCP_ACK_NUM = 0x5C, +}; + +/* Total number of metadata reg_c's. */ +#define MLX5_MREG_C_NUM (MLX5_MODI_META_REG_C_7 - MLX5_MODI_META_REG_C_0 + 1) + +enum modify_reg { + REG_NONE = 0, + REG_A, + REG_B, + REG_C_0, + REG_C_1, + REG_C_2, + REG_C_3, + REG_C_4, + REG_C_5, + REG_C_6, + REG_C_7, +}; + +/* Modification sub command. */ +struct mlx5_modification_cmd { + union { + uint32_t data0; + struct { + unsigned int length:5; + unsigned int rsvd0:3; + unsigned int offset:5; + unsigned int rsvd1:3; + unsigned int field:12; + unsigned int action_type:4; + }; + }; + union { + uint32_t data1; + uint8_t data[4]; + struct { + unsigned int rsvd2:8; + unsigned int dst_offset:5; + unsigned int rsvd3:3; + unsigned int dst_field:12; + unsigned int rsvd4:4; + }; + }; +}; + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) +#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld) +#define __mlx5_bit_off(typ, fld) ((unsigned int)(unsigned long) \ + (&(__mlx5_nullp(typ)->fld))) +#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - \ + (__mlx5_bit_off(typ, fld) & 0x1f)) +#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32) +#define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64) +#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << \ + __mlx5_dw_bit_off(typ, fld)) +#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1)) +#define __mlx5_16_off(typ, fld) (__mlx5_bit_off(typ, fld) / 16) +#define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - \ + (__mlx5_bit_off(typ, fld) & 0xf)) +#define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1)) +#define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8) +#define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32) +#define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8) +#define MLX5_ADDR_OF(typ, p, fld) ((char *)(p) + MLX5_BYTE_OFF(typ, fld)) + +/* insert a value to a struct */ +#define MLX5_SET(typ, p, fld, v) \ + do { \ + u32 _v = v; \ + *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \ + rte_cpu_to_be_32((rte_be_to_cpu_32(*((u32 *)(p) + \ + __mlx5_dw_off(typ, fld))) & \ + (~__mlx5_dw_mask(typ, fld))) | \ + (((_v) & __mlx5_mask(typ, fld)) << \ + __mlx5_dw_bit_off(typ, fld))); \ + } while (0) + +#define MLX5_SET64(typ, p, fld, v) \ + do { \ + assert(__mlx5_bit_sz(typ, fld) == 64); \ + *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = \ + rte_cpu_to_be_64(v); \ + } while (0) + +#define MLX5_GET(typ, p, fld) \ + ((rte_be_to_cpu_32(*((__be32 *)(p) +\ + __mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \ + __mlx5_mask(typ, fld)) +#define MLX5_GET16(typ, p, fld) \ + ((rte_be_to_cpu_16(*((__be16 *)(p) + \ + __mlx5_16_off(typ, fld))) >> __mlx5_16_bit_off(typ, fld)) & \ + __mlx5_mask16(typ, fld)) +#define MLX5_GET64(typ, p, fld) rte_be_to_cpu_64(*((__be64 *)(p) + \ + __mlx5_64_off(typ, fld))) +#define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8) + +struct mlx5_ifc_fte_match_set_misc_bits { + u8 gre_c_present[0x1]; + u8 reserved_at_1[0x1]; + u8 gre_k_present[0x1]; + u8 gre_s_present[0x1]; + u8 source_vhci_port[0x4]; + u8 source_sqn[0x18]; + u8 reserved_at_20[0x10]; + u8 source_port[0x10]; + u8 outer_second_prio[0x3]; + u8 outer_second_cfi[0x1]; + u8 outer_second_vid[0xc]; + u8 inner_second_prio[0x3]; + u8 inner_second_cfi[0x1]; + u8 inner_second_vid[0xc]; + u8 outer_second_cvlan_tag[0x1]; + u8 inner_second_cvlan_tag[0x1]; + u8 outer_second_svlan_tag[0x1]; + u8 inner_second_svlan_tag[0x1]; + u8 reserved_at_64[0xc]; + u8 gre_protocol[0x10]; + u8 gre_key_h[0x18]; + u8 gre_key_l[0x8]; + u8 vxlan_vni[0x18]; + u8 reserved_at_b8[0x8]; + u8 geneve_vni[0x18]; + u8 reserved_at_e4[0x7]; + u8 geneve_oam[0x1]; + u8 reserved_at_e0[0xc]; + u8 outer_ipv6_flow_label[0x14]; + u8 reserved_at_100[0xc]; + u8 inner_ipv6_flow_label[0x14]; + u8 reserved_at_120[0xa]; + u8 geneve_opt_len[0x6]; + u8 geneve_protocol_type[0x10]; + u8 reserved_at_140[0xc0]; +}; + +struct mlx5_ifc_ipv4_layout_bits { + u8 reserved_at_0[0x60]; + u8 ipv4[0x20]; +}; + +struct mlx5_ifc_ipv6_layout_bits { + u8 ipv6[16][0x8]; +}; + +union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits { + struct mlx5_ifc_ipv6_layout_bits ipv6_layout; + struct mlx5_ifc_ipv4_layout_bits ipv4_layout; + u8 reserved_at_0[0x80]; +}; + +struct mlx5_ifc_fte_match_set_lyr_2_4_bits { + u8 smac_47_16[0x20]; + u8 smac_15_0[0x10]; + u8 ethertype[0x10]; + u8 dmac_47_16[0x20]; + u8 dmac_15_0[0x10]; + u8 first_prio[0x3]; + u8 first_cfi[0x1]; + u8 first_vid[0xc]; + u8 ip_protocol[0x8]; + u8 ip_dscp[0x6]; + u8 ip_ecn[0x2]; + u8 cvlan_tag[0x1]; + u8 svlan_tag[0x1]; + u8 frag[0x1]; + u8 ip_version[0x4]; + u8 tcp_flags[0x9]; + u8 tcp_sport[0x10]; + u8 tcp_dport[0x10]; + u8 reserved_at_c0[0x20]; + u8 udp_sport[0x10]; + u8 udp_dport[0x10]; + union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits src_ipv4_src_ipv6; + union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits dst_ipv4_dst_ipv6; +}; + +struct mlx5_ifc_fte_match_mpls_bits { + u8 mpls_label[0x14]; + u8 mpls_exp[0x3]; + u8 mpls_s_bos[0x1]; + u8 mpls_ttl[0x8]; +}; + +struct mlx5_ifc_fte_match_set_misc2_bits { + struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls; + struct mlx5_ifc_fte_match_mpls_bits inner_first_mpls; + struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls_over_gre; + struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls_over_udp; + u8 metadata_reg_c_7[0x20]; + u8 metadata_reg_c_6[0x20]; + u8 metadata_reg_c_5[0x20]; + u8 metadata_reg_c_4[0x20]; + u8 metadata_reg_c_3[0x20]; + u8 metadata_reg_c_2[0x20]; + u8 metadata_reg_c_1[0x20]; + u8 metadata_reg_c_0[0x20]; + u8 metadata_reg_a[0x20]; + u8 metadata_reg_b[0x20]; + u8 reserved_at_1c0[0x40]; +}; + +struct mlx5_ifc_fte_match_set_misc3_bits { + u8 inner_tcp_seq_num[0x20]; + u8 outer_tcp_seq_num[0x20]; + u8 inner_tcp_ack_num[0x20]; + u8 outer_tcp_ack_num[0x20]; + u8 reserved_at_auto1[0x8]; + u8 outer_vxlan_gpe_vni[0x18]; + u8 outer_vxlan_gpe_next_protocol[0x8]; + u8 outer_vxlan_gpe_flags[0x8]; + u8 reserved_at_a8[0x10]; + u8 icmp_header_data[0x20]; + u8 icmpv6_header_data[0x20]; + u8 icmp_type[0x8]; + u8 icmp_code[0x8]; + u8 icmpv6_type[0x8]; + u8 icmpv6_code[0x8]; + u8 reserved_at_120[0x20]; + u8 gtpu_teid[0x20]; + u8 gtpu_msg_type[0x08]; + u8 gtpu_msg_flags[0x08]; + u8 reserved_at_170[0x90]; +}; + +/* Flow matcher. */ +struct mlx5_ifc_fte_match_param_bits { + struct mlx5_ifc_fte_match_set_lyr_2_4_bits outer_headers; + struct mlx5_ifc_fte_match_set_misc_bits misc_parameters; + struct mlx5_ifc_fte_match_set_lyr_2_4_bits inner_headers; + struct mlx5_ifc_fte_match_set_misc2_bits misc_parameters_2; + struct mlx5_ifc_fte_match_set_misc3_bits misc_parameters_3; +}; + +enum { + MLX5_MATCH_CRITERIA_ENABLE_OUTER_BIT, + MLX5_MATCH_CRITERIA_ENABLE_MISC_BIT, + MLX5_MATCH_CRITERIA_ENABLE_INNER_BIT, + MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT, + MLX5_MATCH_CRITERIA_ENABLE_MISC3_BIT +}; + +enum { + MLX5_CMD_OP_QUERY_HCA_CAP = 0x100, + MLX5_CMD_OP_CREATE_MKEY = 0x200, + MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754, + MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN = 0x816, + MLX5_CMD_OP_CREATE_TIR = 0x900, + MLX5_CMD_OP_CREATE_SQ = 0X904, + MLX5_CMD_OP_MODIFY_SQ = 0X905, + MLX5_CMD_OP_CREATE_RQ = 0x908, + MLX5_CMD_OP_MODIFY_RQ = 0x909, + MLX5_CMD_OP_CREATE_TIS = 0x912, + MLX5_CMD_OP_QUERY_TIS = 0x915, + MLX5_CMD_OP_CREATE_RQT = 0x916, + MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939, + MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b, +}; + +enum { + MLX5_MKC_ACCESS_MODE_MTT = 0x1, +}; + +/* Flow counters. */ +struct mlx5_ifc_alloc_flow_counter_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 flow_counter_id[0x20]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_alloc_flow_counter_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 flow_counter_id[0x20]; + u8 reserved_at_40[0x18]; + u8 flow_counter_bulk[0x8]; +}; + +struct mlx5_ifc_dealloc_flow_counter_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_dealloc_flow_counter_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 flow_counter_id[0x20]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_traffic_counter_bits { + u8 packets[0x40]; + u8 octets[0x40]; +}; + +struct mlx5_ifc_query_flow_counter_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; + struct mlx5_ifc_traffic_counter_bits flow_statistics[]; +}; + +struct mlx5_ifc_query_flow_counter_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x20]; + u8 mkey[0x20]; + u8 address[0x40]; + u8 clear[0x1]; + u8 dump_to_memory[0x1]; + u8 num_of_counters[0x1e]; + u8 flow_counter_id[0x20]; +}; + +struct mlx5_ifc_mkc_bits { + u8 reserved_at_0[0x1]; + u8 free[0x1]; + u8 reserved_at_2[0x1]; + u8 access_mode_4_2[0x3]; + u8 reserved_at_6[0x7]; + u8 relaxed_ordering_write[0x1]; + u8 reserved_at_e[0x1]; + u8 small_fence_on_rdma_read_response[0x1]; + u8 umr_en[0x1]; + u8 a[0x1]; + u8 rw[0x1]; + u8 rr[0x1]; + u8 lw[0x1]; + u8 lr[0x1]; + u8 access_mode_1_0[0x2]; + u8 reserved_at_18[0x8]; + + u8 qpn[0x18]; + u8 mkey_7_0[0x8]; + + u8 reserved_at_40[0x20]; + + u8 length64[0x1]; + u8 bsf_en[0x1]; + u8 sync_umr[0x1]; + u8 reserved_at_63[0x2]; + u8 expected_sigerr_count[0x1]; + u8 reserved_at_66[0x1]; + u8 en_rinval[0x1]; + u8 pd[0x18]; + + u8 start_addr[0x40]; + + u8 len[0x40]; + + u8 bsf_octword_size[0x20]; + + u8 reserved_at_120[0x80]; + + u8 translations_octword_size[0x20]; + + u8 reserved_at_1c0[0x1b]; + u8 log_page_size[0x5]; + + u8 reserved_at_1e0[0x20]; +}; + +struct mlx5_ifc_create_mkey_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + + u8 syndrome[0x20]; + + u8 reserved_at_40[0x8]; + u8 mkey_index[0x18]; + + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_mkey_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + + u8 reserved_at_40[0x20]; + + u8 pg_access[0x1]; + u8 reserved_at_61[0x1f]; + + struct mlx5_ifc_mkc_bits memory_key_mkey_entry; + + u8 reserved_at_280[0x80]; + + u8 translations_octword_actual_size[0x20]; + + u8 mkey_umem_id[0x20]; + + u8 mkey_umem_offset[0x40]; + + u8 reserved_at_380[0x500]; + + u8 klm_pas_mtt[][0x20]; +}; + +enum { + MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0 << 1, + MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS = 0x1 << 1, + MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP = 0xc << 1, +}; + +enum { + MLX5_HCA_CAP_OPMOD_GET_MAX = 0, + MLX5_HCA_CAP_OPMOD_GET_CUR = 1, +}; + +enum { + MLX5_CAP_INLINE_MODE_L2, + MLX5_CAP_INLINE_MODE_VPORT_CONTEXT, + MLX5_CAP_INLINE_MODE_NOT_REQUIRED, +}; + +enum { + MLX5_INLINE_MODE_NONE, + MLX5_INLINE_MODE_L2, + MLX5_INLINE_MODE_IP, + MLX5_INLINE_MODE_TCP_UDP, + MLX5_INLINE_MODE_RESERVED4, + MLX5_INLINE_MODE_INNER_L2, + MLX5_INLINE_MODE_INNER_IP, + MLX5_INLINE_MODE_INNER_TCP_UDP, +}; + +/* HCA bit masks indicating which Flex parser protocols are already enabled. */ +#define MLX5_HCA_FLEX_IPV4_OVER_VXLAN_ENABLED (1UL << 0) +#define MLX5_HCA_FLEX_IPV6_OVER_VXLAN_ENABLED (1UL << 1) +#define MLX5_HCA_FLEX_IPV6_OVER_IP_ENABLED (1UL << 2) +#define MLX5_HCA_FLEX_GENEVE_ENABLED (1UL << 3) +#define MLX5_HCA_FLEX_CW_MPLS_OVER_GRE_ENABLED (1UL << 4) +#define MLX5_HCA_FLEX_CW_MPLS_OVER_UDP_ENABLED (1UL << 5) +#define MLX5_HCA_FLEX_P_BIT_VXLAN_GPE_ENABLED (1UL << 6) +#define MLX5_HCA_FLEX_VXLAN_GPE_ENABLED (1UL << 7) +#define MLX5_HCA_FLEX_ICMP_ENABLED (1UL << 8) +#define MLX5_HCA_FLEX_ICMPV6_ENABLED (1UL << 9) + +struct mlx5_ifc_cmd_hca_cap_bits { + u8 reserved_at_0[0x30]; + u8 vhca_id[0x10]; + u8 reserved_at_40[0x40]; + u8 log_max_srq_sz[0x8]; + u8 log_max_qp_sz[0x8]; + u8 reserved_at_90[0xb]; + u8 log_max_qp[0x5]; + u8 reserved_at_a0[0xb]; + u8 log_max_srq[0x5]; + u8 reserved_at_b0[0x10]; + u8 reserved_at_c0[0x8]; + u8 log_max_cq_sz[0x8]; + u8 reserved_at_d0[0xb]; + u8 log_max_cq[0x5]; + u8 log_max_eq_sz[0x8]; + u8 reserved_at_e8[0x2]; + u8 log_max_mkey[0x6]; + u8 reserved_at_f0[0x8]; + u8 dump_fill_mkey[0x1]; + u8 reserved_at_f9[0x3]; + u8 log_max_eq[0x4]; + u8 max_indirection[0x8]; + u8 fixed_buffer_size[0x1]; + u8 log_max_mrw_sz[0x7]; + u8 force_teardown[0x1]; + u8 reserved_at_111[0x1]; + u8 log_max_bsf_list_size[0x6]; + u8 umr_extended_translation_offset[0x1]; + u8 null_mkey[0x1]; + u8 log_max_klm_list_size[0x6]; + u8 reserved_at_120[0xa]; + u8 log_max_ra_req_dc[0x6]; + u8 reserved_at_130[0xa]; + u8 log_max_ra_res_dc[0x6]; + u8 reserved_at_140[0xa]; + u8 log_max_ra_req_qp[0x6]; + u8 reserved_at_150[0xa]; + u8 log_max_ra_res_qp[0x6]; + u8 end_pad[0x1]; + u8 cc_query_allowed[0x1]; + u8 cc_modify_allowed[0x1]; + u8 start_pad[0x1]; + u8 cache_line_128byte[0x1]; + u8 reserved_at_165[0xa]; + u8 qcam_reg[0x1]; + u8 gid_table_size[0x10]; + u8 out_of_seq_cnt[0x1]; + u8 vport_counters[0x1]; + u8 retransmission_q_counters[0x1]; + u8 debug[0x1]; + u8 modify_rq_counter_set_id[0x1]; + u8 rq_delay_drop[0x1]; + u8 max_qp_cnt[0xa]; + u8 pkey_table_size[0x10]; + u8 vport_group_manager[0x1]; + u8 vhca_group_manager[0x1]; + u8 ib_virt[0x1]; + u8 eth_virt[0x1]; + u8 vnic_env_queue_counters[0x1]; + u8 ets[0x1]; + u8 nic_flow_table[0x1]; + u8 eswitch_manager[0x1]; + u8 device_memory[0x1]; + u8 mcam_reg[0x1]; + u8 pcam_reg[0x1]; + u8 local_ca_ack_delay[0x5]; + u8 port_module_event[0x1]; + u8 enhanced_error_q_counters[0x1]; + u8 ports_check[0x1]; + u8 reserved_at_1b3[0x1]; + u8 disable_link_up[0x1]; + u8 beacon_led[0x1]; + u8 port_type[0x2]; + u8 num_ports[0x8]; + u8 reserved_at_1c0[0x1]; + u8 pps[0x1]; + u8 pps_modify[0x1]; + u8 log_max_msg[0x5]; + u8 reserved_at_1c8[0x4]; + u8 max_tc[0x4]; + u8 temp_warn_event[0x1]; + u8 dcbx[0x1]; + u8 general_notification_event[0x1]; + u8 reserved_at_1d3[0x2]; + u8 fpga[0x1]; + u8 rol_s[0x1]; + u8 rol_g[0x1]; + u8 reserved_at_1d8[0x1]; + u8 wol_s[0x1]; + u8 wol_g[0x1]; + u8 wol_a[0x1]; + u8 wol_b[0x1]; + u8 wol_m[0x1]; + u8 wol_u[0x1]; + u8 wol_p[0x1]; + u8 stat_rate_support[0x10]; + u8 reserved_at_1f0[0xc]; + u8 cqe_version[0x4]; + u8 compact_address_vector[0x1]; + u8 striding_rq[0x1]; + u8 reserved_at_202[0x1]; + u8 ipoib_enhanced_offloads[0x1]; + u8 ipoib_basic_offloads[0x1]; + u8 reserved_at_205[0x1]; + u8 repeated_block_disabled[0x1]; + u8 umr_modify_entity_size_disabled[0x1]; + u8 umr_modify_atomic_disabled[0x1]; + u8 umr_indirect_mkey_disabled[0x1]; + u8 umr_fence[0x2]; + u8 reserved_at_20c[0x3]; + u8 drain_sigerr[0x1]; + u8 cmdif_checksum[0x2]; + u8 sigerr_cqe[0x1]; + u8 reserved_at_213[0x1]; + u8 wq_signature[0x1]; + u8 sctr_data_cqe[0x1]; + u8 reserved_at_216[0x1]; + u8 sho[0x1]; + u8 tph[0x1]; + u8 rf[0x1]; + u8 dct[0x1]; + u8 qos[0x1]; + u8 eth_net_offloads[0x1]; + u8 roce[0x1]; + u8 atomic[0x1]; + u8 reserved_at_21f[0x1]; + u8 cq_oi[0x1]; + u8 cq_resize[0x1]; + u8 cq_moderation[0x1]; + u8 reserved_at_223[0x3]; + u8 cq_eq_remap[0x1]; + u8 pg[0x1]; + u8 block_lb_mc[0x1]; + u8 reserved_at_229[0x1]; + u8 scqe_break_moderation[0x1]; + u8 cq_period_start_from_cqe[0x1]; + u8 cd[0x1]; + u8 reserved_at_22d[0x1]; + u8 apm[0x1]; + u8 vector_calc[0x1]; + u8 umr_ptr_rlky[0x1]; + u8 imaicl[0x1]; + u8 reserved_at_232[0x4]; + u8 qkv[0x1]; + u8 pkv[0x1]; + u8 set_deth_sqpn[0x1]; + u8 reserved_at_239[0x3]; + u8 xrc[0x1]; + u8 ud[0x1]; + u8 uc[0x1]; + u8 rc[0x1]; + u8 uar_4k[0x1]; + u8 reserved_at_241[0x9]; + u8 uar_sz[0x6]; + u8 reserved_at_250[0x8]; + u8 log_pg_sz[0x8]; + u8 bf[0x1]; + u8 driver_version[0x1]; + u8 pad_tx_eth_packet[0x1]; + u8 reserved_at_263[0x8]; + u8 log_bf_reg_size[0x5]; + u8 reserved_at_270[0xb]; + u8 lag_master[0x1]; + u8 num_lag_ports[0x4]; + u8 reserved_at_280[0x10]; + u8 max_wqe_sz_sq[0x10]; + u8 reserved_at_2a0[0x10]; + u8 max_wqe_sz_rq[0x10]; + u8 max_flow_counter_31_16[0x10]; + u8 max_wqe_sz_sq_dc[0x10]; + u8 reserved_at_2e0[0x7]; + u8 max_qp_mcg[0x19]; + u8 reserved_at_300[0x10]; + u8 flow_counter_bulk_alloc[0x08]; + u8 log_max_mcg[0x8]; + u8 reserved_at_320[0x3]; + u8 log_max_transport_domain[0x5]; + u8 reserved_at_328[0x3]; + u8 log_max_pd[0x5]; + u8 reserved_at_330[0xb]; + u8 log_max_xrcd[0x5]; + u8 nic_receive_steering_discard[0x1]; + u8 receive_discard_vport_down[0x1]; + u8 transmit_discard_vport_down[0x1]; + u8 reserved_at_343[0x5]; + u8 log_max_flow_counter_bulk[0x8]; + u8 max_flow_counter_15_0[0x10]; + u8 modify_tis[0x1]; + u8 flow_counters_dump[0x1]; + u8 reserved_at_360[0x1]; + u8 log_max_rq[0x5]; + u8 reserved_at_368[0x3]; + u8 log_max_sq[0x5]; + u8 reserved_at_370[0x3]; + u8 log_max_tir[0x5]; + u8 reserved_at_378[0x3]; + u8 log_max_tis[0x5]; + u8 basic_cyclic_rcv_wqe[0x1]; + u8 reserved_at_381[0x2]; + u8 log_max_rmp[0x5]; + u8 reserved_at_388[0x3]; + u8 log_max_rqt[0x5]; + u8 reserved_at_390[0x3]; + u8 log_max_rqt_size[0x5]; + u8 reserved_at_398[0x3]; + u8 log_max_tis_per_sq[0x5]; + u8 ext_stride_num_range[0x1]; + u8 reserved_at_3a1[0x2]; + u8 log_max_stride_sz_rq[0x5]; + u8 reserved_at_3a8[0x3]; + u8 log_min_stride_sz_rq[0x5]; + u8 reserved_at_3b0[0x3]; + u8 log_max_stride_sz_sq[0x5]; + u8 reserved_at_3b8[0x3]; + u8 log_min_stride_sz_sq[0x5]; + u8 hairpin[0x1]; + u8 reserved_at_3c1[0x2]; + u8 log_max_hairpin_queues[0x5]; + u8 reserved_at_3c8[0x3]; + u8 log_max_hairpin_wq_data_sz[0x5]; + u8 reserved_at_3d0[0x3]; + u8 log_max_hairpin_num_packets[0x5]; + u8 reserved_at_3d8[0x3]; + u8 log_max_wq_sz[0x5]; + u8 nic_vport_change_event[0x1]; + u8 disable_local_lb_uc[0x1]; + u8 disable_local_lb_mc[0x1]; + u8 log_min_hairpin_wq_data_sz[0x5]; + u8 reserved_at_3e8[0x3]; + u8 log_max_vlan_list[0x5]; + u8 reserved_at_3f0[0x3]; + u8 log_max_current_mc_list[0x5]; + u8 reserved_at_3f8[0x3]; + u8 log_max_current_uc_list[0x5]; + u8 general_obj_types[0x40]; + u8 reserved_at_440[0x20]; + u8 reserved_at_460[0x10]; + u8 max_num_eqs[0x10]; + u8 reserved_at_480[0x3]; + u8 log_max_l2_table[0x5]; + u8 reserved_at_488[0x8]; + u8 log_uar_page_sz[0x10]; + u8 reserved_at_4a0[0x20]; + u8 device_frequency_mhz[0x20]; + u8 device_frequency_khz[0x20]; + u8 reserved_at_500[0x20]; + u8 num_of_uars_per_page[0x20]; + u8 flex_parser_protocols[0x20]; + u8 reserved_at_560[0x20]; + u8 reserved_at_580[0x3c]; + u8 mini_cqe_resp_stride_index[0x1]; + u8 cqe_128_always[0x1]; + u8 cqe_compression_128[0x1]; + u8 cqe_compression[0x1]; + u8 cqe_compression_timeout[0x10]; + u8 cqe_compression_max_num[0x10]; + u8 reserved_at_5e0[0x10]; + u8 tag_matching[0x1]; + u8 rndv_offload_rc[0x1]; + u8 rndv_offload_dc[0x1]; + u8 log_tag_matching_list_sz[0x5]; + u8 reserved_at_5f8[0x3]; + u8 log_max_xrq[0x5]; + u8 affiliate_nic_vport_criteria[0x8]; + u8 native_port_num[0x8]; + u8 num_vhca_ports[0x8]; + u8 reserved_at_618[0x6]; + u8 sw_owner_id[0x1]; + u8 reserved_at_61f[0x1e1]; +}; + +struct mlx5_ifc_qos_cap_bits { + u8 packet_pacing[0x1]; + u8 esw_scheduling[0x1]; + u8 esw_bw_share[0x1]; + u8 esw_rate_limit[0x1]; + u8 reserved_at_4[0x1]; + u8 packet_pacing_burst_bound[0x1]; + u8 packet_pacing_typical_size[0x1]; + u8 flow_meter_srtcm[0x1]; + u8 reserved_at_8[0x8]; + u8 log_max_flow_meter[0x8]; + u8 flow_meter_reg_id[0x8]; + u8 reserved_at_25[0x8]; + u8 flow_meter_reg_share[0x1]; + u8 reserved_at_2e[0x17]; + u8 packet_pacing_max_rate[0x20]; + u8 packet_pacing_min_rate[0x20]; + u8 reserved_at_80[0x10]; + u8 packet_pacing_rate_table_size[0x10]; + u8 esw_element_type[0x10]; + u8 esw_tsar_type[0x10]; + u8 reserved_at_c0[0x10]; + u8 max_qos_para_vport[0x10]; + u8 max_tsar_bw_share[0x20]; + u8 reserved_at_100[0x6e8]; +}; + +struct mlx5_ifc_per_protocol_networking_offload_caps_bits { + u8 csum_cap[0x1]; + u8 vlan_cap[0x1]; + u8 lro_cap[0x1]; + u8 lro_psh_flag[0x1]; + u8 lro_time_stamp[0x1]; + u8 lro_max_msg_sz_mode[0x2]; + u8 wqe_vlan_insert[0x1]; + u8 self_lb_en_modifiable[0x1]; + u8 self_lb_mc[0x1]; + u8 self_lb_uc[0x1]; + u8 max_lso_cap[0x5]; + u8 multi_pkt_send_wqe[0x2]; + u8 wqe_inline_mode[0x2]; + u8 rss_ind_tbl_cap[0x4]; + u8 reg_umr_sq[0x1]; + u8 scatter_fcs[0x1]; + u8 enhanced_multi_pkt_send_wqe[0x1]; + u8 tunnel_lso_const_out_ip_id[0x1]; + u8 tunnel_lro_gre[0x1]; + u8 tunnel_lro_vxlan[0x1]; + u8 tunnel_stateless_gre[0x1]; + u8 tunnel_stateless_vxlan[0x1]; + u8 swp[0x1]; + u8 swp_csum[0x1]; + u8 swp_lso[0x1]; + u8 reserved_at_23[0x8]; + u8 tunnel_stateless_gtp[0x1]; + u8 reserved_at_25[0x4]; + u8 max_vxlan_udp_ports[0x8]; + u8 reserved_at_38[0x6]; + u8 max_geneve_opt_len[0x1]; + u8 tunnel_stateless_geneve_rx[0x1]; + u8 reserved_at_40[0x10]; + u8 lro_min_mss_size[0x10]; + u8 reserved_at_60[0x120]; + u8 lro_timer_supported_periods[4][0x20]; + u8 reserved_at_200[0x600]; +}; + +union mlx5_ifc_hca_cap_union_bits { + struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap; + struct mlx5_ifc_per_protocol_networking_offload_caps_bits + per_protocol_networking_offload_caps; + struct mlx5_ifc_qos_cap_bits qos_cap; + u8 reserved_at_0[0x8000]; +}; + +struct mlx5_ifc_query_hca_cap_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; + union mlx5_ifc_hca_cap_union_bits capability; +}; + +struct mlx5_ifc_query_hca_cap_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_mac_address_layout_bits { + u8 reserved_at_0[0x10]; + u8 mac_addr_47_32[0x10]; + u8 mac_addr_31_0[0x20]; +}; + +struct mlx5_ifc_nic_vport_context_bits { + u8 reserved_at_0[0x5]; + u8 min_wqe_inline_mode[0x3]; + u8 reserved_at_8[0x15]; + u8 disable_mc_local_lb[0x1]; + u8 disable_uc_local_lb[0x1]; + u8 roce_en[0x1]; + u8 arm_change_event[0x1]; + u8 reserved_at_21[0x1a]; + u8 event_on_mtu[0x1]; + u8 event_on_promisc_change[0x1]; + u8 event_on_vlan_change[0x1]; + u8 event_on_mc_address_change[0x1]; + u8 event_on_uc_address_change[0x1]; + u8 reserved_at_40[0xc]; + u8 affiliation_criteria[0x4]; + u8 affiliated_vhca_id[0x10]; + u8 reserved_at_60[0xd0]; + u8 mtu[0x10]; + u8 system_image_guid[0x40]; + u8 port_guid[0x40]; + u8 node_guid[0x40]; + u8 reserved_at_200[0x140]; + u8 qkey_violation_counter[0x10]; + u8 reserved_at_350[0x430]; + u8 promisc_uc[0x1]; + u8 promisc_mc[0x1]; + u8 promisc_all[0x1]; + u8 reserved_at_783[0x2]; + u8 allowed_list_type[0x3]; + u8 reserved_at_788[0xc]; + u8 allowed_list_size[0xc]; + struct mlx5_ifc_mac_address_layout_bits permanent_address; + u8 reserved_at_7e0[0x20]; +}; + +struct mlx5_ifc_query_nic_vport_context_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; + struct mlx5_ifc_nic_vport_context_bits nic_vport_context; +}; + +struct mlx5_ifc_query_nic_vport_context_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 other_vport[0x1]; + u8 reserved_at_41[0xf]; + u8 vport_number[0x10]; + u8 reserved_at_60[0x5]; + u8 allowed_list_type[0x3]; + u8 reserved_at_68[0x18]; +}; + +struct mlx5_ifc_tisc_bits { + u8 strict_lag_tx_port_affinity[0x1]; + u8 reserved_at_1[0x3]; + u8 lag_tx_port_affinity[0x04]; + u8 reserved_at_8[0x4]; + u8 prio[0x4]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x100]; + u8 reserved_at_120[0x8]; + u8 transport_domain[0x18]; + u8 reserved_at_140[0x8]; + u8 underlay_qpn[0x18]; + u8 reserved_at_160[0x3a0]; +}; + +struct mlx5_ifc_query_tis_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; + struct mlx5_ifc_tisc_bits tis_context; +}; + +struct mlx5_ifc_query_tis_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 tisn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_alloc_transport_domain_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 transport_domain[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_alloc_transport_domain_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x40]; +}; + +enum { + MLX5_WQ_TYPE_LINKED_LIST = 0x0, + MLX5_WQ_TYPE_CYCLIC = 0x1, + MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ = 0x2, + MLX5_WQ_TYPE_CYCLIC_STRIDING_RQ = 0x3, +}; + +enum { + MLX5_WQ_END_PAD_MODE_NONE = 0x0, + MLX5_WQ_END_PAD_MODE_ALIGN = 0x1, +}; + +struct mlx5_ifc_wq_bits { + u8 wq_type[0x4]; + u8 wq_signature[0x1]; + u8 end_padding_mode[0x2]; + u8 cd_slave[0x1]; + u8 reserved_at_8[0x18]; + u8 hds_skip_first_sge[0x1]; + u8 log2_hds_buf_size[0x3]; + u8 reserved_at_24[0x7]; + u8 page_offset[0x5]; + u8 lwm[0x10]; + u8 reserved_at_40[0x8]; + u8 pd[0x18]; + u8 reserved_at_60[0x8]; + u8 uar_page[0x18]; + u8 dbr_addr[0x40]; + u8 hw_counter[0x20]; + u8 sw_counter[0x20]; + u8 reserved_at_100[0xc]; + u8 log_wq_stride[0x4]; + u8 reserved_at_110[0x3]; + u8 log_wq_pg_sz[0x5]; + u8 reserved_at_118[0x3]; + u8 log_wq_sz[0x5]; + u8 dbr_umem_valid[0x1]; + u8 wq_umem_valid[0x1]; + u8 reserved_at_122[0x1]; + u8 log_hairpin_num_packets[0x5]; + u8 reserved_at_128[0x3]; + u8 log_hairpin_data_sz[0x5]; + u8 reserved_at_130[0x4]; + u8 single_wqe_log_num_of_strides[0x4]; + u8 two_byte_shift_en[0x1]; + u8 reserved_at_139[0x4]; + u8 single_stride_log_num_of_bytes[0x3]; + u8 dbr_umem_id[0x20]; + u8 wq_umem_id[0x20]; + u8 wq_umem_offset[0x40]; + u8 reserved_at_1c0[0x440]; +}; + +enum { + MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE = 0x0, + MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_RMP = 0x1, +}; + +enum { + MLX5_RQC_STATE_RST = 0x0, + MLX5_RQC_STATE_RDY = 0x1, + MLX5_RQC_STATE_ERR = 0x3, +}; + +struct mlx5_ifc_rqc_bits { + u8 rlky[0x1]; + u8 delay_drop_en[0x1]; + u8 scatter_fcs[0x1]; + u8 vsd[0x1]; + u8 mem_rq_type[0x4]; + u8 state[0x4]; + u8 reserved_at_c[0x1]; + u8 flush_in_error_en[0x1]; + u8 hairpin[0x1]; + u8 reserved_at_f[0x11]; + u8 reserved_at_20[0x8]; + u8 user_index[0x18]; + u8 reserved_at_40[0x8]; + u8 cqn[0x18]; + u8 counter_set_id[0x8]; + u8 reserved_at_68[0x18]; + u8 reserved_at_80[0x8]; + u8 rmpn[0x18]; + u8 reserved_at_a0[0x8]; + u8 hairpin_peer_sq[0x18]; + u8 reserved_at_c0[0x10]; + u8 hairpin_peer_vhca[0x10]; + u8 reserved_at_e0[0xa0]; + struct mlx5_ifc_wq_bits wq; /* Not used in LRO RQ. */ +}; + +struct mlx5_ifc_create_rq_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 rqn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_rq_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_rqc_bits ctx; +}; + +struct mlx5_ifc_modify_rq_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_create_tis_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 tisn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_tis_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_tisc_bits ctx; +}; + +enum { + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM = 1ULL << 0, + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD = 1ULL << 1, + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS = 1ULL << 2, + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID = 1ULL << 3, +}; + +struct mlx5_ifc_modify_rq_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 rq_state[0x4]; + u8 reserved_at_44[0x4]; + u8 rqn[0x18]; + u8 reserved_at_60[0x20]; + u8 modify_bitmask[0x40]; + u8 reserved_at_c0[0x40]; + struct mlx5_ifc_rqc_bits ctx; +}; + +enum { + MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_SRC_IP = 0x0, + MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_DST_IP = 0x1, + MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_SPORT = 0x2, + MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_DPORT = 0x3, + MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_IPSEC_SPI = 0x4, +}; + +struct mlx5_ifc_rx_hash_field_select_bits { + u8 l3_prot_type[0x1]; + u8 l4_prot_type[0x1]; + u8 selected_fields[0x1e]; +}; + +enum { + MLX5_TIRC_DISP_TYPE_DIRECT = 0x0, + MLX5_TIRC_DISP_TYPE_INDIRECT = 0x1, +}; + +enum { + MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO = 0x1, + MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO = 0x2, +}; + +enum { + MLX5_RX_HASH_FN_NONE = 0x0, + MLX5_RX_HASH_FN_INVERTED_XOR8 = 0x1, + MLX5_RX_HASH_FN_TOEPLITZ = 0x2, +}; + +enum { + MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST = 0x1, + MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST = 0x2, +}; + +enum { + MLX5_LRO_MAX_MSG_SIZE_START_FROM_L4 = 0x0, + MLX5_LRO_MAX_MSG_SIZE_START_FROM_L2 = 0x1, +}; + +struct mlx5_ifc_tirc_bits { + u8 reserved_at_0[0x20]; + u8 disp_type[0x4]; + u8 reserved_at_24[0x1c]; + u8 reserved_at_40[0x40]; + u8 reserved_at_80[0x4]; + u8 lro_timeout_period_usecs[0x10]; + u8 lro_enable_mask[0x4]; + u8 lro_max_msg_sz[0x8]; + u8 reserved_at_a0[0x40]; + u8 reserved_at_e0[0x8]; + u8 inline_rqn[0x18]; + u8 rx_hash_symmetric[0x1]; + u8 reserved_at_101[0x1]; + u8 tunneled_offload_en[0x1]; + u8 reserved_at_103[0x5]; + u8 indirect_table[0x18]; + u8 rx_hash_fn[0x4]; + u8 reserved_at_124[0x2]; + u8 self_lb_block[0x2]; + u8 transport_domain[0x18]; + u8 rx_hash_toeplitz_key[10][0x20]; + struct mlx5_ifc_rx_hash_field_select_bits rx_hash_field_selector_outer; + struct mlx5_ifc_rx_hash_field_select_bits rx_hash_field_selector_inner; + u8 reserved_at_2c0[0x4c0]; +}; + +struct mlx5_ifc_create_tir_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 tirn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_tir_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_tirc_bits ctx; +}; + +struct mlx5_ifc_rq_num_bits { + u8 reserved_at_0[0x8]; + u8 rq_num[0x18]; +}; + +struct mlx5_ifc_rqtc_bits { + u8 reserved_at_0[0xa0]; + u8 reserved_at_a0[0x10]; + u8 rqt_max_size[0x10]; + u8 reserved_at_c0[0x10]; + u8 rqt_actual_size[0x10]; + u8 reserved_at_e0[0x6a0]; + struct mlx5_ifc_rq_num_bits rq_num[]; +}; + +struct mlx5_ifc_create_rqt_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 rqtn[0x18]; + u8 reserved_at_60[0x20]; +}; + +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +struct mlx5_ifc_create_rqt_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_rqtc_bits rqt_context; +}; +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +enum { + MLX5_SQC_STATE_RST = 0x0, + MLX5_SQC_STATE_RDY = 0x1, + MLX5_SQC_STATE_ERR = 0x3, +}; + +struct mlx5_ifc_sqc_bits { + u8 rlky[0x1]; + u8 cd_master[0x1]; + u8 fre[0x1]; + u8 flush_in_error_en[0x1]; + u8 allow_multi_pkt_send_wqe[0x1]; + u8 min_wqe_inline_mode[0x3]; + u8 state[0x4]; + u8 reg_umr[0x1]; + u8 allow_swp[0x1]; + u8 hairpin[0x1]; + u8 reserved_at_f[0x11]; + u8 reserved_at_20[0x8]; + u8 user_index[0x18]; + u8 reserved_at_40[0x8]; + u8 cqn[0x18]; + u8 reserved_at_60[0x8]; + u8 hairpin_peer_rq[0x18]; + u8 reserved_at_80[0x10]; + u8 hairpin_peer_vhca[0x10]; + u8 reserved_at_a0[0x50]; + u8 packet_pacing_rate_limit_index[0x10]; + u8 tis_lst_sz[0x10]; + u8 reserved_at_110[0x10]; + u8 reserved_at_120[0x40]; + u8 reserved_at_160[0x8]; + u8 tis_num_0[0x18]; + struct mlx5_ifc_wq_bits wq; +}; + +struct mlx5_ifc_query_sq_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 sqn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_modify_sq_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_modify_sq_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 sq_state[0x4]; + u8 reserved_at_44[0x4]; + u8 sqn[0x18]; + u8 reserved_at_60[0x20]; + u8 modify_bitmask[0x40]; + u8 reserved_at_c0[0x40]; + struct mlx5_ifc_sqc_bits ctx; +}; + +struct mlx5_ifc_create_sq_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 sqn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_sq_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0xc0]; + struct mlx5_ifc_sqc_bits ctx; +}; + +enum { + MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE = (1ULL << 0), + MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS = (1ULL << 1), + MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR = (1ULL << 2), + MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS = (1ULL << 3), + MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EIR = (1ULL << 4), +}; + +struct mlx5_ifc_flow_meter_parameters_bits { + u8 valid[0x1]; // 00h + u8 bucket_overflow[0x1]; + u8 start_color[0x2]; + u8 both_buckets_on_green[0x1]; + u8 meter_mode[0x2]; + u8 reserved_at_1[0x19]; + u8 reserved_at_2[0x20]; //04h + u8 reserved_at_3[0x3]; + u8 cbs_exponent[0x5]; // 08h + u8 cbs_mantissa[0x8]; + u8 reserved_at_4[0x3]; + u8 cir_exponent[0x5]; + u8 cir_mantissa[0x8]; + u8 reserved_at_5[0x20]; // 0Ch + u8 reserved_at_6[0x3]; + u8 ebs_exponent[0x5]; // 10h + u8 ebs_mantissa[0x8]; + u8 reserved_at_7[0x3]; + u8 eir_exponent[0x5]; + u8 eir_mantissa[0x8]; + u8 reserved_at_8[0x60]; // 14h-1Ch +}; + +/* 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; + struct { + uint16_t checksum; + uint16_t stride_idx; + }; + struct { + uint16_t wqe_counter; + uint8_t s_wqe_opcode; + uint8_t reserved; + } s_wqe_info; + }; + uint32_t byte_cnt; +}; + +/* srTCM PRM flow meter parameters. */ +enum { + MLX5_FLOW_COLOR_RED = 0, + MLX5_FLOW_COLOR_YELLOW, + MLX5_FLOW_COLOR_GREEN, + MLX5_FLOW_COLOR_UNDEFINED, +}; + +/* Maximum value of srTCM metering parameters. */ +#define MLX5_SRTCM_CBS_MAX (0xFF * (1ULL << 0x1F)) +#define MLX5_SRTCM_CIR_MAX (8 * (1ULL << 30) * 0xFF) +#define MLX5_SRTCM_EBS_MAX 0 + +/* The bits meter color use. */ +#define MLX5_MTR_COLOR_BITS 8 + +/** + * Convert a user mark to flow mark. + * + * @param val + * Mark value to convert. + * + * @return + * Converted mark value. + */ +static inline uint32_t +mlx5_flow_mark_set(uint32_t val) +{ + uint32_t ret; + + /* + * Add one to the user value to differentiate un-marked flows from + * marked flows, if the ID is equal to MLX5_FLOW_MARK_DEFAULT it + * remains untouched. + */ + if (val != MLX5_FLOW_MARK_DEFAULT) + ++val; +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + /* + * Mark is 24 bits (minus reserved values) but is stored on a 32 bit + * word, byte-swapped by the kernel on little-endian systems. In this + * case, left-shifting the resulting big-endian value ensures the + * least significant 24 bits are retained when converting it back. + */ + ret = rte_cpu_to_be_32(val) >> 8; +#else + ret = val; +#endif + return ret; +} + +/** + * Convert a mark to user mark. + * + * @param val + * Mark value to convert. + * + * @return + * Converted mark value. + */ +static inline uint32_t +mlx5_flow_mark_get(uint32_t val) +{ + /* + * Subtract one from the retrieved value. It was added by + * mlx5_flow_mark_set() to distinguish unmarked flows. + */ +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + return (val >> 8) - 1; +#else + return val - 1; +#endif +} + +#endif /* RTE_PMD_MLX5_PRM_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map new file mode 100644 index 0000000..e4f85e2 --- /dev/null +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -0,0 +1,20 @@ +DPDK_20.02 { + global: + + mlx5_devx_cmd_create_rq; + mlx5_devx_cmd_create_rqt; + mlx5_devx_cmd_create_sq; + mlx5_devx_cmd_create_tir; + mlx5_devx_cmd_create_td; + mlx5_devx_cmd_create_tis; + mlx5_devx_cmd_destroy; + mlx5_devx_cmd_flow_counter_alloc; + mlx5_devx_cmd_flow_counter_query; + mlx5_devx_cmd_flow_dump; + mlx5_devx_cmd_mkey_create; + mlx5_devx_cmd_modify_rq; + mlx5_devx_cmd_modify_sq; + mlx5_devx_cmd_qp_query_tis_td; + mlx5_devx_cmd_query_hca_attr; + mlx5_devx_get_out_command_status; +}; diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index 0466d9d..a9558ca 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -10,11 +10,14 @@ LIB_GLUE = $(LIB_GLUE_BASE).$(LIB_GLUE_VERSION) LIB_GLUE_BASE = librte_pmd_mlx5_glue.so LIB_GLUE_VERSION = 20.02.0 +ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) +CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' +CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' +LDLIBS += -ldl +endif + # Sources. SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c -ifneq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) -SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_glue.c -endif SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxq.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_txq.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxtx.c @@ -37,34 +40,22 @@ 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_nl.c -SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_devx_cmds.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_utils.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c -ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) -INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE) -endif - # Basic CFLAGS. CFLAGS += -O3 CFLAGS += -std=c11 -Wall -Wextra CFLAGS += -g -CFLAGS += -I. +CFLAGS += -I$(RTE_SDK)/drivers/common/mlx5 +CFLAGS += -I$(RTE_SDK)/drivers/net/mlx5 +CFLAGS += -I$(BUILDDIR)/drivers/common/mlx5 CFLAGS += -D_BSD_SOURCE CFLAGS += -D_DEFAULT_SOURCE CFLAGS += -D_XOPEN_SOURCE=600 CFLAGS += $(WERROR_FLAGS) CFLAGS += -Wno-strict-prototypes -ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) -CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' -CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' -CFLAGS_mlx5_glue.o += -fPIC -LDLIBS += -ldl -else ifeq ($(CONFIG_RTE_IBVERBS_LINK_STATIC),y) -LDLIBS += $(shell $(RTE_SDK)/buildtools/options-ibverbs-static.sh) -else -LDLIBS += -libverbs -lmlx5 -endif +LDLIBS += -lrte_common_mlx5 LDLIBS += -lm LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs @@ -74,6 +65,7 @@ LDLIBS += -lrte_bus_pci CFLAGS += -Wno-error=cast-qual EXPORT_MAP := rte_pmd_mlx5_version.map + # memseg walk is not part of stable API CFLAGS += -DALLOW_EXPERIMENTAL_API @@ -96,282 +88,3 @@ endif include $(RTE_SDK)/mk/rte.lib.mk -# Generate and clean-up mlx5_autoconf.h. - -export CC CFLAGS CPPFLAGS EXTRA_CFLAGS EXTRA_CPPFLAGS -export AUTO_CONFIG_CFLAGS += -Wno-error - -ifndef V -AUTOCONF_OUTPUT := >/dev/null -endif - -mlx5_autoconf.h.new: FORCE - -mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh - $Q $(RM) -f -- '$@' - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT \ - infiniband/mlx5dv.h \ - enum MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVICE_TUNNEL_SUPPORT \ - infiniband/mlx5dv.h \ - enum MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVICE_MPLS_SUPPORT \ - infiniband/verbs.h \ - enum IBV_FLOW_SPEC_MPLS \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING \ - infiniband/verbs.h \ - enum IBV_WQ_FLAGS_PCI_WRITE_END_PADDING \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_WQ_FLAG_RX_END_PADDING \ - infiniband/verbs.h \ - enum IBV_WQ_FLAG_RX_END_PADDING \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_MLX5_MOD_SWP \ - infiniband/mlx5dv.h \ - type 'struct mlx5dv_sw_parsing_caps' \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_MLX5_MOD_MPW \ - infiniband/mlx5dv.h \ - enum MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_MLX5_MOD_CQE_128B_COMP \ - infiniband/mlx5dv.h \ - enum MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_MLX5_MOD_CQE_128B_PAD \ - infiniband/mlx5dv.h \ - enum MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_FLOW_DV_SUPPORT \ - infiniband/mlx5dv.h \ - func mlx5dv_create_flow_action_packet_reformat \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_DR \ - infiniband/mlx5dv.h \ - enum MLX5DV_DR_DOMAIN_TYPE_NIC_RX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_DR_ESWITCH \ - infiniband/mlx5dv.h \ - enum MLX5DV_DR_DOMAIN_TYPE_FDB \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_DR_VLAN \ - infiniband/mlx5dv.h \ - func mlx5dv_dr_action_create_push_vlan \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_DR_DEVX_PORT \ - infiniband/mlx5dv.h \ - func mlx5dv_query_devx_port \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVX_OBJ \ - infiniband/mlx5dv.h \ - func mlx5dv_devx_obj_create \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_FLOW_DEVX_COUNTERS \ - infiniband/mlx5dv.h \ - enum MLX5DV_FLOW_ACTION_COUNTERS_DEVX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVX_ASYNC \ - infiniband/mlx5dv.h \ - func mlx5dv_devx_obj_query_async \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR \ - infiniband/mlx5dv.h \ - func mlx5dv_dr_action_create_dest_devx_tir \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER \ - infiniband/mlx5dv.h \ - func mlx5dv_dr_action_create_flow_meter \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5_DR_FLOW_DUMP \ - infiniband/mlx5dv.h \ - func mlx5dv_dump_dr_domain \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD \ - infiniband/mlx5dv.h \ - enum MLX5_MMAP_GET_NC_PAGES_CMD \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_ETHTOOL_LINK_MODE_25G \ - /usr/include/linux/ethtool.h \ - enum ETHTOOL_LINK_MODE_25000baseCR_Full_BIT \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_ETHTOOL_LINK_MODE_50G \ - /usr/include/linux/ethtool.h \ - enum ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_ETHTOOL_LINK_MODE_100G \ - /usr/include/linux/ethtool.h \ - enum ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVICE_COUNTERS_SET_V42 \ - infiniband/verbs.h \ - type 'struct ibv_counter_set_init_attr' \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IBV_DEVICE_COUNTERS_SET_V45 \ - infiniband/verbs.h \ - type 'struct ibv_counters_init_attr' \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NL_NLDEV \ - rdma/rdma_netlink.h \ - enum RDMA_NL_NLDEV \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_CMD_GET \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_CMD_GET \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_CMD_PORT_GET \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_CMD_PORT_GET \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_ATTR_DEV_INDEX \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_ATTR_DEV_INDEX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_ATTR_DEV_NAME \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_ATTR_DEV_NAME \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_ATTR_PORT_INDEX \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_ATTR_PORT_INDEX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX \ - rdma/rdma_netlink.h \ - enum RDMA_NLDEV_ATTR_NDEV_INDEX \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IFLA_NUM_VF \ - linux/if_link.h \ - enum IFLA_NUM_VF \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IFLA_EXT_MASK \ - linux/if_link.h \ - enum IFLA_EXT_MASK \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IFLA_PHYS_SWITCH_ID \ - linux/if_link.h \ - enum IFLA_PHYS_SWITCH_ID \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_IFLA_PHYS_PORT_NAME \ - linux/if_link.h \ - enum IFLA_PHYS_PORT_NAME \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_40000baseKR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_40000baseKR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_40000baseCR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_40000baseCR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_40000baseSR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_40000baseSR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_40000baseLR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_40000baseLR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_56000baseKR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_56000baseKR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_56000baseCR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_56000baseCR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_56000baseSR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_56000baseSR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_SUPPORTED_56000baseLR4_Full \ - /usr/include/linux/ethtool.h \ - define SUPPORTED_56000baseLR4_Full \ - $(AUTOCONF_OUTPUT) - $Q sh -- '$<' '$@' \ - HAVE_STATIC_ASSERT \ - /usr/include/assert.h \ - define static_assert \ - $(AUTOCONF_OUTPUT) - -# Create mlx5_autoconf.h or update it in case it differs from the new one. - -mlx5_autoconf.h: mlx5_autoconf.h.new - $Q [ -f '$@' ] && \ - cmp '$<' '$@' $(AUTOCONF_OUTPUT) || \ - mv '$<' '$@' - -$(SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD):.c=.o): mlx5_autoconf.h - -# Generate dependency plug-in for rdma-core when the PMD must not be linked -# directly, so that applications do not inherit this dependency. - -ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) - -$(LIB): $(LIB_GLUE) - -ifeq ($(LINK_USING_CC),1) -GLUE_LDFLAGS := $(call linkerprefix,$(LDFLAGS)) -else -GLUE_LDFLAGS := $(LDFLAGS) -endif -$(LIB_GLUE): mlx5_glue.o - $Q $(LD) $(GLUE_LDFLAGS) $(EXTRA_LDFLAGS) \ - -Wl,-h,$(LIB_GLUE) \ - -shared -o $@ $< -libverbs -lmlx5 - -mlx5_glue.o: mlx5_autoconf.h - -endif - -clean_mlx5: FORCE - $Q rm -f -- mlx5_autoconf.h mlx5_autoconf.h.new - $Q rm -f -- mlx5_glue.o $(LIB_GLUE_BASE)* - -clean: clean_mlx5 diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index 3ad4f02..f6d0db9 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -7,224 +7,54 @@ if not is_linux reason = 'only supported on Linux' subdir_done() endif -build = true -pmd_dlopen = (get_option('ibverbs_link') == 'dlopen') LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so' LIB_GLUE_VERSION = '20.02.0' LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION -if pmd_dlopen - dpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1) - cflags += [ - '-DMLX5_GLUE="@0@"'.format(LIB_GLUE), - '-DMLX5_GLUE_VERSION="@0@"'.format(LIB_GLUE_VERSION), - ] -endif -libnames = [ 'mlx5', 'ibverbs' ] -libs = [] -foreach libname:libnames - lib = dependency('lib' + libname, required:false) - if not lib.found() - lib = cc.find_library(libname, required:false) - endif - if lib.found() - libs += [ lib ] - else - build = false - reason = 'missing dependency, "' + libname + '"' +allow_experimental_apis = true +deps += ['hash', 'common_mlx5'] +sources = files( + 'mlx5.c', + 'mlx5_ethdev.c', + 'mlx5_flow.c', + 'mlx5_flow_meter.c', + 'mlx5_flow_dv.c', + 'mlx5_flow_verbs.c', + 'mlx5_mac.c', + 'mlx5_mr.c', + 'mlx5_nl.c', + 'mlx5_rss.c', + 'mlx5_rxmode.c', + 'mlx5_rxq.c', + 'mlx5_rxtx.c', + 'mlx5_mp.c', + 'mlx5_stats.c', + 'mlx5_trigger.c', + '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') + or dpdk_conf.has('RTE_ARCH_PPC_64')) + sources += files('mlx5_rxtx_vec.c') +endif +cflags_options = [ + '-std=c11', + '-Wno-strict-prototypes', + '-D_BSD_SOURCE', + '-D_DEFAULT_SOURCE', + '-D_XOPEN_SOURCE=600' +] +foreach option:cflags_options + if cc.has_argument(option) + cflags += option endif endforeach - -if build - allow_experimental_apis = true - deps += ['hash'] - ext_deps += libs - sources = files( - 'mlx5.c', - 'mlx5_ethdev.c', - 'mlx5_flow.c', - 'mlx5_flow_meter.c', - 'mlx5_flow_dv.c', - 'mlx5_flow_verbs.c', - 'mlx5_mac.c', - 'mlx5_mr.c', - 'mlx5_nl.c', - 'mlx5_rss.c', - 'mlx5_rxmode.c', - 'mlx5_rxq.c', - 'mlx5_rxtx.c', - 'mlx5_mp.c', - 'mlx5_stats.c', - 'mlx5_trigger.c', - 'mlx5_txq.c', - 'mlx5_vlan.c', - 'mlx5_devx_cmds.c', - 'mlx5_utils.c', - 'mlx5_socket.c', - ) - if (dpdk_conf.has('RTE_ARCH_X86_64') - or dpdk_conf.has('RTE_ARCH_ARM64') - or dpdk_conf.has('RTE_ARCH_PPC_64')) - sources += files('mlx5_rxtx_vec.c') - endif - if not pmd_dlopen - sources += files('mlx5_glue.c') - endif - cflags_options = [ - '-std=c11', - '-Wno-strict-prototypes', - '-D_BSD_SOURCE', - '-D_DEFAULT_SOURCE', - '-D_XOPEN_SOURCE=600' - ] - foreach option:cflags_options - if cc.has_argument(option) - cflags += option - endif - endforeach - if get_option('buildtype').contains('debug') - cflags += [ '-pedantic', '-UNDEBUG', '-DPEDANTIC' ] - else - cflags += [ '-DNDEBUG', '-UPEDANTIC' ] - endif - # To maintain the compatibility with the make build system - # mlx5_autoconf.h file is still generated. - # input array for meson member search: - # [ "MACRO to define if found", "header for the search", - # "symbol to search", "struct member to search" ] - has_member_args = [ - [ 'HAVE_IBV_MLX5_MOD_SWP', 'infiniband/mlx5dv.h', - 'struct mlx5dv_sw_parsing_caps', 'sw_parsing_offloads' ], - [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V42', 'infiniband/verbs.h', - 'struct ibv_counter_set_init_attr', 'counter_set_id' ], - [ 'HAVE_IBV_DEVICE_COUNTERS_SET_V45', 'infiniband/verbs.h', - 'struct ibv_counters_init_attr', 'comp_mask' ], - ] - # input array for meson symbol search: - # [ "MACRO to define if found", "header for the search", - # "symbol to search" ] - has_sym_args = [ - [ 'HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT', 'infiniband/mlx5dv.h', - 'MLX5DV_CQE_RES_FORMAT_CSUM_STRIDX' ], - [ 'HAVE_IBV_DEVICE_TUNNEL_SUPPORT', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS' ], - [ 'HAVE_IBV_MLX5_MOD_MPW', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED' ], - [ 'HAVE_IBV_MLX5_MOD_CQE_128B_COMP', 'infiniband/mlx5dv.h', - 'MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP' ], - [ 'HAVE_IBV_MLX5_MOD_CQE_128B_PAD', 'infiniband/mlx5dv.h', - 'MLX5DV_CQ_INIT_ATTR_FLAGS_CQE_PAD' ], - [ 'HAVE_IBV_FLOW_DV_SUPPORT', 'infiniband/mlx5dv.h', - 'mlx5dv_create_flow_action_packet_reformat' ], - [ 'HAVE_IBV_DEVICE_MPLS_SUPPORT', 'infiniband/verbs.h', - 'IBV_FLOW_SPEC_MPLS' ], - [ 'HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING', 'infiniband/verbs.h', - 'IBV_WQ_FLAGS_PCI_WRITE_END_PADDING' ], - [ 'HAVE_IBV_WQ_FLAG_RX_END_PADDING', 'infiniband/verbs.h', - 'IBV_WQ_FLAG_RX_END_PADDING' ], - [ 'HAVE_MLX5DV_DR_DEVX_PORT', 'infiniband/mlx5dv.h', - 'mlx5dv_query_devx_port' ], - [ 'HAVE_IBV_DEVX_OBJ', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_obj_create' ], - [ 'HAVE_IBV_FLOW_DEVX_COUNTERS', 'infiniband/mlx5dv.h', - 'MLX5DV_FLOW_ACTION_COUNTERS_DEVX' ], - [ 'HAVE_IBV_DEVX_ASYNC', 'infiniband/mlx5dv.h', - 'mlx5dv_devx_obj_query_async' ], - [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_dest_devx_tir' ], - [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_flow_meter' ], - [ 'HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD', 'infiniband/mlx5dv.h', - 'MLX5_MMAP_GET_NC_PAGES_CMD' ], - [ 'HAVE_MLX5DV_DR', 'infiniband/mlx5dv.h', - 'MLX5DV_DR_DOMAIN_TYPE_NIC_RX' ], - [ 'HAVE_MLX5DV_DR_ESWITCH', 'infiniband/mlx5dv.h', - 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], - [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', - 'mlx5dv_dr_action_create_push_vlan' ], - [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseKR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseCR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseSR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseSR4_Full' ], - [ 'HAVE_SUPPORTED_40000baseLR4_Full', 'linux/ethtool.h', - 'SUPPORTED_40000baseLR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseKR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseKR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseCR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseCR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseSR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseSR4_Full' ], - [ 'HAVE_SUPPORTED_56000baseLR4_Full', 'linux/ethtool.h', - 'SUPPORTED_56000baseLR4_Full' ], - [ 'HAVE_ETHTOOL_LINK_MODE_25G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_25000baseCR_Full_BIT' ], - [ 'HAVE_ETHTOOL_LINK_MODE_50G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT' ], - [ 'HAVE_ETHTOOL_LINK_MODE_100G', 'linux/ethtool.h', - 'ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT' ], - [ 'HAVE_IFLA_NUM_VF', 'linux/if_link.h', - 'IFLA_NUM_VF' ], - [ 'HAVE_IFLA_EXT_MASK', 'linux/if_link.h', - 'IFLA_EXT_MASK' ], - [ 'HAVE_IFLA_PHYS_SWITCH_ID', 'linux/if_link.h', - 'IFLA_PHYS_SWITCH_ID' ], - [ 'HAVE_IFLA_PHYS_PORT_NAME', 'linux/if_link.h', - 'IFLA_PHYS_PORT_NAME' ], - [ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h', - 'RDMA_NL_NLDEV' ], - [ 'HAVE_RDMA_NLDEV_CMD_GET', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_CMD_GET' ], - [ 'HAVE_RDMA_NLDEV_CMD_PORT_GET', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_CMD_PORT_GET' ], - [ 'HAVE_RDMA_NLDEV_ATTR_DEV_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_DEV_INDEX' ], - [ 'HAVE_RDMA_NLDEV_ATTR_DEV_NAME', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_DEV_NAME' ], - [ 'HAVE_RDMA_NLDEV_ATTR_PORT_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_PORT_INDEX' ], - [ 'HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX', 'rdma/rdma_netlink.h', - 'RDMA_NLDEV_ATTR_NDEV_INDEX' ], - [ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h', - 'mlx5dv_dump_dr_domain'], - ] - config = configuration_data() - foreach arg:has_sym_args - config.set(arg[0], cc.has_header_symbol(arg[1], arg[2], - dependencies: libs)) - endforeach - foreach arg:has_member_args - file_prefix = '#include <' + arg[1] + '>' - config.set(arg[0], cc.has_member(arg[2], arg[3], - prefix : file_prefix, dependencies: libs)) - endforeach - configure_file(output : 'mlx5_autoconf.h', configuration : config) -endif -# Build Glue Library -if pmd_dlopen and build - dlopen_name = 'mlx5_glue' - dlopen_lib_name = driver_name_fmt.format(dlopen_name) - dlopen_so_version = LIB_GLUE_VERSION - dlopen_sources = files('mlx5_glue.c') - dlopen_install_dir = [ eal_pmd_path + '-glue' ] - dlopen_includes = [global_inc] - dlopen_includes += include_directories( - '../../../lib/librte_eal/common/include/generic', - ) - shared_lib = shared_library( - dlopen_lib_name, - dlopen_sources, - include_directories: dlopen_includes, - c_args: cflags, - dependencies: libs, - link_args: [ - '-Wl,-export-dynamic', - '-Wl,-h,@0@'.format(LIB_GLUE), - ], - soversion: dlopen_so_version, - install: true, - install_dir: dlopen_install_dir, - ) +if get_option('buildtype').contains('debug') + cflags += [ '-pedantic', '-UNDEBUG', '-DPEDANTIC' ] +else + cflags += [ '-DNDEBUG', '-UPEDANTIC' ] endif diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 7126edf..7cf357d 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -38,15 +38,16 @@ #include #include +#include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_glue.h" #include "mlx5_mr.h" #include "mlx5_flow.h" -#include "mlx5_devx_cmds.h" /* Device parameter to enable RX completion queue compression. */ #define MLX5_RXQ_CQE_COMP_EN "rxq_cqe_comp_en" diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 4d0485d..872fccb 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -32,13 +32,14 @@ #include #include +#include +#include +#include + +#include "mlx5_defs.h" #include "mlx5_utils.h" #include "mlx5_mr.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_glue.h" -#include "mlx5_prm.h" -#include "mlx5_devx_cmds.h" enum { PCI_VENDOR_ID_MELLANOX = 0x15b3, diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c b/drivers/net/mlx5/mlx5_devx_cmds.c deleted file mode 100644 index 62ca590..0000000 --- a/drivers/net/mlx5/mlx5_devx_cmds.c +++ /dev/null @@ -1,976 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2018 Mellanox Technologies, Ltd */ - -#include - -#include -#include - -#include "mlx5_prm.h" -#include "mlx5_devx_cmds.h" -#include "mlx5_utils.h" - - -/** - * Allocate flow counters via devx interface. - * - * @param[in] ctx - * ibv contexts returned from mlx5dv_open_device. - * @param dcs - * Pointer to counters properties structure to be filled by the routine. - * @param bulk_n_128 - * Bulk counter numbers in 128 counters units. - * - * @return - * Pointer to counter object on success, a negative value otherwise and - * rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, uint32_t bulk_n_128) -{ - struct mlx5_devx_obj *dcs = rte_zmalloc("dcs", sizeof(*dcs), 0); - uint32_t in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0}; - - if (!dcs) { - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(alloc_flow_counter_in, in, opcode, - MLX5_CMD_OP_ALLOC_FLOW_COUNTER); - MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, bulk_n_128); - dcs->obj = mlx5_glue->devx_obj_create(ctx, in, - sizeof(in), out, sizeof(out)); - if (!dcs->obj) { - DRV_LOG(ERR, "Can't allocate counters - error %d", errno); - rte_errno = errno; - rte_free(dcs); - return NULL; - } - dcs->id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id); - return dcs; -} - -/** - * Query flow counters values. - * - * @param[in] dcs - * devx object that was obtained from mlx5_devx_cmd_fc_alloc. - * @param[in] clear - * Whether hardware should clear the counters after the query or not. - * @param[in] n_counters - * 0 in case of 1 counter to read, otherwise the counter number to read. - * @param pkts - * The number of packets that matched the flow. - * @param bytes - * The number of bytes that matched the flow. - * @param mkey - * The mkey key for batch query. - * @param addr - * The address in the mkey range for batch query. - * @param cmd_comp - * The completion object for asynchronous batch query. - * @param async_id - * The ID to be returned in the asynchronous batch query response. - * - * @return - * 0 on success, a negative value otherwise. - */ -int -mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, - int clear, uint32_t n_counters, - uint64_t *pkts, uint64_t *bytes, - uint32_t mkey, void *addr, - struct mlx5dv_devx_cmd_comp *cmd_comp, - uint64_t async_id) -{ - int out_len = MLX5_ST_SZ_BYTES(query_flow_counter_out) + - MLX5_ST_SZ_BYTES(traffic_counter); - uint32_t out[out_len]; - uint32_t in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0}; - void *stats; - int rc; - - MLX5_SET(query_flow_counter_in, in, opcode, - MLX5_CMD_OP_QUERY_FLOW_COUNTER); - MLX5_SET(query_flow_counter_in, in, op_mod, 0); - MLX5_SET(query_flow_counter_in, in, flow_counter_id, dcs->id); - MLX5_SET(query_flow_counter_in, in, clear, !!clear); - - if (n_counters) { - MLX5_SET(query_flow_counter_in, in, num_of_counters, - n_counters); - MLX5_SET(query_flow_counter_in, in, dump_to_memory, 1); - MLX5_SET(query_flow_counter_in, in, mkey, mkey); - MLX5_SET64(query_flow_counter_in, in, address, - (uint64_t)(uintptr_t)addr); - } - if (!cmd_comp) - rc = mlx5_glue->devx_obj_query(dcs->obj, in, sizeof(in), out, - out_len); - else - rc = mlx5_glue->devx_obj_query_async(dcs->obj, in, sizeof(in), - out_len, async_id, - cmd_comp); - if (rc) { - DRV_LOG(ERR, "Failed to query devx counters with rc %d", rc); - rte_errno = rc; - return -rc; - } - if (!n_counters) { - stats = MLX5_ADDR_OF(query_flow_counter_out, - out, flow_statistics); - *pkts = MLX5_GET64(traffic_counter, stats, packets); - *bytes = MLX5_GET64(traffic_counter, stats, octets); - } - return 0; -} - -/** - * Create a new mkey. - * - * @param[in] ctx - * ibv contexts returned from mlx5dv_open_device. - * @param[in] attr - * Attributes of the requested mkey. - * - * @return - * Pointer to Devx mkey on success, a negative value otherwise and rte_errno - * is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, - struct mlx5_devx_mkey_attr *attr) -{ - uint32_t in[MLX5_ST_SZ_DW(create_mkey_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(create_mkey_out)] = {0}; - void *mkc; - struct mlx5_devx_obj *mkey = rte_zmalloc("mkey", sizeof(*mkey), 0); - size_t pgsize; - uint32_t translation_size; - - if (!mkey) { - rte_errno = ENOMEM; - return NULL; - } - pgsize = sysconf(_SC_PAGESIZE); - translation_size = (RTE_ALIGN(attr->size, pgsize) * 8) / 16; - MLX5_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY); - MLX5_SET(create_mkey_in, in, translations_octword_actual_size, - translation_size); - MLX5_SET(create_mkey_in, in, mkey_umem_id, attr->umem_id); - mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); - MLX5_SET(mkc, mkc, lw, 0x1); - MLX5_SET(mkc, mkc, lr, 0x1); - MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT); - MLX5_SET(mkc, mkc, qpn, 0xffffff); - MLX5_SET(mkc, mkc, pd, attr->pd); - MLX5_SET(mkc, mkc, mkey_7_0, attr->umem_id & 0xFF); - MLX5_SET(mkc, mkc, translations_octword_size, translation_size); - MLX5_SET64(mkc, mkc, start_addr, attr->addr); - MLX5_SET64(mkc, mkc, len, attr->size); - MLX5_SET(mkc, mkc, log_page_size, rte_log2_u32(pgsize)); - mkey->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, - sizeof(out)); - if (!mkey->obj) { - DRV_LOG(ERR, "Can't create mkey - error %d", errno); - rte_errno = errno; - rte_free(mkey); - return NULL; - } - mkey->id = MLX5_GET(create_mkey_out, out, mkey_index); - mkey->id = (mkey->id << 8) | (attr->umem_id & 0xFF); - return mkey; -} - -/** - * Get status of devx command response. - * Mainly used for asynchronous commands. - * - * @param[in] out - * The out response buffer. - * - * @return - * 0 on success, non-zero value otherwise. - */ -int -mlx5_devx_get_out_command_status(void *out) -{ - int status; - - if (!out) - return -EINVAL; - status = MLX5_GET(query_flow_counter_out, out, status); - if (status) { - int syndrome = MLX5_GET(query_flow_counter_out, out, syndrome); - - DRV_LOG(ERR, "Bad devX status %x, syndrome = %x", status, - syndrome); - } - return status; -} - -/** - * Destroy any object allocated by a Devx API. - * - * @param[in] obj - * Pointer to a general object. - * - * @return - * 0 on success, a negative value otherwise. - */ -int -mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj) -{ - int ret; - - if (!obj) - return 0; - ret = mlx5_glue->devx_obj_destroy(obj->obj); - rte_free(obj); - return ret; -} - -/** - * Query NIC vport context. - * Fills minimal inline attribute. - * - * @param[in] ctx - * ibv contexts returned from mlx5dv_open_device. - * @param[in] vport - * vport index - * @param[out] attr - * Attributes device values. - * - * @return - * 0 on success, a negative value otherwise. - */ -static int -mlx5_devx_cmd_query_nic_vport_context(struct ibv_context *ctx, - unsigned int vport, - struct mlx5_hca_attr *attr) -{ - uint32_t in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0}; - void *vctx; - int status, syndrome, rc; - - /* Query NIC vport context to determine inline mode. */ - MLX5_SET(query_nic_vport_context_in, in, opcode, - MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT); - MLX5_SET(query_nic_vport_context_in, in, vport_number, vport); - if (vport) - MLX5_SET(query_nic_vport_context_in, in, other_vport, 1); - rc = mlx5_glue->devx_general_cmd(ctx, - in, sizeof(in), - out, sizeof(out)); - if (rc) - goto error; - status = MLX5_GET(query_nic_vport_context_out, out, status); - syndrome = MLX5_GET(query_nic_vport_context_out, out, syndrome); - if (status) { - DRV_LOG(DEBUG, "Failed to query NIC vport context, " - "status %x, syndrome = %x", - status, syndrome); - return -1; - } - vctx = MLX5_ADDR_OF(query_nic_vport_context_out, out, - nic_vport_context); - attr->vport_inline_mode = MLX5_GET(nic_vport_context, vctx, - min_wqe_inline_mode); - return 0; -error: - rc = (rc > 0) ? -rc : rc; - return rc; -} - -/** - * Query HCA attributes. - * Using those attributes we can check on run time if the device - * is having the required capabilities. - * - * @param[in] ctx - * ibv contexts returned from mlx5dv_open_device. - * @param[out] attr - * Attributes device values. - * - * @return - * 0 on success, a negative value otherwise. - */ -int -mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, - struct mlx5_hca_attr *attr) -{ - uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; - void *hcattr; - int status, syndrome, rc; - - MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); - MLX5_SET(query_hca_cap_in, in, op_mod, - MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE | - MLX5_HCA_CAP_OPMOD_GET_CUR); - - rc = mlx5_glue->devx_general_cmd(ctx, - in, sizeof(in), out, sizeof(out)); - if (rc) - goto error; - status = MLX5_GET(query_hca_cap_out, out, status); - syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); - if (status) { - DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, " - "status %x, syndrome = %x", - status, syndrome); - return -1; - } - hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); - attr->flow_counter_bulk_alloc_bitmap = - MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc); - attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, - flow_counters_dump); - attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager); - attr->hairpin = MLX5_GET(cmd_hca_cap, hcattr, hairpin); - attr->log_max_hairpin_queues = MLX5_GET(cmd_hca_cap, hcattr, - log_max_hairpin_queues); - attr->log_max_hairpin_wq_data_sz = MLX5_GET(cmd_hca_cap, hcattr, - log_max_hairpin_wq_data_sz); - attr->log_max_hairpin_num_packets = MLX5_GET - (cmd_hca_cap, hcattr, log_min_hairpin_wq_data_sz); - attr->vhca_id = MLX5_GET(cmd_hca_cap, hcattr, vhca_id); - attr->eth_net_offloads = MLX5_GET(cmd_hca_cap, hcattr, - eth_net_offloads); - attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); - attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, - flex_parser_protocols); - attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); - if (attr->qos.sup) { - MLX5_SET(query_hca_cap_in, in, op_mod, - MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | - MLX5_HCA_CAP_OPMOD_GET_CUR); - rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), - out, sizeof(out)); - if (rc) - goto error; - if (status) { - DRV_LOG(DEBUG, "Failed to query devx QOS capabilities," - " status %x, syndrome = %x", - status, syndrome); - return -1; - } - hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); - attr->qos.srtcm_sup = - MLX5_GET(qos_cap, hcattr, flow_meter_srtcm); - attr->qos.log_max_flow_meter = - MLX5_GET(qos_cap, hcattr, log_max_flow_meter); - attr->qos.flow_meter_reg_c_ids = - MLX5_GET(qos_cap, hcattr, flow_meter_reg_id); - attr->qos.flow_meter_reg_share = - MLX5_GET(qos_cap, hcattr, flow_meter_reg_share); - } - if (!attr->eth_net_offloads) - return 0; - - /* Query HCA offloads for Ethernet protocol. */ - memset(in, 0, sizeof(in)); - memset(out, 0, sizeof(out)); - MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); - MLX5_SET(query_hca_cap_in, in, op_mod, - MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS | - MLX5_HCA_CAP_OPMOD_GET_CUR); - - rc = mlx5_glue->devx_general_cmd(ctx, - in, sizeof(in), - out, sizeof(out)); - if (rc) { - attr->eth_net_offloads = 0; - goto error; - } - status = MLX5_GET(query_hca_cap_out, out, status); - syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); - if (status) { - DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, " - "status %x, syndrome = %x", - status, syndrome); - attr->eth_net_offloads = 0; - return -1; - } - hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); - attr->wqe_vlan_insert = MLX5_GET(per_protocol_networking_offload_caps, - hcattr, wqe_vlan_insert); - attr->lro_cap = MLX5_GET(per_protocol_networking_offload_caps, hcattr, - lro_cap); - attr->tunnel_lro_gre = MLX5_GET(per_protocol_networking_offload_caps, - hcattr, tunnel_lro_gre); - attr->tunnel_lro_vxlan = MLX5_GET(per_protocol_networking_offload_caps, - hcattr, tunnel_lro_vxlan); - attr->lro_max_msg_sz_mode = MLX5_GET - (per_protocol_networking_offload_caps, - hcattr, lro_max_msg_sz_mode); - for (int i = 0 ; i < MLX5_LRO_NUM_SUPP_PERIODS ; i++) { - attr->lro_timer_supported_periods[i] = - MLX5_GET(per_protocol_networking_offload_caps, hcattr, - lro_timer_supported_periods[i]); - } - attr->tunnel_stateless_geneve_rx = - MLX5_GET(per_protocol_networking_offload_caps, - hcattr, tunnel_stateless_geneve_rx); - attr->geneve_max_opt_len = - MLX5_GET(per_protocol_networking_offload_caps, - hcattr, max_geneve_opt_len); - attr->wqe_inline_mode = MLX5_GET(per_protocol_networking_offload_caps, - hcattr, wqe_inline_mode); - attr->tunnel_stateless_gtp = MLX5_GET - (per_protocol_networking_offload_caps, - hcattr, tunnel_stateless_gtp); - if (attr->wqe_inline_mode != MLX5_CAP_INLINE_MODE_VPORT_CONTEXT) - return 0; - if (attr->eth_virt) { - rc = mlx5_devx_cmd_query_nic_vport_context(ctx, 0, attr); - if (rc) { - attr->eth_virt = 0; - goto error; - } - } - return 0; -error: - rc = (rc > 0) ? -rc : rc; - return rc; -} - -/** - * Query TIS transport domain from QP verbs object using DevX API. - * - * @param[in] qp - * Pointer to verbs QP returned by ibv_create_qp . - * @param[in] tis_num - * TIS number of TIS to query. - * @param[out] tis_td - * Pointer to TIS transport domain variable, to be set by the routine. - * - * @return - * 0 on success, a negative value otherwise. - */ -int -mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, - uint32_t *tis_td) -{ - uint32_t in[MLX5_ST_SZ_DW(query_tis_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(query_tis_out)] = {0}; - int rc; - void *tis_ctx; - - MLX5_SET(query_tis_in, in, opcode, MLX5_CMD_OP_QUERY_TIS); - MLX5_SET(query_tis_in, in, tisn, tis_num); - rc = mlx5_glue->devx_qp_query(qp, in, sizeof(in), out, sizeof(out)); - if (rc) { - DRV_LOG(ERR, "Failed to query QP using DevX"); - return -rc; - }; - tis_ctx = MLX5_ADDR_OF(query_tis_out, out, tis_context); - *tis_td = MLX5_GET(tisc, tis_ctx, transport_domain); - return 0; -} - -/** - * Fill WQ data for DevX API command. - * Utility function for use when creating DevX objects containing a WQ. - * - * @param[in] wq_ctx - * Pointer to WQ context to fill with data. - * @param [in] wq_attr - * Pointer to WQ attributes structure to fill in WQ context. - */ -static void -devx_cmd_fill_wq_data(void *wq_ctx, struct mlx5_devx_wq_attr *wq_attr) -{ - MLX5_SET(wq, wq_ctx, wq_type, wq_attr->wq_type); - MLX5_SET(wq, wq_ctx, wq_signature, wq_attr->wq_signature); - MLX5_SET(wq, wq_ctx, end_padding_mode, wq_attr->end_padding_mode); - MLX5_SET(wq, wq_ctx, cd_slave, wq_attr->cd_slave); - MLX5_SET(wq, wq_ctx, hds_skip_first_sge, wq_attr->hds_skip_first_sge); - MLX5_SET(wq, wq_ctx, log2_hds_buf_size, wq_attr->log2_hds_buf_size); - MLX5_SET(wq, wq_ctx, page_offset, wq_attr->page_offset); - MLX5_SET(wq, wq_ctx, lwm, wq_attr->lwm); - MLX5_SET(wq, wq_ctx, pd, wq_attr->pd); - MLX5_SET(wq, wq_ctx, uar_page, wq_attr->uar_page); - MLX5_SET64(wq, wq_ctx, dbr_addr, wq_attr->dbr_addr); - MLX5_SET(wq, wq_ctx, hw_counter, wq_attr->hw_counter); - MLX5_SET(wq, wq_ctx, sw_counter, wq_attr->sw_counter); - MLX5_SET(wq, wq_ctx, log_wq_stride, wq_attr->log_wq_stride); - MLX5_SET(wq, wq_ctx, log_wq_pg_sz, wq_attr->log_wq_pg_sz); - MLX5_SET(wq, wq_ctx, log_wq_sz, wq_attr->log_wq_sz); - MLX5_SET(wq, wq_ctx, dbr_umem_valid, wq_attr->dbr_umem_valid); - MLX5_SET(wq, wq_ctx, wq_umem_valid, wq_attr->wq_umem_valid); - MLX5_SET(wq, wq_ctx, log_hairpin_num_packets, - wq_attr->log_hairpin_num_packets); - MLX5_SET(wq, wq_ctx, log_hairpin_data_sz, wq_attr->log_hairpin_data_sz); - MLX5_SET(wq, wq_ctx, single_wqe_log_num_of_strides, - wq_attr->single_wqe_log_num_of_strides); - MLX5_SET(wq, wq_ctx, two_byte_shift_en, wq_attr->two_byte_shift_en); - MLX5_SET(wq, wq_ctx, single_stride_log_num_of_bytes, - wq_attr->single_stride_log_num_of_bytes); - MLX5_SET(wq, wq_ctx, dbr_umem_id, wq_attr->dbr_umem_id); - MLX5_SET(wq, wq_ctx, wq_umem_id, wq_attr->wq_umem_id); - MLX5_SET64(wq, wq_ctx, wq_umem_offset, wq_attr->wq_umem_offset); -} - -/** - * Create RQ using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * @param [in] rq_attr - * Pointer to create RQ attributes structure. - * @param [in] socket - * CPU socket ID for allocations. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_rq(struct ibv_context *ctx, - struct mlx5_devx_create_rq_attr *rq_attr, - int socket) -{ - uint32_t in[MLX5_ST_SZ_DW(create_rq_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(create_rq_out)] = {0}; - void *rq_ctx, *wq_ctx; - struct mlx5_devx_wq_attr *wq_attr; - struct mlx5_devx_obj *rq = NULL; - - rq = rte_calloc_socket(__func__, 1, sizeof(*rq), 0, socket); - if (!rq) { - DRV_LOG(ERR, "Failed to allocate RQ data"); - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ); - rq_ctx = MLX5_ADDR_OF(create_rq_in, in, ctx); - MLX5_SET(rqc, rq_ctx, rlky, rq_attr->rlky); - MLX5_SET(rqc, rq_ctx, delay_drop_en, rq_attr->delay_drop_en); - MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); - MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); - MLX5_SET(rqc, rq_ctx, mem_rq_type, rq_attr->mem_rq_type); - MLX5_SET(rqc, rq_ctx, state, rq_attr->state); - MLX5_SET(rqc, rq_ctx, flush_in_error_en, rq_attr->flush_in_error_en); - MLX5_SET(rqc, rq_ctx, hairpin, rq_attr->hairpin); - MLX5_SET(rqc, rq_ctx, user_index, rq_attr->user_index); - MLX5_SET(rqc, rq_ctx, cqn, rq_attr->cqn); - MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); - MLX5_SET(rqc, rq_ctx, rmpn, rq_attr->rmpn); - wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); - wq_attr = &rq_attr->wq_attr; - devx_cmd_fill_wq_data(wq_ctx, wq_attr); - rq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), - out, sizeof(out)); - if (!rq->obj) { - DRV_LOG(ERR, "Failed to create RQ using DevX"); - rte_errno = errno; - rte_free(rq); - return NULL; - } - rq->id = MLX5_GET(create_rq_out, out, rqn); - return rq; -} - -/** - * Modify RQ using DevX API. - * - * @param[in] rq - * Pointer to RQ object structure. - * @param [in] rq_attr - * Pointer to modify RQ attributes structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, - struct mlx5_devx_modify_rq_attr *rq_attr) -{ - uint32_t in[MLX5_ST_SZ_DW(modify_rq_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(modify_rq_out)] = {0}; - void *rq_ctx, *wq_ctx; - int ret; - - MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ); - MLX5_SET(modify_rq_in, in, rq_state, rq_attr->rq_state); - MLX5_SET(modify_rq_in, in, rqn, rq->id); - MLX5_SET64(modify_rq_in, in, modify_bitmask, rq_attr->modify_bitmask); - rq_ctx = MLX5_ADDR_OF(modify_rq_in, in, ctx); - MLX5_SET(rqc, rq_ctx, state, rq_attr->state); - if (rq_attr->modify_bitmask & - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS) - MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); - if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD) - MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); - if (rq_attr->modify_bitmask & - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID) - MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); - MLX5_SET(rqc, rq_ctx, hairpin_peer_sq, rq_attr->hairpin_peer_sq); - MLX5_SET(rqc, rq_ctx, hairpin_peer_vhca, rq_attr->hairpin_peer_vhca); - if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM) { - wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); - MLX5_SET(wq, wq_ctx, lwm, rq_attr->lwm); - } - ret = mlx5_glue->devx_obj_modify(rq->obj, in, sizeof(in), - out, sizeof(out)); - if (ret) { - DRV_LOG(ERR, "Failed to modify RQ using DevX"); - rte_errno = errno; - return -errno; - } - return ret; -} - -/** - * Create TIR using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * @param [in] tir_attr - * Pointer to TIR attributes structure. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_tir(struct ibv_context *ctx, - struct mlx5_devx_tir_attr *tir_attr) -{ - uint32_t in[MLX5_ST_SZ_DW(create_tir_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(create_tir_out)] = {0}; - void *tir_ctx, *outer, *inner; - struct mlx5_devx_obj *tir = NULL; - int i; - - tir = rte_calloc(__func__, 1, sizeof(*tir), 0); - if (!tir) { - DRV_LOG(ERR, "Failed to allocate TIR data"); - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); - tir_ctx = MLX5_ADDR_OF(create_tir_in, in, ctx); - MLX5_SET(tirc, tir_ctx, disp_type, tir_attr->disp_type); - MLX5_SET(tirc, tir_ctx, lro_timeout_period_usecs, - tir_attr->lro_timeout_period_usecs); - MLX5_SET(tirc, tir_ctx, lro_enable_mask, tir_attr->lro_enable_mask); - MLX5_SET(tirc, tir_ctx, lro_max_msg_sz, tir_attr->lro_max_msg_sz); - MLX5_SET(tirc, tir_ctx, inline_rqn, tir_attr->inline_rqn); - MLX5_SET(tirc, tir_ctx, rx_hash_symmetric, tir_attr->rx_hash_symmetric); - MLX5_SET(tirc, tir_ctx, tunneled_offload_en, - tir_attr->tunneled_offload_en); - MLX5_SET(tirc, tir_ctx, indirect_table, tir_attr->indirect_table); - MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn); - MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block); - MLX5_SET(tirc, tir_ctx, transport_domain, tir_attr->transport_domain); - for (i = 0; i < 10; i++) { - MLX5_SET(tirc, tir_ctx, rx_hash_toeplitz_key[i], - tir_attr->rx_hash_toeplitz_key[i]); - } - outer = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_outer); - MLX5_SET(rx_hash_field_select, outer, l3_prot_type, - tir_attr->rx_hash_field_selector_outer.l3_prot_type); - MLX5_SET(rx_hash_field_select, outer, l4_prot_type, - tir_attr->rx_hash_field_selector_outer.l4_prot_type); - MLX5_SET(rx_hash_field_select, outer, selected_fields, - tir_attr->rx_hash_field_selector_outer.selected_fields); - inner = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_inner); - MLX5_SET(rx_hash_field_select, inner, l3_prot_type, - tir_attr->rx_hash_field_selector_inner.l3_prot_type); - MLX5_SET(rx_hash_field_select, inner, l4_prot_type, - tir_attr->rx_hash_field_selector_inner.l4_prot_type); - MLX5_SET(rx_hash_field_select, inner, selected_fields, - tir_attr->rx_hash_field_selector_inner.selected_fields); - tir->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), - out, sizeof(out)); - if (!tir->obj) { - DRV_LOG(ERR, "Failed to create TIR using DevX"); - rte_errno = errno; - rte_free(tir); - return NULL; - } - tir->id = MLX5_GET(create_tir_out, out, tirn); - return tir; -} - -/** - * Create RQT using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * @param [in] rqt_attr - * Pointer to RQT attributes structure. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, - struct mlx5_devx_rqt_attr *rqt_attr) -{ - uint32_t *in = NULL; - uint32_t inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + - rqt_attr->rqt_actual_size * sizeof(uint32_t); - uint32_t out[MLX5_ST_SZ_DW(create_rqt_out)] = {0}; - void *rqt_ctx; - struct mlx5_devx_obj *rqt = NULL; - int i; - - in = rte_calloc(__func__, 1, inlen, 0); - if (!in) { - DRV_LOG(ERR, "Failed to allocate RQT IN data"); - rte_errno = ENOMEM; - return NULL; - } - rqt = rte_calloc(__func__, 1, sizeof(*rqt), 0); - if (!rqt) { - DRV_LOG(ERR, "Failed to allocate RQT data"); - rte_errno = ENOMEM; - rte_free(in); - return NULL; - } - MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT); - rqt_ctx = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); - MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size); - MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size); - for (i = 0; i < rqt_attr->rqt_actual_size; i++) - MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]); - rqt->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out)); - rte_free(in); - if (!rqt->obj) { - DRV_LOG(ERR, "Failed to create RQT using DevX"); - rte_errno = errno; - rte_free(rqt); - return NULL; - } - rqt->id = MLX5_GET(create_rqt_out, out, rqtn); - return rqt; -} - -/** - * Create SQ using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * @param [in] sq_attr - * Pointer to SQ attributes structure. - * @param [in] socket - * CPU socket ID for allocations. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - **/ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_sq(struct ibv_context *ctx, - struct mlx5_devx_create_sq_attr *sq_attr) -{ - uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0}; - void *sq_ctx; - void *wq_ctx; - struct mlx5_devx_wq_attr *wq_attr; - struct mlx5_devx_obj *sq = NULL; - - sq = rte_calloc(__func__, 1, sizeof(*sq), 0); - if (!sq) { - DRV_LOG(ERR, "Failed to allocate SQ data"); - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ); - sq_ctx = MLX5_ADDR_OF(create_sq_in, in, ctx); - MLX5_SET(sqc, sq_ctx, rlky, sq_attr->rlky); - MLX5_SET(sqc, sq_ctx, cd_master, sq_attr->cd_master); - MLX5_SET(sqc, sq_ctx, fre, sq_attr->fre); - MLX5_SET(sqc, sq_ctx, flush_in_error_en, sq_attr->flush_in_error_en); - MLX5_SET(sqc, sq_ctx, allow_multi_pkt_send_wqe, - sq_attr->flush_in_error_en); - MLX5_SET(sqc, sq_ctx, min_wqe_inline_mode, - sq_attr->min_wqe_inline_mode); - MLX5_SET(sqc, sq_ctx, state, sq_attr->state); - MLX5_SET(sqc, sq_ctx, reg_umr, sq_attr->reg_umr); - MLX5_SET(sqc, sq_ctx, allow_swp, sq_attr->allow_swp); - MLX5_SET(sqc, sq_ctx, hairpin, sq_attr->hairpin); - MLX5_SET(sqc, sq_ctx, user_index, sq_attr->user_index); - MLX5_SET(sqc, sq_ctx, cqn, sq_attr->cqn); - MLX5_SET(sqc, sq_ctx, packet_pacing_rate_limit_index, - sq_attr->packet_pacing_rate_limit_index); - MLX5_SET(sqc, sq_ctx, tis_lst_sz, sq_attr->tis_lst_sz); - MLX5_SET(sqc, sq_ctx, tis_num_0, sq_attr->tis_num); - wq_ctx = MLX5_ADDR_OF(sqc, sq_ctx, wq); - wq_attr = &sq_attr->wq_attr; - devx_cmd_fill_wq_data(wq_ctx, wq_attr); - sq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), - out, sizeof(out)); - if (!sq->obj) { - DRV_LOG(ERR, "Failed to create SQ using DevX"); - rte_errno = errno; - rte_free(sq); - return NULL; - } - sq->id = MLX5_GET(create_sq_out, out, sqn); - return sq; -} - -/** - * Modify SQ using DevX API. - * - * @param[in] sq - * Pointer to SQ object structure. - * @param [in] sq_attr - * Pointer to SQ attributes structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, - struct mlx5_devx_modify_sq_attr *sq_attr) -{ - uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0}; - void *sq_ctx; - int ret; - - MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); - MLX5_SET(modify_sq_in, in, sq_state, sq_attr->sq_state); - MLX5_SET(modify_sq_in, in, sqn, sq->id); - sq_ctx = MLX5_ADDR_OF(modify_sq_in, in, ctx); - MLX5_SET(sqc, sq_ctx, state, sq_attr->state); - MLX5_SET(sqc, sq_ctx, hairpin_peer_rq, sq_attr->hairpin_peer_rq); - MLX5_SET(sqc, sq_ctx, hairpin_peer_vhca, sq_attr->hairpin_peer_vhca); - ret = mlx5_glue->devx_obj_modify(sq->obj, in, sizeof(in), - out, sizeof(out)); - if (ret) { - DRV_LOG(ERR, "Failed to modify SQ using DevX"); - rte_errno = errno; - return -errno; - } - return ret; -} - -/** - * Create TIS using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * @param [in] tis_attr - * Pointer to TIS attributes structure. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_tis(struct ibv_context *ctx, - struct mlx5_devx_tis_attr *tis_attr) -{ - uint32_t in[MLX5_ST_SZ_DW(create_tis_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(create_tis_out)] = {0}; - struct mlx5_devx_obj *tis = NULL; - void *tis_ctx; - - tis = rte_calloc(__func__, 1, sizeof(*tis), 0); - if (!tis) { - DRV_LOG(ERR, "Failed to allocate TIS object"); - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS); - tis_ctx = MLX5_ADDR_OF(create_tis_in, in, ctx); - MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, - tis_attr->strict_lag_tx_port_affinity); - MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, - tis_attr->strict_lag_tx_port_affinity); - MLX5_SET(tisc, tis_ctx, prio, tis_attr->prio); - MLX5_SET(tisc, tis_ctx, transport_domain, - tis_attr->transport_domain); - tis->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), - out, sizeof(out)); - if (!tis->obj) { - DRV_LOG(ERR, "Failed to create TIS using DevX"); - rte_errno = errno; - rte_free(tis); - return NULL; - } - tis->id = MLX5_GET(create_tis_out, out, tisn); - return tis; -} - -/** - * Create transport domain using DevX API. - * - * @param[in] ctx - * ibv_context returned from mlx5dv_open_device. - * - * @return - * The DevX object created, NULL otherwise and rte_errno is set. - */ -struct mlx5_devx_obj * -mlx5_devx_cmd_create_td(struct ibv_context *ctx) -{ - uint32_t in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {0}; - uint32_t out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0}; - struct mlx5_devx_obj *td = NULL; - - td = rte_calloc(__func__, 1, sizeof(*td), 0); - if (!td) { - DRV_LOG(ERR, "Failed to allocate TD object"); - rte_errno = ENOMEM; - return NULL; - } - MLX5_SET(alloc_transport_domain_in, in, opcode, - MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN); - td->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), - out, sizeof(out)); - if (!td->obj) { - DRV_LOG(ERR, "Failed to create TIS using DevX"); - rte_errno = errno; - rte_free(td); - return NULL; - } - td->id = MLX5_GET(alloc_transport_domain_out, out, - transport_domain); - return td; -} - -/** - * Dump all flows to file. - * - * @param[in] fdb_domain - * FDB domain. - * @param[in] rx_domain - * RX domain. - * @param[in] tx_domain - * TX domain. - * @param[out] file - * Pointer to file stream. - * - * @return - * 0 on success, a nagative value otherwise. - */ -int -mlx5_devx_cmd_flow_dump(void *fdb_domain __rte_unused, - void *rx_domain __rte_unused, - void *tx_domain __rte_unused, FILE *file __rte_unused) -{ - int ret = 0; - -#ifdef HAVE_MLX5_DR_FLOW_DUMP - if (fdb_domain) { - ret = mlx5_glue->dr_dump_domain(file, fdb_domain); - if (ret) - return ret; - } - assert(rx_domain); - ret = mlx5_glue->dr_dump_domain(file, rx_domain); - if (ret) - return ret; - assert(tx_domain); - ret = mlx5_glue->dr_dump_domain(file, tx_domain); -#else - ret = ENOTSUP; -#endif - return -ret; -} diff --git a/drivers/net/mlx5/mlx5_devx_cmds.h b/drivers/net/mlx5/mlx5_devx_cmds.h deleted file mode 100644 index 2d58d96..0000000 --- a/drivers/net/mlx5/mlx5_devx_cmds.h +++ /dev/null @@ -1,231 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2019 Mellanox Technologies, Ltd - */ - -#ifndef RTE_PMD_MLX5_DEVX_CMDS_H_ -#define RTE_PMD_MLX5_DEVX_CMDS_H_ - -#include "mlx5_glue.h" - - -/* devX creation object */ -struct mlx5_devx_obj { - struct mlx5dv_devx_obj *obj; /* The DV object. */ - int id; /* The object ID. */ -}; - -struct mlx5_devx_mkey_attr { - uint64_t addr; - uint64_t size; - uint32_t umem_id; - uint32_t pd; -}; - -/* HCA qos attributes. */ -struct mlx5_hca_qos_attr { - uint32_t sup:1; /* Whether QOS is supported. */ - uint32_t srtcm_sup:1; /* Whether srTCM mode is supported. */ - uint32_t flow_meter_reg_share:1; - /* Whether reg_c share is supported. */ - uint8_t log_max_flow_meter; - /* Power of the maximum supported meters. */ - uint8_t flow_meter_reg_c_ids; - /* Bitmap of the reg_Cs available for flow meter to use. */ - -}; - -/* HCA supports this number of time periods for LRO. */ -#define MLX5_LRO_NUM_SUPP_PERIODS 4 - -/* HCA attributes. */ -struct mlx5_hca_attr { - uint32_t eswitch_manager:1; - uint32_t flow_counters_dump:1; - uint8_t flow_counter_bulk_alloc_bitmap; - uint32_t eth_net_offloads:1; - uint32_t eth_virt:1; - uint32_t wqe_vlan_insert:1; - uint32_t wqe_inline_mode:2; - uint32_t vport_inline_mode:3; - uint32_t tunnel_stateless_geneve_rx:1; - uint32_t geneve_max_opt_len:1; /* 0x0: 14DW, 0x1: 63DW */ - uint32_t tunnel_stateless_gtp:1; - uint32_t lro_cap:1; - uint32_t tunnel_lro_gre:1; - uint32_t tunnel_lro_vxlan:1; - uint32_t lro_max_msg_sz_mode:2; - uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; - uint32_t flex_parser_protocols; - uint32_t hairpin:1; - uint32_t log_max_hairpin_queues:5; - uint32_t log_max_hairpin_wq_data_sz:5; - uint32_t log_max_hairpin_num_packets:5; - uint32_t vhca_id:16; - struct mlx5_hca_qos_attr qos; -}; - -struct mlx5_devx_wq_attr { - uint32_t wq_type:4; - uint32_t wq_signature:1; - uint32_t end_padding_mode:2; - uint32_t cd_slave:1; - uint32_t hds_skip_first_sge:1; - uint32_t log2_hds_buf_size:3; - uint32_t page_offset:5; - uint32_t lwm:16; - uint32_t pd:24; - uint32_t uar_page:24; - uint64_t dbr_addr; - uint32_t hw_counter; - uint32_t sw_counter; - uint32_t log_wq_stride:4; - uint32_t log_wq_pg_sz:5; - uint32_t log_wq_sz:5; - uint32_t dbr_umem_valid:1; - uint32_t wq_umem_valid:1; - uint32_t log_hairpin_num_packets:5; - uint32_t log_hairpin_data_sz:5; - uint32_t single_wqe_log_num_of_strides:4; - uint32_t two_byte_shift_en:1; - uint32_t single_stride_log_num_of_bytes:3; - uint32_t dbr_umem_id; - uint32_t wq_umem_id; - uint64_t wq_umem_offset; -}; - -/* Create RQ attributes structure, used by create RQ operation. */ -struct mlx5_devx_create_rq_attr { - uint32_t rlky:1; - uint32_t delay_drop_en:1; - uint32_t scatter_fcs:1; - uint32_t vsd:1; - uint32_t mem_rq_type:4; - uint32_t state:4; - uint32_t flush_in_error_en:1; - uint32_t hairpin:1; - uint32_t user_index:24; - uint32_t cqn:24; - uint32_t counter_set_id:8; - uint32_t rmpn:24; - struct mlx5_devx_wq_attr wq_attr; -}; - -/* Modify RQ attributes structure, used by modify RQ operation. */ -struct mlx5_devx_modify_rq_attr { - uint32_t rqn:24; - uint32_t rq_state:4; /* Current RQ state. */ - uint32_t state:4; /* Required RQ state. */ - uint32_t scatter_fcs:1; - uint32_t vsd:1; - uint32_t counter_set_id:8; - uint32_t hairpin_peer_sq:24; - uint32_t hairpin_peer_vhca:16; - uint64_t modify_bitmask; - uint32_t lwm:16; /* Contained WQ lwm. */ -}; - -struct mlx5_rx_hash_field_select { - uint32_t l3_prot_type:1; - uint32_t l4_prot_type:1; - uint32_t selected_fields:30; -}; - -/* TIR attributes structure, used by TIR operations. */ -struct mlx5_devx_tir_attr { - uint32_t disp_type:4; - uint32_t lro_timeout_period_usecs:16; - uint32_t lro_enable_mask:4; - uint32_t lro_max_msg_sz:8; - uint32_t inline_rqn:24; - uint32_t rx_hash_symmetric:1; - uint32_t tunneled_offload_en:1; - uint32_t indirect_table:24; - uint32_t rx_hash_fn:4; - uint32_t self_lb_block:2; - uint32_t transport_domain:24; - uint32_t rx_hash_toeplitz_key[10]; - struct mlx5_rx_hash_field_select rx_hash_field_selector_outer; - struct mlx5_rx_hash_field_select rx_hash_field_selector_inner; -}; - -/* RQT attributes structure, used by RQT operations. */ -struct mlx5_devx_rqt_attr { - uint32_t rqt_max_size:16; - uint32_t rqt_actual_size:16; - uint32_t rq_list[]; -}; - -/* TIS attributes structure. */ -struct mlx5_devx_tis_attr { - uint32_t strict_lag_tx_port_affinity:1; - uint32_t tls_en:1; - uint32_t lag_tx_port_affinity:4; - uint32_t prio:4; - uint32_t transport_domain:24; -}; - -/* SQ attributes structure, used by SQ create operation. */ -struct mlx5_devx_create_sq_attr { - uint32_t rlky:1; - uint32_t cd_master:1; - uint32_t fre:1; - uint32_t flush_in_error_en:1; - uint32_t allow_multi_pkt_send_wqe:1; - uint32_t min_wqe_inline_mode:3; - uint32_t state:4; - uint32_t reg_umr:1; - uint32_t allow_swp:1; - uint32_t hairpin:1; - uint32_t user_index:24; - uint32_t cqn:24; - uint32_t packet_pacing_rate_limit_index:16; - uint32_t tis_lst_sz:16; - uint32_t tis_num:24; - struct mlx5_devx_wq_attr wq_attr; -}; - -/* SQ attributes structure, used by SQ modify operation. */ -struct mlx5_devx_modify_sq_attr { - uint32_t sq_state:4; - uint32_t state:4; - uint32_t hairpin_peer_rq:24; - uint32_t hairpin_peer_vhca:16; -}; - -/* mlx5_devx_cmds.c */ - -struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, - uint32_t bulk_sz); -int mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj); -int mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, - int clear, uint32_t n_counters, - uint64_t *pkts, uint64_t *bytes, - uint32_t mkey, void *addr, - struct mlx5dv_devx_cmd_comp *cmd_comp, - uint64_t async_id); -int mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, - struct mlx5_hca_attr *attr); -struct mlx5_devx_obj *mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, - struct mlx5_devx_mkey_attr *attr); -int mlx5_devx_get_out_command_status(void *out); -int mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, - uint32_t *tis_td); -struct mlx5_devx_obj *mlx5_devx_cmd_create_rq(struct ibv_context *ctx, - struct mlx5_devx_create_rq_attr *rq_attr, - int socket); -int mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, - struct mlx5_devx_modify_rq_attr *rq_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_tir(struct ibv_context *ctx, - struct mlx5_devx_tir_attr *tir_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, - struct mlx5_devx_rqt_attr *rqt_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_sq(struct ibv_context *ctx, - struct mlx5_devx_create_sq_attr *sq_attr); -int mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, - struct mlx5_devx_modify_sq_attr *sq_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_tis(struct ibv_context *ctx, - struct mlx5_devx_tis_attr *tis_attr); -struct mlx5_devx_obj *mlx5_devx_cmd_create_td(struct ibv_context *ctx); -int mlx5_devx_cmd_flow_dump(void *fdb_domain, void *rx_domain, void *tx_domain, - FILE *file); -#endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index ce0109c..eddf888 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -36,9 +36,10 @@ #include #include +#include +#include + #include "mlx5.h" -#include "mlx5_glue.h" -#include "mlx5_devx_cmds.h" #include "mlx5_rxtx.h" #include "mlx5_utils.h" diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 983b1c3..47ba521 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -27,12 +27,13 @@ #include #include -#include "mlx5.h" +#include +#include +#include + #include "mlx5_defs.h" +#include "mlx5.h" #include "mlx5_flow.h" -#include "mlx5_glue.h" -#include "mlx5_devx_cmds.h" -#include "mlx5_prm.h" #include "mlx5_rxtx.h" /* Dev ops structure defined in mlx5.c */ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 39be5ba..4255472 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -25,8 +25,9 @@ #include #include +#include + #include "mlx5.h" -#include "mlx5_prm.h" /* Private rte flow items. */ enum mlx5_rte_flow_item_type { diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 653d649..1b31602 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -29,12 +29,13 @@ #include #include -#include "mlx5.h" +#include +#include +#include + #include "mlx5_defs.h" -#include "mlx5_glue.h" -#include "mlx5_devx_cmds.h" +#include "mlx5.h" #include "mlx5_flow.h" -#include "mlx5_prm.h" #include "mlx5_rxtx.h" #ifdef HAVE_IBV_FLOW_DV_SUPPORT diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index c4d28b2..32d51c0 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -9,6 +9,8 @@ #include #include +#include + #include "mlx5.h" #include "mlx5_flow.h" diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c index 72fb1e4..9231451 100644 --- a/drivers/net/mlx5/mlx5_flow_verbs.c +++ b/drivers/net/mlx5/mlx5_flow_verbs.c @@ -26,11 +26,12 @@ #include #include -#include "mlx5.h" +#include +#include + #include "mlx5_defs.h" +#include "mlx5.h" #include "mlx5_flow.h" -#include "mlx5_glue.h" -#include "mlx5_prm.h" #include "mlx5_rxtx.h" #define VERBS_SPEC_INNER(item_flags) \ diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c deleted file mode 100644 index 4906eeb..0000000 --- a/drivers/net/mlx5/mlx5_glue.c +++ /dev/null @@ -1,1150 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include - -/* - * Not needed by this file; included to work around the lack of off_t - * definition for mlx5dv.h with unpatched rdma-core versions. - */ -#include - -/* Verbs headers do not support -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -#include -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - -#include - -#include "mlx5_autoconf.h" -#include "mlx5_glue.h" - -static int -mlx5_glue_fork_init(void) -{ - return ibv_fork_init(); -} - -static struct ibv_pd * -mlx5_glue_alloc_pd(struct ibv_context *context) -{ - return ibv_alloc_pd(context); -} - -static int -mlx5_glue_dealloc_pd(struct ibv_pd *pd) -{ - return ibv_dealloc_pd(pd); -} - -static struct ibv_device ** -mlx5_glue_get_device_list(int *num_devices) -{ - return ibv_get_device_list(num_devices); -} - -static void -mlx5_glue_free_device_list(struct ibv_device **list) -{ - ibv_free_device_list(list); -} - -static struct ibv_context * -mlx5_glue_open_device(struct ibv_device *device) -{ - return ibv_open_device(device); -} - -static int -mlx5_glue_close_device(struct ibv_context *context) -{ - return ibv_close_device(context); -} - -static int -mlx5_glue_query_device(struct ibv_context *context, - struct ibv_device_attr *device_attr) -{ - return ibv_query_device(context, device_attr); -} - -static int -mlx5_glue_query_device_ex(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr) -{ - return ibv_query_device_ex(context, input, attr); -} - -static int -mlx5_glue_query_rt_values_ex(struct ibv_context *context, - struct ibv_values_ex *values) -{ - return ibv_query_rt_values_ex(context, values); -} - -static int -mlx5_glue_query_port(struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr) -{ - return ibv_query_port(context, port_num, port_attr); -} - -static struct ibv_comp_channel * -mlx5_glue_create_comp_channel(struct ibv_context *context) -{ - return ibv_create_comp_channel(context); -} - -static int -mlx5_glue_destroy_comp_channel(struct ibv_comp_channel *channel) -{ - return ibv_destroy_comp_channel(channel); -} - -static struct ibv_cq * -mlx5_glue_create_cq(struct ibv_context *context, int cqe, void *cq_context, - struct ibv_comp_channel *channel, int comp_vector) -{ - return ibv_create_cq(context, cqe, cq_context, channel, comp_vector); -} - -static int -mlx5_glue_destroy_cq(struct ibv_cq *cq) -{ - return ibv_destroy_cq(cq); -} - -static int -mlx5_glue_get_cq_event(struct ibv_comp_channel *channel, struct ibv_cq **cq, - void **cq_context) -{ - return ibv_get_cq_event(channel, cq, cq_context); -} - -static void -mlx5_glue_ack_cq_events(struct ibv_cq *cq, unsigned int nevents) -{ - ibv_ack_cq_events(cq, nevents); -} - -static struct ibv_rwq_ind_table * -mlx5_glue_create_rwq_ind_table(struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr) -{ - return ibv_create_rwq_ind_table(context, init_attr); -} - -static int -mlx5_glue_destroy_rwq_ind_table(struct ibv_rwq_ind_table *rwq_ind_table) -{ - return ibv_destroy_rwq_ind_table(rwq_ind_table); -} - -static struct ibv_wq * -mlx5_glue_create_wq(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr) -{ - return ibv_create_wq(context, wq_init_attr); -} - -static int -mlx5_glue_destroy_wq(struct ibv_wq *wq) -{ - return ibv_destroy_wq(wq); -} -static int -mlx5_glue_modify_wq(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr) -{ - return ibv_modify_wq(wq, wq_attr); -} - -static struct ibv_flow * -mlx5_glue_create_flow(struct ibv_qp *qp, struct ibv_flow_attr *flow) -{ - return ibv_create_flow(qp, flow); -} - -static int -mlx5_glue_destroy_flow(struct ibv_flow *flow_id) -{ - return ibv_destroy_flow(flow_id); -} - -static int -mlx5_glue_destroy_flow_action(void *action) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_destroy(action); -#else - struct mlx5dv_flow_action_attr *attr = action; - int res = 0; - switch (attr->type) { - case MLX5DV_FLOW_ACTION_TAG: - break; - default: - res = ibv_destroy_flow_action(attr->action); - break; - } - free(action); - return res; -#endif -#else - (void)action; - return ENOTSUP; -#endif -} - -static struct ibv_qp * -mlx5_glue_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) -{ - return ibv_create_qp(pd, qp_init_attr); -} - -static struct ibv_qp * -mlx5_glue_create_qp_ex(struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex) -{ - return ibv_create_qp_ex(context, qp_init_attr_ex); -} - -static int -mlx5_glue_destroy_qp(struct ibv_qp *qp) -{ - return ibv_destroy_qp(qp); -} - -static int -mlx5_glue_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask) -{ - return ibv_modify_qp(qp, attr, attr_mask); -} - -static struct ibv_mr * -mlx5_glue_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access) -{ - return ibv_reg_mr(pd, addr, length, access); -} - -static int -mlx5_glue_dereg_mr(struct ibv_mr *mr) -{ - return ibv_dereg_mr(mr); -} - -static struct ibv_counter_set * -mlx5_glue_create_counter_set(struct ibv_context *context, - struct ibv_counter_set_init_attr *init_attr) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)context; - (void)init_attr; - return NULL; -#else - return ibv_create_counter_set(context, init_attr); -#endif -} - -static int -mlx5_glue_destroy_counter_set(struct ibv_counter_set *cs) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)cs; - return ENOTSUP; -#else - return ibv_destroy_counter_set(cs); -#endif -} - -static int -mlx5_glue_describe_counter_set(struct ibv_context *context, - uint16_t counter_set_id, - struct ibv_counter_set_description *cs_desc) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)context; - (void)counter_set_id; - (void)cs_desc; - return ENOTSUP; -#else - return ibv_describe_counter_set(context, counter_set_id, cs_desc); -#endif -} - -static int -mlx5_glue_query_counter_set(struct ibv_query_counter_set_attr *query_attr, - struct ibv_counter_set_data *cs_data) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 - (void)query_attr; - (void)cs_data; - return ENOTSUP; -#else - return ibv_query_counter_set(query_attr, cs_data); -#endif -} - -static struct ibv_counters * -mlx5_glue_create_counters(struct ibv_context *context, - struct ibv_counters_init_attr *init_attr) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)context; - (void)init_attr; - errno = ENOTSUP; - return NULL; -#else - return ibv_create_counters(context, init_attr); -#endif -} - -static int -mlx5_glue_destroy_counters(struct ibv_counters *counters) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - return ENOTSUP; -#else - return ibv_destroy_counters(counters); -#endif -} - -static int -mlx5_glue_attach_counters(struct ibv_counters *counters, - struct ibv_counter_attach_attr *attr, - struct ibv_flow *flow) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - (void)attr; - (void)flow; - return ENOTSUP; -#else - return ibv_attach_counters_point_flow(counters, attr, flow); -#endif -} - -static int -mlx5_glue_query_counters(struct ibv_counters *counters, - uint64_t *counters_value, - uint32_t ncounters, - uint32_t flags) -{ -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 - (void)counters; - (void)counters_value; - (void)ncounters; - (void)flags; - return ENOTSUP; -#else - return ibv_read_counters(counters, counters_value, ncounters, flags); -#endif -} - -static void -mlx5_glue_ack_async_event(struct ibv_async_event *event) -{ - ibv_ack_async_event(event); -} - -static int -mlx5_glue_get_async_event(struct ibv_context *context, - struct ibv_async_event *event) -{ - return ibv_get_async_event(context, event); -} - -static const char * -mlx5_glue_port_state_str(enum ibv_port_state port_state) -{ - return ibv_port_state_str(port_state); -} - -static struct ibv_cq * -mlx5_glue_cq_ex_to_cq(struct ibv_cq_ex *cq) -{ - return ibv_cq_ex_to_cq(cq); -} - -static void * -mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_dest_table(tbl); -#else - (void)tbl; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_dest_port(void *domain, uint32_t port) -{ -#ifdef HAVE_MLX5DV_DR_DEVX_PORT - return mlx5dv_dr_action_create_dest_ib_port(domain, port); -#else -#ifdef HAVE_MLX5DV_DR_ESWITCH - return mlx5dv_dr_action_create_dest_vport(domain, port); -#else - (void)domain; - (void)port; - errno = ENOTSUP; - return NULL; -#endif -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_drop(void) -{ -#ifdef HAVE_MLX5DV_DR_ESWITCH - return mlx5dv_dr_action_create_drop(); -#else - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_push_vlan(struct mlx5dv_dr_domain *domain, - rte_be32_t vlan_tag) -{ -#ifdef HAVE_MLX5DV_DR_VLAN - return mlx5dv_dr_action_create_push_vlan(domain, vlan_tag); -#else - (void)domain; - (void)vlan_tag; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_action_pop_vlan(void) -{ -#ifdef HAVE_MLX5DV_DR_VLAN - return mlx5dv_dr_action_create_pop_vlan(); -#else - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_table_create(domain, level); -#else - (void)domain; - (void)level; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dr_destroy_flow_tbl(void *tbl) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_table_destroy(tbl); -#else - (void)tbl; - errno = ENOTSUP; - return errno; -#endif -} - -static void * -mlx5_glue_dr_create_domain(struct ibv_context *ctx, - enum mlx5dv_dr_domain_type domain) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_domain_create(ctx, domain); -#else - (void)ctx; - (void)domain; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dr_destroy_domain(void *domain) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_domain_destroy(domain); -#else - (void)domain; - errno = ENOTSUP; - return errno; -#endif -} - -static struct ibv_cq_ex * -mlx5_glue_dv_create_cq(struct ibv_context *context, - struct ibv_cq_init_attr_ex *cq_attr, - struct mlx5dv_cq_init_attr *mlx5_cq_attr) -{ - return mlx5dv_create_cq(context, cq_attr, mlx5_cq_attr); -} - -static struct ibv_wq * -mlx5_glue_dv_create_wq(struct ibv_context *context, - struct ibv_wq_init_attr *wq_attr, - struct mlx5dv_wq_init_attr *mlx5_wq_attr) -{ -#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT - (void)context; - (void)wq_attr; - (void)mlx5_wq_attr; - errno = ENOTSUP; - return NULL; -#else - return mlx5dv_create_wq(context, wq_attr, mlx5_wq_attr); -#endif -} - -static int -mlx5_glue_dv_query_device(struct ibv_context *ctx, - struct mlx5dv_context *attrs_out) -{ - return mlx5dv_query_device(ctx, attrs_out); -} - -static int -mlx5_glue_dv_set_context_attr(struct ibv_context *ibv_ctx, - enum mlx5dv_set_ctx_attr_type type, void *attr) -{ - return mlx5dv_set_context_attr(ibv_ctx, type, attr); -} - -static int -mlx5_glue_dv_init_obj(struct mlx5dv_obj *obj, uint64_t obj_type) -{ - return mlx5dv_init_obj(obj, obj_type); -} - -static struct ibv_qp * -mlx5_glue_dv_create_qp(struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex, - struct mlx5dv_qp_init_attr *dv_qp_init_attr) -{ -#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT - return mlx5dv_create_qp(context, qp_init_attr_ex, dv_qp_init_attr); -#else - (void)context; - (void)qp_init_attr_ex; - (void)dv_qp_init_attr; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_matcher(struct ibv_context *context, - struct mlx5dv_flow_matcher_attr *matcher_attr, - void *tbl) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)context; - return mlx5dv_dr_matcher_create(tbl, matcher_attr->priority, - matcher_attr->match_criteria_enable, - matcher_attr->match_mask); -#else - (void)tbl; - return mlx5dv_create_flow_matcher(context, matcher_attr); -#endif -#else - (void)context; - (void)matcher_attr; - (void)tbl; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow(void *matcher, - void *match_value, - size_t num_actions, - void *actions[]) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_rule_create(matcher, match_value, num_actions, - (struct mlx5dv_dr_action **)actions); -#else - struct mlx5dv_flow_action_attr actions_attr[8]; - - if (num_actions > 8) - return NULL; - for (size_t i = 0; i < num_actions; i++) - actions_attr[i] = - *((struct mlx5dv_flow_action_attr *)(actions[i])); - return mlx5dv_create_flow(matcher, match_value, - num_actions, actions_attr); -#endif -#else - (void)matcher; - (void)match_value; - (void)num_actions; - (void)actions; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_counter(void *counter_obj, uint32_t offset) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_flow_counter(counter_obj, offset); -#else - struct mlx5dv_flow_action_attr *action; - - (void)offset; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_COUNTERS_DEVX; - action->obj = counter_obj; - return action; -#endif -#else - (void)counter_obj; - (void)offset; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_dest_ibv_qp(void *qp) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_dest_ibv_qp(qp); -#else - struct mlx5dv_flow_action_attr *action; - - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_DEST_IBV_QP; - action->obj = qp; - return action; -#endif -#else - (void)qp; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_dest_devx_tir(void *tir) -{ -#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR - return mlx5dv_dr_action_create_dest_devx_tir(tir); -#else - (void)tir; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_modify_header - (struct ibv_context *ctx, - enum mlx5dv_flow_table_type ft_type, - void *domain, uint64_t flags, - size_t actions_sz, - uint64_t actions[]) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)ctx; - (void)ft_type; - return mlx5dv_dr_action_create_modify_header(domain, flags, actions_sz, - (__be64 *)actions); -#else - struct mlx5dv_flow_action_attr *action; - - (void)domain; - (void)flags; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - action->action = mlx5dv_create_flow_action_modify_header - (ctx, actions_sz, actions, ft_type); - return action; -#endif -#else - (void)ctx; - (void)ft_type; - (void)domain; - (void)flags; - (void)actions_sz; - (void)actions; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_packet_reformat - (struct ibv_context *ctx, - enum mlx5dv_flow_action_packet_reformat_type reformat_type, - enum mlx5dv_flow_table_type ft_type, - struct mlx5dv_dr_domain *domain, - uint32_t flags, size_t data_sz, void *data) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - (void)ctx; - (void)ft_type; - return mlx5dv_dr_action_create_packet_reformat(domain, flags, - reformat_type, data_sz, - data); -#else - (void)domain; - (void)flags; - struct mlx5dv_flow_action_attr *action; - - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - action->action = mlx5dv_create_flow_action_packet_reformat - (ctx, data_sz, data, reformat_type, ft_type); - return action; -#endif -#else - (void)ctx; - (void)reformat_type; - (void)ft_type; - (void)domain; - (void)flags; - (void)data_sz; - (void)data; - errno = ENOTSUP; - return NULL; -#endif -} - -static void * -mlx5_glue_dv_create_flow_action_tag(uint32_t tag) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_action_create_tag(tag); -#else - struct mlx5dv_flow_action_attr *action; - action = malloc(sizeof(*action)); - if (!action) - return NULL; - action->type = MLX5DV_FLOW_ACTION_TAG; - action->tag_value = tag; - return action; -#endif -#endif - (void)tag; - errno = ENOTSUP; - return NULL; -} - -static void * -mlx5_glue_dv_create_flow_action_meter(struct mlx5dv_dr_flow_meter_attr *attr) -{ -#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) - return mlx5dv_dr_action_create_flow_meter(attr); -#else - (void)attr; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_dv_modify_flow_action_meter(void *action, - struct mlx5dv_dr_flow_meter_attr *attr, - uint64_t modify_bits) -{ -#if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) - return mlx5dv_dr_action_modify_flow_meter(action, attr, modify_bits); -#else - (void)action; - (void)attr; - (void)modify_bits; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_dv_destroy_flow(void *flow_id) -{ -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_rule_destroy(flow_id); -#else - return ibv_destroy_flow(flow_id); -#endif -} - -static int -mlx5_glue_dv_destroy_flow_matcher(void *matcher) -{ -#ifdef HAVE_IBV_FLOW_DV_SUPPORT -#ifdef HAVE_MLX5DV_DR - return mlx5dv_dr_matcher_destroy(matcher); -#else - return mlx5dv_destroy_flow_matcher(matcher); -#endif -#else - (void)matcher; - errno = ENOTSUP; - return errno; -#endif -} - -static struct ibv_context * -mlx5_glue_dv_open_device(struct ibv_device *device) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_open_device(device, - &(struct mlx5dv_context_attr){ - .flags = MLX5DV_CONTEXT_FLAGS_DEVX, - }); -#else - (void)device; - errno = ENOTSUP; - return NULL; -#endif -} - -static struct mlx5dv_devx_obj * -mlx5_glue_devx_obj_create(struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_create(ctx, in, inlen, out, outlen); -#else - (void)ctx; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - errno = ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_devx_obj_destroy(struct mlx5dv_devx_obj *obj) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_destroy(obj); -#else - (void)obj; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_query(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_query(obj, in, inlen, out, outlen); -#else - (void)obj; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_modify(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_obj_modify(obj, in, inlen, out, outlen); -#else - (void)obj; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_general_cmd(struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_general_cmd(ctx, in, inlen, out, outlen); -#else - (void)ctx; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - return -ENOTSUP; -#endif -} - -static struct mlx5dv_devx_cmd_comp * -mlx5_glue_devx_create_cmd_comp(struct ibv_context *ctx) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_create_cmd_comp(ctx); -#else - (void)ctx; - errno = -ENOTSUP; - return NULL; -#endif -} - -static void -mlx5_glue_devx_destroy_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - mlx5dv_devx_destroy_cmd_comp(cmd_comp); -#else - (void)cmd_comp; - errno = -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_obj_query_async(struct mlx5dv_devx_obj *obj, const void *in, - size_t inlen, size_t outlen, uint64_t wr_id, - struct mlx5dv_devx_cmd_comp *cmd_comp) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_obj_query_async(obj, in, inlen, outlen, wr_id, - cmd_comp); -#else - (void)obj; - (void)in; - (void)inlen; - (void)outlen; - (void)wr_id; - (void)cmd_comp; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_get_async_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp, - struct mlx5dv_devx_async_cmd_hdr *cmd_resp, - size_t cmd_resp_len) -{ -#ifdef HAVE_IBV_DEVX_ASYNC - return mlx5dv_devx_get_async_cmd_comp(cmd_comp, cmd_resp, - cmd_resp_len); -#else - (void)cmd_comp; - (void)cmd_resp; - (void)cmd_resp_len; - return -ENOTSUP; -#endif -} - -static struct mlx5dv_devx_umem * -mlx5_glue_devx_umem_reg(struct ibv_context *context, void *addr, size_t size, - uint32_t access) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_umem_reg(context, addr, size, access); -#else - (void)context; - (void)addr; - (void)size; - (void)access; - errno = -ENOTSUP; - return NULL; -#endif -} - -static int -mlx5_glue_devx_umem_dereg(struct mlx5dv_devx_umem *dv_devx_umem) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_umem_dereg(dv_devx_umem); -#else - (void)dv_devx_umem; - return -ENOTSUP; -#endif -} - -static int -mlx5_glue_devx_qp_query(struct ibv_qp *qp, - const void *in, size_t inlen, - void *out, size_t outlen) -{ -#ifdef HAVE_IBV_DEVX_OBJ - return mlx5dv_devx_qp_query(qp, in, inlen, out, outlen); -#else - (void)qp; - (void)in; - (void)inlen; - (void)out; - (void)outlen; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_devx_port_query(struct ibv_context *ctx, - uint32_t port_num, - struct mlx5dv_devx_port *mlx5_devx_port) -{ -#ifdef HAVE_MLX5DV_DR_DEVX_PORT - return mlx5dv_query_devx_port(ctx, port_num, mlx5_devx_port); -#else - (void)ctx; - (void)port_num; - (void)mlx5_devx_port; - errno = ENOTSUP; - return errno; -#endif -} - -static int -mlx5_glue_dr_dump_domain(FILE *file, void *domain) -{ -#ifdef HAVE_MLX5_DR_FLOW_DUMP - return mlx5dv_dump_dr_domain(file, domain); -#else - RTE_SET_USED(file); - RTE_SET_USED(domain); - return -ENOTSUP; -#endif -} - -alignas(RTE_CACHE_LINE_SIZE) -const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ - .version = MLX5_GLUE_VERSION, - .fork_init = mlx5_glue_fork_init, - .alloc_pd = mlx5_glue_alloc_pd, - .dealloc_pd = mlx5_glue_dealloc_pd, - .get_device_list = mlx5_glue_get_device_list, - .free_device_list = mlx5_glue_free_device_list, - .open_device = mlx5_glue_open_device, - .close_device = mlx5_glue_close_device, - .query_device = mlx5_glue_query_device, - .query_device_ex = mlx5_glue_query_device_ex, - .query_rt_values_ex = mlx5_glue_query_rt_values_ex, - .query_port = mlx5_glue_query_port, - .create_comp_channel = mlx5_glue_create_comp_channel, - .destroy_comp_channel = mlx5_glue_destroy_comp_channel, - .create_cq = mlx5_glue_create_cq, - .destroy_cq = mlx5_glue_destroy_cq, - .get_cq_event = mlx5_glue_get_cq_event, - .ack_cq_events = mlx5_glue_ack_cq_events, - .create_rwq_ind_table = mlx5_glue_create_rwq_ind_table, - .destroy_rwq_ind_table = mlx5_glue_destroy_rwq_ind_table, - .create_wq = mlx5_glue_create_wq, - .destroy_wq = mlx5_glue_destroy_wq, - .modify_wq = mlx5_glue_modify_wq, - .create_flow = mlx5_glue_create_flow, - .destroy_flow = mlx5_glue_destroy_flow, - .destroy_flow_action = mlx5_glue_destroy_flow_action, - .create_qp = mlx5_glue_create_qp, - .create_qp_ex = mlx5_glue_create_qp_ex, - .destroy_qp = mlx5_glue_destroy_qp, - .modify_qp = mlx5_glue_modify_qp, - .reg_mr = mlx5_glue_reg_mr, - .dereg_mr = mlx5_glue_dereg_mr, - .create_counter_set = mlx5_glue_create_counter_set, - .destroy_counter_set = mlx5_glue_destroy_counter_set, - .describe_counter_set = mlx5_glue_describe_counter_set, - .query_counter_set = mlx5_glue_query_counter_set, - .create_counters = mlx5_glue_create_counters, - .destroy_counters = mlx5_glue_destroy_counters, - .attach_counters = mlx5_glue_attach_counters, - .query_counters = mlx5_glue_query_counters, - .ack_async_event = mlx5_glue_ack_async_event, - .get_async_event = mlx5_glue_get_async_event, - .port_state_str = mlx5_glue_port_state_str, - .cq_ex_to_cq = mlx5_glue_cq_ex_to_cq, - .dr_create_flow_action_dest_flow_tbl = - mlx5_glue_dr_create_flow_action_dest_flow_tbl, - .dr_create_flow_action_dest_port = - mlx5_glue_dr_create_flow_action_dest_port, - .dr_create_flow_action_drop = - mlx5_glue_dr_create_flow_action_drop, - .dr_create_flow_action_push_vlan = - mlx5_glue_dr_create_flow_action_push_vlan, - .dr_create_flow_action_pop_vlan = - mlx5_glue_dr_create_flow_action_pop_vlan, - .dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl, - .dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl, - .dr_create_domain = mlx5_glue_dr_create_domain, - .dr_destroy_domain = mlx5_glue_dr_destroy_domain, - .dv_create_cq = mlx5_glue_dv_create_cq, - .dv_create_wq = mlx5_glue_dv_create_wq, - .dv_query_device = mlx5_glue_dv_query_device, - .dv_set_context_attr = mlx5_glue_dv_set_context_attr, - .dv_init_obj = mlx5_glue_dv_init_obj, - .dv_create_qp = mlx5_glue_dv_create_qp, - .dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher, - .dv_create_flow = mlx5_glue_dv_create_flow, - .dv_create_flow_action_counter = - mlx5_glue_dv_create_flow_action_counter, - .dv_create_flow_action_dest_ibv_qp = - mlx5_glue_dv_create_flow_action_dest_ibv_qp, - .dv_create_flow_action_dest_devx_tir = - mlx5_glue_dv_create_flow_action_dest_devx_tir, - .dv_create_flow_action_modify_header = - mlx5_glue_dv_create_flow_action_modify_header, - .dv_create_flow_action_packet_reformat = - mlx5_glue_dv_create_flow_action_packet_reformat, - .dv_create_flow_action_tag = mlx5_glue_dv_create_flow_action_tag, - .dv_create_flow_action_meter = mlx5_glue_dv_create_flow_action_meter, - .dv_modify_flow_action_meter = mlx5_glue_dv_modify_flow_action_meter, - .dv_destroy_flow = mlx5_glue_dv_destroy_flow, - .dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher, - .dv_open_device = mlx5_glue_dv_open_device, - .devx_obj_create = mlx5_glue_devx_obj_create, - .devx_obj_destroy = mlx5_glue_devx_obj_destroy, - .devx_obj_query = mlx5_glue_devx_obj_query, - .devx_obj_modify = mlx5_glue_devx_obj_modify, - .devx_general_cmd = mlx5_glue_devx_general_cmd, - .devx_create_cmd_comp = mlx5_glue_devx_create_cmd_comp, - .devx_destroy_cmd_comp = mlx5_glue_devx_destroy_cmd_comp, - .devx_obj_query_async = mlx5_glue_devx_obj_query_async, - .devx_get_async_cmd_comp = mlx5_glue_devx_get_async_cmd_comp, - .devx_umem_reg = mlx5_glue_devx_umem_reg, - .devx_umem_dereg = mlx5_glue_devx_umem_dereg, - .devx_qp_query = mlx5_glue_devx_qp_query, - .devx_port_query = mlx5_glue_devx_port_query, - .dr_dump_domain = mlx5_glue_dr_dump_domain, -}; diff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h deleted file mode 100644 index 6771a18..0000000 --- a/drivers/net/mlx5/mlx5_glue.h +++ /dev/null @@ -1,264 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#ifndef MLX5_GLUE_H_ -#define MLX5_GLUE_H_ - -#include -#include - -#include "rte_byteorder.h" - -/* Verbs headers do not support -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -#include -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - -#ifndef MLX5_GLUE_VERSION -#define MLX5_GLUE_VERSION "" -#endif - -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V42 -struct ibv_counter_set; -struct ibv_counter_set_data; -struct ibv_counter_set_description; -struct ibv_counter_set_init_attr; -struct ibv_query_counter_set_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_COUNTERS_SET_V45 -struct ibv_counters; -struct ibv_counters_init_attr; -struct ibv_counter_attach_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_TUNNEL_SUPPORT -struct mlx5dv_qp_init_attr; -#endif - -#ifndef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT -struct mlx5dv_wq_init_attr; -#endif - -#ifndef HAVE_IBV_FLOW_DV_SUPPORT -struct mlx5dv_flow_matcher; -struct mlx5dv_flow_matcher_attr; -struct mlx5dv_flow_action_attr; -struct mlx5dv_flow_match_parameters; -struct mlx5dv_dr_flow_meter_attr; -struct ibv_flow_action; -enum mlx5dv_flow_action_packet_reformat_type { packet_reformat_type = 0, }; -enum mlx5dv_flow_table_type { flow_table_type = 0, }; -#endif - -#ifndef HAVE_IBV_FLOW_DEVX_COUNTERS -#define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0 -#endif - -#ifndef HAVE_IBV_DEVX_OBJ -struct mlx5dv_devx_obj; -struct mlx5dv_devx_umem { uint32_t umem_id; }; -#endif - -#ifndef HAVE_IBV_DEVX_ASYNC -struct mlx5dv_devx_cmd_comp; -struct mlx5dv_devx_async_cmd_hdr; -#endif - -#ifndef HAVE_MLX5DV_DR -enum mlx5dv_dr_domain_type { unused, }; -struct mlx5dv_dr_domain; -#endif - -#ifndef HAVE_MLX5DV_DR_DEVX_PORT -struct mlx5dv_devx_port; -#endif - -#ifndef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER -struct mlx5dv_dr_flow_meter_attr; -#endif - -/* LIB_GLUE_VERSION must be updated every time this structure is modified. */ -struct mlx5_glue { - const char *version; - int (*fork_init)(void); - struct ibv_pd *(*alloc_pd)(struct ibv_context *context); - int (*dealloc_pd)(struct ibv_pd *pd); - struct ibv_device **(*get_device_list)(int *num_devices); - void (*free_device_list)(struct ibv_device **list); - struct ibv_context *(*open_device)(struct ibv_device *device); - int (*close_device)(struct ibv_context *context); - int (*query_device)(struct ibv_context *context, - struct ibv_device_attr *device_attr); - int (*query_device_ex)(struct ibv_context *context, - const struct ibv_query_device_ex_input *input, - struct ibv_device_attr_ex *attr); - int (*query_rt_values_ex)(struct ibv_context *context, - struct ibv_values_ex *values); - int (*query_port)(struct ibv_context *context, uint8_t port_num, - struct ibv_port_attr *port_attr); - struct ibv_comp_channel *(*create_comp_channel) - (struct ibv_context *context); - int (*destroy_comp_channel)(struct ibv_comp_channel *channel); - struct ibv_cq *(*create_cq)(struct ibv_context *context, int cqe, - void *cq_context, - struct ibv_comp_channel *channel, - int comp_vector); - int (*destroy_cq)(struct ibv_cq *cq); - int (*get_cq_event)(struct ibv_comp_channel *channel, - struct ibv_cq **cq, void **cq_context); - void (*ack_cq_events)(struct ibv_cq *cq, unsigned int nevents); - struct ibv_rwq_ind_table *(*create_rwq_ind_table) - (struct ibv_context *context, - struct ibv_rwq_ind_table_init_attr *init_attr); - int (*destroy_rwq_ind_table)(struct ibv_rwq_ind_table *rwq_ind_table); - struct ibv_wq *(*create_wq)(struct ibv_context *context, - struct ibv_wq_init_attr *wq_init_attr); - int (*destroy_wq)(struct ibv_wq *wq); - int (*modify_wq)(struct ibv_wq *wq, struct ibv_wq_attr *wq_attr); - struct ibv_flow *(*create_flow)(struct ibv_qp *qp, - struct ibv_flow_attr *flow); - int (*destroy_flow)(struct ibv_flow *flow_id); - int (*destroy_flow_action)(void *action); - struct ibv_qp *(*create_qp)(struct ibv_pd *pd, - struct ibv_qp_init_attr *qp_init_attr); - struct ibv_qp *(*create_qp_ex) - (struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex); - int (*destroy_qp)(struct ibv_qp *qp); - int (*modify_qp)(struct ibv_qp *qp, struct ibv_qp_attr *attr, - int attr_mask); - struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, - size_t length, int access); - int (*dereg_mr)(struct ibv_mr *mr); - struct ibv_counter_set *(*create_counter_set) - (struct ibv_context *context, - struct ibv_counter_set_init_attr *init_attr); - int (*destroy_counter_set)(struct ibv_counter_set *cs); - int (*describe_counter_set) - (struct ibv_context *context, - uint16_t counter_set_id, - struct ibv_counter_set_description *cs_desc); - int (*query_counter_set)(struct ibv_query_counter_set_attr *query_attr, - struct ibv_counter_set_data *cs_data); - struct ibv_counters *(*create_counters) - (struct ibv_context *context, - struct ibv_counters_init_attr *init_attr); - int (*destroy_counters)(struct ibv_counters *counters); - int (*attach_counters)(struct ibv_counters *counters, - struct ibv_counter_attach_attr *attr, - struct ibv_flow *flow); - int (*query_counters)(struct ibv_counters *counters, - uint64_t *counters_value, - uint32_t ncounters, - uint32_t flags); - void (*ack_async_event)(struct ibv_async_event *event); - int (*get_async_event)(struct ibv_context *context, - struct ibv_async_event *event); - const char *(*port_state_str)(enum ibv_port_state port_state); - struct ibv_cq *(*cq_ex_to_cq)(struct ibv_cq_ex *cq); - void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl); - void *(*dr_create_flow_action_dest_port)(void *domain, - uint32_t port); - void *(*dr_create_flow_action_drop)(); - void *(*dr_create_flow_action_push_vlan) - (struct mlx5dv_dr_domain *domain, - rte_be32_t vlan_tag); - void *(*dr_create_flow_action_pop_vlan)(); - void *(*dr_create_flow_tbl)(void *domain, uint32_t level); - int (*dr_destroy_flow_tbl)(void *tbl); - void *(*dr_create_domain)(struct ibv_context *ctx, - enum mlx5dv_dr_domain_type domain); - int (*dr_destroy_domain)(void *domain); - struct ibv_cq_ex *(*dv_create_cq) - (struct ibv_context *context, - struct ibv_cq_init_attr_ex *cq_attr, - struct mlx5dv_cq_init_attr *mlx5_cq_attr); - struct ibv_wq *(*dv_create_wq) - (struct ibv_context *context, - struct ibv_wq_init_attr *wq_attr, - struct mlx5dv_wq_init_attr *mlx5_wq_attr); - int (*dv_query_device)(struct ibv_context *ctx_in, - struct mlx5dv_context *attrs_out); - int (*dv_set_context_attr)(struct ibv_context *ibv_ctx, - enum mlx5dv_set_ctx_attr_type type, - void *attr); - int (*dv_init_obj)(struct mlx5dv_obj *obj, uint64_t obj_type); - struct ibv_qp *(*dv_create_qp) - (struct ibv_context *context, - struct ibv_qp_init_attr_ex *qp_init_attr_ex, - struct mlx5dv_qp_init_attr *dv_qp_init_attr); - void *(*dv_create_flow_matcher) - (struct ibv_context *context, - struct mlx5dv_flow_matcher_attr *matcher_attr, - void *tbl); - void *(*dv_create_flow)(void *matcher, void *match_value, - size_t num_actions, void *actions[]); - void *(*dv_create_flow_action_counter)(void *obj, uint32_t offset); - void *(*dv_create_flow_action_dest_ibv_qp)(void *qp); - void *(*dv_create_flow_action_dest_devx_tir)(void *tir); - void *(*dv_create_flow_action_modify_header) - (struct ibv_context *ctx, enum mlx5dv_flow_table_type ft_type, - void *domain, uint64_t flags, size_t actions_sz, - uint64_t actions[]); - void *(*dv_create_flow_action_packet_reformat) - (struct ibv_context *ctx, - enum mlx5dv_flow_action_packet_reformat_type reformat_type, - enum mlx5dv_flow_table_type ft_type, - struct mlx5dv_dr_domain *domain, - uint32_t flags, size_t data_sz, void *data); - void *(*dv_create_flow_action_tag)(uint32_t tag); - void *(*dv_create_flow_action_meter) - (struct mlx5dv_dr_flow_meter_attr *attr); - int (*dv_modify_flow_action_meter)(void *action, - struct mlx5dv_dr_flow_meter_attr *attr, uint64_t modify_bits); - int (*dv_destroy_flow)(void *flow); - int (*dv_destroy_flow_matcher)(void *matcher); - struct ibv_context *(*dv_open_device)(struct ibv_device *device); - struct mlx5dv_devx_obj *(*devx_obj_create) - (struct ibv_context *ctx, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_obj_destroy)(struct mlx5dv_devx_obj *obj); - int (*devx_obj_query)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_obj_modify)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_general_cmd)(struct ibv_context *context, - const void *in, size_t inlen, - void *out, size_t outlen); - struct mlx5dv_devx_cmd_comp *(*devx_create_cmd_comp) - (struct ibv_context *context); - void (*devx_destroy_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp); - int (*devx_obj_query_async)(struct mlx5dv_devx_obj *obj, - const void *in, size_t inlen, - size_t outlen, uint64_t wr_id, - struct mlx5dv_devx_cmd_comp *cmd_comp); - int (*devx_get_async_cmd_comp)(struct mlx5dv_devx_cmd_comp *cmd_comp, - struct mlx5dv_devx_async_cmd_hdr *resp, - size_t cmd_resp_len); - struct mlx5dv_devx_umem *(*devx_umem_reg)(struct ibv_context *context, - void *addr, size_t size, - uint32_t access); - int (*devx_umem_dereg)(struct mlx5dv_devx_umem *dv_devx_umem); - int (*devx_qp_query)(struct ibv_qp *qp, - const void *in, size_t inlen, - void *out, size_t outlen); - int (*devx_port_query)(struct ibv_context *ctx, - uint32_t port_num, - struct mlx5dv_devx_port *mlx5_devx_port); - int (*dr_dump_domain)(FILE *file, void *domain); -}; - -const struct mlx5_glue *mlx5_glue; - -#endif /* MLX5_GLUE_H_ */ diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c index 7bdaa2a..a646b90 100644 --- a/drivers/net/mlx5/mlx5_mac.c +++ b/drivers/net/mlx5/mlx5_mac.c @@ -27,10 +27,10 @@ #include #include +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" -#include "mlx5_defs.h" /** * Get MAC address by querying netdevice. diff --git a/drivers/net/mlx5/mlx5_mr.c b/drivers/net/mlx5/mlx5_mr.c index 0d549b6..b1cd9f7 100644 --- a/drivers/net/mlx5/mlx5_mr.c +++ b/drivers/net/mlx5/mlx5_mr.c @@ -17,10 +17,11 @@ #include #include +#include + #include "mlx5.h" #include "mlx5_mr.h" #include "mlx5_rxtx.h" -#include "mlx5_glue.h" struct mr_find_contig_memsegs_data { uintptr_t addr; diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h deleted file mode 100644 index 8a67025..0000000 --- a/drivers/net/mlx5/mlx5_prm.h +++ /dev/null @@ -1,1888 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2016 6WIND S.A. - * Copyright 2016 Mellanox Technologies, Ltd - */ - -#ifndef RTE_PMD_MLX5_PRM_H_ -#define RTE_PMD_MLX5_PRM_H_ - -#include - -/* Verbs header. */ -/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -#include -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - -#include -#include "mlx5_autoconf.h" - -/* RSS hash key size. */ -#define MLX5_RSS_HASH_KEY_LEN 40 - -/* Get CQE owner bit. */ -#define MLX5_CQE_OWNER(op_own) ((op_own) & MLX5_CQE_OWNER_MASK) - -/* Get CQE format. */ -#define MLX5_CQE_FORMAT(op_own) (((op_own) & MLX5E_CQE_FORMAT_MASK) >> 2) - -/* Get CQE opcode. */ -#define MLX5_CQE_OPCODE(op_own) (((op_own) & 0xf0) >> 4) - -/* Get CQE solicited event. */ -#define MLX5_CQE_SE(op_own) (((op_own) >> 1) & 1) - -/* Invalidate a CQE. */ -#define MLX5_CQE_INVALIDATE (MLX5_CQE_INVALID << 4) - -/* WQE Segment sizes in bytes. */ -#define MLX5_WSEG_SIZE 16u -#define MLX5_WQE_CSEG_SIZE sizeof(struct mlx5_wqe_cseg) -#define MLX5_WQE_DSEG_SIZE sizeof(struct mlx5_wqe_dseg) -#define MLX5_WQE_ESEG_SIZE sizeof(struct mlx5_wqe_eseg) - -/* WQE/WQEBB size in bytes. */ -#define MLX5_WQE_SIZE sizeof(struct mlx5_wqe) - -/* - * Max size of a WQE session. - * Absolute maximum size is 63 (MLX5_DSEG_MAX) segments, - * the WQE size field in Control Segment is 6 bits wide. - */ -#define MLX5_WQE_SIZE_MAX (60 * MLX5_WSEG_SIZE) - -/* - * Default minimum number of Tx queues for inlining packets. - * If there are less queues as specified we assume we have - * no enough CPU resources (cycles) to perform inlining, - * the PCIe throughput is not supposed as bottleneck and - * inlining is disabled. - */ -#define MLX5_INLINE_MAX_TXQS 8u -#define MLX5_INLINE_MAX_TXQS_BLUEFIELD 16u - -/* - * Default packet length threshold to be inlined with - * enhanced MPW. If packet length exceeds the threshold - * the data are not inlined. Should be aligned in WQEBB - * boundary with accounting the title Control and Ethernet - * segments. - */ -#define MLX5_EMPW_DEF_INLINE_LEN (4u * MLX5_WQE_SIZE + \ - MLX5_DSEG_MIN_INLINE_SIZE) -/* - * Maximal inline data length sent with enhanced MPW. - * Is based on maximal WQE size. - */ -#define MLX5_EMPW_MAX_INLINE_LEN (MLX5_WQE_SIZE_MAX - \ - MLX5_WQE_CSEG_SIZE - \ - MLX5_WQE_ESEG_SIZE - \ - MLX5_WQE_DSEG_SIZE + \ - MLX5_DSEG_MIN_INLINE_SIZE) -/* - * Minimal amount of packets to be sent with EMPW. - * This limits the minimal required size of sent EMPW. - * If there are no enough resources to built minimal - * EMPW the sending loop exits. - */ -#define MLX5_EMPW_MIN_PACKETS (2u + 3u * 4u) -/* - * Maximal amount of packets to be sent with EMPW. - * This value is not recommended to exceed MLX5_TX_COMP_THRESH, - * otherwise there might be up to MLX5_EMPW_MAX_PACKETS mbufs - * without CQE generation request, being multiplied by - * MLX5_TX_COMP_MAX_CQE it may cause significant latency - * in tx burst routine at the moment of freeing multiple mbufs. - */ -#define MLX5_EMPW_MAX_PACKETS MLX5_TX_COMP_THRESH -#define MLX5_MPW_MAX_PACKETS 6 -#define MLX5_MPW_INLINE_MAX_PACKETS 2 - -/* - * Default packet length threshold to be inlined with - * ordinary SEND. Inlining saves the MR key search - * and extra PCIe data fetch transaction, but eats the - * CPU cycles. - */ -#define MLX5_SEND_DEF_INLINE_LEN (5U * MLX5_WQE_SIZE + \ - MLX5_ESEG_MIN_INLINE_SIZE - \ - MLX5_WQE_CSEG_SIZE - \ - MLX5_WQE_ESEG_SIZE - \ - MLX5_WQE_DSEG_SIZE) -/* - * Maximal inline data length sent with ordinary SEND. - * Is based on maximal WQE size. - */ -#define MLX5_SEND_MAX_INLINE_LEN (MLX5_WQE_SIZE_MAX - \ - MLX5_WQE_CSEG_SIZE - \ - MLX5_WQE_ESEG_SIZE - \ - MLX5_WQE_DSEG_SIZE + \ - MLX5_ESEG_MIN_INLINE_SIZE) - -/* Missed in mlv5dv.h, should define here. */ -#define MLX5_OPCODE_ENHANCED_MPSW 0x29u - -/* CQE value to inform that VLAN is stripped. */ -#define MLX5_CQE_VLAN_STRIPPED (1u << 0) - -/* IPv4 options. */ -#define MLX5_CQE_RX_IP_EXT_OPTS_PACKET (1u << 1) - -/* IPv6 packet. */ -#define MLX5_CQE_RX_IPV6_PACKET (1u << 2) - -/* IPv4 packet. */ -#define MLX5_CQE_RX_IPV4_PACKET (1u << 3) - -/* TCP packet. */ -#define MLX5_CQE_RX_TCP_PACKET (1u << 4) - -/* UDP packet. */ -#define MLX5_CQE_RX_UDP_PACKET (1u << 5) - -/* IP is fragmented. */ -#define MLX5_CQE_RX_IP_FRAG_PACKET (1u << 7) - -/* L2 header is valid. */ -#define MLX5_CQE_RX_L2_HDR_VALID (1u << 8) - -/* L3 header is valid. */ -#define MLX5_CQE_RX_L3_HDR_VALID (1u << 9) - -/* L4 header is valid. */ -#define MLX5_CQE_RX_L4_HDR_VALID (1u << 10) - -/* Outer packet, 0 IPv4, 1 IPv6. */ -#define MLX5_CQE_RX_OUTER_PACKET (1u << 1) - -/* Tunnel packet bit in the CQE. */ -#define MLX5_CQE_RX_TUNNEL_PACKET (1u << 0) - -/* Mask for LRO push flag in the CQE lro_tcppsh_abort_dupack field. */ -#define MLX5_CQE_LRO_PUSH_MASK 0x40 - -/* Mask for L4 type in the CQE hdr_type_etc field. */ -#define MLX5_CQE_L4_TYPE_MASK 0x70 - -/* The bit index of L4 type in CQE hdr_type_etc field. */ -#define MLX5_CQE_L4_TYPE_SHIFT 0x4 - -/* L4 type to indicate TCP packet without acknowledgment. */ -#define MLX5_L4_HDR_TYPE_TCP_EMPTY_ACK 0x3 - -/* L4 type to indicate TCP packet with acknowledgment. */ -#define MLX5_L4_HDR_TYPE_TCP_WITH_ACL 0x4 - -/* Inner L3 checksum offload (Tunneled packets only). */ -#define MLX5_ETH_WQE_L3_INNER_CSUM (1u << 4) - -/* Inner L4 checksum offload (Tunneled packets only). */ -#define MLX5_ETH_WQE_L4_INNER_CSUM (1u << 5) - -/* Outer L4 type is TCP. */ -#define MLX5_ETH_WQE_L4_OUTER_TCP (0u << 5) - -/* Outer L4 type is UDP. */ -#define MLX5_ETH_WQE_L4_OUTER_UDP (1u << 5) - -/* Outer L3 type is IPV4. */ -#define MLX5_ETH_WQE_L3_OUTER_IPV4 (0u << 4) - -/* Outer L3 type is IPV6. */ -#define MLX5_ETH_WQE_L3_OUTER_IPV6 (1u << 4) - -/* Inner L4 type is TCP. */ -#define MLX5_ETH_WQE_L4_INNER_TCP (0u << 1) - -/* Inner L4 type is UDP. */ -#define MLX5_ETH_WQE_L4_INNER_UDP (1u << 1) - -/* Inner L3 type is IPV4. */ -#define MLX5_ETH_WQE_L3_INNER_IPV4 (0u << 0) - -/* Inner L3 type is IPV6. */ -#define MLX5_ETH_WQE_L3_INNER_IPV6 (1u << 0) - -/* VLAN insertion flag. */ -#define MLX5_ETH_WQE_VLAN_INSERT (1u << 31) - -/* Data inline segment flag. */ -#define MLX5_ETH_WQE_DATA_INLINE (1u << 31) - -/* Is flow mark valid. */ -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN -#define MLX5_FLOW_MARK_IS_VALID(val) ((val) & 0xffffff00) -#else -#define MLX5_FLOW_MARK_IS_VALID(val) ((val) & 0xffffff) -#endif - -/* INVALID is used by packets matching no flow rules. */ -#define MLX5_FLOW_MARK_INVALID 0 - -/* Maximum allowed value to mark a packet. */ -#define MLX5_FLOW_MARK_MAX 0xfffff0 - -/* Default mark value used when none is provided. */ -#define MLX5_FLOW_MARK_DEFAULT 0xffffff - -/* Default mark mask for metadata legacy mode. */ -#define MLX5_FLOW_MARK_MASK 0xffffff - -/* Maximum number of DS in WQE. Limited by 6-bit field. */ -#define MLX5_DSEG_MAX 63 - -/* The completion mode offset in the WQE control segment line 2. */ -#define MLX5_COMP_MODE_OFFSET 2 - -/* Amount of data bytes in minimal inline data segment. */ -#define MLX5_DSEG_MIN_INLINE_SIZE 12u - -/* Amount of data bytes in minimal inline eth segment. */ -#define MLX5_ESEG_MIN_INLINE_SIZE 18u - -/* Amount of data bytes after eth data segment. */ -#define MLX5_ESEG_EXTRA_DATA_SIZE 32u - -/* The maximum log value of segments per RQ WQE. */ -#define MLX5_MAX_LOG_RQ_SEGS 5u - -/* The alignment needed for WQ buffer. */ -#define MLX5_WQE_BUF_ALIGNMENT 512 - -/* Completion mode. */ -enum mlx5_completion_mode { - MLX5_COMP_ONLY_ERR = 0x0, - MLX5_COMP_ONLY_FIRST_ERR = 0x1, - MLX5_COMP_ALWAYS = 0x2, - MLX5_COMP_CQE_AND_EQE = 0x3, -}; - -/* MPW mode. */ -enum mlx5_mpw_mode { - MLX5_MPW_DISABLED, - MLX5_MPW, - MLX5_MPW_ENHANCED, /* Enhanced Multi-Packet Send WQE, a.k.a MPWv2. */ -}; - -/* WQE Control segment. */ -struct mlx5_wqe_cseg { - uint32_t opcode; - uint32_t sq_ds; - uint32_t flags; - uint32_t misc; -} __rte_packed __rte_aligned(MLX5_WSEG_SIZE); - -/* Header of data segment. Minimal size Data Segment */ -struct mlx5_wqe_dseg { - uint32_t bcount; - union { - uint8_t inline_data[MLX5_DSEG_MIN_INLINE_SIZE]; - struct { - uint32_t lkey; - uint64_t pbuf; - } __rte_packed; - }; -} __rte_packed; - -/* Subset of struct WQE Ethernet Segment. */ -struct mlx5_wqe_eseg { - union { - struct { - uint32_t swp_offs; - uint8_t cs_flags; - uint8_t swp_flags; - uint16_t mss; - uint32_t metadata; - uint16_t inline_hdr_sz; - union { - uint16_t inline_data; - uint16_t vlan_tag; - }; - } __rte_packed; - struct { - uint32_t offsets; - uint32_t flags; - uint32_t flow_metadata; - uint32_t inline_hdr; - } __rte_packed; - }; -} __rte_packed; - -/* The title WQEBB, header of WQE. */ -struct mlx5_wqe { - union { - struct mlx5_wqe_cseg cseg; - uint32_t ctrl[4]; - }; - struct mlx5_wqe_eseg eseg; - union { - struct mlx5_wqe_dseg dseg[2]; - uint8_t data[MLX5_ESEG_EXTRA_DATA_SIZE]; - }; -} __rte_packed; - -/* WQE for Multi-Packet RQ. */ -struct mlx5_wqe_mprq { - struct mlx5_wqe_srq_next_seg next_seg; - struct mlx5_wqe_data_seg dseg; -}; - -#define MLX5_MPRQ_LEN_MASK 0x000ffff -#define MLX5_MPRQ_LEN_SHIFT 0 -#define MLX5_MPRQ_STRIDE_NUM_MASK 0x3fff0000 -#define MLX5_MPRQ_STRIDE_NUM_SHIFT 16 -#define MLX5_MPRQ_FILLER_MASK 0x80000000 -#define MLX5_MPRQ_FILLER_SHIFT 31 - -#define MLX5_MPRQ_STRIDE_SHIFT_BYTE 2 - -/* CQ element structure - should be equal to the cache line size */ -struct mlx5_cqe { -#if (RTE_CACHE_LINE_SIZE == 128) - uint8_t padding[64]; -#endif - uint8_t pkt_info; - uint8_t rsvd0; - uint16_t wqe_id; - uint8_t lro_tcppsh_abort_dupack; - uint8_t lro_min_ttl; - uint16_t lro_tcp_win; - uint32_t lro_ack_seq_num; - uint32_t rx_hash_res; - uint8_t rx_hash_type; - uint8_t rsvd1[3]; - uint16_t csum; - uint8_t rsvd2[6]; - uint16_t hdr_type_etc; - uint16_t vlan_info; - uint8_t lro_num_seg; - uint8_t rsvd3[3]; - uint32_t flow_table_metadata; - uint8_t rsvd4[4]; - uint32_t byte_cnt; - uint64_t timestamp; - uint32_t sop_drop_qpn; - uint16_t wqe_counter; - uint8_t rsvd5; - 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 - -/* Action type of header modification. */ -enum { - MLX5_MODIFICATION_TYPE_SET = 0x1, - MLX5_MODIFICATION_TYPE_ADD = 0x2, - MLX5_MODIFICATION_TYPE_COPY = 0x3, -}; - -/* The field of packet to be modified. */ -enum mlx5_modification_field { - MLX5_MODI_OUT_NONE = -1, - MLX5_MODI_OUT_SMAC_47_16 = 1, - MLX5_MODI_OUT_SMAC_15_0, - MLX5_MODI_OUT_ETHERTYPE, - MLX5_MODI_OUT_DMAC_47_16, - MLX5_MODI_OUT_DMAC_15_0, - MLX5_MODI_OUT_IP_DSCP, - MLX5_MODI_OUT_TCP_FLAGS, - MLX5_MODI_OUT_TCP_SPORT, - MLX5_MODI_OUT_TCP_DPORT, - MLX5_MODI_OUT_IPV4_TTL, - MLX5_MODI_OUT_UDP_SPORT, - MLX5_MODI_OUT_UDP_DPORT, - MLX5_MODI_OUT_SIPV6_127_96, - MLX5_MODI_OUT_SIPV6_95_64, - MLX5_MODI_OUT_SIPV6_63_32, - MLX5_MODI_OUT_SIPV6_31_0, - MLX5_MODI_OUT_DIPV6_127_96, - MLX5_MODI_OUT_DIPV6_95_64, - MLX5_MODI_OUT_DIPV6_63_32, - MLX5_MODI_OUT_DIPV6_31_0, - MLX5_MODI_OUT_SIPV4, - MLX5_MODI_OUT_DIPV4, - MLX5_MODI_OUT_FIRST_VID, - MLX5_MODI_IN_SMAC_47_16 = 0x31, - MLX5_MODI_IN_SMAC_15_0, - MLX5_MODI_IN_ETHERTYPE, - MLX5_MODI_IN_DMAC_47_16, - MLX5_MODI_IN_DMAC_15_0, - MLX5_MODI_IN_IP_DSCP, - MLX5_MODI_IN_TCP_FLAGS, - MLX5_MODI_IN_TCP_SPORT, - MLX5_MODI_IN_TCP_DPORT, - MLX5_MODI_IN_IPV4_TTL, - MLX5_MODI_IN_UDP_SPORT, - MLX5_MODI_IN_UDP_DPORT, - MLX5_MODI_IN_SIPV6_127_96, - MLX5_MODI_IN_SIPV6_95_64, - MLX5_MODI_IN_SIPV6_63_32, - MLX5_MODI_IN_SIPV6_31_0, - MLX5_MODI_IN_DIPV6_127_96, - MLX5_MODI_IN_DIPV6_95_64, - MLX5_MODI_IN_DIPV6_63_32, - MLX5_MODI_IN_DIPV6_31_0, - MLX5_MODI_IN_SIPV4, - MLX5_MODI_IN_DIPV4, - MLX5_MODI_OUT_IPV6_HOPLIMIT, - MLX5_MODI_IN_IPV6_HOPLIMIT, - MLX5_MODI_META_DATA_REG_A, - MLX5_MODI_META_DATA_REG_B = 0x50, - MLX5_MODI_META_REG_C_0, - MLX5_MODI_META_REG_C_1, - MLX5_MODI_META_REG_C_2, - MLX5_MODI_META_REG_C_3, - MLX5_MODI_META_REG_C_4, - MLX5_MODI_META_REG_C_5, - MLX5_MODI_META_REG_C_6, - MLX5_MODI_META_REG_C_7, - MLX5_MODI_OUT_TCP_SEQ_NUM, - MLX5_MODI_IN_TCP_SEQ_NUM, - MLX5_MODI_OUT_TCP_ACK_NUM, - MLX5_MODI_IN_TCP_ACK_NUM = 0x5C, -}; - -/* Total number of metadata reg_c's. */ -#define MLX5_MREG_C_NUM (MLX5_MODI_META_REG_C_7 - MLX5_MODI_META_REG_C_0 + 1) - -enum modify_reg { - REG_NONE = 0, - REG_A, - REG_B, - REG_C_0, - REG_C_1, - REG_C_2, - REG_C_3, - REG_C_4, - REG_C_5, - REG_C_6, - REG_C_7, -}; - -/* Modification sub command. */ -struct mlx5_modification_cmd { - union { - uint32_t data0; - struct { - unsigned int length:5; - unsigned int rsvd0:3; - unsigned int offset:5; - unsigned int rsvd1:3; - unsigned int field:12; - unsigned int action_type:4; - }; - }; - union { - uint32_t data1; - uint8_t data[4]; - struct { - unsigned int rsvd2:8; - unsigned int dst_offset:5; - unsigned int rsvd3:3; - unsigned int dst_field:12; - unsigned int rsvd4:4; - }; - }; -}; - -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -#define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) -#define __mlx5_bit_sz(typ, fld) sizeof(__mlx5_nullp(typ)->fld) -#define __mlx5_bit_off(typ, fld) ((unsigned int)(unsigned long) \ - (&(__mlx5_nullp(typ)->fld))) -#define __mlx5_dw_bit_off(typ, fld) (32 - __mlx5_bit_sz(typ, fld) - \ - (__mlx5_bit_off(typ, fld) & 0x1f)) -#define __mlx5_dw_off(typ, fld) (__mlx5_bit_off(typ, fld) / 32) -#define __mlx5_64_off(typ, fld) (__mlx5_bit_off(typ, fld) / 64) -#define __mlx5_dw_mask(typ, fld) (__mlx5_mask(typ, fld) << \ - __mlx5_dw_bit_off(typ, fld)) -#define __mlx5_mask(typ, fld) ((u32)((1ull << __mlx5_bit_sz(typ, fld)) - 1)) -#define __mlx5_16_off(typ, fld) (__mlx5_bit_off(typ, fld) / 16) -#define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - \ - (__mlx5_bit_off(typ, fld) & 0xf)) -#define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1)) -#define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8) -#define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32) -#define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8) -#define MLX5_ADDR_OF(typ, p, fld) ((char *)(p) + MLX5_BYTE_OFF(typ, fld)) - -/* insert a value to a struct */ -#define MLX5_SET(typ, p, fld, v) \ - do { \ - u32 _v = v; \ - *((__be32 *)(p) + __mlx5_dw_off(typ, fld)) = \ - rte_cpu_to_be_32((rte_be_to_cpu_32(*((u32 *)(p) + \ - __mlx5_dw_off(typ, fld))) & \ - (~__mlx5_dw_mask(typ, fld))) | \ - (((_v) & __mlx5_mask(typ, fld)) << \ - __mlx5_dw_bit_off(typ, fld))); \ - } while (0) - -#define MLX5_SET64(typ, p, fld, v) \ - do { \ - assert(__mlx5_bit_sz(typ, fld) == 64); \ - *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = \ - rte_cpu_to_be_64(v); \ - } while (0) - -#define MLX5_GET(typ, p, fld) \ - ((rte_be_to_cpu_32(*((__be32 *)(p) +\ - __mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \ - __mlx5_mask(typ, fld)) -#define MLX5_GET16(typ, p, fld) \ - ((rte_be_to_cpu_16(*((__be16 *)(p) + \ - __mlx5_16_off(typ, fld))) >> __mlx5_16_bit_off(typ, fld)) & \ - __mlx5_mask16(typ, fld)) -#define MLX5_GET64(typ, p, fld) rte_be_to_cpu_64(*((__be64 *)(p) + \ - __mlx5_64_off(typ, fld))) -#define MLX5_FLD_SZ_BYTES(typ, fld) (__mlx5_bit_sz(typ, fld) / 8) - -struct mlx5_ifc_fte_match_set_misc_bits { - u8 gre_c_present[0x1]; - u8 reserved_at_1[0x1]; - u8 gre_k_present[0x1]; - u8 gre_s_present[0x1]; - u8 source_vhci_port[0x4]; - u8 source_sqn[0x18]; - u8 reserved_at_20[0x10]; - u8 source_port[0x10]; - u8 outer_second_prio[0x3]; - u8 outer_second_cfi[0x1]; - u8 outer_second_vid[0xc]; - u8 inner_second_prio[0x3]; - u8 inner_second_cfi[0x1]; - u8 inner_second_vid[0xc]; - u8 outer_second_cvlan_tag[0x1]; - u8 inner_second_cvlan_tag[0x1]; - u8 outer_second_svlan_tag[0x1]; - u8 inner_second_svlan_tag[0x1]; - u8 reserved_at_64[0xc]; - u8 gre_protocol[0x10]; - u8 gre_key_h[0x18]; - u8 gre_key_l[0x8]; - u8 vxlan_vni[0x18]; - u8 reserved_at_b8[0x8]; - u8 geneve_vni[0x18]; - u8 reserved_at_e4[0x7]; - u8 geneve_oam[0x1]; - u8 reserved_at_e0[0xc]; - u8 outer_ipv6_flow_label[0x14]; - u8 reserved_at_100[0xc]; - u8 inner_ipv6_flow_label[0x14]; - u8 reserved_at_120[0xa]; - u8 geneve_opt_len[0x6]; - u8 geneve_protocol_type[0x10]; - u8 reserved_at_140[0xc0]; -}; - -struct mlx5_ifc_ipv4_layout_bits { - u8 reserved_at_0[0x60]; - u8 ipv4[0x20]; -}; - -struct mlx5_ifc_ipv6_layout_bits { - u8 ipv6[16][0x8]; -}; - -union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits { - struct mlx5_ifc_ipv6_layout_bits ipv6_layout; - struct mlx5_ifc_ipv4_layout_bits ipv4_layout; - u8 reserved_at_0[0x80]; -}; - -struct mlx5_ifc_fte_match_set_lyr_2_4_bits { - u8 smac_47_16[0x20]; - u8 smac_15_0[0x10]; - u8 ethertype[0x10]; - u8 dmac_47_16[0x20]; - u8 dmac_15_0[0x10]; - u8 first_prio[0x3]; - u8 first_cfi[0x1]; - u8 first_vid[0xc]; - u8 ip_protocol[0x8]; - u8 ip_dscp[0x6]; - u8 ip_ecn[0x2]; - u8 cvlan_tag[0x1]; - u8 svlan_tag[0x1]; - u8 frag[0x1]; - u8 ip_version[0x4]; - u8 tcp_flags[0x9]; - u8 tcp_sport[0x10]; - u8 tcp_dport[0x10]; - u8 reserved_at_c0[0x20]; - u8 udp_sport[0x10]; - u8 udp_dport[0x10]; - union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits src_ipv4_src_ipv6; - union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits dst_ipv4_dst_ipv6; -}; - -struct mlx5_ifc_fte_match_mpls_bits { - u8 mpls_label[0x14]; - u8 mpls_exp[0x3]; - u8 mpls_s_bos[0x1]; - u8 mpls_ttl[0x8]; -}; - -struct mlx5_ifc_fte_match_set_misc2_bits { - struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls; - struct mlx5_ifc_fte_match_mpls_bits inner_first_mpls; - struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls_over_gre; - struct mlx5_ifc_fte_match_mpls_bits outer_first_mpls_over_udp; - u8 metadata_reg_c_7[0x20]; - u8 metadata_reg_c_6[0x20]; - u8 metadata_reg_c_5[0x20]; - u8 metadata_reg_c_4[0x20]; - u8 metadata_reg_c_3[0x20]; - u8 metadata_reg_c_2[0x20]; - u8 metadata_reg_c_1[0x20]; - u8 metadata_reg_c_0[0x20]; - u8 metadata_reg_a[0x20]; - u8 metadata_reg_b[0x20]; - u8 reserved_at_1c0[0x40]; -}; - -struct mlx5_ifc_fte_match_set_misc3_bits { - u8 inner_tcp_seq_num[0x20]; - u8 outer_tcp_seq_num[0x20]; - u8 inner_tcp_ack_num[0x20]; - u8 outer_tcp_ack_num[0x20]; - u8 reserved_at_auto1[0x8]; - u8 outer_vxlan_gpe_vni[0x18]; - u8 outer_vxlan_gpe_next_protocol[0x8]; - u8 outer_vxlan_gpe_flags[0x8]; - u8 reserved_at_a8[0x10]; - u8 icmp_header_data[0x20]; - u8 icmpv6_header_data[0x20]; - u8 icmp_type[0x8]; - u8 icmp_code[0x8]; - u8 icmpv6_type[0x8]; - u8 icmpv6_code[0x8]; - u8 reserved_at_120[0x20]; - u8 gtpu_teid[0x20]; - u8 gtpu_msg_type[0x08]; - u8 gtpu_msg_flags[0x08]; - u8 reserved_at_170[0x90]; -}; - -/* Flow matcher. */ -struct mlx5_ifc_fte_match_param_bits { - struct mlx5_ifc_fte_match_set_lyr_2_4_bits outer_headers; - struct mlx5_ifc_fte_match_set_misc_bits misc_parameters; - struct mlx5_ifc_fte_match_set_lyr_2_4_bits inner_headers; - struct mlx5_ifc_fte_match_set_misc2_bits misc_parameters_2; - struct mlx5_ifc_fte_match_set_misc3_bits misc_parameters_3; -}; - -enum { - MLX5_MATCH_CRITERIA_ENABLE_OUTER_BIT, - MLX5_MATCH_CRITERIA_ENABLE_MISC_BIT, - MLX5_MATCH_CRITERIA_ENABLE_INNER_BIT, - MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT, - MLX5_MATCH_CRITERIA_ENABLE_MISC3_BIT -}; - -enum { - MLX5_CMD_OP_QUERY_HCA_CAP = 0x100, - MLX5_CMD_OP_CREATE_MKEY = 0x200, - MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754, - MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN = 0x816, - MLX5_CMD_OP_CREATE_TIR = 0x900, - MLX5_CMD_OP_CREATE_SQ = 0X904, - MLX5_CMD_OP_MODIFY_SQ = 0X905, - MLX5_CMD_OP_CREATE_RQ = 0x908, - MLX5_CMD_OP_MODIFY_RQ = 0x909, - MLX5_CMD_OP_CREATE_TIS = 0x912, - MLX5_CMD_OP_QUERY_TIS = 0x915, - MLX5_CMD_OP_CREATE_RQT = 0x916, - MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939, - MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b, -}; - -enum { - MLX5_MKC_ACCESS_MODE_MTT = 0x1, -}; - -/* Flow counters. */ -struct mlx5_ifc_alloc_flow_counter_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 flow_counter_id[0x20]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_alloc_flow_counter_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 flow_counter_id[0x20]; - u8 reserved_at_40[0x18]; - u8 flow_counter_bulk[0x8]; -}; - -struct mlx5_ifc_dealloc_flow_counter_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; -}; - -struct mlx5_ifc_dealloc_flow_counter_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 flow_counter_id[0x20]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_traffic_counter_bits { - u8 packets[0x40]; - u8 octets[0x40]; -}; - -struct mlx5_ifc_query_flow_counter_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; - struct mlx5_ifc_traffic_counter_bits flow_statistics[]; -}; - -struct mlx5_ifc_query_flow_counter_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0x20]; - u8 mkey[0x20]; - u8 address[0x40]; - u8 clear[0x1]; - u8 dump_to_memory[0x1]; - u8 num_of_counters[0x1e]; - u8 flow_counter_id[0x20]; -}; - -struct mlx5_ifc_mkc_bits { - u8 reserved_at_0[0x1]; - u8 free[0x1]; - u8 reserved_at_2[0x1]; - u8 access_mode_4_2[0x3]; - u8 reserved_at_6[0x7]; - u8 relaxed_ordering_write[0x1]; - u8 reserved_at_e[0x1]; - u8 small_fence_on_rdma_read_response[0x1]; - u8 umr_en[0x1]; - u8 a[0x1]; - u8 rw[0x1]; - u8 rr[0x1]; - u8 lw[0x1]; - u8 lr[0x1]; - u8 access_mode_1_0[0x2]; - u8 reserved_at_18[0x8]; - - u8 qpn[0x18]; - u8 mkey_7_0[0x8]; - - u8 reserved_at_40[0x20]; - - u8 length64[0x1]; - u8 bsf_en[0x1]; - u8 sync_umr[0x1]; - u8 reserved_at_63[0x2]; - u8 expected_sigerr_count[0x1]; - u8 reserved_at_66[0x1]; - u8 en_rinval[0x1]; - u8 pd[0x18]; - - u8 start_addr[0x40]; - - u8 len[0x40]; - - u8 bsf_octword_size[0x20]; - - u8 reserved_at_120[0x80]; - - u8 translations_octword_size[0x20]; - - u8 reserved_at_1c0[0x1b]; - u8 log_page_size[0x5]; - - u8 reserved_at_1e0[0x20]; -}; - -struct mlx5_ifc_create_mkey_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - - u8 syndrome[0x20]; - - u8 reserved_at_40[0x8]; - u8 mkey_index[0x18]; - - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_create_mkey_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - - u8 reserved_at_40[0x20]; - - u8 pg_access[0x1]; - u8 reserved_at_61[0x1f]; - - struct mlx5_ifc_mkc_bits memory_key_mkey_entry; - - u8 reserved_at_280[0x80]; - - u8 translations_octword_actual_size[0x20]; - - u8 mkey_umem_id[0x20]; - - u8 mkey_umem_offset[0x40]; - - u8 reserved_at_380[0x500]; - - u8 klm_pas_mtt[][0x20]; -}; - -enum { - MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0 << 1, - MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS = 0x1 << 1, - MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP = 0xc << 1, -}; - -enum { - MLX5_HCA_CAP_OPMOD_GET_MAX = 0, - MLX5_HCA_CAP_OPMOD_GET_CUR = 1, -}; - -enum { - MLX5_CAP_INLINE_MODE_L2, - MLX5_CAP_INLINE_MODE_VPORT_CONTEXT, - MLX5_CAP_INLINE_MODE_NOT_REQUIRED, -}; - -enum { - MLX5_INLINE_MODE_NONE, - MLX5_INLINE_MODE_L2, - MLX5_INLINE_MODE_IP, - MLX5_INLINE_MODE_TCP_UDP, - MLX5_INLINE_MODE_RESERVED4, - MLX5_INLINE_MODE_INNER_L2, - MLX5_INLINE_MODE_INNER_IP, - MLX5_INLINE_MODE_INNER_TCP_UDP, -}; - -/* HCA bit masks indicating which Flex parser protocols are already enabled. */ -#define MLX5_HCA_FLEX_IPV4_OVER_VXLAN_ENABLED (1UL << 0) -#define MLX5_HCA_FLEX_IPV6_OVER_VXLAN_ENABLED (1UL << 1) -#define MLX5_HCA_FLEX_IPV6_OVER_IP_ENABLED (1UL << 2) -#define MLX5_HCA_FLEX_GENEVE_ENABLED (1UL << 3) -#define MLX5_HCA_FLEX_CW_MPLS_OVER_GRE_ENABLED (1UL << 4) -#define MLX5_HCA_FLEX_CW_MPLS_OVER_UDP_ENABLED (1UL << 5) -#define MLX5_HCA_FLEX_P_BIT_VXLAN_GPE_ENABLED (1UL << 6) -#define MLX5_HCA_FLEX_VXLAN_GPE_ENABLED (1UL << 7) -#define MLX5_HCA_FLEX_ICMP_ENABLED (1UL << 8) -#define MLX5_HCA_FLEX_ICMPV6_ENABLED (1UL << 9) - -struct mlx5_ifc_cmd_hca_cap_bits { - u8 reserved_at_0[0x30]; - u8 vhca_id[0x10]; - u8 reserved_at_40[0x40]; - u8 log_max_srq_sz[0x8]; - u8 log_max_qp_sz[0x8]; - u8 reserved_at_90[0xb]; - u8 log_max_qp[0x5]; - u8 reserved_at_a0[0xb]; - u8 log_max_srq[0x5]; - u8 reserved_at_b0[0x10]; - u8 reserved_at_c0[0x8]; - u8 log_max_cq_sz[0x8]; - u8 reserved_at_d0[0xb]; - u8 log_max_cq[0x5]; - u8 log_max_eq_sz[0x8]; - u8 reserved_at_e8[0x2]; - u8 log_max_mkey[0x6]; - u8 reserved_at_f0[0x8]; - u8 dump_fill_mkey[0x1]; - u8 reserved_at_f9[0x3]; - u8 log_max_eq[0x4]; - u8 max_indirection[0x8]; - u8 fixed_buffer_size[0x1]; - u8 log_max_mrw_sz[0x7]; - u8 force_teardown[0x1]; - u8 reserved_at_111[0x1]; - u8 log_max_bsf_list_size[0x6]; - u8 umr_extended_translation_offset[0x1]; - u8 null_mkey[0x1]; - u8 log_max_klm_list_size[0x6]; - u8 reserved_at_120[0xa]; - u8 log_max_ra_req_dc[0x6]; - u8 reserved_at_130[0xa]; - u8 log_max_ra_res_dc[0x6]; - u8 reserved_at_140[0xa]; - u8 log_max_ra_req_qp[0x6]; - u8 reserved_at_150[0xa]; - u8 log_max_ra_res_qp[0x6]; - u8 end_pad[0x1]; - u8 cc_query_allowed[0x1]; - u8 cc_modify_allowed[0x1]; - u8 start_pad[0x1]; - u8 cache_line_128byte[0x1]; - u8 reserved_at_165[0xa]; - u8 qcam_reg[0x1]; - u8 gid_table_size[0x10]; - u8 out_of_seq_cnt[0x1]; - u8 vport_counters[0x1]; - u8 retransmission_q_counters[0x1]; - u8 debug[0x1]; - u8 modify_rq_counter_set_id[0x1]; - u8 rq_delay_drop[0x1]; - u8 max_qp_cnt[0xa]; - u8 pkey_table_size[0x10]; - u8 vport_group_manager[0x1]; - u8 vhca_group_manager[0x1]; - u8 ib_virt[0x1]; - u8 eth_virt[0x1]; - u8 vnic_env_queue_counters[0x1]; - u8 ets[0x1]; - u8 nic_flow_table[0x1]; - u8 eswitch_manager[0x1]; - u8 device_memory[0x1]; - u8 mcam_reg[0x1]; - u8 pcam_reg[0x1]; - u8 local_ca_ack_delay[0x5]; - u8 port_module_event[0x1]; - u8 enhanced_error_q_counters[0x1]; - u8 ports_check[0x1]; - u8 reserved_at_1b3[0x1]; - u8 disable_link_up[0x1]; - u8 beacon_led[0x1]; - u8 port_type[0x2]; - u8 num_ports[0x8]; - u8 reserved_at_1c0[0x1]; - u8 pps[0x1]; - u8 pps_modify[0x1]; - u8 log_max_msg[0x5]; - u8 reserved_at_1c8[0x4]; - u8 max_tc[0x4]; - u8 temp_warn_event[0x1]; - u8 dcbx[0x1]; - u8 general_notification_event[0x1]; - u8 reserved_at_1d3[0x2]; - u8 fpga[0x1]; - u8 rol_s[0x1]; - u8 rol_g[0x1]; - u8 reserved_at_1d8[0x1]; - u8 wol_s[0x1]; - u8 wol_g[0x1]; - u8 wol_a[0x1]; - u8 wol_b[0x1]; - u8 wol_m[0x1]; - u8 wol_u[0x1]; - u8 wol_p[0x1]; - u8 stat_rate_support[0x10]; - u8 reserved_at_1f0[0xc]; - u8 cqe_version[0x4]; - u8 compact_address_vector[0x1]; - u8 striding_rq[0x1]; - u8 reserved_at_202[0x1]; - u8 ipoib_enhanced_offloads[0x1]; - u8 ipoib_basic_offloads[0x1]; - u8 reserved_at_205[0x1]; - u8 repeated_block_disabled[0x1]; - u8 umr_modify_entity_size_disabled[0x1]; - u8 umr_modify_atomic_disabled[0x1]; - u8 umr_indirect_mkey_disabled[0x1]; - u8 umr_fence[0x2]; - u8 reserved_at_20c[0x3]; - u8 drain_sigerr[0x1]; - u8 cmdif_checksum[0x2]; - u8 sigerr_cqe[0x1]; - u8 reserved_at_213[0x1]; - u8 wq_signature[0x1]; - u8 sctr_data_cqe[0x1]; - u8 reserved_at_216[0x1]; - u8 sho[0x1]; - u8 tph[0x1]; - u8 rf[0x1]; - u8 dct[0x1]; - u8 qos[0x1]; - u8 eth_net_offloads[0x1]; - u8 roce[0x1]; - u8 atomic[0x1]; - u8 reserved_at_21f[0x1]; - u8 cq_oi[0x1]; - u8 cq_resize[0x1]; - u8 cq_moderation[0x1]; - u8 reserved_at_223[0x3]; - u8 cq_eq_remap[0x1]; - u8 pg[0x1]; - u8 block_lb_mc[0x1]; - u8 reserved_at_229[0x1]; - u8 scqe_break_moderation[0x1]; - u8 cq_period_start_from_cqe[0x1]; - u8 cd[0x1]; - u8 reserved_at_22d[0x1]; - u8 apm[0x1]; - u8 vector_calc[0x1]; - u8 umr_ptr_rlky[0x1]; - u8 imaicl[0x1]; - u8 reserved_at_232[0x4]; - u8 qkv[0x1]; - u8 pkv[0x1]; - u8 set_deth_sqpn[0x1]; - u8 reserved_at_239[0x3]; - u8 xrc[0x1]; - u8 ud[0x1]; - u8 uc[0x1]; - u8 rc[0x1]; - u8 uar_4k[0x1]; - u8 reserved_at_241[0x9]; - u8 uar_sz[0x6]; - u8 reserved_at_250[0x8]; - u8 log_pg_sz[0x8]; - u8 bf[0x1]; - u8 driver_version[0x1]; - u8 pad_tx_eth_packet[0x1]; - u8 reserved_at_263[0x8]; - u8 log_bf_reg_size[0x5]; - u8 reserved_at_270[0xb]; - u8 lag_master[0x1]; - u8 num_lag_ports[0x4]; - u8 reserved_at_280[0x10]; - u8 max_wqe_sz_sq[0x10]; - u8 reserved_at_2a0[0x10]; - u8 max_wqe_sz_rq[0x10]; - u8 max_flow_counter_31_16[0x10]; - u8 max_wqe_sz_sq_dc[0x10]; - u8 reserved_at_2e0[0x7]; - u8 max_qp_mcg[0x19]; - u8 reserved_at_300[0x10]; - u8 flow_counter_bulk_alloc[0x08]; - u8 log_max_mcg[0x8]; - u8 reserved_at_320[0x3]; - u8 log_max_transport_domain[0x5]; - u8 reserved_at_328[0x3]; - u8 log_max_pd[0x5]; - u8 reserved_at_330[0xb]; - u8 log_max_xrcd[0x5]; - u8 nic_receive_steering_discard[0x1]; - u8 receive_discard_vport_down[0x1]; - u8 transmit_discard_vport_down[0x1]; - u8 reserved_at_343[0x5]; - u8 log_max_flow_counter_bulk[0x8]; - u8 max_flow_counter_15_0[0x10]; - u8 modify_tis[0x1]; - u8 flow_counters_dump[0x1]; - u8 reserved_at_360[0x1]; - u8 log_max_rq[0x5]; - u8 reserved_at_368[0x3]; - u8 log_max_sq[0x5]; - u8 reserved_at_370[0x3]; - u8 log_max_tir[0x5]; - u8 reserved_at_378[0x3]; - u8 log_max_tis[0x5]; - u8 basic_cyclic_rcv_wqe[0x1]; - u8 reserved_at_381[0x2]; - u8 log_max_rmp[0x5]; - u8 reserved_at_388[0x3]; - u8 log_max_rqt[0x5]; - u8 reserved_at_390[0x3]; - u8 log_max_rqt_size[0x5]; - u8 reserved_at_398[0x3]; - u8 log_max_tis_per_sq[0x5]; - u8 ext_stride_num_range[0x1]; - u8 reserved_at_3a1[0x2]; - u8 log_max_stride_sz_rq[0x5]; - u8 reserved_at_3a8[0x3]; - u8 log_min_stride_sz_rq[0x5]; - u8 reserved_at_3b0[0x3]; - u8 log_max_stride_sz_sq[0x5]; - u8 reserved_at_3b8[0x3]; - u8 log_min_stride_sz_sq[0x5]; - u8 hairpin[0x1]; - u8 reserved_at_3c1[0x2]; - u8 log_max_hairpin_queues[0x5]; - u8 reserved_at_3c8[0x3]; - u8 log_max_hairpin_wq_data_sz[0x5]; - u8 reserved_at_3d0[0x3]; - u8 log_max_hairpin_num_packets[0x5]; - u8 reserved_at_3d8[0x3]; - u8 log_max_wq_sz[0x5]; - u8 nic_vport_change_event[0x1]; - u8 disable_local_lb_uc[0x1]; - u8 disable_local_lb_mc[0x1]; - u8 log_min_hairpin_wq_data_sz[0x5]; - u8 reserved_at_3e8[0x3]; - u8 log_max_vlan_list[0x5]; - u8 reserved_at_3f0[0x3]; - u8 log_max_current_mc_list[0x5]; - u8 reserved_at_3f8[0x3]; - u8 log_max_current_uc_list[0x5]; - u8 general_obj_types[0x40]; - u8 reserved_at_440[0x20]; - u8 reserved_at_460[0x10]; - u8 max_num_eqs[0x10]; - u8 reserved_at_480[0x3]; - u8 log_max_l2_table[0x5]; - u8 reserved_at_488[0x8]; - u8 log_uar_page_sz[0x10]; - u8 reserved_at_4a0[0x20]; - u8 device_frequency_mhz[0x20]; - u8 device_frequency_khz[0x20]; - u8 reserved_at_500[0x20]; - u8 num_of_uars_per_page[0x20]; - u8 flex_parser_protocols[0x20]; - u8 reserved_at_560[0x20]; - u8 reserved_at_580[0x3c]; - u8 mini_cqe_resp_stride_index[0x1]; - u8 cqe_128_always[0x1]; - u8 cqe_compression_128[0x1]; - u8 cqe_compression[0x1]; - u8 cqe_compression_timeout[0x10]; - u8 cqe_compression_max_num[0x10]; - u8 reserved_at_5e0[0x10]; - u8 tag_matching[0x1]; - u8 rndv_offload_rc[0x1]; - u8 rndv_offload_dc[0x1]; - u8 log_tag_matching_list_sz[0x5]; - u8 reserved_at_5f8[0x3]; - u8 log_max_xrq[0x5]; - u8 affiliate_nic_vport_criteria[0x8]; - u8 native_port_num[0x8]; - u8 num_vhca_ports[0x8]; - u8 reserved_at_618[0x6]; - u8 sw_owner_id[0x1]; - u8 reserved_at_61f[0x1e1]; -}; - -struct mlx5_ifc_qos_cap_bits { - u8 packet_pacing[0x1]; - u8 esw_scheduling[0x1]; - u8 esw_bw_share[0x1]; - u8 esw_rate_limit[0x1]; - u8 reserved_at_4[0x1]; - u8 packet_pacing_burst_bound[0x1]; - u8 packet_pacing_typical_size[0x1]; - u8 flow_meter_srtcm[0x1]; - u8 reserved_at_8[0x8]; - u8 log_max_flow_meter[0x8]; - u8 flow_meter_reg_id[0x8]; - u8 reserved_at_25[0x8]; - u8 flow_meter_reg_share[0x1]; - u8 reserved_at_2e[0x17]; - u8 packet_pacing_max_rate[0x20]; - u8 packet_pacing_min_rate[0x20]; - u8 reserved_at_80[0x10]; - u8 packet_pacing_rate_table_size[0x10]; - u8 esw_element_type[0x10]; - u8 esw_tsar_type[0x10]; - u8 reserved_at_c0[0x10]; - u8 max_qos_para_vport[0x10]; - u8 max_tsar_bw_share[0x20]; - u8 reserved_at_100[0x6e8]; -}; - -struct mlx5_ifc_per_protocol_networking_offload_caps_bits { - u8 csum_cap[0x1]; - u8 vlan_cap[0x1]; - u8 lro_cap[0x1]; - u8 lro_psh_flag[0x1]; - u8 lro_time_stamp[0x1]; - u8 lro_max_msg_sz_mode[0x2]; - u8 wqe_vlan_insert[0x1]; - u8 self_lb_en_modifiable[0x1]; - u8 self_lb_mc[0x1]; - u8 self_lb_uc[0x1]; - u8 max_lso_cap[0x5]; - u8 multi_pkt_send_wqe[0x2]; - u8 wqe_inline_mode[0x2]; - u8 rss_ind_tbl_cap[0x4]; - u8 reg_umr_sq[0x1]; - u8 scatter_fcs[0x1]; - u8 enhanced_multi_pkt_send_wqe[0x1]; - u8 tunnel_lso_const_out_ip_id[0x1]; - u8 tunnel_lro_gre[0x1]; - u8 tunnel_lro_vxlan[0x1]; - u8 tunnel_stateless_gre[0x1]; - u8 tunnel_stateless_vxlan[0x1]; - u8 swp[0x1]; - u8 swp_csum[0x1]; - u8 swp_lso[0x1]; - u8 reserved_at_23[0x8]; - u8 tunnel_stateless_gtp[0x1]; - u8 reserved_at_25[0x4]; - u8 max_vxlan_udp_ports[0x8]; - u8 reserved_at_38[0x6]; - u8 max_geneve_opt_len[0x1]; - u8 tunnel_stateless_geneve_rx[0x1]; - u8 reserved_at_40[0x10]; - u8 lro_min_mss_size[0x10]; - u8 reserved_at_60[0x120]; - u8 lro_timer_supported_periods[4][0x20]; - u8 reserved_at_200[0x600]; -}; - -union mlx5_ifc_hca_cap_union_bits { - struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap; - struct mlx5_ifc_per_protocol_networking_offload_caps_bits - per_protocol_networking_offload_caps; - struct mlx5_ifc_qos_cap_bits qos_cap; - u8 reserved_at_0[0x8000]; -}; - -struct mlx5_ifc_query_hca_cap_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; - union mlx5_ifc_hca_cap_union_bits capability; -}; - -struct mlx5_ifc_query_hca_cap_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0x40]; -}; - -struct mlx5_ifc_mac_address_layout_bits { - u8 reserved_at_0[0x10]; - u8 mac_addr_47_32[0x10]; - u8 mac_addr_31_0[0x20]; -}; - -struct mlx5_ifc_nic_vport_context_bits { - u8 reserved_at_0[0x5]; - u8 min_wqe_inline_mode[0x3]; - u8 reserved_at_8[0x15]; - u8 disable_mc_local_lb[0x1]; - u8 disable_uc_local_lb[0x1]; - u8 roce_en[0x1]; - u8 arm_change_event[0x1]; - u8 reserved_at_21[0x1a]; - u8 event_on_mtu[0x1]; - u8 event_on_promisc_change[0x1]; - u8 event_on_vlan_change[0x1]; - u8 event_on_mc_address_change[0x1]; - u8 event_on_uc_address_change[0x1]; - u8 reserved_at_40[0xc]; - u8 affiliation_criteria[0x4]; - u8 affiliated_vhca_id[0x10]; - u8 reserved_at_60[0xd0]; - u8 mtu[0x10]; - u8 system_image_guid[0x40]; - u8 port_guid[0x40]; - u8 node_guid[0x40]; - u8 reserved_at_200[0x140]; - u8 qkey_violation_counter[0x10]; - u8 reserved_at_350[0x430]; - u8 promisc_uc[0x1]; - u8 promisc_mc[0x1]; - u8 promisc_all[0x1]; - u8 reserved_at_783[0x2]; - u8 allowed_list_type[0x3]; - u8 reserved_at_788[0xc]; - u8 allowed_list_size[0xc]; - struct mlx5_ifc_mac_address_layout_bits permanent_address; - u8 reserved_at_7e0[0x20]; -}; - -struct mlx5_ifc_query_nic_vport_context_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; - struct mlx5_ifc_nic_vport_context_bits nic_vport_context; -}; - -struct mlx5_ifc_query_nic_vport_context_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 other_vport[0x1]; - u8 reserved_at_41[0xf]; - u8 vport_number[0x10]; - u8 reserved_at_60[0x5]; - u8 allowed_list_type[0x3]; - u8 reserved_at_68[0x18]; -}; - -struct mlx5_ifc_tisc_bits { - u8 strict_lag_tx_port_affinity[0x1]; - u8 reserved_at_1[0x3]; - u8 lag_tx_port_affinity[0x04]; - u8 reserved_at_8[0x4]; - u8 prio[0x4]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x100]; - u8 reserved_at_120[0x8]; - u8 transport_domain[0x18]; - u8 reserved_at_140[0x8]; - u8 underlay_qpn[0x18]; - u8 reserved_at_160[0x3a0]; -}; - -struct mlx5_ifc_query_tis_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; - struct mlx5_ifc_tisc_bits tis_context; -}; - -struct mlx5_ifc_query_tis_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0x8]; - u8 tisn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_alloc_transport_domain_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 transport_domain[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_alloc_transport_domain_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0x40]; -}; - -enum { - MLX5_WQ_TYPE_LINKED_LIST = 0x0, - MLX5_WQ_TYPE_CYCLIC = 0x1, - MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ = 0x2, - MLX5_WQ_TYPE_CYCLIC_STRIDING_RQ = 0x3, -}; - -enum { - MLX5_WQ_END_PAD_MODE_NONE = 0x0, - MLX5_WQ_END_PAD_MODE_ALIGN = 0x1, -}; - -struct mlx5_ifc_wq_bits { - u8 wq_type[0x4]; - u8 wq_signature[0x1]; - u8 end_padding_mode[0x2]; - u8 cd_slave[0x1]; - u8 reserved_at_8[0x18]; - u8 hds_skip_first_sge[0x1]; - u8 log2_hds_buf_size[0x3]; - u8 reserved_at_24[0x7]; - u8 page_offset[0x5]; - u8 lwm[0x10]; - u8 reserved_at_40[0x8]; - u8 pd[0x18]; - u8 reserved_at_60[0x8]; - u8 uar_page[0x18]; - u8 dbr_addr[0x40]; - u8 hw_counter[0x20]; - u8 sw_counter[0x20]; - u8 reserved_at_100[0xc]; - u8 log_wq_stride[0x4]; - u8 reserved_at_110[0x3]; - u8 log_wq_pg_sz[0x5]; - u8 reserved_at_118[0x3]; - u8 log_wq_sz[0x5]; - u8 dbr_umem_valid[0x1]; - u8 wq_umem_valid[0x1]; - u8 reserved_at_122[0x1]; - u8 log_hairpin_num_packets[0x5]; - u8 reserved_at_128[0x3]; - u8 log_hairpin_data_sz[0x5]; - u8 reserved_at_130[0x4]; - u8 single_wqe_log_num_of_strides[0x4]; - u8 two_byte_shift_en[0x1]; - u8 reserved_at_139[0x4]; - u8 single_stride_log_num_of_bytes[0x3]; - u8 dbr_umem_id[0x20]; - u8 wq_umem_id[0x20]; - u8 wq_umem_offset[0x40]; - u8 reserved_at_1c0[0x440]; -}; - -enum { - MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE = 0x0, - MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_RMP = 0x1, -}; - -enum { - MLX5_RQC_STATE_RST = 0x0, - MLX5_RQC_STATE_RDY = 0x1, - MLX5_RQC_STATE_ERR = 0x3, -}; - -struct mlx5_ifc_rqc_bits { - u8 rlky[0x1]; - u8 delay_drop_en[0x1]; - u8 scatter_fcs[0x1]; - u8 vsd[0x1]; - u8 mem_rq_type[0x4]; - u8 state[0x4]; - u8 reserved_at_c[0x1]; - u8 flush_in_error_en[0x1]; - u8 hairpin[0x1]; - u8 reserved_at_f[0x11]; - u8 reserved_at_20[0x8]; - u8 user_index[0x18]; - u8 reserved_at_40[0x8]; - u8 cqn[0x18]; - u8 counter_set_id[0x8]; - u8 reserved_at_68[0x18]; - u8 reserved_at_80[0x8]; - u8 rmpn[0x18]; - u8 reserved_at_a0[0x8]; - u8 hairpin_peer_sq[0x18]; - u8 reserved_at_c0[0x10]; - u8 hairpin_peer_vhca[0x10]; - u8 reserved_at_e0[0xa0]; - struct mlx5_ifc_wq_bits wq; /* Not used in LRO RQ. */ -}; - -struct mlx5_ifc_create_rq_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 rqn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_create_rq_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0xc0]; - struct mlx5_ifc_rqc_bits ctx; -}; - -struct mlx5_ifc_modify_rq_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; -}; - -struct mlx5_ifc_create_tis_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 tisn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_create_tis_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0xc0]; - struct mlx5_ifc_tisc_bits ctx; -}; - -enum { - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM = 1ULL << 0, - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD = 1ULL << 1, - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS = 1ULL << 2, - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID = 1ULL << 3, -}; - -struct mlx5_ifc_modify_rq_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 rq_state[0x4]; - u8 reserved_at_44[0x4]; - u8 rqn[0x18]; - u8 reserved_at_60[0x20]; - u8 modify_bitmask[0x40]; - u8 reserved_at_c0[0x40]; - struct mlx5_ifc_rqc_bits ctx; -}; - -enum { - MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_SRC_IP = 0x0, - MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_DST_IP = 0x1, - MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_SPORT = 0x2, - MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_DPORT = 0x3, - MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_IPSEC_SPI = 0x4, -}; - -struct mlx5_ifc_rx_hash_field_select_bits { - u8 l3_prot_type[0x1]; - u8 l4_prot_type[0x1]; - u8 selected_fields[0x1e]; -}; - -enum { - MLX5_TIRC_DISP_TYPE_DIRECT = 0x0, - MLX5_TIRC_DISP_TYPE_INDIRECT = 0x1, -}; - -enum { - MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO = 0x1, - MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO = 0x2, -}; - -enum { - MLX5_RX_HASH_FN_NONE = 0x0, - MLX5_RX_HASH_FN_INVERTED_XOR8 = 0x1, - MLX5_RX_HASH_FN_TOEPLITZ = 0x2, -}; - -enum { - MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST = 0x1, - MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST = 0x2, -}; - -enum { - MLX5_LRO_MAX_MSG_SIZE_START_FROM_L4 = 0x0, - MLX5_LRO_MAX_MSG_SIZE_START_FROM_L2 = 0x1, -}; - -struct mlx5_ifc_tirc_bits { - u8 reserved_at_0[0x20]; - u8 disp_type[0x4]; - u8 reserved_at_24[0x1c]; - u8 reserved_at_40[0x40]; - u8 reserved_at_80[0x4]; - u8 lro_timeout_period_usecs[0x10]; - u8 lro_enable_mask[0x4]; - u8 lro_max_msg_sz[0x8]; - u8 reserved_at_a0[0x40]; - u8 reserved_at_e0[0x8]; - u8 inline_rqn[0x18]; - u8 rx_hash_symmetric[0x1]; - u8 reserved_at_101[0x1]; - u8 tunneled_offload_en[0x1]; - u8 reserved_at_103[0x5]; - u8 indirect_table[0x18]; - u8 rx_hash_fn[0x4]; - u8 reserved_at_124[0x2]; - u8 self_lb_block[0x2]; - u8 transport_domain[0x18]; - u8 rx_hash_toeplitz_key[10][0x20]; - struct mlx5_ifc_rx_hash_field_select_bits rx_hash_field_selector_outer; - struct mlx5_ifc_rx_hash_field_select_bits rx_hash_field_selector_inner; - u8 reserved_at_2c0[0x4c0]; -}; - -struct mlx5_ifc_create_tir_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 tirn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_create_tir_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0xc0]; - struct mlx5_ifc_tirc_bits ctx; -}; - -struct mlx5_ifc_rq_num_bits { - u8 reserved_at_0[0x8]; - u8 rq_num[0x18]; -}; - -struct mlx5_ifc_rqtc_bits { - u8 reserved_at_0[0xa0]; - u8 reserved_at_a0[0x10]; - u8 rqt_max_size[0x10]; - u8 reserved_at_c0[0x10]; - u8 rqt_actual_size[0x10]; - u8 reserved_at_e0[0x6a0]; - struct mlx5_ifc_rq_num_bits rq_num[]; -}; - -struct mlx5_ifc_create_rqt_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 rqtn[0x18]; - u8 reserved_at_60[0x20]; -}; - -#ifdef PEDANTIC -#pragma GCC diagnostic ignored "-Wpedantic" -#endif -struct mlx5_ifc_create_rqt_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0xc0]; - struct mlx5_ifc_rqtc_bits rqt_context; -}; -#ifdef PEDANTIC -#pragma GCC diagnostic error "-Wpedantic" -#endif - -enum { - MLX5_SQC_STATE_RST = 0x0, - MLX5_SQC_STATE_RDY = 0x1, - MLX5_SQC_STATE_ERR = 0x3, -}; - -struct mlx5_ifc_sqc_bits { - u8 rlky[0x1]; - u8 cd_master[0x1]; - u8 fre[0x1]; - u8 flush_in_error_en[0x1]; - u8 allow_multi_pkt_send_wqe[0x1]; - u8 min_wqe_inline_mode[0x3]; - u8 state[0x4]; - u8 reg_umr[0x1]; - u8 allow_swp[0x1]; - u8 hairpin[0x1]; - u8 reserved_at_f[0x11]; - u8 reserved_at_20[0x8]; - u8 user_index[0x18]; - u8 reserved_at_40[0x8]; - u8 cqn[0x18]; - u8 reserved_at_60[0x8]; - u8 hairpin_peer_rq[0x18]; - u8 reserved_at_80[0x10]; - u8 hairpin_peer_vhca[0x10]; - u8 reserved_at_a0[0x50]; - u8 packet_pacing_rate_limit_index[0x10]; - u8 tis_lst_sz[0x10]; - u8 reserved_at_110[0x10]; - u8 reserved_at_120[0x40]; - u8 reserved_at_160[0x8]; - u8 tis_num_0[0x18]; - struct mlx5_ifc_wq_bits wq; -}; - -struct mlx5_ifc_query_sq_in_bits { - u8 opcode[0x10]; - u8 reserved_at_10[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0x8]; - u8 sqn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_modify_sq_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x40]; -}; - -struct mlx5_ifc_modify_sq_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 sq_state[0x4]; - u8 reserved_at_44[0x4]; - u8 sqn[0x18]; - u8 reserved_at_60[0x20]; - u8 modify_bitmask[0x40]; - u8 reserved_at_c0[0x40]; - struct mlx5_ifc_sqc_bits ctx; -}; - -struct mlx5_ifc_create_sq_out_bits { - u8 status[0x8]; - u8 reserved_at_8[0x18]; - u8 syndrome[0x20]; - u8 reserved_at_40[0x8]; - u8 sqn[0x18]; - u8 reserved_at_60[0x20]; -}; - -struct mlx5_ifc_create_sq_in_bits { - u8 opcode[0x10]; - u8 uid[0x10]; - u8 reserved_at_20[0x10]; - u8 op_mod[0x10]; - u8 reserved_at_40[0xc0]; - struct mlx5_ifc_sqc_bits ctx; -}; - -enum { - MLX5_FLOW_METER_OBJ_MODIFY_FIELD_ACTIVE = (1ULL << 0), - MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CBS = (1ULL << 1), - MLX5_FLOW_METER_OBJ_MODIFY_FIELD_CIR = (1ULL << 2), - MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EBS = (1ULL << 3), - MLX5_FLOW_METER_OBJ_MODIFY_FIELD_EIR = (1ULL << 4), -}; - -struct mlx5_ifc_flow_meter_parameters_bits { - u8 valid[0x1]; // 00h - u8 bucket_overflow[0x1]; - u8 start_color[0x2]; - u8 both_buckets_on_green[0x1]; - u8 meter_mode[0x2]; - u8 reserved_at_1[0x19]; - u8 reserved_at_2[0x20]; //04h - u8 reserved_at_3[0x3]; - u8 cbs_exponent[0x5]; // 08h - u8 cbs_mantissa[0x8]; - u8 reserved_at_4[0x3]; - u8 cir_exponent[0x5]; - u8 cir_mantissa[0x8]; - u8 reserved_at_5[0x20]; // 0Ch - u8 reserved_at_6[0x3]; - u8 ebs_exponent[0x5]; // 10h - u8 ebs_mantissa[0x8]; - u8 reserved_at_7[0x3]; - u8 eir_exponent[0x5]; - u8 eir_mantissa[0x8]; - u8 reserved_at_8[0x60]; // 14h-1Ch -}; - -/* 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; - struct { - uint16_t checksum; - uint16_t stride_idx; - }; - struct { - uint16_t wqe_counter; - uint8_t s_wqe_opcode; - uint8_t reserved; - } s_wqe_info; - }; - uint32_t byte_cnt; -}; - -/* srTCM PRM flow meter parameters. */ -enum { - MLX5_FLOW_COLOR_RED = 0, - MLX5_FLOW_COLOR_YELLOW, - MLX5_FLOW_COLOR_GREEN, - MLX5_FLOW_COLOR_UNDEFINED, -}; - -/* Maximum value of srTCM metering parameters. */ -#define MLX5_SRTCM_CBS_MAX (0xFF * (1ULL << 0x1F)) -#define MLX5_SRTCM_CIR_MAX (8 * (1ULL << 30) * 0xFF) -#define MLX5_SRTCM_EBS_MAX 0 - -/* The bits meter color use. */ -#define MLX5_MTR_COLOR_BITS 8 - -/** - * Convert a user mark to flow mark. - * - * @param val - * Mark value to convert. - * - * @return - * Converted mark value. - */ -static inline uint32_t -mlx5_flow_mark_set(uint32_t val) -{ - uint32_t ret; - - /* - * Add one to the user value to differentiate un-marked flows from - * marked flows, if the ID is equal to MLX5_FLOW_MARK_DEFAULT it - * remains untouched. - */ - if (val != MLX5_FLOW_MARK_DEFAULT) - ++val; -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - /* - * Mark is 24 bits (minus reserved values) but is stored on a 32 bit - * word, byte-swapped by the kernel on little-endian systems. In this - * case, left-shifting the resulting big-endian value ensures the - * least significant 24 bits are retained when converting it back. - */ - ret = rte_cpu_to_be_32(val) >> 8; -#else - ret = val; -#endif - return ret; -} - -/** - * Convert a mark to user mark. - * - * @param val - * Mark value to convert. - * - * @return - * Converted mark value. - */ -static inline uint32_t -mlx5_flow_mark_get(uint32_t val) -{ - /* - * Subtract one from the retrieved value. It was added by - * mlx5_flow_mark_set() to distinguish unmarked flows. - */ -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - return (val >> 8) - 1; -#else - return val - 1; -#endif -} - -#endif /* RTE_PMD_MLX5_PRM_H_ */ diff --git a/drivers/net/mlx5/mlx5_rss.c b/drivers/net/mlx5/mlx5_rss.c index 1028264..345ce3a 100644 --- a/drivers/net/mlx5/mlx5_rss.c +++ b/drivers/net/mlx5/mlx5_rss.c @@ -22,8 +22,8 @@ #include #include -#include "mlx5.h" #include "mlx5_defs.h" +#include "mlx5.h" #include "mlx5_rxtx.h" /** diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c index 371b996..e01cbfd 100644 --- a/drivers/net/mlx5/mlx5_rxq.c +++ b/drivers/net/mlx5/mlx5_rxq.c @@ -30,14 +30,16 @@ #include #include +#include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_rxtx.h" #include "mlx5_utils.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_glue.h" #include "mlx5_flow.h" -#include "mlx5_devx_cmds.h" + /* Default RSS hash key also used for ConnectX-3. */ uint8_t rss_hash_default_key[] = { diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index 5a03556..d8f6671 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -28,13 +28,14 @@ #include #include +#include +#include + +#include "mlx5_defs.h" #include "mlx5.h" -#include "mlx5_devx_cmds.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" /* TX burst subroutines return codes. */ enum mlx5_txcmp_code { diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h index 3f659d2..fb13919 100644 --- a/drivers/net/mlx5/mlx5_rxtx.h +++ b/drivers/net/mlx5/mlx5_rxtx.h @@ -31,13 +31,14 @@ #include #include +#include +#include + +#include "mlx5_defs.h" #include "mlx5_utils.h" #include "mlx5.h" #include "mlx5_mr.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" -#include "mlx5_glue.h" /* Support tunnel matching. */ #define MLX5_FLOW_TUNNEL 10 diff --git a/drivers/net/mlx5/mlx5_rxtx_vec.c b/drivers/net/mlx5/mlx5_rxtx_vec.c index d85f908..5505762 100644 --- a/drivers/net/mlx5/mlx5_rxtx_vec.c +++ b/drivers/net/mlx5/mlx5_rxtx_vec.c @@ -23,13 +23,14 @@ #include #include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_rxtx_vec.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" #if defined RTE_ARCH_X86_64 #include "mlx5_rxtx_vec_sse.h" diff --git a/drivers/net/mlx5/mlx5_rxtx_vec.h b/drivers/net/mlx5/mlx5_rxtx_vec.h index d8c07f2..82f77e5 100644 --- a/drivers/net/mlx5/mlx5_rxtx_vec.h +++ b/drivers/net/mlx5/mlx5_rxtx_vec.h @@ -9,8 +9,9 @@ #include #include +#include + #include "mlx5_autoconf.h" -#include "mlx5_prm.h" /* HW checksum offload capabilities of vectorized Tx. */ #define MLX5_VEC_TX_CKSUM_OFFLOAD_CAP \ diff --git a/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h b/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h index 9e5c6ee..1467a42 100644 --- a/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h +++ b/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h @@ -17,13 +17,14 @@ #include #include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_rxtx_vec.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" #ifndef __INTEL_COMPILER #pragma GCC diagnostic ignored "-Wcast-qual" diff --git a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h index 332e9ac..5b846c1 100644 --- a/drivers/net/mlx5/mlx5_rxtx_vec_neon.h +++ b/drivers/net/mlx5/mlx5_rxtx_vec_neon.h @@ -16,13 +16,14 @@ #include #include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_rxtx_vec.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" #pragma GCC diagnostic ignored "-Wcast-qual" diff --git a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h index 07d40d5..6e1b967 100644 --- a/drivers/net/mlx5/mlx5_rxtx_vec_sse.h +++ b/drivers/net/mlx5/mlx5_rxtx_vec_sse.h @@ -16,13 +16,14 @@ #include #include +#include + +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_utils.h" #include "mlx5_rxtx.h" #include "mlx5_rxtx_vec.h" #include "mlx5_autoconf.h" -#include "mlx5_defs.h" -#include "mlx5_prm.h" #ifndef __INTEL_COMPILER #pragma GCC diagnostic ignored "-Wcast-qual" diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c index 205e4fe..0ed7170 100644 --- a/drivers/net/mlx5/mlx5_stats.c +++ b/drivers/net/mlx5/mlx5_stats.c @@ -13,9 +13,9 @@ #include #include +#include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_rxtx.h" -#include "mlx5_defs.h" static const struct mlx5_counter_ctrl mlx5_counters_init[] = { { diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index 5adb4dc..1d2ba8a 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -28,13 +28,14 @@ #include #include -#include "mlx5_utils.h" +#include +#include + #include "mlx5_defs.h" +#include "mlx5_utils.h" #include "mlx5.h" #include "mlx5_rxtx.h" #include "mlx5_autoconf.h" -#include "mlx5_glue.h" -#include "mlx5_devx_cmds.h" /** * Allocate TX queue elements. diff --git a/drivers/net/mlx5/mlx5_utils.h b/drivers/net/mlx5/mlx5_utils.h index ebf79b8..c868aee 100644 --- a/drivers/net/mlx5/mlx5_utils.h +++ b/drivers/net/mlx5/mlx5_utils.h @@ -13,8 +13,11 @@ #include #include +#include + #include "mlx5_defs.h" + /* * Compilation workaround for PPC64 when AltiVec is fully enabled, e.g. std=c11. * Otherwise there would be a type conflict between stdbool and altivec. @@ -50,81 +53,14 @@ /* Save and restore errno around argument evaluation. */ #define ERRNO_SAFE(x) ((errno = (int []){ errno, ((x), 0) }[0])) -/* - * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant - * manner. - */ -#define PMD_DRV_LOG_STRIP(a, b) a -#define PMD_DRV_LOG_OPAREN ( -#define PMD_DRV_LOG_CPAREN ) -#define PMD_DRV_LOG_COMMA , - -/* Return the file name part of a path. */ -static inline const char * -pmd_drv_log_basename(const char *s) -{ - const char *n = s; - - while (*n) - if (*(n++) == '/') - s = n; - return s; -} - extern int mlx5_logtype; -#define PMD_DRV_LOG___(level, ...) \ - rte_log(RTE_LOG_ ## level, \ - mlx5_logtype, \ - RTE_FMT(MLX5_DRIVER_NAME ": " \ - RTE_FMT_HEAD(__VA_ARGS__,), \ - RTE_FMT_TAIL(__VA_ARGS__,))) - -/* - * When debugging is enabled (NDEBUG not defined), file, line and function - * information replace the driver name (MLX5_DRIVER_NAME) in log messages. - */ -#ifndef NDEBUG - -#define PMD_DRV_LOG__(level, ...) \ - PMD_DRV_LOG___(level, "%s:%u: %s(): " __VA_ARGS__) -#define PMD_DRV_LOG_(level, s, ...) \ - PMD_DRV_LOG__(level, \ - s "\n" PMD_DRV_LOG_COMMA \ - pmd_drv_log_basename(__FILE__) PMD_DRV_LOG_COMMA \ - __LINE__ PMD_DRV_LOG_COMMA \ - __func__, \ - __VA_ARGS__) - -#else /* NDEBUG */ -#define PMD_DRV_LOG__(level, ...) \ - PMD_DRV_LOG___(level, __VA_ARGS__) -#define PMD_DRV_LOG_(level, s, ...) \ - PMD_DRV_LOG__(level, s "\n", __VA_ARGS__) - -#endif /* NDEBUG */ - /* Generic printf()-like logging macro with automatic line feed. */ #define DRV_LOG(level, ...) \ - PMD_DRV_LOG_(level, \ + PMD_DRV_LOG_(level, mlx5_logtype, MLX5_DRIVER_NAME, \ __VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \ PMD_DRV_LOG_CPAREN) -/* claim_zero() does not perform any check when debugging is disabled. */ -#ifndef NDEBUG - -#define DEBUG(...) DRV_LOG(DEBUG, __VA_ARGS__) -#define claim_zero(...) assert((__VA_ARGS__) == 0) -#define claim_nonzero(...) assert((__VA_ARGS__) != 0) - -#else /* NDEBUG */ - -#define DEBUG(...) (void)0 -#define claim_zero(...) (__VA_ARGS__) -#define claim_nonzero(...) (__VA_ARGS__) - -#endif /* NDEBUG */ - #define INFO(...) DRV_LOG(INFO, __VA_ARGS__) #define WARN(...) DRV_LOG(WARNING, __VA_ARGS__) #define ERROR(...) DRV_LOG(ERR, __VA_ARGS__) @@ -144,13 +80,6 @@ (((val) & (from)) / ((from) / (to))) : \ (((val) & (from)) * ((to) / (from)))) -/* Allocate a buffer on the stack and fill it with a printf format string. */ -#define MKSTR(name, ...) \ - int mkstr_size_##name = snprintf(NULL, 0, "" __VA_ARGS__); \ - char name[mkstr_size_##name + 1]; \ - \ - snprintf(name, sizeof(name), "" __VA_ARGS__) - /** * Return logarithm of the nearest power of two above input value. * diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index feac0f1..b0fa31a 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -27,10 +27,11 @@ #include #include +#include +#include + #include "mlx5.h" #include "mlx5_autoconf.h" -#include "mlx5_glue.h" -#include "mlx5_devx_cmds.h" #include "mlx5_rxtx.h" #include "mlx5_utils.h" diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 15acf95..45f4cad 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -196,6 +196,7 @@ endif _LDLIBS-$(CONFIG_RTE_LIBRTE_LIO_PMD) += -lrte_pmd_lio _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_MEMIF) += -lrte_pmd_memif _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4 +_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_common_mlx5 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -ldl From patchwork Wed Jan 29 12:38:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65310 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id B1658A052F; Wed, 29 Jan 2020 13:39:19 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3DCD81BFD3; Wed, 29 Jan 2020 13:39:16 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 95CBF1BFD1 for ; Wed, 29 Jan 2020 13:39:14 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:10 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1b018914; Wed, 29 Jan 2020 14:39:10 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:28 +0000 Message-Id: <1580301530-6643-4-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 03/25] common/mlx5: share the mlx5 glue reference X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" A new Mellanox vdpa PMD will be added to support vdpa operations by Mellanox adapters. Both, the mlx5 PMD and the vdpa mlx5 PMD should initialize the glue. The glue initialization should be only one per process, so all the mlx5 PMDs using the glue should share the same glue object. Move the glue initialization to be in common/mlx5 library to be initialized by its constructor only once. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_common.c | 173 +++++++++++++++++++++++++++++++++++++- drivers/net/mlx5/Makefile | 9 -- drivers/net/mlx5/meson.build | 4 - drivers/net/mlx5/mlx5.c | 172 +------------------------------------ 4 files changed, 173 insertions(+), 185 deletions(-) diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c index 14ebd30..9c88a63 100644 --- a/drivers/common/mlx5/mlx5_common.c +++ b/drivers/common/mlx5/mlx5_common.c @@ -2,16 +2,185 @@ * Copyright 2019 Mellanox Technologies, Ltd */ +#include +#include +#include + +#include + #include "mlx5_common.h" +#include "mlx5_common_utils.h" +#include "mlx5_glue.h" int mlx5_common_logtype; -RTE_INIT(rte_mlx5_common_pmd_init) +#ifdef RTE_IBVERBS_LINK_DLOPEN + +/** + * Suffix RTE_EAL_PMD_PATH with "-glue". + * + * This function performs a sanity check on RTE_EAL_PMD_PATH before + * suffixing its last component. + * + * @param buf[out] + * Output buffer, should be large enough otherwise NULL is returned. + * @param size + * Size of @p out. + * + * @return + * Pointer to @p buf or @p NULL in case suffix cannot be appended. + */ +static char * +mlx5_glue_path(char *buf, size_t size) +{ + static const char *const bad[] = { "/", ".", "..", NULL }; + const char *path = RTE_EAL_PMD_PATH; + size_t len = strlen(path); + size_t off; + int i; + + while (len && path[len - 1] == '/') + --len; + for (off = len; off && path[off - 1] != '/'; --off) + ; + for (i = 0; bad[i]; ++i) + if (!strncmp(path + off, bad[i], (int)(len - off))) + goto error; + i = snprintf(buf, size, "%.*s-glue", (int)len, path); + if (i == -1 || (size_t)i >= size) + goto error; + return buf; +error: + RTE_LOG(ERR, PMD, "unable to append \"-glue\" to last component of" + " RTE_EAL_PMD_PATH (\"" RTE_EAL_PMD_PATH "\"), please" + " re-configure DPDK"); + return NULL; +} +#endif + +/** + * Initialization routine for run-time dependency on rdma-core. + */ +RTE_INIT_PRIO(mlx5_glue_init, CLASS) { - /* Initialize driver log type. */ + void *handle = NULL; + + /* Initialize common log type. */ mlx5_common_logtype = rte_log_register("pmd.common.mlx5"); if (mlx5_common_logtype >= 0) rte_log_set_level(mlx5_common_logtype, RTE_LOG_NOTICE); + /* + * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use + * huge pages. Calling ibv_fork_init() during init allows + * applications to use fork() safely for purposes other than + * using this PMD, which is not supported in forked processes. + */ + setenv("RDMAV_HUGEPAGES_SAFE", "1", 1); + /* Match the size of Rx completion entry to the size of a cacheline. */ + if (RTE_CACHE_LINE_SIZE == 128) + setenv("MLX5_CQE_SIZE", "128", 0); + /* + * MLX5_DEVICE_FATAL_CLEANUP tells ibv_destroy functions to + * cleanup all the Verbs resources even when the device was removed. + */ + setenv("MLX5_DEVICE_FATAL_CLEANUP", "1", 1); + /* The glue initialization was done earlier by mlx5 common library. */ +#ifdef RTE_IBVERBS_LINK_DLOPEN + char glue_path[sizeof(RTE_EAL_PMD_PATH) - 1 + sizeof("-glue")]; + const char *path[] = { + /* + * A basic security check is necessary before trusting + * MLX5_GLUE_PATH, which may override RTE_EAL_PMD_PATH. + */ + (geteuid() == getuid() && getegid() == getgid() ? + getenv("MLX5_GLUE_PATH") : NULL), + /* + * When RTE_EAL_PMD_PATH is set, use its glue-suffixed + * variant, otherwise let dlopen() look up libraries on its + * own. + */ + (*RTE_EAL_PMD_PATH ? + mlx5_glue_path(glue_path, sizeof(glue_path)) : ""), + }; + unsigned int i = 0; + void **sym; + const char *dlmsg; + + while (!handle && i != RTE_DIM(path)) { + const char *end; + size_t len; + int ret; + + if (!path[i]) { + ++i; + continue; + } + end = strpbrk(path[i], ":;"); + if (!end) + end = path[i] + strlen(path[i]); + len = end - path[i]; + ret = 0; + do { + char name[ret + 1]; + + ret = snprintf(name, sizeof(name), "%.*s%s" MLX5_GLUE, + (int)len, path[i], + (!len || *(end - 1) == '/') ? "" : "/"); + if (ret == -1) + break; + if (sizeof(name) != (size_t)ret + 1) + continue; + DRV_LOG(DEBUG, "Looking for rdma-core glue as " + "\"%s\"", name); + handle = dlopen(name, RTLD_LAZY); + break; + } while (1); + path[i] = end + 1; + if (!*end) + ++i; + } + if (!handle) { + rte_errno = EINVAL; + dlmsg = dlerror(); + if (dlmsg) + DRV_LOG(WARNING, "Cannot load glue library: %s", dlmsg); + goto glue_error; + } + sym = dlsym(handle, "mlx5_glue"); + if (!sym || !*sym) { + rte_errno = EINVAL; + dlmsg = dlerror(); + if (dlmsg) + DRV_LOG(ERR, "Cannot resolve glue symbol: %s", dlmsg); + goto glue_error; + } + mlx5_glue = *sym; +#endif /* RTE_IBVERBS_LINK_DLOPEN */ +#ifndef NDEBUG + /* Glue structure must not contain any NULL pointers. */ + { + unsigned int i; + + for (i = 0; i != sizeof(*mlx5_glue) / sizeof(void *); ++i) + assert(((const void *const *)mlx5_glue)[i]); + } +#endif + if (strcmp(mlx5_glue->version, MLX5_GLUE_VERSION)) { + rte_errno = EINVAL; + DRV_LOG(ERR, "rdma-core glue \"%s\" mismatch: \"%s\" is " + "required", mlx5_glue->version, MLX5_GLUE_VERSION); + goto glue_error; + } + mlx5_glue->fork_init(); + return; +glue_error: + if (handle) + dlclose(handle); + DRV_LOG(WARNING, "Cannot initialize MLX5 common due to missing" + " run-time dependency on rdma-core libraries (libibverbs," + " libmlx5)"); + mlx5_glue = NULL; + return; } diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index a9558ca..dc6b3c8 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -6,15 +6,6 @@ include $(RTE_SDK)/mk/rte.vars.mk # Library name. LIB = librte_pmd_mlx5.a -LIB_GLUE = $(LIB_GLUE_BASE).$(LIB_GLUE_VERSION) -LIB_GLUE_BASE = librte_pmd_mlx5_glue.so -LIB_GLUE_VERSION = 20.02.0 - -ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) -CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"' -CFLAGS += -DMLX5_GLUE_VERSION='"$(LIB_GLUE_VERSION)"' -LDLIBS += -ldl -endif # Sources. SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index f6d0db9..e10ef3a 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -8,10 +8,6 @@ if not is_linux subdir_done() endif -LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so' -LIB_GLUE_VERSION = '20.02.0' -LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION - allow_experimental_apis = true deps += ['hash', 'common_mlx5'] sources = files( diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 7cf357d..8fbe826 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -3505,138 +3504,6 @@ struct mlx5_flow_id_pool * RTE_PCI_DRV_PROBE_AGAIN, }; -#ifdef RTE_IBVERBS_LINK_DLOPEN - -/** - * Suffix RTE_EAL_PMD_PATH with "-glue". - * - * This function performs a sanity check on RTE_EAL_PMD_PATH before - * suffixing its last component. - * - * @param buf[out] - * Output buffer, should be large enough otherwise NULL is returned. - * @param size - * Size of @p out. - * - * @return - * Pointer to @p buf or @p NULL in case suffix cannot be appended. - */ -static char * -mlx5_glue_path(char *buf, size_t size) -{ - static const char *const bad[] = { "/", ".", "..", NULL }; - const char *path = RTE_EAL_PMD_PATH; - size_t len = strlen(path); - size_t off; - int i; - - while (len && path[len - 1] == '/') - --len; - for (off = len; off && path[off - 1] != '/'; --off) - ; - for (i = 0; bad[i]; ++i) - if (!strncmp(path + off, bad[i], (int)(len - off))) - goto error; - i = snprintf(buf, size, "%.*s-glue", (int)len, path); - if (i == -1 || (size_t)i >= size) - goto error; - return buf; -error: - DRV_LOG(ERR, - "unable to append \"-glue\" to last component of" - " RTE_EAL_PMD_PATH (\"" RTE_EAL_PMD_PATH "\")," - " please re-configure DPDK"); - return NULL; -} - -/** - * Initialization routine for run-time dependency on rdma-core. - */ -static int -mlx5_glue_init(void) -{ - char glue_path[sizeof(RTE_EAL_PMD_PATH) - 1 + sizeof("-glue")]; - const char *path[] = { - /* - * A basic security check is necessary before trusting - * MLX5_GLUE_PATH, which may override RTE_EAL_PMD_PATH. - */ - (geteuid() == getuid() && getegid() == getgid() ? - getenv("MLX5_GLUE_PATH") : NULL), - /* - * When RTE_EAL_PMD_PATH is set, use its glue-suffixed - * variant, otherwise let dlopen() look up libraries on its - * own. - */ - (*RTE_EAL_PMD_PATH ? - mlx5_glue_path(glue_path, sizeof(glue_path)) : ""), - }; - unsigned int i = 0; - void *handle = NULL; - void **sym; - const char *dlmsg; - - while (!handle && i != RTE_DIM(path)) { - const char *end; - size_t len; - int ret; - - if (!path[i]) { - ++i; - continue; - } - end = strpbrk(path[i], ":;"); - if (!end) - end = path[i] + strlen(path[i]); - len = end - path[i]; - ret = 0; - do { - char name[ret + 1]; - - ret = snprintf(name, sizeof(name), "%.*s%s" MLX5_GLUE, - (int)len, path[i], - (!len || *(end - 1) == '/') ? "" : "/"); - if (ret == -1) - break; - if (sizeof(name) != (size_t)ret + 1) - continue; - DRV_LOG(DEBUG, "looking for rdma-core glue as \"%s\"", - name); - handle = dlopen(name, RTLD_LAZY); - break; - } while (1); - path[i] = end + 1; - if (!*end) - ++i; - } - if (!handle) { - rte_errno = EINVAL; - dlmsg = dlerror(); - if (dlmsg) - DRV_LOG(WARNING, "cannot load glue library: %s", dlmsg); - goto glue_error; - } - sym = dlsym(handle, "mlx5_glue"); - if (!sym || !*sym) { - rte_errno = EINVAL; - dlmsg = dlerror(); - if (dlmsg) - DRV_LOG(ERR, "cannot resolve glue symbol: %s", dlmsg); - goto glue_error; - } - mlx5_glue = *sym; - return 0; -glue_error: - if (handle) - dlclose(handle); - DRV_LOG(WARNING, - "cannot initialize PMD due to missing run-time dependency on" - " rdma-core libraries (libibverbs, libmlx5)"); - return -rte_errno; -} - -#endif - /** * Driver initialization routine. */ @@ -3651,43 +3518,8 @@ struct mlx5_flow_id_pool * mlx5_set_ptype_table(); mlx5_set_cksum_table(); mlx5_set_swp_types_table(); - /* - * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use - * huge pages. Calling ibv_fork_init() during init allows - * applications to use fork() safely for purposes other than - * using this PMD, which is not supported in forked processes. - */ - setenv("RDMAV_HUGEPAGES_SAFE", "1", 1); - /* Match the size of Rx completion entry to the size of a cacheline. */ - if (RTE_CACHE_LINE_SIZE == 128) - setenv("MLX5_CQE_SIZE", "128", 0); - /* - * MLX5_DEVICE_FATAL_CLEANUP tells ibv_destroy functions to - * cleanup all the Verbs resources even when the device was removed. - */ - setenv("MLX5_DEVICE_FATAL_CLEANUP", "1", 1); -#ifdef RTE_IBVERBS_LINK_DLOPEN - if (mlx5_glue_init()) - return; - assert(mlx5_glue); -#endif -#ifndef NDEBUG - /* Glue structure must not contain any NULL pointers. */ - { - unsigned int i; - - for (i = 0; i != sizeof(*mlx5_glue) / sizeof(void *); ++i) - assert(((const void *const *)mlx5_glue)[i]); - } -#endif - if (strcmp(mlx5_glue->version, MLX5_GLUE_VERSION)) { - DRV_LOG(ERR, - "rdma-core glue \"%s\" mismatch: \"%s\" is required", - mlx5_glue->version, MLX5_GLUE_VERSION); - return; - } - mlx5_glue->fork_init(); - rte_pci_register(&mlx5_driver); + if (mlx5_glue) + rte_pci_register(&mlx5_driver); } RTE_PMD_EXPORT_NAME(net_mlx5, __COUNTER__); From patchwork Wed Jan 29 12:38:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65311 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8D8D7A052F; Wed, 29 Jan 2020 13:39:28 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8292F1BFE0; Wed, 29 Jan 2020 13:39:17 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id A33321BFD3 for ; Wed, 29 Jan 2020 13:39:14 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:13 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1c018914; Wed, 29 Jan 2020 14:39:12 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:29 +0000 Message-Id: <1580301530-6643-5-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 04/25] common/mlx5: share mlx5 PCI device detection X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Move PCI detection by IB device from mlx5 PMD to the common code. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 2 +- drivers/common/mlx5/mlx5_common.c | 55 +++++++++++++++++++++++++ drivers/common/mlx5/mlx5_common.h | 4 ++ drivers/common/mlx5/rte_common_mlx5_version.map | 2 + drivers/net/mlx5/mlx5.c | 1 + drivers/net/mlx5/mlx5.h | 2 - drivers/net/mlx5/mlx5_ethdev.c | 53 +----------------------- drivers/net/mlx5/mlx5_rxtx.c | 1 + drivers/net/mlx5/mlx5_stats.c | 3 ++ 9 files changed, 68 insertions(+), 55 deletions(-) diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index b94d3c0..66585b2 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -41,7 +41,7 @@ else LDLIBS += -libverbs -lmlx5 endif -LDLIBS += -lrte_eal +LDLIBS += -lrte_eal -lrte_pci # A few warnings cannot be avoided in external headers. CFLAGS += -Wno-error=cast-qual -DNDEBUG -UPEDANTIC diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c index 9c88a63..2381208 100644 --- a/drivers/common/mlx5/mlx5_common.c +++ b/drivers/common/mlx5/mlx5_common.c @@ -5,6 +5,9 @@ #include #include #include +#include + +#include #include @@ -16,6 +19,58 @@ int mlx5_common_logtype; +/** + * Get PCI information by sysfs device path. + * + * @param dev_path + * Pointer to device sysfs folder name. + * @param[out] pci_addr + * PCI bus address output buffer. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_dev_to_pci_addr(const char *dev_path, + struct rte_pci_addr *pci_addr) +{ + FILE *file; + char line[32]; + MKSTR(path, "%s/device/uevent", dev_path); + + file = fopen(path, "rb"); + if (file == NULL) { + rte_errno = errno; + return -rte_errno; + } + while (fgets(line, sizeof(line), file) == line) { + size_t len = strlen(line); + int ret; + + /* Truncate long lines. */ + if (len == (sizeof(line) - 1)) + while (line[(len - 1)] != '\n') { + ret = fgetc(file); + if (ret == EOF) + break; + line[(len - 1)] = ret; + } + /* Extract information. */ + if (sscanf(line, + "PCI_SLOT_NAME=" + "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n", + &pci_addr->domain, + &pci_addr->bus, + &pci_addr->devid, + &pci_addr->function) == 4) { + ret = 0; + break; + } + } + fclose(file); + return 0; +} + #ifdef RTE_IBVERBS_LINK_DLOPEN /** diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 9f10def..107ab8d 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -6,7 +6,9 @@ #define RTE_PMD_MLX5_COMMON_H_ #include +#include +#include #include @@ -84,4 +86,6 @@ \ snprintf(name, sizeof(name), "" __VA_ARGS__) +int mlx5_dev_to_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr); + #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index e4f85e2..0c01172 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -17,4 +17,6 @@ DPDK_20.02 { mlx5_devx_cmd_qp_query_tis_td; mlx5_devx_cmd_query_hca_attr; mlx5_devx_get_out_command_status; + + mlx5_dev_to_pci_addr; }; diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 8fbe826..d0fa2da 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -39,6 +39,7 @@ #include #include +#include #include "mlx5_defs.h" #include "mlx5.h" diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 872fccb..261a8fc 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -655,8 +655,6 @@ 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, struct rte_eth_fc_conf *fc_conf); -int mlx5_dev_to_pci_addr(const char *dev_path, - struct rte_pci_addr *pci_addr); void mlx5_dev_link_status_handler(void *arg); void mlx5_dev_interrupt_handler(void *arg); void mlx5_dev_interrupt_handler_devx(void *arg); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index eddf888..2628e64 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -38,6 +38,7 @@ #include #include +#include #include "mlx5.h" #include "mlx5_rxtx.h" @@ -1212,58 +1213,6 @@ int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) } /** - * Get PCI information by sysfs device path. - * - * @param dev_path - * Pointer to device sysfs folder name. - * @param[out] pci_addr - * PCI bus address output buffer. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_dev_to_pci_addr(const char *dev_path, - struct rte_pci_addr *pci_addr) -{ - FILE *file; - char line[32]; - MKSTR(path, "%s/device/uevent", dev_path); - - file = fopen(path, "rb"); - if (file == NULL) { - rte_errno = errno; - return -rte_errno; - } - while (fgets(line, sizeof(line), file) == line) { - size_t len = strlen(line); - int ret; - - /* Truncate long lines. */ - if (len == (sizeof(line) - 1)) - while (line[(len - 1)] != '\n') { - ret = fgetc(file); - if (ret == EOF) - break; - line[(len - 1)] = ret; - } - /* Extract information. */ - if (sscanf(line, - "PCI_SLOT_NAME=" - "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n", - &pci_addr->domain, - &pci_addr->bus, - &pci_addr->devid, - &pci_addr->function) == 4) { - ret = 0; - break; - } - } - fclose(file); - return 0; -} - -/** * Handle asynchronous removal event for entire multiport device. * * @param sh diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index d8f6671..b14ae31 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -30,6 +30,7 @@ #include #include +#include #include "mlx5_defs.h" #include "mlx5.h" diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c index 0ed7170..4c69e77 100644 --- a/drivers/net/mlx5/mlx5_stats.c +++ b/drivers/net/mlx5/mlx5_stats.c @@ -13,10 +13,13 @@ #include #include +#include + #include "mlx5_defs.h" #include "mlx5.h" #include "mlx5_rxtx.h" + static const struct mlx5_counter_ctrl mlx5_counters_init[] = { { .dpdk_name = "rx_port_unicast_bytes", From patchwork Wed Jan 29 12:38:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65312 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id F24D9A052F; Wed, 29 Jan 2020 13:39:43 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 973291BFF0; Wed, 29 Jan 2020 13:39:22 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id BC77A1BFE2 for ; Wed, 29 Jan 2020 13:39:19 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:16 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1d018914; Wed, 29 Jan 2020 14:39:16 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:30 +0000 Message-Id: <1580301530-6643-6-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 05/25] common/mlx5: share mlx5 devices information X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Move the vendor information, vendor ID and device IDs from net/mlx5 PMD to the common mlx5 file. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_common.h | 21 +++++++++++++++++++++ drivers/net/mlx5/mlx5.h | 21 --------------------- drivers/net/mlx5/mlx5_txq.c | 1 + 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 107ab8d..0f57a27 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -86,6 +86,27 @@ \ snprintf(name, sizeof(name), "" __VA_ARGS__) +enum { + PCI_VENDOR_ID_MELLANOX = 0x15b3, +}; + +enum { + PCI_DEVICE_ID_MELLANOX_CONNECTX4 = 0x1013, + PCI_DEVICE_ID_MELLANOX_CONNECTX4VF = 0x1014, + PCI_DEVICE_ID_MELLANOX_CONNECTX4LX = 0x1015, + PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF = 0x1016, + PCI_DEVICE_ID_MELLANOX_CONNECTX5 = 0x1017, + PCI_DEVICE_ID_MELLANOX_CONNECTX5VF = 0x1018, + PCI_DEVICE_ID_MELLANOX_CONNECTX5EX = 0x1019, + PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF = 0x101a, + PCI_DEVICE_ID_MELLANOX_CONNECTX5BF = 0xa2d2, + PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF = 0xa2d3, + PCI_DEVICE_ID_MELLANOX_CONNECTX6 = 0x101b, + PCI_DEVICE_ID_MELLANOX_CONNECTX6VF = 0x101c, + PCI_DEVICE_ID_MELLANOX_CONNECTX6DX = 0x101d, + PCI_DEVICE_ID_MELLANOX_CONNECTX6DXVF = 0x101e, +}; + int mlx5_dev_to_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr); #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 261a8fc..3daf0db 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -41,27 +41,6 @@ #include "mlx5_mr.h" #include "mlx5_autoconf.h" -enum { - PCI_VENDOR_ID_MELLANOX = 0x15b3, -}; - -enum { - PCI_DEVICE_ID_MELLANOX_CONNECTX4 = 0x1013, - PCI_DEVICE_ID_MELLANOX_CONNECTX4VF = 0x1014, - PCI_DEVICE_ID_MELLANOX_CONNECTX4LX = 0x1015, - PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF = 0x1016, - PCI_DEVICE_ID_MELLANOX_CONNECTX5 = 0x1017, - PCI_DEVICE_ID_MELLANOX_CONNECTX5VF = 0x1018, - PCI_DEVICE_ID_MELLANOX_CONNECTX5EX = 0x1019, - PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF = 0x101a, - PCI_DEVICE_ID_MELLANOX_CONNECTX5BF = 0xa2d2, - PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF = 0xa2d3, - PCI_DEVICE_ID_MELLANOX_CONNECTX6 = 0x101b, - PCI_DEVICE_ID_MELLANOX_CONNECTX6VF = 0x101c, - PCI_DEVICE_ID_MELLANOX_CONNECTX6DX = 0x101d, - PCI_DEVICE_ID_MELLANOX_CONNECTX6DXVF = 0x101e, -}; - /* Request types for IPC. */ enum mlx5_mp_req_type { MLX5_MP_REQ_VERBS_CMD_FD = 1, diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c index 1d2ba8a..7bff769 100644 --- a/drivers/net/mlx5/mlx5_txq.c +++ b/drivers/net/mlx5/mlx5_txq.c @@ -30,6 +30,7 @@ #include #include +#include #include "mlx5_defs.h" #include "mlx5_utils.h" From patchwork Wed Jan 29 12:38:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65313 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 60FE7A052F; Wed, 29 Jan 2020 13:39:55 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DB12C1BFDF; Wed, 29 Jan 2020 13:39:26 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 28D531BFD1 for ; Wed, 29 Jan 2020 13:39:25 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:19 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1e018914; Wed, 29 Jan 2020 14:39:19 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:31 +0000 Message-Id: <1580301530-6643-7-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 06/25] common/mlx5: share CQ entry check X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The CQE has owner bit to indicate if it is in SW control or HW. Share a CQE check for all the mlx5 drivers. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_common.h | 41 +++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_rxtx.h | 39 +------------------------------------ 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 0f57a27..9d464d4 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -9,8 +9,11 @@ #include #include +#include #include +#include "mlx5_prm.h" + /* * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant @@ -107,6 +110,44 @@ enum { PCI_DEVICE_ID_MELLANOX_CONNECTX6DXVF = 0x101e, }; +/* CQE status. */ +enum mlx5_cqe_status { + MLX5_CQE_STATUS_SW_OWN = -1, + MLX5_CQE_STATUS_HW_OWN = -2, + MLX5_CQE_STATUS_ERR = -3, +}; + +/** + * Check whether CQE is valid. + * + * @param cqe + * Pointer to CQE. + * @param cqes_n + * Size of completion queue. + * @param ci + * Consumer index. + * + * @return + * The CQE status. + */ +static __rte_always_inline enum mlx5_cqe_status +check_cqe(volatile struct mlx5_cqe *cqe, const uint16_t cqes_n, + const uint16_t ci) +{ + const uint16_t idx = ci & cqes_n; + const uint8_t op_own = cqe->op_own; + const uint8_t op_owner = MLX5_CQE_OWNER(op_own); + const uint8_t op_code = MLX5_CQE_OPCODE(op_own); + + if (unlikely((op_owner != (!!(idx))) || (op_code == MLX5_CQE_INVALID))) + return MLX5_CQE_STATUS_HW_OWN; + rte_cio_rmb(); + if (unlikely(op_code == MLX5_CQE_RESP_ERR || + op_code == MLX5_CQE_REQ_ERR)) + return MLX5_CQE_STATUS_ERR; + return MLX5_CQE_STATUS_SW_OWN; +} + int mlx5_dev_to_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr); #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h index fb13919..c2cd23b 100644 --- a/drivers/net/mlx5/mlx5_rxtx.h +++ b/drivers/net/mlx5/mlx5_rxtx.h @@ -33,6 +33,7 @@ #include #include +#include #include "mlx5_defs.h" #include "mlx5_utils.h" @@ -549,44 +550,6 @@ int mlx5_dma_unmap(struct rte_pci_device *pdev, void *addr, uint64_t iova, #define mlx5_uar_write64(val, dst, lock) __mlx5_uar_write64(val, dst, lock) #endif -/* CQE status. */ -enum mlx5_cqe_status { - MLX5_CQE_STATUS_SW_OWN = -1, - MLX5_CQE_STATUS_HW_OWN = -2, - MLX5_CQE_STATUS_ERR = -3, -}; - -/** - * Check whether CQE is valid. - * - * @param cqe - * Pointer to CQE. - * @param cqes_n - * Size of completion queue. - * @param ci - * Consumer index. - * - * @return - * The CQE status. - */ -static __rte_always_inline enum mlx5_cqe_status -check_cqe(volatile struct mlx5_cqe *cqe, const uint16_t cqes_n, - const uint16_t ci) -{ - const uint16_t idx = ci & cqes_n; - const uint8_t op_own = cqe->op_own; - const uint8_t op_owner = MLX5_CQE_OWNER(op_own); - const uint8_t op_code = MLX5_CQE_OPCODE(op_own); - - if (unlikely((op_owner != (!!(idx))) || (op_code == MLX5_CQE_INVALID))) - return MLX5_CQE_STATUS_HW_OWN; - rte_cio_rmb(); - if (unlikely(op_code == MLX5_CQE_RESP_ERR || - op_code == MLX5_CQE_REQ_ERR)) - return MLX5_CQE_STATUS_ERR; - return MLX5_CQE_STATUS_SW_OWN; -} - /** * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which the * cloned mbuf is allocated is returned instead. From patchwork Wed Jan 29 12:38:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65314 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4F79EA052F; Wed, 29 Jan 2020 13:40:08 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5A74A1BFF6; Wed, 29 Jan 2020 13:39:28 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 28CE41BF74 for ; Wed, 29 Jan 2020 13:39:25 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:22 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1f018914; Wed, 29 Jan 2020 14:39:22 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:32 +0000 Message-Id: <1580301530-6643-8-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 07/25] common/mlx5: add query vDPA DevX capabilities X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add the DevX capabilities for vDPA configuration and information of Mellanox devices. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 90 ++++++++++++++++++++++++++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 24 ++++++++++ drivers/common/mlx5/mlx5_prm.h | 45 ++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 4d94f92..3a10ff0 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -285,6 +285,91 @@ struct mlx5_devx_obj * } /** + * Query NIC vDPA attributes. + * + * @param[in] ctx + * ibv contexts returned from mlx5dv_open_device. + * @param[out] vdpa_attr + * vDPA Attributes structure to fill. + */ +static void +mlx5_devx_cmd_query_hca_vdpa_attr(struct ibv_context *ctx, + struct mlx5_hca_vdpa_attr *vdpa_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; + void *hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); + int status, syndrome, rc; + + MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION | + MLX5_HCA_CAP_OPMOD_GET_CUR); + rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); + status = MLX5_GET(query_hca_cap_out, out, status); + syndrome = MLX5_GET(query_hca_cap_out, out, syndrome); + if (rc || status) { + RTE_LOG(DEBUG, PMD, "Failed to query devx VDPA capabilities," + " status %x, syndrome = %x", status, syndrome); + vdpa_attr->valid = 0; + } else { + vdpa_attr->valid = 1; + vdpa_attr->desc_tunnel_offload_type = + MLX5_GET(virtio_emulation_cap, hcattr, + desc_tunnel_offload_type); + vdpa_attr->eth_frame_offload_type = + MLX5_GET(virtio_emulation_cap, hcattr, + eth_frame_offload_type); + vdpa_attr->virtio_version_1_0 = + MLX5_GET(virtio_emulation_cap, hcattr, + virtio_version_1_0); + vdpa_attr->tso_ipv4 = MLX5_GET(virtio_emulation_cap, hcattr, + tso_ipv4); + vdpa_attr->tso_ipv6 = MLX5_GET(virtio_emulation_cap, hcattr, + tso_ipv6); + vdpa_attr->tx_csum = MLX5_GET(virtio_emulation_cap, hcattr, + tx_csum); + vdpa_attr->rx_csum = MLX5_GET(virtio_emulation_cap, hcattr, + rx_csum); + vdpa_attr->event_mode = MLX5_GET(virtio_emulation_cap, hcattr, + event_mode); + vdpa_attr->virtio_queue_type = + MLX5_GET(virtio_emulation_cap, hcattr, + virtio_queue_type); + vdpa_attr->log_doorbell_stride = + MLX5_GET(virtio_emulation_cap, hcattr, + log_doorbell_stride); + vdpa_attr->log_doorbell_bar_size = + MLX5_GET(virtio_emulation_cap, hcattr, + log_doorbell_bar_size); + vdpa_attr->doorbell_bar_offset = + MLX5_GET64(virtio_emulation_cap, hcattr, + doorbell_bar_offset); + vdpa_attr->max_num_virtio_queues = + MLX5_GET(virtio_emulation_cap, hcattr, + max_num_virtio_queues); + vdpa_attr->umem_1_buffer_param_a = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_1_buffer_param_a); + vdpa_attr->umem_1_buffer_param_b = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_1_buffer_param_b); + vdpa_attr->umem_2_buffer_param_a = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_2_buffer_param_a); + vdpa_attr->umem_2_buffer_param_b = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_2_buffer_param_a); + vdpa_attr->umem_3_buffer_param_a = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_3_buffer_param_a); + vdpa_attr->umem_3_buffer_param_b = + MLX5_GET(virtio_emulation_cap, hcattr, + umem_3_buffer_param_b); + } +} + +/** * Query HCA attributes. * Using those attributes we can check on run time if the device * is having the required capabilities. @@ -343,6 +428,9 @@ struct mlx5_devx_obj * attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, flex_parser_protocols); attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); + attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types) & + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q); if (attr->qos.sup) { MLX5_SET(query_hca_cap_in, in, op_mod, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | @@ -367,6 +455,8 @@ struct mlx5_devx_obj * attr->qos.flow_meter_reg_share = MLX5_GET(qos_cap, hcattr, flow_meter_reg_share); } + if (attr->vdpa.valid) + mlx5_devx_cmd_query_hca_vdpa_attr(ctx, &attr->vdpa); if (!attr->eth_net_offloads) return 0; diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 2d58d96..c1c9e99 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -34,6 +34,29 @@ struct mlx5_hca_qos_attr { }; +struct mlx5_hca_vdpa_attr { + uint8_t virtio_queue_type; + uint32_t valid:1; + uint32_t desc_tunnel_offload_type:1; + uint32_t eth_frame_offload_type:1; + uint32_t virtio_version_1_0:1; + uint32_t tso_ipv4:1; + uint32_t tso_ipv6:1; + uint32_t tx_csum:1; + uint32_t rx_csum:1; + uint32_t event_mode:3; + uint32_t log_doorbell_stride:5; + uint32_t log_doorbell_bar_size:5; + uint32_t max_num_virtio_queues; + uint32_t umem_1_buffer_param_a; + uint32_t umem_1_buffer_param_b; + uint32_t umem_2_buffer_param_a; + uint32_t umem_2_buffer_param_b; + uint32_t umem_3_buffer_param_a; + uint32_t umem_3_buffer_param_b; + uint64_t doorbell_bar_offset; +}; + /* HCA supports this number of time periods for LRO. */ #define MLX5_LRO_NUM_SUPP_PERIODS 4 @@ -62,6 +85,7 @@ struct mlx5_hca_attr { uint32_t log_max_hairpin_num_packets:5; uint32_t vhca_id:16; struct mlx5_hca_qos_attr qos; + struct mlx5_hca_vdpa_attr vdpa; }; struct mlx5_devx_wq_attr { diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 5730ad1..efd6ad4 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -881,6 +881,11 @@ enum { MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0 << 1, MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS = 0x1 << 1, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP = 0xc << 1, + MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION = 0x13 << 1, +}; + +enum { + MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q = (1ULL << 0xd), }; enum { @@ -1256,11 +1261,51 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits { u8 reserved_at_200[0x600]; }; +enum { + MLX5_VIRTQ_TYPE_SPLIT = 0, + MLX5_VIRTQ_TYPE_PACKED = 1, +}; + +enum { + MLX5_VIRTQ_EVENT_MODE_NO_MSIX = 0, + MLX5_VIRTQ_EVENT_MODE_QP = 1, + MLX5_VIRTQ_EVENT_MODE_MSIX = 2, +}; + +struct mlx5_ifc_virtio_emulation_cap_bits { + u8 desc_tunnel_offload_type[0x1]; + u8 eth_frame_offload_type[0x1]; + u8 virtio_version_1_0[0x1]; + u8 tso_ipv4[0x1]; + u8 tso_ipv6[0x1]; + u8 tx_csum[0x1]; + u8 rx_csum[0x1]; + u8 reserved_at_7[0x1][0x9]; + u8 event_mode[0x8]; + u8 virtio_queue_type[0x8]; + u8 reserved_at_20[0x13]; + u8 log_doorbell_stride[0x5]; + u8 reserved_at_3b[0x3]; + u8 log_doorbell_bar_size[0x5]; + u8 doorbell_bar_offset[0x40]; + u8 reserved_at_80[0x8]; + u8 max_num_virtio_queues[0x18]; + u8 reserved_at_a0[0x60]; + u8 umem_1_buffer_param_a[0x20]; + u8 umem_1_buffer_param_b[0x20]; + u8 umem_2_buffer_param_a[0x20]; + u8 umem_2_buffer_param_b[0x20]; + u8 umem_3_buffer_param_a[0x20]; + u8 umem_3_buffer_param_b[0x20]; + u8 reserved_at_1c0[0x620]; +}; + union mlx5_ifc_hca_cap_union_bits { struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap; struct mlx5_ifc_per_protocol_networking_offload_caps_bits per_protocol_networking_offload_caps; struct mlx5_ifc_qos_cap_bits qos_cap; + struct mlx5_ifc_virtio_emulation_cap_bits vdpa_caps; u8 reserved_at_0[0x8000]; }; From patchwork Wed Jan 29 12:38:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65316 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 19E9DA052F; Wed, 29 Jan 2020 13:40:29 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4DF2B1C00D; Wed, 29 Jan 2020 13:39:33 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 392901BFFB for ; Wed, 29 Jan 2020 13:39:30 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:26 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1g018914; Wed, 29 Jan 2020 14:39:26 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:33 +0000 Message-Id: <1580301530-6643-9-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 08/25] common/mlx5: glue null memory region allocation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for rdma-core API to allocate NULL MR. When the device HW get a NULL MR address, it will do nothing with the address, no read and no write. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_glue.c | 13 +++++++++++++ drivers/common/mlx5/mlx5_glue.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c index d5bc84e..e75e6bc 100644 --- a/drivers/common/mlx5/mlx5_glue.c +++ b/drivers/common/mlx5/mlx5_glue.c @@ -226,6 +226,18 @@ return ibv_reg_mr(pd, addr, length, access); } +static struct ibv_mr * +mlx5_glue_alloc_null_mr(struct ibv_pd *pd) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return ibv_alloc_null_mr(pd); +#else + (void)pd; + errno = ENOTSUP; + return NULL; +#endif +} + static int mlx5_glue_dereg_mr(struct ibv_mr *mr) { @@ -1070,6 +1082,7 @@ .destroy_qp = mlx5_glue_destroy_qp, .modify_qp = mlx5_glue_modify_qp, .reg_mr = mlx5_glue_reg_mr, + .alloc_null_mr = mlx5_glue_alloc_null_mr, .dereg_mr = mlx5_glue_dereg_mr, .create_counter_set = mlx5_glue_create_counter_set, .destroy_counter_set = mlx5_glue_destroy_counter_set, diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h index f4c3180..33afaf4 100644 --- a/drivers/common/mlx5/mlx5_glue.h +++ b/drivers/common/mlx5/mlx5_glue.h @@ -138,6 +138,7 @@ struct mlx5_glue { int attr_mask); struct ibv_mr *(*reg_mr)(struct ibv_pd *pd, void *addr, size_t length, int access); + struct ibv_mr *(*alloc_null_mr)(struct ibv_pd *pd); int (*dereg_mr)(struct ibv_mr *mr); struct ibv_counter_set *(*create_counter_set) (struct ibv_context *context, From patchwork Wed Jan 29 12:38:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65315 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C888BA052F; Wed, 29 Jan 2020 13:40:19 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E2CCA1BFFB; Wed, 29 Jan 2020 13:39:31 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 313861BFD1 for ; Wed, 29 Jan 2020 13:39:30 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:29 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1h018914; Wed, 29 Jan 2020 14:39:29 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:34 +0000 Message-Id: <1580301530-6643-10-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 09/25] common/mlx5: support DevX indirect mkey creation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add option to create an indirect mkey by the current mlx5_devx_cmd_mkey_create command. Indirect mkey points to set of direct mkeys. By this way, the HW\SW can reference fragmented memory by one object. Align the net/mlx5 driver usage in the above command. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 43 ++++++++++++++++++++++++++++++------ drivers/common/mlx5/mlx5_devx_cmds.h | 17 ++++++++++++++ drivers/common/mlx5/mlx5_prm.h | 12 ++++++++++ drivers/net/mlx5/mlx5_flow_dv.c | 4 ++++ 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 3a10ff0..2197705 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -142,7 +142,11 @@ struct mlx5_devx_obj * mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, struct mlx5_devx_mkey_attr *attr) { - uint32_t in[MLX5_ST_SZ_DW(create_mkey_in)] = {0}; + struct mlx5_klm *klm_array = attr->klm_array; + int klm_num = attr->klm_num; + int in_size_dw = MLX5_ST_SZ_DW(create_mkey_in) + + (klm_num ? RTE_ALIGN(klm_num, 4) : 0) * MLX5_ST_SZ_DW(klm); + uint32_t in[in_size_dw]; uint32_t out[MLX5_ST_SZ_DW(create_mkey_out)] = {0}; void *mkc; struct mlx5_devx_obj *mkey = rte_zmalloc("mkey", sizeof(*mkey), 0); @@ -153,27 +157,52 @@ struct mlx5_devx_obj * rte_errno = ENOMEM; return NULL; } + memset(in, 0, in_size_dw * 4); pgsize = sysconf(_SC_PAGESIZE); - translation_size = (RTE_ALIGN(attr->size, pgsize) * 8) / 16; 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) { + int i; + uint8_t *klm = (uint8_t *)MLX5_ADDR_OF(create_mkey_in, in, + klm_pas_mtt); + translation_size = RTE_ALIGN(klm_num, 4); + for (i = 0; i < klm_num; i++) { + MLX5_SET(klm, klm, byte_count, klm_array[i].byte_count); + MLX5_SET(klm, klm, mkey, klm_array[i].mkey); + MLX5_SET64(klm, klm, address, klm_array[i].address); + klm += MLX5_ST_SZ_BYTES(klm); + } + for (; i < (int)translation_size; i++) { + MLX5_SET(klm, klm, mkey, 0x0); + MLX5_SET64(klm, klm, address, 0x0); + klm += MLX5_ST_SZ_BYTES(klm); + } + MLX5_SET(mkc, mkc, access_mode_1_0, attr->log_entity_size ? + MLX5_MKC_ACCESS_MODE_KLM_FBS : + MLX5_MKC_ACCESS_MODE_KLM); + MLX5_SET(mkc, mkc, log_page_size, attr->log_entity_size); + } else { + translation_size = (RTE_ALIGN(attr->size, pgsize) * 8) / 16; + MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT); + MLX5_SET(mkc, mkc, log_page_size, rte_log2_u32(pgsize)); + } MLX5_SET(create_mkey_in, in, translations_octword_actual_size, translation_size); MLX5_SET(create_mkey_in, in, mkey_umem_id, attr->umem_id); - mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry); + MLX5_SET(create_mkey_in, in, pg_access, attr->pg_access); MLX5_SET(mkc, mkc, lw, 0x1); MLX5_SET(mkc, mkc, lr, 0x1); - MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT); MLX5_SET(mkc, mkc, qpn, 0xffffff); MLX5_SET(mkc, mkc, pd, attr->pd); MLX5_SET(mkc, mkc, mkey_7_0, attr->umem_id & 0xFF); MLX5_SET(mkc, mkc, translations_octword_size, translation_size); MLX5_SET64(mkc, mkc, start_addr, attr->addr); MLX5_SET64(mkc, mkc, len, attr->size); - MLX5_SET(mkc, mkc, log_page_size, rte_log2_u32(pgsize)); - mkey->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + mkey->obj = mlx5_glue->devx_obj_create(ctx, in, in_size_dw * 4, out, sizeof(out)); if (!mkey->obj) { - DRV_LOG(ERR, "Can't create mkey - error %d", errno); + DRV_LOG(ERR, "Can't create %sdirect mkey - error %d\n", + klm_num ? "an in" : "a ", errno); rte_errno = errno; rte_free(mkey); return NULL; diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index c1c9e99..c76c172 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -6,6 +6,7 @@ #define RTE_PMD_MLX5_DEVX_CMDS_H_ #include "mlx5_glue.h" +#include "mlx5_prm.h" /* devX creation object */ @@ -14,11 +15,26 @@ struct mlx5_devx_obj { int id; /* The object ID. */ }; +/* UMR memory buffer used to define 1 entry in indirect mkey. */ +struct mlx5_klm { + uint32_t byte_count; + uint32_t mkey; + uint64_t address; +}; + +/* This is limitation of libibverbs: in length variable type is u16. */ +#define MLX5_DEVX_MAX_KLM_ENTRIES ((UINT16_MAX - \ + MLX5_ST_SZ_DW(create_mkey_in) * 4) / (MLX5_ST_SZ_DW(klm) * 4)) + struct mlx5_devx_mkey_attr { uint64_t addr; uint64_t size; uint32_t umem_id; uint32_t pd; + uint32_t log_entity_size; + uint32_t pg_access:1; + struct mlx5_klm *klm_array; + int klm_num; }; /* HCA qos attributes. */ @@ -216,6 +232,7 @@ struct mlx5_devx_modify_sq_attr { uint32_t hairpin_peer_vhca:16; }; + /* mlx5_devx_cmds.c */ struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index efd6ad4..db15bb6 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -726,6 +726,8 @@ enum { enum { MLX5_MKC_ACCESS_MODE_MTT = 0x1, + MLX5_MKC_ACCESS_MODE_KLM = 0x2, + MLX5_MKC_ACCESS_MODE_KLM_FBS = 0x3, }; /* Flow counters. */ @@ -790,6 +792,16 @@ struct mlx5_ifc_query_flow_counter_in_bits { u8 flow_counter_id[0x20]; }; +#define MLX5_MAX_KLM_BYTE_COUNT 0x80000000u +#define MLX5_MIN_KLM_FIXED_BUFFER_SIZE 0x1000u + + +struct mlx5_ifc_klm_bits { + u8 byte_count[0x20]; + u8 mkey[0x20]; + u8 address[0x40]; +}; + struct mlx5_ifc_mkc_bits { u8 reserved_at_0[0x1]; u8 free[0x1]; diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 1b31602..5610d94 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3885,6 +3885,10 @@ struct field_modify_info modify_tcp[] = { mkey_attr.size = size; mkey_attr.umem_id = mem_mng->umem->umem_id; mkey_attr.pd = sh->pdn; + mkey_attr.log_entity_size = 0; + mkey_attr.pg_access = 0; + mkey_attr.klm_array = NULL; + mkey_attr.klm_num = 0; mem_mng->dm = mlx5_devx_cmd_mkey_create(sh->ctx, &mkey_attr); if (!mem_mng->dm) { mlx5_glue->devx_umem_dereg(mem_mng->umem); From patchwork Wed Jan 29 12:38:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65319 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E49A8A052F; Wed, 29 Jan 2020 13:41:08 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4BBCA1C02A; Wed, 29 Jan 2020 13:39:40 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 4ECB41C01B for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:30 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1i018914; Wed, 29 Jan 2020 14:39:30 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:35 +0000 Message-Id: <1580301530-6643-11-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 10/25] common/mlx5: glue event queue query X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The event queue is managed only by the kernel. Add the rdma-core command in glue to query the kernel event queue details. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_glue.c | 15 +++++++++++++++ drivers/common/mlx5/mlx5_glue.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c index e75e6bc..fedce77 100644 --- a/drivers/common/mlx5/mlx5_glue.c +++ b/drivers/common/mlx5/mlx5_glue.c @@ -1049,6 +1049,20 @@ #endif } +static int +mlx5_glue_devx_query_eqn(struct ibv_context *ctx, uint32_t cpus, + uint32_t *eqn) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_query_eqn(ctx, cpus, eqn); +#else + (void)ctx; + (void)cpus; + (void)eqn; + return -ENOTSUP; +#endif +} + alignas(RTE_CACHE_LINE_SIZE) const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ .version = MLX5_GLUE_VERSION, @@ -1148,4 +1162,5 @@ .devx_qp_query = mlx5_glue_devx_qp_query, .devx_port_query = mlx5_glue_devx_port_query, .dr_dump_domain = mlx5_glue_dr_dump_domain, + .devx_query_eqn = mlx5_glue_devx_query_eqn, }; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h index 33afaf4..fe51f97 100644 --- a/drivers/common/mlx5/mlx5_glue.h +++ b/drivers/common/mlx5/mlx5_glue.h @@ -259,6 +259,8 @@ struct mlx5_glue { uint32_t port_num, struct mlx5dv_devx_port *mlx5_devx_port); int (*dr_dump_domain)(FILE *file, void *domain); + int (*devx_query_eqn)(struct ibv_context *context, uint32_t cpus, + uint32_t *eqn); }; const struct mlx5_glue *mlx5_glue; From patchwork Wed Jan 29 12:38:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65317 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id C8238A052F; Wed, 29 Jan 2020 13:40:42 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B758B1BFED; Wed, 29 Jan 2020 13:39:37 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 3D5851BFF5 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:30 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1j018914; Wed, 29 Jan 2020 14:39:30 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:36 +0000 Message-Id: <1580301530-6643-12-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 11/25] common/mlx5: glue event interrupt commands X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add the next commands to glue in order to support interrupt event channel operations associated to events in the EQ: devx_create_event_channel, devx_destroy_event_channel, devx_subscribe_devx_event, devx_subscribe_devx_event_fd, devx_get_event. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 5 +++ drivers/common/mlx5/meson.build | 2 ++ drivers/common/mlx5/mlx5_glue.c | 79 +++++++++++++++++++++++++++++++++++++++++ drivers/common/mlx5/mlx5_glue.h | 25 +++++++++++++ 4 files changed, 111 insertions(+) diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 66585b2..7110231 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -154,6 +154,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh func mlx5dv_dr_action_create_dest_devx_tir \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_IBV_DEVX_EVENT \ + infiniband/mlx5dv.h \ + func mlx5dv_devx_get_event \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER \ infiniband/mlx5dv.h \ func mlx5dv_dr_action_create_flow_meter \ diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 718cef2..76ca7d7 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -108,6 +108,8 @@ if build 'mlx5dv_devx_obj_query_async' ], [ 'HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR', 'infiniband/mlx5dv.h', 'mlx5dv_dr_action_create_dest_devx_tir' ], + [ 'HAVE_IBV_DEVX_EVENT', 'infiniband/mlx5dv.h', + 'mlx5dv_devx_get_event' ], [ 'HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER', 'infiniband/mlx5dv.h', 'mlx5dv_dr_action_create_flow_meter' ], [ 'HAVE_MLX5DV_MMAP_GET_NC_PAGES_CMD', 'infiniband/mlx5dv.h', diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c index fedce77..e4eabdb 100644 --- a/drivers/common/mlx5/mlx5_glue.c +++ b/drivers/common/mlx5/mlx5_glue.c @@ -1063,6 +1063,80 @@ #endif } +static struct mlx5dv_devx_event_channel * +mlx5_glue_devx_create_event_channel(struct ibv_context *ctx, int flags) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_create_event_channel(ctx, flags); +#else + (void)ctx; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_destroy_event_channel(struct mlx5dv_devx_event_channel *eventc) +{ +#ifdef HAVE_IBV_DEVX_EVENT + mlx5dv_devx_destroy_event_channel(eventc); +#else + (void)eventc; +#endif +} + +static int +mlx5_glue_devx_subscribe_devx_event(struct mlx5dv_devx_event_channel *eventc, + struct mlx5dv_devx_obj *obj, + uint16_t events_sz, uint16_t events_num[], + uint64_t cookie) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_subscribe_devx_event(eventc, obj, events_sz, + events_num, cookie); +#else + (void)eventc; + (void)obj; + (void)events_sz; + (void)events_num; + (void)cookie; + return -ENOTSUP; +#endif +} + +static int +mlx5_glue_devx_subscribe_devx_event_fd(struct mlx5dv_devx_event_channel *eventc, + int fd, struct mlx5dv_devx_obj *obj, + uint16_t event_num) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_subscribe_devx_event_fd(eventc, fd, obj, event_num); +#else + (void)eventc; + (void)fd; + (void)obj; + (void)event_num; + return -ENOTSUP; +#endif +} + +static ssize_t +mlx5_glue_devx_get_event(struct mlx5dv_devx_event_channel *eventc, + struct mlx5dv_devx_async_event_hdr *event_data, + size_t event_resp_len) +{ +#ifdef HAVE_IBV_DEVX_EVENT + return mlx5dv_devx_get_event(eventc, event_data, event_resp_len); +#else + (void)eventc; + (void)event_data; + (void)event_resp_len; + errno = ENOTSUP; + return -1; +#endif +} + alignas(RTE_CACHE_LINE_SIZE) const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ .version = MLX5_GLUE_VERSION, @@ -1163,4 +1237,9 @@ .devx_port_query = mlx5_glue_devx_port_query, .dr_dump_domain = mlx5_glue_dr_dump_domain, .devx_query_eqn = mlx5_glue_devx_query_eqn, + .devx_create_event_channel = mlx5_glue_devx_create_event_channel, + .devx_destroy_event_channel = mlx5_glue_devx_destroy_event_channel, + .devx_subscribe_devx_event = mlx5_glue_devx_subscribe_devx_event, + .devx_subscribe_devx_event_fd = mlx5_glue_devx_subscribe_devx_event_fd, + .devx_get_event = mlx5_glue_devx_get_event, }; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h index fe51f97..6fc00dd 100644 --- a/drivers/common/mlx5/mlx5_glue.h +++ b/drivers/common/mlx5/mlx5_glue.h @@ -86,6 +86,12 @@ struct mlx5dv_dr_flow_meter_attr; #endif +#ifndef HAVE_IBV_DEVX_EVENT +struct mlx5dv_devx_event_channel { int fd; }; +struct mlx5dv_devx_async_event_hdr; +#define MLX5DV_DEVX_CREATE_EVENT_CHANNEL_FLAGS_OMIT_EV_DATA 1 +#endif + /* LIB_GLUE_VERSION must be updated every time this structure is modified. */ struct mlx5_glue { const char *version; @@ -261,6 +267,25 @@ struct mlx5_glue { int (*dr_dump_domain)(FILE *file, void *domain); int (*devx_query_eqn)(struct ibv_context *context, uint32_t cpus, uint32_t *eqn); + struct mlx5dv_devx_event_channel *(*devx_create_event_channel) + (struct ibv_context *context, int flags); + void (*devx_destroy_event_channel) + (struct mlx5dv_devx_event_channel *event_channel); + int (*devx_subscribe_devx_event) + (struct mlx5dv_devx_event_channel *event_channel, + struct mlx5dv_devx_obj *obj, + uint16_t events_sz, + uint16_t events_num[], + uint64_t cookie); + int (*devx_subscribe_devx_event_fd) + (struct mlx5dv_devx_event_channel *event_channel, + int fd, + struct mlx5dv_devx_obj *obj, + uint16_t event_num); + ssize_t (*devx_get_event) + (struct mlx5dv_devx_event_channel *event_channel, + struct mlx5dv_devx_async_event_hdr *event_data, + size_t event_resp_len); }; const struct mlx5_glue *mlx5_glue; From patchwork Wed Jan 29 12:38:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65320 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id BE27AA052F; Wed, 29 Jan 2020 13:41:20 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A64031C030; Wed, 29 Jan 2020 13:39:41 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 5837B1C023 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1k018914; Wed, 29 Jan 2020 14:39:30 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:37 +0000 Message-Id: <1580301530-6643-13-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 12/25] common/mlx5: glue UAR allocation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The isolated, protected and independent direct access to the HW by multiple processes is implemented via User Access Region (UAR) mechanism. The UAR is part of PCI address space that is mapped for direct access to the HW from the CPU. UAR is comprised of multiple pages, each page containing registers that control the HW operation. UAR mechanism is used to post execution or control requests to the HW. It is used by the HW to enforce protection and isolation between different processes. Add a glue command to allocate and free an UAR. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_glue.c | 25 +++++++++++++++++++++++++ drivers/common/mlx5/mlx5_glue.h | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c index e4eabdb..5691636 100644 --- a/drivers/common/mlx5/mlx5_glue.c +++ b/drivers/common/mlx5/mlx5_glue.c @@ -1137,6 +1137,29 @@ #endif } +static struct mlx5dv_devx_uar * +mlx5_glue_devx_alloc_uar(struct ibv_context *context, uint32_t flags) +{ +#ifdef HAVE_IBV_DEVX_OBJ + return mlx5dv_devx_alloc_uar(context, flags); +#else + (void)context; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_devx_free_uar(struct mlx5dv_devx_uar *devx_uar) +{ +#ifdef HAVE_IBV_DEVX_OBJ + mlx5dv_devx_free_uar(devx_uar); +#else + (void)devx_uar; +#endif +} + alignas(RTE_CACHE_LINE_SIZE) const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ .version = MLX5_GLUE_VERSION, @@ -1242,4 +1265,6 @@ .devx_subscribe_devx_event = mlx5_glue_devx_subscribe_devx_event, .devx_subscribe_devx_event_fd = mlx5_glue_devx_subscribe_devx_event_fd, .devx_get_event = mlx5_glue_devx_get_event, + .devx_alloc_uar = mlx5_glue_devx_alloc_uar, + .devx_free_uar = mlx5_glue_devx_free_uar, }; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h index 6fc00dd..7d9256e 100644 --- a/drivers/common/mlx5/mlx5_glue.h +++ b/drivers/common/mlx5/mlx5_glue.h @@ -66,6 +66,7 @@ #ifndef HAVE_IBV_DEVX_OBJ struct mlx5dv_devx_obj; struct mlx5dv_devx_umem { uint32_t umem_id; }; +struct mlx5dv_devx_uar { void *reg_addr; void *base_addr; uint32_t page_id; }; #endif #ifndef HAVE_IBV_DEVX_ASYNC @@ -230,6 +231,9 @@ struct mlx5_glue { int (*dv_destroy_flow)(void *flow); int (*dv_destroy_flow_matcher)(void *matcher); struct ibv_context *(*dv_open_device)(struct ibv_device *device); + struct mlx5dv_devx_uar *(*devx_alloc_uar)(struct ibv_context *context, + uint32_t flags); + void (*devx_free_uar)(struct mlx5dv_devx_uar *devx_uar); struct mlx5dv_devx_obj *(*devx_obj_create) (struct ibv_context *ctx, const void *in, size_t inlen, From patchwork Wed Jan 29 12:38:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65318 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6A52FA052F; Wed, 29 Jan 2020 13:40:56 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 042521C023; Wed, 29 Jan 2020 13:39:39 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 3DB321C014 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1l018914; Wed, 29 Jan 2020 14:39:30 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:38 +0000 Message-Id: <1580301530-6643-14-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 13/25] common/mlx5: add DevX command to create CQ X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" HW implements completion queues(CQ) used to post completion reports upon completion of work request. Used for Rx and Tx datapath. Add DevX command to create a CQ. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 57 ++++++++++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 19 +++++++ drivers/common/mlx5/mlx5_prm.h | 71 +++++++++++++++++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 1 + 4 files changed, 148 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 2197705..cdc041b 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -1093,3 +1093,60 @@ struct mlx5_devx_obj * #endif return -ret; } + +/* + * Create CQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] attr + * Pointer to CQ attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_cq(struct ibv_context *ctx, struct mlx5_devx_cq_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_cq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_cq_out)] = {0}; + struct mlx5_devx_obj *cq_obj = rte_zmalloc(__func__, sizeof(*cq_obj), + 0); + void *cqctx = MLX5_ADDR_OF(create_cq_in, in, cq_context); + + if (!cq_obj) { + DRV_LOG(ERR, "Failed to allocate CQ object memory."); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_cq_in, in, opcode, MLX5_CMD_OP_CREATE_CQ); + if (attr->db_umem_valid) { + MLX5_SET(cqc, cqctx, dbr_umem_valid, attr->db_umem_valid); + MLX5_SET(cqc, cqctx, dbr_umem_id, attr->db_umem_id); + MLX5_SET64(cqc, cqctx, dbr_addr, attr->db_umem_offset); + } else { + MLX5_SET64(cqc, cqctx, dbr_addr, attr->db_addr); + } + MLX5_SET(cqc, cqctx, cc, attr->use_first_only); + MLX5_SET(cqc, cqctx, oi, attr->overrun_ignore); + MLX5_SET(cqc, cqctx, log_cq_size, attr->log_cq_size); + MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size); + MLX5_SET(cqc, cqctx, c_eqn, attr->eqn); + MLX5_SET(cqc, cqctx, uar_page, attr->uar_page_id); + if (attr->q_umem_valid) { + MLX5_SET(create_cq_in, in, cq_umem_valid, attr->q_umem_valid); + MLX5_SET(create_cq_in, in, cq_umem_id, attr->q_umem_id); + MLX5_SET64(create_cq_in, in, cq_umem_offset, + attr->q_umem_offset); + } + cq_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!cq_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create CQ using DevX errno=%d.", errno); + rte_free(cq_obj); + return NULL; + } + cq_obj->id = MLX5_GET(create_cq_out, out, cqn); + return cq_obj; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index c76c172..581658b 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -233,6 +233,23 @@ struct mlx5_devx_modify_sq_attr { }; +/* CQ attributes structure, used by CQ operations. */ +struct mlx5_devx_cq_attr { + uint32_t q_umem_valid:1; + uint32_t db_umem_valid:1; + uint32_t use_first_only:1; + uint32_t overrun_ignore:1; + uint32_t log_cq_size:5; + uint32_t log_page_size:5; + uint32_t uar_page_id; + uint32_t q_umem_id; + uint64_t q_umem_offset; + uint32_t db_umem_id; + uint64_t db_umem_offset; + uint32_t eqn; + uint64_t db_addr; +}; + /* mlx5_devx_cmds.c */ struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, @@ -269,4 +286,6 @@ struct mlx5_devx_obj *mlx5_devx_cmd_create_tis(struct ibv_context *ctx, struct mlx5_devx_obj *mlx5_devx_cmd_create_td(struct ibv_context *ctx); int mlx5_devx_cmd_flow_dump(void *fdb_domain, void *rx_domain, void *tx_domain, FILE *file); +struct mlx5_devx_obj *mlx5_devx_cmd_create_cq(struct ibv_context *ctx, + struct mlx5_devx_cq_attr *attr); #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index db15bb6..a4082b9 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -710,6 +710,7 @@ enum { enum { MLX5_CMD_OP_QUERY_HCA_CAP = 0x100, MLX5_CMD_OP_CREATE_MKEY = 0x200, + MLX5_CMD_OP_CREATE_CQ = 0x400, MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754, MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN = 0x816, MLX5_CMD_OP_CREATE_TIR = 0x900, @@ -1846,6 +1847,76 @@ struct mlx5_ifc_flow_meter_parameters_bits { u8 reserved_at_8[0x60]; // 14h-1Ch }; +struct mlx5_ifc_cqc_bits { + u8 status[0x4]; + u8 as_notify[0x1]; + u8 initiator_src_dct[0x1]; + u8 dbr_umem_valid[0x1]; + u8 reserved_at_7[0x1]; + u8 cqe_sz[0x3]; + u8 cc[0x1]; + u8 reserved_at_c[0x1]; + u8 scqe_break_moderation_en[0x1]; + u8 oi[0x1]; + u8 cq_period_mode[0x2]; + u8 cqe_comp_en[0x1]; + u8 mini_cqe_res_format[0x2]; + u8 st[0x4]; + u8 reserved_at_18[0x8]; + u8 dbr_umem_id[0x20]; + u8 reserved_at_40[0x14]; + u8 page_offset[0x6]; + u8 reserved_at_5a[0x6]; + u8 reserved_at_60[0x3]; + u8 log_cq_size[0x5]; + u8 uar_page[0x18]; + u8 reserved_at_80[0x4]; + u8 cq_period[0xc]; + u8 cq_max_count[0x10]; + u8 reserved_at_a0[0x18]; + u8 c_eqn[0x8]; + u8 reserved_at_c0[0x3]; + u8 log_page_size[0x5]; + u8 reserved_at_c8[0x18]; + u8 reserved_at_e0[0x20]; + u8 reserved_at_100[0x8]; + u8 last_notified_index[0x18]; + u8 reserved_at_120[0x8]; + u8 last_solicit_index[0x18]; + u8 reserved_at_140[0x8]; + u8 consumer_counter[0x18]; + u8 reserved_at_160[0x8]; + u8 producer_counter[0x18]; + u8 local_partition_id[0xc]; + u8 process_id[0x14]; + u8 reserved_at_1A0[0x20]; + u8 dbr_addr[0x40]; +}; + +struct mlx5_ifc_create_cq_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 cqn[0x18]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_create_cq_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x40]; + struct mlx5_ifc_cqc_bits cq_context; + u8 cq_umem_offset[0x40]; + u8 cq_umem_id[0x20]; + u8 cq_umem_valid[0x1]; + u8 reserved_at_2e1[0x1f]; + u8 reserved_at_300[0x580]; + u8 pas[]; +}; + /* CQE format mask. */ #define MLX5E_CQE_FORMAT_MASK 0xc diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index 0c01172..c6a203d 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -1,6 +1,7 @@ DPDK_20.02 { global: + mlx5_devx_cmd_create_cq; mlx5_devx_cmd_create_rq; mlx5_devx_cmd_create_rqt; mlx5_devx_cmd_create_sq; From patchwork Wed Jan 29 12:38:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65324 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D8B9FA052F; Wed, 29 Jan 2020 13:42:10 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C4A221C0AC; Wed, 29 Jan 2020 13:39:47 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 64CFF1C026 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1m018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:39 +0000 Message-Id: <1580301530-6643-15-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 14/25] common/mlx5: glue VAR allocation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Virtio access region(VAR) is the UAR that allocated for virtio emulation access. Add rdma-core operations to allocate and free VAR. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 5 +++++ drivers/common/mlx5/meson.build | 1 + drivers/common/mlx5/mlx5_glue.c | 26 ++++++++++++++++++++++++++ drivers/common/mlx5/mlx5_glue.h | 8 ++++++++ 4 files changed, 40 insertions(+) diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 7110231..d1de3ec 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -174,6 +174,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum MLX5_MMAP_GET_NC_PAGES_CMD \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_IBV_VAR \ + infiniband/mlx5dv.h \ + func mlx5dv_alloc_var \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_ETHTOOL_LINK_MODE_25G \ /usr/include/linux/ethtool.h \ enum ETHTOOL_LINK_MODE_25000baseCR_Full_BIT \ diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 76ca7d7..3e130cb 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -120,6 +120,7 @@ if build 'MLX5DV_DR_DOMAIN_TYPE_FDB' ], [ 'HAVE_MLX5DV_DR_VLAN', 'infiniband/mlx5dv.h', 'mlx5dv_dr_action_create_push_vlan' ], + [ 'HAVE_IBV_VAR', 'infiniband/mlx5dv.h', 'mlx5dv_alloc_var' ], [ 'HAVE_SUPPORTED_40000baseKR4_Full', 'linux/ethtool.h', 'SUPPORTED_40000baseKR4_Full' ], [ 'HAVE_SUPPORTED_40000baseCR4_Full', 'linux/ethtool.h', diff --git a/drivers/common/mlx5/mlx5_glue.c b/drivers/common/mlx5/mlx5_glue.c index 5691636..27cf33c 100644 --- a/drivers/common/mlx5/mlx5_glue.c +++ b/drivers/common/mlx5/mlx5_glue.c @@ -1160,6 +1160,30 @@ #endif } +static struct mlx5dv_var * +mlx5_glue_dv_alloc_var(struct ibv_context *context, uint32_t flags) +{ +#ifdef HAVE_IBV_VAR + return mlx5dv_alloc_var(context, flags); +#else + (void)context; + (void)flags; + errno = ENOTSUP; + return NULL; +#endif +} + +static void +mlx5_glue_dv_free_var(struct mlx5dv_var *var) +{ +#ifdef HAVE_IBV_VAR + mlx5dv_free_var(var); +#else + (void)var; + errno = ENOTSUP; +#endif +} + alignas(RTE_CACHE_LINE_SIZE) const struct mlx5_glue *mlx5_glue = &(const struct mlx5_glue){ .version = MLX5_GLUE_VERSION, @@ -1267,4 +1291,6 @@ .devx_get_event = mlx5_glue_devx_get_event, .devx_alloc_uar = mlx5_glue_devx_alloc_uar, .devx_free_uar = mlx5_glue_devx_free_uar, + .dv_alloc_var = mlx5_glue_dv_alloc_var, + .dv_free_var = mlx5_glue_dv_free_var, }; diff --git a/drivers/common/mlx5/mlx5_glue.h b/drivers/common/mlx5/mlx5_glue.h index 7d9256e..6238b43 100644 --- a/drivers/common/mlx5/mlx5_glue.h +++ b/drivers/common/mlx5/mlx5_glue.h @@ -93,6 +93,11 @@ #define MLX5DV_DEVX_CREATE_EVENT_CHANNEL_FLAGS_OMIT_EV_DATA 1 #endif +#ifndef HAVE_IBV_VAR +struct mlx5dv_var { uint32_t page_id; uint32_t length; off_t mmap_off; + uint64_t comp_mask; }; +#endif + /* LIB_GLUE_VERSION must be updated every time this structure is modified. */ struct mlx5_glue { const char *version; @@ -231,6 +236,9 @@ struct mlx5_glue { int (*dv_destroy_flow)(void *flow); int (*dv_destroy_flow_matcher)(void *matcher); struct ibv_context *(*dv_open_device)(struct ibv_device *device); + struct mlx5dv_var *(*dv_alloc_var)(struct ibv_context *context, + uint32_t flags); + void (*dv_free_var)(struct mlx5dv_var *var); struct mlx5dv_devx_uar *(*devx_alloc_uar)(struct ibv_context *context, uint32_t flags); void (*devx_free_uar)(struct mlx5dv_devx_uar *devx_uar); From patchwork Wed Jan 29 12:38:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65322 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1E3DAA052F; Wed, 29 Jan 2020 13:41:40 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3F64F1C045; Wed, 29 Jan 2020 13:39:44 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 610051C025 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1n018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:40 +0000 Message-Id: <1580301530-6643-16-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 15/25] common/mlx5: add DevX virtq commands X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Virtio emulation offload allows SW to offload the I/O operations of a virtio virtqueue, using the device, allowing an improved performance for its users. While supplying all the relevant Virtqueue information (type, size, memory location, doorbell information, etc.). The device can then offload the I/O operation of this queue, according to its device type characteristics. Some of the virtio features can be supported according to the device capability, for example, TSO and checksum. Add virtio queue create, modify and query DevX commands. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 199 +++++++++++++++++++++--- drivers/common/mlx5/mlx5_devx_cmds.h | 48 +++++- drivers/common/mlx5/mlx5_prm.h | 117 ++++++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 3 + 4 files changed, 343 insertions(+), 24 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index cdc041b..2425513 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -377,24 +377,18 @@ struct mlx5_devx_obj * vdpa_attr->max_num_virtio_queues = MLX5_GET(virtio_emulation_cap, hcattr, max_num_virtio_queues); - vdpa_attr->umem_1_buffer_param_a = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_1_buffer_param_a); - vdpa_attr->umem_1_buffer_param_b = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_1_buffer_param_b); - vdpa_attr->umem_2_buffer_param_a = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_2_buffer_param_a); - vdpa_attr->umem_2_buffer_param_b = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_2_buffer_param_a); - vdpa_attr->umem_3_buffer_param_a = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_3_buffer_param_a); - vdpa_attr->umem_3_buffer_param_b = - MLX5_GET(virtio_emulation_cap, hcattr, - umem_3_buffer_param_b); + vdpa_attr->umems[0].a = MLX5_GET(virtio_emulation_cap, hcattr, + umem_1_buffer_param_a); + vdpa_attr->umems[0].b = MLX5_GET(virtio_emulation_cap, hcattr, + umem_1_buffer_param_b); + vdpa_attr->umems[1].a = MLX5_GET(virtio_emulation_cap, hcattr, + umem_2_buffer_param_a); + vdpa_attr->umems[1].b = MLX5_GET(virtio_emulation_cap, hcattr, + umem_2_buffer_param_b); + vdpa_attr->umems[2].a = MLX5_GET(virtio_emulation_cap, hcattr, + umem_3_buffer_param_a); + vdpa_attr->umems[2].b = MLX5_GET(virtio_emulation_cap, hcattr, + umem_3_buffer_param_b); } } @@ -1150,3 +1144,172 @@ struct mlx5_devx_obj * cq_obj->id = MLX5_GET(create_cq_out, out, cqn); return cq_obj; } + +/** + * Create VIRTQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] attr + * Pointer to VIRTQ attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_virtq(struct ibv_context *ctx, + struct mlx5_devx_virtq_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_virtq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; + struct mlx5_devx_obj *virtq_obj = rte_zmalloc(__func__, + sizeof(*virtq_obj), 0); + void *virtq = MLX5_ADDR_OF(create_virtq_in, in, virtq); + void *hdr = MLX5_ADDR_OF(create_virtq_in, in, hdr); + void *virtctx = MLX5_ADDR_OF(virtio_net_q, virtq, virtio_q_context); + + if (!virtq_obj) { + DRV_LOG(ERR, "Failed to allocate virtq data."); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_CREATE_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_GENERAL_OBJ_TYPE_VIRTQ); + MLX5_SET16(virtio_net_q, virtq, hw_available_index, + attr->hw_available_index); + MLX5_SET16(virtio_net_q, virtq, hw_used_index, attr->hw_used_index); + MLX5_SET16(virtio_net_q, virtq, tso_ipv4, attr->tso_ipv4); + MLX5_SET16(virtio_net_q, virtq, tso_ipv6, attr->tso_ipv6); + MLX5_SET16(virtio_net_q, virtq, tx_csum, attr->tx_csum); + MLX5_SET16(virtio_net_q, virtq, rx_csum, attr->rx_csum); + MLX5_SET16(virtio_q, virtctx, virtio_version_1_0, + attr->virtio_version_1_0); + MLX5_SET16(virtio_q, virtctx, event_mode, attr->event_mode); + MLX5_SET(virtio_q, virtctx, event_qpn_or_msix, attr->qp_id); + MLX5_SET64(virtio_q, virtctx, desc_addr, attr->desc_addr); + MLX5_SET64(virtio_q, virtctx, used_addr, attr->used_addr); + MLX5_SET64(virtio_q, virtctx, available_addr, attr->available_addr); + MLX5_SET16(virtio_q, virtctx, queue_index, attr->queue_index); + MLX5_SET16(virtio_q, virtctx, queue_size, attr->q_size); + MLX5_SET(virtio_q, virtctx, virtio_q_mkey, attr->mkey); + MLX5_SET(virtio_q, virtctx, umem_1_id, attr->umems[0].id); + MLX5_SET(virtio_q, virtctx, umem_1_size, attr->umems[0].size); + MLX5_SET64(virtio_q, virtctx, umem_1_offset, attr->umems[0].offset); + MLX5_SET(virtio_q, virtctx, umem_2_id, attr->umems[1].id); + MLX5_SET(virtio_q, virtctx, umem_2_size, attr->umems[1].size); + MLX5_SET64(virtio_q, virtctx, umem_2_offset, attr->umems[1].offset); + MLX5_SET(virtio_q, virtctx, umem_3_id, attr->umems[2].id); + MLX5_SET(virtio_q, virtctx, umem_3_size, attr->umems[2].size); + MLX5_SET64(virtio_q, virtctx, umem_3_offset, attr->umems[2].offset); + MLX5_SET(virtio_net_q, virtq, tisn_or_qpn, attr->tis_id); + virtq_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!virtq_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create VIRTQ Obj using DevX."); + rte_free(virtq_obj); + return NULL; + } + virtq_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); + return virtq_obj; +} + +/** + * Modify VIRTQ using DevX API. + * + * @param[in] virtq_obj + * Pointer to virtq object structure. + * @param [in] attr + * Pointer to modify virtq attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj *virtq_obj, + struct mlx5_devx_virtq_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_virtq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; + void *virtq = MLX5_ADDR_OF(create_virtq_in, in, virtq); + void *hdr = MLX5_ADDR_OF(create_virtq_in, in, hdr); + void *virtctx = MLX5_ADDR_OF(virtio_net_q, virtq, virtio_q_context); + int ret; + + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_MODIFY_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_GENERAL_OBJ_TYPE_VIRTQ); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, virtq_obj->id); + MLX5_SET64(virtio_net_q, virtq, modify_field_select, attr->type); + MLX5_SET16(virtio_q, virtctx, queue_index, attr->queue_index); + switch (attr->type) { + case MLX5_VIRTQ_MODIFY_TYPE_STATE: + MLX5_SET16(virtio_net_q, virtq, state, attr->state); + break; + case MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_PARAMS: + MLX5_SET(virtio_net_q, virtq, dirty_bitmap_mkey, + attr->dirty_bitmap_mkey); + MLX5_SET64(virtio_net_q, virtq, dirty_bitmap_addr, + attr->dirty_bitmap_addr); + MLX5_SET(virtio_net_q, virtq, dirty_bitmap_size, + attr->dirty_bitmap_size); + break; + case MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_DUMP_ENABLE: + MLX5_SET(virtio_net_q, virtq, dirty_bitmap_dump_enable, + attr->dirty_bitmap_dump_enable); + break; + default: + rte_errno = EINVAL; + return -rte_errno; + } + ret = mlx5_glue->devx_obj_modify(virtq_obj->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify VIRTQ using DevX."); + rte_errno = errno; + return -errno; + } + return ret; +} + +/** + * Query VIRTQ using DevX API. + * + * @param[in] virtq_obj + * Pointer to virtq object structure. + * @param [in/out] attr + * Pointer to virtq attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj *virtq_obj, + struct mlx5_devx_virtq_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_virtq_out)] = {0}; + void *hdr = MLX5_ADDR_OF(query_virtq_out, in, hdr); + void *virtq = MLX5_ADDR_OF(query_virtq_out, out, virtq); + int ret; + + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_QUERY_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_GENERAL_OBJ_TYPE_VIRTQ); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, virtq_obj->id); + ret = mlx5_glue->devx_obj_query(virtq_obj->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify VIRTQ using DevX."); + rte_errno = errno; + return -errno; + } + attr->hw_available_index = MLX5_GET16(virtio_net_q, virtq, + hw_available_index); + attr->hw_used_index = MLX5_GET16(virtio_net_q, virtq, hw_used_index); + return ret; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 581658b..1631c08 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -64,12 +64,10 @@ struct mlx5_hca_vdpa_attr { uint32_t log_doorbell_stride:5; uint32_t log_doorbell_bar_size:5; uint32_t max_num_virtio_queues; - uint32_t umem_1_buffer_param_a; - uint32_t umem_1_buffer_param_b; - uint32_t umem_2_buffer_param_a; - uint32_t umem_2_buffer_param_b; - uint32_t umem_3_buffer_param_a; - uint32_t umem_3_buffer_param_b; + struct { + uint32_t a; + uint32_t b; + } umems[3]; uint64_t doorbell_bar_offset; }; @@ -250,6 +248,37 @@ struct mlx5_devx_cq_attr { uint64_t db_addr; }; +/* Virtq attributes structure, used by VIRTQ operations. */ +struct mlx5_devx_virtq_attr { + uint16_t hw_available_index; + uint16_t hw_used_index; + uint16_t q_size; + uint32_t virtio_version_1_0:1; + uint32_t tso_ipv4:1; + uint32_t tso_ipv6:1; + uint32_t tx_csum:1; + uint32_t rx_csum:1; + uint32_t event_mode:3; + uint32_t state:4; + uint32_t dirty_bitmap_dump_enable:1; + uint32_t dirty_bitmap_mkey; + uint32_t dirty_bitmap_size; + uint32_t mkey; + uint32_t qp_id; + uint32_t queue_index; + uint32_t tis_id; + uint64_t dirty_bitmap_addr; + uint64_t type; + uint64_t desc_addr; + uint64_t used_addr; + uint64_t available_addr; + struct { + uint32_t id; + uint32_t size; + uint64_t offset; + } umems[3]; +}; + /* mlx5_devx_cmds.c */ struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, @@ -288,4 +317,11 @@ int mlx5_devx_cmd_flow_dump(void *fdb_domain, void *rx_domain, void *tx_domain, FILE *file); struct mlx5_devx_obj *mlx5_devx_cmd_create_cq(struct ibv_context *ctx, struct mlx5_devx_cq_attr *attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_virtq(struct ibv_context *ctx, + struct mlx5_devx_virtq_attr *attr); +int mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj *virtq_obj, + struct mlx5_devx_virtq_attr *attr); +int mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj *virtq_obj, + struct mlx5_devx_virtq_attr *attr); + #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index a4082b9..4b8a34c 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -527,6 +527,8 @@ struct mlx5_modification_cmd { #define __mlx5_16_bit_off(typ, fld) (16 - __mlx5_bit_sz(typ, fld) - \ (__mlx5_bit_off(typ, fld) & 0xf)) #define __mlx5_mask16(typ, fld) ((u16)((1ull << __mlx5_bit_sz(typ, fld)) - 1)) +#define __mlx5_16_mask(typ, fld) (__mlx5_mask16(typ, fld) << \ + __mlx5_16_bit_off(typ, fld)) #define MLX5_ST_SZ_BYTES(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 8) #define MLX5_ST_SZ_DW(typ) (sizeof(struct mlx5_ifc_##typ##_bits) / 32) #define MLX5_BYTE_OFF(typ, fld) (__mlx5_bit_off(typ, fld) / 8) @@ -551,6 +553,17 @@ struct mlx5_modification_cmd { rte_cpu_to_be_64(v); \ } while (0) +#define MLX5_SET16(typ, p, fld, v) \ + do { \ + u16 _v = v; \ + *((__be16 *)(p) + __mlx5_16_off(typ, fld)) = \ + rte_cpu_to_be_16((rte_be_to_cpu_16(*((__be16 *)(p) + \ + __mlx5_16_off(typ, fld))) & \ + (~__mlx5_16_mask(typ, fld))) | \ + (((_v) & __mlx5_mask16(typ, fld)) << \ + __mlx5_16_bit_off(typ, fld))); \ + } while (0) + #define MLX5_GET(typ, p, fld) \ ((rte_be_to_cpu_32(*((__be32 *)(p) +\ __mlx5_dw_off(typ, fld))) >> __mlx5_dw_bit_off(typ, fld)) & \ @@ -723,6 +736,9 @@ enum { MLX5_CMD_OP_CREATE_RQT = 0x916, MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939, MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b, + MLX5_CMD_OP_CREATE_GENERAL_OBJECT = 0xa00, + MLX5_CMD_OP_MODIFY_GENERAL_OBJECT = 0xa01, + MLX5_CMD_OP_QUERY_GENERAL_OBJECT = 0xa02, }; enum { @@ -1691,6 +1707,11 @@ struct mlx5_ifc_create_tir_in_bits { struct mlx5_ifc_tirc_bits ctx; }; +enum { + MLX5_INLINE_Q_TYPE_RQ = 0x0, + MLX5_INLINE_Q_TYPE_VIRTQ = 0x1, +}; + struct mlx5_ifc_rq_num_bits { u8 reserved_at_0[0x8]; u8 rq_num[0x18]; @@ -1917,6 +1938,102 @@ struct mlx5_ifc_create_cq_in_bits { u8 pas[]; }; +enum { + MLX5_GENERAL_OBJ_TYPE_VIRTQ = 0x000d, +}; + +struct mlx5_ifc_general_obj_in_cmd_hdr_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x20]; + u8 obj_type[0x10]; + u8 obj_id[0x20]; + u8 reserved_at_60[0x20]; +}; + +struct mlx5_ifc_general_obj_out_cmd_hdr_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 obj_id[0x20]; + u8 reserved_at_60[0x20]; +}; + +enum { + MLX5_VIRTQ_STATE_INIT = 0, + MLX5_VIRTQ_STATE_RDY = 1, + MLX5_VIRTQ_STATE_SUSPEND = 2, + MLX5_VIRTQ_STATE_ERROR = 3, +}; + +enum { + MLX5_VIRTQ_MODIFY_TYPE_STATE = (1UL << 0), + MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_PARAMS = (1UL << 3), + MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_DUMP_ENABLE = (1UL << 4), +}; + +struct mlx5_ifc_virtio_q_bits { + u8 virtio_q_type[0x8]; + u8 reserved_at_8[0x5]; + u8 event_mode[0x3]; + u8 queue_index[0x10]; + u8 full_emulation[0x1]; + u8 virtio_version_1_0[0x1]; + u8 reserved_at_22[0x2]; + u8 offload_type[0x4]; + u8 event_qpn_or_msix[0x18]; + u8 doorbell_stride_idx[0x10]; + u8 queue_size[0x10]; + u8 device_emulation_id[0x20]; + u8 desc_addr[0x40]; + u8 used_addr[0x40]; + u8 available_addr[0x40]; + u8 virtio_q_mkey[0x20]; + u8 reserved_at_160[0x20]; + u8 umem_1_id[0x20]; + u8 umem_1_size[0x20]; + u8 umem_1_offset[0x40]; + u8 umem_2_id[0x20]; + u8 umem_2_size[0x20]; + u8 umem_2_offset[0x40]; + u8 umem_3_id[0x20]; + u8 umem_3_size[0x20]; + u8 umem_3_offset[0x40]; + u8 reserved_at_300[0x100]; +}; + +struct mlx5_ifc_virtio_net_q_bits { + u8 modify_field_select[0x40]; + u8 reserved_at_40[0x40]; + u8 tso_ipv4[0x1]; + u8 tso_ipv6[0x1]; + u8 tx_csum[0x1]; + u8 rx_csum[0x1]; + u8 reserved_at_84[0x6]; + u8 dirty_bitmap_dump_enable[0x1]; + u8 vhost_log_page[0x5]; + u8 reserved_at_90[0xc]; + u8 state[0x4]; + u8 error_type[0x8]; + u8 tisn_or_qpn[0x18]; + u8 dirty_bitmap_mkey[0x20]; + u8 dirty_bitmap_size[0x20]; + u8 dirty_bitmap_addr[0x40]; + u8 hw_available_index[0x10]; + u8 hw_used_index[0x10]; + u8 reserved_at_160[0xa0]; + struct mlx5_ifc_virtio_q_bits virtio_q_context; +}; + +struct mlx5_ifc_create_virtq_in_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_virtio_net_q_bits virtq; +}; + +struct mlx5_ifc_query_virtq_out_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_virtio_net_q_bits virtq; +}; + /* CQE format mask. */ #define MLX5E_CQE_FORMAT_MASK 0xc diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index c6a203d..f3082ce 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -8,6 +8,7 @@ DPDK_20.02 { mlx5_devx_cmd_create_tir; mlx5_devx_cmd_create_td; mlx5_devx_cmd_create_tis; + mlx5_devx_cmd_create_virtq; mlx5_devx_cmd_destroy; mlx5_devx_cmd_flow_counter_alloc; mlx5_devx_cmd_flow_counter_query; @@ -15,8 +16,10 @@ DPDK_20.02 { mlx5_devx_cmd_mkey_create; mlx5_devx_cmd_modify_rq; mlx5_devx_cmd_modify_sq; + mlx5_devx_cmd_modify_virtq; mlx5_devx_cmd_qp_query_tis_td; mlx5_devx_cmd_query_hca_attr; + mlx5_devx_cmd_query_virtq; mlx5_devx_get_out_command_status; mlx5_dev_to_pci_addr; From patchwork Wed Jan 29 12:38:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65325 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 84F73A052F; Wed, 29 Jan 2020 13:42:21 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 304871C0B1; Wed, 29 Jan 2020 13:39:49 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 67E101C028 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1o018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:41 +0000 Message-Id: <1580301530-6643-17-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 16/25] common/mlx5: add support for DevX QP operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" QP creation is needed for vDPA virtq support. Add 2 DevX commands to create QP and to modify QP state. The support is for RC QP only in force loopback address mode. By this way, the packets can be sent to other inernal destinations in the nic. For example: other QPs or virtqs. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 167 ++++++++++- drivers/common/mlx5/mlx5_devx_cmds.h | 20 ++ drivers/common/mlx5/mlx5_prm.h | 376 ++++++++++++++++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 2 + 4 files changed, 564 insertions(+), 1 deletion(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 2425513..e7288c8 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -1124,7 +1124,8 @@ struct mlx5_devx_obj * MLX5_SET(cqc, cqctx, cc, attr->use_first_only); MLX5_SET(cqc, cqctx, oi, attr->overrun_ignore); MLX5_SET(cqc, cqctx, log_cq_size, attr->log_cq_size); - MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size); + MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size - + MLX5_ADAPTER_PAGE_SHIFT); MLX5_SET(cqc, cqctx, c_eqn, attr->eqn); MLX5_SET(cqc, cqctx, uar_page, attr->uar_page_id); if (attr->q_umem_valid) { @@ -1313,3 +1314,167 @@ struct mlx5_devx_obj * attr->hw_used_index = MLX5_GET16(virtio_net_q, virtq, hw_used_index); return ret; } + +/** + * Create QP using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] attr + * Pointer to QP attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_qp(struct ibv_context *ctx, + struct mlx5_devx_qp_attr *attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_qp_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_qp_out)] = {0}; + struct mlx5_devx_obj *qp_obj = rte_zmalloc(__func__, sizeof(*qp_obj), + 0); + void *qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); + + if (!qp_obj) { + DRV_LOG(ERR, "Failed to allocate QP data."); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP); + MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC); + MLX5_SET(qpc, qpc, pd, attr->pd); + if (attr->uar_index) { + MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); + MLX5_SET(qpc, qpc, uar_page, attr->uar_index); + MLX5_SET(qpc, qpc, log_page_size, attr->log_page_size - + MLX5_ADAPTER_PAGE_SHIFT); + if (attr->sq_size) { + RTE_ASSERT(RTE_IS_POWER_OF_2(attr->sq_size)); + MLX5_SET(qpc, qpc, cqn_snd, attr->cqn); + MLX5_SET(qpc, qpc, log_sq_size, + rte_log2_u32(attr->sq_size)); + } else { + MLX5_SET(qpc, qpc, no_sq, 1); + } + if (attr->rq_size) { + RTE_ASSERT(RTE_IS_POWER_OF_2(attr->rq_size)); + MLX5_SET(qpc, qpc, cqn_rcv, attr->cqn); + MLX5_SET(qpc, qpc, log_rq_stride, attr->log_rq_stride - + MLX5_LOG_RQ_STRIDE_SHIFT); + MLX5_SET(qpc, qpc, log_rq_size, + rte_log2_u32(attr->rq_size)); + MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ); + } else { + MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ); + } + if (attr->dbr_umem_valid) { + MLX5_SET(qpc, qpc, dbr_umem_valid, + attr->dbr_umem_valid); + MLX5_SET(qpc, qpc, dbr_umem_id, attr->dbr_umem_id); + } + MLX5_SET64(qpc, qpc, dbr_addr, attr->dbr_address); + MLX5_SET64(create_qp_in, in, wq_umem_offset, + attr->wq_umem_offset); + MLX5_SET(create_qp_in, in, wq_umem_id, attr->wq_umem_id); + MLX5_SET(create_qp_in, in, wq_umem_valid, 1); + } else { + /* Special QP to be managed by FW - no SQ\RQ\CQ\UAR\DB rec. */ + MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ); + MLX5_SET(qpc, qpc, no_sq, 1); + } + qp_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, + sizeof(out)); + if (!qp_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create QP Obj using DevX."); + rte_free(qp_obj); + return NULL; + } + qp_obj->id = MLX5_GET(create_qp_out, out, qpn); + return qp_obj; +} + +/** + * Modify QP using DevX API. + * Currently supports only force loop-back QP. + * + * @param[in] qp + * Pointer to QP object structure. + * @param [in] qp_st_mod_op + * The QP state modification operation. + * @param [in] remote_qp_id + * The remote QP ID for MLX5_CMD_OP_INIT2RTR_QP operation. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, uint32_t qp_st_mod_op, + uint32_t remote_qp_id) +{ + union { + uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_in)]; + uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_in)]; + uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_in)]; + } in; + union { + uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_out)]; + uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_out)]; + uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_out)]; + } out; + void *qpc; + int ret; + unsigned int inlen; + unsigned int outlen; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + MLX5_SET(rst2init_qp_in, &in, opcode, qp_st_mod_op); + switch (qp_st_mod_op) { + case MLX5_CMD_OP_RST2INIT_QP: + MLX5_SET(rst2init_qp_in, &in, qpn, qp->id); + qpc = MLX5_ADDR_OF(rst2init_qp_in, &in, qpc); + MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1); + MLX5_SET(qpc, qpc, rre, 1); + MLX5_SET(qpc, qpc, rwe, 1); + MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); + inlen = sizeof(in.rst2init); + outlen = sizeof(out.rst2init); + break; + case MLX5_CMD_OP_INIT2RTR_QP: + MLX5_SET(init2rtr_qp_in, &in, qpn, qp->id); + qpc = MLX5_ADDR_OF(init2rtr_qp_in, &in, qpc); + MLX5_SET(qpc, qpc, primary_address_path.fl, 1); + MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1); + MLX5_SET(qpc, qpc, mtu, 1); + MLX5_SET(qpc, qpc, log_msg_max, 30); + MLX5_SET(qpc, qpc, remote_qpn, remote_qp_id); + MLX5_SET(qpc, qpc, min_rnr_nak, 0); + inlen = sizeof(in.init2rtr); + outlen = sizeof(out.init2rtr); + break; + case MLX5_CMD_OP_RTR2RTS_QP: + qpc = MLX5_ADDR_OF(rtr2rts_qp_in, &in, qpc); + MLX5_SET(rtr2rts_qp_in, &in, qpn, qp->id); + MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 14); + MLX5_SET(qpc, qpc, log_ack_req_freq, 0); + MLX5_SET(qpc, qpc, retry_count, 7); + MLX5_SET(qpc, qpc, rnr_retry, 7); + inlen = sizeof(in.rtr2rts); + outlen = sizeof(out.rtr2rts); + break; + default: + DRV_LOG(ERR, "Invalid or unsupported QP modify op %u.", + qp_st_mod_op); + rte_errno = EINVAL; + return -rte_errno; + } + ret = mlx5_glue->devx_obj_modify(qp->obj, &in, inlen, &out, outlen); + if (ret) { + DRV_LOG(ERR, "Failed to modify QP using DevX."); + rte_errno = errno; + return -errno; + } + return ret; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 1631c08..d1a21b8 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -279,6 +279,22 @@ struct mlx5_devx_virtq_attr { } umems[3]; }; + +struct mlx5_devx_qp_attr { + uint32_t pd:24; + uint32_t uar_index:24; + uint32_t cqn:24; + uint32_t log_page_size:5; + uint32_t rq_size:17; /* Must be power of 2. */ + uint32_t log_rq_stride:3; + uint32_t sq_size:17; /* Must be power of 2. */ + uint32_t dbr_umem_valid:1; + uint32_t dbr_umem_id; + uint64_t dbr_address; + uint32_t wq_umem_id; + uint64_t wq_umem_offset; +}; + /* mlx5_devx_cmds.c */ struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, @@ -323,5 +339,9 @@ int mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj *virtq_obj, struct mlx5_devx_virtq_attr *attr); int mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj *virtq_obj, struct mlx5_devx_virtq_attr *attr); +struct mlx5_devx_obj *mlx5_devx_cmd_create_qp(struct ibv_context *ctx, + struct mlx5_devx_qp_attr *attr); +int mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, + uint32_t qp_st_mod_op, uint32_t remote_qp_id); #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 4b8a34c..e53dd61 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -724,6 +724,19 @@ enum { MLX5_CMD_OP_QUERY_HCA_CAP = 0x100, MLX5_CMD_OP_CREATE_MKEY = 0x200, MLX5_CMD_OP_CREATE_CQ = 0x400, + MLX5_CMD_OP_CREATE_QP = 0x500, + MLX5_CMD_OP_RST2INIT_QP = 0x502, + MLX5_CMD_OP_INIT2RTR_QP = 0x503, + MLX5_CMD_OP_RTR2RTS_QP = 0x504, + MLX5_CMD_OP_RTS2RTS_QP = 0x505, + MLX5_CMD_OP_SQERR2RTS_QP = 0x506, + MLX5_CMD_OP_QP_2ERR = 0x507, + MLX5_CMD_OP_QP_2RST = 0x50A, + MLX5_CMD_OP_QUERY_QP = 0x50B, + MLX5_CMD_OP_SQD2RTS_QP = 0x50C, + MLX5_CMD_OP_INIT2INIT_QP = 0x50E, + MLX5_CMD_OP_SUSPEND_QP = 0x50F, + MLX5_CMD_OP_RESUME_QP = 0x510, MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754, MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN = 0x816, MLX5_CMD_OP_CREATE_TIR = 0x900, @@ -747,6 +760,9 @@ enum { MLX5_MKC_ACCESS_MODE_KLM_FBS = 0x3, }; +#define MLX5_ADAPTER_PAGE_SHIFT 12 +#define MLX5_LOG_RQ_STRIDE_SHIFT 4 + /* Flow counters. */ struct mlx5_ifc_alloc_flow_counter_out_bits { u8 status[0x8]; @@ -2034,6 +2050,366 @@ struct mlx5_ifc_query_virtq_out_bits { struct mlx5_ifc_virtio_net_q_bits virtq; }; +enum { + MLX5_QP_ST_RC = 0x0, +}; + +enum { + MLX5_QP_PM_MIGRATED = 0x3, +}; + +enum { + MLX5_NON_ZERO_RQ = 0x0, + MLX5_SRQ_RQ = 0x1, + MLX5_CRQ_RQ = 0x2, + MLX5_ZERO_LEN_RQ = 0x3, +}; + +struct mlx5_ifc_ads_bits { + u8 fl[0x1]; + u8 free_ar[0x1]; + u8 reserved_at_2[0xe]; + u8 pkey_index[0x10]; + u8 reserved_at_20[0x8]; + u8 grh[0x1]; + u8 mlid[0x7]; + u8 rlid[0x10]; + u8 ack_timeout[0x5]; + u8 reserved_at_45[0x3]; + u8 src_addr_index[0x8]; + u8 reserved_at_50[0x4]; + u8 stat_rate[0x4]; + u8 hop_limit[0x8]; + u8 reserved_at_60[0x4]; + u8 tclass[0x8]; + u8 flow_label[0x14]; + u8 rgid_rip[16][0x8]; + u8 reserved_at_100[0x4]; + u8 f_dscp[0x1]; + u8 f_ecn[0x1]; + u8 reserved_at_106[0x1]; + u8 f_eth_prio[0x1]; + u8 ecn[0x2]; + u8 dscp[0x6]; + u8 udp_sport[0x10]; + u8 dei_cfi[0x1]; + u8 eth_prio[0x3]; + u8 sl[0x4]; + u8 vhca_port_num[0x8]; + u8 rmac_47_32[0x10]; + u8 rmac_31_0[0x20]; +}; + +struct mlx5_ifc_qpc_bits { + u8 state[0x4]; + u8 lag_tx_port_affinity[0x4]; + u8 st[0x8]; + u8 reserved_at_10[0x3]; + u8 pm_state[0x2]; + u8 reserved_at_15[0x1]; + u8 req_e2e_credit_mode[0x2]; + u8 offload_type[0x4]; + u8 end_padding_mode[0x2]; + u8 reserved_at_1e[0x2]; + u8 wq_signature[0x1]; + u8 block_lb_mc[0x1]; + u8 atomic_like_write_en[0x1]; + u8 latency_sensitive[0x1]; + u8 reserved_at_24[0x1]; + u8 drain_sigerr[0x1]; + u8 reserved_at_26[0x2]; + u8 pd[0x18]; + u8 mtu[0x3]; + u8 log_msg_max[0x5]; + u8 reserved_at_48[0x1]; + u8 log_rq_size[0x4]; + u8 log_rq_stride[0x3]; + u8 no_sq[0x1]; + u8 log_sq_size[0x4]; + u8 reserved_at_55[0x6]; + u8 rlky[0x1]; + u8 ulp_stateless_offload_mode[0x4]; + u8 counter_set_id[0x8]; + u8 uar_page[0x18]; + u8 reserved_at_80[0x8]; + u8 user_index[0x18]; + u8 reserved_at_a0[0x3]; + u8 log_page_size[0x5]; + u8 remote_qpn[0x18]; + struct mlx5_ifc_ads_bits primary_address_path; + struct mlx5_ifc_ads_bits secondary_address_path; + u8 log_ack_req_freq[0x4]; + u8 reserved_at_384[0x4]; + u8 log_sra_max[0x3]; + u8 reserved_at_38b[0x2]; + u8 retry_count[0x3]; + u8 rnr_retry[0x3]; + u8 reserved_at_393[0x1]; + u8 fre[0x1]; + u8 cur_rnr_retry[0x3]; + u8 cur_retry_count[0x3]; + u8 reserved_at_39b[0x5]; + u8 reserved_at_3a0[0x20]; + u8 reserved_at_3c0[0x8]; + u8 next_send_psn[0x18]; + u8 reserved_at_3e0[0x8]; + u8 cqn_snd[0x18]; + u8 reserved_at_400[0x8]; + u8 deth_sqpn[0x18]; + u8 reserved_at_420[0x20]; + u8 reserved_at_440[0x8]; + u8 last_acked_psn[0x18]; + u8 reserved_at_460[0x8]; + u8 ssn[0x18]; + u8 reserved_at_480[0x8]; + u8 log_rra_max[0x3]; + u8 reserved_at_48b[0x1]; + u8 atomic_mode[0x4]; + u8 rre[0x1]; + u8 rwe[0x1]; + u8 rae[0x1]; + u8 reserved_at_493[0x1]; + u8 page_offset[0x6]; + u8 reserved_at_49a[0x3]; + u8 cd_slave_receive[0x1]; + u8 cd_slave_send[0x1]; + u8 cd_master[0x1]; + u8 reserved_at_4a0[0x3]; + u8 min_rnr_nak[0x5]; + u8 next_rcv_psn[0x18]; + u8 reserved_at_4c0[0x8]; + u8 xrcd[0x18]; + u8 reserved_at_4e0[0x8]; + u8 cqn_rcv[0x18]; + u8 dbr_addr[0x40]; + u8 q_key[0x20]; + u8 reserved_at_560[0x5]; + u8 rq_type[0x3]; + u8 srqn_rmpn_xrqn[0x18]; + u8 reserved_at_580[0x8]; + u8 rmsn[0x18]; + u8 hw_sq_wqebb_counter[0x10]; + u8 sw_sq_wqebb_counter[0x10]; + u8 hw_rq_counter[0x20]; + u8 sw_rq_counter[0x20]; + u8 reserved_at_600[0x20]; + u8 reserved_at_620[0xf]; + u8 cgs[0x1]; + u8 cs_req[0x8]; + u8 cs_res[0x8]; + u8 dc_access_key[0x40]; + u8 reserved_at_680[0x3]; + u8 dbr_umem_valid[0x1]; + u8 reserved_at_684[0x9c]; + u8 dbr_umem_id[0x20]; +}; + +struct mlx5_ifc_create_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; +}; + +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +struct mlx5_ifc_create_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x40]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 wq_umem_offset[0x40]; + u8 wq_umem_id[0x20]; + u8 wq_umem_valid[0x1]; + u8 reserved_at_861[0x1f]; + u8 pas[0][0x40]; +}; +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +struct mlx5_ifc_sqerr2rts_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_sqerr2rts_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_sqd2rts_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_sqd2rts_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_rts2rts_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_rts2rts_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_rtr2rts_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_rtr2rts_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_rst2init_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_rst2init_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_init2rtr_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_init2rtr_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +struct mlx5_ifc_init2init_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_init2init_qp_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; +}; + +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +struct mlx5_ifc_query_qp_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; + u8 opt_param_mask[0x20]; + u8 reserved_at_a0[0x20]; + struct mlx5_ifc_qpc_bits qpc; + u8 reserved_at_800[0x80]; + u8 pas[0][0x40]; +}; +#ifdef PEDANTIC +#pragma GCC diagnostic error "-Wpedantic" +#endif + +struct mlx5_ifc_query_qp_in_bits { + u8 opcode[0x10]; + u8 reserved_at_10[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 qpn[0x18]; + u8 reserved_at_60[0x20]; +}; + /* CQE format mask. */ #define MLX5E_CQE_FORMAT_MASK 0xc diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index f3082ce..df8e064 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -2,6 +2,7 @@ DPDK_20.02 { global: mlx5_devx_cmd_create_cq; + mlx5_devx_cmd_create_qp; mlx5_devx_cmd_create_rq; mlx5_devx_cmd_create_rqt; mlx5_devx_cmd_create_sq; @@ -14,6 +15,7 @@ DPDK_20.02 { mlx5_devx_cmd_flow_counter_query; mlx5_devx_cmd_flow_dump; mlx5_devx_cmd_mkey_create; + mlx5_devx_cmd_modify_qp_state; mlx5_devx_cmd_modify_rq; mlx5_devx_cmd_modify_sq; mlx5_devx_cmd_modify_virtq; From patchwork Wed Jan 29 12:38:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65321 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9611CA052F; Wed, 29 Jan 2020 13:41:28 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EE35C1C037; Wed, 29 Jan 2020 13:39:42 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 5D1EF1C024 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1p018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:42 +0000 Message-Id: <1580301530-6643-18-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 17/25] common/mlx5: allow type configuration for DevX RQT X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Allow virtio queue type configuration in the RQ table. The needed fields and configuration was added. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 1 + drivers/common/mlx5/mlx5_devx_cmds.h | 1 + drivers/common/mlx5/mlx5_prm.h | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index e7288c8..e372df6 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -846,6 +846,7 @@ struct mlx5_devx_obj * } MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT); rqt_ctx = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); + MLX5_SET(rqtc, rqt_ctx, list_q_type, rqt_attr->rq_type); MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size); MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size); for (i = 0; i < rqt_attr->rqt_actual_size; i++) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index d1a21b8..9ef3ce2 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -188,6 +188,7 @@ struct mlx5_devx_tir_attr { /* RQT attributes structure, used by RQT operations. */ struct mlx5_devx_rqt_attr { + uint8_t rq_type; uint32_t rqt_max_size:16; uint32_t rqt_actual_size:16; uint32_t rq_list[]; diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index e53dd61..000ba1f 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -1734,8 +1734,9 @@ struct mlx5_ifc_rq_num_bits { }; struct mlx5_ifc_rqtc_bits { - u8 reserved_at_0[0xa0]; - u8 reserved_at_a0[0x10]; + u8 reserved_at_0[0xa5]; + u8 list_q_type[0x3]; + u8 reserved_at_a8[0x8]; u8 rqt_max_size[0x10]; u8 reserved_at_c0[0x10]; u8 rqt_actual_size[0x10]; From patchwork Wed Jan 29 12:38:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65327 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 415F5A052F; Wed, 29 Jan 2020 13:42:47 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0CDA81C0C0; Wed, 29 Jan 2020 13:39:52 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 732F91C02C for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1q018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:43 +0000 Message-Id: <1580301530-6643-19-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 18/25] common/mlx5: add TIR field constants X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The DevX TIR object configuration should get L3 and L4 protocols expected to be forwarded by the TIR. Add the PRM constant values needed to configure the L3 and L4 protocols. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_prm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 000ba1f..e326868 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -1639,6 +1639,16 @@ struct mlx5_ifc_modify_rq_in_bits { }; enum { + MLX5_L3_PROT_TYPE_IPV4 = 0, + MLX5_L3_PROT_TYPE_IPV6 = 1, +}; + +enum { + MLX5_L4_PROT_TYPE_TCP = 0, + MLX5_L4_PROT_TYPE_UDP = 1, +}; + +enum { MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_SRC_IP = 0x0, MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_DST_IP = 0x1, MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_SPORT = 0x2, From patchwork Wed Jan 29 12:38:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65323 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 33CC2A052F; Wed, 29 Jan 2020 13:41:58 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 71BE41C07F; Wed, 29 Jan 2020 13:39:46 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 6BCFB1C029 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1r018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:44 +0000 Message-Id: <1580301530-6643-20-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 19/25] common/mlx5: add DevX command to modify RQT X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" RQ table can be changed to support different list of queues. Add DevX command to modify DevX RQT object to point on new RQ list. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 47 +++++++++++++++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 2 ++ drivers/common/mlx5/mlx5_prm.h | 21 +++++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 1 + 4 files changed, 71 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index e372df6..1d3a729 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -864,6 +864,53 @@ struct mlx5_devx_obj * } /** + * Modify RQT using DevX API. + * + * @param[in] rqt + * Pointer to RQT DevX object structure. + * @param [in] rqt_attr + * Pointer to RQT attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_rqt(struct mlx5_devx_obj *rqt, + struct mlx5_devx_rqt_attr *rqt_attr) +{ + uint32_t inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + + rqt_attr->rqt_actual_size * sizeof(uint32_t); + uint32_t out[MLX5_ST_SZ_DW(modify_rqt_out)] = {0}; + uint32_t *in = rte_calloc(__func__, 1, inlen, 0); + void *rqt_ctx; + int i; + int ret; + + if (!in) { + DRV_LOG(ERR, "Failed to allocate RQT modify IN data."); + rte_errno = ENOMEM; + return -ENOMEM; + } + MLX5_SET(modify_rqt_in, in, opcode, MLX5_CMD_OP_MODIFY_RQT); + MLX5_SET(modify_rqt_in, in, rqtn, rqt->id); + MLX5_SET64(modify_rqt_in, in, modify_bitmask, 0x1); + rqt_ctx = MLX5_ADDR_OF(modify_rqt_in, in, rqt_context); + MLX5_SET(rqtc, rqt_ctx, list_q_type, rqt_attr->rq_type); + MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size); + MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size); + for (i = 0; i < rqt_attr->rqt_actual_size; i++) + MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]); + ret = mlx5_glue->devx_obj_modify(rqt->obj, in, inlen, out, sizeof(out)); + rte_free(in); + if (ret) { + DRV_LOG(ERR, "Failed to modify RQT using DevX."); + rte_errno = errno; + return -rte_errno; + } + return ret; +} + +/** * Create SQ using DevX API. * * @param[in] ctx diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 9ef3ce2..b99c54b 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -344,5 +344,7 @@ struct mlx5_devx_obj *mlx5_devx_cmd_create_qp(struct ibv_context *ctx, struct mlx5_devx_qp_attr *attr); int mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, uint32_t qp_st_mod_op, uint32_t remote_qp_id); +int mlx5_devx_cmd_modify_rqt(struct mlx5_devx_obj *rqt, + struct mlx5_devx_rqt_attr *rqt_attr); #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */ diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index e326868..b48cd0a 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -747,6 +747,7 @@ enum { MLX5_CMD_OP_CREATE_TIS = 0x912, MLX5_CMD_OP_QUERY_TIS = 0x915, MLX5_CMD_OP_CREATE_RQT = 0x916, + MLX5_CMD_OP_MODIFY_RQT = 0x917, MLX5_CMD_OP_ALLOC_FLOW_COUNTER = 0x939, MLX5_CMD_OP_QUERY_FLOW_COUNTER = 0x93b, MLX5_CMD_OP_CREATE_GENERAL_OBJECT = 0xa00, @@ -1774,10 +1775,30 @@ struct mlx5_ifc_create_rqt_in_bits { u8 reserved_at_40[0xc0]; struct mlx5_ifc_rqtc_bits rqt_context; }; + +struct mlx5_ifc_modify_rqt_in_bits { + u8 opcode[0x10]; + u8 uid[0x10]; + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + u8 reserved_at_40[0x8]; + u8 rqtn[0x18]; + u8 reserved_at_60[0x20]; + u8 modify_bitmask[0x40]; + u8 reserved_at_c0[0x40]; + struct mlx5_ifc_rqtc_bits rqt_context; +}; #ifdef PEDANTIC #pragma GCC diagnostic error "-Wpedantic" #endif +struct mlx5_ifc_modify_rqt_out_bits { + u8 status[0x8]; + u8 reserved_at_8[0x18]; + u8 syndrome[0x20]; + u8 reserved_at_40[0x40]; +}; + enum { MLX5_SQC_STATE_RST = 0x0, MLX5_SQC_STATE_RDY = 0x1, diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index df8e064..95ca54a 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -17,6 +17,7 @@ DPDK_20.02 { mlx5_devx_cmd_mkey_create; mlx5_devx_cmd_modify_qp_state; mlx5_devx_cmd_modify_rq; + mlx5_devx_cmd_modify_rqt; mlx5_devx_cmd_modify_sq; mlx5_devx_cmd_modify_virtq; mlx5_devx_cmd_qp_query_tis_td; From patchwork Wed Jan 29 12:38:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65326 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2AFBCA052F; Wed, 29 Jan 2020 13:42:39 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7B0A31C0BC; Wed, 29 Jan 2020 13:39:50 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 736EB1C02D for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1s018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:45 +0000 Message-Id: <1580301530-6643-21-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 20/25] common/mlx5: get DevX capability for max RQT size X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" In order to allow RQT size configuration which is limited to the correct maximum value, add log_max_rqt_size for DevX capability structure. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/mlx5_devx_cmds.c | 2 ++ drivers/common/mlx5/mlx5_devx_cmds.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 1d3a729..b0803ac 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -436,6 +436,8 @@ struct mlx5_devx_obj * MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc); attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, flow_counters_dump); + attr->log_max_rqt_size = MLX5_GET(cmd_hca_cap, hcattr, + log_max_rqt_size); attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager); attr->hairpin = MLX5_GET(cmd_hca_cap, hcattr, hairpin); attr->log_max_hairpin_queues = MLX5_GET(cmd_hca_cap, hcattr, diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index b99c54b..6912dc6 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -78,6 +78,7 @@ struct mlx5_hca_vdpa_attr { struct mlx5_hca_attr { uint32_t eswitch_manager:1; uint32_t flow_counters_dump:1; + uint32_t log_max_rqt_size:5; uint8_t flow_counter_bulk_alloc_bitmap; uint32_t eth_net_offloads:1; uint32_t eth_virt:1; From patchwork Wed Jan 29 12:38:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65328 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0C1DEA052F; Wed, 29 Jan 2020 13:42:59 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B5BB71C0C5; Wed, 29 Jan 2020 13:39:53 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 713AC1C02A for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:31 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1t018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:46 +0000 Message-Id: <1580301530-6643-22-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 21/25] net/mlx5: select driver by class device argument X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" There might be a case that one Mellanox device can be probed by multiple mlx5 drivers. One case is that any mlx5 vDPA device can be probed by bothe net/mlx5 and vdpa/mlx5. Add a new mlx5 common API to get the requested driver by devargs: class=[net/vdpa]. Skip net/mlx5 PMD probing while the device is selected to be probed by the vDPA driver. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 2 +- drivers/common/mlx5/meson.build | 2 +- drivers/common/mlx5/mlx5_common.c | 36 +++++++++++++++++++++++++ drivers/common/mlx5/mlx5_common.h | 11 ++++++++ drivers/common/mlx5/rte_common_mlx5_version.map | 2 ++ drivers/net/mlx5/mlx5.c | 8 ++++++ 6 files changed, 59 insertions(+), 2 deletions(-) diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index d1de3ec..b9e9803 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -41,7 +41,7 @@ else LDLIBS += -libverbs -lmlx5 endif -LDLIBS += -lrte_eal -lrte_pci +LDLIBS += -lrte_eal -lrte_pci -lrte_kvargs # A few warnings cannot be avoided in external headers. CFLAGS += -Wno-error=cast-qual -DNDEBUG -UPEDANTIC diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 3e130cb..b88822e 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -37,7 +37,7 @@ endforeach if build allow_experimental_apis = true - deps += ['hash', 'pci', 'net', 'eal'] + deps += ['hash', 'pci', 'net', 'eal', 'kvargs'] ext_deps += libs sources = files( 'mlx5_devx_cmds.c', diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c index 2381208..52f191a 100644 --- a/drivers/common/mlx5/mlx5_common.c +++ b/drivers/common/mlx5/mlx5_common.c @@ -71,6 +71,42 @@ return 0; } +static int +mlx5_class_check_handler(__rte_unused const char *key, const char *value, + void *opaque) +{ + enum mlx5_class *ret = opaque; + + if (strcmp(value, "vdpa") == 0) { + *ret = MLX5_CLASS_VDPA; + } else if (strcmp(value, "net") == 0) { + *ret = MLX5_CLASS_NET; + } else { + DRV_LOG(ERR, "Invalid mlx5 class %s. Maybe typo in device" + " class argument setting?", value); + *ret = MLX5_CLASS_INVALID; + } + return 0; +} + +enum mlx5_class +mlx5_class_get(struct rte_devargs *devargs) +{ + struct rte_kvargs *kvlist; + const char *key = MLX5_CLASS_ARG_NAME; + enum mlx5_class ret = MLX5_CLASS_NET; + + if (devargs == NULL) + return ret; + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (kvlist == NULL) + return ret; + if (rte_kvargs_count(kvlist, key)) + rte_kvargs_process(kvlist, key, mlx5_class_check_handler, &ret); + rte_kvargs_free(kvlist); + return ret; +} + #ifdef RTE_IBVERBS_LINK_DLOPEN /** diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 9d464d4..2988f4b 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "mlx5_prm.h" @@ -150,4 +152,13 @@ enum mlx5_cqe_status { int mlx5_dev_to_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr); +#define MLX5_CLASS_ARG_NAME "class" + +enum mlx5_class { + MLX5_CLASS_NET, + MLX5_CLASS_VDPA, + MLX5_CLASS_INVALID, +}; +enum mlx5_class mlx5_class_get(struct rte_devargs *devargs); + #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index 95ca54a..3e7038b 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -1,6 +1,8 @@ DPDK_20.02 { global: + mlx5_class_get; + mlx5_devx_cmd_create_cq; mlx5_devx_cmd_create_qp; mlx5_devx_cmd_create_rq; diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index d0fa2da..ca5bc14 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1565,6 +1565,8 @@ struct mlx5_flow_id_pool * config->max_dump_files_num = tmp; } else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) { config->lro.timeout = tmp; + } else if (strcmp(MLX5_CLASS_ARG_NAME, key) == 0) { + DRV_LOG(DEBUG, "class argument is %s.", val); } else { DRV_LOG(WARNING, "%s: unknown parameter", key); rte_errno = EINVAL; @@ -1616,6 +1618,7 @@ struct mlx5_flow_id_pool * MLX5_REPRESENTOR, MLX5_MAX_DUMP_FILES_NUM, MLX5_LRO_TIMEOUT_USEC, + MLX5_CLASS_ARG_NAME, NULL, }; struct rte_kvargs *kvlist; @@ -2967,6 +2970,11 @@ struct mlx5_flow_id_pool * struct mlx5_dev_config dev_config; int ret; + if (mlx5_class_get(pci_dev->device.devargs) != MLX5_CLASS_NET) { + DRV_LOG(DEBUG, "Skip probing - should be probed by other mlx5" + " driver."); + return 1; + } if (rte_eal_process_type() == RTE_PROC_PRIMARY) mlx5_pmd_socket_init(); ret = mlx5_init_once(); From patchwork Wed Jan 29 12:38:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65329 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 59841A052F; Wed, 29 Jan 2020 13:43:09 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8D8A41C0CD; Wed, 29 Jan 2020 13:39:55 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 924DF1C030 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:32 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1u018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:47 +0000 Message-Id: <1580301530-6643-23-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 22/25] net/mlx5: separate Netlink command interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The Netlink commands interfaces is included in the mlx5.h file with a lot of other PMD interfaces. As an arrangement to make the Netlink commands shared with different PMDs, this patch moves the Netlink interface to a new file called mlx5_nl.h. Move non Netlink pure vlan commands from mlx5_nl.c to the mlx5_vlan.c. Rename Netlink commands and structures to use prefix mlx5_nl. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.h | 72 +++------------------ drivers/net/mlx5/mlx5_nl.c | 149 +++---------------------------------------- drivers/net/mlx5/mlx5_nl.h | 69 ++++++++++++++++++++ drivers/net/mlx5/mlx5_vlan.c | 134 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 204 deletions(-) create mode 100644 drivers/net/mlx5/mlx5_nl.h diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 3daf0db..01d0051 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -39,6 +39,7 @@ #include "mlx5_defs.h" #include "mlx5_utils.h" #include "mlx5_mr.h" +#include "mlx5_nl.h" #include "mlx5_autoconf.h" /* Request types for IPC. */ @@ -75,24 +76,6 @@ struct mlx5_mp_param { /** Key string for IPC. */ #define MLX5_MP_NAME "net_mlx5_mp" -/* Recognized Infiniband device physical port name types. */ -enum mlx5_phys_port_name_type { - MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */ - MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */ -}; - -/** Switch information returned by mlx5_nl_switch_info(). */ -struct mlx5_switch_info { - uint32_t master:1; /**< Master device. */ - uint32_t representor:1; /**< Representor device. */ - enum mlx5_phys_port_name_type name_type; /** < Port name type. */ - int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ - int32_t port_name; /**< Representor port name. */ - uint64_t switch_id; /**< Switch identifier. */ -}; LIST_HEAD(mlx5_dev_list, mlx5_ibv_shared); @@ -226,30 +209,12 @@ enum mlx5_verbs_alloc_type { MLX5_VERBS_ALLOC_TYPE_RX_QUEUE, }; -/* VLAN netdev for VLAN workaround. */ -struct mlx5_vlan_dev { - uint32_t refcnt; - uint32_t ifindex; /**< Own interface index. */ -}; - /* Structure for VF VLAN workaround. */ struct mlx5_vf_vlan { uint32_t tag:12; uint32_t created:1; }; -/* - * Array of VLAN devices created on the base of VF - * used for workaround in virtual environments. - */ -struct mlx5_vlan_vmwa_context { - int nl_socket; - uint32_t nl_sn; - uint32_t vf_ifindex; - struct rte_eth_dev *dev; - struct mlx5_vlan_dev vlan_dev[4096]; -}; - /** * Verbs allocator needs a context to know in the callback which kind of * resources it is allocating. @@ -576,7 +541,7 @@ struct mlx5_priv { int nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */ uint32_t nl_sn; /* Netlink message sequence number. */ LIST_HEAD(dbrpage, mlx5_devx_dbr_page) dbrpgs; /* Door-bell pages. */ - struct mlx5_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */ + struct mlx5_nl_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */ struct mlx5_flow_id_pool *qrss_id_pool; struct mlx5_hlist *mreg_cp_tbl; /* Hash table of Rx metadata register copy table. */ @@ -672,6 +637,8 @@ int mlx5_hairpin_cap_get(struct rte_eth_dev *dev, void mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index); int mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uint32_t index, uint32_t vmdq); +struct mlx5_nl_vlan_vmwa_context *mlx5_vlan_vmwa_init + (struct rte_eth_dev *dev, uint32_t ifindex); int mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); int mlx5_set_mc_addr_list(struct rte_eth_dev *dev, struct rte_ether_addr *mc_addr_set, @@ -715,6 +682,11 @@ int mlx5_xstats_get_names(struct rte_eth_dev *dev __rte_unused, int mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on); void mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on); int mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask); +void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *ctx); +void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, + struct mlx5_vf_vlan *vf_vlan); +void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, + struct mlx5_vf_vlan *vf_vlan); /* mlx5_trigger.c */ @@ -796,32 +768,6 @@ int mlx5_mp_req_queue_state_modify(struct rte_eth_dev *dev, int mlx5_pmd_socket_init(void); void mlx5_pmd_socket_uninit(void); -/* mlx5_nl.c */ - -int mlx5_nl_init(int protocol); -int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, - uint32_t index); -int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac, - uint32_t index); -void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev); -void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev); -int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable); -int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable); -unsigned int mlx5_nl_portnum(int nl, const char *name); -unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); -int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev, - struct rte_ether_addr *mac, int vf_index); -int mlx5_nl_switch_info(int nl, unsigned int ifindex, - struct mlx5_switch_info *info); - -struct mlx5_vlan_vmwa_context *mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, - uint32_t ifindex); -void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *ctx); -void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, - struct mlx5_vf_vlan *vf_vlan); -void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, - struct mlx5_vf_vlan *vf_vlan); - /* mlx5_flow_meter.c */ int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg); diff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c index e7ba034..3fe4b6f 100644 --- a/drivers/net/mlx5/mlx5_nl.c +++ b/drivers/net/mlx5/mlx5_nl.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -18,8 +17,6 @@ #include #include -#include -#include #include "mlx5.h" #include "mlx5_utils.h" @@ -1072,7 +1069,8 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info) +mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info) { uint32_t seq = random(); struct { @@ -1116,12 +1114,12 @@ struct mlx5_nl_ifindex_data { * Delete VLAN network device by ifindex. * * @param[in] tcf - * Context object initialized by mlx5_vlan_vmwa_init(). + * Context object initialized by mlx5_nl_vlan_vmwa_init(). * @param[in] ifindex * Interface index of network device to delete. */ -static void -mlx5_vlan_vmwa_delete(struct mlx5_vlan_vmwa_context *vmwa, +void +mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex) { int ret; @@ -1196,14 +1194,14 @@ struct mlx5_nl_ifindex_data { * Create network VLAN device with specified VLAN tag. * * @param[in] tcf - * Context object initialized by mlx5_vlan_vmwa_init(). + * Context object initialized by mlx5_nl_vlan_vmwa_init(). * @param[in] ifindex * Base network interface index. * @param[in] tag * VLAN tag for VLAN network device to create. */ -static uint32_t -mlx5_vlan_vmwa_create(struct mlx5_vlan_vmwa_context *vmwa, +uint32_t +mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex, uint16_t tag) { @@ -1269,134 +1267,3 @@ struct mlx5_nl_ifindex_data { } return ret; } - -/* - * Release VLAN network device, created for VM workaround. - * - * @param[in] dev - * Ethernet device object, Netlink context provider. - * @param[in] vlan - * Object representing the network device to release. - */ -void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, - struct mlx5_vf_vlan *vlan) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context; - struct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; - - assert(vlan->created); - assert(priv->vmwa_context); - if (!vlan->created || !vmwa) - return; - vlan->created = 0; - assert(vlan_dev[vlan->tag].refcnt); - if (--vlan_dev[vlan->tag].refcnt == 0 && - vlan_dev[vlan->tag].ifindex) { - mlx5_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex); - vlan_dev[vlan->tag].ifindex = 0; - } -} - -/** - * Acquire VLAN interface with specified tag for VM workaround. - * - * @param[in] dev - * Ethernet device object, Netlink context provider. - * @param[in] vlan - * Object representing the network device to acquire. - */ -void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, - struct mlx5_vf_vlan *vlan) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_vlan_vmwa_context *vmwa = priv->vmwa_context; - struct mlx5_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; - - assert(!vlan->created); - assert(priv->vmwa_context); - if (vlan->created || !vmwa) - return; - if (vlan_dev[vlan->tag].refcnt == 0) { - assert(!vlan_dev[vlan->tag].ifindex); - vlan_dev[vlan->tag].ifindex = - mlx5_vlan_vmwa_create(vmwa, - vmwa->vf_ifindex, - vlan->tag); - } - if (vlan_dev[vlan->tag].ifindex) { - vlan_dev[vlan->tag].refcnt++; - vlan->created = 1; - } -} - -/* - * Create per ethernet device VLAN VM workaround context - */ -struct mlx5_vlan_vmwa_context * -mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, - uint32_t ifindex) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_dev_config *config = &priv->config; - struct mlx5_vlan_vmwa_context *vmwa; - enum rte_hypervisor hv_type; - - /* Do not engage workaround over PF. */ - if (!config->vf) - return NULL; - /* Check whether there is desired virtual environment */ - hv_type = rte_hypervisor_get(); - switch (hv_type) { - case RTE_HYPERVISOR_UNKNOWN: - case RTE_HYPERVISOR_VMWARE: - /* - * The "white list" of configurations - * to engage the workaround. - */ - break; - default: - /* - * The configuration is not found in the "white list". - * We should not engage the VLAN workaround. - */ - return NULL; - } - vmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t)); - if (!vmwa) { - DRV_LOG(WARNING, - "Can not allocate memory" - " for VLAN workaround context"); - return NULL; - } - vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE); - if (vmwa->nl_socket < 0) { - DRV_LOG(WARNING, - "Can not create Netlink socket" - " for VLAN workaround context"); - rte_free(vmwa); - return NULL; - } - vmwa->nl_sn = random(); - vmwa->vf_ifindex = ifindex; - vmwa->dev = dev; - /* Cleanup for existing VLAN devices. */ - return vmwa; -} - -/* - * Destroy per ethernet device VLAN VM workaround context - */ -void mlx5_vlan_vmwa_exit(struct mlx5_vlan_vmwa_context *vmwa) -{ - unsigned int i; - - /* Delete all remaining VLAN devices. */ - for (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) { - if (vmwa->vlan_dev[i].ifindex) - mlx5_vlan_vmwa_delete(vmwa, vmwa->vlan_dev[i].ifindex); - } - if (vmwa->nl_socket >= 0) - close(vmwa->nl_socket); - rte_free(vmwa); -} diff --git a/drivers/net/mlx5/mlx5_nl.h b/drivers/net/mlx5/mlx5_nl.h new file mode 100644 index 0000000..7903673 --- /dev/null +++ b/drivers/net/mlx5/mlx5_nl.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_NL_H_ +#define RTE_PMD_MLX5_NL_H_ + +#include + + +/* Recognized Infiniband device physical port name types. */ +enum mlx5_nl_phys_port_name_type { + MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */ + MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */ +}; + +/** Switch information returned by mlx5_nl_switch_info(). */ +struct mlx5_switch_info { + uint32_t master:1; /**< Master device. */ + uint32_t representor:1; /**< Representor device. */ + enum mlx5_nl_phys_port_name_type name_type; /** < Port name type. */ + int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ + int32_t port_name; /**< Representor port name. */ + uint64_t switch_id; /**< Switch identifier. */ +}; + +/* VLAN netdev for VLAN workaround. */ +struct mlx5_nl_vlan_dev { + uint32_t refcnt; + uint32_t ifindex; /**< Own interface index. */ +}; + +/* + * Array of VLAN devices created on the base of VF + * used for workaround in virtual environments. + */ +struct mlx5_nl_vlan_vmwa_context { + int nl_socket; + uint32_t nl_sn; + uint32_t vf_ifindex; + struct mlx5_nl_vlan_dev vlan_dev[4096]; +}; + + +int mlx5_nl_init(int protocol); +int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, + uint32_t index); +int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac, + uint32_t index); +void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev); +void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev); +int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable); +int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable); +unsigned int mlx5_nl_portnum(int nl, const char *name); +unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); +int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev, + struct rte_ether_addr *mac, int vf_index); +int mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info); + +void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex); +uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex, uint16_t tag); + +#endif /* RTE_PMD_MLX5_NL_H_ */ diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index b0fa31a..fb52d8f 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -7,6 +7,8 @@ #include #include #include +#include + /* * Not needed by this file; included to work around the lack of off_t @@ -26,6 +28,8 @@ #include #include +#include +#include #include #include @@ -33,6 +37,7 @@ #include "mlx5.h" #include "mlx5_autoconf.h" #include "mlx5_rxtx.h" +#include "mlx5_nl.h" #include "mlx5_utils.h" /** @@ -193,3 +198,132 @@ } return 0; } + +/* + * Release VLAN network device, created for VM workaround. + * + * @param[in] dev + * Ethernet device object, Netlink context provider. + * @param[in] vlan + * Object representing the network device to release. + */ +void mlx5_vlan_vmwa_release(struct rte_eth_dev *dev, + struct mlx5_vf_vlan *vlan) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context; + struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; + + assert(vlan->created); + assert(priv->vmwa_context); + if (!vlan->created || !vmwa) + return; + vlan->created = 0; + assert(vlan_dev[vlan->tag].refcnt); + if (--vlan_dev[vlan->tag].refcnt == 0 && + vlan_dev[vlan->tag].ifindex) { + mlx5_nl_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex); + vlan_dev[vlan->tag].ifindex = 0; + } +} + +/** + * Acquire VLAN interface with specified tag for VM workaround. + * + * @param[in] dev + * Ethernet device object, Netlink context provider. + * @param[in] vlan + * Object representing the network device to acquire. + */ +void mlx5_vlan_vmwa_acquire(struct rte_eth_dev *dev, + struct mlx5_vf_vlan *vlan) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_nl_vlan_vmwa_context *vmwa = priv->vmwa_context; + struct mlx5_nl_vlan_dev *vlan_dev = &vmwa->vlan_dev[0]; + + assert(!vlan->created); + assert(priv->vmwa_context); + if (vlan->created || !vmwa) + return; + if (vlan_dev[vlan->tag].refcnt == 0) { + assert(!vlan_dev[vlan->tag].ifindex); + vlan_dev[vlan->tag].ifindex = + mlx5_nl_vlan_vmwa_create(vmwa, vmwa->vf_ifindex, + vlan->tag); + } + if (vlan_dev[vlan->tag].ifindex) { + vlan_dev[vlan->tag].refcnt++; + vlan->created = 1; + } +} + +/* + * Create per ethernet device VLAN VM workaround context + */ +struct mlx5_nl_vlan_vmwa_context * +mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_config *config = &priv->config; + struct mlx5_nl_vlan_vmwa_context *vmwa; + enum rte_hypervisor hv_type; + + /* Do not engage workaround over PF. */ + if (!config->vf) + return NULL; + /* Check whether there is desired virtual environment */ + hv_type = rte_hypervisor_get(); + switch (hv_type) { + case RTE_HYPERVISOR_UNKNOWN: + case RTE_HYPERVISOR_VMWARE: + /* + * The "white list" of configurations + * to engage the workaround. + */ + break; + default: + /* + * The configuration is not found in the "white list". + * We should not engage the VLAN workaround. + */ + return NULL; + } + vmwa = rte_zmalloc(__func__, sizeof(*vmwa), sizeof(uint32_t)); + if (!vmwa) { + DRV_LOG(WARNING, + "Can not allocate memory" + " for VLAN workaround context"); + return NULL; + } + vmwa->nl_socket = mlx5_nl_init(NETLINK_ROUTE); + if (vmwa->nl_socket < 0) { + DRV_LOG(WARNING, + "Can not create Netlink socket" + " for VLAN workaround context"); + rte_free(vmwa); + return NULL; + } + vmwa->nl_sn = random(); + vmwa->vf_ifindex = ifindex; + /* Cleanup for existing VLAN devices. */ + return vmwa; +} + +/* + * Destroy per ethernet device VLAN VM workaround context + */ +void mlx5_vlan_vmwa_exit(struct mlx5_nl_vlan_vmwa_context *vmwa) +{ + unsigned int i; + + /* Delete all remaining VLAN devices. */ + for (i = 0; i < RTE_DIM(vmwa->vlan_dev); i++) { + if (vmwa->vlan_dev[i].ifindex) + mlx5_nl_vlan_vmwa_delete(vmwa, + vmwa->vlan_dev[i].ifindex); + } + if (vmwa->nl_socket >= 0) + close(vmwa->nl_socket); + rte_free(vmwa); +} From patchwork Wed Jan 29 12:38:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65331 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 15A16A052F; Wed, 29 Jan 2020 13:43:32 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2DB491C0D8; Wed, 29 Jan 2020 13:39:58 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 954241C031 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:32 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1v018914; Wed, 29 Jan 2020 14:39:31 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:48 +0000 Message-Id: <1580301530-6643-24-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 23/25] net/mlx5: reduce Netlink commands dependencies X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" As an arrangment for Netlink command moving to the common library, reduce the net/mlx5 dependencies. Replace ethdev class command parameters. Improve Netlink sequence number mechanism to be controlled by the mlx5 Netlink mechanism. Move mlx5_nl_check_switch_info to mlx5_nl.c since it is the only one which uses it. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5.c | 10 +- drivers/net/mlx5/mlx5.h | 3 - drivers/net/mlx5/mlx5_ethdev.c | 49 ------ drivers/net/mlx5/mlx5_mac.c | 14 +- drivers/net/mlx5/mlx5_nl.c | 329 +++++++++++++++++++++++++---------------- drivers/net/mlx5/mlx5_nl.h | 23 +-- drivers/net/mlx5/mlx5_rxmode.c | 12 +- drivers/net/mlx5/mlx5_vlan.c | 1 - 8 files changed, 236 insertions(+), 205 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index ca5bc14..3b8de8f 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1270,7 +1270,9 @@ struct mlx5_flow_id_pool * if (priv->reta_idx != NULL) rte_free(priv->reta_idx); if (priv->config.vf) - mlx5_nl_mac_addr_flush(dev); + mlx5_nl_mac_addr_flush(priv->nl_socket_route, mlx5_ifindex(dev), + dev->data->mac_addrs, + MLX5_MAX_MAC_ADDRESSES, priv->mac_own); if (priv->nl_socket_route >= 0) close(priv->nl_socket_route); if (priv->nl_socket_rdma >= 0) @@ -2330,7 +2332,6 @@ struct mlx5_flow_id_pool * /* Some internal functions rely on Netlink sockets, open them now. */ priv->nl_socket_rdma = mlx5_nl_init(NETLINK_RDMA); priv->nl_socket_route = mlx5_nl_init(NETLINK_ROUTE); - priv->nl_sn = 0; priv->representor = !!switch_info->representor; priv->master = !!switch_info->master; priv->domain_id = RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; @@ -2650,7 +2651,10 @@ struct mlx5_flow_id_pool * /* Register MAC address. */ claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0)); if (config.vf && config.vf_nl_en) - mlx5_nl_mac_addr_sync(eth_dev); + mlx5_nl_mac_addr_sync(priv->nl_socket_route, + mlx5_ifindex(eth_dev), + eth_dev->data->mac_addrs, + MLX5_MAX_MAC_ADDRESSES); TAILQ_INIT(&priv->flows); TAILQ_INIT(&priv->ctrl_flows); TAILQ_INIT(&priv->flow_meters); diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 01d0051..9864aa7 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -539,7 +539,6 @@ struct mlx5_priv { /* Context for Verbs allocator. */ int nl_socket_rdma; /* Netlink socket (NETLINK_RDMA). */ int nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */ - uint32_t nl_sn; /* Netlink message sequence number. */ LIST_HEAD(dbrpage, mlx5_devx_dbr_page) dbrpgs; /* Door-bell pages. */ struct mlx5_nl_vlan_vmwa_context *vmwa_context; /* VLAN WA context. */ struct mlx5_flow_id_pool *qrss_id_pool; @@ -617,8 +616,6 @@ int mlx5_sysfs_switch_info(unsigned int ifindex, struct mlx5_switch_info *info); void mlx5_sysfs_check_switch_info(bool device_dir, struct mlx5_switch_info *switch_info); -void mlx5_nl_check_switch_info(bool nun_vf_set, - struct mlx5_switch_info *switch_info); void mlx5_translate_port_name(const char *port_name_in, struct mlx5_switch_info *port_info_out); void mlx5_intr_callback_unregister(const struct rte_intr_handle *handle, diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 2628e64..5484104 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -1891,55 +1891,6 @@ struct mlx5_priv * } /** - * Analyze gathered port parameters via Netlink to recognize master - * and representor devices for E-Switch configuration. - * - * @param[in] num_vf_set - * flag of presence of number of VFs port attribute. - * @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_nl_check_switch_info(bool num_vf_set, - 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 number of VFs key presence. - */ - switch_info->master = num_vf_set; - 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 - * number of VFs key. - */ - switch_info->master = num_vf_set; - 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 = !num_vf_set; - break; - case MLX5_PHYS_PORT_NAME_TYPE_PFVF: - /* New representors naming schema. */ - switch_info->representor = 1; - break; - } -} - -/** * Analyze gathered port parameters via sysfs to recognize master * and representor devices for E-Switch configuration. * diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c index a646b90..0ab2a0e 100644 --- a/drivers/net/mlx5/mlx5_mac.c +++ b/drivers/net/mlx5/mlx5_mac.c @@ -74,8 +74,9 @@ if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index])) return; if (vf) - mlx5_nl_mac_addr_remove(dev, &dev->data->mac_addrs[index], - index); + mlx5_nl_mac_addr_remove(priv->nl_socket_route, + mlx5_ifindex(dev), priv->mac_own, + &dev->data->mac_addrs[index], index); memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr)); } @@ -117,7 +118,9 @@ return -rte_errno; } if (vf) { - int ret = mlx5_nl_mac_addr_add(dev, mac, index); + int ret = mlx5_nl_mac_addr_add(priv->nl_socket_route, + mlx5_ifindex(dev), priv->mac_own, + mac, index); if (ret) return ret; @@ -209,8 +212,9 @@ if (priv->master == 1) { priv = dev->data->dev_private; return mlx5_nl_vf_mac_addr_modify - (&rte_eth_devices[port_id], - mac_addr, priv->representor_id); + (priv->nl_socket_route, + mlx5_ifindex(&rte_eth_devices[port_id]), + mac_addr, priv->representor_id); } } rte_errno = -ENOTSUP; diff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c index 3fe4b6f..6b8ca00 100644 --- a/drivers/net/mlx5/mlx5_nl.c +++ b/drivers/net/mlx5/mlx5_nl.c @@ -17,8 +17,11 @@ #include #include +#include +#include #include "mlx5.h" +#include "mlx5_nl.h" #include "mlx5_utils.h" /* Size of the buffer to receive kernel messages */ @@ -109,6 +112,11 @@ struct mlx5_nl_ifindex_data { uint32_t portnum; /**< IB device max port number (out). */ }; +rte_atomic32_t atomic_sn = RTE_ATOMIC32_INIT(0); + +/* Generate Netlink sequence number. */ +#define MLX5_NL_SN_GENERATE ((uint32_t)rte_atomic32_add_return(&atomic_sn, 1)) + /** * Opens a Netlink socket. * @@ -369,8 +377,10 @@ struct mlx5_nl_ifindex_data { /** * Get bridge MAC addresses. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param mac[out] * Pointer to the array table of MAC addresses to fill. * Its size should be of MLX5_MAX_MAC_ADDRESSES. @@ -381,11 +391,9 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_nl_mac_addr_list(struct rte_eth_dev *dev, struct rte_ether_addr (*mac)[], - int *mac_n) +mlx5_nl_mac_addr_list(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr (*mac)[], int *mac_n) { - struct mlx5_priv *priv = dev->data->dev_private; - unsigned int iface_idx = mlx5_ifindex(dev); struct { struct nlmsghdr hdr; struct ifinfomsg ifm; @@ -404,33 +412,33 @@ struct mlx5_nl_ifindex_data { .mac = mac, .mac_n = 0, }; - int fd; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; - uint32_t sn = priv->nl_sn++; - if (priv->nl_socket_route == -1) + if (nlsk_fd == -1) return 0; - fd = priv->nl_socket_route; - ret = mlx5_nl_request(fd, &req.hdr, sn, &req.ifm, + ret = mlx5_nl_request(nlsk_fd, &req.hdr, sn, &req.ifm, sizeof(struct ifinfomsg)); if (ret < 0) goto error; - ret = mlx5_nl_recv(fd, sn, mlx5_nl_mac_addr_cb, &data); + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_mac_addr_cb, &data); if (ret < 0) goto error; *mac_n = data.mac_n; return 0; error: - DRV_LOG(DEBUG, "port %u cannot retrieve MAC address list %s", - dev->data->port_id, strerror(rte_errno)); + DRV_LOG(DEBUG, "Interface %u cannot retrieve MAC address list %s", + iface_idx, strerror(rte_errno)); return -rte_errno; } /** * Modify the MAC address neighbour table with Netlink. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param mac * MAC address to consider. * @param add @@ -440,11 +448,9 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_nl_mac_addr_modify(struct rte_eth_dev *dev, struct rte_ether_addr *mac, - int add) +mlx5_nl_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int add) { - struct mlx5_priv *priv = dev->data->dev_private; - unsigned int iface_idx = mlx5_ifindex(dev); struct { struct nlmsghdr hdr; struct ndmsg ndm; @@ -468,28 +474,26 @@ struct mlx5_nl_ifindex_data { .rta_len = RTA_LENGTH(RTE_ETHER_ADDR_LEN), }, }; - int fd; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; - uint32_t sn = priv->nl_sn++; - if (priv->nl_socket_route == -1) + if (nlsk_fd == -1) return 0; - fd = priv->nl_socket_route; memcpy(RTA_DATA(&req.rta), mac, RTE_ETHER_ADDR_LEN); req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + RTA_ALIGN(req.rta.rta_len); - ret = mlx5_nl_send(fd, &req.hdr, sn); + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); if (ret < 0) goto error; - ret = mlx5_nl_recv(fd, sn, NULL, NULL); + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); if (ret < 0) goto error; return 0; error: DRV_LOG(DEBUG, - "port %u cannot %s MAC address %02X:%02X:%02X:%02X:%02X:%02X" - " %s", - dev->data->port_id, + "Interface %u cannot %s MAC address" + " %02X:%02X:%02X:%02X:%02X:%02X %s", + iface_idx, add ? "add" : "remove", mac->addr_bytes[0], mac->addr_bytes[1], mac->addr_bytes[2], mac->addr_bytes[3], @@ -501,8 +505,10 @@ struct mlx5_nl_ifindex_data { /** * Modify the VF MAC address neighbour table with Netlink. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param mac * MAC address to consider. * @param vf_index @@ -512,12 +518,10 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev, +mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, struct rte_ether_addr *mac, int vf_index) { - int fd, ret; - struct mlx5_priv *priv = dev->data->dev_private; - unsigned int iface_idx = mlx5_ifindex(dev); + int ret; struct { struct nlmsghdr hdr; struct ifinfomsg ifm; @@ -546,10 +550,10 @@ struct mlx5_nl_ifindex_data { .rta_type = IFLA_VF_MAC, }, }; - uint32_t sn = priv->nl_sn++; struct ifla_vf_mac ivm = { .vf = vf_index, }; + uint32_t sn = MLX5_NL_SN_GENERATE; memcpy(&ivm.mac, mac, RTE_ETHER_ADDR_LEN); memcpy(RTA_DATA(&req.vf_mac_rta), &ivm, sizeof(ivm)); @@ -564,13 +568,12 @@ struct mlx5_nl_ifindex_data { req.vf_info_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), &req.vf_info_rta); - fd = priv->nl_socket_route; - if (fd < 0) + if (nlsk_fd < 0) return -1; - ret = mlx5_nl_send(fd, &req.hdr, sn); + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); if (ret < 0) goto error; - ret = mlx5_nl_recv(fd, sn, NULL, NULL); + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); if (ret < 0) goto error; return 0; @@ -589,8 +592,12 @@ struct mlx5_nl_ifindex_data { /** * Add a MAC address. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. * @param mac * MAC address to register. * @param index @@ -600,15 +607,15 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, +mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, uint32_t index) { - struct mlx5_priv *priv = dev->data->dev_private; int ret; - ret = mlx5_nl_mac_addr_modify(dev, mac, 1); + ret = mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 1); if (!ret) - BITFIELD_SET(priv->mac_own, index); + BITFIELD_SET(mac_own, index); if (ret == -EEXIST) return 0; return ret; @@ -617,8 +624,12 @@ struct mlx5_nl_ifindex_data { /** * Remove a MAC address. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. * @param mac * MAC address to remove. * @param index @@ -628,46 +639,50 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac, - uint32_t index) +mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index) { - struct mlx5_priv *priv = dev->data->dev_private; - - BITFIELD_RESET(priv->mac_own, index); - return mlx5_nl_mac_addr_modify(dev, mac, 0); + BITFIELD_RESET(mac_own, index); + return mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 0); } /** * Synchronize Netlink bridge table to the internal table. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_addrs + * Mac addresses array to sync. + * @param n + * @p mac_addrs array size. */ void -mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev) +mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n) { - struct rte_ether_addr macs[MLX5_MAX_MAC_ADDRESSES]; + struct rte_ether_addr macs[n]; int macs_n = 0; int i; int ret; - ret = mlx5_nl_mac_addr_list(dev, &macs, &macs_n); + ret = mlx5_nl_mac_addr_list(nlsk_fd, iface_idx, &macs, &macs_n); if (ret) return; for (i = 0; i != macs_n; ++i) { int j; /* Verify the address is not in the array yet. */ - for (j = 0; j != MLX5_MAX_MAC_ADDRESSES; ++j) - if (rte_is_same_ether_addr(&macs[i], - &dev->data->mac_addrs[j])) + for (j = 0; j != n; ++j) + if (rte_is_same_ether_addr(&macs[i], &mac_addrs[j])) break; - if (j != MLX5_MAX_MAC_ADDRESSES) + if (j != n) continue; /* Find the first entry available. */ - for (j = 0; j != MLX5_MAX_MAC_ADDRESSES; ++j) { - if (rte_is_zero_ether_addr(&dev->data->mac_addrs[j])) { - dev->data->mac_addrs[j] = macs[i]; + for (j = 0; j != n; ++j) { + if (rte_is_zero_ether_addr(&mac_addrs[j])) { + mac_addrs[j] = macs[i]; break; } } @@ -677,28 +692,40 @@ struct mlx5_nl_ifindex_data { /** * Flush all added MAC addresses. * - * @param dev - * Pointer to Ethernet device. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param[in] mac_addrs + * Mac addresses array to flush. + * @param n + * @p mac_addrs array size. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. */ void -mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev) +mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own) { - struct mlx5_priv *priv = dev->data->dev_private; int i; - for (i = MLX5_MAX_MAC_ADDRESSES - 1; i >= 0; --i) { - struct rte_ether_addr *m = &dev->data->mac_addrs[i]; + for (i = n - 1; i >= 0; --i) { + struct rte_ether_addr *m = &mac_addrs[i]; - if (BITFIELD_ISSET(priv->mac_own, i)) - mlx5_nl_mac_addr_remove(dev, m, i); + if (BITFIELD_ISSET(mac_own, i)) + mlx5_nl_mac_addr_remove(nlsk_fd, iface_idx, mac_own, m, + i); } } /** * Enable promiscuous / all multicast mode through Netlink. * - * @param dev - * Pointer to Ethernet device structure. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param flags * IFF_PROMISC for promiscuous, IFF_ALLMULTI for allmulti. * @param enable @@ -708,10 +735,9 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -mlx5_nl_device_flags(struct rte_eth_dev *dev, uint32_t flags, int enable) +mlx5_nl_device_flags(int nlsk_fd, unsigned int iface_idx, uint32_t flags, + int enable) { - struct mlx5_priv *priv = dev->data->dev_private; - unsigned int iface_idx = mlx5_ifindex(dev); struct { struct nlmsghdr hdr; struct ifinfomsg ifi; @@ -727,14 +753,13 @@ struct mlx5_nl_ifindex_data { .ifi_index = iface_idx, }, }; - int fd; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; assert(!(flags & ~(IFF_PROMISC | IFF_ALLMULTI))); - if (priv->nl_socket_route < 0) + if (nlsk_fd < 0) return 0; - fd = priv->nl_socket_route; - ret = mlx5_nl_send(fd, &req.hdr, priv->nl_sn++); + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); if (ret < 0) return ret; return 0; @@ -743,8 +768,10 @@ struct mlx5_nl_ifindex_data { /** * Enable promiscuous mode through Netlink. * - * @param dev - * Pointer to Ethernet device structure. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param enable * Nonzero to enable, disable otherwise. * @@ -752,14 +779,14 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_promisc(struct rte_eth_dev *dev, int enable) +mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable) { - int ret = mlx5_nl_device_flags(dev, IFF_PROMISC, enable); + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_PROMISC, enable); if (ret) DRV_LOG(DEBUG, - "port %u cannot %s promisc mode: Netlink error %s", - dev->data->port_id, enable ? "enable" : "disable", + "Interface %u cannot %s promisc mode: Netlink error %s", + iface_idx, enable ? "enable" : "disable", strerror(rte_errno)); return ret; } @@ -767,8 +794,10 @@ struct mlx5_nl_ifindex_data { /** * Enable all multicast mode through Netlink. * - * @param dev - * Pointer to Ethernet device structure. + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. * @param enable * Nonzero to enable, disable otherwise. * @@ -776,14 +805,15 @@ struct mlx5_nl_ifindex_data { * 0 on success, a negative errno value otherwise and rte_errno is set. */ int -mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable) +mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable) { - int ret = mlx5_nl_device_flags(dev, IFF_ALLMULTI, enable); + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_ALLMULTI, + enable); if (ret) DRV_LOG(DEBUG, - "port %u cannot %s allmulti mode: Netlink error %s", - dev->data->port_id, enable ? "enable" : "disable", + "Interface %u cannot %s allmulti : Netlink error %s", + iface_idx, enable ? "enable" : "disable", strerror(rte_errno)); return ret; } @@ -879,7 +909,6 @@ struct mlx5_nl_ifindex_data { unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex) { - uint32_t seq = random(); struct mlx5_nl_ifindex_data data = { .name = name, .flags = 0, @@ -900,19 +929,20 @@ struct mlx5_nl_ifindex_data { }, }; struct nlattr *na; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; - ret = mlx5_nl_send(nl, &req.nh, seq); + ret = mlx5_nl_send(nl, &req.nh, sn); if (ret < 0) return 0; - ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data); + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); if (ret < 0) return 0; if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || !(data.flags & MLX5_NL_CMD_GET_IB_INDEX)) goto error; data.flags = 0; - ++seq; + sn = MLX5_NL_SN_GENERATE; req.nh.nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_PORT_GET); req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; @@ -927,10 +957,10 @@ struct mlx5_nl_ifindex_data { na->nla_type = RDMA_NLDEV_ATTR_PORT_INDEX; memcpy((void *)((uintptr_t)na + NLA_HDRLEN), &pindex, sizeof(pindex)); - ret = mlx5_nl_send(nl, &req.nh, seq); + ret = mlx5_nl_send(nl, &req.nh, sn); if (ret < 0) return 0; - ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data); + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); if (ret < 0) return 0; if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || @@ -959,7 +989,6 @@ struct mlx5_nl_ifindex_data { unsigned int mlx5_nl_portnum(int nl, const char *name) { - uint32_t seq = random(); struct mlx5_nl_ifindex_data data = { .flags = 0, .name = name, @@ -972,12 +1001,13 @@ struct mlx5_nl_ifindex_data { RDMA_NLDEV_CMD_GET), .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, }; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; - ret = mlx5_nl_send(nl, &req, seq); + ret = mlx5_nl_send(nl, &req, sn); if (ret < 0) return 0; - ret = mlx5_nl_recv(nl, seq, mlx5_nl_cmdget_cb, &data); + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); if (ret < 0) return 0; if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || @@ -992,6 +1022,55 @@ struct mlx5_nl_ifindex_data { } /** + * Analyze gathered port parameters via Netlink to recognize master + * and representor devices for E-Switch configuration. + * + * @param[in] num_vf_set + * flag of presence of number of VFs port attribute. + * @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). + */ +static void +mlx5_nl_check_switch_info(bool num_vf_set, + 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 number of VFs key presence. + */ + switch_info->master = num_vf_set; + 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 + * number of VFs key. + */ + switch_info->master = num_vf_set; + 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 = !num_vf_set; + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFVF: + /* New representors naming schema. */ + switch_info->representor = 1; + break; + } +} + +/** * Process switch information from Netlink message. * * @param nh @@ -1072,7 +1151,6 @@ struct mlx5_nl_ifindex_data { mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info) { - uint32_t seq = random(); struct { struct nlmsghdr nh; struct ifinfomsg info; @@ -1096,11 +1174,12 @@ struct mlx5_nl_ifindex_data { }, .extmask = RTE_LE32(1), }; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; - ret = mlx5_nl_send(nl, &req.nh, seq); + ret = mlx5_nl_send(nl, &req.nh, sn); if (ret >= 0) - ret = mlx5_nl_recv(nl, seq, mlx5_nl_switch_info_cb, info); + ret = mlx5_nl_recv(nl, sn, mlx5_nl_switch_info_cb, info); if (info->master && info->representor) { DRV_LOG(ERR, "ifindex %u device is recognized as master" " and as representor", ifindex); @@ -1122,6 +1201,7 @@ struct mlx5_nl_ifindex_data { mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex) { + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; struct { struct nlmsghdr nh; @@ -1139,18 +1219,12 @@ struct mlx5_nl_ifindex_data { }; if (ifindex) { - ++vmwa->nl_sn; - if (!vmwa->nl_sn) - ++vmwa->nl_sn; - ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, vmwa->nl_sn); + ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, sn); if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, - vmwa->nl_sn, - NULL, NULL); + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); if (ret < 0) - DRV_LOG(WARNING, "netlink: error deleting" - " VLAN WA ifindex %u, %d", - ifindex, ret); + DRV_LOG(WARNING, "netlink: error deleting VLAN WA" + " ifindex %u, %d", ifindex, ret); } } @@ -1202,8 +1276,7 @@ struct mlx5_nl_ifindex_data { */ uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex, - uint16_t tag) + uint32_t ifindex, uint16_t tag) { struct nlmsghdr *nlh; struct ifinfomsg *ifm; @@ -1220,12 +1293,10 @@ struct mlx5_nl_ifindex_data { NLMSG_ALIGN(sizeof(uint16_t)) + 16]; struct nlattr *na_info; struct nlattr *na_vlan; + uint32_t sn = MLX5_NL_SN_GENERATE; int ret; memset(buf, 0, sizeof(buf)); - ++vmwa->nl_sn; - if (!vmwa->nl_sn) - ++vmwa->nl_sn; nlh = (struct nlmsghdr *)buf; nlh->nlmsg_len = sizeof(struct nlmsghdr); nlh->nlmsg_type = RTM_NEWLINK; @@ -1249,20 +1320,18 @@ struct mlx5_nl_ifindex_data { nl_attr_nest_end(nlh, na_vlan); nl_attr_nest_end(nlh, na_info); assert(sizeof(buf) >= nlh->nlmsg_len); - ret = mlx5_nl_send(vmwa->nl_socket, nlh, vmwa->nl_sn); + ret = mlx5_nl_send(vmwa->nl_socket, nlh, sn); if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, vmwa->nl_sn, NULL, NULL); + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); if (ret < 0) { - DRV_LOG(WARNING, - "netlink: VLAN %s create failure (%d)", - name, ret); + DRV_LOG(WARNING, "netlink: VLAN %s create failure (%d)", name, + ret); } // Try to get ifindex of created or pre-existing device. ret = if_nametoindex(name); if (!ret) { - DRV_LOG(WARNING, - "VLAN %s failed to get index (%d)", - name, errno); + DRV_LOG(WARNING, "VLAN %s failed to get index (%d)", name, + errno); return 0; } return ret; diff --git a/drivers/net/mlx5/mlx5_nl.h b/drivers/net/mlx5/mlx5_nl.h index 7903673..9be87c0 100644 --- a/drivers/net/mlx5/mlx5_nl.h +++ b/drivers/net/mlx5/mlx5_nl.h @@ -39,30 +39,33 @@ struct mlx5_nl_vlan_dev { */ struct mlx5_nl_vlan_vmwa_context { int nl_socket; - uint32_t nl_sn; uint32_t vf_ifindex; struct mlx5_nl_vlan_dev vlan_dev[4096]; }; int mlx5_nl_init(int protocol); -int mlx5_nl_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, - uint32_t index); -int mlx5_nl_mac_addr_remove(struct rte_eth_dev *dev, struct rte_ether_addr *mac, +int mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index); +int mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, uint32_t index); -void mlx5_nl_mac_addr_sync(struct rte_eth_dev *dev); -void mlx5_nl_mac_addr_flush(struct rte_eth_dev *dev); -int mlx5_nl_promisc(struct rte_eth_dev *dev, int enable); -int mlx5_nl_allmulti(struct rte_eth_dev *dev, int enable); +void mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n); +void mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own); +int mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable); +int mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable); unsigned int mlx5_nl_portnum(int nl, const char *name); unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); -int mlx5_nl_vf_mac_addr_modify(struct rte_eth_dev *dev, +int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, struct rte_ether_addr *mac, int vf_index); int mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info); void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex); + uint32_t ifindex); uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex, uint16_t tag); diff --git a/drivers/net/mlx5/mlx5_rxmode.c b/drivers/net/mlx5/mlx5_rxmode.c index 760cc2f..84c8b05 100644 --- a/drivers/net/mlx5/mlx5_rxmode.c +++ b/drivers/net/mlx5/mlx5_rxmode.c @@ -47,7 +47,8 @@ return 0; } if (priv->config.vf) { - ret = mlx5_nl_promisc(dev, 1); + ret = mlx5_nl_promisc(priv->nl_socket_route, mlx5_ifindex(dev), + 1); if (ret) return ret; } @@ -80,7 +81,8 @@ dev->data->promiscuous = 0; if (priv->config.vf) { - ret = mlx5_nl_promisc(dev, 0); + ret = mlx5_nl_promisc(priv->nl_socket_route, mlx5_ifindex(dev), + 0); if (ret) return ret; } @@ -120,7 +122,8 @@ return 0; } if (priv->config.vf) { - ret = mlx5_nl_allmulti(dev, 1); + ret = mlx5_nl_allmulti(priv->nl_socket_route, mlx5_ifindex(dev), + 1); if (ret) goto error; } @@ -153,7 +156,8 @@ dev->data->all_multicast = 0; if (priv->config.vf) { - ret = mlx5_nl_allmulti(dev, 0); + ret = mlx5_nl_allmulti(priv->nl_socket_route, mlx5_ifindex(dev), + 0); if (ret) goto error; } diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index fb52d8f..fc1a91c 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -304,7 +304,6 @@ struct mlx5_nl_vlan_vmwa_context * rte_free(vmwa); return NULL; } - vmwa->nl_sn = random(); vmwa->vf_ifindex = ifindex; /* Cleanup for existing VLAN devices. */ return vmwa; From patchwork Wed Jan 29 12:38:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65332 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E91D9A052F; Wed, 29 Jan 2020 13:43:43 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 60AB01C10A; Wed, 29 Jan 2020 13:39:59 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 924141C02E for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:32 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1w018914; Wed, 29 Jan 2020 14:39:32 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:49 +0000 Message-Id: <1580301530-6643-25-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 24/25] common/mlx5: share Netlink commands X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Move Netlink mechanism and its dependencies from net/mlx5 to common/mlx5 in order to be ready to use by other mlx5 drivers. The dependencies are BITFIELD defines, the ppc64 compilation workaround for bool type and the function mlx5_translate_port_name. Update build mechanism accordingly. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 3 +- drivers/common/mlx5/meson.build | 1 + drivers/common/mlx5/mlx5_common.c | 55 + drivers/common/mlx5/mlx5_common.h | 59 + drivers/common/mlx5/mlx5_nl.c | 1337 ++++++++++++++++++++++ drivers/common/mlx5/mlx5_nl.h | 57 + drivers/common/mlx5/rte_common_mlx5_version.map | 16 + drivers/net/mlx5/Makefile | 1 - drivers/net/mlx5/meson.build | 1 - drivers/net/mlx5/mlx5.h | 2 +- drivers/net/mlx5/mlx5_defs.h | 8 - drivers/net/mlx5/mlx5_ethdev.c | 55 - drivers/net/mlx5/mlx5_nl.c | 1338 ----------------------- drivers/net/mlx5/mlx5_nl.h | 72 -- drivers/net/mlx5/mlx5_vlan.c | 2 +- 15 files changed, 1529 insertions(+), 1478 deletions(-) create mode 100644 drivers/common/mlx5/mlx5_nl.c create mode 100644 drivers/common/mlx5/mlx5_nl.h delete mode 100644 drivers/net/mlx5/mlx5_nl.c delete mode 100644 drivers/net/mlx5/mlx5_nl.h diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index b9e9803..6a14b7d 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -15,6 +15,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_glue.c endif SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_devx_cmds.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_common.c +SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_nl.c ifeq ($(CONFIG_RTE_IBVERBS_LINK_DLOPEN),y) INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE) @@ -41,7 +42,7 @@ else LDLIBS += -libverbs -lmlx5 endif -LDLIBS += -lrte_eal -lrte_pci -lrte_kvargs +LDLIBS += -lrte_eal -lrte_pci -lrte_kvargs -lrte_net # A few warnings cannot be avoided in external headers. CFLAGS += -Wno-error=cast-qual -DNDEBUG -UPEDANTIC diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index b88822e..34cb7b9 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -42,6 +42,7 @@ if build sources = files( 'mlx5_devx_cmds.c', 'mlx5_common.c', + 'mlx5_nl.c', ) if not pmd_dlopen sources += files('mlx5_glue.c') diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c index 52f191a..922794e 100644 --- a/drivers/common/mlx5/mlx5_common.c +++ b/drivers/common/mlx5/mlx5_common.c @@ -107,6 +107,61 @@ enum mlx5_class return ret; } +/** + * Extract port name, as a number, from sysfs or netlink information. + * + * @param[in] port_name_in + * String representing the port name. + * @param[out] port_info_out + * Port information, including port name as a number and port name + * type if recognized + * + * @return + * port_name field set according to recognized name format. + */ +void +mlx5_translate_port_name(const char *port_name_in, + struct mlx5_switch_info *port_info_out) +{ + char pf_c1, pf_c2, vf_c1, vf_c2; + char *end; + int sc_items; + + /* + * Check for port-name as a string of the form pf0vf0 + * (support kernel ver >= 5.0 or OFED ver >= 4.6). + */ + sc_items = sscanf(port_name_in, "%c%c%d%c%c%d", + &pf_c1, &pf_c2, &port_info_out->pf_num, + &vf_c1, &vf_c2, &port_info_out->port_name); + if (sc_items == 6 && + pf_c1 == 'p' && pf_c2 == 'f' && + vf_c1 == 'v' && vf_c2 == 'f') { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_PFVF; + return; + } + /* + * Check for port-name as a string of the form p0 + * (support kernel ver >= 5.0, or OFED ver >= 4.6). + */ + sc_items = sscanf(port_name_in, "%c%d", + &pf_c1, &port_info_out->port_name); + if (sc_items == 2 && pf_c1 == 'p') { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK; + return; + } + /* Check for port-name as a number (support kernel ver < 5.0 */ + errno = 0; + port_info_out->port_name = strtol(port_name_in, &end, 0); + if (!errno && + (size_t)(end - port_name_in) == strlen(port_name_in)) { + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_LEGACY; + return; + } + port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; + return; +} + #ifdef RTE_IBVERBS_LINK_DLOPEN /** diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h index 2988f4b..d9c2d26 100644 --- a/drivers/common/mlx5/mlx5_common.h +++ b/drivers/common/mlx5/mlx5_common.h @@ -18,6 +18,35 @@ /* + * Compilation workaround for PPC64 when AltiVec is fully enabled, e.g. std=c11. + * Otherwise there would be a type conflict between stdbool and altivec. + */ +#if defined(__PPC64__) && !defined(__APPLE_ALTIVEC__) +#undef bool +/* redefine as in stdbool.h */ +#define bool _Bool +#endif + +/* Bit-field manipulation. */ +#define BITFIELD_DECLARE(bf, type, size) \ + type bf[(((size_t)(size) / (sizeof(type) * CHAR_BIT)) + \ + !!((size_t)(size) % (sizeof(type) * CHAR_BIT)))] +#define BITFIELD_DEFINE(bf, type, size) \ + BITFIELD_DECLARE((bf), type, (size)) = { 0 } +#define BITFIELD_SET(bf, b) \ + (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ + (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] |= \ + ((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT))))) +#define BITFIELD_RESET(bf, b) \ + (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ + (void)((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] &= \ + ~((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT))))) +#define BITFIELD_ISSET(bf, b) \ + (assert((size_t)(b) < (sizeof(bf) * CHAR_BIT)), \ + !!(((bf)[((b) / (sizeof((bf)[0]) * CHAR_BIT))] & \ + ((size_t)1 << ((b) % (sizeof((bf)[0]) * CHAR_BIT)))))) + +/* * Helper macros to work around __VA_ARGS__ limitations in a C99 compliant * manner. */ @@ -112,6 +141,33 @@ enum { PCI_DEVICE_ID_MELLANOX_CONNECTX6DXVF = 0x101e, }; +/* Maximum number of simultaneous unicast MAC addresses. */ +#define MLX5_MAX_UC_MAC_ADDRESSES 128 +/* Maximum number of simultaneous Multicast MAC addresses. */ +#define MLX5_MAX_MC_MAC_ADDRESSES 128 +/* Maximum number of simultaneous MAC addresses. */ +#define MLX5_MAX_MAC_ADDRESSES \ + (MLX5_MAX_UC_MAC_ADDRESSES + MLX5_MAX_MC_MAC_ADDRESSES) + +/* Recognized Infiniband device physical port name types. */ +enum mlx5_nl_phys_port_name_type { + MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */ + MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */ + MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */ +}; + +/** Switch information returned by mlx5_nl_switch_info(). */ +struct mlx5_switch_info { + uint32_t master:1; /**< Master device. */ + uint32_t representor:1; /**< Representor device. */ + enum mlx5_nl_phys_port_name_type name_type; /** < Port name type. */ + int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ + int32_t port_name; /**< Representor port name. */ + uint64_t switch_id; /**< Switch identifier. */ +}; + /* CQE status. */ enum mlx5_cqe_status { MLX5_CQE_STATUS_SW_OWN = -1, @@ -159,6 +215,9 @@ enum mlx5_class { MLX5_CLASS_VDPA, MLX5_CLASS_INVALID, }; + enum mlx5_class mlx5_class_get(struct rte_devargs *devargs); +void mlx5_translate_port_name(const char *port_name_in, + struct mlx5_switch_info *port_info_out); #endif /* RTE_PMD_MLX5_COMMON_H_ */ diff --git a/drivers/common/mlx5/mlx5_nl.c b/drivers/common/mlx5/mlx5_nl.c new file mode 100644 index 0000000..b4fc053 --- /dev/null +++ b/drivers/common/mlx5/mlx5_nl.c @@ -0,0 +1,1337 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 6WIND S.A. + * Copyright 2018 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mlx5_nl.h" +#include "mlx5_common_utils.h" + +/* Size of the buffer to receive kernel messages */ +#define MLX5_NL_BUF_SIZE (32 * 1024) +/* Send buffer size for the Netlink socket */ +#define MLX5_SEND_BUF_SIZE 32768 +/* Receive buffer size for the Netlink socket */ +#define MLX5_RECV_BUF_SIZE 32768 + +/** Parameters of VLAN devices created by driver. */ +#define MLX5_VMWA_VLAN_DEVICE_PFX "evmlx" +/* + * Define NDA_RTA as defined in iproute2 sources. + * + * see in iproute2 sources file include/libnetlink.h + */ +#ifndef MLX5_NDA_RTA +#define MLX5_NDA_RTA(r) \ + ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif +/* + * Define NLMSG_TAIL as defined in iproute2 sources. + * + * see in iproute2 sources file include/libnetlink.h + */ +#ifndef NLMSG_TAIL +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *)(((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#endif +/* + * The following definitions are normally found in rdma/rdma_netlink.h, + * however they are so recent that most systems do not expose them yet. + */ +#ifndef HAVE_RDMA_NL_NLDEV +#define RDMA_NL_NLDEV 5 +#endif +#ifndef HAVE_RDMA_NLDEV_CMD_GET +#define RDMA_NLDEV_CMD_GET 1 +#endif +#ifndef HAVE_RDMA_NLDEV_CMD_PORT_GET +#define RDMA_NLDEV_CMD_PORT_GET 5 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_INDEX +#define RDMA_NLDEV_ATTR_DEV_INDEX 1 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_NAME +#define RDMA_NLDEV_ATTR_DEV_NAME 2 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_PORT_INDEX +#define RDMA_NLDEV_ATTR_PORT_INDEX 3 +#endif +#ifndef HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX +#define RDMA_NLDEV_ATTR_NDEV_INDEX 50 +#endif + +/* These are normally found in linux/if_link.h. */ +#ifndef HAVE_IFLA_NUM_VF +#define IFLA_NUM_VF 21 +#endif +#ifndef HAVE_IFLA_EXT_MASK +#define IFLA_EXT_MASK 29 +#endif +#ifndef HAVE_IFLA_PHYS_SWITCH_ID +#define IFLA_PHYS_SWITCH_ID 36 +#endif +#ifndef HAVE_IFLA_PHYS_PORT_NAME +#define IFLA_PHYS_PORT_NAME 38 +#endif + +/* Add/remove MAC address through Netlink */ +struct mlx5_nl_mac_addr { + struct rte_ether_addr (*mac)[]; + /**< MAC address handled by the device. */ + int mac_n; /**< Number of addresses in the array. */ +}; + +#define MLX5_NL_CMD_GET_IB_NAME (1 << 0) +#define MLX5_NL_CMD_GET_IB_INDEX (1 << 1) +#define MLX5_NL_CMD_GET_NET_INDEX (1 << 2) +#define MLX5_NL_CMD_GET_PORT_INDEX (1 << 3) + +/** Data structure used by mlx5_nl_cmdget_cb(). */ +struct mlx5_nl_ifindex_data { + const char *name; /**< IB device name (in). */ + uint32_t flags; /**< found attribute flags (out). */ + uint32_t ibindex; /**< IB device index (out). */ + uint32_t ifindex; /**< Network interface index (out). */ + uint32_t portnum; /**< IB device max port number (out). */ +}; + +rte_atomic32_t atomic_sn = RTE_ATOMIC32_INIT(0); + +/* Generate Netlink sequence number. */ +#define MLX5_NL_SN_GENERATE ((uint32_t)rte_atomic32_add_return(&atomic_sn, 1)) + +/** + * Opens a Netlink socket. + * + * @param protocol + * Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA). + * + * @return + * A file descriptor on success, a negative errno value otherwise and + * rte_errno is set. + */ +int +mlx5_nl_init(int protocol) +{ + int fd; + int sndbuf_size = MLX5_SEND_BUF_SIZE; + int rcvbuf_size = MLX5_RECV_BUF_SIZE; + struct sockaddr_nl local = { + .nl_family = AF_NETLINK, + }; + int ret; + + fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); + if (fd == -1) { + rte_errno = errno; + return -rte_errno; + } + ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(int)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, sizeof(int)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + ret = bind(fd, (struct sockaddr *)&local, sizeof(local)); + if (ret == -1) { + rte_errno = errno; + goto error; + } + return fd; +error: + close(fd); + return -rte_errno; +} + +/** + * Send a request message to the kernel on the Netlink socket. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] nh + * The Netlink message send to the kernel. + * @param[in] ssn + * Sequence number. + * @param[in] req + * Pointer to the request structure. + * @param[in] len + * Length of the request in bytes. + * + * @return + * The number of sent bytes on success, a negative errno value otherwise and + * rte_errno is set. + */ +static int +mlx5_nl_request(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn, void *req, + int len) +{ + struct sockaddr_nl sa = { + .nl_family = AF_NETLINK, + }; + struct iovec iov[2] = { + { .iov_base = nh, .iov_len = sizeof(*nh), }, + { .iov_base = req, .iov_len = len, }, + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = iov, + .msg_iovlen = 2, + }; + int send_bytes; + + nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ + nh->nlmsg_seq = sn; + send_bytes = sendmsg(nlsk_fd, &msg, 0); + if (send_bytes < 0) { + rte_errno = errno; + return -rte_errno; + } + return send_bytes; +} + +/** + * Send a message to the kernel on the Netlink socket. + * + * @param[in] nlsk_fd + * The Netlink socket file descriptor used for communication. + * @param[in] nh + * The Netlink message send to the kernel. + * @param[in] sn + * Sequence number. + * + * @return + * The number of sent bytes on success, a negative errno value otherwise and + * rte_errno is set. + */ +static int +mlx5_nl_send(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn) +{ + struct sockaddr_nl sa = { + .nl_family = AF_NETLINK, + }; + struct iovec iov = { + .iov_base = nh, + .iov_len = nh->nlmsg_len, + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + .msg_iovlen = 1, + }; + int send_bytes; + + nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ + nh->nlmsg_seq = sn; + send_bytes = sendmsg(nlsk_fd, &msg, 0); + if (send_bytes < 0) { + rte_errno = errno; + return -rte_errno; + } + return send_bytes; +} + +/** + * Receive a message from the kernel on the Netlink socket, following + * mlx5_nl_send(). + * + * @param[in] nlsk_fd + * The Netlink socket file descriptor used for communication. + * @param[in] sn + * Sequence number. + * @param[in] cb + * The callback function to call for each Netlink message received. + * @param[in, out] arg + * Custom arguments for the callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), + void *arg) +{ + struct sockaddr_nl sa; + char buf[MLX5_RECV_BUF_SIZE]; + struct iovec iov = { + .iov_base = buf, + .iov_len = sizeof(buf), + }; + struct msghdr msg = { + .msg_name = &sa, + .msg_namelen = sizeof(sa), + .msg_iov = &iov, + /* One message at a time */ + .msg_iovlen = 1, + }; + int multipart = 0; + int ret = 0; + + do { + struct nlmsghdr *nh; + int recv_bytes = 0; + + do { + recv_bytes = recvmsg(nlsk_fd, &msg, 0); + if (recv_bytes == -1) { + rte_errno = errno; + return -rte_errno; + } + nh = (struct nlmsghdr *)buf; + } while (nh->nlmsg_seq != sn); + for (; + NLMSG_OK(nh, (unsigned int)recv_bytes); + nh = NLMSG_NEXT(nh, recv_bytes)) { + if (nh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err_data = NLMSG_DATA(nh); + + if (err_data->error < 0) { + rte_errno = -err_data->error; + return -rte_errno; + } + /* Ack message. */ + return 0; + } + /* Multi-part msgs and their trailing DONE message. */ + if (nh->nlmsg_flags & NLM_F_MULTI) { + if (nh->nlmsg_type == NLMSG_DONE) + return 0; + multipart = 1; + } + if (cb) { + ret = cb(nh, arg); + if (ret < 0) + return ret; + } + } + } while (multipart); + return ret; +} + +/** + * Parse Netlink message to retrieve the bridge MAC address. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_nl_mac_addr *data = arg; + struct ndmsg *r = NLMSG_DATA(nh); + struct rtattr *attribute; + int len; + + len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); + for (attribute = MLX5_NDA_RTA(r); + RTA_OK(attribute, len); + attribute = RTA_NEXT(attribute, len)) { + if (attribute->rta_type == NDA_LLADDR) { + if (data->mac_n == MLX5_MAX_MAC_ADDRESSES) { + DRV_LOG(WARNING, + "not enough room to finalize the" + " request"); + rte_errno = ENOMEM; + return -rte_errno; + } +#ifndef NDEBUG + char m[18]; + + rte_ether_format_addr(m, 18, RTA_DATA(attribute)); + DRV_LOG(DEBUG, "bridge MAC address %s", m); +#endif + memcpy(&(*data->mac)[data->mac_n++], + RTA_DATA(attribute), RTE_ETHER_ADDR_LEN); + } + } + return 0; +} + +/** + * Get bridge MAC addresses. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac[out] + * Pointer to the array table of MAC addresses to fill. + * Its size should be of MLX5_MAX_MAC_ADDRESSES. + * @param mac_n[out] + * Number of entries filled in MAC array. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_list(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr (*mac)[], int *mac_n) +{ + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_GETNEIGH, + .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, + }, + .ifm = { + .ifi_family = PF_BRIDGE, + .ifi_index = iface_idx, + }, + }; + struct mlx5_nl_mac_addr data = { + .mac = mac, + .mac_n = 0, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + if (nlsk_fd == -1) + return 0; + ret = mlx5_nl_request(nlsk_fd, &req.hdr, sn, &req.ifm, + sizeof(struct ifinfomsg)); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_mac_addr_cb, &data); + if (ret < 0) + goto error; + *mac_n = data.mac_n; + return 0; +error: + DRV_LOG(DEBUG, "Interface %u cannot retrieve MAC address list %s", + iface_idx, strerror(rte_errno)); + return -rte_errno; +} + +/** + * Modify the MAC address neighbour table with Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac + * MAC address to consider. + * @param add + * 1 to add the MAC address, 0 to remove the MAC address. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int add) +{ + struct { + struct nlmsghdr hdr; + struct ndmsg ndm; + struct rtattr rta; + uint8_t buffer[RTE_ETHER_ADDR_LEN]; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | + NLM_F_EXCL | NLM_F_ACK, + .nlmsg_type = add ? RTM_NEWNEIGH : RTM_DELNEIGH, + }, + .ndm = { + .ndm_family = PF_BRIDGE, + .ndm_state = NUD_NOARP | NUD_PERMANENT, + .ndm_ifindex = iface_idx, + .ndm_flags = NTF_SELF, + }, + .rta = { + .rta_type = NDA_LLADDR, + .rta_len = RTA_LENGTH(RTE_ETHER_ADDR_LEN), + }, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + if (nlsk_fd == -1) + return 0; + memcpy(RTA_DATA(&req.rta), mac, RTE_ETHER_ADDR_LEN); + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_ALIGN(req.rta.rta_len); + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) + goto error; + return 0; +error: + DRV_LOG(DEBUG, + "Interface %u cannot %s MAC address" + " %02X:%02X:%02X:%02X:%02X:%02X %s", + iface_idx, + add ? "add" : "remove", + mac->addr_bytes[0], mac->addr_bytes[1], + mac->addr_bytes[2], mac->addr_bytes[3], + mac->addr_bytes[4], mac->addr_bytes[5], + strerror(rte_errno)); + return -rte_errno; +} + +/** + * Modify the VF MAC address neighbour table with Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac + * MAC address to consider. + * @param vf_index + * VF index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int vf_index) +{ + int ret; + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifm; + struct rtattr vf_list_rta; + struct rtattr vf_info_rta; + struct rtattr vf_mac_rta; + struct ifla_vf_mac ivm; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + .nlmsg_type = RTM_BASE, + }, + .ifm = { + .ifi_index = iface_idx, + }, + .vf_list_rta = { + .rta_type = IFLA_VFINFO_LIST, + .rta_len = RTA_ALIGN(RTA_LENGTH(0)), + }, + .vf_info_rta = { + .rta_type = IFLA_VF_INFO, + .rta_len = RTA_ALIGN(RTA_LENGTH(0)), + }, + .vf_mac_rta = { + .rta_type = IFLA_VF_MAC, + }, + }; + struct ifla_vf_mac ivm = { + .vf = vf_index, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + + memcpy(&ivm.mac, mac, RTE_ETHER_ADDR_LEN); + memcpy(RTA_DATA(&req.vf_mac_rta), &ivm, sizeof(ivm)); + + req.vf_mac_rta.rta_len = RTA_LENGTH(sizeof(ivm)); + req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + + RTA_ALIGN(req.vf_list_rta.rta_len) + + RTA_ALIGN(req.vf_info_rta.rta_len) + + RTA_ALIGN(req.vf_mac_rta.rta_len); + req.vf_list_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), + &req.vf_list_rta); + req.vf_info_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), + &req.vf_info_rta); + + if (nlsk_fd < 0) + return -1; + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + goto error; + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) + goto error; + return 0; +error: + DRV_LOG(ERR, + "representor %u cannot set VF MAC address " + "%02X:%02X:%02X:%02X:%02X:%02X : %s", + vf_index, + mac->addr_bytes[0], mac->addr_bytes[1], + mac->addr_bytes[2], mac->addr_bytes[3], + mac->addr_bytes[4], mac->addr_bytes[5], + strerror(rte_errno)); + return -rte_errno; +} + +/** + * Add a MAC address. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + * @param mac + * MAC address to register. + * @param index + * MAC address index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, + uint32_t index) +{ + int ret; + + ret = mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 1); + if (!ret) + BITFIELD_SET(mac_own, index); + if (ret == -EEXIST) + return 0; + return ret; +} + +/** + * Remove a MAC address. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + * @param mac + * MAC address to remove. + * @param index + * MAC address index. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index) +{ + BITFIELD_RESET(mac_own, index); + return mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 0); +} + +/** + * Synchronize Netlink bridge table to the internal table. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param mac_addrs + * Mac addresses array to sync. + * @param n + * @p mac_addrs array size. + */ +void +mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n) +{ + struct rte_ether_addr macs[n]; + int macs_n = 0; + int i; + int ret; + + ret = mlx5_nl_mac_addr_list(nlsk_fd, iface_idx, &macs, &macs_n); + if (ret) + return; + for (i = 0; i != macs_n; ++i) { + int j; + + /* Verify the address is not in the array yet. */ + for (j = 0; j != n; ++j) + if (rte_is_same_ether_addr(&macs[i], &mac_addrs[j])) + break; + if (j != n) + continue; + /* Find the first entry available. */ + for (j = 0; j != n; ++j) { + if (rte_is_zero_ether_addr(&mac_addrs[j])) { + mac_addrs[j] = macs[i]; + break; + } + } + } +} + +/** + * Flush all added MAC addresses. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param[in] mac_addrs + * Mac addresses array to flush. + * @param n + * @p mac_addrs array size. + * @param mac_own + * BITFIELD_DECLARE array to store the mac. + */ +void +mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own) +{ + int i; + + for (i = n - 1; i >= 0; --i) { + struct rte_ether_addr *m = &mac_addrs[i]; + + if (BITFIELD_ISSET(mac_own, i)) + mlx5_nl_mac_addr_remove(nlsk_fd, iface_idx, mac_own, m, + i); + } +} + +/** + * Enable promiscuous / all multicast mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param flags + * IFF_PROMISC for promiscuous, IFF_ALLMULTI for allmulti. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_device_flags(int nlsk_fd, unsigned int iface_idx, uint32_t flags, + int enable) +{ + struct { + struct nlmsghdr hdr; + struct ifinfomsg ifi; + } req = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_NEWLINK, + .nlmsg_flags = NLM_F_REQUEST, + }, + .ifi = { + .ifi_flags = enable ? flags : 0, + .ifi_change = flags, + .ifi_index = iface_idx, + }, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + assert(!(flags & ~(IFF_PROMISC | IFF_ALLMULTI))); + if (nlsk_fd < 0) + return 0; + ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); + if (ret < 0) + return ret; + return 0; +} + +/** + * Enable promiscuous mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable) +{ + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_PROMISC, enable); + + if (ret) + DRV_LOG(DEBUG, + "Interface %u cannot %s promisc mode: Netlink error %s", + iface_idx, enable ? "enable" : "disable", + strerror(rte_errno)); + return ret; +} + +/** + * Enable all multicast mode through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] iface_idx + * Net device interface index. + * @param enable + * Nonzero to enable, disable otherwise. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable) +{ + int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_ALLMULTI, + enable); + + if (ret) + DRV_LOG(DEBUG, + "Interface %u cannot %s allmulti : Netlink error %s", + iface_idx, enable ? "enable" : "disable", + strerror(rte_errno)); + return ret; +} + +/** + * Process network interface information from Netlink message. + * + * @param nh + * Pointer to Netlink message header. + * @param arg + * Opaque data pointer for this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_cmdget_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_nl_ifindex_data *data = arg; + struct mlx5_nl_ifindex_data local = { + .flags = 0, + }; + size_t off = NLMSG_HDRLEN; + + if (nh->nlmsg_type != + RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET) && + nh->nlmsg_type != + RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_PORT_GET)) + goto error; + while (off < nh->nlmsg_len) { + struct nlattr *na = (void *)((uintptr_t)nh + off); + void *payload = (void *)((uintptr_t)na + NLA_HDRLEN); + + if (na->nla_len > nh->nlmsg_len - off) + goto error; + switch (na->nla_type) { + case RDMA_NLDEV_ATTR_DEV_INDEX: + local.ibindex = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_IB_INDEX; + break; + case RDMA_NLDEV_ATTR_DEV_NAME: + if (!strcmp(payload, data->name)) + local.flags |= MLX5_NL_CMD_GET_IB_NAME; + break; + case RDMA_NLDEV_ATTR_NDEV_INDEX: + local.ifindex = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_NET_INDEX; + break; + case RDMA_NLDEV_ATTR_PORT_INDEX: + local.portnum = *(uint32_t *)payload; + local.flags |= MLX5_NL_CMD_GET_PORT_INDEX; + break; + default: + break; + } + off += NLA_ALIGN(na->nla_len); + } + /* + * It is possible to have multiple messages for all + * Infiniband devices in the system with appropriate name. + * So we should gather parameters locally and copy to + * query context only in case of coinciding device name. + */ + if (local.flags & MLX5_NL_CMD_GET_IB_NAME) { + data->flags = local.flags; + data->ibindex = local.ibindex; + data->ifindex = local.ifindex; + data->portnum = local.portnum; + } + return 0; +error: + rte_errno = EINVAL; + return -rte_errno; +} + +/** + * Get index of network interface associated with some IB device. + * + * This is the only somewhat safe method to avoid resorting to heuristics + * when faced with port representors. Unfortunately it requires at least + * Linux 4.17. + * + * @param nl + * Netlink socket of the RDMA kind (NETLINK_RDMA). + * @param[in] name + * IB device name. + * @param[in] pindex + * IB device port index, starting from 1 + * @return + * A valid (nonzero) interface index on success, 0 otherwise and rte_errno + * is set. + */ +unsigned int +mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex) +{ + struct mlx5_nl_ifindex_data data = { + .name = name, + .flags = 0, + .ibindex = 0, /* Determined during first pass. */ + .ifindex = 0, /* Determined during second pass. */ + }; + union { + struct nlmsghdr nh; + uint8_t buf[NLMSG_HDRLEN + + NLA_HDRLEN + NLA_ALIGN(sizeof(data.ibindex)) + + NLA_HDRLEN + NLA_ALIGN(sizeof(pindex))]; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH(0), + .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_GET), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, + }, + }; + struct nlattr *na; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX)) + goto error; + data.flags = 0; + sn = MLX5_NL_SN_GENERATE; + req.nh.nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_PORT_GET); + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.buf) - NLMSG_HDRLEN); + na = (void *)((uintptr_t)req.buf + NLMSG_HDRLEN); + na->nla_len = NLA_HDRLEN + sizeof(data.ibindex); + na->nla_type = RDMA_NLDEV_ATTR_DEV_INDEX; + memcpy((void *)((uintptr_t)na + NLA_HDRLEN), + &data.ibindex, sizeof(data.ibindex)); + na = (void *)((uintptr_t)na + NLA_ALIGN(na->nla_len)); + na->nla_len = NLA_HDRLEN + sizeof(pindex); + na->nla_type = RDMA_NLDEV_ATTR_PORT_INDEX; + memcpy((void *)((uintptr_t)na + NLA_HDRLEN), + &pindex, sizeof(pindex)); + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || + !(data.flags & MLX5_NL_CMD_GET_NET_INDEX) || + !data.ifindex) + goto error; + return data.ifindex; +error: + rte_errno = ENODEV; + return 0; +} + +/** + * Get the number of physical ports of given IB device. + * + * @param nl + * Netlink socket of the RDMA kind (NETLINK_RDMA). + * @param[in] name + * IB device name. + * + * @return + * A valid (nonzero) number of ports on success, 0 otherwise + * and rte_errno is set. + */ +unsigned int +mlx5_nl_portnum(int nl, const char *name) +{ + struct mlx5_nl_ifindex_data data = { + .flags = 0, + .name = name, + .ifindex = 0, + .portnum = 0, + }; + struct nlmsghdr req = { + .nlmsg_len = NLMSG_LENGTH(0), + .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, + RDMA_NLDEV_CMD_GET), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req, sn); + if (ret < 0) + return 0; + ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); + if (ret < 0) + return 0; + if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || + !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || + !(data.flags & MLX5_NL_CMD_GET_PORT_INDEX)) { + rte_errno = ENODEV; + return 0; + } + if (!data.portnum) + rte_errno = EINVAL; + return data.portnum; +} + +/** + * Analyze gathered port parameters via Netlink to recognize master + * and representor devices for E-Switch configuration. + * + * @param[in] num_vf_set + * flag of presence of number of VFs port attribute. + * @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). + */ +static void +mlx5_nl_check_switch_info(bool num_vf_set, + 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 number of VFs key presence. + */ + switch_info->master = num_vf_set; + 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 + * number of VFs key. + */ + switch_info->master = num_vf_set; + 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 = !num_vf_set; + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFVF: + /* New representors naming schema. */ + switch_info->representor = 1; + break; + } +} + +/** + * Process switch information from Netlink message. + * + * @param nh + * Pointer to Netlink message header. + * @param arg + * Opaque data pointer for this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) +{ + struct mlx5_switch_info info = { + .master = 0, + .representor = 0, + .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET, + .port_name = 0, + .switch_id = 0, + }; + size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + bool switch_id_set = false; + bool num_vf_set = false; + + if (nh->nlmsg_type != RTM_NEWLINK) + goto error; + while (off < nh->nlmsg_len) { + struct rtattr *ra = (void *)((uintptr_t)nh + off); + void *payload = RTA_DATA(ra); + unsigned int i; + + if (ra->rta_len > nh->nlmsg_len - off) + goto error; + switch (ra->rta_type) { + case IFLA_NUM_VF: + num_vf_set = true; + break; + case IFLA_PHYS_PORT_NAME: + mlx5_translate_port_name((char *)payload, &info); + break; + case IFLA_PHYS_SWITCH_ID: + info.switch_id = 0; + for (i = 0; i < RTA_PAYLOAD(ra); ++i) { + info.switch_id <<= 8; + info.switch_id |= ((uint8_t *)payload)[i]; + } + switch_id_set = true; + break; + } + off += RTA_ALIGN(ra->rta_len); + } + if (switch_id_set) { + /* We have some E-Switch configuration. */ + mlx5_nl_check_switch_info(num_vf_set, &info); + } + assert(!(info.master && info.representor)); + memcpy(arg, &info, sizeof(info)); + return 0; +error: + rte_errno = EINVAL; + return -rte_errno; +} + +/** + * Get switch information associated with network interface. + * + * @param nl + * Netlink socket of the ROUTE kind (NETLINK_ROUTE). + * @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_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info) +{ + struct { + struct nlmsghdr nh; + struct ifinfomsg info; + struct rtattr rta; + uint32_t extmask; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH + (sizeof(req.info) + + RTA_LENGTH(sizeof(uint32_t))), + .nlmsg_type = RTM_GETLINK, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + }, + .info = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex, + }, + .rta = { + .rta_type = IFLA_EXT_MASK, + .rta_len = RTA_LENGTH(sizeof(int32_t)), + }, + .extmask = RTE_LE32(1), + }; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + ret = mlx5_nl_send(nl, &req.nh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nl, sn, mlx5_nl_switch_info_cb, info); + if (info->master && info->representor) { + DRV_LOG(ERR, "ifindex %u device is recognized as master" + " and as representor", ifindex); + rte_errno = ENODEV; + ret = -rte_errno; + } + return ret; +} + +/* + * Delete VLAN network device by ifindex. + * + * @param[in] tcf + * Context object initialized by mlx5_nl_vlan_vmwa_init(). + * @param[in] ifindex + * Interface index of network device to delete. + */ +void +mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex) +{ + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + struct { + struct nlmsghdr nh; + struct ifinfomsg info; + } req = { + .nh = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + .nlmsg_type = RTM_DELLINK, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + }, + .info = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex, + }, + }; + + if (ifindex) { + ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); + if (ret < 0) + DRV_LOG(WARNING, "netlink: error deleting VLAN WA" + " ifindex %u, %d", ifindex, ret); + } +} + +/* Set of subroutines to build Netlink message. */ +static struct nlattr * +nl_msg_tail(struct nlmsghdr *nlh) +{ + return (struct nlattr *) + (((uint8_t *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len)); +} + +static void +nl_attr_put(struct nlmsghdr *nlh, int type, const void *data, int alen) +{ + struct nlattr *nla = nl_msg_tail(nlh); + + nla->nla_type = type; + nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr) + alen); + nlh->nlmsg_len = NLMSG_ALIGN(nlh->nlmsg_len) + nla->nla_len; + + if (alen) + memcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen); +} + +static struct nlattr * +nl_attr_nest_start(struct nlmsghdr *nlh, int type) +{ + struct nlattr *nest = (struct nlattr *)nl_msg_tail(nlh); + + nl_attr_put(nlh, type, NULL, 0); + return nest; +} + +static void +nl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *nest) +{ + nest->nla_len = (uint8_t *)nl_msg_tail(nlh) - (uint8_t *)nest; +} + +/* + * Create network VLAN device with specified VLAN tag. + * + * @param[in] tcf + * Context object initialized by mlx5_nl_vlan_vmwa_init(). + * @param[in] ifindex + * Base network interface index. + * @param[in] tag + * VLAN tag for VLAN network device to create. + */ +uint32_t +mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex, uint16_t tag) +{ + struct nlmsghdr *nlh; + struct ifinfomsg *ifm; + char name[sizeof(MLX5_VMWA_VLAN_DEVICE_PFX) + 32]; + + alignas(RTE_CACHE_LINE_SIZE) + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifinfomsg)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 8 + + NLMSG_ALIGN(sizeof(uint32_t)) + + NLMSG_ALIGN(sizeof(name)) + + NLMSG_ALIGN(sizeof("vlan")) + + NLMSG_ALIGN(sizeof(uint32_t)) + + NLMSG_ALIGN(sizeof(uint16_t)) + 16]; + struct nlattr *na_info; + struct nlattr *na_vlan; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = RTM_NEWLINK; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | + NLM_F_EXCL | NLM_F_ACK; + ifm = (struct ifinfomsg *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct ifinfomsg); + ifm->ifi_family = AF_UNSPEC; + ifm->ifi_type = 0; + ifm->ifi_index = 0; + ifm->ifi_flags = IFF_UP; + ifm->ifi_change = 0xffffffff; + nl_attr_put(nlh, IFLA_LINK, &ifindex, sizeof(ifindex)); + ret = snprintf(name, sizeof(name), "%s.%u.%u", + MLX5_VMWA_VLAN_DEVICE_PFX, ifindex, tag); + nl_attr_put(nlh, IFLA_IFNAME, name, ret + 1); + na_info = nl_attr_nest_start(nlh, IFLA_LINKINFO); + nl_attr_put(nlh, IFLA_INFO_KIND, "vlan", sizeof("vlan")); + na_vlan = nl_attr_nest_start(nlh, IFLA_INFO_DATA); + nl_attr_put(nlh, IFLA_VLAN_ID, &tag, sizeof(tag)); + nl_attr_nest_end(nlh, na_vlan); + nl_attr_nest_end(nlh, na_info); + assert(sizeof(buf) >= nlh->nlmsg_len); + ret = mlx5_nl_send(vmwa->nl_socket, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(WARNING, "netlink: VLAN %s create failure (%d)", name, + ret); + } + // Try to get ifindex of created or pre-existing device. + ret = if_nametoindex(name); + if (!ret) { + DRV_LOG(WARNING, "VLAN %s failed to get index (%d)", name, + errno); + return 0; + } + return ret; +} diff --git a/drivers/common/mlx5/mlx5_nl.h b/drivers/common/mlx5/mlx5_nl.h new file mode 100644 index 0000000..8e66a98 --- /dev/null +++ b/drivers/common/mlx5/mlx5_nl.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 Mellanox Technologies, Ltd + */ + +#ifndef RTE_PMD_MLX5_NL_H_ +#define RTE_PMD_MLX5_NL_H_ + +#include + +#include + +#include "mlx5_common.h" + + +/* VLAN netdev for VLAN workaround. */ +struct mlx5_nl_vlan_dev { + uint32_t refcnt; + uint32_t ifindex; /**< Own interface index. */ +}; + +/* + * Array of VLAN devices created on the base of VF + * used for workaround in virtual environments. + */ +struct mlx5_nl_vlan_vmwa_context { + int nl_socket; + uint32_t vf_ifindex; + struct mlx5_nl_vlan_dev vlan_dev[4096]; +}; + + +int mlx5_nl_init(int protocol); +int mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, + struct rte_ether_addr *mac, uint32_t index); +int mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, + uint64_t *mac_own, struct rte_ether_addr *mac, + uint32_t index); +void mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n); +void mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac_addrs, int n, + uint64_t *mac_own); +int mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable); +int mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable); +unsigned int mlx5_nl_portnum(int nl, const char *name); +unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); +int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, + struct rte_ether_addr *mac, int vf_index); +int mlx5_nl_switch_info(int nl, unsigned int ifindex, + struct mlx5_switch_info *info); + +void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex); +uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, + uint32_t ifindex, uint16_t tag); + +#endif /* RTE_PMD_MLX5_NL_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index 3e7038b..f93f5cb 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -28,4 +28,20 @@ DPDK_20.02 { mlx5_devx_get_out_command_status; mlx5_dev_to_pci_addr; + + mlx5_nl_allmulti; + mlx5_nl_ifindex; + mlx5_nl_init; + mlx5_nl_mac_addr_add; + mlx5_nl_mac_addr_flush; + mlx5_nl_mac_addr_remove; + mlx5_nl_mac_addr_sync; + mlx5_nl_portnum; + mlx5_nl_promisc; + mlx5_nl_switch_info; + mlx5_nl_vf_mac_addr_modify; + mlx5_nl_vlan_vmwa_create; + mlx5_nl_vlan_vmwa_delete; + + mlx5_translate_port_name; }; diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile index dc6b3c8..d26afbb 100644 --- a/drivers/net/mlx5/Makefile +++ b/drivers/net/mlx5/Makefile @@ -30,7 +30,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow_meter.c 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_nl.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_utils.c SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build index e10ef3a..d45be00 100644 --- a/drivers/net/mlx5/meson.build +++ b/drivers/net/mlx5/meson.build @@ -19,7 +19,6 @@ sources = files( 'mlx5_flow_verbs.c', 'mlx5_mac.c', 'mlx5_mr.c', - 'mlx5_nl.c', 'mlx5_rss.c', 'mlx5_rxmode.c', 'mlx5_rxq.c', diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 9864aa7..a7e7089 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -35,11 +35,11 @@ #include #include #include +#include #include "mlx5_defs.h" #include "mlx5_utils.h" #include "mlx5_mr.h" -#include "mlx5_nl.h" #include "mlx5_autoconf.h" /* Request types for IPC. */ diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h index dc9b965..9b392ed 100644 --- a/drivers/net/mlx5/mlx5_defs.h +++ b/drivers/net/mlx5/mlx5_defs.h @@ -14,14 +14,6 @@ /* Reported driver name. */ #define MLX5_DRIVER_NAME "net_mlx5" -/* Maximum number of simultaneous unicast MAC addresses. */ -#define MLX5_MAX_UC_MAC_ADDRESSES 128 -/* Maximum number of simultaneous Multicast MAC addresses. */ -#define MLX5_MAX_MC_MAC_ADDRESSES 128 -/* Maximum number of simultaneous MAC addresses. */ -#define MLX5_MAX_MAC_ADDRESSES \ - (MLX5_MAX_UC_MAC_ADDRESSES + MLX5_MAX_MC_MAC_ADDRESSES) - /* Maximum number of simultaneous VLAN filters. */ #define MLX5_MAX_VLAN_IDS 128 diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index 5484104..b765636 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -1940,61 +1940,6 @@ struct mlx5_priv * } /** - * Extract port name, as a number, from sysfs or netlink information. - * - * @param[in] port_name_in - * String representing the port name. - * @param[out] port_info_out - * Port information, including port name as a number and port name - * type if recognized - * - * @return - * port_name field set according to recognized name format. - */ -void -mlx5_translate_port_name(const char *port_name_in, - struct mlx5_switch_info *port_info_out) -{ - char pf_c1, pf_c2, vf_c1, vf_c2; - char *end; - int sc_items; - - /* - * Check for port-name as a string of the form pf0vf0 - * (support kernel ver >= 5.0 or OFED ver >= 4.6). - */ - sc_items = sscanf(port_name_in, "%c%c%d%c%c%d", - &pf_c1, &pf_c2, &port_info_out->pf_num, - &vf_c1, &vf_c2, &port_info_out->port_name); - if (sc_items == 6 && - pf_c1 == 'p' && pf_c2 == 'f' && - vf_c1 == 'v' && vf_c2 == 'f') { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_PFVF; - return; - } - /* - * Check for port-name as a string of the form p0 - * (support kernel ver >= 5.0, or OFED ver >= 4.6). - */ - sc_items = sscanf(port_name_in, "%c%d", - &pf_c1, &port_info_out->port_name); - if (sc_items == 2 && pf_c1 == 'p') { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK; - return; - } - /* Check for port-name as a number (support kernel ver < 5.0 */ - errno = 0; - port_info_out->port_name = strtol(port_name_in, &end, 0); - if (!errno && - (size_t)(end - port_name_in) == strlen(port_name_in)) { - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_LEGACY; - return; - } - port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN; - return; -} - -/** * DPDK callback to retrieve plug-in module EEPROM information (type and size). * * @param dev diff --git a/drivers/net/mlx5/mlx5_nl.c b/drivers/net/mlx5/mlx5_nl.c deleted file mode 100644 index 6b8ca00..0000000 --- a/drivers/net/mlx5/mlx5_nl.c +++ /dev/null @@ -1,1338 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018 6WIND S.A. - * Copyright 2018 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "mlx5.h" -#include "mlx5_nl.h" -#include "mlx5_utils.h" - -/* Size of the buffer to receive kernel messages */ -#define MLX5_NL_BUF_SIZE (32 * 1024) -/* Send buffer size for the Netlink socket */ -#define MLX5_SEND_BUF_SIZE 32768 -/* Receive buffer size for the Netlink socket */ -#define MLX5_RECV_BUF_SIZE 32768 - -/** Parameters of VLAN devices created by driver. */ -#define MLX5_VMWA_VLAN_DEVICE_PFX "evmlx" -/* - * Define NDA_RTA as defined in iproute2 sources. - * - * see in iproute2 sources file include/libnetlink.h - */ -#ifndef MLX5_NDA_RTA -#define MLX5_NDA_RTA(r) \ - ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) -#endif -/* - * Define NLMSG_TAIL as defined in iproute2 sources. - * - * see in iproute2 sources file include/libnetlink.h - */ -#ifndef NLMSG_TAIL -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *)(((char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) -#endif -/* - * The following definitions are normally found in rdma/rdma_netlink.h, - * however they are so recent that most systems do not expose them yet. - */ -#ifndef HAVE_RDMA_NL_NLDEV -#define RDMA_NL_NLDEV 5 -#endif -#ifndef HAVE_RDMA_NLDEV_CMD_GET -#define RDMA_NLDEV_CMD_GET 1 -#endif -#ifndef HAVE_RDMA_NLDEV_CMD_PORT_GET -#define RDMA_NLDEV_CMD_PORT_GET 5 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_INDEX -#define RDMA_NLDEV_ATTR_DEV_INDEX 1 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_DEV_NAME -#define RDMA_NLDEV_ATTR_DEV_NAME 2 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_PORT_INDEX -#define RDMA_NLDEV_ATTR_PORT_INDEX 3 -#endif -#ifndef HAVE_RDMA_NLDEV_ATTR_NDEV_INDEX -#define RDMA_NLDEV_ATTR_NDEV_INDEX 50 -#endif - -/* These are normally found in linux/if_link.h. */ -#ifndef HAVE_IFLA_NUM_VF -#define IFLA_NUM_VF 21 -#endif -#ifndef HAVE_IFLA_EXT_MASK -#define IFLA_EXT_MASK 29 -#endif -#ifndef HAVE_IFLA_PHYS_SWITCH_ID -#define IFLA_PHYS_SWITCH_ID 36 -#endif -#ifndef HAVE_IFLA_PHYS_PORT_NAME -#define IFLA_PHYS_PORT_NAME 38 -#endif - -/* Add/remove MAC address through Netlink */ -struct mlx5_nl_mac_addr { - struct rte_ether_addr (*mac)[]; - /**< MAC address handled by the device. */ - int mac_n; /**< Number of addresses in the array. */ -}; - -#define MLX5_NL_CMD_GET_IB_NAME (1 << 0) -#define MLX5_NL_CMD_GET_IB_INDEX (1 << 1) -#define MLX5_NL_CMD_GET_NET_INDEX (1 << 2) -#define MLX5_NL_CMD_GET_PORT_INDEX (1 << 3) - -/** Data structure used by mlx5_nl_cmdget_cb(). */ -struct mlx5_nl_ifindex_data { - const char *name; /**< IB device name (in). */ - uint32_t flags; /**< found attribute flags (out). */ - uint32_t ibindex; /**< IB device index (out). */ - uint32_t ifindex; /**< Network interface index (out). */ - uint32_t portnum; /**< IB device max port number (out). */ -}; - -rte_atomic32_t atomic_sn = RTE_ATOMIC32_INIT(0); - -/* Generate Netlink sequence number. */ -#define MLX5_NL_SN_GENERATE ((uint32_t)rte_atomic32_add_return(&atomic_sn, 1)) - -/** - * Opens a Netlink socket. - * - * @param protocol - * Netlink protocol (e.g. NETLINK_ROUTE, NETLINK_RDMA). - * - * @return - * A file descriptor on success, a negative errno value otherwise and - * rte_errno is set. - */ -int -mlx5_nl_init(int protocol) -{ - int fd; - int sndbuf_size = MLX5_SEND_BUF_SIZE; - int rcvbuf_size = MLX5_RECV_BUF_SIZE; - struct sockaddr_nl local = { - .nl_family = AF_NETLINK, - }; - int ret; - - fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); - if (fd == -1) { - rte_errno = errno; - return -rte_errno; - } - ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, sizeof(int)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, sizeof(int)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - ret = bind(fd, (struct sockaddr *)&local, sizeof(local)); - if (ret == -1) { - rte_errno = errno; - goto error; - } - return fd; -error: - close(fd); - return -rte_errno; -} - -/** - * Send a request message to the kernel on the Netlink socket. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] nh - * The Netlink message send to the kernel. - * @param[in] ssn - * Sequence number. - * @param[in] req - * Pointer to the request structure. - * @param[in] len - * Length of the request in bytes. - * - * @return - * The number of sent bytes on success, a negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_nl_request(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn, void *req, - int len) -{ - struct sockaddr_nl sa = { - .nl_family = AF_NETLINK, - }; - struct iovec iov[2] = { - { .iov_base = nh, .iov_len = sizeof(*nh), }, - { .iov_base = req, .iov_len = len, }, - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = iov, - .msg_iovlen = 2, - }; - int send_bytes; - - nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ - nh->nlmsg_seq = sn; - send_bytes = sendmsg(nlsk_fd, &msg, 0); - if (send_bytes < 0) { - rte_errno = errno; - return -rte_errno; - } - return send_bytes; -} - -/** - * Send a message to the kernel on the Netlink socket. - * - * @param[in] nlsk_fd - * The Netlink socket file descriptor used for communication. - * @param[in] nh - * The Netlink message send to the kernel. - * @param[in] sn - * Sequence number. - * - * @return - * The number of sent bytes on success, a negative errno value otherwise and - * rte_errno is set. - */ -static int -mlx5_nl_send(int nlsk_fd, struct nlmsghdr *nh, uint32_t sn) -{ - struct sockaddr_nl sa = { - .nl_family = AF_NETLINK, - }; - struct iovec iov = { - .iov_base = nh, - .iov_len = nh->nlmsg_len, - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - int send_bytes; - - nh->nlmsg_pid = 0; /* communication with the kernel uses pid 0 */ - nh->nlmsg_seq = sn; - send_bytes = sendmsg(nlsk_fd, &msg, 0); - if (send_bytes < 0) { - rte_errno = errno; - return -rte_errno; - } - return send_bytes; -} - -/** - * Receive a message from the kernel on the Netlink socket, following - * mlx5_nl_send(). - * - * @param[in] nlsk_fd - * The Netlink socket file descriptor used for communication. - * @param[in] sn - * Sequence number. - * @param[in] cb - * The callback function to call for each Netlink message received. - * @param[in, out] arg - * Custom arguments for the callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_recv(int nlsk_fd, uint32_t sn, int (*cb)(struct nlmsghdr *, void *arg), - void *arg) -{ - struct sockaddr_nl sa; - char buf[MLX5_RECV_BUF_SIZE]; - struct iovec iov = { - .iov_base = buf, - .iov_len = sizeof(buf), - }; - struct msghdr msg = { - .msg_name = &sa, - .msg_namelen = sizeof(sa), - .msg_iov = &iov, - /* One message at a time */ - .msg_iovlen = 1, - }; - int multipart = 0; - int ret = 0; - - do { - struct nlmsghdr *nh; - int recv_bytes = 0; - - do { - recv_bytes = recvmsg(nlsk_fd, &msg, 0); - if (recv_bytes == -1) { - rte_errno = errno; - return -rte_errno; - } - nh = (struct nlmsghdr *)buf; - } while (nh->nlmsg_seq != sn); - for (; - NLMSG_OK(nh, (unsigned int)recv_bytes); - nh = NLMSG_NEXT(nh, recv_bytes)) { - if (nh->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err_data = NLMSG_DATA(nh); - - if (err_data->error < 0) { - rte_errno = -err_data->error; - return -rte_errno; - } - /* Ack message. */ - return 0; - } - /* Multi-part msgs and their trailing DONE message. */ - if (nh->nlmsg_flags & NLM_F_MULTI) { - if (nh->nlmsg_type == NLMSG_DONE) - return 0; - multipart = 1; - } - if (cb) { - ret = cb(nh, arg); - if (ret < 0) - return ret; - } - } - } while (multipart); - return ret; -} - -/** - * Parse Netlink message to retrieve the bridge MAC address. - * - * @param nh - * Pointer to Netlink Message Header. - * @param arg - * PMD data register with this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_nl_mac_addr *data = arg; - struct ndmsg *r = NLMSG_DATA(nh); - struct rtattr *attribute; - int len; - - len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); - for (attribute = MLX5_NDA_RTA(r); - RTA_OK(attribute, len); - attribute = RTA_NEXT(attribute, len)) { - if (attribute->rta_type == NDA_LLADDR) { - if (data->mac_n == MLX5_MAX_MAC_ADDRESSES) { - DRV_LOG(WARNING, - "not enough room to finalize the" - " request"); - rte_errno = ENOMEM; - return -rte_errno; - } -#ifndef NDEBUG - char m[18]; - - rte_ether_format_addr(m, 18, RTA_DATA(attribute)); - DRV_LOG(DEBUG, "bridge MAC address %s", m); -#endif - memcpy(&(*data->mac)[data->mac_n++], - RTA_DATA(attribute), RTE_ETHER_ADDR_LEN); - } - } - return 0; -} - -/** - * Get bridge MAC addresses. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac[out] - * Pointer to the array table of MAC addresses to fill. - * Its size should be of MLX5_MAX_MAC_ADDRESSES. - * @param mac_n[out] - * Number of entries filled in MAC array. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_list(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr (*mac)[], int *mac_n) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifm; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_GETNEIGH, - .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST, - }, - .ifm = { - .ifi_family = PF_BRIDGE, - .ifi_index = iface_idx, - }, - }; - struct mlx5_nl_mac_addr data = { - .mac = mac, - .mac_n = 0, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - if (nlsk_fd == -1) - return 0; - ret = mlx5_nl_request(nlsk_fd, &req.hdr, sn, &req.ifm, - sizeof(struct ifinfomsg)); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_mac_addr_cb, &data); - if (ret < 0) - goto error; - *mac_n = data.mac_n; - return 0; -error: - DRV_LOG(DEBUG, "Interface %u cannot retrieve MAC address list %s", - iface_idx, strerror(rte_errno)); - return -rte_errno; -} - -/** - * Modify the MAC address neighbour table with Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac - * MAC address to consider. - * @param add - * 1 to add the MAC address, 0 to remove the MAC address. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int add) -{ - struct { - struct nlmsghdr hdr; - struct ndmsg ndm; - struct rtattr rta; - uint8_t buffer[RTE_ETHER_ADDR_LEN]; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_EXCL | NLM_F_ACK, - .nlmsg_type = add ? RTM_NEWNEIGH : RTM_DELNEIGH, - }, - .ndm = { - .ndm_family = PF_BRIDGE, - .ndm_state = NUD_NOARP | NUD_PERMANENT, - .ndm_ifindex = iface_idx, - .ndm_flags = NTF_SELF, - }, - .rta = { - .rta_type = NDA_LLADDR, - .rta_len = RTA_LENGTH(RTE_ETHER_ADDR_LEN), - }, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - if (nlsk_fd == -1) - return 0; - memcpy(RTA_DATA(&req.rta), mac, RTE_ETHER_ADDR_LEN); - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_ALIGN(req.rta.rta_len); - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) - goto error; - return 0; -error: - DRV_LOG(DEBUG, - "Interface %u cannot %s MAC address" - " %02X:%02X:%02X:%02X:%02X:%02X %s", - iface_idx, - add ? "add" : "remove", - mac->addr_bytes[0], mac->addr_bytes[1], - mac->addr_bytes[2], mac->addr_bytes[3], - mac->addr_bytes[4], mac->addr_bytes[5], - strerror(rte_errno)); - return -rte_errno; -} - -/** - * Modify the VF MAC address neighbour table with Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac - * MAC address to consider. - * @param vf_index - * VF index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int vf_index) -{ - int ret; - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifm; - struct rtattr vf_list_rta; - struct rtattr vf_info_rta; - struct rtattr vf_mac_rta; - struct ifla_vf_mac ivm; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - .nlmsg_type = RTM_BASE, - }, - .ifm = { - .ifi_index = iface_idx, - }, - .vf_list_rta = { - .rta_type = IFLA_VFINFO_LIST, - .rta_len = RTA_ALIGN(RTA_LENGTH(0)), - }, - .vf_info_rta = { - .rta_type = IFLA_VF_INFO, - .rta_len = RTA_ALIGN(RTA_LENGTH(0)), - }, - .vf_mac_rta = { - .rta_type = IFLA_VF_MAC, - }, - }; - struct ifla_vf_mac ivm = { - .vf = vf_index, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - - memcpy(&ivm.mac, mac, RTE_ETHER_ADDR_LEN); - memcpy(RTA_DATA(&req.vf_mac_rta), &ivm, sizeof(ivm)); - - req.vf_mac_rta.rta_len = RTA_LENGTH(sizeof(ivm)); - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_ALIGN(req.vf_list_rta.rta_len) + - RTA_ALIGN(req.vf_info_rta.rta_len) + - RTA_ALIGN(req.vf_mac_rta.rta_len); - req.vf_list_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), - &req.vf_list_rta); - req.vf_info_rta.rta_len = RTE_PTR_DIFF(NLMSG_TAIL(&req.hdr), - &req.vf_info_rta); - - if (nlsk_fd < 0) - return -1; - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - goto error; - ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); - if (ret < 0) - goto error; - return 0; -error: - DRV_LOG(ERR, - "representor %u cannot set VF MAC address " - "%02X:%02X:%02X:%02X:%02X:%02X : %s", - vf_index, - mac->addr_bytes[0], mac->addr_bytes[1], - mac->addr_bytes[2], mac->addr_bytes[3], - mac->addr_bytes[4], mac->addr_bytes[5], - strerror(rte_errno)); - return -rte_errno; -} - -/** - * Add a MAC address. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - * @param mac - * MAC address to register. - * @param index - * MAC address index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, - uint64_t *mac_own, struct rte_ether_addr *mac, - uint32_t index) -{ - int ret; - - ret = mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 1); - if (!ret) - BITFIELD_SET(mac_own, index); - if (ret == -EEXIST) - return 0; - return ret; -} - -/** - * Remove a MAC address. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - * @param mac - * MAC address to remove. - * @param index - * MAC address index. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, - struct rte_ether_addr *mac, uint32_t index) -{ - BITFIELD_RESET(mac_own, index); - return mlx5_nl_mac_addr_modify(nlsk_fd, iface_idx, mac, 0); -} - -/** - * Synchronize Netlink bridge table to the internal table. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param mac_addrs - * Mac addresses array to sync. - * @param n - * @p mac_addrs array size. - */ -void -mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n) -{ - struct rte_ether_addr macs[n]; - int macs_n = 0; - int i; - int ret; - - ret = mlx5_nl_mac_addr_list(nlsk_fd, iface_idx, &macs, &macs_n); - if (ret) - return; - for (i = 0; i != macs_n; ++i) { - int j; - - /* Verify the address is not in the array yet. */ - for (j = 0; j != n; ++j) - if (rte_is_same_ether_addr(&macs[i], &mac_addrs[j])) - break; - if (j != n) - continue; - /* Find the first entry available. */ - for (j = 0; j != n; ++j) { - if (rte_is_zero_ether_addr(&mac_addrs[j])) { - mac_addrs[j] = macs[i]; - break; - } - } - } -} - -/** - * Flush all added MAC addresses. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param[in] mac_addrs - * Mac addresses array to flush. - * @param n - * @p mac_addrs array size. - * @param mac_own - * BITFIELD_DECLARE array to store the mac. - */ -void -mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n, - uint64_t *mac_own) -{ - int i; - - for (i = n - 1; i >= 0; --i) { - struct rte_ether_addr *m = &mac_addrs[i]; - - if (BITFIELD_ISSET(mac_own, i)) - mlx5_nl_mac_addr_remove(nlsk_fd, iface_idx, mac_own, m, - i); - } -} - -/** - * Enable promiscuous / all multicast mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param flags - * IFF_PROMISC for promiscuous, IFF_ALLMULTI for allmulti. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_device_flags(int nlsk_fd, unsigned int iface_idx, uint32_t flags, - int enable) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifi; - } req = { - .hdr = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_NEWLINK, - .nlmsg_flags = NLM_F_REQUEST, - }, - .ifi = { - .ifi_flags = enable ? flags : 0, - .ifi_change = flags, - .ifi_index = iface_idx, - }, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - assert(!(flags & ~(IFF_PROMISC | IFF_ALLMULTI))); - if (nlsk_fd < 0) - return 0; - ret = mlx5_nl_send(nlsk_fd, &req.hdr, sn); - if (ret < 0) - return ret; - return 0; -} - -/** - * Enable promiscuous mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable) -{ - int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_PROMISC, enable); - - if (ret) - DRV_LOG(DEBUG, - "Interface %u cannot %s promisc mode: Netlink error %s", - iface_idx, enable ? "enable" : "disable", - strerror(rte_errno)); - return ret; -} - -/** - * Enable all multicast mode through Netlink. - * - * @param[in] nlsk_fd - * Netlink socket file descriptor. - * @param[in] iface_idx - * Net device interface index. - * @param enable - * Nonzero to enable, disable otherwise. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -int -mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable) -{ - int ret = mlx5_nl_device_flags(nlsk_fd, iface_idx, IFF_ALLMULTI, - enable); - - if (ret) - DRV_LOG(DEBUG, - "Interface %u cannot %s allmulti : Netlink error %s", - iface_idx, enable ? "enable" : "disable", - strerror(rte_errno)); - return ret; -} - -/** - * Process network interface information from Netlink message. - * - * @param nh - * Pointer to Netlink message header. - * @param arg - * Opaque data pointer for this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_cmdget_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_nl_ifindex_data *data = arg; - struct mlx5_nl_ifindex_data local = { - .flags = 0, - }; - size_t off = NLMSG_HDRLEN; - - if (nh->nlmsg_type != - RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_GET) && - nh->nlmsg_type != - RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_PORT_GET)) - goto error; - while (off < nh->nlmsg_len) { - struct nlattr *na = (void *)((uintptr_t)nh + off); - void *payload = (void *)((uintptr_t)na + NLA_HDRLEN); - - if (na->nla_len > nh->nlmsg_len - off) - goto error; - switch (na->nla_type) { - case RDMA_NLDEV_ATTR_DEV_INDEX: - local.ibindex = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_IB_INDEX; - break; - case RDMA_NLDEV_ATTR_DEV_NAME: - if (!strcmp(payload, data->name)) - local.flags |= MLX5_NL_CMD_GET_IB_NAME; - break; - case RDMA_NLDEV_ATTR_NDEV_INDEX: - local.ifindex = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_NET_INDEX; - break; - case RDMA_NLDEV_ATTR_PORT_INDEX: - local.portnum = *(uint32_t *)payload; - local.flags |= MLX5_NL_CMD_GET_PORT_INDEX; - break; - default: - break; - } - off += NLA_ALIGN(na->nla_len); - } - /* - * It is possible to have multiple messages for all - * Infiniband devices in the system with appropriate name. - * So we should gather parameters locally and copy to - * query context only in case of coinciding device name. - */ - if (local.flags & MLX5_NL_CMD_GET_IB_NAME) { - data->flags = local.flags; - data->ibindex = local.ibindex; - data->ifindex = local.ifindex; - data->portnum = local.portnum; - } - return 0; -error: - rte_errno = EINVAL; - return -rte_errno; -} - -/** - * Get index of network interface associated with some IB device. - * - * This is the only somewhat safe method to avoid resorting to heuristics - * when faced with port representors. Unfortunately it requires at least - * Linux 4.17. - * - * @param nl - * Netlink socket of the RDMA kind (NETLINK_RDMA). - * @param[in] name - * IB device name. - * @param[in] pindex - * IB device port index, starting from 1 - * @return - * A valid (nonzero) interface index on success, 0 otherwise and rte_errno - * is set. - */ -unsigned int -mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex) -{ - struct mlx5_nl_ifindex_data data = { - .name = name, - .flags = 0, - .ibindex = 0, /* Determined during first pass. */ - .ifindex = 0, /* Determined during second pass. */ - }; - union { - struct nlmsghdr nh; - uint8_t buf[NLMSG_HDRLEN + - NLA_HDRLEN + NLA_ALIGN(sizeof(data.ibindex)) + - NLA_HDRLEN + NLA_ALIGN(sizeof(pindex))]; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH(0), - .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_GET), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, - }, - }; - struct nlattr *na; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX)) - goto error; - data.flags = 0; - sn = MLX5_NL_SN_GENERATE; - req.nh.nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_PORT_GET); - req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.buf) - NLMSG_HDRLEN); - na = (void *)((uintptr_t)req.buf + NLMSG_HDRLEN); - na->nla_len = NLA_HDRLEN + sizeof(data.ibindex); - na->nla_type = RDMA_NLDEV_ATTR_DEV_INDEX; - memcpy((void *)((uintptr_t)na + NLA_HDRLEN), - &data.ibindex, sizeof(data.ibindex)); - na = (void *)((uintptr_t)na + NLA_ALIGN(na->nla_len)); - na->nla_len = NLA_HDRLEN + sizeof(pindex); - na->nla_type = RDMA_NLDEV_ATTR_PORT_INDEX; - memcpy((void *)((uintptr_t)na + NLA_HDRLEN), - &pindex, sizeof(pindex)); - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || - !(data.flags & MLX5_NL_CMD_GET_NET_INDEX) || - !data.ifindex) - goto error; - return data.ifindex; -error: - rte_errno = ENODEV; - return 0; -} - -/** - * Get the number of physical ports of given IB device. - * - * @param nl - * Netlink socket of the RDMA kind (NETLINK_RDMA). - * @param[in] name - * IB device name. - * - * @return - * A valid (nonzero) number of ports on success, 0 otherwise - * and rte_errno is set. - */ -unsigned int -mlx5_nl_portnum(int nl, const char *name) -{ - struct mlx5_nl_ifindex_data data = { - .flags = 0, - .name = name, - .ifindex = 0, - .portnum = 0, - }; - struct nlmsghdr req = { - .nlmsg_len = NLMSG_LENGTH(0), - .nlmsg_type = RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, - RDMA_NLDEV_CMD_GET), - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req, sn); - if (ret < 0) - return 0; - ret = mlx5_nl_recv(nl, sn, mlx5_nl_cmdget_cb, &data); - if (ret < 0) - return 0; - if (!(data.flags & MLX5_NL_CMD_GET_IB_NAME) || - !(data.flags & MLX5_NL_CMD_GET_IB_INDEX) || - !(data.flags & MLX5_NL_CMD_GET_PORT_INDEX)) { - rte_errno = ENODEV; - return 0; - } - if (!data.portnum) - rte_errno = EINVAL; - return data.portnum; -} - -/** - * Analyze gathered port parameters via Netlink to recognize master - * and representor devices for E-Switch configuration. - * - * @param[in] num_vf_set - * flag of presence of number of VFs port attribute. - * @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). - */ -static void -mlx5_nl_check_switch_info(bool num_vf_set, - 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 number of VFs key presence. - */ - switch_info->master = num_vf_set; - 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 - * number of VFs key. - */ - switch_info->master = num_vf_set; - 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 = !num_vf_set; - break; - case MLX5_PHYS_PORT_NAME_TYPE_PFVF: - /* New representors naming schema. */ - switch_info->representor = 1; - break; - } -} - -/** - * Process switch information from Netlink message. - * - * @param nh - * Pointer to Netlink message header. - * @param arg - * Opaque data pointer for this callback. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg) -{ - struct mlx5_switch_info info = { - .master = 0, - .representor = 0, - .name_type = MLX5_PHYS_PORT_NAME_TYPE_NOTSET, - .port_name = 0, - .switch_id = 0, - }; - size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - bool switch_id_set = false; - bool num_vf_set = false; - - if (nh->nlmsg_type != RTM_NEWLINK) - goto error; - while (off < nh->nlmsg_len) { - struct rtattr *ra = (void *)((uintptr_t)nh + off); - void *payload = RTA_DATA(ra); - unsigned int i; - - if (ra->rta_len > nh->nlmsg_len - off) - goto error; - switch (ra->rta_type) { - case IFLA_NUM_VF: - num_vf_set = true; - break; - case IFLA_PHYS_PORT_NAME: - mlx5_translate_port_name((char *)payload, &info); - break; - case IFLA_PHYS_SWITCH_ID: - info.switch_id = 0; - for (i = 0; i < RTA_PAYLOAD(ra); ++i) { - info.switch_id <<= 8; - info.switch_id |= ((uint8_t *)payload)[i]; - } - switch_id_set = true; - break; - } - off += RTA_ALIGN(ra->rta_len); - } - if (switch_id_set) { - /* We have some E-Switch configuration. */ - mlx5_nl_check_switch_info(num_vf_set, &info); - } - assert(!(info.master && info.representor)); - memcpy(arg, &info, sizeof(info)); - return 0; -error: - rte_errno = EINVAL; - return -rte_errno; -} - -/** - * Get switch information associated with network interface. - * - * @param nl - * Netlink socket of the ROUTE kind (NETLINK_ROUTE). - * @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_nl_switch_info(int nl, unsigned int ifindex, - struct mlx5_switch_info *info) -{ - struct { - struct nlmsghdr nh; - struct ifinfomsg info; - struct rtattr rta; - uint32_t extmask; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH - (sizeof(req.info) + - RTA_LENGTH(sizeof(uint32_t))), - .nlmsg_type = RTM_GETLINK, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - }, - .info = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex, - }, - .rta = { - .rta_type = IFLA_EXT_MASK, - .rta_len = RTA_LENGTH(sizeof(int32_t)), - }, - .extmask = RTE_LE32(1), - }; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - ret = mlx5_nl_send(nl, &req.nh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(nl, sn, mlx5_nl_switch_info_cb, info); - if (info->master && info->representor) { - DRV_LOG(ERR, "ifindex %u device is recognized as master" - " and as representor", ifindex); - rte_errno = ENODEV; - ret = -rte_errno; - } - return ret; -} - -/* - * Delete VLAN network device by ifindex. - * - * @param[in] tcf - * Context object initialized by mlx5_nl_vlan_vmwa_init(). - * @param[in] ifindex - * Interface index of network device to delete. - */ -void -mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex) -{ - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - struct { - struct nlmsghdr nh; - struct ifinfomsg info; - } req = { - .nh = { - .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), - .nlmsg_type = RTM_DELLINK, - .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, - }, - .info = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex, - }, - }; - - if (ifindex) { - ret = mlx5_nl_send(vmwa->nl_socket, &req.nh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); - if (ret < 0) - DRV_LOG(WARNING, "netlink: error deleting VLAN WA" - " ifindex %u, %d", ifindex, ret); - } -} - -/* Set of subroutines to build Netlink message. */ -static struct nlattr * -nl_msg_tail(struct nlmsghdr *nlh) -{ - return (struct nlattr *) - (((uint8_t *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len)); -} - -static void -nl_attr_put(struct nlmsghdr *nlh, int type, const void *data, int alen) -{ - struct nlattr *nla = nl_msg_tail(nlh); - - nla->nla_type = type; - nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr) + alen); - nlh->nlmsg_len = NLMSG_ALIGN(nlh->nlmsg_len) + nla->nla_len; - - if (alen) - memcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen); -} - -static struct nlattr * -nl_attr_nest_start(struct nlmsghdr *nlh, int type) -{ - struct nlattr *nest = (struct nlattr *)nl_msg_tail(nlh); - - nl_attr_put(nlh, type, NULL, 0); - return nest; -} - -static void -nl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *nest) -{ - nest->nla_len = (uint8_t *)nl_msg_tail(nlh) - (uint8_t *)nest; -} - -/* - * Create network VLAN device with specified VLAN tag. - * - * @param[in] tcf - * Context object initialized by mlx5_nl_vlan_vmwa_init(). - * @param[in] ifindex - * Base network interface index. - * @param[in] tag - * VLAN tag for VLAN network device to create. - */ -uint32_t -mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex, uint16_t tag) -{ - struct nlmsghdr *nlh; - struct ifinfomsg *ifm; - char name[sizeof(MLX5_VMWA_VLAN_DEVICE_PFX) + 32]; - - alignas(RTE_CACHE_LINE_SIZE) - uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct ifinfomsg)) + - NLMSG_ALIGN(sizeof(struct nlattr)) * 8 + - NLMSG_ALIGN(sizeof(uint32_t)) + - NLMSG_ALIGN(sizeof(name)) + - NLMSG_ALIGN(sizeof("vlan")) + - NLMSG_ALIGN(sizeof(uint32_t)) + - NLMSG_ALIGN(sizeof(uint16_t)) + 16]; - struct nlattr *na_info; - struct nlattr *na_vlan; - uint32_t sn = MLX5_NL_SN_GENERATE; - int ret; - - memset(buf, 0, sizeof(buf)); - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_len = sizeof(struct nlmsghdr); - nlh->nlmsg_type = RTM_NEWLINK; - nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | - NLM_F_EXCL | NLM_F_ACK; - ifm = (struct ifinfomsg *)nl_msg_tail(nlh); - nlh->nlmsg_len += sizeof(struct ifinfomsg); - ifm->ifi_family = AF_UNSPEC; - ifm->ifi_type = 0; - ifm->ifi_index = 0; - ifm->ifi_flags = IFF_UP; - ifm->ifi_change = 0xffffffff; - nl_attr_put(nlh, IFLA_LINK, &ifindex, sizeof(ifindex)); - ret = snprintf(name, sizeof(name), "%s.%u.%u", - MLX5_VMWA_VLAN_DEVICE_PFX, ifindex, tag); - nl_attr_put(nlh, IFLA_IFNAME, name, ret + 1); - na_info = nl_attr_nest_start(nlh, IFLA_LINKINFO); - nl_attr_put(nlh, IFLA_INFO_KIND, "vlan", sizeof("vlan")); - na_vlan = nl_attr_nest_start(nlh, IFLA_INFO_DATA); - nl_attr_put(nlh, IFLA_VLAN_ID, &tag, sizeof(tag)); - nl_attr_nest_end(nlh, na_vlan); - nl_attr_nest_end(nlh, na_info); - assert(sizeof(buf) >= nlh->nlmsg_len); - ret = mlx5_nl_send(vmwa->nl_socket, nlh, sn); - if (ret >= 0) - ret = mlx5_nl_recv(vmwa->nl_socket, sn, NULL, NULL); - if (ret < 0) { - DRV_LOG(WARNING, "netlink: VLAN %s create failure (%d)", name, - ret); - } - // Try to get ifindex of created or pre-existing device. - ret = if_nametoindex(name); - if (!ret) { - DRV_LOG(WARNING, "VLAN %s failed to get index (%d)", name, - errno); - return 0; - } - return ret; -} diff --git a/drivers/net/mlx5/mlx5_nl.h b/drivers/net/mlx5/mlx5_nl.h deleted file mode 100644 index 9be87c0..0000000 --- a/drivers/net/mlx5/mlx5_nl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2019 Mellanox Technologies, Ltd - */ - -#ifndef RTE_PMD_MLX5_NL_H_ -#define RTE_PMD_MLX5_NL_H_ - -#include - - -/* Recognized Infiniband device physical port name types. */ -enum mlx5_nl_phys_port_name_type { - MLX5_PHYS_PORT_NAME_TYPE_NOTSET = 0, /* Not set. */ - MLX5_PHYS_PORT_NAME_TYPE_LEGACY, /* before kernel ver < 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_UPLINK, /* p0, kernel ver >= 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */ - MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */ -}; - -/** Switch information returned by mlx5_nl_switch_info(). */ -struct mlx5_switch_info { - uint32_t master:1; /**< Master device. */ - uint32_t representor:1; /**< Representor device. */ - enum mlx5_nl_phys_port_name_type name_type; /** < Port name type. */ - int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ - int32_t port_name; /**< Representor port name. */ - uint64_t switch_id; /**< Switch identifier. */ -}; - -/* VLAN netdev for VLAN workaround. */ -struct mlx5_nl_vlan_dev { - uint32_t refcnt; - uint32_t ifindex; /**< Own interface index. */ -}; - -/* - * Array of VLAN devices created on the base of VF - * used for workaround in virtual environments. - */ -struct mlx5_nl_vlan_vmwa_context { - int nl_socket; - uint32_t vf_ifindex; - struct mlx5_nl_vlan_dev vlan_dev[4096]; -}; - - -int mlx5_nl_init(int protocol); -int mlx5_nl_mac_addr_add(int nlsk_fd, unsigned int iface_idx, uint64_t *mac_own, - struct rte_ether_addr *mac, uint32_t index); -int mlx5_nl_mac_addr_remove(int nlsk_fd, unsigned int iface_idx, - uint64_t *mac_own, struct rte_ether_addr *mac, - uint32_t index); -void mlx5_nl_mac_addr_sync(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n); -void mlx5_nl_mac_addr_flush(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac_addrs, int n, - uint64_t *mac_own); -int mlx5_nl_promisc(int nlsk_fd, unsigned int iface_idx, int enable); -int mlx5_nl_allmulti(int nlsk_fd, unsigned int iface_idx, int enable); -unsigned int mlx5_nl_portnum(int nl, const char *name); -unsigned int mlx5_nl_ifindex(int nl, const char *name, uint32_t pindex); -int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx, - struct rte_ether_addr *mac, int vf_index); -int mlx5_nl_switch_info(int nl, unsigned int ifindex, - struct mlx5_switch_info *info); - -void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex); -uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, - uint32_t ifindex, uint16_t tag); - -#endif /* RTE_PMD_MLX5_NL_H_ */ diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c index fc1a91c..8e63b67 100644 --- a/drivers/net/mlx5/mlx5_vlan.c +++ b/drivers/net/mlx5/mlx5_vlan.c @@ -33,11 +33,11 @@ #include #include +#include #include "mlx5.h" #include "mlx5_autoconf.h" #include "mlx5_rxtx.h" -#include "mlx5_nl.h" #include "mlx5_utils.h" /** From patchwork Wed Jan 29 12:38:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matan Azrad X-Patchwork-Id: 65330 X-Patchwork-Delegate: rasland@nvidia.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id CD8AAA052F; Wed, 29 Jan 2020 13:43:20 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C60E11C0D1; Wed, 29 Jan 2020 13:39:56 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 9AD8B1C032 for ; Wed, 29 Jan 2020 13:39:35 +0100 (CET) Received: from Internal Mail-Server by MTLPINE2 (envelope-from asafp@mellanox.com) with ESMTPS (AES256-SHA encrypted); 29 Jan 2020 14:39:32 +0200 Received: from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx [10.210.16.112]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00TCcs1x018914; Wed, 29 Jan 2020 14:39:32 +0200 From: Matan Azrad To: dev@dpdk.org, Viacheslav Ovsiienko Cc: Raslan Darawsheh Date: Wed, 29 Jan 2020 12:38:50 +0000 Message-Id: <1580301530-6643-26-git-send-email-matan@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1580301530-6643-1-git-send-email-matan@mellanox.com> References: <1580228860-10665-1-git-send-email-matan@mellanox.com> <1580301530-6643-1-git-send-email-matan@mellanox.com> Subject: [dpdk-dev] [PATCH v4 25/25] common/mlx5: support ROCE disable through Netlink X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add new 4 Netlink commands to support enable/disable ROCE: 1. mlx5_nl_devlink_family_id_get to get the Devlink family ID of Netlink general command. 2. mlx5_nl_enable_roce_get to get the ROCE current status. 3. mlx5_nl_driver_reload - to reload the device kernel driver. 4. mlx5_nl_enable_roce_set - to set the ROCE status. When the user changes the ROCE status, the IB device may disappear and appear again, so DPDK driver should wait for it and to restart itself. Signed-off-by: Matan Azrad Acked-by: Viacheslav Ovsiienko --- drivers/common/mlx5/Makefile | 5 + drivers/common/mlx5/meson.build | 1 + drivers/common/mlx5/mlx5_nl.c | 366 +++++++++++++++++++++++- drivers/common/mlx5/mlx5_nl.h | 6 + drivers/common/mlx5/rte_common_mlx5_version.map | 4 + 5 files changed, 380 insertions(+), 2 deletions(-) diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile index 6a14b7d..9d4d81f 100644 --- a/drivers/common/mlx5/Makefile +++ b/drivers/common/mlx5/Makefile @@ -260,6 +260,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh enum IFLA_PHYS_PORT_NAME \ $(AUTOCONF_OUTPUT) $Q sh -- '$<' '$@' \ + HAVE_DEVLINK \ + linux/devlink.h \ + define DEVLINK_GENL_NAME \ + $(AUTOCONF_OUTPUT) + $Q sh -- '$<' '$@' \ HAVE_SUPPORTED_40000baseKR4_Full \ /usr/include/linux/ethtool.h \ define SUPPORTED_40000baseKR4_Full \ diff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build index 34cb7b9..fdd1e85 100644 --- a/drivers/common/mlx5/meson.build +++ b/drivers/common/mlx5/meson.build @@ -168,6 +168,7 @@ if build 'RDMA_NLDEV_ATTR_NDEV_INDEX' ], [ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h', 'mlx5dv_dump_dr_domain'], + [ 'HAVE_DEVLINK', 'linux/devlink.h', 'DEVLINK_GENL_NAME' ], ] config = configuration_data() foreach arg:has_sym_args diff --git a/drivers/common/mlx5/mlx5_nl.c b/drivers/common/mlx5/mlx5_nl.c index b4fc053..0d1efd2 100644 --- a/drivers/common/mlx5/mlx5_nl.c +++ b/drivers/common/mlx5/mlx5_nl.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,10 @@ #include "mlx5_nl.h" #include "mlx5_common_utils.h" +#ifdef HAVE_DEVLINK +#include +#endif + /* Size of the buffer to receive kernel messages */ #define MLX5_NL_BUF_SIZE (32 * 1024) @@ -90,6 +95,59 @@ #define IFLA_PHYS_PORT_NAME 38 #endif +/* + * Some Devlink defines may be missed in old kernel versions, + * adjust used defines. + */ +#ifndef DEVLINK_GENL_NAME +#define DEVLINK_GENL_NAME "devlink" +#endif +#ifndef DEVLINK_GENL_VERSION +#define DEVLINK_GENL_VERSION 1 +#endif +#ifndef DEVLINK_ATTR_BUS_NAME +#define DEVLINK_ATTR_BUS_NAME 1 +#endif +#ifndef DEVLINK_ATTR_DEV_NAME +#define DEVLINK_ATTR_DEV_NAME 2 +#endif +#ifndef DEVLINK_ATTR_PARAM +#define DEVLINK_ATTR_PARAM 80 +#endif +#ifndef DEVLINK_ATTR_PARAM_NAME +#define DEVLINK_ATTR_PARAM_NAME 81 +#endif +#ifndef DEVLINK_ATTR_PARAM_TYPE +#define DEVLINK_ATTR_PARAM_TYPE 83 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUES_LIST +#define DEVLINK_ATTR_PARAM_VALUES_LIST 84 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE +#define DEVLINK_ATTR_PARAM_VALUE 85 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE_DATA +#define DEVLINK_ATTR_PARAM_VALUE_DATA 86 +#endif +#ifndef DEVLINK_ATTR_PARAM_VALUE_CMODE +#define DEVLINK_ATTR_PARAM_VALUE_CMODE 87 +#endif +#ifndef DEVLINK_PARAM_CMODE_DRIVERINIT +#define DEVLINK_PARAM_CMODE_DRIVERINIT 1 +#endif +#ifndef DEVLINK_CMD_RELOAD +#define DEVLINK_CMD_RELOAD 37 +#endif +#ifndef DEVLINK_CMD_PARAM_GET +#define DEVLINK_CMD_PARAM_GET 38 +#endif +#ifndef DEVLINK_CMD_PARAM_SET +#define DEVLINK_CMD_PARAM_SET 39 +#endif +#ifndef NLA_FLAG +#define NLA_FLAG 6 +#endif + /* Add/remove MAC address through Netlink */ struct mlx5_nl_mac_addr { struct rte_ether_addr (*mac)[]; @@ -1241,8 +1299,8 @@ struct mlx5_nl_ifindex_data { struct nlattr *nla = nl_msg_tail(nlh); nla->nla_type = type; - nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr) + alen); - nlh->nlmsg_len = NLMSG_ALIGN(nlh->nlmsg_len) + nla->nla_len; + nla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr)) + alen; + nlh->nlmsg_len += NLMSG_ALIGN(nla->nla_len); if (alen) memcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen); @@ -1335,3 +1393,307 @@ struct mlx5_nl_ifindex_data { } return ret; } + +/** + * Parse Netlink message to retrieve the general family ID. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_family_id_cb(struct nlmsghdr *nh, void *arg) +{ + + struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); + struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr))); + + for (; nla->nla_len && nla < tail; + nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len))) { + if (nla->nla_type == CTRL_ATTR_FAMILY_ID) { + *(uint16_t *)arg = *(uint16_t *)(nla + 1); + return 0; + } + } + return -EINVAL; +} + +#define MLX5_NL_MAX_ATTR_SIZE 100 +/** + * Get generic netlink family ID. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] name + * The family name. + * + * @return + * ID >= 0 on success and @p enable is updated, a negative errno value + * otherwise and rte_errno is set. + */ +static int +mlx5_nl_generic_family_id_get(int nlsk_fd, const char *name) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int name_size = strlen(name) + 1; + int ret; + uint16_t id = -1; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE)]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = GENL_ID_CTRL; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = CTRL_CMD_GETFAMILY; + genl->version = 1; + nl_attr_put(nlh, CTRL_ATTR_FAMILY_NAME, name, name_size); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_family_id_cb, &id); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to get Netlink %s family ID: %d.", name, + ret); + return ret; + } + DRV_LOG(DEBUG, "Netlink \"%s\" family ID is %u.", name, id); + return (int)id; +} + +/** + * Get Devlink family ID. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * + * @return + * ID >= 0 on success and @p enable is updated, a negative errno value + * otherwise and rte_errno is set. + */ + +int +mlx5_nl_devlink_family_id_get(int nlsk_fd) +{ + return mlx5_nl_generic_family_id_get(nlsk_fd, DEVLINK_GENL_NAME); +} + +/** + * Parse Netlink message to retrieve the ROCE enable status. + * + * @param nh + * Pointer to Netlink Message Header. + * @param arg + * PMD data register with this callback. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +mlx5_nl_roce_cb(struct nlmsghdr *nh, void *arg) +{ + + int ret = -EINVAL; + int *enable = arg; + struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); + struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr))); + + while (nla->nla_len && nla < tail) { + switch (nla->nla_type) { + /* Expected nested attributes case. */ + case DEVLINK_ATTR_PARAM: + case DEVLINK_ATTR_PARAM_VALUES_LIST: + case DEVLINK_ATTR_PARAM_VALUE: + ret = 0; + nla += 1; + break; + case DEVLINK_ATTR_PARAM_VALUE_DATA: + *enable = 1; + return 0; + default: + nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len)); + } + } + *enable = 0; + return ret; +} + +/** + * Get ROCE enable status through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * Where to store the enable status. + * + * @return + * 0 on success and @p enable is updated, a negative errno value otherwise + * and rte_errno is set. + */ +int +mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, + int *enable) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + int cur_en; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 4 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 4]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_PARAM_GET; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_roce_cb, &cur_en); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to get ROCE enable on device %s: %d.", + pci_addr, ret); + return ret; + } + *enable = cur_en; + DRV_LOG(DEBUG, "ROCE is %sabled for device \"%s\".", + cur_en ? "en" : "dis", pci_addr); + return ret; +} + +/** + * Reload mlx5 device kernel driver through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * The enable status to set. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 2 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 2]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_RELOAD; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to reload %s device by Netlink - %d", + pci_addr, ret); + return ret; + } + DRV_LOG(DEBUG, "Device \"%s\" was reloaded by Netlink successfully.", + pci_addr); + return 0; +} + +/** + * Set ROCE enable status through Netlink. + * + * @param[in] nlsk_fd + * Netlink socket file descriptor. + * @param[in] family_id + * the Devlink family ID. + * @param pci_addr + * The device PCI address. + * @param[out] enable + * The enable status to set. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, + int enable) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 6 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 6]; + uint8_t cmode = DEVLINK_PARAM_CMODE_DRIVERINIT; + uint8_t ptype = NLA_FLAG; +; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_PARAM_SET; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, "enable_roce", 12); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, &cmode, sizeof(cmode)); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_TYPE, &ptype, sizeof(ptype)); + if (enable) + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, NULL, 0); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to %sable ROCE for device %s by Netlink:" + " %d.", enable ? "en" : "dis", pci_addr, ret); + return ret; + } + DRV_LOG(DEBUG, "Device %s ROCE was %sabled by Netlink successfully.", + pci_addr, enable ? "en" : "dis"); + /* Now, need to reload the driver. */ + return mlx5_nl_driver_reload(nlsk_fd, family_id, pci_addr); +} diff --git a/drivers/common/mlx5/mlx5_nl.h b/drivers/common/mlx5/mlx5_nl.h index 8e66a98..2c3f837 100644 --- a/drivers/common/mlx5/mlx5_nl.h +++ b/drivers/common/mlx5/mlx5_nl.h @@ -53,5 +53,11 @@ void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex); uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex, uint16_t tag); +int mlx5_nl_devlink_family_id_get(int nlsk_fd); +int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, + int *enable); +int mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr); +int mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr, + int enable); #endif /* RTE_PMD_MLX5_NL_H_ */ diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map index f93f5cb..b1a2014 100644 --- a/drivers/common/mlx5/rte_common_mlx5_version.map +++ b/drivers/common/mlx5/rte_common_mlx5_version.map @@ -30,6 +30,10 @@ DPDK_20.02 { mlx5_dev_to_pci_addr; mlx5_nl_allmulti; + mlx5_nl_devlink_family_id_get; + mlx5_nl_driver_reload; + mlx5_nl_enable_roce_get; + mlx5_nl_enable_roce_set; mlx5_nl_ifindex; mlx5_nl_init; mlx5_nl_mac_addr_add;