New upstream version 18.11-rc1
[deb_dpdk.git] / drivers / bus / fslmc / mc / dpci.c
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2013-2016 Freescale Semiconductor Inc.
4  *
5  */
6 #include <fsl_mc_sys.h>
7 #include <fsl_mc_cmd.h>
8 #include <fsl_dpci.h>
9 #include <fsl_dpci_cmd.h>
10
11 /**
12  * dpci_open() - Open a control session for the specified object
13  * @mc_io:      Pointer to MC portal's I/O object
14  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
15  * @dpci_id:    DPCI unique ID
16  * @token:      Returned token; use in subsequent API calls
17  *
18  * This function can be used to open a control session for an
19  * already created object; an object may have been declared in
20  * the DPL or by calling the dpci_create() function.
21  * This function returns a unique authentication token,
22  * associated with the specific object ID and the specific MC
23  * portal; this token must be used in all subsequent commands for
24  * this specific object.
25  *
26  * Return:      '0' on Success; Error code otherwise.
27  */
28 int dpci_open(struct fsl_mc_io *mc_io,
29               uint32_t cmd_flags,
30               int dpci_id,
31               uint16_t *token)
32 {
33         struct dpci_cmd_open *cmd_params;
34         struct mc_command cmd = { 0 };
35         int err;
36
37         /* prepare command */
38         cmd.header = mc_encode_cmd_header(DPCI_CMDID_OPEN,
39                                           cmd_flags,
40                                           0);
41         cmd_params = (struct dpci_cmd_open *)cmd.params;
42         cmd_params->dpci_id = cpu_to_le32(dpci_id);
43
44         /* send command to mc*/
45         err = mc_send_command(mc_io, &cmd);
46         if (err)
47                 return err;
48
49         /* retrieve response parameters */
50         *token = mc_cmd_hdr_read_token(&cmd);
51
52         return 0;
53 }
54
55 /**
56  * dpci_close() - Close the control session of the object
57  * @mc_io:      Pointer to MC portal's I/O object
58  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
59  * @token:      Token of DPCI object
60  *
61  * After this function is called, no further operations are
62  * allowed on the object without opening a new control session.
63  *
64  * Return:      '0' on Success; Error code otherwise.
65  */
66 int dpci_close(struct fsl_mc_io *mc_io,
67                uint32_t cmd_flags,
68                uint16_t token)
69 {
70         struct mc_command cmd = { 0 };
71
72         /* prepare command */
73         cmd.header = mc_encode_cmd_header(DPCI_CMDID_CLOSE,
74                                           cmd_flags,
75                                           token);
76
77         /* send command to mc*/
78         return mc_send_command(mc_io, &cmd);
79 }
80
81 /**
82  * dpci_create() - Create the DPCI object.
83  * @mc_io:      Pointer to MC portal's I/O object
84  * @dprc_token: Parent container token; '0' for default container
85  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
86  * @cfg:        Configuration structure
87  * @obj_id:     Returned object id
88  *
89  * Create the DPCI object, allocate required resources and perform required
90  * initialization.
91  *
92  * The object can be created either by declaring it in the
93  * DPL file, or by calling this function.
94  *
95  * The function accepts an authentication token of a parent
96  * container that this object should be assigned to. The token
97  * can be '0' so the object will be assigned to the default container.
98  * The newly created object can be opened with the returned
99  * object id and using the container's associated tokens and MC portals.
100  *
101  * Return:      '0' on Success; Error code otherwise.
102  */
103 int dpci_create(struct fsl_mc_io *mc_io,
104                 uint16_t dprc_token,
105                 uint32_t cmd_flags,
106                 const struct dpci_cfg *cfg,
107                 uint32_t *obj_id)
108 {
109         struct dpci_cmd_create *cmd_params;
110         struct mc_command cmd = { 0 };
111         int err;
112
113         /* prepare command */
114         cmd.header = mc_encode_cmd_header(DPCI_CMDID_CREATE,
115                                           cmd_flags,
116                                           dprc_token);
117         cmd_params = (struct dpci_cmd_create *)cmd.params;
118         cmd_params->num_of_priorities = cfg->num_of_priorities;
119
120         /* send command to mc*/
121         err = mc_send_command(mc_io, &cmd);
122         if (err)
123                 return err;
124
125         /* retrieve response parameters */
126         *obj_id = mc_cmd_read_object_id(&cmd);
127
128         return 0;
129 }
130
131 /**
132  * dpci_destroy() - Destroy the DPCI object and release all its resources.
133  * @mc_io:      Pointer to MC portal's I/O object
134  * @dprc_token: Parent container token; '0' for default container
135  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
136  * @object_id:  The object id; it must be a valid id within the container that
137  * created this object;
138  *
139  * The function accepts the authentication token of the parent container that
140  * created the object (not the one that currently owns the object). The object
141  * is searched within parent using the provided 'object_id'.
142  * All tokens to the object must be closed before calling destroy.
143  *
144  * Return:      '0' on Success; error code otherwise.
145  */
146 int dpci_destroy(struct fsl_mc_io *mc_io,
147                  uint16_t dprc_token,
148                  uint32_t cmd_flags,
149                  uint32_t object_id)
150 {
151         struct dpci_cmd_destroy *cmd_params;
152         struct mc_command cmd = { 0 };
153
154         /* prepare command */
155         cmd.header = mc_encode_cmd_header(DPCI_CMDID_DESTROY,
156                                           cmd_flags,
157                                           dprc_token);
158         cmd_params = (struct dpci_cmd_destroy *)cmd.params;
159         cmd_params->dpci_id = cpu_to_le32(object_id);
160
161         /* send command to mc*/
162         return mc_send_command(mc_io, &cmd);
163 }
164
165 /**
166  * dpci_enable() - Enable the DPCI, allow 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 DPCI object
170  *
171  * Return:      '0' on Success; Error code otherwise.
172  */
173 int dpci_enable(struct fsl_mc_io *mc_io,
174                 uint32_t cmd_flags,
175                 uint16_t token)
176 {
177         struct mc_command cmd = { 0 };
178
179         /* prepare command */
180         cmd.header = mc_encode_cmd_header(DPCI_CMDID_ENABLE,
181                                           cmd_flags,
182                                           token);
183
184         /* send command to mc*/
185         return mc_send_command(mc_io, &cmd);
186 }
187
188 /**
189  * dpci_disable() - Disable the DPCI, stop sending and receiving frames.
190  * @mc_io:      Pointer to MC portal's I/O object
191  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
192  * @token:      Token of DPCI object
193  *
194  * Return:      '0' on Success; Error code otherwise.
195  */
196 int dpci_disable(struct fsl_mc_io *mc_io,
197                  uint32_t cmd_flags,
198                  uint16_t token)
199 {
200         struct mc_command cmd = { 0 };
201
202         /* prepare command */
203         cmd.header = mc_encode_cmd_header(DPCI_CMDID_DISABLE,
204                                           cmd_flags,
205                                           token);
206
207         /* send command to mc*/
208         return mc_send_command(mc_io, &cmd);
209 }
210
211 /**
212  * dpci_is_enabled() - Check if the DPCI is enabled.
213  * @mc_io:      Pointer to MC portal's I/O object
214  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
215  * @token:      Token of DPCI object
216  * @en:         Returns '1' if object is enabled; '0' otherwise
217  *
218  * Return:      '0' on Success; Error code otherwise.
219  */
220 int dpci_is_enabled(struct fsl_mc_io *mc_io,
221                     uint32_t cmd_flags,
222                     uint16_t token,
223                     int *en)
224 {
225         struct dpci_rsp_is_enabled *rsp_params;
226         struct mc_command cmd = { 0 };
227         int err;
228
229         /* prepare command */
230         cmd.header = mc_encode_cmd_header(DPCI_CMDID_IS_ENABLED, cmd_flags,
231                                           token);
232
233         /* send command to mc*/
234         err = mc_send_command(mc_io, &cmd);
235         if (err)
236                 return err;
237
238         /* retrieve response parameters */
239         rsp_params = (struct dpci_rsp_is_enabled *)cmd.params;
240         *en = dpci_get_field(rsp_params->en, ENABLE);
241
242         return 0;
243 }
244
245 /**
246  * dpci_reset() - Reset the DPCI, returns the object to initial state.
247  * @mc_io:      Pointer to MC portal's I/O object
248  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
249  * @token:      Token of DPCI object
250  *
251  * Return:      '0' on Success; Error code otherwise.
252  */
253 int dpci_reset(struct fsl_mc_io *mc_io,
254                uint32_t cmd_flags,
255                uint16_t token)
256 {
257         struct mc_command cmd = { 0 };
258
259         /* prepare command */
260         cmd.header = mc_encode_cmd_header(DPCI_CMDID_RESET,
261                                           cmd_flags,
262                                           token);
263
264         /* send command to mc*/
265         return mc_send_command(mc_io, &cmd);
266 }
267
268 /**
269  * dpci_get_attributes() - Retrieve DPCI attributes.
270  * @mc_io:      Pointer to MC portal's I/O object
271  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
272  * @token:      Token of DPCI object
273  * @attr:       Returned object's attributes
274  *
275  * Return:      '0' on Success; Error code otherwise.
276  */
277 int dpci_get_attributes(struct fsl_mc_io *mc_io,
278                         uint32_t cmd_flags,
279                         uint16_t token,
280                         struct dpci_attr *attr)
281 {
282         struct dpci_rsp_get_attr *rsp_params;
283         struct mc_command cmd = { 0 };
284         int err;
285
286         /* prepare command */
287         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_ATTR,
288                                           cmd_flags,
289                                           token);
290
291         /* send command to mc*/
292         err = mc_send_command(mc_io, &cmd);
293         if (err)
294                 return err;
295
296         /* retrieve response parameters */
297         rsp_params = (struct dpci_rsp_get_attr *)cmd.params;
298         attr->id = le32_to_cpu(rsp_params->id);
299         attr->num_of_priorities = rsp_params->num_of_priorities;
300
301         return 0;
302 }
303
304 /**
305  * dpci_get_peer_attributes() - Retrieve peer DPCI attributes.
306  * @mc_io:      Pointer to MC portal's I/O object
307  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
308  * @token:      Token of DPCI object
309  * @attr:       Returned peer attributes
310  *
311  * Return:      '0' on Success; Error code otherwise.
312  */
313 int dpci_get_peer_attributes(struct fsl_mc_io *mc_io,
314                              uint32_t cmd_flags,
315                              uint16_t token,
316                              struct dpci_peer_attr *attr)
317 {
318         struct dpci_rsp_get_peer_attr *rsp_params;
319         struct mc_command cmd = { 0 };
320         int err;
321
322         /* prepare command */
323         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_PEER_ATTR,
324                                           cmd_flags,
325                                           token);
326
327         /* send command to mc*/
328         err = mc_send_command(mc_io, &cmd);
329         if (err)
330                 return err;
331
332         /* retrieve response parameters */
333         rsp_params = (struct dpci_rsp_get_peer_attr *)cmd.params;
334         attr->peer_id = le32_to_cpu(rsp_params->id);
335         attr->num_of_priorities = rsp_params->num_of_priorities;
336
337         return 0;
338 }
339
340 /**
341  * dpci_get_link_state() - Retrieve the DPCI link state.
342  * @mc_io:      Pointer to MC portal's I/O object
343  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
344  * @token:      Token of DPCI object
345  * @up:         Returned link state; returns '1' if link is up, '0' otherwise
346  *
347  * DPCI can be connected to another DPCI, together they
348  * create a 'link'. In order to use the DPCI Tx and Rx queues,
349  * both objects must be enabled.
350  *
351  * Return:      '0' on Success; Error code otherwise.
352  */
353 int dpci_get_link_state(struct fsl_mc_io *mc_io,
354                         uint32_t cmd_flags,
355                         uint16_t token,
356                         int *up)
357 {
358         struct dpci_rsp_get_link_state *rsp_params;
359         struct mc_command cmd = { 0 };
360         int err;
361
362         /* prepare command */
363         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_LINK_STATE,
364                                           cmd_flags,
365                                           token);
366
367         /* send command to mc*/
368         err = mc_send_command(mc_io, &cmd);
369         if (err)
370                 return err;
371
372         /* retrieve response parameters */
373         rsp_params = (struct dpci_rsp_get_link_state *)cmd.params;
374         *up = dpci_get_field(rsp_params->up, UP);
375
376         return 0;
377 }
378
379 /**
380  * dpci_set_rx_queue() - Set Rx queue configuration
381  * @mc_io:      Pointer to MC portal's I/O object
382  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
383  * @token:      Token of DPCI object
384  * @priority:   Select the queue relative to number of
385  *                      priorities configured at DPCI creation; use
386  *                      DPCI_ALL_QUEUES to configure all Rx queues
387  *                      identically.
388  * @cfg:        Rx queue configuration
389  *
390  * Return:      '0' on Success; Error code otherwise.
391  */
392 int dpci_set_rx_queue(struct fsl_mc_io *mc_io,
393                       uint32_t cmd_flags,
394                       uint16_t token,
395                       uint8_t priority,
396                       const struct dpci_rx_queue_cfg *cfg)
397 {
398         struct dpci_cmd_set_rx_queue *cmd_params;
399         struct mc_command cmd = { 0 };
400
401         /* prepare command */
402         cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_RX_QUEUE,
403                                           cmd_flags,
404                                           token);
405         cmd_params = (struct dpci_cmd_set_rx_queue *)cmd.params;
406         cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
407         cmd_params->dest_priority = cfg->dest_cfg.priority;
408         cmd_params->priority = priority;
409         cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
410         cmd_params->options = cpu_to_le32(cfg->options);
411         dpci_set_field(cmd_params->dest_type,
412                        DEST_TYPE,
413                        cfg->dest_cfg.dest_type);
414         dpci_set_field(cmd_params->dest_type,
415                        ORDER_PRESERVATION,
416                        cfg->order_preservation_en);
417
418         /* send command to mc*/
419         return mc_send_command(mc_io, &cmd);
420 }
421
422 /**
423  * dpci_get_rx_queue() - Retrieve Rx queue attributes.
424  * @mc_io:      Pointer to MC portal's I/O object
425  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
426  * @token:      Token of DPCI object
427  * @priority:   Select the queue relative to number of
428  *              priorities configured at DPCI creation
429  * @attr:       Returned Rx queue attributes
430  *
431  * Return:      '0' on Success; Error code otherwise.
432  */
433 int dpci_get_rx_queue(struct fsl_mc_io *mc_io,
434                       uint32_t cmd_flags,
435                       uint16_t token,
436                       uint8_t priority,
437                       struct dpci_rx_queue_attr *attr)
438 {
439         struct dpci_cmd_get_queue *cmd_params;
440         struct dpci_rsp_get_rx_queue *rsp_params;
441         struct mc_command cmd = { 0 };
442         int err;
443
444         /* prepare command */
445         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_RX_QUEUE,
446                                           cmd_flags,
447                                           token);
448         cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
449         cmd_params->priority = priority;
450
451         /* send command to mc*/
452         err = mc_send_command(mc_io, &cmd);
453         if (err)
454                 return err;
455
456         /* retrieve response parameters */
457         rsp_params = (struct dpci_rsp_get_rx_queue *)cmd.params;
458         attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
459         attr->fqid = le32_to_cpu(rsp_params->fqid);
460         attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
461         attr->dest_cfg.priority = rsp_params->dest_priority;
462         attr->dest_cfg.dest_type = dpci_get_field(rsp_params->dest_type,
463                                                   DEST_TYPE);
464
465         return 0;
466 }
467
468 /**
469  * dpci_get_tx_queue() - Retrieve Tx queue attributes.
470  * @mc_io:      Pointer to MC portal's I/O object
471  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
472  * @token:      Token of DPCI object
473  * @priority:   Select the queue relative to number of
474  *              priorities of the peer DPCI object
475  * @attr:       Returned Tx queue attributes
476  *
477  * Return:      '0' on Success; Error code otherwise.
478  */
479 int dpci_get_tx_queue(struct fsl_mc_io *mc_io,
480                       uint32_t cmd_flags,
481                       uint16_t token,
482                       uint8_t priority,
483                       struct dpci_tx_queue_attr *attr)
484 {
485         struct dpci_cmd_get_queue *cmd_params;
486         struct dpci_rsp_get_tx_queue *rsp_params;
487         struct mc_command cmd = { 0 };
488         int err;
489
490         /* prepare command */
491         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_TX_QUEUE,
492                                           cmd_flags,
493                                           token);
494         cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
495         cmd_params->priority = priority;
496
497         /* send command to mc*/
498         err = mc_send_command(mc_io, &cmd);
499         if (err)
500                 return err;
501
502         /* retrieve response parameters */
503         rsp_params = (struct dpci_rsp_get_tx_queue *)cmd.params;
504         attr->fqid = le32_to_cpu(rsp_params->fqid);
505
506         return 0;
507 }
508
509 /**
510  * dpci_get_api_version() - Get communication interface API version
511  * @mc_io:      Pointer to MC portal's I/O object
512  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
513  * @major_ver:  Major version of data path communication interface API
514  * @minor_ver:  Minor version of data path communication interface API
515  *
516  * Return:  '0' on Success; Error code otherwise.
517  */
518 int dpci_get_api_version(struct fsl_mc_io *mc_io,
519                          uint32_t cmd_flags,
520                          uint16_t *major_ver,
521                          uint16_t *minor_ver)
522 {
523         struct dpci_rsp_get_api_version *rsp_params;
524         struct mc_command cmd = { 0 };
525         int err;
526
527         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_API_VERSION,
528                                         cmd_flags,
529                                         0);
530
531         err = mc_send_command(mc_io, &cmd);
532         if (err)
533                 return err;
534
535         rsp_params = (struct dpci_rsp_get_api_version *)cmd.params;
536         *major_ver = le16_to_cpu(rsp_params->major);
537         *minor_ver = le16_to_cpu(rsp_params->minor);
538
539         return 0;
540 }
541
542 /**
543  * dpci_set_opr() - Set Order Restoration configuration.
544  * @mc_io:      Pointer to MC portal's I/O object
545  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
546  * @token:      Token of DPCI object
547  * @index:      The queue index
548  * @options:    Configuration mode options
549  *              can be OPR_OPT_CREATE or OPR_OPT_RETIRE
550  * @cfg:        Configuration options for the OPR
551  *
552  * Return:      '0' on Success; Error code otherwise.
553  */
554 int dpci_set_opr(struct fsl_mc_io *mc_io,
555                  uint32_t cmd_flags,
556                  uint16_t token,
557                  uint8_t index,
558                  uint8_t options,
559                  struct opr_cfg *cfg)
560 {
561         struct dpci_cmd_set_opr *cmd_params;
562         struct mc_command cmd = { 0 };
563
564         /* prepare command */
565         cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_OPR,
566                                           cmd_flags,
567                                           token);
568         cmd_params = (struct dpci_cmd_set_opr *)cmd.params;
569         cmd_params->index = index;
570         cmd_params->options = options;
571         cmd_params->oloe = cfg->oloe;
572         cmd_params->oeane = cfg->oeane;
573         cmd_params->olws = cfg->olws;
574         cmd_params->oa = cfg->oa;
575         cmd_params->oprrws = cfg->oprrws;
576
577         /* send command to mc*/
578         return mc_send_command(mc_io, &cmd);
579 }
580
581 /**
582  * dpci_get_opr() - Retrieve Order Restoration config and query.
583  * @mc_io:      Pointer to MC portal's I/O object
584  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
585  * @token:      Token of DPCI object
586  * @index:      The queue index
587  * @cfg:        Returned OPR configuration
588  * @qry:        Returned OPR query
589  *
590  * Return:      '0' on Success; Error code otherwise.
591  */
592 int dpci_get_opr(struct fsl_mc_io *mc_io,
593                  uint32_t cmd_flags,
594                  uint16_t token,
595                  uint8_t index,
596                  struct opr_cfg *cfg,
597                  struct opr_qry *qry)
598 {
599         struct dpci_rsp_get_opr *rsp_params;
600         struct dpci_cmd_get_opr *cmd_params;
601         struct mc_command cmd = { 0 };
602         int err;
603
604         /* prepare command */
605         cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_OPR,
606                                           cmd_flags,
607                                           token);
608         cmd_params = (struct dpci_cmd_get_opr *)cmd.params;
609         cmd_params->index = index;
610
611         /* send command to mc*/
612         err = mc_send_command(mc_io, &cmd);
613         if (err)
614                 return err;
615
616         /* retrieve response parameters */
617         rsp_params = (struct dpci_rsp_get_opr *)cmd.params;
618         cfg->oloe = rsp_params->oloe;
619         cfg->oeane = rsp_params->oeane;
620         cfg->olws = rsp_params->olws;
621         cfg->oa = rsp_params->oa;
622         cfg->oprrws = rsp_params->oprrws;
623         qry->rip = dpci_get_field(rsp_params->flags, RIP);
624         qry->enable = dpci_get_field(rsp_params->flags, OPR_ENABLE);
625         qry->nesn = le16_to_cpu(rsp_params->nesn);
626         qry->ndsn = le16_to_cpu(rsp_params->ndsn);
627         qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq);
628         qry->tseq_nlis = dpci_get_field(rsp_params->tseq_nlis, TSEQ_NLIS);
629         qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq);
630         qry->hseq_nlis = dpci_get_field(rsp_params->hseq_nlis, HSEQ_NLIS);
631         qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr);
632         qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr);
633         qry->opr_vid = le16_to_cpu(rsp_params->opr_vid);
634         qry->opr_id = le16_to_cpu(rsp_params->opr_id);
635
636         return 0;
637 }