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(mdev, &wq_ctrl->db); 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(mdev, mlx5_wq_cyc_get_byte_size(wq), 79 max_direct, &wq_ctrl->buf); 80 if (err) { 81 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 82 goto err_db_free; 83 } 84 85 wq->buf = wq_ctrl->buf.direct.buf; 86 wq->db = wq_ctrl->db.db; 87 88 wq_ctrl->mdev = mdev; 89 90 return 0; 91 92 err_db_free: 93 mlx5_db_free(mdev, &wq_ctrl->db); 94 95 return err; 96 } 97 98 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 99 void *cqc, struct mlx5_cqwq *wq, 100 struct mlx5_wq_ctrl *wq_ctrl) 101 { 102 int max_direct = param->linear ? INT_MAX : 0; 103 int err; 104 105 wq->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz); 106 wq->log_sz = MLX5_GET(cqc, cqc, log_cq_size); 107 wq->sz_m1 = (1 << wq->log_sz) - 1; 108 109 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 110 if (err) { 111 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 112 return err; 113 } 114 115 err = mlx5_buf_alloc(mdev, mlx5_cqwq_get_byte_size(wq), 116 max_direct, &wq_ctrl->buf); 117 if (err) { 118 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 119 goto err_db_free; 120 } 121 122 wq->buf = wq_ctrl->buf.direct.buf; 123 wq->db = wq_ctrl->db.db; 124 125 wq_ctrl->mdev = mdev; 126 127 return 0; 128 129 err_db_free: 130 mlx5_db_free(mdev, &wq_ctrl->db); 131 132 return err; 133 } 134 135 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 136 void *wqc, struct mlx5_wq_ll *wq, 137 struct mlx5_wq_ctrl *wq_ctrl) 138 { 139 struct mlx5_wqe_srq_next_seg *next_seg; 140 int max_direct = param->linear ? INT_MAX : 0; 141 int err; 142 int i; 143 144 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 145 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 146 147 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 148 if (err) { 149 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 150 return err; 151 } 152 153 err = mlx5_buf_alloc(mdev, mlx5_wq_ll_get_byte_size(wq), 154 max_direct, &wq_ctrl->buf); 155 if (err) { 156 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 157 goto err_db_free; 158 } 159 160 wq->buf = wq_ctrl->buf.direct.buf; 161 wq->db = wq_ctrl->db.db; 162 163 for (i = 0; i < wq->sz_m1; i++) { 164 next_seg = mlx5_wq_ll_get_wqe(wq, i); 165 next_seg->next_wqe_index = cpu_to_be16(i + 1); 166 } 167 next_seg = mlx5_wq_ll_get_wqe(wq, i); 168 wq->tail_next = &next_seg->next_wqe_index; 169 170 wq_ctrl->mdev = mdev; 171 172 return 0; 173 174 err_db_free: 175 mlx5_db_free(mdev, &wq_ctrl->db); 176 177 return err; 178 } 179 180 void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl) 181 { 182 mlx5_buf_free(wq_ctrl->mdev, &wq_ctrl->buf); 183 mlx5_db_free(wq_ctrl->mdev, &wq_ctrl->db); 184 } 185