1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33#include <linux/mlx5/driver.h> 34#include "wq.h" 35#include "mlx5_core.h" 36 37u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq) 38{ 39 return (u32)wq->sz_m1 + 1; 40} 41 42u32 mlx5_cqwq_get_size(struct mlx5_cqwq *wq) 43{ 44 return wq->sz_m1 + 1; 45} 46 47u32 mlx5_wq_ll_get_size(struct mlx5_wq_ll *wq) 48{ 49 return (u32)wq->sz_m1 + 1; 50} 51 52static u32 mlx5_wq_cyc_get_byte_size(struct mlx5_wq_cyc *wq) 53{ 54 return mlx5_wq_cyc_get_size(wq) << wq->log_stride; 55} 56 57static u32 mlx5_cqwq_get_byte_size(struct mlx5_cqwq *wq) 58{ 59 return mlx5_cqwq_get_size(wq) << wq->log_stride; 60} 61 62static u32 mlx5_wq_ll_get_byte_size(struct mlx5_wq_ll *wq) 63{ 64 return mlx5_wq_ll_get_size(wq) << wq->log_stride; 65} 66 67int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 68 void *wqc, struct mlx5_wq_cyc *wq, 69 struct mlx5_wq_ctrl *wq_ctrl) 70{ 71 int err; 72 73 wq->log_stride = MLX5_GET(wq, wqc, log_wq_stride); 74 wq->sz_m1 = (1 << MLX5_GET(wq, wqc, log_wq_sz)) - 1; 75 76 err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node); 77 if (err) { 78 mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err); 79 return err; 80 } 81 82 err = mlx5_buf_alloc_node(mdev, mlx5_wq_cyc_get_byte_size(wq), 83 &wq_ctrl->buf, param->buf_numa_node); 84 if (err) { 85 mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err); 86 goto err_db_free; 87 } 88 89 wq->buf = wq_ctrl->buf.direct.buf; 90 wq->db = wq_ctrl->db.db; 91 92 wq_ctrl->mdev = mdev; 93 94 return 0; 95 96err_db_free: 97 mlx5_db_free(mdev, &wq_ctrl->db); 98 99 return err; 100} 101 102int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, 103 void *cqc, struct mlx5_cqwq *wq, 104 struct mlx5_wq_ctrl *wq_ctrl) 105{ 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_node(mdev, &wq_ctrl->db, param->db_numa_node); 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_node(mdev, mlx5_cqwq_get_byte_size(wq), 119 &wq_ctrl->buf, param->buf_numa_node); 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 132err_db_free: 133 mlx5_db_free(mdev, &wq_ctrl->db); 134 135 return err; 136} 137 138int 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 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(mdev, mlx5_wq_ll_get_byte_size(wq), &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 175err_db_free: 176 mlx5_db_free(mdev, &wq_ctrl->db); 177 178 return err; 179} 180 181void 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