Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / staging / fsl-dpaa2 / ethsw / dpsw.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2014-2016 Freescale Semiconductor Inc.
4  * Copyright 2017-2018 NXP
5  *
6  */
7
8 #include <linux/fsl/mc.h>
9 #include "dpsw.h"
10 #include "dpsw-cmd.h"
11
12 static void build_if_id_bitmap(__le64 *bmap,
13                                const u16 *id,
14                                const u16 num_ifs)
15 {
16         int i;
17
18         for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++) {
19                 if (id[i] < DPSW_MAX_IF)
20                         bmap[id[i] / 64] |= cpu_to_le64(BIT_MASK(id[i] % 64));
21         }
22 }
23
24 /**
25  * dpsw_open() - Open a control session for the specified object
26  * @mc_io:      Pointer to MC portal's I/O object
27  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
28  * @dpsw_id:    DPSW unique ID
29  * @token:      Returned token; use in subsequent API calls
30  *
31  * This function can be used to open a control session for an
32  * already created object; an object may have been declared in
33  * the DPL or by calling the dpsw_create() function.
34  * This function returns a unique authentication token,
35  * associated with the specific object ID and the specific MC
36  * portal; this token must be used in all subsequent commands for
37  * this specific object
38  *
39  * Return:      '0' on Success; Error code otherwise.
40  */
41 int dpsw_open(struct fsl_mc_io *mc_io,
42               u32 cmd_flags,
43               int dpsw_id,
44               u16 *token)
45 {
46         struct fsl_mc_command cmd = { 0 };
47         struct dpsw_cmd_open *cmd_params;
48         int err;
49
50         /* prepare command */
51         cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
52                                           cmd_flags,
53                                           0);
54         cmd_params = (struct dpsw_cmd_open *)cmd.params;
55         cmd_params->dpsw_id = cpu_to_le32(dpsw_id);
56
57         /* send command to mc*/
58         err = mc_send_command(mc_io, &cmd);
59         if (err)
60                 return err;
61
62         /* retrieve response parameters */
63         *token = mc_cmd_hdr_read_token(&cmd);
64
65         return 0;
66 }
67
68 /**
69  * dpsw_close() - Close the control session of the object
70  * @mc_io:      Pointer to MC portal's I/O object
71  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
72  * @token:      Token of DPSW object
73  *
74  * After this function is called, no further operations are
75  * allowed on the object without opening a new control session.
76  *
77  * Return:      '0' on Success; Error code otherwise.
78  */
79 int dpsw_close(struct fsl_mc_io *mc_io,
80                u32 cmd_flags,
81                u16 token)
82 {
83         struct fsl_mc_command cmd = { 0 };
84
85         /* prepare command */
86         cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
87                                           cmd_flags,
88                                           token);
89
90         /* send command to mc*/
91         return mc_send_command(mc_io, &cmd);
92 }
93
94 /**
95  * dpsw_enable() - Enable DPSW functionality
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 DPSW object
99  *
100  * Return:      Completion status. '0' on Success; Error code otherwise.
101  */
102 int dpsw_enable(struct fsl_mc_io *mc_io,
103                 u32 cmd_flags,
104                 u16 token)
105 {
106         struct fsl_mc_command cmd = { 0 };
107
108         /* prepare command */
109         cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
110                                           cmd_flags,
111                                           token);
112
113         /* send command to mc*/
114         return mc_send_command(mc_io, &cmd);
115 }
116
117 /**
118  * dpsw_disable() - Disable DPSW functionality
119  * @mc_io:      Pointer to MC portal's I/O object
120  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
121  * @token:      Token of DPSW object
122  *
123  * Return:      Completion status. '0' on Success; Error code otherwise.
124  */
125 int dpsw_disable(struct fsl_mc_io *mc_io,
126                  u32 cmd_flags,
127                  u16 token)
128 {
129         struct fsl_mc_command cmd = { 0 };
130
131         /* prepare command */
132         cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
133                                           cmd_flags,
134                                           token);
135
136         /* send command to mc*/
137         return mc_send_command(mc_io, &cmd);
138 }
139
140 /**
141  * dpsw_reset() - Reset the DPSW, returns the object to initial state.
142  * @mc_io:      Pointer to MC portal's I/O object
143  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
144  * @token:      Token of DPSW object
145  *
146  * Return:      '0' on Success; Error code otherwise.
147  */
148 int dpsw_reset(struct fsl_mc_io *mc_io,
149                u32 cmd_flags,
150                u16 token)
151 {
152         struct fsl_mc_command cmd = { 0 };
153
154         /* prepare command */
155         cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
156                                           cmd_flags,
157                                           token);
158
159         /* send command to mc*/
160         return mc_send_command(mc_io, &cmd);
161 }
162
163 /**
164  * dpsw_set_irq_enable() - Set overall interrupt state.
165  * @mc_io:      Pointer to MC portal's I/O object
166  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
167  * @token:      Token of DPCI object
168  * @irq_index:  The interrupt index to configure
169  * @en:         Interrupt state - enable = 1, disable = 0
170  *
171  * Allows GPP software to control when interrupts are generated.
172  * Each interrupt can have up to 32 causes.  The enable/disable control's the
173  * overall interrupt state. if the interrupt is disabled no causes will cause
174  * an interrupt
175  *
176  * Return:      '0' on Success; Error code otherwise.
177  */
178 int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
179                         u32 cmd_flags,
180                         u16 token,
181                         u8 irq_index,
182                         u8 en)
183 {
184         struct fsl_mc_command cmd = { 0 };
185         struct dpsw_cmd_set_irq_enable *cmd_params;
186
187         /* prepare command */
188         cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
189                                           cmd_flags,
190                                           token);
191         cmd_params = (struct dpsw_cmd_set_irq_enable *)cmd.params;
192         dpsw_set_field(cmd_params->enable_state, ENABLE, en);
193         cmd_params->irq_index = irq_index;
194
195         /* send command to mc*/
196         return mc_send_command(mc_io, &cmd);
197 }
198
199 /**
200  * dpsw_set_irq_mask() - Set interrupt mask.
201  * @mc_io:      Pointer to MC portal's I/O object
202  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
203  * @token:      Token of DPCI object
204  * @irq_index:  The interrupt index to configure
205  * @mask:       Event mask to trigger interrupt;
206  *              each bit:
207  *                      0 = ignore event
208  *                      1 = consider event for asserting IRQ
209  *
210  * Every interrupt can have up to 32 causes and the interrupt model supports
211  * masking/unmasking each cause independently
212  *
213  * Return:      '0' on Success; Error code otherwise.
214  */
215 int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
216                       u32 cmd_flags,
217                       u16 token,
218                       u8 irq_index,
219                       u32 mask)
220 {
221         struct fsl_mc_command cmd = { 0 };
222         struct dpsw_cmd_set_irq_mask *cmd_params;
223
224         /* prepare command */
225         cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
226                                           cmd_flags,
227                                           token);
228         cmd_params = (struct dpsw_cmd_set_irq_mask *)cmd.params;
229         cmd_params->mask = cpu_to_le32(mask);
230         cmd_params->irq_index = irq_index;
231
232         /* send command to mc*/
233         return mc_send_command(mc_io, &cmd);
234 }
235
236 /**
237  * dpsw_get_irq_status() - Get the current status of any pending interrupts
238  * @mc_io:      Pointer to MC portal's I/O object
239  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
240  * @token:      Token of DPSW object
241  * @irq_index:  The interrupt index to configure
242  * @status:     Returned interrupts status - one bit per cause:
243  *                      0 = no interrupt pending
244  *                      1 = interrupt pending
245  *
246  * Return:      '0' on Success; Error code otherwise.
247  */
248 int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
249                         u32 cmd_flags,
250                         u16 token,
251                         u8 irq_index,
252                         u32 *status)
253 {
254         struct fsl_mc_command cmd = { 0 };
255         struct dpsw_cmd_get_irq_status *cmd_params;
256         struct dpsw_rsp_get_irq_status *rsp_params;
257         int err;
258
259         /* prepare command */
260         cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
261                                           cmd_flags,
262                                           token);
263         cmd_params = (struct dpsw_cmd_get_irq_status *)cmd.params;
264         cmd_params->status = cpu_to_le32(*status);
265         cmd_params->irq_index = irq_index;
266
267         /* send command to mc*/
268         err = mc_send_command(mc_io, &cmd);
269         if (err)
270                 return err;
271
272         /* retrieve response parameters */
273         rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params;
274         *status = le32_to_cpu(rsp_params->status);
275
276         return 0;
277 }
278
279 /**
280  * dpsw_clear_irq_status() - Clear a pending interrupt's status
281  * @mc_io:      Pointer to MC portal's I/O object
282  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
283  * @token:      Token of DPCI object
284  * @irq_index:  The interrupt index to configure
285  * @status:     bits to clear (W1C) - one bit per cause:
286  *                      0 = don't change
287  *                      1 = clear status bit
288  *
289  * Return:      '0' on Success; Error code otherwise.
290  */
291 int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
292                           u32 cmd_flags,
293                           u16 token,
294                           u8 irq_index,
295                           u32 status)
296 {
297         struct fsl_mc_command cmd = { 0 };
298         struct dpsw_cmd_clear_irq_status *cmd_params;
299
300         /* prepare command */
301         cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
302                                           cmd_flags,
303                                           token);
304         cmd_params = (struct dpsw_cmd_clear_irq_status *)cmd.params;
305         cmd_params->status = cpu_to_le32(status);
306         cmd_params->irq_index = irq_index;
307
308         /* send command to mc*/
309         return mc_send_command(mc_io, &cmd);
310 }
311
312 /**
313  * dpsw_get_attributes() - Retrieve DPSW attributes
314  * @mc_io:      Pointer to MC portal's I/O object
315  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
316  * @token:      Token of DPSW object
317  * @attr:       Returned DPSW attributes
318  *
319  * Return:      Completion status. '0' on Success; Error code otherwise.
320  */
321 int dpsw_get_attributes(struct fsl_mc_io *mc_io,
322                         u32 cmd_flags,
323                         u16 token,
324                         struct dpsw_attr *attr)
325 {
326         struct fsl_mc_command cmd = { 0 };
327         struct dpsw_rsp_get_attr *rsp_params;
328         int err;
329
330         /* prepare command */
331         cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
332                                           cmd_flags,
333                                           token);
334
335         /* send command to mc*/
336         err = mc_send_command(mc_io, &cmd);
337         if (err)
338                 return err;
339
340         /* retrieve response parameters */
341         rsp_params = (struct dpsw_rsp_get_attr *)cmd.params;
342         attr->num_ifs = le16_to_cpu(rsp_params->num_ifs);
343         attr->max_fdbs = rsp_params->max_fdbs;
344         attr->num_fdbs = rsp_params->num_fdbs;
345         attr->max_vlans = le16_to_cpu(rsp_params->max_vlans);
346         attr->num_vlans = le16_to_cpu(rsp_params->num_vlans);
347         attr->max_fdb_entries = le16_to_cpu(rsp_params->max_fdb_entries);
348         attr->fdb_aging_time = le16_to_cpu(rsp_params->fdb_aging_time);
349         attr->id = le32_to_cpu(rsp_params->dpsw_id);
350         attr->mem_size = le16_to_cpu(rsp_params->mem_size);
351         attr->max_fdb_mc_groups = le16_to_cpu(rsp_params->max_fdb_mc_groups);
352         attr->max_meters_per_if = rsp_params->max_meters_per_if;
353         attr->options = le64_to_cpu(rsp_params->options);
354         attr->component_type = dpsw_get_field(rsp_params->component_type,
355                                               COMPONENT_TYPE);
356
357         return 0;
358 }
359
360 /**
361  * dpsw_if_set_link_cfg() - Set the link configuration.
362  * @mc_io:      Pointer to MC portal's I/O object
363  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
364  * @token:      Token of DPSW object
365  * @if_id:      Interface id
366  * @cfg:        Link configuration
367  *
368  * Return:      '0' on Success; Error code otherwise.
369  */
370 int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
371                          u32 cmd_flags,
372                          u16 token,
373                          u16 if_id,
374                          struct dpsw_link_cfg *cfg)
375 {
376         struct fsl_mc_command cmd = { 0 };
377         struct dpsw_cmd_if_set_link_cfg *cmd_params;
378
379         /* prepare command */
380         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,
381                                           cmd_flags,
382                                           token);
383         cmd_params = (struct dpsw_cmd_if_set_link_cfg *)cmd.params;
384         cmd_params->if_id = cpu_to_le16(if_id);
385         cmd_params->rate = cpu_to_le32(cfg->rate);
386         cmd_params->options = cpu_to_le64(cfg->options);
387
388         /* send command to mc*/
389         return mc_send_command(mc_io, &cmd);
390 }
391
392 /**
393  * dpsw_if_get_link_state - Return the link state
394  * @mc_io:      Pointer to MC portal's I/O object
395  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
396  * @token:      Token of DPSW object
397  * @if_id:      Interface id
398  * @state:      Link state      1 - linkup, 0 - link down or disconnected
399  *
400  * @Return      '0' on Success; Error code otherwise.
401  */
402 int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
403                            u32 cmd_flags,
404                            u16 token,
405                            u16 if_id,
406                            struct dpsw_link_state *state)
407 {
408         struct fsl_mc_command cmd = { 0 };
409         struct dpsw_cmd_if_get_link_state *cmd_params;
410         struct dpsw_rsp_if_get_link_state *rsp_params;
411         int err;
412
413         /* prepare command */
414         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
415                                           cmd_flags,
416                                           token);
417         cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params;
418         cmd_params->if_id = cpu_to_le16(if_id);
419
420         /* send command to mc*/
421         err = mc_send_command(mc_io, &cmd);
422         if (err)
423                 return err;
424
425         /* retrieve response parameters */
426         rsp_params = (struct dpsw_rsp_if_get_link_state *)cmd.params;
427         state->rate = le32_to_cpu(rsp_params->rate);
428         state->options = le64_to_cpu(rsp_params->options);
429         state->up = dpsw_get_field(rsp_params->up, UP);
430
431         return 0;
432 }
433
434 /**
435  * dpsw_if_set_flooding() - Enable Disable flooding for particular interface
436  * @mc_io:      Pointer to MC portal's I/O object
437  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
438  * @token:      Token of DPSW object
439  * @if_id:      Interface Identifier
440  * @en:         1 - enable, 0 - disable
441  *
442  * Return:      Completion status. '0' on Success; Error code otherwise.
443  */
444 int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
445                          u32 cmd_flags,
446                          u16 token,
447                          u16 if_id,
448                          u8 en)
449 {
450         struct fsl_mc_command cmd = { 0 };
451         struct dpsw_cmd_if_set_flooding *cmd_params;
452
453         /* prepare command */
454         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING,
455                                           cmd_flags,
456                                           token);
457         cmd_params = (struct dpsw_cmd_if_set_flooding *)cmd.params;
458         cmd_params->if_id = cpu_to_le16(if_id);
459         dpsw_set_field(cmd_params->enable, ENABLE, en);
460
461         /* send command to mc*/
462         return mc_send_command(mc_io, &cmd);
463 }
464
465 /**
466  * dpsw_if_set_broadcast() - Enable/disable broadcast for particular interface
467  * @mc_io:      Pointer to MC portal's I/O object
468  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
469  * @token:      Token of DPSW object
470  * @if_id:      Interface Identifier
471  * @en:         1 - enable, 0 - disable
472  *
473  * Return:      Completion status. '0' on Success; Error code otherwise.
474  */
475 int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
476                           u32 cmd_flags,
477                           u16 token,
478                           u16 if_id,
479                           u8 en)
480 {
481         struct fsl_mc_command cmd = { 0 };
482         struct dpsw_cmd_if_set_broadcast *cmd_params;
483
484         /* prepare command */
485         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_BROADCAST,
486                                           cmd_flags,
487                                           token);
488         cmd_params = (struct dpsw_cmd_if_set_broadcast *)cmd.params;
489         cmd_params->if_id = cpu_to_le16(if_id);
490         dpsw_set_field(cmd_params->enable, ENABLE, en);
491
492         /* send command to mc*/
493         return mc_send_command(mc_io, &cmd);
494 }
495
496 /**
497  * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)
498  * @mc_io:      Pointer to MC portal's I/O object
499  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
500  * @token:      Token of DPSW object
501  * @if_id:      Interface Identifier
502  * @cfg:        Tag Control Information Configuration
503  *
504  * Return:      Completion status. '0' on Success; Error code otherwise.
505  */
506 int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
507                     u32 cmd_flags,
508                     u16 token,
509                     u16 if_id,
510                     const struct dpsw_tci_cfg *cfg)
511 {
512         struct fsl_mc_command cmd = { 0 };
513         struct dpsw_cmd_if_set_tci *cmd_params;
514         u16 tmp_conf = 0;
515
516         /* prepare command */
517         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
518                                           cmd_flags,
519                                           token);
520         cmd_params = (struct dpsw_cmd_if_set_tci *)cmd.params;
521         cmd_params->if_id = cpu_to_le16(if_id);
522         dpsw_set_field(tmp_conf, VLAN_ID, cfg->vlan_id);
523         dpsw_set_field(tmp_conf, DEI, cfg->dei);
524         dpsw_set_field(tmp_conf, PCP, cfg->pcp);
525         cmd_params->conf = cpu_to_le16(tmp_conf);
526
527         /* send command to mc*/
528         return mc_send_command(mc_io, &cmd);
529 }
530
531 /**
532  * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI)
533  * @mc_io:      Pointer to MC portal's I/O object
534  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
535  * @token:      Token of DPSW object
536  * @if_id:      Interface Identifier
537  * @cfg:        Tag Control Information Configuration
538  *
539  * Return:      Completion status. '0' on Success; Error code otherwise.
540  */
541 int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
542                     u32 cmd_flags,
543                     u16 token,
544                     u16 if_id,
545                     struct dpsw_tci_cfg *cfg)
546 {
547         struct fsl_mc_command cmd = { 0 };
548         struct dpsw_cmd_if_get_tci *cmd_params;
549         struct dpsw_rsp_if_get_tci *rsp_params;
550         int err;
551
552         /* prepare command */
553         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,
554                                           cmd_flags,
555                                           token);
556         cmd_params = (struct dpsw_cmd_if_get_tci *)cmd.params;
557         cmd_params->if_id = cpu_to_le16(if_id);
558
559         /* send command to mc*/
560         err = mc_send_command(mc_io, &cmd);
561         if (err)
562                 return err;
563
564         /* retrieve response parameters */
565         rsp_params = (struct dpsw_rsp_if_get_tci *)cmd.params;
566         cfg->pcp = rsp_params->pcp;
567         cfg->dei = rsp_params->dei;
568         cfg->vlan_id = le16_to_cpu(rsp_params->vlan_id);
569
570         return 0;
571 }
572
573 /**
574  * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state.
575  * @mc_io:      Pointer to MC portal's I/O object
576  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
577  * @token:      Token of DPSW object
578  * @if_id:      Interface Identifier
579  * @cfg:        STP State configuration parameters
580  *
581  * The following STP states are supported -
582  * blocking, listening, learning, forwarding and disabled.
583  *
584  * Return:      Completion status. '0' on Success; Error code otherwise.
585  */
586 int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
587                     u32 cmd_flags,
588                     u16 token,
589                     u16 if_id,
590                     const struct dpsw_stp_cfg *cfg)
591 {
592         struct fsl_mc_command cmd = { 0 };
593         struct dpsw_cmd_if_set_stp *cmd_params;
594
595         /* prepare command */
596         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
597                                           cmd_flags,
598                                           token);
599         cmd_params = (struct dpsw_cmd_if_set_stp *)cmd.params;
600         cmd_params->if_id = cpu_to_le16(if_id);
601         cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);
602         dpsw_set_field(cmd_params->state, STATE, cfg->state);
603
604         /* send command to mc*/
605         return mc_send_command(mc_io, &cmd);
606 }
607
608 /**
609  * dpsw_if_get_counter() - Get specific counter of particular interface
610  * @mc_io:      Pointer to MC portal's I/O object
611  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
612  * @token:      Token of DPSW object
613  * @if_id:      Interface Identifier
614  * @type:       Counter type
615  * @counter:    return value
616  *
617  * Return:      Completion status. '0' on Success; Error code otherwise.
618  */
619 int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
620                         u32 cmd_flags,
621                         u16 token,
622                         u16 if_id,
623                         enum dpsw_counter type,
624                         u64 *counter)
625 {
626         struct fsl_mc_command cmd = { 0 };
627         struct dpsw_cmd_if_get_counter *cmd_params;
628         struct dpsw_rsp_if_get_counter *rsp_params;
629         int err;
630
631         /* prepare command */
632         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
633                                           cmd_flags,
634                                           token);
635         cmd_params = (struct dpsw_cmd_if_get_counter *)cmd.params;
636         cmd_params->if_id = cpu_to_le16(if_id);
637         dpsw_set_field(cmd_params->type, COUNTER_TYPE, type);
638
639         /* send command to mc*/
640         err = mc_send_command(mc_io, &cmd);
641         if (err)
642                 return err;
643
644         /* retrieve response parameters */
645         rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params;
646         *counter = le64_to_cpu(rsp_params->counter);
647
648         return 0;
649 }
650
651 /**
652  * dpsw_if_enable() - Enable Interface
653  * @mc_io:      Pointer to MC portal's I/O object
654  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
655  * @token:      Token of DPSW object
656  * @if_id:      Interface Identifier
657  *
658  * Return:      Completion status. '0' on Success; Error code otherwise.
659  */
660 int dpsw_if_enable(struct fsl_mc_io *mc_io,
661                    u32 cmd_flags,
662                    u16 token,
663                    u16 if_id)
664 {
665         struct fsl_mc_command cmd = { 0 };
666         struct dpsw_cmd_if *cmd_params;
667
668         /* prepare command */
669         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
670                                           cmd_flags,
671                                           token);
672         cmd_params = (struct dpsw_cmd_if *)cmd.params;
673         cmd_params->if_id = cpu_to_le16(if_id);
674
675         /* send command to mc*/
676         return mc_send_command(mc_io, &cmd);
677 }
678
679 /**
680  * dpsw_if_disable() - Disable Interface
681  * @mc_io:      Pointer to MC portal's I/O object
682  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
683  * @token:      Token of DPSW object
684  * @if_id:      Interface Identifier
685  *
686  * Return:      Completion status. '0' on Success; Error code otherwise.
687  */
688 int dpsw_if_disable(struct fsl_mc_io *mc_io,
689                     u32 cmd_flags,
690                     u16 token,
691                     u16 if_id)
692 {
693         struct fsl_mc_command cmd = { 0 };
694         struct dpsw_cmd_if *cmd_params;
695
696         /* prepare command */
697         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
698                                           cmd_flags,
699                                           token);
700         cmd_params = (struct dpsw_cmd_if *)cmd.params;
701         cmd_params->if_id = cpu_to_le16(if_id);
702
703         /* send command to mc*/
704         return mc_send_command(mc_io, &cmd);
705 }
706
707 /**
708  * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.
709  * @mc_io:              Pointer to MC portal's I/O object
710  * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
711  * @token:              Token of DPSW object
712  * @if_id:              Interface Identifier
713  * @frame_length:       Maximum Frame Length
714  *
715  * Return:      Completion status. '0' on Success; Error code otherwise.
716  */
717 int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
718                                  u32 cmd_flags,
719                                  u16 token,
720                                  u16 if_id,
721                                  u16 frame_length)
722 {
723         struct fsl_mc_command cmd = { 0 };
724         struct dpsw_cmd_if_set_max_frame_length *cmd_params;
725
726         /* prepare command */
727         cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
728                                           cmd_flags,
729                                           token);
730         cmd_params = (struct dpsw_cmd_if_set_max_frame_length *)cmd.params;
731         cmd_params->if_id = cpu_to_le16(if_id);
732         cmd_params->frame_length = cpu_to_le16(frame_length);
733
734         /* send command to mc*/
735         return mc_send_command(mc_io, &cmd);
736 }
737
738 /**
739  * dpsw_vlan_add() - Adding new VLAN to DPSW.
740  * @mc_io:      Pointer to MC portal's I/O object
741  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
742  * @token:      Token of DPSW object
743  * @vlan_id:    VLAN Identifier
744  * @cfg:        VLAN configuration
745  *
746  * Only VLAN ID and FDB ID are required parameters here.
747  * 12 bit VLAN ID is defined in IEEE802.1Q.
748  * Adding a duplicate VLAN ID is not allowed.
749  * FDB ID can be shared across multiple VLANs. Shared learning
750  * is obtained by calling dpsw_vlan_add for multiple VLAN IDs
751  * with same fdb_id
752  *
753  * Return:      Completion status. '0' on Success; Error code otherwise.
754  */
755 int dpsw_vlan_add(struct fsl_mc_io *mc_io,
756                   u32 cmd_flags,
757                   u16 token,
758                   u16 vlan_id,
759                   const struct dpsw_vlan_cfg *cfg)
760 {
761         struct fsl_mc_command cmd = { 0 };
762         struct dpsw_vlan_add *cmd_params;
763
764         /* prepare command */
765         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
766                                           cmd_flags,
767                                           token);
768         cmd_params = (struct dpsw_vlan_add *)cmd.params;
769         cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);
770         cmd_params->vlan_id = cpu_to_le16(vlan_id);
771
772         /* send command to mc*/
773         return mc_send_command(mc_io, &cmd);
774 }
775
776 /**
777  * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.
778  * @mc_io:      Pointer to MC portal's I/O object
779  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
780  * @token:      Token of DPSW object
781  * @vlan_id:    VLAN Identifier
782  * @cfg:        Set of interfaces to add
783  *
784  * It adds only interfaces not belonging to this VLAN yet,
785  * otherwise an error is generated and an entire command is
786  * ignored. This function can be called numerous times always
787  * providing required interfaces delta.
788  *
789  * Return:      Completion status. '0' on Success; Error code otherwise.
790  */
791 int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
792                      u32 cmd_flags,
793                      u16 token,
794                      u16 vlan_id,
795                      const struct dpsw_vlan_if_cfg *cfg)
796 {
797         struct fsl_mc_command cmd = { 0 };
798         struct dpsw_cmd_vlan_manage_if *cmd_params;
799
800         /* prepare command */
801         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
802                                           cmd_flags,
803                                           token);
804         cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
805         cmd_params->vlan_id = cpu_to_le16(vlan_id);
806         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
807
808         /* send command to mc*/
809         return mc_send_command(mc_io, &cmd);
810 }
811
812 /**
813  * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be
814  *                              transmitted as untagged.
815  * @mc_io:      Pointer to MC portal's I/O object
816  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
817  * @token:      Token of DPSW object
818  * @vlan_id:    VLAN Identifier
819  * @cfg:        Set of interfaces that should be transmitted as untagged
820  *
821  * These interfaces should already belong to this VLAN.
822  * By default all interfaces are transmitted as tagged.
823  * Providing un-existing interface or untagged interface that is
824  * configured untagged already generates an error and the entire
825  * command is ignored.
826  *
827  * Return:      Completion status. '0' on Success; Error code otherwise.
828  */
829 int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
830                               u32 cmd_flags,
831                               u16 token,
832                               u16 vlan_id,
833                               const struct dpsw_vlan_if_cfg *cfg)
834 {
835         struct fsl_mc_command cmd = { 0 };
836         struct dpsw_cmd_vlan_manage_if *cmd_params;
837
838         /* prepare command */
839         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
840                                           cmd_flags,
841                                           token);
842         cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
843         cmd_params->vlan_id = cpu_to_le16(vlan_id);
844         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
845
846         /* send command to mc*/
847         return mc_send_command(mc_io, &cmd);
848 }
849
850 /**
851  * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.
852  * @mc_io:      Pointer to MC portal's I/O object
853  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
854  * @token:      Token of DPSW object
855  * @vlan_id:    VLAN Identifier
856  * @cfg:        Set of interfaces that should be removed
857  *
858  * Interfaces must belong to this VLAN, otherwise an error
859  * is returned and an the command is ignored
860  *
861  * Return:      Completion status. '0' on Success; Error code otherwise.
862  */
863 int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
864                         u32 cmd_flags,
865                         u16 token,
866                         u16 vlan_id,
867                         const struct dpsw_vlan_if_cfg *cfg)
868 {
869         struct fsl_mc_command cmd = { 0 };
870         struct dpsw_cmd_vlan_manage_if *cmd_params;
871
872         /* prepare command */
873         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
874                                           cmd_flags,
875                                           token);
876         cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
877         cmd_params->vlan_id = cpu_to_le16(vlan_id);
878         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
879
880         /* send command to mc*/
881         return mc_send_command(mc_io, &cmd);
882 }
883
884 /**
885  * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be
886  *              converted from transmitted as untagged to transmit as tagged.
887  * @mc_io:      Pointer to MC portal's I/O object
888  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
889  * @token:      Token of DPSW object
890  * @vlan_id:    VLAN Identifier
891  * @cfg:        Set of interfaces that should be removed
892  *
893  * Interfaces provided by API have to belong to this VLAN and
894  * configured untagged, otherwise an error is returned and the
895  * command is ignored
896  *
897  * Return:      Completion status. '0' on Success; Error code otherwise.
898  */
899 int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
900                                  u32 cmd_flags,
901                                  u16 token,
902                                  u16 vlan_id,
903                                  const struct dpsw_vlan_if_cfg *cfg)
904 {
905         struct fsl_mc_command cmd = { 0 };
906         struct dpsw_cmd_vlan_manage_if *cmd_params;
907
908         /* prepare command */
909         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
910                                           cmd_flags,
911                                           token);
912         cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
913         cmd_params->vlan_id = cpu_to_le16(vlan_id);
914         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
915
916         /* send command to mc*/
917         return mc_send_command(mc_io, &cmd);
918 }
919
920 /**
921  * dpsw_vlan_remove() - Remove an entire VLAN
922  * @mc_io:      Pointer to MC portal's I/O object
923  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
924  * @token:      Token of DPSW object
925  * @vlan_id:    VLAN Identifier
926  *
927  * Return:      Completion status. '0' on Success; Error code otherwise.
928  */
929 int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
930                      u32 cmd_flags,
931                      u16 token,
932                      u16 vlan_id)
933 {
934         struct fsl_mc_command cmd = { 0 };
935         struct dpsw_cmd_vlan_remove *cmd_params;
936
937         /* prepare command */
938         cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
939                                           cmd_flags,
940                                           token);
941         cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params;
942         cmd_params->vlan_id = cpu_to_le16(vlan_id);
943
944         /* send command to mc*/
945         return mc_send_command(mc_io, &cmd);
946 }
947
948 /**
949  * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table
950  * @mc_io:      Pointer to MC portal's I/O object
951  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
952  * @token:      Token of DPSW object
953  * @fdb_id:     Forwarding Database Identifier
954  * @cfg:        Unicast entry configuration
955  *
956  * Return:      Completion status. '0' on Success; Error code otherwise.
957  */
958 int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
959                          u32 cmd_flags,
960                          u16 token,
961                          u16 fdb_id,
962                          const struct dpsw_fdb_unicast_cfg *cfg)
963 {
964         struct fsl_mc_command cmd = { 0 };
965         struct dpsw_cmd_fdb_unicast_op *cmd_params;
966         int i;
967
968         /* prepare command */
969         cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
970                                           cmd_flags,
971                                           token);
972         cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
973         cmd_params->fdb_id = cpu_to_le16(fdb_id);
974         cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
975         for (i = 0; i < 6; i++)
976                 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
977         dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
978
979         /* send command to mc*/
980         return mc_send_command(mc_io, &cmd);
981 }
982
983 /**
984  * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
985  * @mc_io:      Pointer to MC portal's I/O object
986  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
987  * @token:      Token of DPSW object
988  * @fdb_id:     Forwarding Database Identifier
989  * @cfg:        Unicast entry configuration
990  *
991  * Return:      Completion status. '0' on Success; Error code otherwise.
992  */
993 int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
994                             u32 cmd_flags,
995                             u16 token,
996                             u16 fdb_id,
997                             const struct dpsw_fdb_unicast_cfg *cfg)
998 {
999         struct fsl_mc_command cmd = { 0 };
1000         struct dpsw_cmd_fdb_unicast_op *cmd_params;
1001         int i;
1002
1003         /* prepare command */
1004         cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
1005                                           cmd_flags,
1006                                           token);
1007         cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
1008         cmd_params->fdb_id = cpu_to_le16(fdb_id);
1009         for (i = 0; i < 6; i++)
1010                 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1011         cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
1012         dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1013
1014         /* send command to mc*/
1015         return mc_send_command(mc_io, &cmd);
1016 }
1017
1018 /**
1019  * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
1020  * @mc_io:      Pointer to MC portal's I/O object
1021  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1022  * @token:      Token of DPSW object
1023  * @fdb_id:     Forwarding Database Identifier
1024  * @cfg:        Multicast entry configuration
1025  *
1026  * If group doesn't exist, it will be created.
1027  * It adds only interfaces not belonging to this multicast group
1028  * yet, otherwise error will be generated and the command is
1029  * ignored.
1030  * This function may be called numerous times always providing
1031  * required interfaces delta.
1032  *
1033  * Return:      Completion status. '0' on Success; Error code otherwise.
1034  */
1035 int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
1036                            u32 cmd_flags,
1037                            u16 token,
1038                            u16 fdb_id,
1039                            const struct dpsw_fdb_multicast_cfg *cfg)
1040 {
1041         struct fsl_mc_command cmd = { 0 };
1042         struct dpsw_cmd_fdb_multicast_op *cmd_params;
1043         int i;
1044
1045         /* prepare command */
1046         cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
1047                                           cmd_flags,
1048                                           token);
1049         cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
1050         cmd_params->fdb_id = cpu_to_le16(fdb_id);
1051         cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
1052         dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1053         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
1054         for (i = 0; i < 6; i++)
1055                 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1056
1057         /* send command to mc*/
1058         return mc_send_command(mc_io, &cmd);
1059 }
1060
1061 /**
1062  * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
1063  *                              group.
1064  * @mc_io:      Pointer to MC portal's I/O object
1065  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1066  * @token:      Token of DPSW object
1067  * @fdb_id:     Forwarding Database Identifier
1068  * @cfg:        Multicast entry configuration
1069  *
1070  * Interfaces provided by this API have to exist in the group,
1071  * otherwise an error will be returned and an entire command
1072  * ignored. If there is no interface left in the group,
1073  * an entire group is deleted
1074  *
1075  * Return:      Completion status. '0' on Success; Error code otherwise.
1076  */
1077 int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
1078                               u32 cmd_flags,
1079                               u16 token,
1080                               u16 fdb_id,
1081                               const struct dpsw_fdb_multicast_cfg *cfg)
1082 {
1083         struct fsl_mc_command cmd = { 0 };
1084         struct dpsw_cmd_fdb_multicast_op *cmd_params;
1085         int i;
1086
1087         /* prepare command */
1088         cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
1089                                           cmd_flags,
1090                                           token);
1091         cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
1092         cmd_params->fdb_id = cpu_to_le16(fdb_id);
1093         cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
1094         dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1095         build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
1096         for (i = 0; i < 6; i++)
1097                 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1098
1099         /* send command to mc*/
1100         return mc_send_command(mc_io, &cmd);
1101 }
1102
1103 /**
1104  * dpsw_fdb_set_learning_mode() - Define FDB learning mode
1105  * @mc_io:      Pointer to MC portal's I/O object
1106  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1107  * @token:      Token of DPSW object
1108  * @fdb_id:     Forwarding Database Identifier
1109  * @mode:       Learning mode
1110  *
1111  * Return:      Completion status. '0' on Success; Error code otherwise.
1112  */
1113 int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
1114                                u32 cmd_flags,
1115                                u16 token,
1116                                u16 fdb_id,
1117                                enum dpsw_fdb_learning_mode mode)
1118 {
1119         struct fsl_mc_command cmd = { 0 };
1120         struct dpsw_cmd_fdb_set_learning_mode *cmd_params;
1121
1122         /* prepare command */
1123         cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
1124                                           cmd_flags,
1125                                           token);
1126         cmd_params = (struct dpsw_cmd_fdb_set_learning_mode *)cmd.params;
1127         cmd_params->fdb_id = cpu_to_le16(fdb_id);
1128         dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode);
1129
1130         /* send command to mc*/
1131         return mc_send_command(mc_io, &cmd);
1132 }
1133
1134 /**
1135  * dpsw_get_api_version() - Get Data Path Switch API version
1136  * @mc_io:      Pointer to MC portal's I/O object
1137  * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1138  * @major_ver:  Major version of data path switch API
1139  * @minor_ver:  Minor version of data path switch API
1140  *
1141  * Return:  '0' on Success; Error code otherwise.
1142  */
1143 int dpsw_get_api_version(struct fsl_mc_io *mc_io,
1144                          u32 cmd_flags,
1145                          u16 *major_ver,
1146                          u16 *minor_ver)
1147 {
1148         struct fsl_mc_command cmd = { 0 };
1149         struct dpsw_rsp_get_api_version *rsp_params;
1150         int err;
1151
1152         cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,
1153                                           cmd_flags,
1154                                           0);
1155
1156         err = mc_send_command(mc_io, &cmd);
1157         if (err)
1158                 return err;
1159
1160         rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params;
1161         *major_ver = le16_to_cpu(rsp_params->version_major);
1162         *minor_ver = le16_to_cpu(rsp_params->version_minor);
1163
1164         return 0;
1165 }