Merge tag 'block-5.18-2022-04-15' of git://git.kernel.dk/linux-block
[sfrench/cifs-2.6.git] / drivers / infiniband / hw / mlx5 / cmd.c
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /*
3  * Copyright (c) 2017-2020, Mellanox Technologies inc. All rights reserved.
4  */
5
6 #include "cmd.h"
7
8 int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey)
9 {
10         u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {};
11         u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {};
12         int err;
13
14         MLX5_SET(query_special_contexts_in, in, opcode,
15                  MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
16         err = mlx5_cmd_exec_inout(dev, query_special_contexts, in, out);
17         if (!err)
18                 *mkey = MLX5_GET(query_special_contexts_out, out,
19                                  dump_fill_mkey);
20         return err;
21 }
22
23 int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey)
24 {
25         u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {};
26         u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {};
27         int err;
28
29         MLX5_SET(query_special_contexts_in, in, opcode,
30                  MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
31         err = mlx5_cmd_exec_inout(dev, query_special_contexts, in, out);
32         if (!err)
33                 *null_mkey = MLX5_GET(query_special_contexts_out, out,
34                                       null_mkey);
35         return err;
36 }
37
38 int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
39                                void *out)
40 {
41         u32 in[MLX5_ST_SZ_DW(query_cong_params_in)] = {};
42
43         MLX5_SET(query_cong_params_in, in, opcode,
44                  MLX5_CMD_OP_QUERY_CONG_PARAMS);
45         MLX5_SET(query_cong_params_in, in, cong_protocol, cong_point);
46
47         return mlx5_cmd_exec_inout(dev, query_cong_params, in, out);
48 }
49
50 void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid)
51 {
52         u32 in[MLX5_ST_SZ_DW(destroy_tir_in)] = {};
53
54         MLX5_SET(destroy_tir_in, in, opcode, MLX5_CMD_OP_DESTROY_TIR);
55         MLX5_SET(destroy_tir_in, in, tirn, tirn);
56         MLX5_SET(destroy_tir_in, in, uid, uid);
57         mlx5_cmd_exec_in(dev, destroy_tir, in);
58 }
59
60 void mlx5_cmd_destroy_tis(struct mlx5_core_dev *dev, u32 tisn, u16 uid)
61 {
62         u32 in[MLX5_ST_SZ_DW(destroy_tis_in)] = {};
63
64         MLX5_SET(destroy_tis_in, in, opcode, MLX5_CMD_OP_DESTROY_TIS);
65         MLX5_SET(destroy_tis_in, in, tisn, tisn);
66         MLX5_SET(destroy_tis_in, in, uid, uid);
67         mlx5_cmd_exec_in(dev, destroy_tis, in);
68 }
69
70 int mlx5_cmd_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn, u16 uid)
71 {
72         u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)] = {};
73
74         MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
75         MLX5_SET(destroy_rqt_in, in, rqtn, rqtn);
76         MLX5_SET(destroy_rqt_in, in, uid, uid);
77         return mlx5_cmd_exec_in(dev, destroy_rqt, in);
78 }
79
80 int mlx5_cmd_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn,
81                                     u16 uid)
82 {
83         u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {};
84         u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {};
85         int err;
86
87         MLX5_SET(alloc_transport_domain_in, in, opcode,
88                  MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN);
89         MLX5_SET(alloc_transport_domain_in, in, uid, uid);
90
91         err = mlx5_cmd_exec_inout(dev, alloc_transport_domain, in, out);
92         if (!err)
93                 *tdn = MLX5_GET(alloc_transport_domain_out, out,
94                                 transport_domain);
95
96         return err;
97 }
98
99 void mlx5_cmd_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn,
100                                        u16 uid)
101 {
102         u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)] = {};
103
104         MLX5_SET(dealloc_transport_domain_in, in, opcode,
105                  MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
106         MLX5_SET(dealloc_transport_domain_in, in, uid, uid);
107         MLX5_SET(dealloc_transport_domain_in, in, transport_domain, tdn);
108         mlx5_cmd_exec_in(dev, dealloc_transport_domain, in);
109 }
110
111 int mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid)
112 {
113         u32 in[MLX5_ST_SZ_DW(dealloc_pd_in)] = {};
114
115         MLX5_SET(dealloc_pd_in, in, opcode, MLX5_CMD_OP_DEALLOC_PD);
116         MLX5_SET(dealloc_pd_in, in, pd, pdn);
117         MLX5_SET(dealloc_pd_in, in, uid, uid);
118         return mlx5_cmd_exec_in(dev, dealloc_pd, in);
119 }
120
121 int mlx5_cmd_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
122                         u32 qpn, u16 uid)
123 {
124         u32 in[MLX5_ST_SZ_DW(attach_to_mcg_in)] = {};
125         void *gid;
126
127         MLX5_SET(attach_to_mcg_in, in, opcode, MLX5_CMD_OP_ATTACH_TO_MCG);
128         MLX5_SET(attach_to_mcg_in, in, qpn, qpn);
129         MLX5_SET(attach_to_mcg_in, in, uid, uid);
130         gid = MLX5_ADDR_OF(attach_to_mcg_in, in, multicast_gid);
131         memcpy(gid, mgid, sizeof(*mgid));
132         return mlx5_cmd_exec_in(dev, attach_to_mcg, in);
133 }
134
135 int mlx5_cmd_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
136                         u32 qpn, u16 uid)
137 {
138         u32 in[MLX5_ST_SZ_DW(detach_from_mcg_in)] = {};
139         void *gid;
140
141         MLX5_SET(detach_from_mcg_in, in, opcode, MLX5_CMD_OP_DETACH_FROM_MCG);
142         MLX5_SET(detach_from_mcg_in, in, qpn, qpn);
143         MLX5_SET(detach_from_mcg_in, in, uid, uid);
144         gid = MLX5_ADDR_OF(detach_from_mcg_in, in, multicast_gid);
145         memcpy(gid, mgid, sizeof(*mgid));
146         return mlx5_cmd_exec_in(dev, detach_from_mcg, in);
147 }
148
149 int mlx5_cmd_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn, u16 uid)
150 {
151         u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)] = {};
152         u32 in[MLX5_ST_SZ_DW(alloc_xrcd_in)] = {};
153         int err;
154
155         MLX5_SET(alloc_xrcd_in, in, opcode, MLX5_CMD_OP_ALLOC_XRCD);
156         MLX5_SET(alloc_xrcd_in, in, uid, uid);
157         err = mlx5_cmd_exec_inout(dev, alloc_xrcd, in, out);
158         if (!err)
159                 *xrcdn = MLX5_GET(alloc_xrcd_out, out, xrcd);
160         return err;
161 }
162
163 int mlx5_cmd_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn, u16 uid)
164 {
165         u32 in[MLX5_ST_SZ_DW(dealloc_xrcd_in)] = {};
166
167         MLX5_SET(dealloc_xrcd_in, in, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
168         MLX5_SET(dealloc_xrcd_in, in, xrcd, xrcdn);
169         MLX5_SET(dealloc_xrcd_in, in, uid, uid);
170         return mlx5_cmd_exec_in(dev, dealloc_xrcd, in);
171 }
172
173 int mlx5_cmd_mad_ifc(struct mlx5_core_dev *dev, const void *inb, void *outb,
174                      u16 opmod, u8 port)
175 {
176         int outlen = MLX5_ST_SZ_BYTES(mad_ifc_out);
177         int inlen = MLX5_ST_SZ_BYTES(mad_ifc_in);
178         int err = -ENOMEM;
179         void *data;
180         void *resp;
181         u32 *out;
182         u32 *in;
183
184         in = kzalloc(inlen, GFP_KERNEL);
185         out = kzalloc(outlen, GFP_KERNEL);
186         if (!in || !out)
187                 goto out;
188
189         MLX5_SET(mad_ifc_in, in, opcode, MLX5_CMD_OP_MAD_IFC);
190         MLX5_SET(mad_ifc_in, in, op_mod, opmod);
191         MLX5_SET(mad_ifc_in, in, port, port);
192
193         data = MLX5_ADDR_OF(mad_ifc_in, in, mad);
194         memcpy(data, inb, MLX5_FLD_SZ_BYTES(mad_ifc_in, mad));
195
196         err = mlx5_cmd_exec_inout(dev, mad_ifc, in, out);
197         if (err)
198                 goto out;
199
200         resp = MLX5_ADDR_OF(mad_ifc_out, out, response_mad_packet);
201         memcpy(outb, resp,
202                MLX5_FLD_SZ_BYTES(mad_ifc_out, response_mad_packet));
203
204 out:
205         kfree(out);
206         kfree(in);
207         return err;
208 }
209
210 int mlx5_cmd_uar_alloc(struct mlx5_core_dev *dev, u32 *uarn, u16 uid)
211 {
212         u32 out[MLX5_ST_SZ_DW(alloc_uar_out)] = {};
213         u32 in[MLX5_ST_SZ_DW(alloc_uar_in)] = {};
214         int err;
215
216         MLX5_SET(alloc_uar_in, in, opcode, MLX5_CMD_OP_ALLOC_UAR);
217         MLX5_SET(alloc_uar_in, in, uid, uid);
218         err = mlx5_cmd_exec_inout(dev, alloc_uar, in, out);
219         if (err)
220                 return err;
221
222         *uarn = MLX5_GET(alloc_uar_out, out, uar);
223         return 0;
224 }
225
226 int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 uarn, u16 uid)
227 {
228         u32 in[MLX5_ST_SZ_DW(dealloc_uar_in)] = {};
229
230         MLX5_SET(dealloc_uar_in, in, opcode, MLX5_CMD_OP_DEALLOC_UAR);
231         MLX5_SET(dealloc_uar_in, in, uar, uarn);
232         MLX5_SET(dealloc_uar_in, in, uid, uid);
233         return mlx5_cmd_exec_in(dev, dealloc_uar, in);
234 }