common/mlx5: introduce common library
[dpdk.git] / drivers / net / mlx5 / mlx5_rxq.c
index 2a12d5f..e01cbfd 100644 (file)
 #include <rte_debug.h>
 #include <rte_io.h>
 
+#include <mlx5_glue.h>
+#include <mlx5_devx_cmds.h>
+
+#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"
+
 
 /* Default RSS hash key also used for ConnectX-3. */
 uint8_t rss_hash_default_key[] = {
@@ -224,6 +228,9 @@ rxq_alloc_elts_sprq(struct mlx5_rxq_ctrl *rxq_ctrl)
        if (mlx5_rxq_check_vec_support(&rxq_ctrl->rxq) > 0) {
                struct mlx5_rxq_data *rxq = &rxq_ctrl->rxq;
                struct rte_mbuf *mbuf_init = &rxq->fake_mbuf;
+               struct rte_pktmbuf_pool_private *priv =
+                       (struct rte_pktmbuf_pool_private *)
+                               rte_mempool_get_priv(rxq_ctrl->rxq.mp);
                int j;
 
                /* Initialize default rearm_data for vPMD. */
@@ -231,13 +238,15 @@ rxq_alloc_elts_sprq(struct mlx5_rxq_ctrl *rxq_ctrl)
                rte_mbuf_refcnt_set(mbuf_init, 1);
                mbuf_init->nb_segs = 1;
                mbuf_init->port = rxq->port_id;
+               if (priv->flags & RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF)
+                       mbuf_init->ol_flags = EXT_ATTACHED_MBUF;
                /*
                 * prevent compiler reordering:
                 * rearm_data covers previous fields.
                 */
                rte_compiler_barrier();
                rxq->mbuf_initializer =
-                       *(uint64_t *)&mbuf_init->rearm_data;
+                       *(rte_xmm_t *)&mbuf_init->rearm_data;
                /* Padding with a fake mbuf for vectorized Rx. */
                for (j = 0; j < MLX5_VPMD_DESCS_PER_LOOP; ++j)
                        (*rxq->elts)[elts_n + j] = &rxq->fake_mbuf;
@@ -671,23 +680,25 @@ static int
 mlx5_rxq_obj_release(struct mlx5_rxq_obj *rxq_obj)
 {
        assert(rxq_obj);
-       if (rxq_obj->type == MLX5_RXQ_OBJ_TYPE_IBV)
-               assert(rxq_obj->wq);
-       assert(rxq_obj->cq);
        if (rte_atomic32_dec_and_test(&rxq_obj->refcnt)) {
                switch (rxq_obj->type) {
                case MLX5_RXQ_OBJ_TYPE_IBV:
+                       assert(rxq_obj->wq);
+                       assert(rxq_obj->cq);
                        rxq_free_elts(rxq_obj->rxq_ctrl);
                        claim_zero(mlx5_glue->destroy_wq(rxq_obj->wq));
                        claim_zero(mlx5_glue->destroy_cq(rxq_obj->cq));
                        break;
                case MLX5_RXQ_OBJ_TYPE_DEVX_RQ:
+                       assert(rxq_obj->cq);
+                       assert(rxq_obj->rq);
                        rxq_free_elts(rxq_obj->rxq_ctrl);
                        claim_zero(mlx5_devx_cmd_destroy(rxq_obj->rq));
                        rxq_release_rq_resources(rxq_obj->rxq_ctrl);
                        claim_zero(mlx5_glue->destroy_cq(rxq_obj->cq));
                        break;
                case MLX5_RXQ_OBJ_TYPE_DEVX_HAIRPIN:
+                       assert(rxq_obj->rq);
                        rxq_obj_hairpin_release(rxq_obj);
                        break;
                }
@@ -1715,11 +1726,14 @@ exit:
  *
  * @param dev
  *   Pointer to Ethernet device.
+ * @param idx
+ *   RX queue index.
  * @param max_lro_size
  *   The maximum size for LRO packet.
  */
 static void
-mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint32_t max_lro_size)
+mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint16_t idx,
+                            uint32_t max_lro_size)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
 
@@ -1728,13 +1742,17 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint32_t max_lro_size)
            MLX5_MAX_TCP_HDR_OFFSET)
                max_lro_size -= MLX5_MAX_TCP_HDR_OFFSET;
        max_lro_size = RTE_MIN(max_lro_size, MLX5_MAX_LRO_SIZE);
-       assert(max_lro_size >= 256u);
-       max_lro_size /= 256u;
+       assert(max_lro_size >= MLX5_LRO_SEG_CHUNK_SIZE);
+       max_lro_size /= MLX5_LRO_SEG_CHUNK_SIZE;
        if (priv->max_lro_msg_size)
                priv->max_lro_msg_size =
                        RTE_MIN((uint32_t)priv->max_lro_msg_size, max_lro_size);
        else
                priv->max_lro_msg_size = max_lro_size;
+       DRV_LOG(DEBUG,
+               "port %u Rx Queue %u max LRO message size adjusted to %u bytes",
+               dev->data->port_id, idx,
+               priv->max_lro_msg_size * MLX5_LRO_SEG_CHUNK_SIZE);
 }
 
 /**
@@ -1907,7 +1925,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                rte_errno = EINVAL;
                goto error;
        }
-       mlx5_max_lro_msg_size_adjust(dev, max_lro_size);
+       mlx5_max_lro_msg_size_adjust(dev, idx, max_lro_size);
        /* Toggle RX checksum offload if hardware supports it. */
        tmpl->rxq.csum = !!(offloads & DEV_RX_OFFLOAD_CHECKSUM);
        tmpl->rxq.hw_timestamp = !!(offloads & DEV_RX_OFFLOAD_TIMESTAMP);
@@ -2463,8 +2481,36 @@ mlx5_hrxq_new(struct rte_eth_dev *dev,
                memset(&tir_attr, 0, sizeof(tir_attr));
                tir_attr.disp_type = MLX5_TIRC_DISP_TYPE_INDIRECT;
                tir_attr.rx_hash_fn = MLX5_RX_HASH_FN_TOEPLITZ;
-               memcpy(&tir_attr.rx_hash_field_selector_outer, &hash_fields,
-                      sizeof(uint64_t));
+               tir_attr.tunneled_offload_en = !!tunnel;
+               /* If needed, translate hash_fields bitmap to PRM format. */
+               if (hash_fields) {
+#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
+                       struct mlx5_rx_hash_field_select *rx_hash_field_select =
+                                       hash_fields & IBV_RX_HASH_INNER ?
+                                       &tir_attr.rx_hash_field_selector_inner :
+                                       &tir_attr.rx_hash_field_selector_outer;
+#else
+                       struct mlx5_rx_hash_field_select *rx_hash_field_select =
+                                       &tir_attr.rx_hash_field_selector_outer;
+#endif
+
+                       /* 1 bit: 0: IPv4, 1: IPv6. */
+                       rx_hash_field_select->l3_prot_type =
+                               !!(hash_fields & MLX5_IPV6_IBV_RX_HASH);
+                       /* 1 bit: 0: TCP, 1: UDP. */
+                       rx_hash_field_select->l4_prot_type =
+                               !!(hash_fields & MLX5_UDP_IBV_RX_HASH);
+                       /* Bitmask which sets which fields to use in RX Hash. */
+                       rx_hash_field_select->selected_fields =
+                       ((!!(hash_fields & MLX5_L3_SRC_IBV_RX_HASH)) <<
+                        MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_SRC_IP) |
+                       (!!(hash_fields & MLX5_L3_DST_IBV_RX_HASH)) <<
+                        MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_DST_IP |
+                       (!!(hash_fields & MLX5_L4_SRC_IBV_RX_HASH)) <<
+                        MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_SPORT |
+                       (!!(hash_fields & MLX5_L4_DST_IBV_RX_HASH)) <<
+                        MLX5_RX_HASH_FIELD_SELECT_SELECTED_FIELDS_L4_DPORT;
+               }
                if (rxq_ctrl->obj->type == MLX5_RXQ_OBJ_TYPE_DEVX_HAIRPIN)
                        tir_attr.transport_domain = priv->sh->td->id;
                else