1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2014-2016 Freescale Semiconductor Inc.
4 * Copyright 2017-2018 NXP
8 #include <linux/fsl/mc.h>
12 static void build_if_id_bitmap(__le64 *bmap,
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));
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
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
39 * Return: '0' on Success; Error code otherwise.
41 int dpsw_open(struct fsl_mc_io *mc_io,
46 struct fsl_mc_command cmd = { 0 };
47 struct dpsw_cmd_open *cmd_params;
51 cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
54 cmd_params = (struct dpsw_cmd_open *)cmd.params;
55 cmd_params->dpsw_id = cpu_to_le32(dpsw_id);
57 /* send command to mc*/
58 err = mc_send_command(mc_io, &cmd);
62 /* retrieve response parameters */
63 *token = mc_cmd_hdr_read_token(&cmd);
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
74 * After this function is called, no further operations are
75 * allowed on the object without opening a new control session.
77 * Return: '0' on Success; Error code otherwise.
79 int dpsw_close(struct fsl_mc_io *mc_io,
83 struct fsl_mc_command cmd = { 0 };
86 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
90 /* send command to mc*/
91 return mc_send_command(mc_io, &cmd);
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
100 * Return: Completion status. '0' on Success; Error code otherwise.
102 int dpsw_enable(struct fsl_mc_io *mc_io,
106 struct fsl_mc_command cmd = { 0 };
108 /* prepare command */
109 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
113 /* send command to mc*/
114 return mc_send_command(mc_io, &cmd);
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
123 * Return: Completion status. '0' on Success; Error code otherwise.
125 int dpsw_disable(struct fsl_mc_io *mc_io,
129 struct fsl_mc_command cmd = { 0 };
131 /* prepare command */
132 cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
136 /* send command to mc*/
137 return mc_send_command(mc_io, &cmd);
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
146 * Return: '0' on Success; Error code otherwise.
148 int dpsw_reset(struct fsl_mc_io *mc_io,
152 struct fsl_mc_command cmd = { 0 };
154 /* prepare command */
155 cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
159 /* send command to mc*/
160 return mc_send_command(mc_io, &cmd);
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
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
176 * Return: '0' on Success; Error code otherwise.
178 int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
184 struct fsl_mc_command cmd = { 0 };
185 struct dpsw_cmd_set_irq_enable *cmd_params;
187 /* prepare command */
188 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
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;
195 /* send command to mc*/
196 return mc_send_command(mc_io, &cmd);
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;
208 * 1 = consider event for asserting IRQ
210 * Every interrupt can have up to 32 causes and the interrupt model supports
211 * masking/unmasking each cause independently
213 * Return: '0' on Success; Error code otherwise.
215 int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
221 struct fsl_mc_command cmd = { 0 };
222 struct dpsw_cmd_set_irq_mask *cmd_params;
224 /* prepare command */
225 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
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;
232 /* send command to mc*/
233 return mc_send_command(mc_io, &cmd);
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
246 * Return: '0' on Success; Error code otherwise.
248 int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
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;
259 /* prepare command */
260 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
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;
267 /* send command to mc*/
268 err = mc_send_command(mc_io, &cmd);
272 /* retrieve response parameters */
273 rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params;
274 *status = le32_to_cpu(rsp_params->status);
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:
287 * 1 = clear status bit
289 * Return: '0' on Success; Error code otherwise.
291 int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
297 struct fsl_mc_command cmd = { 0 };
298 struct dpsw_cmd_clear_irq_status *cmd_params;
300 /* prepare command */
301 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
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;
308 /* send command to mc*/
309 return mc_send_command(mc_io, &cmd);
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
319 * Return: Completion status. '0' on Success; Error code otherwise.
321 int dpsw_get_attributes(struct fsl_mc_io *mc_io,
324 struct dpsw_attr *attr)
326 struct fsl_mc_command cmd = { 0 };
327 struct dpsw_rsp_get_attr *rsp_params;
330 /* prepare command */
331 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
335 /* send command to mc*/
336 err = mc_send_command(mc_io, &cmd);
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,
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
368 * Return: '0' on Success; Error code otherwise.
370 int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io,
374 struct dpsw_link_cfg *cfg)
376 struct fsl_mc_command cmd = { 0 };
377 struct dpsw_cmd_if_set_link_cfg *cmd_params;
379 /* prepare command */
380 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,
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);
388 /* send command to mc*/
389 return mc_send_command(mc_io, &cmd);
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
400 * @Return '0' on Success; Error code otherwise.
402 int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
406 struct dpsw_link_state *state)
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;
413 /* prepare command */
414 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
417 cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params;
418 cmd_params->if_id = cpu_to_le16(if_id);
420 /* send command to mc*/
421 err = mc_send_command(mc_io, &cmd);
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);
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
442 * Return: Completion status. '0' on Success; Error code otherwise.
444 int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
450 struct fsl_mc_command cmd = { 0 };
451 struct dpsw_cmd_if_set_flooding *cmd_params;
453 /* prepare command */
454 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING,
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);
461 /* send command to mc*/
462 return mc_send_command(mc_io, &cmd);
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
473 * Return: Completion status. '0' on Success; Error code otherwise.
475 int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
481 struct fsl_mc_command cmd = { 0 };
482 struct dpsw_cmd_if_set_broadcast *cmd_params;
484 /* prepare command */
485 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_BROADCAST,
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);
492 /* send command to mc*/
493 return mc_send_command(mc_io, &cmd);
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
504 * Return: Completion status. '0' on Success; Error code otherwise.
506 int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
510 const struct dpsw_tci_cfg *cfg)
512 struct fsl_mc_command cmd = { 0 };
513 struct dpsw_cmd_if_set_tci *cmd_params;
516 /* prepare command */
517 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
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);
527 /* send command to mc*/
528 return mc_send_command(mc_io, &cmd);
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
539 * Return: Completion status. '0' on Success; Error code otherwise.
541 int dpsw_if_get_tci(struct fsl_mc_io *mc_io,
545 struct dpsw_tci_cfg *cfg)
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;
552 /* prepare command */
553 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,
556 cmd_params = (struct dpsw_cmd_if_get_tci *)cmd.params;
557 cmd_params->if_id = cpu_to_le16(if_id);
559 /* send command to mc*/
560 err = mc_send_command(mc_io, &cmd);
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);
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
581 * The following STP states are supported -
582 * blocking, listening, learning, forwarding and disabled.
584 * Return: Completion status. '0' on Success; Error code otherwise.
586 int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
590 const struct dpsw_stp_cfg *cfg)
592 struct fsl_mc_command cmd = { 0 };
593 struct dpsw_cmd_if_set_stp *cmd_params;
595 /* prepare command */
596 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
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);
604 /* send command to mc*/
605 return mc_send_command(mc_io, &cmd);
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
617 * Return: Completion status. '0' on Success; Error code otherwise.
619 int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
623 enum dpsw_counter type,
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;
631 /* prepare command */
632 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
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);
639 /* send command to mc*/
640 err = mc_send_command(mc_io, &cmd);
644 /* retrieve response parameters */
645 rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params;
646 *counter = le64_to_cpu(rsp_params->counter);
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
658 * Return: Completion status. '0' on Success; Error code otherwise.
660 int dpsw_if_enable(struct fsl_mc_io *mc_io,
665 struct fsl_mc_command cmd = { 0 };
666 struct dpsw_cmd_if *cmd_params;
668 /* prepare command */
669 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
672 cmd_params = (struct dpsw_cmd_if *)cmd.params;
673 cmd_params->if_id = cpu_to_le16(if_id);
675 /* send command to mc*/
676 return mc_send_command(mc_io, &cmd);
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
686 * Return: Completion status. '0' on Success; Error code otherwise.
688 int dpsw_if_disable(struct fsl_mc_io *mc_io,
693 struct fsl_mc_command cmd = { 0 };
694 struct dpsw_cmd_if *cmd_params;
696 /* prepare command */
697 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
700 cmd_params = (struct dpsw_cmd_if *)cmd.params;
701 cmd_params->if_id = cpu_to_le16(if_id);
703 /* send command to mc*/
704 return mc_send_command(mc_io, &cmd);
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
715 * Return: Completion status. '0' on Success; Error code otherwise.
717 int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
723 struct fsl_mc_command cmd = { 0 };
724 struct dpsw_cmd_if_set_max_frame_length *cmd_params;
726 /* prepare command */
727 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
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);
734 /* send command to mc*/
735 return mc_send_command(mc_io, &cmd);
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
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
753 * Return: Completion status. '0' on Success; Error code otherwise.
755 int dpsw_vlan_add(struct fsl_mc_io *mc_io,
759 const struct dpsw_vlan_cfg *cfg)
761 struct fsl_mc_command cmd = { 0 };
762 struct dpsw_vlan_add *cmd_params;
764 /* prepare command */
765 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
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);
772 /* send command to mc*/
773 return mc_send_command(mc_io, &cmd);
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
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.
789 * Return: Completion status. '0' on Success; Error code otherwise.
791 int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
795 const struct dpsw_vlan_if_cfg *cfg)
797 struct fsl_mc_command cmd = { 0 };
798 struct dpsw_cmd_vlan_manage_if *cmd_params;
800 /* prepare command */
801 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
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);
808 /* send command to mc*/
809 return mc_send_command(mc_io, &cmd);
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
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.
827 * Return: Completion status. '0' on Success; Error code otherwise.
829 int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
833 const struct dpsw_vlan_if_cfg *cfg)
835 struct fsl_mc_command cmd = { 0 };
836 struct dpsw_cmd_vlan_manage_if *cmd_params;
838 /* prepare command */
839 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
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);
846 /* send command to mc*/
847 return mc_send_command(mc_io, &cmd);
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
858 * Interfaces must belong to this VLAN, otherwise an error
859 * is returned and an the command is ignored
861 * Return: Completion status. '0' on Success; Error code otherwise.
863 int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
867 const struct dpsw_vlan_if_cfg *cfg)
869 struct fsl_mc_command cmd = { 0 };
870 struct dpsw_cmd_vlan_manage_if *cmd_params;
872 /* prepare command */
873 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
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);
880 /* send command to mc*/
881 return mc_send_command(mc_io, &cmd);
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
893 * Interfaces provided by API have to belong to this VLAN and
894 * configured untagged, otherwise an error is returned and the
897 * Return: Completion status. '0' on Success; Error code otherwise.
899 int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
903 const struct dpsw_vlan_if_cfg *cfg)
905 struct fsl_mc_command cmd = { 0 };
906 struct dpsw_cmd_vlan_manage_if *cmd_params;
908 /* prepare command */
909 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
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);
916 /* send command to mc*/
917 return mc_send_command(mc_io, &cmd);
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
927 * Return: Completion status. '0' on Success; Error code otherwise.
929 int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
934 struct fsl_mc_command cmd = { 0 };
935 struct dpsw_cmd_vlan_remove *cmd_params;
937 /* prepare command */
938 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
941 cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params;
942 cmd_params->vlan_id = cpu_to_le16(vlan_id);
944 /* send command to mc*/
945 return mc_send_command(mc_io, &cmd);
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
956 * Return: Completion status. '0' on Success; Error code otherwise.
958 int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
962 const struct dpsw_fdb_unicast_cfg *cfg)
964 struct fsl_mc_command cmd = { 0 };
965 struct dpsw_cmd_fdb_unicast_op *cmd_params;
968 /* prepare command */
969 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
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);
979 /* send command to mc*/
980 return mc_send_command(mc_io, &cmd);
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
993 * Return: Completion status. '0' on Success; Error code otherwise.
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.
1001 int dpsw_fdb_dump(struct fsl_mc_io *mc_io,
1009 struct dpsw_cmd_fdb_dump *cmd_params;
1010 struct dpsw_rsp_fdb_dump *rsp_params;
1011 struct fsl_mc_command cmd = { 0 };
1014 /* prepare command */
1015 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP,
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);
1023 /* send command to mc */
1024 err = mc_send_command(mc_io, &cmd);
1028 rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params;
1029 *num_entries = le16_to_cpu(rsp_params->num_entries);
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
1042 * Return: Completion status. '0' on Success; Error code otherwise.
1044 int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
1048 const struct dpsw_fdb_unicast_cfg *cfg)
1050 struct fsl_mc_command cmd = { 0 };
1051 struct dpsw_cmd_fdb_unicast_op *cmd_params;
1054 /* prepare command */
1055 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
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);
1065 /* send command to mc*/
1066 return mc_send_command(mc_io, &cmd);
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
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
1081 * This function may be called numerous times always providing
1082 * required interfaces delta.
1084 * Return: Completion status. '0' on Success; Error code otherwise.
1086 int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
1090 const struct dpsw_fdb_multicast_cfg *cfg)
1092 struct fsl_mc_command cmd = { 0 };
1093 struct dpsw_cmd_fdb_multicast_op *cmd_params;
1096 /* prepare command */
1097 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
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];
1108 /* send command to mc*/
1109 return mc_send_command(mc_io, &cmd);
1113 * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
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
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
1126 * Return: Completion status. '0' on Success; Error code otherwise.
1128 int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
1132 const struct dpsw_fdb_multicast_cfg *cfg)
1134 struct fsl_mc_command cmd = { 0 };
1135 struct dpsw_cmd_fdb_multicast_op *cmd_params;
1138 /* prepare command */
1139 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
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];
1150 /* send command to mc*/
1151 return mc_send_command(mc_io, &cmd);
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
1162 * Return: Completion status. '0' on Success; Error code otherwise.
1164 int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
1168 enum dpsw_fdb_learning_mode mode)
1170 struct fsl_mc_command cmd = { 0 };
1171 struct dpsw_cmd_fdb_set_learning_mode *cmd_params;
1173 /* prepare command */
1174 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
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);
1181 /* send command to mc*/
1182 return mc_send_command(mc_io, &cmd);
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
1192 * Return: '0' on Success; Error code otherwise.
1194 int dpsw_get_api_version(struct fsl_mc_io *mc_io,
1199 struct fsl_mc_command cmd = { 0 };
1200 struct dpsw_rsp_get_api_version *rsp_params;
1203 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,
1207 err = mc_send_command(mc_io, &cmd);
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);
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
1226 * Return: Completion status. '0' on Success; Error code otherwise.
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])
1231 struct dpsw_rsp_if_get_mac_addr *rsp_params;
1232 struct fsl_mc_command cmd = { 0 };
1233 struct dpsw_cmd_if *cmd_params;
1236 /* prepare command */
1237 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_PORT_MAC_ADDR,
1240 cmd_params = (struct dpsw_cmd_if *)cmd.params;
1241 cmd_params->if_id = cpu_to_le16(if_id);
1243 /* send command to mc*/
1244 err = mc_send_command(mc_io, &cmd);
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];
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
1264 * Return: Completion status. '0' on Success; Error code otherwise.
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])
1269 struct dpsw_rsp_if_get_mac_addr *rsp_params;
1270 struct fsl_mc_command cmd = { 0 };
1271 struct dpsw_cmd_if *cmd_params;
1274 /* prepare command */
1275 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_PRIMARY_MAC_ADDR,
1278 cmd_params = (struct dpsw_cmd_if *)cmd.params;
1279 cmd_params->if_id = cpu_to_le16(if_id);
1281 /* send command to mc*/
1282 err = mc_send_command(mc_io, &cmd);
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];
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
1302 * Return: Completion status. '0' on Success; Error code otherwise.
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])
1307 struct dpsw_cmd_if_set_mac_addr *cmd_params;
1308 struct fsl_mc_command cmd = { 0 };
1311 /* prepare command */
1312 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_PRIMARY_MAC_ADDR,
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];
1320 /* send command to mc*/
1321 return mc_send_command(mc_io, &cmd);