xref: /freebsd/sys/dev/mlx5/mlx5_core/mlx5_wq.c (revision 7b9b93a8)
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