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 "opt_rss.h" 29 #include "opt_ratelimit.h" 30 31 #include <dev/mlx5/driver.h> 32 #include <dev/mlx5/mlx5_core/wq.h> 33 #include <dev/mlx5/mlx5_core/mlx5_core.h> 34 35 u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 36 { 37 return (u32)wq->sz_m1 + 1; 38 } 39 40 u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 41 { 42 return wq->sz_m1 + 1; 43 } 44 45 u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 46 { 47 return (u32)wq->sz_m1 + 1; 48 } 49 50 static u32 mlx5_wq_cyc_get_byte_size(struct mlx5_wq_cyc *wq) 51 { 52 return mlx5_wq_cyc_get_size(wq) << wq->log_stride; 53 } 54 55 static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq) 56 { 57 return mlx5_cqwq_get_size(wq) << wq->log_stride; 58 } 59 60 static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq) 61 { 62 return mlx5_wq_ll_get_size(wq) << wq->log_stride; 63 } 64 65 int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 66 void *wqc, struct mlx5_wq_cyc *wq, 67 struct mlx5_wq_ctrl *wq_ctrl) 68 { 69 int max_direct = param->linear ? INT_MAX : 0; 70 int err; 71 72 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 73 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 74 75 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 76 if (err) { 77 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 78 return err; 79 } 80 81 err = mlx5_buf_alloc(mdev, mlx5_wq_cyc_get_byte_size(wq), 82 max_direct, &wq_ctrl->buf); 83 if (err) { 84 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 85 goto err_db_free; 86 } 87 88 wq->buf = wq_ctrl->buf.direct.buf; 89 wq->db = wq_ctrl->db.db; 90 91 wq_ctrl->mdev = mdev; 92 93 return 0; 94 95 err_db_free: 96 mlx5_db_free(mdev, &wq_ctrl->db); 97 98 return err; 99 } 100 101 int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 102 void *cqc, struct mlx5_cqwq *wq, 103 struct mlx5_wq_ctrl *wq_ctrl) 104 { 105 int max_direct = param->linear ? INT_MAX : 0; 106 int err; 107 108 wq->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz); 109 wq->log_sz = MLX5_GET(cqc, cqc, log_cq_size); 110 wq->sz_m1 = (1 << wq->log_sz) - 1; 111 112 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 113 if (err) { 114 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 115 return err; 116 } 117 118 err = mlx5_buf_alloc(mdev, mlx5_cqwq_get_byte_size(wq), 119 max_direct, &wq_ctrl->buf); 120 if (err) { 121 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 122 goto err_db_free; 123 } 124 125 wq->buf = wq_ctrl->buf.direct.buf; 126 wq->db = wq_ctrl->db.db; 127 128 wq_ctrl->mdev = mdev; 129 130 return 0; 131 132 err_db_free: 133 mlx5_db_free(mdev, &wq_ctrl->db); 134 135 return err; 136 } 137 138 int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 139 void *wqc, struct mlx5_wq_ll *wq, 140 struct mlx5_wq_ctrl *wq_ctrl) 141 { 142 struct mlx5_wqe_srq_next_seg *next_seg; 143 int max_direct = param->linear ? INT_MAX : 0; 144 int err; 145 int i; 146 147 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 148 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 149 150 err = mlx5_db_alloc(mdev, &wq_ctrl->db); 151 if (err) { 152 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 153 return err; 154 } 155 156 err = mlx5_buf_alloc(mdev, mlx5_wq_ll_get_byte_size(wq), 157 max_direct, &wq_ctrl->buf); 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