brintos

brintos / linux-shallow public Read only

0
0
Text · 7.1 KiB · 3091dd0 Raw
262 lines · c
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 two5 * licenses.  You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 *     Redistribution and use in source and binary forms, with or11 *     without modification, are permitted provided that the following12 *     conditions are met:13 *14 *      - Redistributions of source code must retain the above15 *        copyright notice, this list of conditions and the following16 *        disclaimer.17 *18 *      - Redistributions in binary form must reproduce the above19 *        copyright notice, this list of conditions and the following20 *        disclaimer in the documentation and/or other materials21 *        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 OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * SOFTWARE.31 */32 33#include <linux/mlx5/driver.h>34#include "wq.h"35#include "mlx5_core.h"36 37int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,38		       void *wqc, struct mlx5_wq_cyc *wq,39		       struct mlx5_wq_ctrl *wq_ctrl)40{41	u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride);42	u8 log_wq_sz     = MLX5_GET(wq, wqc, log_wq_sz);43	struct mlx5_frag_buf_ctrl *fbc = &wq->fbc;44	int err;45 46	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);47	if (err) {48		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);49		return err;50	}51 52	wq->db  = wq_ctrl->db.db;53 54	err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),55				       &wq_ctrl->buf, param->buf_numa_node);56	if (err) {57		mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);58		goto err_db_free;59	}60 61	mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc);62	wq->sz = mlx5_wq_cyc_get_size(wq);63 64	wq_ctrl->mdev = mdev;65 66	return 0;67 68err_db_free:69	mlx5_db_free(mdev, &wq_ctrl->db);70 71	return err;72}73 74void mlx5_wq_cyc_wqe_dump(struct mlx5_wq_cyc *wq, u16 ix, u8 nstrides)75{76	size_t len;77	void *wqe;78 79	if (!net_ratelimit())80		return;81 82	nstrides = max_t(u8, nstrides, 1);83 84	len = nstrides << wq->fbc.log_stride;85	wqe = mlx5_wq_cyc_get_wqe(wq, ix);86 87	pr_info("WQE DUMP: WQ size %d WQ cur size %d, WQE index 0x%x, len: %zu\n",88		mlx5_wq_cyc_get_size(wq), wq->cur_sz, ix, len);89	print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, wqe, len, false);90}91 92void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq)93{94	wq->wqe_ctr = 0;95	wq->cur_sz = 0;96	mlx5_wq_cyc_update_db_record(wq);97}98 99int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,100		      void *qpc, struct mlx5_wq_qp *wq,101		      struct mlx5_wq_ctrl *wq_ctrl)102{103	u8 log_rq_stride = MLX5_GET(qpc, qpc, log_rq_stride) + 4;104	u8 log_rq_sz     = MLX5_GET(qpc, qpc, log_rq_size);105	u8 log_sq_stride = ilog2(MLX5_SEND_WQE_BB);106	u8 log_sq_sz     = MLX5_GET(qpc, qpc, log_sq_size);107 108	u32 rq_byte_size;109	int err;110 111 112 113	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);114	if (err) {115		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);116		return err;117	}118 119	err = mlx5_frag_buf_alloc_node(mdev,120				       wq_get_byte_sz(log_rq_sz, log_rq_stride) +121				       wq_get_byte_sz(log_sq_sz, log_sq_stride),122				       &wq_ctrl->buf, param->buf_numa_node);123	if (err) {124		mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);125		goto err_db_free;126	}127 128	mlx5_init_fbc(wq_ctrl->buf.frags, log_rq_stride, log_rq_sz, &wq->rq.fbc);129 130	rq_byte_size = wq_get_byte_sz(log_rq_sz, log_rq_stride);131 132	if (rq_byte_size < PAGE_SIZE) {133		/* SQ starts within the same page of the RQ */134		u16 sq_strides_offset = rq_byte_size / MLX5_SEND_WQE_BB;135 136		mlx5_init_fbc_offset(wq_ctrl->buf.frags,137				     log_sq_stride, log_sq_sz, sq_strides_offset,138				     &wq->sq.fbc);139	} else {140		u16 rq_npages = rq_byte_size >> PAGE_SHIFT;141 142		mlx5_init_fbc(wq_ctrl->buf.frags + rq_npages,143			      log_sq_stride, log_sq_sz, &wq->sq.fbc);144	}145 146	wq->rq.db  = &wq_ctrl->db.db[MLX5_RCV_DBR];147	wq->sq.db  = &wq_ctrl->db.db[MLX5_SND_DBR];148 149	wq_ctrl->mdev = mdev;150 151	return 0;152 153err_db_free:154	mlx5_db_free(mdev, &wq_ctrl->db);155 156	return err;157}158 159int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,160		     void *cqc, struct mlx5_cqwq *wq,161		     struct mlx5_wq_ctrl *wq_ctrl)162{163	/* CQE_STRIDE_128 and CQE_STRIDE_128_PAD both mean 128B stride */164	u8 log_wq_stride = MLX5_GET(cqc, cqc, cqe_sz) == CQE_STRIDE_64 ? 6 : 7;165	u8 log_wq_sz     = MLX5_GET(cqc, cqc, log_cq_size);166	int err;167 168	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);169	if (err) {170		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);171		return err;172	}173 174	wq->db  = wq_ctrl->db.db;175 176	err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),177				       &wq_ctrl->buf,178				       param->buf_numa_node);179	if (err) {180		mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n",181			       err);182		goto err_db_free;183	}184 185	mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, &wq->fbc);186 187	wq_ctrl->mdev = mdev;188 189	return 0;190 191err_db_free:192	mlx5_db_free(mdev, &wq_ctrl->db);193 194	return err;195}196 197static void mlx5_wq_ll_init_list(struct mlx5_wq_ll *wq)198{199	struct mlx5_wqe_srq_next_seg *next_seg;200	int i;201 202	for (i = 0; i < wq->fbc.sz_m1; i++) {203		next_seg = mlx5_wq_ll_get_wqe(wq, i);204		next_seg->next_wqe_index = cpu_to_be16(i + 1);205	}206	next_seg = mlx5_wq_ll_get_wqe(wq, i);207	wq->tail_next = &next_seg->next_wqe_index;208}209 210int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,211		      void *wqc, struct mlx5_wq_ll *wq,212		      struct mlx5_wq_ctrl *wq_ctrl)213{214	u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride);215	u8 log_wq_sz     = MLX5_GET(wq, wqc, log_wq_sz);216	struct mlx5_frag_buf_ctrl *fbc = &wq->fbc;217	int err;218 219	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);220	if (err) {221		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);222		return err;223	}224 225	wq->db  = wq_ctrl->db.db;226 227	err = mlx5_frag_buf_alloc_node(mdev, wq_get_byte_sz(log_wq_sz, log_wq_stride),228				       &wq_ctrl->buf, param->buf_numa_node);229	if (err) {230		mlx5_core_warn(mdev, "mlx5_frag_buf_alloc_node() failed, %d\n", err);231		goto err_db_free;232	}233 234	mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc);235 236	mlx5_wq_ll_init_list(wq);237	wq_ctrl->mdev = mdev;238 239	return 0;240 241err_db_free:242	mlx5_db_free(mdev, &wq_ctrl->db);243 244	return err;245}246 247void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq)248{249	wq->head = 0;250	wq->wqe_ctr = 0;251	wq->cur_sz = 0;252	mlx5_wq_ll_init_list(wq);253	mlx5_wq_ll_update_db_record(wq);254}255 256void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl)257{258	mlx5_frag_buf_free(wq_ctrl->mdev, &wq_ctrl->buf);259	mlx5_db_free(wq_ctrl->mdev, &wq_ctrl->db);260}261 262