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 
build_if_id_bitmap(__le64 * bmap,const u16 * id,const u16 num_ifs)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  */
dpsw_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int dpsw_id,u16 * token)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  */
dpsw_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)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  */
dpsw_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)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  */
dpsw_disable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)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  */
dpsw_reset(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)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  */
dpsw_set_irq_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u8 en)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  */
dpsw_set_irq_mask(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 mask)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  */
dpsw_get_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 * status)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  */
dpsw_clear_irq_status(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u8 irq_index,u32 status)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  */
dpsw_get_attributes(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,struct dpsw_attr * attr)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  */
dpsw_if_set_link_cfg(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,struct dpsw_link_cfg * cfg)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  */
dpsw_if_get_link_state(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,struct dpsw_link_state * state)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  */
dpsw_if_set_flooding(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u8 en)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  */
dpsw_if_set_broadcast(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u8 en)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  */
dpsw_if_set_tci(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,const struct dpsw_tci_cfg * cfg)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  */
dpsw_if_get_tci(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,struct dpsw_tci_cfg * cfg)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  */
dpsw_if_set_stp(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,const struct dpsw_stp_cfg * cfg)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  */
dpsw_if_get_counter(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,enum dpsw_counter type,u64 * counter)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  */
dpsw_if_enable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id)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  */
dpsw_if_disable(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id)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  */
dpsw_if_set_max_frame_length(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u16 frame_length)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  */
dpsw_vlan_add(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id,const struct dpsw_vlan_cfg * cfg)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  */
dpsw_vlan_add_if(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id,const struct dpsw_vlan_if_cfg * cfg)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  */
dpsw_vlan_add_if_untagged(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id,const struct dpsw_vlan_if_cfg * cfg)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  */
dpsw_vlan_remove_if(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id,const struct dpsw_vlan_if_cfg * cfg)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  */
dpsw_vlan_remove_if_untagged(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id,const struct dpsw_vlan_if_cfg * cfg)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  */
dpsw_vlan_remove(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 vlan_id)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  */
dpsw_fdb_add_unicast(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,const struct dpsw_fdb_unicast_cfg * cfg)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_dump() - Dump the content of FDB table into memory.
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  * @iova_addr:	Data will be stored here as an array of struct fdb_dump_entry
990  * @iova_size:	Memory size allocated at iova_addr
991  * @num_entries:Number of entries written at iova_addr
992  *
993  * Return:	Completion status. '0' on Success; Error code otherwise.
994  *
995  * The memory allocated at iova_addr must be initialized with zero before
996  * command execution. If the FDB table does not fit into memory MC will stop
997  * after the memory is filled up.
998  * The struct fdb_dump_entry array must be parsed until the end of memory
999  * area or until an entry with mac_addr set to zero is found.
1000  */
dpsw_fdb_dump(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,u64 iova_addr,u32 iova_size,u16 * num_entries)1001 int dpsw_fdb_dump(struct fsl_mc_io *mc_io,
1002 		  u32 cmd_flags,
1003 		  u16 token,
1004 		  u16 fdb_id,
1005 		  u64 iova_addr,
1006 		  u32 iova_size,
1007 		  u16 *num_entries)
1008 {
1009 	struct dpsw_cmd_fdb_dump *cmd_params;
1010 	struct dpsw_rsp_fdb_dump *rsp_params;
1011 	struct fsl_mc_command cmd = { 0 };
1012 	int err;
1013 
1014 	/* prepare command */
1015 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP,
1016 					  cmd_flags,
1017 					  token);
1018 	cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params;
1019 	cmd_params->fdb_id = cpu_to_le16(fdb_id);
1020 	cmd_params->iova_addr = cpu_to_le64(iova_addr);
1021 	cmd_params->iova_size = cpu_to_le32(iova_size);
1022 
1023 	/* send command to mc */
1024 	err = mc_send_command(mc_io, &cmd);
1025 	if (err)
1026 		return err;
1027 
1028 	rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params;
1029 	*num_entries = le16_to_cpu(rsp_params->num_entries);
1030 
1031 	return 0;
1032 }
1033 
1034 /**
1035  * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
1036  * @mc_io:	Pointer to MC portal's I/O object
1037  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1038  * @token:	Token of DPSW object
1039  * @fdb_id:	Forwarding Database Identifier
1040  * @cfg:	Unicast entry configuration
1041  *
1042  * Return:	Completion status. '0' on Success; Error code otherwise.
1043  */
dpsw_fdb_remove_unicast(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,const struct dpsw_fdb_unicast_cfg * cfg)1044 int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
1045 			    u32 cmd_flags,
1046 			    u16 token,
1047 			    u16 fdb_id,
1048 			    const struct dpsw_fdb_unicast_cfg *cfg)
1049 {
1050 	struct fsl_mc_command cmd = { 0 };
1051 	struct dpsw_cmd_fdb_unicast_op *cmd_params;
1052 	int i;
1053 
1054 	/* prepare command */
1055 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
1056 					  cmd_flags,
1057 					  token);
1058 	cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
1059 	cmd_params->fdb_id = cpu_to_le16(fdb_id);
1060 	for (i = 0; i < 6; i++)
1061 		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1062 	cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
1063 	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1064 
1065 	/* send command to mc*/
1066 	return mc_send_command(mc_io, &cmd);
1067 }
1068 
1069 /**
1070  * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
1071  * @mc_io:	Pointer to MC portal's I/O object
1072  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1073  * @token:	Token of DPSW object
1074  * @fdb_id:	Forwarding Database Identifier
1075  * @cfg:	Multicast entry configuration
1076  *
1077  * If group doesn't exist, it will be created.
1078  * It adds only interfaces not belonging to this multicast group
1079  * yet, otherwise error will be generated and the command is
1080  * ignored.
1081  * This function may be called numerous times always providing
1082  * required interfaces delta.
1083  *
1084  * Return:	Completion status. '0' on Success; Error code otherwise.
1085  */
dpsw_fdb_add_multicast(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,const struct dpsw_fdb_multicast_cfg * cfg)1086 int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
1087 			   u32 cmd_flags,
1088 			   u16 token,
1089 			   u16 fdb_id,
1090 			   const struct dpsw_fdb_multicast_cfg *cfg)
1091 {
1092 	struct fsl_mc_command cmd = { 0 };
1093 	struct dpsw_cmd_fdb_multicast_op *cmd_params;
1094 	int i;
1095 
1096 	/* prepare command */
1097 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
1098 					  cmd_flags,
1099 					  token);
1100 	cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
1101 	cmd_params->fdb_id = cpu_to_le16(fdb_id);
1102 	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
1103 	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1104 	build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
1105 	for (i = 0; i < 6; i++)
1106 		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1107 
1108 	/* send command to mc*/
1109 	return mc_send_command(mc_io, &cmd);
1110 }
1111 
1112 /**
1113  * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
1114  *				group.
1115  * @mc_io:	Pointer to MC portal's I/O object
1116  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1117  * @token:	Token of DPSW object
1118  * @fdb_id:	Forwarding Database Identifier
1119  * @cfg:	Multicast entry configuration
1120  *
1121  * Interfaces provided by this API have to exist in the group,
1122  * otherwise an error will be returned and an entire command
1123  * ignored. If there is no interface left in the group,
1124  * an entire group is deleted
1125  *
1126  * Return:	Completion status. '0' on Success; Error code otherwise.
1127  */
dpsw_fdb_remove_multicast(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,const struct dpsw_fdb_multicast_cfg * cfg)1128 int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
1129 			      u32 cmd_flags,
1130 			      u16 token,
1131 			      u16 fdb_id,
1132 			      const struct dpsw_fdb_multicast_cfg *cfg)
1133 {
1134 	struct fsl_mc_command cmd = { 0 };
1135 	struct dpsw_cmd_fdb_multicast_op *cmd_params;
1136 	int i;
1137 
1138 	/* prepare command */
1139 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
1140 					  cmd_flags,
1141 					  token);
1142 	cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
1143 	cmd_params->fdb_id = cpu_to_le16(fdb_id);
1144 	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
1145 	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
1146 	build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
1147 	for (i = 0; i < 6; i++)
1148 		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
1149 
1150 	/* send command to mc*/
1151 	return mc_send_command(mc_io, &cmd);
1152 }
1153 
1154 /**
1155  * dpsw_fdb_set_learning_mode() - Define FDB learning mode
1156  * @mc_io:	Pointer to MC portal's I/O object
1157  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1158  * @token:	Token of DPSW object
1159  * @fdb_id:	Forwarding Database Identifier
1160  * @mode:	Learning mode
1161  *
1162  * Return:	Completion status. '0' on Success; Error code otherwise.
1163  */
dpsw_fdb_set_learning_mode(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 fdb_id,enum dpsw_fdb_learning_mode mode)1164 int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
1165 			       u32 cmd_flags,
1166 			       u16 token,
1167 			       u16 fdb_id,
1168 			       enum dpsw_fdb_learning_mode mode)
1169 {
1170 	struct fsl_mc_command cmd = { 0 };
1171 	struct dpsw_cmd_fdb_set_learning_mode *cmd_params;
1172 
1173 	/* prepare command */
1174 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
1175 					  cmd_flags,
1176 					  token);
1177 	cmd_params = (struct dpsw_cmd_fdb_set_learning_mode *)cmd.params;
1178 	cmd_params->fdb_id = cpu_to_le16(fdb_id);
1179 	dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode);
1180 
1181 	/* send command to mc*/
1182 	return mc_send_command(mc_io, &cmd);
1183 }
1184 
1185 /**
1186  * dpsw_get_api_version() - Get Data Path Switch API version
1187  * @mc_io:	Pointer to MC portal's I/O object
1188  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1189  * @major_ver:	Major version of data path switch API
1190  * @minor_ver:	Minor version of data path switch API
1191  *
1192  * Return:  '0' on Success; Error code otherwise.
1193  */
dpsw_get_api_version(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 * major_ver,u16 * minor_ver)1194 int dpsw_get_api_version(struct fsl_mc_io *mc_io,
1195 			 u32 cmd_flags,
1196 			 u16 *major_ver,
1197 			 u16 *minor_ver)
1198 {
1199 	struct fsl_mc_command cmd = { 0 };
1200 	struct dpsw_rsp_get_api_version *rsp_params;
1201 	int err;
1202 
1203 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,
1204 					  cmd_flags,
1205 					  0);
1206 
1207 	err = mc_send_command(mc_io, &cmd);
1208 	if (err)
1209 		return err;
1210 
1211 	rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params;
1212 	*major_ver = le16_to_cpu(rsp_params->version_major);
1213 	*minor_ver = le16_to_cpu(rsp_params->version_minor);
1214 
1215 	return 0;
1216 }
1217 
1218 /**
1219  * dpsw_if_get_port_mac_addr()
1220  * @mc_io:	Pointer to MC portal's I/O object
1221  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1222  * @token:	Token of DPSW object
1223  * @if_id:	Interface Identifier
1224  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1225  *
1226  * Return:	Completion status. '0' on Success; Error code otherwise.
1227  */
dpsw_if_get_port_mac_addr(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u8 mac_addr[6])1228 int dpsw_if_get_port_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1229 			      u16 if_id, u8 mac_addr[6])
1230 {
1231 	struct dpsw_rsp_if_get_mac_addr *rsp_params;
1232 	struct fsl_mc_command cmd = { 0 };
1233 	struct dpsw_cmd_if *cmd_params;
1234 	int err, i;
1235 
1236 	/* prepare command */
1237 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_PORT_MAC_ADDR,
1238 					  cmd_flags,
1239 					  token);
1240 	cmd_params = (struct dpsw_cmd_if *)cmd.params;
1241 	cmd_params->if_id = cpu_to_le16(if_id);
1242 
1243 	/* send command to mc*/
1244 	err = mc_send_command(mc_io, &cmd);
1245 	if (err)
1246 		return err;
1247 
1248 	/* retrieve response parameters */
1249 	rsp_params = (struct dpsw_rsp_if_get_mac_addr *)cmd.params;
1250 	for (i = 0; i < 6; i++)
1251 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1252 
1253 	return 0;
1254 }
1255 
1256 /**
1257  * dpsw_if_get_primary_mac_addr()
1258  * @mc_io:	Pointer to MC portal's I/O object
1259  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1260  * @token:	Token of DPSW object
1261  * @if_id:	Interface Identifier
1262  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1263  *
1264  * Return:	Completion status. '0' on Success; Error code otherwise.
1265  */
dpsw_if_get_primary_mac_addr(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u8 mac_addr[6])1266 int dpsw_if_get_primary_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags,
1267 				 u16 token, u16 if_id, u8 mac_addr[6])
1268 {
1269 	struct dpsw_rsp_if_get_mac_addr *rsp_params;
1270 	struct fsl_mc_command cmd = { 0 };
1271 	struct dpsw_cmd_if *cmd_params;
1272 	int err, i;
1273 
1274 	/* prepare command */
1275 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_PRIMARY_MAC_ADDR,
1276 					  cmd_flags,
1277 					  token);
1278 	cmd_params = (struct dpsw_cmd_if *)cmd.params;
1279 	cmd_params->if_id = cpu_to_le16(if_id);
1280 
1281 	/* send command to mc*/
1282 	err = mc_send_command(mc_io, &cmd);
1283 	if (err)
1284 		return err;
1285 
1286 	/* retrieve response parameters */
1287 	rsp_params = (struct dpsw_rsp_if_get_mac_addr *)cmd.params;
1288 	for (i = 0; i < 6; i++)
1289 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1290 
1291 	return 0;
1292 }
1293 
1294 /**
1295  * dpsw_if_set_primary_mac_addr()
1296  * @mc_io:	Pointer to MC portal's I/O object
1297  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1298  * @token:	Token of DPSW object
1299  * @if_id:	Interface Identifier
1300  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1301  *
1302  * Return:	Completion status. '0' on Success; Error code otherwise.
1303  */
dpsw_if_set_primary_mac_addr(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,u16 if_id,u8 mac_addr[6])1304 int dpsw_if_set_primary_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags,
1305 				 u16 token, u16 if_id, u8 mac_addr[6])
1306 {
1307 	struct dpsw_cmd_if_set_mac_addr *cmd_params;
1308 	struct fsl_mc_command cmd = { 0 };
1309 	int i;
1310 
1311 	/* prepare command */
1312 	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_PRIMARY_MAC_ADDR,
1313 					  cmd_flags,
1314 					  token);
1315 	cmd_params = (struct dpsw_cmd_if_set_mac_addr *)cmd.params;
1316 	cmd_params->if_id = cpu_to_le16(if_id);
1317 	for (i = 0; i < 6; i++)
1318 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1319 
1320 	/* send command to mc*/
1321 	return mc_send_command(mc_io, &cmd);
1322 }
1323