]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net/mlx5e: Reset RQ doorbell counter before moving RQ state from RST to RDY
authorAya Levin <ayal@mellanox.com>
Mon, 9 Dec 2019 12:08:18 +0000 (14:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Feb 2020 16:22:28 +0000 (17:22 +0100)
commit 5ee090ed0da649b1febae2b7c285ac77d1e55a0c upstream.

Initialize RQ doorbell counters to zero prior to moving an RQ from RST
to RDY state. Per HW spec, when RQ is back to RDY state, the descriptor
ID on the completion is reset. The doorbell record must comply.

Fixes: 8276ea1353a4 ("net/mlx5e: Report and recover from CQE with error on RQ")
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reported-by: Tariq Toukan <tariqt@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/wq.c
drivers/net/ethernet/mellanox/mlx5/core/wq.h

index 7c8796d9743fa5a6c66f4aa3e0017b800a121a9b..a226277b09805a75a107e069db46801ffa1c454c 100644 (file)
@@ -179,6 +179,14 @@ mlx5e_tx_dma_unmap(struct device *pdev, struct mlx5e_sq_dma *dma)
        }
 }
 
+static inline void mlx5e_rqwq_reset(struct mlx5e_rq *rq)
+{
+       if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ)
+               mlx5_wq_ll_reset(&rq->mpwqe.wq);
+       else
+               mlx5_wq_cyc_reset(&rq->wqe.wq);
+}
+
 /* SW parser related functions */
 
 struct mlx5e_swp_spec {
index 29a5a8c894e3937b9d099167b417ec7dea485674..e5e91cbcbc31916b65e0633fcea8ec765f482f81 100644 (file)
@@ -723,6 +723,9 @@ int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_state)
        if (!in)
                return -ENOMEM;
 
+       if (curr_state == MLX5_RQC_STATE_RST && next_state == MLX5_RQC_STATE_RDY)
+               mlx5e_rqwq_reset(rq);
+
        rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
 
        MLX5_SET(modify_rq_in, in, rq_state, curr_state);
index dd2315ce4441fefe5db27fdcd5c75bf8e6d9e1be..41e35b341b7098343c24409bef44620cb68b2948 100644 (file)
@@ -96,6 +96,13 @@ err_db_free:
        return err;
 }
 
+void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq)
+{
+       wq->wqe_ctr = 0;
+       wq->cur_sz = 0;
+       mlx5_wq_cyc_update_db_record(wq);
+}
+
 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      void *qpc, struct mlx5_wq_qp *wq,
                      struct mlx5_wq_ctrl *wq_ctrl)
@@ -194,6 +201,19 @@ err_db_free:
        return err;
 }
 
+static void mlx5_wq_ll_init_list(struct mlx5_wq_ll *wq)
+{
+       struct mlx5_wqe_srq_next_seg *next_seg;
+       int i;
+
+       for (i = 0; i < wq->fbc.sz_m1; i++) {
+               next_seg = mlx5_wq_ll_get_wqe(wq, i);
+               next_seg->next_wqe_index = cpu_to_be16(i + 1);
+       }
+       next_seg = mlx5_wq_ll_get_wqe(wq, i);
+       wq->tail_next = &next_seg->next_wqe_index;
+}
+
 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      void *wqc, struct mlx5_wq_ll *wq,
                      struct mlx5_wq_ctrl *wq_ctrl)
@@ -201,9 +221,7 @@ int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
        u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride);
        u8 log_wq_sz     = MLX5_GET(wq, wqc, log_wq_sz);
        struct mlx5_frag_buf_ctrl *fbc = &wq->fbc;
-       struct mlx5_wqe_srq_next_seg *next_seg;
        int err;
-       int i;
 
        err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
        if (err) {
@@ -222,13 +240,7 @@ int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
 
        mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc);
 
-       for (i = 0; i < fbc->sz_m1; i++) {
-               next_seg = mlx5_wq_ll_get_wqe(wq, i);
-               next_seg->next_wqe_index = cpu_to_be16(i + 1);
-       }
-       next_seg = mlx5_wq_ll_get_wqe(wq, i);
-       wq->tail_next = &next_seg->next_wqe_index;
-
+       mlx5_wq_ll_init_list(wq);
        wq_ctrl->mdev = mdev;
 
        return 0;
@@ -239,6 +251,15 @@ err_db_free:
        return err;
 }
 
+void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq)
+{
+       wq->head = 0;
+       wq->wqe_ctr = 0;
+       wq->cur_sz = 0;
+       mlx5_wq_ll_init_list(wq);
+       mlx5_wq_ll_update_db_record(wq);
+}
+
 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl)
 {
        mlx5_frag_buf_free(wq_ctrl->mdev, &wq_ctrl->buf);
index 55791f71a7785f461d34fa8b52c7babe85145e5b..5efc038440df8be40f60a10eaf6531cc8125ce49 100644 (file)
@@ -80,10 +80,12 @@ int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                       void *wqc, struct mlx5_wq_cyc *wq,
                       struct mlx5_wq_ctrl *wq_ctrl);
 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq);
+void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq);
 
 int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      void *qpc, struct mlx5_wq_qp *wq,
                      struct mlx5_wq_ctrl *wq_ctrl);
+void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq);
 
 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                     void *cqc, struct mlx5_cqwq *wq,