New upstream version 17.11-rc3
[deb_dpdk.git] / drivers / bus / fslmc / mc / dpci.c
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  *   BSD LICENSE
6  *
7  * Copyright 2013-2016 Freescale Semiconductor Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * * Neither the name of the above-listed copyright holders nor the
17  * names of any contributors may be used to endorse or promote products
18  * derived from this software without specific prior written permission.
19  *
20  *   GPL LICENSE SUMMARY
21  *
22  * ALTERNATIVELY, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") as published by the Free Software
24  * Foundation, either version 2 of that License or (at your option) any
25  * later version.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 #include <fsl_mc_sys.h>
40 #include <fsl_mc_cmd.h>
41 #include <fsl_dpci.h>
42 #include <fsl_dpci_cmd.h>
43
44 /**
45  * dpci_open() - Open a control session for the specified object
46  * @mc_io:      Pointer to MC portal's I/O object
47  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
48  * @dpci_id:    DPCI unique ID
49  * @token:      Returned token; use in subsequent API calls
50  *
51  * This function can be used to open a control session for an
52  * already created object; an object may have been declared in
53  * the DPL or by calling the dpci_create() function.
54  * This function returns a unique authentication token,
55  * associated with the specific object ID and the specific MC
56  * portal; this token must be used in all subsequent commands for
57  * this specific object.
58  *
59  * Return:      '0' on Success; Error code otherwise.
60  */
61 int dpci_open(struct fsl_mc_io *mc_io,
62               uint32_t cmd_flags,
63               int dpci_id,
64               uint16_t *token)
65 {
66         struct dpci_cmd_open *cmd_params;
67         struct mc_command cmd = { 0 };
68         int err;
69
70         /* prepare command */
71         cmd.header = mc_encode_cmd_header(DPCI_CMDID_OPEN,
72                                           cmd_flags,
73                                           0);
74         cmd_params = (struct dpci_cmd_open *)cmd.params;
75         cmd_params->dpci_id = cpu_to_le32(dpci_id);
76
77         /* send command to mc*/
78         err = mc_send_command(mc_io, &cmd);
79         if (err)
80                 return err;
81
82         /* retrieve response parameters */
83         *token = mc_cmd_hdr_read_token(&cmd);
84
85         return 0;
86 }
87
88 /**
89  * dpci_close() - Close the control session of the object
90  * @mc_io:      Pointer to MC portal's I/O object
91  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
92  * @token:      Token of DPCI object
93  *
94  * After this function is called, no further operations are
95  * allowed on the object without opening a new control session.
96  *
97  * Return:      '0' on Success; Error code otherwise.
98  */
99 int dpci_close(struct fsl_mc_io *mc_io,
100                uint32_t cmd_flags,
101                uint16_t token)
102 {
103         struct mc_command cmd = { 0 };
104
105         /* prepare command */
106         cmd.header = mc_encode_cmd_header(DPCI_CMDID_CLOSE,
107                                           cmd_flags,
108                                           token);
109
110         /* send command to mc*/
111         return mc_send_command(mc_io, &cmd);
112 }
113
114 /**
115  * dpci_create() - Create the DPCI object.
116  * @mc_io:      Pointer to MC portal's I/O object
117  * @dprc_token: Parent container token; '0' for default container
118  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
119  * @cfg:        Configuration structure
120  * @obj_id:     Returned object id
121  *
122  * Create the DPCI object, allocate required resources and perform required
123  * initialization.
124  *
125  * The object can be created either by declaring it in the
126  * DPL file, or by calling this function.
127  *
128  * The function accepts an authentication token of a parent
129  * container that this object should be assigned to. The token
130  * can be '0' so the object will be assigned to the default container.
131  * The newly created object can be opened with the returned
132  * object id and using the container's associated tokens and MC portals.
133  *
134  * Return:      '0' on Success; Error code otherwise.
135  */
136 int dpci_create(struct fsl_mc_io *mc_io,
137                 uint16_t dprc_token,
138                 uint32_t cmd_flags,
139                 const struct dpci_cfg *cfg,
140                 uint32_t *obj_id)
141 {
142         struct dpci_cmd_create *cmd_params;
143         struct mc_command cmd = { 0 };
144         int err;
145
146         /* prepare command */
147         cmd.header = mc_encode_cmd_header(DPCI_CMDID_CREATE,
148                                           cmd_flags,
149                                           dprc_token);
150         cmd_params = (struct dpci_cmd_create *)cmd.params;
151         cmd_params->num_of_priorities = cfg->num_of_priorities;
152
153         /* send command to mc*/
154         err = mc_send_command(mc_io, &cmd);
155         if (err)
156                 return err;
157
158         /* retrieve response parameters */
159         *obj_id = mc_cmd_read_object_id(&cmd);
160
161         return 0;
162 }
163
164 /**
165  * dpci_destroy() - Destroy the DPCI object and release all its resources.
166  * @mc_io:      Pointer to MC portal's I/O object
167  * @dprc_token: Parent container token; '0' for default container
168  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
169  * @object_id:  The object id; it must be a valid id within the container that
170  * created this object;
171  *
172  * The function accepts the authentication token of the parent container that
173  * created the object (not the one that currently owns the object). The object
174  * is searched within parent using the provided 'object_id'.
175  * All tokens to the object must be closed before calling destroy.
176  *
177  * Return:      '0' on Success; error code otherwise.
178  */
179 int dpci_destroy(struct fsl_mc_io *mc_io,
180                  uint16_t dprc_token,
181                  uint32_t cmd_flags,
182                  uint32_t object_id)
183 {
184         struct dpci_cmd_destroy *cmd_params;
185         struct mc_command cmd = { 0 };
186
187         /* prepare command */
188         cmd.header = mc_encode_cmd_header(DPCI_CMDID_DESTROY,
189                                           cmd_flags,
190                                           dprc_token);
191         cmd_params = (struct dpci_cmd_destroy *)cmd.params;
192         cmd_params->dpci_id = cpu_to_le32(object_id);
193
194         /* send command to mc*/
195         return mc_send_command(mc_io, &cmd);
196 }
197
198 /**
199  * dpci_enable() - Enable the DPCI, allow sending and receiving frames.
200  * @mc_io:      Pointer to MC portal's I/O object
201  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
202  * @token:      Token of DPCI object
203  *
204  * Return:      '0' on Success; Error code otherwise.
205  */
206 int dpci_enable(struct fsl_mc_io *mc_io,
207                 uint32_t cmd_flags,
208                 uint16_t token)
209 {
210         struct mc_command cmd = { 0 };
211
212         /* prepare command */
213         cmd.header = mc_encode_cmd_header(DPCI_CMDID_ENABLE,
214                                           cmd_flags,
215                                           token);
216
217         /* send command to mc*/
218         return mc_send_command(mc_io, &cmd);
219 }
220
221 /**
222  * dpci_disable() - Disable the DPCI, stop sending and receiving frames.
223  * @mc_io:      Pointer to MC portal's I/O object
224  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
225  * @token:      Token of DPCI object
226  *
227  * Return:      '0' on Success; Error code otherwise.
228  */
229 int dpci_disable(struct fsl_mc_io *mc_io,
230                  uint32_t cmd_flags,
231                  uint16_t token)
232 {
233         struct mc_command cmd = { 0 };
234
235         /* prepare command */
236         cmd.header = mc_encode_cmd_header(DPCI_CMDID_DISABLE,
237                                           cmd_flags,
238                                           token);
239
240         /* send command to mc*/
241         return mc_send_command(mc_io, &cmd);
242 }
243
244 /**
245  * dpci_is_enabled() - Check if the DPCI is enabled.
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 DPCI object
249  * @en:         Returns '1' if object is enabled; '0' otherwise
250  *
251  * Return:      '0' on Success; Error code otherwise.
252  */
253 int dpci_is_enabled(struct fsl_mc_io *mc_io,
254                     uint32_t cmd_flags,
255                     uint16_t token,
256                     int *en)
257 {
258         struct dpci_rsp_is_enabled *rsp_params;
259         struct mc_command cmd = { 0 };
260         int err;
261
262         /* prepare command */
263         cmd.header = mc_encode_cmd_header(DPCI_CMDID_IS_ENABLED, cmd_flags,
264                                           token);
265
266         /* send command to mc*/
267         err = mc_send_command(mc_io, &cmd);
268         if (err)
269                 return err;
270
271         /* retrieve response parameters */
272         rsp_params = (struct dpci_rsp_is_enabled *)cmd.params;
273         *en = dpci_get_field(rsp_params->en, ENABLE);
274
275         return 0;
276 }
277
278 /**
279  * dpci_reset() - Reset the DPCI, returns the object to initial state.
280  * @mc_io:      Pointer to MC portal's I/O object
281  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
282  * @token:      Token of DPCI object
283  *
284  * Return:      '0' on Success; Error code otherwise.
285  */
286 int dpci_reset(struct fsl_mc_io *mc_io,
287                uint32_t cmd_flags,
288                uint16_t token)
289 {
290         struct mc_command cmd = { 0 };
291
292         /* prepare command */
293         cmd.header = mc_encode_cmd_header(DPCI_CMDID_RESET,
294                                           cmd_flags,
295                                           token);
296
297         /* send command to mc*/
298         return mc_send_command(mc_io, &cmd);
299 }
300
301 int dpci_get_attributes(struct fsl_mc_io *mc_io,
302                         uint32_t cmd_flags,
303                         uint16_t token,
304                         struct dpci_attr *attr)
305 {
306         struct dpci_rsp_get_attr *rsp_params;
307         struct mc_command cmd = { 0 };
308         int err;
309
310         /* prepare command */
311         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_ATTR,
312                                           cmd_flags,
313                                           token);
314
315         /* send command to mc*/
316         err = mc_send_command(mc_io, &cmd);
317         if (err)
318                 return err;
319
320         /* retrieve response parameters */
321         rsp_params = (struct dpci_rsp_get_attr *)cmd.params;
322         attr->id = le32_to_cpu(rsp_params->id);
323         attr->num_of_priorities = rsp_params->num_of_priorities;
324
325         return 0;
326 }
327
328 int dpci_set_rx_queue(struct fsl_mc_io *mc_io,
329                       uint32_t cmd_flags,
330                       uint16_t token,
331                       uint8_t priority,
332                       const struct dpci_rx_queue_cfg *cfg)
333 {
334         struct dpci_cmd_set_rx_queue *cmd_params;
335         struct mc_command cmd = { 0 };
336
337         /* prepare command */
338         cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_RX_QUEUE,
339                                           cmd_flags,
340                                           token);
341         cmd_params = (struct dpci_cmd_set_rx_queue *)cmd.params;
342         cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
343         cmd_params->dest_priority = cfg->dest_cfg.priority;
344         cmd_params->priority = priority;
345         cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
346         cmd_params->options = cpu_to_le32(cfg->options);
347         dpci_set_field(cmd_params->dest_type,
348                        DEST_TYPE,
349                        cfg->dest_cfg.dest_type);
350
351         /* send command to mc*/
352         return mc_send_command(mc_io, &cmd);
353 }
354
355 /**
356  * dpci_get_rx_queue() - Retrieve Rx queue attributes.
357  * @mc_io:      Pointer to MC portal's I/O object
358  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
359  * @token:      Token of DPCI object
360  * @priority:   Select the queue relative to number of
361  *              priorities configured at DPCI creation
362  * @attr:       Returned Rx queue attributes
363  *
364  * Return:      '0' on Success; Error code otherwise.
365  */
366 int dpci_get_rx_queue(struct fsl_mc_io *mc_io,
367                       uint32_t cmd_flags,
368                       uint16_t token,
369                       uint8_t priority,
370                       struct dpci_rx_queue_attr *attr)
371 {
372         struct dpci_cmd_get_queue *cmd_params;
373         struct dpci_rsp_get_rx_queue *rsp_params;
374         struct mc_command cmd = { 0 };
375         int err;
376
377         /* prepare command */
378         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_RX_QUEUE,
379                                           cmd_flags,
380                                           token);
381         cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
382         cmd_params->priority = priority;
383
384         /* send command to mc*/
385         err = mc_send_command(mc_io, &cmd);
386         if (err)
387                 return err;
388
389         /* retrieve response parameters */
390         rsp_params = (struct dpci_rsp_get_rx_queue *)cmd.params;
391         attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
392         attr->fqid = le32_to_cpu(rsp_params->fqid);
393         attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
394         attr->dest_cfg.priority = rsp_params->dest_priority;
395         attr->dest_cfg.dest_type = dpci_get_field(rsp_params->dest_type,
396                                                   DEST_TYPE);
397
398         return 0;
399 }
400
401 /**
402  * dpci_get_tx_queue() - Retrieve Tx queue attributes.
403  * @mc_io:      Pointer to MC portal's I/O object
404  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
405  * @token:      Token of DPCI object
406  * @priority:   Select the queue relative to number of
407  *              priorities of the peer DPCI object
408  * @attr:       Returned Tx queue attributes
409  *
410  * Return:      '0' on Success; Error code otherwise.
411  */
412 int dpci_get_tx_queue(struct fsl_mc_io *mc_io,
413                       uint32_t cmd_flags,
414                       uint16_t token,
415                       uint8_t priority,
416                       struct dpci_tx_queue_attr *attr)
417 {
418         struct dpci_cmd_get_queue *cmd_params;
419         struct dpci_rsp_get_tx_queue *rsp_params;
420         struct mc_command cmd = { 0 };
421         int err;
422
423         /* prepare command */
424         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_TX_QUEUE,
425                                           cmd_flags,
426                                           token);
427         cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
428         cmd_params->priority = priority;
429
430         /* send command to mc*/
431         err = mc_send_command(mc_io, &cmd);
432         if (err)
433                 return err;
434
435         /* retrieve response parameters */
436         rsp_params = (struct dpci_rsp_get_tx_queue *)cmd.params;
437         attr->fqid = le32_to_cpu(rsp_params->fqid);
438
439         return 0;
440 }
441
442 /**
443  * dpci_get_api_version() - Get communication interface API version
444  * @mc_io:      Pointer to MC portal's I/O object
445  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
446  * @major_ver:  Major version of data path communication interface API
447  * @minor_ver:  Minor version of data path communication interface API
448  *
449  * Return:  '0' on Success; Error code otherwise.
450  */
451 int dpci_get_api_version(struct fsl_mc_io *mc_io,
452                          uint32_t cmd_flags,
453                          uint16_t *major_ver,
454                          uint16_t *minor_ver)
455 {
456         struct dpci_rsp_get_api_version *rsp_params;
457         struct mc_command cmd = { 0 };
458         int err;
459
460         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_API_VERSION,
461                                         cmd_flags,
462                                         0);
463
464         err = mc_send_command(mc_io, &cmd);
465         if (err)
466                 return err;
467
468         rsp_params = (struct dpci_rsp_get_api_version *)cmd.params;
469         *major_ver = le16_to_cpu(rsp_params->major);
470         *minor_ver = le16_to_cpu(rsp_params->minor);
471
472         return 0;
473 }