xref: /linux/drivers/dma/fsl-dpaa2-qdma/dpdmai.c (revision b4ada0618eed0fbd1b1630f73deb048c592b06a1)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright 2019 NXP
3 
4 #include <linux/bitfield.h>
5 #include <linux/module.h>
6 #include <linux/types.h>
7 #include <linux/io.h>
8 #include <linux/fsl/mc.h>
9 #include "dpdmai.h"
10 
11 #define DEST_TYPE_MASK 0xF
12 
13 struct dpdmai_rsp_get_attributes {
14 	__le32 id;
15 	u8 num_of_priorities;
16 	u8 num_of_queues;
17 	u8 pad0[2];
18 	__le16 major;
19 	__le16 minor;
20 };
21 
22 struct dpdmai_cmd_queue {
23 	__le32 dest_id;
24 	u8 dest_priority;
25 	union {
26 		u8 queue;
27 		u8 pri;
28 	};
29 	u8 dest_type;
30 	u8 queue_idx;
31 	__le64 user_ctx;
32 	union {
33 		__le32 options;
34 		__le32 fqid;
35 	};
36 } __packed;
37 
38 struct dpdmai_rsp_get_tx_queue {
39 	__le64 pad;
40 	__le32 fqid;
41 };
42 
43 struct dpdmai_cmd_open {
44 	__le32 dpdmai_id;
45 } __packed;
46 
47 struct dpdmai_cmd_destroy {
48 	__le32 dpdmai_id;
49 } __packed;
50 
51 /**
52  * dpdmai_open() - Open a control session for the specified object
53  * @mc_io:	Pointer to MC portal's I/O object
54  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
55  * @dpdmai_id:	DPDMAI unique ID
56  * @token:	Returned token; use in subsequent API calls
57  *
58  * This function can be used to open a control session for an
59  * already created object; an object may have been declared in
60  * the DPL or by calling the dpdmai_create() function.
61  * This function returns a unique authentication token,
62  * associated with the specific object ID and the specific MC
63  * portal; this token must be used in all subsequent commands for
64  * this specific object.
65  *
66  * Return:	'0' on Success; Error code otherwise.
67  */
68 int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags,
69 		int dpdmai_id, u16 *token)
70 {
71 	struct dpdmai_cmd_open *cmd_params;
72 	struct fsl_mc_command cmd = { 0 };
73 	int err;
74 
75 	/* prepare command */
76 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN,
77 					  cmd_flags, 0);
78 
79 	cmd_params = (struct dpdmai_cmd_open *)&cmd.params;
80 	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);
81 
82 	/* send command to mc*/
83 	err = mc_send_command(mc_io, &cmd);
84 	if (err)
85 		return err;
86 
87 	/* retrieve response parameters */
88 	*token = mc_cmd_hdr_read_token(&cmd);
89 
90 	return 0;
91 }
92 EXPORT_SYMBOL_GPL(dpdmai_open);
93 
94 /**
95  * dpdmai_close() - Close the control session of the object
96  * @mc_io:	Pointer to MC portal's I/O object
97  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
98  * @token:	Token of DPDMAI object
99  *
100  * After this function is called, no further operations are
101  * allowed on the object without opening a new control session.
102  *
103  * Return:	'0' on Success; Error code otherwise.
104  */
105 int dpdmai_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
106 {
107 	struct fsl_mc_command cmd = { 0 };
108 
109 	/* prepare command */
110 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CLOSE,
111 					  cmd_flags, token);
112 
113 	/* send command to mc*/
114 	return mc_send_command(mc_io, &cmd);
115 }
116 EXPORT_SYMBOL_GPL(dpdmai_close);
117 
118 /**
119  * dpdmai_destroy() - Destroy the DPDMAI object and release all its resources.
120  * @mc_io:      Pointer to MC portal's I/O object
121  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
122  * @dpdmai_id:	The object id; it must be a valid id within the container that created this object;
123  * @token:      Token of DPDMAI object
124  *
125  * Return:      '0' on Success; error code otherwise.
126  */
127 int dpdmai_destroy(struct fsl_mc_io *mc_io, u32 cmd_flags, u32 dpdmai_id, u16 token)
128 {
129 	struct dpdmai_cmd_destroy *cmd_params;
130 	struct fsl_mc_command cmd = { 0 };
131 
132 	/* prepare command */
133 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DESTROY,
134 					  cmd_flags, token);
135 
136 	cmd_params = (struct dpdmai_cmd_destroy *)&cmd.params;
137 	cmd_params->dpdmai_id = cpu_to_le32(dpdmai_id);
138 
139 	/* send command to mc*/
140 	return mc_send_command(mc_io, &cmd);
141 }
142 EXPORT_SYMBOL_GPL(dpdmai_destroy);
143 
144 /**
145  * dpdmai_enable() - Enable the DPDMAI, allow sending and receiving frames.
146  * @mc_io:	Pointer to MC portal's I/O object
147  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
148  * @token:	Token of DPDMAI object
149  *
150  * Return:	'0' on Success; Error code otherwise.
151  */
152 int dpdmai_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
153 {
154 	struct fsl_mc_command cmd = { 0 };
155 
156 	/* prepare command */
157 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_ENABLE,
158 					  cmd_flags, token);
159 
160 	/* send command to mc*/
161 	return mc_send_command(mc_io, &cmd);
162 }
163 EXPORT_SYMBOL_GPL(dpdmai_enable);
164 
165 /**
166  * dpdmai_disable() - Disable the DPDMAI, stop sending and receiving frames.
167  * @mc_io:	Pointer to MC portal's I/O object
168  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
169  * @token:	Token of DPDMAI object
170  *
171  * Return:	'0' on Success; Error code otherwise.
172  */
173 int dpdmai_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
174 {
175 	struct fsl_mc_command cmd = { 0 };
176 
177 	/* prepare command */
178 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DISABLE,
179 					  cmd_flags, token);
180 
181 	/* send command to mc*/
182 	return mc_send_command(mc_io, &cmd);
183 }
184 EXPORT_SYMBOL_GPL(dpdmai_disable);
185 
186 /**
187  * dpdmai_reset() - Reset the DPDMAI, returns the object to initial state.
188  * @mc_io:	Pointer to MC portal's I/O object
189  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
190  * @token:	Token of DPDMAI object
191  *
192  * Return:	'0' on Success; Error code otherwise.
193  */
194 int dpdmai_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
195 {
196 	struct fsl_mc_command cmd = { 0 };
197 
198 	/* prepare command */
199 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_RESET,
200 					  cmd_flags, token);
201 
202 	/* send command to mc*/
203 	return mc_send_command(mc_io, &cmd);
204 }
205 EXPORT_SYMBOL_GPL(dpdmai_reset);
206 
207 /**
208  * dpdmai_get_attributes() - Retrieve DPDMAI attributes.
209  * @mc_io:	Pointer to MC portal's I/O object
210  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
211  * @token:	Token of DPDMAI object
212  * @attr:	Returned object's attributes
213  *
214  * Return:	'0' on Success; Error code otherwise.
215  */
216 int dpdmai_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags,
217 			  u16 token, struct dpdmai_attr *attr)
218 {
219 	struct dpdmai_rsp_get_attributes *rsp_params;
220 	struct fsl_mc_command cmd = { 0 };
221 	int err;
222 
223 	/* prepare command */
224 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR,
225 					  cmd_flags, token);
226 
227 	/* send command to mc*/
228 	err = mc_send_command(mc_io, &cmd);
229 	if (err)
230 		return err;
231 
232 	/* retrieve response parameters */
233 	rsp_params = (struct dpdmai_rsp_get_attributes *)cmd.params;
234 	attr->id = le32_to_cpu(rsp_params->id);
235 	attr->version.major = le16_to_cpu(rsp_params->major);
236 	attr->version.minor = le16_to_cpu(rsp_params->minor);
237 	attr->num_of_priorities = rsp_params->num_of_priorities;
238 	attr->num_of_queues = rsp_params->num_of_queues;
239 
240 	return 0;
241 }
242 EXPORT_SYMBOL_GPL(dpdmai_get_attributes);
243 
244 /**
245  * dpdmai_set_rx_queue() - Set Rx queue configuration
246  * @mc_io:	Pointer to MC portal's I/O object
247  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
248  * @token:	Token of DPDMAI object
249  * @queue_idx:	DMA queue index
250  * @priority:	Select the queue relative to number of
251  *		priorities configured at DPDMAI creation
252  * @cfg:	Rx queue configuration
253  *
254  * Return:	'0' on Success; Error code otherwise.
255  */
256 int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,
257 			u8 priority, const struct dpdmai_rx_queue_cfg *cfg)
258 {
259 	struct dpdmai_cmd_queue *cmd_params;
260 	struct fsl_mc_command cmd = { 0 };
261 
262 	/* prepare command */
263 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE,
264 					  cmd_flags, token);
265 
266 	cmd_params = (struct dpdmai_cmd_queue *)cmd.params;
267 	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
268 	cmd_params->dest_priority = cfg->dest_cfg.priority;
269 	cmd_params->pri = priority;
270 	cmd_params->dest_type = cfg->dest_cfg.dest_type;
271 	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
272 	cmd_params->options = cpu_to_le32(cfg->options);
273 	cmd_params->queue_idx = queue_idx;
274 
275 	/* send command to mc*/
276 	return mc_send_command(mc_io, &cmd);
277 }
278 EXPORT_SYMBOL_GPL(dpdmai_set_rx_queue);
279 
280 /**
281  * dpdmai_get_rx_queue() - Retrieve Rx queue attributes.
282  * @mc_io:	Pointer to MC portal's I/O object
283  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
284  * @token:	Token of DPDMAI object
285  * @queue_idx:	DMA Queue index
286  * @priority:	Select the queue relative to number of
287  *				priorities configured at DPDMAI creation
288  * @attr:	Returned Rx queue attributes
289  *
290  * Return:	'0' on Success; Error code otherwise.
291  */
292 int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 queue_idx,
293 			u8 priority, struct dpdmai_rx_queue_attr *attr)
294 {
295 	struct dpdmai_cmd_queue *cmd_params;
296 	struct fsl_mc_command cmd = { 0 };
297 	int err;
298 
299 	/* prepare command */
300 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE,
301 					  cmd_flags, token);
302 
303 	cmd_params = (struct dpdmai_cmd_queue *)cmd.params;
304 	cmd_params->queue = priority;
305 	cmd_params->queue_idx = queue_idx;
306 
307 	/* send command to mc*/
308 	err = mc_send_command(mc_io, &cmd);
309 	if (err)
310 		return err;
311 
312 	/* retrieve response parameters */
313 	attr->dest_cfg.dest_id = le32_to_cpu(cmd_params->dest_id);
314 	attr->dest_cfg.priority = cmd_params->dest_priority;
315 	attr->dest_cfg.dest_type = FIELD_GET(DEST_TYPE_MASK, cmd_params->dest_type);
316 	attr->user_ctx = le64_to_cpu(cmd_params->user_ctx);
317 	attr->fqid = le32_to_cpu(cmd_params->fqid);
318 
319 	return 0;
320 }
321 EXPORT_SYMBOL_GPL(dpdmai_get_rx_queue);
322 
323 /**
324  * dpdmai_get_tx_queue() - Retrieve Tx queue attributes.
325  * @mc_io:	Pointer to MC portal's I/O object
326  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
327  * @token:	Token of DPDMAI object
328  * @queue_idx:	DMA queue index
329  * @priority:	Select the queue relative to number of
330  *			priorities configured at DPDMAI creation
331  * @attr:	Returned DMA Tx queue attributes
332  *
333  * Return:	'0' on Success; Error code otherwise.
334  */
335 int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags,
336 			u16 token, u8 queue_idx, u8 priority, struct dpdmai_tx_queue_attr *attr)
337 {
338 	struct dpdmai_rsp_get_tx_queue *rsp_params;
339 	struct dpdmai_cmd_queue *cmd_params;
340 	struct fsl_mc_command cmd = { 0 };
341 	int err;
342 
343 	/* prepare command */
344 	cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE,
345 					  cmd_flags, token);
346 
347 	cmd_params = (struct dpdmai_cmd_queue *)cmd.params;
348 	cmd_params->queue = priority;
349 	cmd_params->queue_idx = queue_idx;
350 
351 	/* send command to mc*/
352 	err = mc_send_command(mc_io, &cmd);
353 	if (err)
354 		return err;
355 
356 	/* retrieve response parameters */
357 
358 	rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params;
359 	attr->fqid = le32_to_cpu(rsp_params->fqid);
360 
361 	return 0;
362 }
363 EXPORT_SYMBOL_GPL(dpdmai_get_tx_queue);
364 
365 MODULE_DESCRIPTION("NXP DPAA2 QDMA driver");
366 MODULE_LICENSE("GPL v2");
367