1 /*- 2 * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include "opt_rss.h" 27 #include "opt_ratelimit.h" 28 29 #include <dev/mlx5/driver.h> 30 #include <dev/mlx5/mlx5_core/wq.h> 31 #include <dev/mlx5/mlx5_core/mlx5_core.h> 32 33 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 34 { 35 return (u32)wq->sz_m1 + 1; 36 } 37 38 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 39 { 40 return wq->sz_m1 + 1; 41 } 42 43 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 44 { 45 return (u32)wq->sz_m1 + 1; 46 } 47 48 static u32 mlx5_wq_cyc_get_byte_size(struct mlx5_wq_cyc *wq) 49 { 50 return mlx5_wq_cyc_get_size(wq) << wq->log_stride; 51 } 52 53 static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq) 54 { 55 return mlx5_cqwq_get_size(wq) << wq->log_stride; 56 } 57 58 static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq) 59 { 60 return mlx5_wq_ll_get_size(wq) << wq->log_stride; 61 } 62 63 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 64 void *wqc, struct mlx5_wq_cyc *wq, 65 struct mlx5_wq_ctrl *wq_ctrl) 66 { 67 int max_direct = param->linear ? INT_MAX : 0; 68 int err; 69 70 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 71 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 72 73 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 74 if (err) { 75 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 76 return err; 77 } 78 79 err = mlx5_buf_alloc(mdev, mlx5_wq_cyc_get_byte_size(wq), 80 max_direct, &wq_ctrl->buf); 81 if (err) { 82 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 83 goto err_db_free; 84 } 85 86 wq->buf = wq_ctrl->buf.direct.buf; 87 wq->db = wq_ctrl->db.db; 88 89 wq_ctrl->mdev = mdev; 90 91 return 0; 92 93 err_db_free: 94 mlx5_db_free(mdev, &wq_ctrl->db); 95 96 return err; 97 } 98 99 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 100 void *cqc, struct mlx5_cqwq *wq, 101 struct mlx5_wq_ctrl *wq_ctrl) 102 { 103 int max_direct = param->linear ? INT_MAX : 0; 104 int err; 105 106 wq->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz); 107 wq->log_sz = MLX5_GET(cqc, cqc, log_cq_size); 108 wq->sz_m1 = (1 << wq->log_sz) - 1; 109 110 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 111 if (err) { 112 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 113 return err; 114 } 115 116 err = mlx5_buf_alloc(mdev, mlx5_cqwq_get_byte_size(wq), 117 max_direct, &wq_ctrl->buf); 118 if (err) { 119 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 120 goto err_db_free; 121 } 122 123 wq->buf = wq_ctrl->buf.direct.buf; 124 wq->db = wq_ctrl->db.db; 125 126 wq_ctrl->mdev = mdev; 127 128 return 0; 129 130 err_db_free: 131 mlx5_db_free(mdev, &wq_ctrl->db); 132 133 return err; 134 } 135 136 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 137 void *wqc, struct mlx5_wq_ll *wq, 138 struct mlx5_wq_ctrl *wq_ctrl) 139 { 140 struct mlx5_wqe_srq_next_seg *next_seg; 141 int max_direct = param->linear ? INT_MAX : 0; 142 int err; 143 int i; 144 145 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 146 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 147 148 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 149 if (err) { 150 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 151 return err; 152 } 153 154 err = mlx5_buf_alloc(mdev, mlx5_wq_ll_get_byte_size(wq), 155 max_direct, &wq_ctrl->buf); 156 if (err) { 157 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 158 goto err_db_free; 159 } 160 161 wq->buf = wq_ctrl->buf.direct.buf; 162 wq->db = wq_ctrl->db.db; 163 164 for (i = 0; i < wq->sz_m1; i++) { 165 next_seg = mlx5_wq_ll_get_wqe(wq, i); 166 next_seg->next_wqe_index = cpu_to_be16(i + 1); 167 } 168 next_seg = mlx5_wq_ll_get_wqe(wq, i); 169 wq->tail_next = &next_seg->next_wqe_index; 170 171 wq_ctrl->mdev = mdev; 172 173 return 0; 174 175 err_db_free: 176 mlx5_db_free(mdev, &wq_ctrl->db); 177 178 return err; 179 } 180 181 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl) 182 { 183 mlx5_buf_free(wq_ctrl->mdev, &wq_ctrl->buf); 184 mlx5_db_free(wq_ctrl->mdev, &wq_ctrl->db); 185 } 186