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 * $FreeBSD$ 26 */ 27 28 #include <dev/mlx5/driver.h> 29 #include "wq.h" 30 #include "mlx5_core.h" 31 32 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 33 { 34 return (u32)wq->sz_m1 + 1; 35 } 36 37 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 38 { 39 return wq->sz_m1 + 1; 40 } 41 42 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 43 { 44 return (u32)wq->sz_m1 + 1; 45 } 46 47 static u32 mlx5_wq_cyc_get_byte_size(struct mlx5_wq_cyc *wq) 48 { 49 return mlx5_wq_cyc_get_size(wq) << wq->log_stride; 50 } 51 52 static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq) 53 { 54 return mlx5_cqwq_get_size(wq) << wq->log_stride; 55 } 56 57 static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq) 58 { 59 return mlx5_wq_ll_get_size(wq) << wq->log_stride; 60 } 61 62 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 63 void *wqc, struct mlx5_wq_cyc *wq, 64 struct mlx5_wq_ctrl *wq_ctrl) 65 { 66 int max_direct = param->linear ? INT_MAX : 0; 67 int err; 68 69 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 70 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 71 72 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node); 73 if (err) { 74 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 75 return err; 76 } 77 78 err = mlx5_buf_alloc_node(mdev, mlx5_wq_cyc_get_byte_size(wq), 79 max_direct, &wq_ctrl->buf, 80 param->buf_numa_node); 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_node(mdev, &wq_ctrl->db, param->db_numa_node); 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_node(mdev, mlx5_cqwq_get_byte_size(wq), 117 max_direct, &wq_ctrl->buf, 118 param->buf_numa_node); 119 if (err) { 120 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 121 goto err_db_free; 122 } 123 124 wq->buf = wq_ctrl->buf.direct.buf; 125 wq->db = wq_ctrl->db.db; 126 127 wq_ctrl->mdev = mdev; 128 129 return 0; 130 131 err_db_free: 132 mlx5_db_free(mdev, &wq_ctrl->db); 133 134 return err; 135 } 136 137 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 138 void *wqc, struct mlx5_wq_ll *wq, 139 struct mlx5_wq_ctrl *wq_ctrl) 140 { 141 struct mlx5_wqe_srq_next_seg *next_seg; 142 int max_direct = param->linear ? INT_MAX : 0; 143 int err; 144 int i; 145 146 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 147 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 148 149 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node); 150 if (err) { 151 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 152 return err; 153 } 154 155 err = mlx5_buf_alloc_node(mdev, mlx5_wq_ll_get_byte_size(wq), 156 max_direct, &wq_ctrl->buf, 157 param->buf_numa_node); 158 if (err) { 159 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 160 goto err_db_free; 161 } 162 163 wq->buf = wq_ctrl->buf.direct.buf; 164 wq->db = wq_ctrl->db.db; 165 166 for (i = 0; i < wq->sz_m1; i++) { 167 next_seg = mlx5_wq_ll_get_wqe(wq, i); 168 next_seg->next_wqe_index = cpu_to_be16(i + 1); 169 } 170 next_seg = mlx5_wq_ll_get_wqe(wq, i); 171 wq->tail_next = &next_seg->next_wqe_index; 172 173 wq_ctrl->mdev = mdev; 174 175 return 0; 176 177 err_db_free: 178 mlx5_db_free(mdev, &wq_ctrl->db); 179 180 return err; 181 } 182 183 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl) 184 { 185 mlx5_buf_free(wq_ctrl->mdev, &wq_ctrl->buf); 186 mlx5_db_free(wq_ctrl->mdev, &wq_ctrl->db); 187 } 188