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