New upstream version 16.11.3
[deb_dpdk.git] / drivers / net / mlx5 / mlx5_rxq.c
index 7dbe8dd..aea203b 100644 (file)
@@ -723,7 +723,7 @@ rxq_free_elts(struct rxq_ctrl *rxq_ctrl)
        if (rxq_ctrl->rxq.elts == NULL)
                return;
 
-       for (i = 0; (i != rxq_ctrl->rxq.elts_n); ++i) {
+       for (i = 0; (i != (1u << rxq_ctrl->rxq.elts_n)); ++i) {
                if ((*rxq_ctrl->rxq.elts)[i] != NULL)
                        rte_pktmbuf_free_seg((*rxq_ctrl->rxq.elts)[i]);
                (*rxq_ctrl->rxq.elts)[i] = NULL;
@@ -807,7 +807,7 @@ rxq_cleanup(struct rxq_ctrl *rxq_ctrl)
 int
 rxq_rehash(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl)
 {
-       unsigned int elts_n = rxq_ctrl->rxq.elts_n;
+       unsigned int elts_n = 1 << rxq_ctrl->rxq.elts_n;
        unsigned int i;
        struct ibv_exp_wq_attr mod;
        int err;
@@ -868,12 +868,16 @@ static inline int
 rxq_setup(struct rxq_ctrl *tmpl)
 {
        struct ibv_cq *ibcq = tmpl->cq;
-       struct mlx5_cq *cq = to_mxxx(cq, cq);
+       struct ibv_mlx5_cq_info cq_info;
        struct mlx5_rwq *rwq = container_of(tmpl->wq, struct mlx5_rwq, wq);
-       struct rte_mbuf *(*elts)[tmpl->rxq.elts_n] =
+       struct rte_mbuf *(*elts)[1 << tmpl->rxq.elts_n] =
                rte_calloc_socket("RXQ", 1, sizeof(*elts), 0, tmpl->socket);
 
-       if (cq->cqe_sz != RTE_CACHE_LINE_SIZE) {
+       if (ibv_mlx5_exp_get_cq_info(ibcq, &cq_info)) {
+               ERROR("Unable to query CQ info. check your OFED.");
+               return ENOTSUP;
+       }
+       if (cq_info.cqe_size != RTE_CACHE_LINE_SIZE) {
                ERROR("Wrong MLX5_CQE_SIZE environment variable value: "
                      "it should be set to %u", RTE_CACHE_LINE_SIZE);
                return EINVAL;
@@ -881,16 +885,16 @@ rxq_setup(struct rxq_ctrl *tmpl)
        if (elts == NULL)
                return ENOMEM;
        tmpl->rxq.rq_db = rwq->rq.db;
-       tmpl->rxq.cqe_n = ibcq->cqe + 1;
+       tmpl->rxq.cqe_n = log2above(cq_info.cqe_cnt);
        tmpl->rxq.cq_ci = 0;
        tmpl->rxq.rq_ci = 0;
-       tmpl->rxq.cq_db = cq->dbrec;
+       tmpl->rxq.cq_db = cq_info.dbrec;
        tmpl->rxq.wqes =
                (volatile struct mlx5_wqe_data_seg (*)[])
                (uintptr_t)rwq->rq.buff;
        tmpl->rxq.cqes =
                (volatile struct mlx5_cqe (*)[])
-               (uintptr_t)cq->active_buf->buf;
+               (uintptr_t)cq_info.buf;
        tmpl->rxq.elts = elts;
        return 0;
 }
@@ -924,8 +928,9 @@ rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
                .priv = priv,
                .socket = socket,
                .rxq = {
-                       .elts_n = desc,
+                       .elts_n = log2above(desc),
                        .mp = mp,
+                       .rss_hash = priv->rxqs_n > 1,
                },
        };
        struct ibv_exp_wq_attr mod;
@@ -1153,7 +1158,7 @@ rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
        }
        /* Reuse buffers from original queue if possible. */
        if (rxq_ctrl->rxq.elts_n) {
-               assert(rxq_ctrl->rxq.elts_n == desc);
+               assert(1 << rxq_ctrl->rxq.elts_n == desc);
                assert(rxq_ctrl->rxq.elts != tmpl.rxq.elts);
                ret = rxq_alloc_elts(&tmpl, desc, rxq_ctrl->rxq.elts);
        } else
@@ -1246,6 +1251,19 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
                }
                (*priv->rxqs)[idx] = NULL;
                rxq_cleanup(rxq_ctrl);
+               /* Resize if rxq size is changed. */
+               if (rxq_ctrl->rxq.elts_n != log2above(desc)) {
+                       rxq_ctrl = rte_realloc(rxq_ctrl,
+                                              sizeof(*rxq_ctrl) +
+                                              desc * sizeof(struct rte_mbuf *),
+                                              RTE_CACHE_LINE_SIZE);
+                       if (!rxq_ctrl) {
+                               ERROR("%p: unable to reallocate queue index %u",
+                                       (void *)dev, idx);
+                               priv_unlock(priv);
+                               return -ENOMEM;
+                       }
+               }
        } else {
                rxq_ctrl = rte_calloc_socket("RXQ", 1, sizeof(*rxq_ctrl) +
                                             desc * sizeof(struct rte_mbuf *),