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_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  */
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)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  */
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)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  */
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)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  */
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)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  */
dpsw_get_api_version(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 * major_ver,u16 * minor_ver)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 }
1166