LCOV - code coverage report
Current view: top level - drivers/net/mlx5 - mlx5_tx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 191 0.0 %
Date: 2025-05-01 17:49:45 Functions: 0 8 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 154 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2021 6WIND S.A.
       3                 :            :  * Copyright 2021 Mellanox Technologies, Ltd
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <stdint.h>
       7                 :            : #include <string.h>
       8                 :            : #include <stdlib.h>
       9                 :            : 
      10                 :            : #include <eal_export.h>
      11                 :            : #include <rte_mbuf.h>
      12                 :            : #include <rte_mempool.h>
      13                 :            : #include <rte_prefetch.h>
      14                 :            : #include <rte_common.h>
      15                 :            : #include <rte_branch_prediction.h>
      16                 :            : #include <rte_ether.h>
      17                 :            : #include <rte_cycles.h>
      18                 :            : #include <rte_flow.h>
      19                 :            : 
      20                 :            : #include <mlx5_prm.h>
      21                 :            : #include <mlx5_common.h>
      22                 :            : 
      23                 :            : #include "mlx5_autoconf.h"
      24                 :            : #include "mlx5_defs.h"
      25                 :            : #include "mlx5.h"
      26                 :            : #include "mlx5_utils.h"
      27                 :            : #include "mlx5_rxtx.h"
      28                 :            : #include "mlx5_tx.h"
      29                 :            : 
      30                 :            : #define MLX5_TXOFF_INFO(func, olx) {mlx5_tx_burst_##func, olx},
      31                 :            : 
      32                 :            : /**
      33                 :            :  * Move QP from error state to running state and initialize indexes.
      34                 :            :  *
      35                 :            :  * @param txq_ctrl
      36                 :            :  *   Pointer to TX queue control structure.
      37                 :            :  *
      38                 :            :  * @return
      39                 :            :  *   0 on success, else -1.
      40                 :            :  */
      41                 :            : static int
      42                 :          0 : tx_recover_qp(struct mlx5_txq_ctrl *txq_ctrl)
      43                 :            : {
      44                 :          0 :         struct mlx5_mp_arg_queue_state_modify sm = {
      45                 :            :                         .is_wq = 0,
      46                 :          0 :                         .queue_id = txq_ctrl->txq.idx,
      47                 :            :         };
      48                 :            : 
      49         [ #  # ]:          0 :         if (mlx5_queue_state_modify(ETH_DEV(txq_ctrl->priv), &sm))
      50                 :            :                 return -1;
      51                 :          0 :         txq_ctrl->txq.wqe_ci = 0;
      52                 :          0 :         txq_ctrl->txq.wqe_pi = 0;
      53                 :          0 :         txq_ctrl->txq.elts_comp = 0;
      54                 :          0 :         return 0;
      55                 :            : }
      56                 :            : 
      57                 :            : /* Return 1 if the error CQE is signed otherwise, sign it and return 0. */
      58                 :            : static int
      59                 :            : check_err_cqe_seen(volatile struct mlx5_error_cqe *err_cqe)
      60                 :            : {
      61                 :            :         static const uint8_t magic[] = "seen";
      62                 :            :         int ret = 1;
      63                 :            :         unsigned int i;
      64                 :            : 
      65         [ #  # ]:          0 :         for (i = 0; i < sizeof(magic); ++i)
      66   [ #  #  #  # ]:          0 :                 if (!ret || err_cqe->rsvd1[i] != magic[i]) {
      67                 :            :                         ret = 0;
      68                 :          0 :                         err_cqe->rsvd1[i] = magic[i];
      69                 :            :                 }
      70                 :            :         return ret;
      71                 :            : }
      72                 :            : 
      73                 :            : /**
      74                 :            :  * Handle error CQE.
      75                 :            :  *
      76                 :            :  * @param txq
      77                 :            :  *   Pointer to TX queue structure.
      78                 :            :  * @param error_cqe
      79                 :            :  *   Pointer to the error CQE.
      80                 :            :  *
      81                 :            :  * @return
      82                 :            :  *   Negative value if queue recovery failed, otherwise
      83                 :            :  *   the error completion entry is handled successfully.
      84                 :            :  */
      85                 :            : static int
      86                 :          0 : mlx5_tx_error_cqe_handle(struct mlx5_txq_data *__rte_restrict txq,
      87                 :            :                          volatile struct mlx5_error_cqe *err_cqe)
      88                 :            : {
      89         [ #  # ]:          0 :         if (err_cqe->syndrome != MLX5_CQE_SYNDROME_WR_FLUSH_ERR) {
      90                 :          0 :                 const uint16_t wqe_m = ((1 << txq->wqe_n) - 1);
      91                 :            :                 struct mlx5_txq_ctrl *txq_ctrl =
      92                 :          0 :                                 container_of(txq, struct mlx5_txq_ctrl, txq);
      93                 :          0 :                 uint16_t new_wqe_pi = rte_be_to_cpu_16(err_cqe->wqe_counter);
      94                 :            :                 int seen = check_err_cqe_seen(err_cqe);
      95                 :            : 
      96         [ #  # ]:          0 :                 if (!seen && txq_ctrl->dump_file_n <
      97         [ #  # ]:          0 :                     txq_ctrl->priv->config.max_dump_files_num) {
      98                 :          0 :                         MKSTR(err_str, "Unexpected CQE error syndrome "
      99                 :            :                               "0x%02x CQN = %u SQN = %u wqe_counter = %u "
     100                 :            :                               "wq_ci = %u cq_ci = %u", err_cqe->syndrome,
     101                 :            :                               txq->cqe_s, txq->qp_num_8s >> 8,
     102                 :            :                               rte_be_to_cpu_16(err_cqe->wqe_counter),
     103                 :            :                               txq->wqe_ci, txq->cq_ci);
     104                 :          0 :                         MKSTR(name, "dpdk_mlx5_port_%u_txq_%u_index_%u_%u",
     105                 :            :                               PORT_ID(txq_ctrl->priv), txq->idx,
     106                 :            :                               txq_ctrl->dump_file_n, (uint32_t)rte_rdtsc());
     107                 :          0 :                         mlx5_dump_debug_information(name, NULL, err_str, 0);
     108                 :          0 :                         mlx5_dump_debug_information(name, "MLX5 Error CQ:",
     109                 :            :                                                     (const void *)((uintptr_t)
     110                 :          0 :                                                     txq->cqes),
     111                 :            :                                                     sizeof(struct mlx5_error_cqe) *
     112                 :          0 :                                                     (1 << txq->cqe_n));
     113                 :          0 :                         mlx5_dump_debug_information(name, "MLX5 Error SQ:",
     114                 :            :                                                     (const void *)((uintptr_t)
     115                 :          0 :                                                     txq->wqes),
     116                 :            :                                                     MLX5_WQE_SIZE *
     117                 :          0 :                                                     (1 << txq->wqe_n));
     118                 :          0 :                         txq_ctrl->dump_file_n++;
     119                 :            :                 }
     120         [ #  # ]:          0 :                 if (!seen)
     121                 :            :                         /*
     122                 :            :                          * Count errors in WQEs units.
     123                 :            :                          * Later it can be improved to count error packets,
     124                 :            :                          * for example, by SQ parsing to find how much packets
     125                 :            :                          * should be counted for each WQE.
     126                 :            :                          */
     127                 :          0 :                         txq->stats.oerrors += ((txq->wqe_ci & wqe_m) -
     128                 :          0 :                                                 new_wqe_pi) & wqe_m;
     129         [ #  # ]:          0 :                 if (tx_recover_qp(txq_ctrl)) {
     130                 :            :                         /* Recovering failed - retry later on the same WQE. */
     131                 :            :                         return -1;
     132                 :            :                 }
     133                 :            :                 /* Release all the remaining buffers. */
     134                 :          0 :                 txq_free_elts(txq_ctrl);
     135                 :            :         }
     136                 :            :         return 0;
     137                 :            : }
     138                 :            : 
     139                 :            : /**
     140                 :            :  * Update completion queue consuming index via doorbell
     141                 :            :  * and flush the completed data buffers.
     142                 :            :  *
     143                 :            :  * @param txq
     144                 :            :  *   Pointer to TX queue structure.
     145                 :            :  * @param last_cqe
     146                 :            :  *   valid CQE pointer, if not NULL update txq->wqe_pi and flush the buffers.
     147                 :            :  * @param olx
     148                 :            :  *   Configured Tx offloads mask. It is fully defined at
     149                 :            :  *   compile time and may be used for optimization.
     150                 :            :  */
     151                 :            : static __rte_always_inline void
     152                 :            : mlx5_tx_comp_flush(struct mlx5_txq_data *__rte_restrict txq,
     153                 :            :                    volatile struct mlx5_cqe *last_cqe,
     154                 :            :                    unsigned int olx __rte_unused)
     155                 :            : {
     156                 :          0 :         if (likely(last_cqe != NULL)) {
     157                 :            :                 uint16_t tail;
     158                 :            : 
     159                 :          0 :                 txq->wqe_pi = rte_be_to_cpu_16(last_cqe->wqe_counter);
     160                 :          0 :                 tail = txq->fcqs[(txq->cq_ci - 1) & txq->cqe_m];
     161         [ #  # ]:          0 :                 if (likely(tail != txq->elts_tail)) {
     162                 :            :                         mlx5_tx_free_elts(txq, tail, olx);
     163                 :            :                         MLX5_ASSERT(tail == txq->elts_tail);
     164                 :            :                 }
     165                 :            :         }
     166                 :            : }
     167                 :            : 
     168                 :            : /**
     169                 :            :  * Manage TX completions. This routine checks the CQ for
     170                 :            :  * arrived CQEs, deduces the last accomplished WQE in SQ,
     171                 :            :  * updates SQ producing index and frees all completed mbufs.
     172                 :            :  *
     173                 :            :  * @param txq
     174                 :            :  *   Pointer to TX queue structure.
     175                 :            :  * @param olx
     176                 :            :  *   Configured Tx offloads mask. It is fully defined at
     177                 :            :  *   compile time and may be used for optimization.
     178                 :            :  *
     179                 :            :  * NOTE: not inlined intentionally, it makes tx_burst
     180                 :            :  * routine smaller, simple and faster - from experiments.
     181                 :            :  */
     182                 :            : void
     183                 :          0 : mlx5_tx_handle_completion(struct mlx5_txq_data *__rte_restrict txq,
     184                 :            :                           unsigned int olx __rte_unused)
     185                 :            : {
     186                 :            :         unsigned int count = MLX5_TX_COMP_MAX_CQE;
     187                 :            :         volatile struct mlx5_cqe *last_cqe = NULL;
     188                 :            :         bool ring_doorbell = false;
     189                 :            :         int ret;
     190                 :            : 
     191                 :            :         do {
     192                 :            :                 volatile struct mlx5_cqe *cqe;
     193                 :            : 
     194                 :          0 :                 cqe = &txq->cqes[txq->cq_ci & txq->cqe_m];
     195         [ #  # ]:          0 :                 ret = check_cqe(cqe, txq->cqe_s, txq->cq_ci);
     196         [ #  # ]:          0 :                 if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) {
     197         [ #  # ]:          0 :                         if (likely(ret != MLX5_CQE_STATUS_ERR)) {
     198                 :            :                                 /* No new CQEs in completion queue. */
     199                 :            :                                 MLX5_ASSERT(ret == MLX5_CQE_STATUS_HW_OWN);
     200                 :            :                                 break;
     201                 :            :                         }
     202                 :            :                         /*
     203                 :            :                          * Some error occurred, try to restart.
     204                 :            :                          * We have no barrier after WQE related Doorbell
     205                 :            :                          * written, make sure all writes are completed
     206                 :            :                          * here, before we might perform SQ reset.
     207                 :            :                          */
     208                 :            :                         rte_wmb();
     209                 :          0 :                         ret = mlx5_tx_error_cqe_handle
     210                 :            :                                 (txq, (volatile struct mlx5_error_cqe *)cqe);
     211         [ #  # ]:          0 :                         if (unlikely(ret < 0)) {
     212                 :            :                                 /*
     213                 :            :                                  * Some error occurred on queue error
     214                 :            :                                  * handling, we do not advance the index
     215                 :            :                                  * here, allowing to retry on next call.
     216                 :            :                                  */
     217                 :            :                                 return;
     218                 :            :                         }
     219                 :            :                         /*
     220                 :            :                          * We are going to fetch all entries with
     221                 :            :                          * MLX5_CQE_SYNDROME_WR_FLUSH_ERR status.
     222                 :            :                          * The send queue is supposed to be empty.
     223                 :            :                          */
     224                 :            :                         ring_doorbell = true;
     225                 :          0 :                         ++txq->cq_ci;
     226                 :          0 :                         txq->cq_pi = txq->cq_ci;
     227                 :            :                         last_cqe = NULL;
     228                 :          0 :                         continue;
     229                 :            :                 }
     230                 :            :                 /* Normal transmit completion. */
     231                 :            :                 MLX5_ASSERT(txq->cq_ci != txq->cq_pi);
     232                 :            : #ifdef RTE_LIBRTE_MLX5_DEBUG
     233                 :            :                 MLX5_ASSERT((txq->fcqs[txq->cq_ci & txq->cqe_m] >> 16) ==
     234                 :            :                             cqe->wqe_counter);
     235                 :            : #endif
     236                 :            :                 if (__rte_trace_point_fp_is_enabled()) {
     237                 :            :                         uint64_t ts = rte_be_to_cpu_64(cqe->timestamp);
     238                 :            :                         uint16_t wqe_id = rte_be_to_cpu_16(cqe->wqe_counter);
     239                 :            : 
     240                 :            :                         if (txq->rt_timestamp)
     241                 :            :                                 ts = mlx5_txpp_convert_rx_ts(NULL, ts);
     242                 :            :                         rte_pmd_mlx5_trace_tx_complete(txq->port_id, txq->idx,
     243                 :            :                                                        wqe_id, ts);
     244                 :            :                 }
     245                 :            :                 ring_doorbell = true;
     246                 :          0 :                 ++txq->cq_ci;
     247                 :            :                 last_cqe = cqe;
     248                 :            :                 /*
     249                 :            :                  * We have to restrict the amount of processed CQEs
     250                 :            :                  * in one tx_burst routine call. The CQ may be large
     251                 :            :                  * and many CQEs may be updated by the NIC in one
     252                 :            :                  * transaction. Buffers freeing is time consuming,
     253                 :            :                  * multiple iterations may introduce significant latency.
     254                 :            :                  */
     255         [ #  # ]:          0 :                 if (likely(--count == 0))
     256                 :            :                         break;
     257                 :            :         } while (true);
     258         [ #  # ]:          0 :         if (likely(ring_doorbell)) {
     259                 :            :                 /* Ring doorbell to notify hardware. */
     260                 :          0 :                 rte_compiler_barrier();
     261   [ #  #  #  # ]:          0 :                 *txq->cq_db = rte_cpu_to_be_32(txq->cq_ci);
     262                 :            :                 mlx5_tx_comp_flush(txq, last_cqe, olx);
     263                 :            :         }
     264                 :            : }
     265                 :            : 
     266                 :            : /**
     267                 :            :  * DPDK callback to check the status of a Tx descriptor.
     268                 :            :  *
     269                 :            :  * @param tx_queue
     270                 :            :  *   The Tx queue.
     271                 :            :  * @param[in] offset
     272                 :            :  *   The index of the descriptor in the ring.
     273                 :            :  *
     274                 :            :  * @return
     275                 :            :  *   The status of the Tx descriptor.
     276                 :            :  */
     277                 :            : int
     278                 :          0 : mlx5_tx_descriptor_status(void *tx_queue, uint16_t offset)
     279                 :            : {
     280                 :            :         struct mlx5_txq_data *__rte_restrict txq = tx_queue;
     281                 :            :         uint16_t used;
     282                 :            : 
     283                 :          0 :         mlx5_tx_handle_completion(txq, 0);
     284                 :          0 :         used = txq->elts_head - txq->elts_tail;
     285         [ #  # ]:          0 :         if (offset < used)
     286                 :          0 :                 return RTE_ETH_TX_DESC_FULL;
     287                 :            :         return RTE_ETH_TX_DESC_DONE;
     288                 :            : }
     289                 :            : 
     290                 :            : /*
     291                 :            :  * Array of declared and compiled Tx burst function and corresponding
     292                 :            :  * supported offloads set. The array is used to select the Tx burst
     293                 :            :  * function for specified offloads set at Tx queue configuration time.
     294                 :            :  */
     295                 :            : const struct {
     296                 :            :         eth_tx_burst_t func;
     297                 :            :         unsigned int olx;
     298                 :            : } txoff_func[] = {
     299                 :            : MLX5_TXOFF_INFO(full_empw,
     300                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     301                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     302                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     303                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     304                 :            : 
     305                 :            : MLX5_TXOFF_INFO(none_empw,
     306                 :            :                 MLX5_TXOFF_CONFIG_NONE | MLX5_TXOFF_CONFIG_EMPW)
     307                 :            : 
     308                 :            : MLX5_TXOFF_INFO(md_empw,
     309                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     310                 :            : 
     311                 :            : MLX5_TXOFF_INFO(mt_empw,
     312                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     313                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     314                 :            : 
     315                 :            : MLX5_TXOFF_INFO(mtsc_empw,
     316                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     317                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     318                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     319                 :            : 
     320                 :            : MLX5_TXOFF_INFO(mti_empw,
     321                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     322                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     323                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     324                 :            : 
     325                 :            : MLX5_TXOFF_INFO(mtv_empw,
     326                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     327                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     328                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     329                 :            : 
     330                 :            : MLX5_TXOFF_INFO(mtiv_empw,
     331                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     332                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     333                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     334                 :            : 
     335                 :            : MLX5_TXOFF_INFO(sc_empw,
     336                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     337                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     338                 :            : 
     339                 :            : MLX5_TXOFF_INFO(sci_empw,
     340                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     341                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     342                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     343                 :            : 
     344                 :            : MLX5_TXOFF_INFO(scv_empw,
     345                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     346                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     347                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     348                 :            : 
     349                 :            : MLX5_TXOFF_INFO(sciv_empw,
     350                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     351                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     352                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     353                 :            : 
     354                 :            : MLX5_TXOFF_INFO(i_empw,
     355                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     356                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     357                 :            : 
     358                 :            : MLX5_TXOFF_INFO(v_empw,
     359                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     360                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     361                 :            : 
     362                 :            : MLX5_TXOFF_INFO(iv_empw,
     363                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     364                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_EMPW)
     365                 :            : 
     366                 :            : MLX5_TXOFF_INFO(full_ts_nompw,
     367                 :            :                 MLX5_TXOFF_CONFIG_FULL | MLX5_TXOFF_CONFIG_TXPP)
     368                 :            : 
     369                 :            : MLX5_TXOFF_INFO(full_ts_nompwi,
     370                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     371                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     372                 :            :                 MLX5_TXOFF_CONFIG_VLAN | MLX5_TXOFF_CONFIG_METADATA |
     373                 :            :                 MLX5_TXOFF_CONFIG_TXPP)
     374                 :            : 
     375                 :            : MLX5_TXOFF_INFO(full_ts,
     376                 :            :                 MLX5_TXOFF_CONFIG_FULL | MLX5_TXOFF_CONFIG_TXPP |
     377                 :            :                 MLX5_TXOFF_CONFIG_EMPW)
     378                 :            : 
     379                 :            : MLX5_TXOFF_INFO(full_ts_noi,
     380                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     381                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     382                 :            :                 MLX5_TXOFF_CONFIG_VLAN | MLX5_TXOFF_CONFIG_METADATA |
     383                 :            :                 MLX5_TXOFF_CONFIG_TXPP | MLX5_TXOFF_CONFIG_EMPW)
     384                 :            : 
     385                 :            : MLX5_TXOFF_INFO(none_ts,
     386                 :            :                 MLX5_TXOFF_CONFIG_NONE | MLX5_TXOFF_CONFIG_TXPP |
     387                 :            :                 MLX5_TXOFF_CONFIG_EMPW)
     388                 :            : 
     389                 :            : MLX5_TXOFF_INFO(mdi_ts,
     390                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_METADATA |
     391                 :            :                 MLX5_TXOFF_CONFIG_TXPP | MLX5_TXOFF_CONFIG_EMPW)
     392                 :            : 
     393                 :            : MLX5_TXOFF_INFO(mti_ts,
     394                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     395                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_METADATA |
     396                 :            :                 MLX5_TXOFF_CONFIG_TXPP | MLX5_TXOFF_CONFIG_EMPW)
     397                 :            : 
     398                 :            : MLX5_TXOFF_INFO(mtiv_ts,
     399                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     400                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     401                 :            :                 MLX5_TXOFF_CONFIG_METADATA | MLX5_TXOFF_CONFIG_TXPP |
     402                 :            :                 MLX5_TXOFF_CONFIG_EMPW)
     403                 :            : 
     404                 :            : MLX5_TXOFF_INFO(full,
     405                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     406                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     407                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     408                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     409                 :            : 
     410                 :            : MLX5_TXOFF_INFO(none,
     411                 :            :                 MLX5_TXOFF_CONFIG_NONE)
     412                 :            : 
     413                 :            : MLX5_TXOFF_INFO(md,
     414                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     415                 :            : 
     416                 :            : MLX5_TXOFF_INFO(mt,
     417                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     418                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     419                 :            : 
     420                 :            : MLX5_TXOFF_INFO(mtsc,
     421                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     422                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     423                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     424                 :            : 
     425                 :            : MLX5_TXOFF_INFO(mti,
     426                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     427                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     428                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     429                 :            : 
     430                 :            : MLX5_TXOFF_INFO(mtv,
     431                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     432                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     433                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     434                 :            : 
     435                 :            : MLX5_TXOFF_INFO(mtiv,
     436                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_TSO |
     437                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     438                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     439                 :            : 
     440                 :            : MLX5_TXOFF_INFO(sc,
     441                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     442                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     443                 :            : 
     444                 :            : MLX5_TXOFF_INFO(sci,
     445                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     446                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     447                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     448                 :            : 
     449                 :            : MLX5_TXOFF_INFO(scv,
     450                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     451                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     452                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     453                 :            : 
     454                 :            : MLX5_TXOFF_INFO(sciv,
     455                 :            :                 MLX5_TXOFF_CONFIG_SWP | MLX5_TXOFF_CONFIG_CSUM |
     456                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     457                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     458                 :            : 
     459                 :            : MLX5_TXOFF_INFO(i,
     460                 :            :                 MLX5_TXOFF_CONFIG_INLINE |
     461                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     462                 :            : 
     463                 :            : MLX5_TXOFF_INFO(v,
     464                 :            :                 MLX5_TXOFF_CONFIG_VLAN |
     465                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     466                 :            : 
     467                 :            : MLX5_TXOFF_INFO(iv,
     468                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_VLAN |
     469                 :            :                 MLX5_TXOFF_CONFIG_METADATA)
     470                 :            : 
     471                 :            : MLX5_TXOFF_INFO(none_mpw,
     472                 :            :                 MLX5_TXOFF_CONFIG_NONE | MLX5_TXOFF_CONFIG_EMPW |
     473                 :            :                 MLX5_TXOFF_CONFIG_MPW)
     474                 :            : 
     475                 :            : MLX5_TXOFF_INFO(mci_mpw,
     476                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_CSUM |
     477                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW |
     478                 :            :                 MLX5_TXOFF_CONFIG_MPW)
     479                 :            : 
     480                 :            : MLX5_TXOFF_INFO(mc_mpw,
     481                 :            :                 MLX5_TXOFF_CONFIG_MULTI | MLX5_TXOFF_CONFIG_CSUM |
     482                 :            :                 MLX5_TXOFF_CONFIG_EMPW | MLX5_TXOFF_CONFIG_MPW)
     483                 :            : 
     484                 :            : MLX5_TXOFF_INFO(i_mpw,
     485                 :            :                 MLX5_TXOFF_CONFIG_INLINE | MLX5_TXOFF_CONFIG_EMPW |
     486                 :            :                 MLX5_TXOFF_CONFIG_MPW)
     487                 :            : };
     488                 :            : 
     489                 :            : /**
     490                 :            :  * Configure the Tx function to use. The routine checks configured
     491                 :            :  * Tx offloads for the device and selects appropriate Tx burst routine.
     492                 :            :  * There are multiple Tx burst routines compiled from the same template
     493                 :            :  * in the most optimal way for the dedicated Tx offloads set.
     494                 :            :  *
     495                 :            :  * @param dev
     496                 :            :  *   Pointer to private data structure.
     497                 :            :  *
     498                 :            :  * @return
     499                 :            :  *   Pointer to selected Tx burst function.
     500                 :            :  */
     501                 :            : eth_tx_burst_t
     502                 :          0 : mlx5_select_tx_function(struct rte_eth_dev *dev)
     503                 :            : {
     504                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     505                 :            :         struct mlx5_port_config *config = &priv->config;
     506                 :          0 :         uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
     507                 :            :         unsigned int diff = 0, olx = 0, i, m;
     508                 :            : 
     509                 :            :         MLX5_ASSERT(priv);
     510         [ #  # ]:          0 :         if (tx_offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) {
     511                 :            :                 /* We should support Multi-Segment Packets. */
     512                 :            :                 olx |= MLX5_TXOFF_CONFIG_MULTI;
     513                 :            :         }
     514         [ #  # ]:          0 :         if (tx_offloads & (RTE_ETH_TX_OFFLOAD_TCP_TSO |
     515                 :            :                            RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
     516                 :            :                            RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
     517                 :            :                            RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
     518                 :            :                            RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO)) {
     519                 :            :                 /* We should support TCP Send Offload. */
     520                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_TSO;
     521                 :            :         }
     522         [ #  # ]:          0 :         if (tx_offloads & (RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
     523                 :            :                            RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO |
     524                 :            :                            RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM)) {
     525                 :            :                 /* We should support Software Parser for Tunnels. */
     526                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_SWP;
     527                 :            :         }
     528         [ #  # ]:          0 :         if (tx_offloads & (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
     529                 :            :                            RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
     530                 :            :                            RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
     531                 :            :                            RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM)) {
     532                 :            :                 /* We should support IP/TCP/UDP Checksums. */
     533                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_CSUM;
     534                 :            :         }
     535         [ #  # ]:          0 :         if (tx_offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) {
     536                 :            :                 /* We should support VLAN insertion. */
     537                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_VLAN;
     538                 :            :         }
     539   [ #  #  #  # ]:          0 :         if (tx_offloads & RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP &&
     540                 :          0 :             rte_mbuf_dynflag_lookup
     541         [ #  # ]:          0 :                         (RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL) >= 0 &&
     542                 :          0 :             rte_mbuf_dynfield_lookup
     543                 :            :                         (RTE_MBUF_DYNFIELD_TIMESTAMP_NAME, NULL) >= 0) {
     544                 :            :                 /* Offload configured, dynamic entities registered. */
     545                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_TXPP;
     546                 :            :         }
     547   [ #  #  #  # ]:          0 :         if (priv->txqs_n && (*priv->txqs)[0]) {
     548                 :            :                 struct mlx5_txq_data *txd = (*priv->txqs)[0];
     549                 :            : 
     550         [ #  # ]:          0 :                 if (txd->inlen_send) {
     551                 :            :                         /*
     552                 :            :                          * Check the data inline requirements. Data inline
     553                 :            :                          * is enabled on per device basis, we can check
     554                 :            :                          * the first Tx queue only.
     555                 :            :                          *
     556                 :            :                          * If device does not support VLAN insertion in WQE
     557                 :            :                          * and some queues are requested to perform VLAN
     558                 :            :                          * insertion offload than inline must be enabled.
     559                 :            :                          */
     560                 :          0 :                         olx |= MLX5_TXOFF_CONFIG_INLINE;
     561                 :            :                 }
     562                 :            :         }
     563         [ #  # ]:          0 :         if (config->mps == MLX5_MPW_ENHANCED &&
     564         [ #  # ]:          0 :             config->txq_inline_min <= 0) {
     565                 :            :                 /*
     566                 :            :                  * The NIC supports Enhanced Multi-Packet Write
     567                 :            :                  * and does not require minimal inline data.
     568                 :            :                  */
     569                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_EMPW;
     570                 :            :         }
     571         [ #  # ]:          0 :         if (rte_flow_dynf_metadata_avail()) {
     572                 :            :                 /* We should support Flow metadata. */
     573                 :          0 :                 olx |= MLX5_TXOFF_CONFIG_METADATA;
     574                 :            :         }
     575         [ #  # ]:          0 :         if (config->mps == MLX5_MPW) {
     576                 :            :                 /*
     577                 :            :                  * The NIC supports Legacy Multi-Packet Write.
     578                 :            :                  * The MLX5_TXOFF_CONFIG_MPW controls the descriptor building
     579                 :            :                  * method in combination with MLX5_TXOFF_CONFIG_EMPW.
     580                 :            :                  */
     581         [ #  # ]:          0 :                 if (!(olx & (MLX5_TXOFF_CONFIG_TSO |
     582                 :            :                              MLX5_TXOFF_CONFIG_SWP |
     583                 :            :                              MLX5_TXOFF_CONFIG_VLAN |
     584                 :            :                              MLX5_TXOFF_CONFIG_METADATA)))
     585                 :          0 :                         olx |= MLX5_TXOFF_CONFIG_EMPW |
     586                 :            :                                MLX5_TXOFF_CONFIG_MPW;
     587                 :            :         }
     588                 :            :         /*
     589                 :            :          * Scan the routines table to find the minimal
     590                 :            :          * satisfying routine with requested offloads.
     591                 :            :          */
     592                 :            :         m = RTE_DIM(txoff_func);
     593         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(txoff_func); i++) {
     594                 :            :                 unsigned int tmp;
     595                 :            : 
     596                 :          0 :                 tmp = txoff_func[i].olx;
     597         [ #  # ]:          0 :                 if (tmp == olx) {
     598                 :            :                         /* Meets requested offloads exactly.*/
     599                 :            :                         m = i;
     600                 :            :                         break;
     601                 :            :                 }
     602         [ #  # ]:          0 :                 if ((tmp & olx) != olx) {
     603                 :            :                         /* Does not meet requested offloads at all. */
     604                 :          0 :                         continue;
     605                 :            :                 }
     606         [ #  # ]:          0 :                 if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_MPW)
     607                 :            :                         /* Do not enable legacy MPW if not configured. */
     608                 :          0 :                         continue;
     609         [ #  # ]:          0 :                 if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_EMPW)
     610                 :            :                         /* Do not enable eMPW if not configured. */
     611                 :          0 :                         continue;
     612         [ #  # ]:          0 :                 if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_INLINE)
     613                 :            :                         /* Do not enable inlining if not configured. */
     614                 :          0 :                         continue;
     615         [ #  # ]:          0 :                 if ((olx ^ tmp) & MLX5_TXOFF_CONFIG_TXPP)
     616                 :            :                         /* Do not enable scheduling if not configured. */
     617                 :          0 :                         continue;
     618                 :            :                 /*
     619                 :            :                  * Some routine meets the requirements.
     620                 :            :                  * Check whether it has minimal amount
     621                 :            :                  * of not requested offloads.
     622                 :            :                  */
     623         [ #  # ]:          0 :                 tmp = rte_popcount64(tmp & ~olx);
     624         [ #  # ]:          0 :                 if (m >= RTE_DIM(txoff_func) || tmp < diff) {
     625                 :            :                         /* First or better match, save and continue. */
     626                 :            :                         m = i;
     627                 :            :                         diff = tmp;
     628                 :          0 :                         continue;
     629                 :            :                 }
     630         [ #  # ]:          0 :                 if (tmp == diff) {
     631                 :          0 :                         tmp = txoff_func[i].olx ^ txoff_func[m].olx;
     632                 :          0 :                         if (__builtin_ffsl(txoff_func[i].olx & ~tmp) <
     633         [ #  # ]:          0 :                             __builtin_ffsl(txoff_func[m].olx & ~tmp)) {
     634                 :            :                                 /* Lighter not requested offload. */
     635                 :            :                                 m = i;
     636                 :            :                         }
     637                 :            :                 }
     638                 :            :         }
     639         [ #  # ]:          0 :         if (m >= RTE_DIM(txoff_func)) {
     640                 :          0 :                 DRV_LOG(DEBUG, "port %u has no selected Tx function"
     641                 :            :                                " for requested offloads %04X",
     642                 :            :                                 dev->data->port_id, olx);
     643                 :          0 :                 return NULL;
     644                 :            :         }
     645                 :          0 :         DRV_LOG(DEBUG, "port %u has selected Tx function"
     646                 :            :                        " supporting offloads %04X/%04X",
     647                 :            :                         dev->data->port_id, olx, txoff_func[m].olx);
     648         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_MULTI)
     649                 :          0 :                 DRV_LOG(DEBUG, "\tMULTI (multi segment)");
     650         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_TSO)
     651                 :          0 :                 DRV_LOG(DEBUG, "\tTSO   (TCP send offload)");
     652         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_SWP)
     653                 :          0 :                 DRV_LOG(DEBUG, "\tSWP   (software parser)");
     654         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_CSUM)
     655                 :          0 :                 DRV_LOG(DEBUG, "\tCSUM  (checksum offload)");
     656         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_INLINE)
     657                 :          0 :                 DRV_LOG(DEBUG, "\tINLIN (inline data)");
     658         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_VLAN)
     659                 :          0 :                 DRV_LOG(DEBUG, "\tVLANI (VLAN insertion)");
     660         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_METADATA)
     661                 :          0 :                 DRV_LOG(DEBUG, "\tMETAD (tx Flow metadata)");
     662         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_TXPP)
     663                 :          0 :                 DRV_LOG(DEBUG, "\tMETAD (tx Scheduling)");
     664         [ #  # ]:          0 :         if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_EMPW) {
     665         [ #  # ]:          0 :                 if (txoff_func[m].olx & MLX5_TXOFF_CONFIG_MPW)
     666                 :          0 :                         DRV_LOG(DEBUG, "\tMPW   (Legacy MPW)");
     667                 :            :                 else
     668                 :          0 :                         DRV_LOG(DEBUG, "\tEMPW  (Enhanced MPW)");
     669                 :            :         }
     670                 :          0 :         return txoff_func[m].func;
     671                 :            : }
     672                 :            : 
     673                 :            : /**
     674                 :            :  * DPDK callback to get the TX queue information.
     675                 :            :  *
     676                 :            :  * @param dev
     677                 :            :  *   Pointer to the device structure.
     678                 :            :  *
     679                 :            :  * @param tx_queue_id
     680                 :            :  *   Tx queue identificator.
     681                 :            :  *
     682                 :            :  * @param qinfo
     683                 :            :  *   Pointer to the TX queue information structure.
     684                 :            :  *
     685                 :            :  * @return
     686                 :            :  *   None.
     687                 :            :  */
     688                 :            : void
     689                 :          0 : mlx5_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
     690                 :            :                   struct rte_eth_txq_info *qinfo)
     691                 :            : {
     692                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     693                 :          0 :         struct mlx5_txq_data *txq = (*priv->txqs)[tx_queue_id];
     694                 :            :         struct mlx5_txq_ctrl *txq_ctrl =
     695                 :            :                         container_of(txq, struct mlx5_txq_ctrl, txq);
     696                 :            : 
     697         [ #  # ]:          0 :         if (!txq)
     698                 :            :                 return;
     699                 :          0 :         qinfo->nb_desc = txq->elts_s;
     700                 :          0 :         qinfo->conf.tx_thresh.pthresh = 0;
     701                 :          0 :         qinfo->conf.tx_thresh.hthresh = 0;
     702                 :          0 :         qinfo->conf.tx_thresh.wthresh = 0;
     703                 :          0 :         qinfo->conf.tx_rs_thresh = 0;
     704                 :          0 :         qinfo->conf.tx_free_thresh = 0;
     705                 :          0 :         qinfo->conf.tx_deferred_start = txq_ctrl ? 0 : 1;
     706                 :          0 :         qinfo->conf.offloads = dev->data->dev_conf.txmode.offloads;
     707                 :            : }
     708                 :            : 
     709                 :            : /**
     710                 :            :  * DPDK callback to get the TX packet burst mode information.
     711                 :            :  *
     712                 :            :  * @param dev
     713                 :            :  *   Pointer to the device structure.
     714                 :            :  *
     715                 :            :  * @param tx_queue_id
     716                 :            :  *   Tx queue identification.
     717                 :            :  *
     718                 :            :  * @param mode
     719                 :            :  *   Pointer to the burts mode information.
     720                 :            :  *
     721                 :            :  * @return
     722                 :            :  *   0 as success, -EINVAL as failure.
     723                 :            :  */
     724                 :            : int
     725                 :          0 : mlx5_tx_burst_mode_get(struct rte_eth_dev *dev,
     726                 :            :                        uint16_t tx_queue_id,
     727                 :            :                        struct rte_eth_burst_mode *mode)
     728                 :            : {
     729                 :          0 :         eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
     730                 :          0 :         struct mlx5_priv *priv = dev->data->dev_private;
     731                 :          0 :         struct mlx5_txq_data *txq = (*priv->txqs)[tx_queue_id];
     732                 :            :         unsigned int i, olx;
     733                 :            : 
     734         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(txoff_func); i++) {
     735         [ #  # ]:          0 :                 if (pkt_burst == txoff_func[i].func) {
     736                 :          0 :                         olx = txoff_func[i].olx;
     737         [ #  # ]:          0 :                         snprintf(mode->info, sizeof(mode->info),
     738                 :            :                                  "%s%s%s%s%s%s%s%s%s%s",
     739         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_EMPW) ?
     740                 :          0 :                                  ((olx & MLX5_TXOFF_CONFIG_MPW) ?
     741         [ #  # ]:          0 :                                  "Legacy MPW" : "Enhanced MPW") : "No MPW",
     742         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_MULTI) ?
     743                 :            :                                  " + MULTI" : "",
     744         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_TSO) ?
     745                 :            :                                  " + TSO" : "",
     746         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_SWP) ?
     747                 :            :                                  " + SWP" : "",
     748         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_CSUM) ?
     749                 :            :                                  "  + CSUM" : "",
     750         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_INLINE) ?
     751                 :            :                                  " + INLINE" : "",
     752         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_VLAN) ?
     753                 :            :                                  " + VLAN" : "",
     754         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_METADATA) ?
     755                 :            :                                  " + METADATA" : "",
     756         [ #  # ]:          0 :                                  (olx & MLX5_TXOFF_CONFIG_TXPP) ?
     757                 :            :                                  " + TXPP" : "",
     758         [ #  # ]:          0 :                                  (txq && txq->fast_free) ?
     759                 :            :                                  " + Fast Free" : "");
     760                 :          0 :                         return 0;
     761                 :            :                 }
     762                 :            :         }
     763                 :            :         return -EINVAL;
     764                 :            : }
     765                 :            : 
     766                 :            : /**
     767                 :            :  * Dump SQ/CQ Context to a file.
     768                 :            :  *
     769                 :            :  * @param[in] port_id
     770                 :            :  *   Port ID
     771                 :            :  * @param[in] queue_id
     772                 :            :  *   Queue ID
     773                 :            :  * @param[in] filename
     774                 :            :  *   Name of file to dump the Tx Queue Context
     775                 :            :  *
     776                 :            :  * @return
     777                 :            :  *   0 for success, non-zero value depending on failure.
     778                 :            :  *
     779                 :            :  */
     780                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_mlx5_txq_dump_contexts, 24.07)
     781                 :          0 : int rte_pmd_mlx5_txq_dump_contexts(uint16_t port_id, uint16_t queue_id, const char *filename)
     782                 :            : {
     783                 :            :         struct rte_eth_dev *dev;
     784                 :            :         struct mlx5_priv *priv;
     785                 :            :         struct mlx5_txq_data *txq_data;
     786                 :            :         struct mlx5_txq_ctrl *txq_ctrl;
     787                 :            :         struct mlx5_txq_obj *txq_obj;
     788                 :            :         struct mlx5_devx_sq *sq;
     789                 :            :         struct mlx5_devx_cq *cq;
     790                 :            :         struct mlx5_devx_obj *sq_devx_obj;
     791                 :            :         struct mlx5_devx_obj *cq_devx_obj;
     792                 :            : 
     793                 :          0 :         uint32_t sq_out[MLX5_ST_SZ_DW(query_sq_out)] = {0};
     794                 :          0 :         uint32_t cq_out[MLX5_ST_SZ_DW(query_cq_out)] = {0};
     795                 :            : 
     796                 :            :         int ret;
     797                 :            :         FILE *fd;
     798                 :          0 :         MKSTR(path, "./%s", filename);
     799                 :            : 
     800         [ #  # ]:          0 :         if (!rte_eth_dev_is_valid_port(port_id))
     801                 :            :                 return -ENODEV;
     802                 :            : 
     803         [ #  # ]:          0 :         if (rte_eth_tx_queue_is_valid(port_id, queue_id))
     804                 :            :                 return -EINVAL;
     805                 :            : 
     806                 :          0 :         fd = fopen(path, "w");
     807         [ #  # ]:          0 :         if (!fd) {
     808                 :          0 :                 rte_errno = errno;
     809                 :          0 :                 return -EIO;
     810                 :            :         }
     811                 :            : 
     812                 :            :         dev = &rte_eth_devices[port_id];
     813                 :          0 :         priv = dev->data->dev_private;
     814                 :          0 :         txq_data = (*priv->txqs)[queue_id];
     815                 :          0 :         txq_ctrl = container_of(txq_data, struct mlx5_txq_ctrl, txq);
     816                 :          0 :         txq_obj = txq_ctrl->obj;
     817                 :            :         sq = &txq_obj->sq_obj;
     818                 :            :         cq = &txq_obj->cq_obj;
     819                 :          0 :         sq_devx_obj = sq->sq;
     820                 :          0 :         cq_devx_obj = cq->cq;
     821                 :            : 
     822                 :            :         do {
     823                 :          0 :                 ret = mlx5_devx_cmd_query_sq(sq_devx_obj, sq_out, sizeof(sq_out));
     824         [ #  # ]:          0 :                 if (ret)
     825                 :            :                         break;
     826                 :            : 
     827                 :            :                 /* Dump sq query output to file */
     828                 :          0 :                 MKSTR(sq_headline, "SQ DevX ID = %u Port = %u Queue index = %u ",
     829                 :            :                                         sq_devx_obj->id, port_id, queue_id);
     830                 :          0 :                 mlx5_dump_to_file(fd, NULL, sq_headline, 0);
     831                 :          0 :                 mlx5_dump_to_file(fd, "Query SQ Dump:",
     832                 :            :                                         (const void *)((uintptr_t)sq_out),
     833                 :            :                                         sizeof(sq_out));
     834                 :            : 
     835                 :          0 :                 ret = mlx5_devx_cmd_query_cq(cq_devx_obj, cq_out, sizeof(cq_out));
     836         [ #  # ]:          0 :                 if (ret)
     837                 :            :                         break;
     838                 :            : 
     839                 :            :                 /* Dump cq query output to file */
     840                 :          0 :                 MKSTR(cq_headline, "CQ DevX ID = %u Port = %u Queue index = %u ",
     841                 :            :                                                 cq_devx_obj->id, port_id, queue_id);
     842                 :          0 :                 mlx5_dump_to_file(fd, NULL, cq_headline, 0);
     843                 :          0 :                 mlx5_dump_to_file(fd, "Query CQ Dump:",
     844                 :            :                                         (const void *)((uintptr_t)cq_out),
     845                 :            :                                         sizeof(cq_out));
     846                 :            :         } while (false);
     847                 :            : 
     848                 :          0 :         fclose(fd);
     849                 :          0 :         return ret;
     850                 :            : }

Generated by: LCOV version 1.14