1662 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2014-2016 Freescale Semiconductor Inc.4 * Copyright 2017-2021 NXP5 *6 */7 8#include <linux/fsl/mc.h>9#include "dpsw.h"10#include "dpsw-cmd.h"11 12static void build_if_id_bitmap(__le64 *bmap, const u16 *id, const u16 num_ifs)13{14 int i;15 16 for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++) {17 if (id[i] < DPSW_MAX_IF)18 bmap[id[i] / 64] |= cpu_to_le64(BIT_MASK(id[i] % 64));19 }20}21 22/**23 * dpsw_open() - Open a control session for the specified object24 * @mc_io: Pointer to MC portal's I/O object25 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'26 * @dpsw_id: DPSW unique ID27 * @token: Returned token; use in subsequent API calls28 *29 * This function can be used to open a control session for an30 * already created object; an object may have been declared in31 * the DPL or by calling the dpsw_create() function.32 * This function returns a unique authentication token,33 * associated with the specific object ID and the specific MC34 * portal; this token must be used in all subsequent commands for35 * this specific object36 *37 * Return: '0' on Success; Error code otherwise.38 */39int dpsw_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpsw_id, u16 *token)40{41 struct fsl_mc_command cmd = { 0 };42 struct dpsw_cmd_open *cmd_params;43 int err;44 45 /* prepare command */46 cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,47 cmd_flags,48 0);49 cmd_params = (struct dpsw_cmd_open *)cmd.params;50 cmd_params->dpsw_id = cpu_to_le32(dpsw_id);51 52 /* send command to mc*/53 err = mc_send_command(mc_io, &cmd);54 if (err)55 return err;56 57 /* retrieve response parameters */58 *token = mc_cmd_hdr_read_token(&cmd);59 60 return 0;61}62 63/**64 * dpsw_close() - Close the control session of the object65 * @mc_io: Pointer to MC portal's I/O object66 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'67 * @token: Token of DPSW object68 *69 * After this function is called, no further operations are70 * allowed on the object without opening a new control session.71 *72 * Return: '0' on Success; Error code otherwise.73 */74int dpsw_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)75{76 struct fsl_mc_command cmd = { 0 };77 78 /* prepare command */79 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,80 cmd_flags,81 token);82 83 /* send command to mc*/84 return mc_send_command(mc_io, &cmd);85}86 87/**88 * dpsw_enable() - Enable DPSW functionality89 * @mc_io: Pointer to MC portal's I/O object90 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'91 * @token: Token of DPSW object92 *93 * Return: Completion status. '0' on Success; Error code otherwise.94 */95int dpsw_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)96{97 struct fsl_mc_command cmd = { 0 };98 99 /* prepare command */100 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,101 cmd_flags,102 token);103 104 /* send command to mc*/105 return mc_send_command(mc_io, &cmd);106}107 108/**109 * dpsw_disable() - Disable DPSW functionality110 * @mc_io: Pointer to MC portal's I/O object111 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'112 * @token: Token of DPSW object113 *114 * Return: Completion status. '0' on Success; Error code otherwise.115 */116int dpsw_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)117{118 struct fsl_mc_command cmd = { 0 };119 120 /* prepare command */121 cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,122 cmd_flags,123 token);124 125 /* send command to mc*/126 return mc_send_command(mc_io, &cmd);127}128 129/**130 * dpsw_reset() - Reset the DPSW, returns the object to initial state.131 * @mc_io: Pointer to MC portal's I/O object132 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'133 * @token: Token of DPSW object134 *135 * Return: '0' on Success; Error code otherwise.136 */137int dpsw_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)138{139 struct fsl_mc_command cmd = { 0 };140 141 /* prepare command */142 cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,143 cmd_flags,144 token);145 146 /* send command to mc*/147 return mc_send_command(mc_io, &cmd);148}149 150/**151 * dpsw_set_irq_enable() - Set overall interrupt state.152 * @mc_io: Pointer to MC portal's I/O object153 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'154 * @token: Token of DPCI object155 * @irq_index: The interrupt index to configure156 * @en: Interrupt state - enable = 1, disable = 0157 *158 * Allows GPP software to control when interrupts are generated.159 * Each interrupt can have up to 32 causes. The enable/disable control's the160 * overall interrupt state. if the interrupt is disabled no causes will cause161 * an interrupt162 *163 * Return: '0' on Success; Error code otherwise.164 */165int dpsw_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,166 u8 irq_index, u8 en)167{168 struct fsl_mc_command cmd = { 0 };169 struct dpsw_cmd_set_irq_enable *cmd_params;170 171 /* prepare command */172 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,173 cmd_flags,174 token);175 cmd_params = (struct dpsw_cmd_set_irq_enable *)cmd.params;176 dpsw_set_field(cmd_params->enable_state, ENABLE, en);177 cmd_params->irq_index = irq_index;178 179 /* send command to mc*/180 return mc_send_command(mc_io, &cmd);181}182 183/**184 * dpsw_set_irq_mask() - Set interrupt mask.185 * @mc_io: Pointer to MC portal's I/O object186 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'187 * @token: Token of DPCI object188 * @irq_index: The interrupt index to configure189 * @mask: Event mask to trigger interrupt;190 * each bit:191 * 0 = ignore event192 * 1 = consider event for asserting IRQ193 *194 * Every interrupt can have up to 32 causes and the interrupt model supports195 * masking/unmasking each cause independently196 *197 * Return: '0' on Success; Error code otherwise.198 */199int dpsw_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,200 u8 irq_index, u32 mask)201{202 struct fsl_mc_command cmd = { 0 };203 struct dpsw_cmd_set_irq_mask *cmd_params;204 205 /* prepare command */206 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,207 cmd_flags,208 token);209 cmd_params = (struct dpsw_cmd_set_irq_mask *)cmd.params;210 cmd_params->mask = cpu_to_le32(mask);211 cmd_params->irq_index = irq_index;212 213 /* send command to mc*/214 return mc_send_command(mc_io, &cmd);215}216 217/**218 * dpsw_get_irq_status() - Get the current status of any pending interrupts219 * @mc_io: Pointer to MC portal's I/O object220 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'221 * @token: Token of DPSW object222 * @irq_index: The interrupt index to configure223 * @status: Returned interrupts status - one bit per cause:224 * 0 = no interrupt pending225 * 1 = interrupt pending226 *227 * Return: '0' on Success; Error code otherwise.228 */229int dpsw_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,230 u8 irq_index, u32 *status)231{232 struct fsl_mc_command cmd = { 0 };233 struct dpsw_cmd_get_irq_status *cmd_params;234 struct dpsw_rsp_get_irq_status *rsp_params;235 int err;236 237 /* prepare command */238 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,239 cmd_flags,240 token);241 cmd_params = (struct dpsw_cmd_get_irq_status *)cmd.params;242 cmd_params->status = cpu_to_le32(*status);243 cmd_params->irq_index = irq_index;244 245 /* send command to mc*/246 err = mc_send_command(mc_io, &cmd);247 if (err)248 return err;249 250 /* retrieve response parameters */251 rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params;252 *status = le32_to_cpu(rsp_params->status);253 254 return 0;255}256 257/**258 * dpsw_clear_irq_status() - Clear a pending interrupt's status259 * @mc_io: Pointer to MC portal's I/O object260 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'261 * @token: Token of DPCI object262 * @irq_index: The interrupt index to configure263 * @status: bits to clear (W1C) - one bit per cause:264 * 0 = don't change265 * 1 = clear status bit266 *267 * Return: '0' on Success; Error code otherwise.268 */269int dpsw_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,270 u8 irq_index, u32 status)271{272 struct fsl_mc_command cmd = { 0 };273 struct dpsw_cmd_clear_irq_status *cmd_params;274 275 /* prepare command */276 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,277 cmd_flags,278 token);279 cmd_params = (struct dpsw_cmd_clear_irq_status *)cmd.params;280 cmd_params->status = cpu_to_le32(status);281 cmd_params->irq_index = irq_index;282 283 /* send command to mc*/284 return mc_send_command(mc_io, &cmd);285}286 287/**288 * dpsw_get_attributes() - Retrieve DPSW attributes289 * @mc_io: Pointer to MC portal's I/O object290 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'291 * @token: Token of DPSW object292 * @attr: Returned DPSW attributes293 *294 * Return: Completion status. '0' on Success; Error code otherwise.295 */296int dpsw_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,297 struct dpsw_attr *attr)298{299 struct fsl_mc_command cmd = { 0 };300 struct dpsw_rsp_get_attr *rsp_params;301 int err;302 303 /* prepare command */304 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,305 cmd_flags,306 token);307 308 /* send command to mc*/309 err = mc_send_command(mc_io, &cmd);310 if (err)311 return err;312 313 /* retrieve response parameters */314 rsp_params = (struct dpsw_rsp_get_attr *)cmd.params;315 attr->num_ifs = le16_to_cpu(rsp_params->num_ifs);316 attr->max_fdbs = rsp_params->max_fdbs;317 attr->num_fdbs = rsp_params->num_fdbs;318 attr->max_vlans = le16_to_cpu(rsp_params->max_vlans);319 attr->num_vlans = le16_to_cpu(rsp_params->num_vlans);320 attr->max_fdb_entries = le16_to_cpu(rsp_params->max_fdb_entries);321 attr->fdb_aging_time = le16_to_cpu(rsp_params->fdb_aging_time);322 attr->id = le32_to_cpu(rsp_params->dpsw_id);323 attr->mem_size = le16_to_cpu(rsp_params->mem_size);324 attr->max_fdb_mc_groups = le16_to_cpu(rsp_params->max_fdb_mc_groups);325 attr->max_meters_per_if = rsp_params->max_meters_per_if;326 attr->options = le64_to_cpu(rsp_params->options);327 attr->component_type = dpsw_get_field(rsp_params->component_type, COMPONENT_TYPE);328 attr->flooding_cfg = dpsw_get_field(rsp_params->repl_cfg, FLOODING_CFG);329 attr->broadcast_cfg = dpsw_get_field(rsp_params->repl_cfg, BROADCAST_CFG);330 return 0;331}332 333/**334 * dpsw_if_set_link_cfg() - Set the link configuration.335 * @mc_io: Pointer to MC portal's I/O object336 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'337 * @token: Token of DPSW object338 * @if_id: Interface id339 * @cfg: Link configuration340 *341 * Return: '0' on Success; Error code otherwise.342 */343int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,344 struct dpsw_link_cfg *cfg)345{346 struct fsl_mc_command cmd = { 0 };347 struct dpsw_cmd_if_set_link_cfg *cmd_params;348 349 /* prepare command */350 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,351 cmd_flags,352 token);353 cmd_params = (struct dpsw_cmd_if_set_link_cfg *)cmd.params;354 cmd_params->if_id = cpu_to_le16(if_id);355 cmd_params->rate = cpu_to_le32(cfg->rate);356 cmd_params->options = cpu_to_le64(cfg->options);357 358 /* send command to mc*/359 return mc_send_command(mc_io, &cmd);360}361 362/**363 * dpsw_if_get_link_state - Return the link state364 * @mc_io: Pointer to MC portal's I/O object365 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'366 * @token: Token of DPSW object367 * @if_id: Interface id368 * @state: Link state 1 - linkup, 0 - link down or disconnected369 *370 * Return: '0' on Success; Error code otherwise.371 */372int dpsw_if_get_link_state(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,373 u16 if_id, struct dpsw_link_state *state)374{375 struct fsl_mc_command cmd = { 0 };376 struct dpsw_cmd_if_get_link_state *cmd_params;377 struct dpsw_rsp_if_get_link_state *rsp_params;378 int err;379 380 /* prepare command */381 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,382 cmd_flags,383 token);384 cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params;385 cmd_params->if_id = cpu_to_le16(if_id);386 387 /* send command to mc*/388 err = mc_send_command(mc_io, &cmd);389 if (err)390 return err;391 392 /* retrieve response parameters */393 rsp_params = (struct dpsw_rsp_if_get_link_state *)cmd.params;394 state->rate = le32_to_cpu(rsp_params->rate);395 state->options = le64_to_cpu(rsp_params->options);396 state->up = dpsw_get_field(rsp_params->up, UP);397 398 return 0;399}400 401/**402 * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)403 * @mc_io: Pointer to MC portal's I/O object404 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'405 * @token: Token of DPSW object406 * @if_id: Interface Identifier407 * @cfg: Tag Control Information Configuration408 *409 * Return: Completion status. '0' on Success; Error code otherwise.410 */411int dpsw_if_set_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,412 const struct dpsw_tci_cfg *cfg)413{414 struct fsl_mc_command cmd = { 0 };415 struct dpsw_cmd_if_set_tci *cmd_params;416 u16 tmp_conf = 0;417 418 /* prepare command */419 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,420 cmd_flags,421 token);422 cmd_params = (struct dpsw_cmd_if_set_tci *)cmd.params;423 cmd_params->if_id = cpu_to_le16(if_id);424 dpsw_set_field(tmp_conf, VLAN_ID, cfg->vlan_id);425 dpsw_set_field(tmp_conf, DEI, cfg->dei);426 dpsw_set_field(tmp_conf, PCP, cfg->pcp);427 cmd_params->conf = cpu_to_le16(tmp_conf);428 429 /* send command to mc*/430 return mc_send_command(mc_io, &cmd);431}432 433/**434 * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI)435 * @mc_io: Pointer to MC portal's I/O object436 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'437 * @token: Token of DPSW object438 * @if_id: Interface Identifier439 * @cfg: Tag Control Information Configuration440 *441 * Return: Completion status. '0' on Success; Error code otherwise.442 */443int dpsw_if_get_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,444 struct dpsw_tci_cfg *cfg)445{446 struct fsl_mc_command cmd = { 0 };447 struct dpsw_cmd_if_get_tci *cmd_params;448 struct dpsw_rsp_if_get_tci *rsp_params;449 int err;450 451 /* prepare command */452 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,453 cmd_flags,454 token);455 cmd_params = (struct dpsw_cmd_if_get_tci *)cmd.params;456 cmd_params->if_id = cpu_to_le16(if_id);457 458 /* send command to mc*/459 err = mc_send_command(mc_io, &cmd);460 if (err)461 return err;462 463 /* retrieve response parameters */464 rsp_params = (struct dpsw_rsp_if_get_tci *)cmd.params;465 cfg->pcp = rsp_params->pcp;466 cfg->dei = rsp_params->dei;467 cfg->vlan_id = le16_to_cpu(rsp_params->vlan_id);468 469 return 0;470}471 472/**473 * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state.474 * @mc_io: Pointer to MC portal's I/O object475 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'476 * @token: Token of DPSW object477 * @if_id: Interface Identifier478 * @cfg: STP State configuration parameters479 *480 * The following STP states are supported -481 * blocking, listening, learning, forwarding and disabled.482 *483 * Return: Completion status. '0' on Success; Error code otherwise.484 */485int dpsw_if_set_stp(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,486 const struct dpsw_stp_cfg *cfg)487{488 struct fsl_mc_command cmd = { 0 };489 struct dpsw_cmd_if_set_stp *cmd_params;490 491 /* prepare command */492 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,493 cmd_flags,494 token);495 cmd_params = (struct dpsw_cmd_if_set_stp *)cmd.params;496 cmd_params->if_id = cpu_to_le16(if_id);497 cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);498 dpsw_set_field(cmd_params->state, STATE, cfg->state);499 500 /* send command to mc*/501 return mc_send_command(mc_io, &cmd);502}503 504/**505 * dpsw_if_get_counter() - Get specific counter of particular interface506 * @mc_io: Pointer to MC portal's I/O object507 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'508 * @token: Token of DPSW object509 * @if_id: Interface Identifier510 * @type: Counter type511 * @counter: return value512 *513 * Return: Completion status. '0' on Success; Error code otherwise.514 */515int dpsw_if_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,516 u16 if_id, enum dpsw_counter type, u64 *counter)517{518 struct fsl_mc_command cmd = { 0 };519 struct dpsw_cmd_if_get_counter *cmd_params;520 struct dpsw_rsp_if_get_counter *rsp_params;521 int err;522 523 /* prepare command */524 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,525 cmd_flags,526 token);527 cmd_params = (struct dpsw_cmd_if_get_counter *)cmd.params;528 cmd_params->if_id = cpu_to_le16(if_id);529 dpsw_set_field(cmd_params->type, COUNTER_TYPE, type);530 531 /* send command to mc*/532 err = mc_send_command(mc_io, &cmd);533 if (err)534 return err;535 536 /* retrieve response parameters */537 rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params;538 *counter = le64_to_cpu(rsp_params->counter);539 540 return 0;541}542 543/**544 * dpsw_if_enable() - Enable Interface545 * @mc_io: Pointer to MC portal's I/O object546 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'547 * @token: Token of DPSW object548 * @if_id: Interface Identifier549 *550 * Return: Completion status. '0' on Success; Error code otherwise.551 */552int dpsw_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id)553{554 struct fsl_mc_command cmd = { 0 };555 struct dpsw_cmd_if *cmd_params;556 557 /* prepare command */558 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,559 cmd_flags,560 token);561 cmd_params = (struct dpsw_cmd_if *)cmd.params;562 cmd_params->if_id = cpu_to_le16(if_id);563 564 /* send command to mc*/565 return mc_send_command(mc_io, &cmd);566}567 568/**569 * dpsw_if_disable() - Disable Interface570 * @mc_io: Pointer to MC portal's I/O object571 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'572 * @token: Token of DPSW object573 * @if_id: Interface Identifier574 *575 * Return: Completion status. '0' on Success; Error code otherwise.576 */577int dpsw_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id)578{579 struct fsl_mc_command cmd = { 0 };580 struct dpsw_cmd_if *cmd_params;581 582 /* prepare command */583 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,584 cmd_flags,585 token);586 cmd_params = (struct dpsw_cmd_if *)cmd.params;587 cmd_params->if_id = cpu_to_le16(if_id);588 589 /* send command to mc*/590 return mc_send_command(mc_io, &cmd);591}592 593/**594 * dpsw_if_get_attributes() - Function obtains attributes of interface595 * @mc_io: Pointer to MC portal's I/O object596 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'597 * @token: Token of DPSW object598 * @if_id: Interface Identifier599 * @attr: Returned interface attributes600 *601 * Return: Completion status. '0' on Success; Error code otherwise.602 */603int dpsw_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,604 u16 if_id, struct dpsw_if_attr *attr)605{606 struct dpsw_rsp_if_get_attr *rsp_params;607 struct fsl_mc_command cmd = { 0 };608 struct dpsw_cmd_if *cmd_params;609 int err;610 611 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_ATTR, cmd_flags,612 token);613 cmd_params = (struct dpsw_cmd_if *)cmd.params;614 cmd_params->if_id = cpu_to_le16(if_id);615 616 err = mc_send_command(mc_io, &cmd);617 if (err)618 return err;619 620 rsp_params = (struct dpsw_rsp_if_get_attr *)cmd.params;621 attr->num_tcs = rsp_params->num_tcs;622 attr->rate = le32_to_cpu(rsp_params->rate);623 attr->options = le32_to_cpu(rsp_params->options);624 attr->qdid = le16_to_cpu(rsp_params->qdid);625 attr->enabled = dpsw_get_field(rsp_params->conf, ENABLED);626 attr->accept_all_vlan = dpsw_get_field(rsp_params->conf,627 ACCEPT_ALL_VLAN);628 attr->admit_untagged = dpsw_get_field(rsp_params->conf,629 ADMIT_UNTAGGED);630 631 return 0;632}633 634/**635 * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.636 * @mc_io: Pointer to MC portal's I/O object637 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'638 * @token: Token of DPSW object639 * @if_id: Interface Identifier640 * @frame_length: Maximum Frame Length641 *642 * Return: Completion status. '0' on Success; Error code otherwise.643 */644int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,645 u16 if_id, u16 frame_length)646{647 struct fsl_mc_command cmd = { 0 };648 struct dpsw_cmd_if_set_max_frame_length *cmd_params;649 650 /* prepare command */651 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,652 cmd_flags,653 token);654 cmd_params = (struct dpsw_cmd_if_set_max_frame_length *)cmd.params;655 cmd_params->if_id = cpu_to_le16(if_id);656 cmd_params->frame_length = cpu_to_le16(frame_length);657 658 /* send command to mc*/659 return mc_send_command(mc_io, &cmd);660}661 662/**663 * dpsw_vlan_add() - Adding new VLAN to DPSW.664 * @mc_io: Pointer to MC portal's I/O object665 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'666 * @token: Token of DPSW object667 * @vlan_id: VLAN Identifier668 * @cfg: VLAN configuration669 *670 * Only VLAN ID and FDB ID are required parameters here.671 * 12 bit VLAN ID is defined in IEEE802.1Q.672 * Adding a duplicate VLAN ID is not allowed.673 * FDB ID can be shared across multiple VLANs. Shared learning674 * is obtained by calling dpsw_vlan_add for multiple VLAN IDs675 * with same fdb_id676 *677 * Return: Completion status. '0' on Success; Error code otherwise.678 */679int dpsw_vlan_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,680 u16 vlan_id, const struct dpsw_vlan_cfg *cfg)681{682 struct fsl_mc_command cmd = { 0 };683 struct dpsw_vlan_add *cmd_params;684 685 /* prepare command */686 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,687 cmd_flags,688 token);689 cmd_params = (struct dpsw_vlan_add *)cmd.params;690 cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);691 cmd_params->vlan_id = cpu_to_le16(vlan_id);692 693 /* send command to mc*/694 return mc_send_command(mc_io, &cmd);695}696 697/**698 * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.699 * @mc_io: Pointer to MC portal's I/O object700 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'701 * @token: Token of DPSW object702 * @vlan_id: VLAN Identifier703 * @cfg: Set of interfaces to add704 *705 * It adds only interfaces not belonging to this VLAN yet,706 * otherwise an error is generated and an entire command is707 * ignored. This function can be called numerous times always708 * providing required interfaces delta.709 *710 * Return: Completion status. '0' on Success; Error code otherwise.711 */712int dpsw_vlan_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,713 u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)714{715 struct dpsw_cmd_vlan_add_if *cmd_params;716 struct fsl_mc_command cmd = { 0 };717 718 /* prepare command */719 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,720 cmd_flags,721 token);722 cmd_params = (struct dpsw_cmd_vlan_add_if *)cmd.params;723 cmd_params->vlan_id = cpu_to_le16(vlan_id);724 cmd_params->options = cpu_to_le16(cfg->options);725 cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);726 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);727 728 /* send command to mc*/729 return mc_send_command(mc_io, &cmd);730}731 732/**733 * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be734 * transmitted as untagged.735 * @mc_io: Pointer to MC portal's I/O object736 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'737 * @token: Token of DPSW object738 * @vlan_id: VLAN Identifier739 * @cfg: Set of interfaces that should be transmitted as untagged740 *741 * These interfaces should already belong to this VLAN.742 * By default all interfaces are transmitted as tagged.743 * Providing un-existing interface or untagged interface that is744 * configured untagged already generates an error and the entire745 * command is ignored.746 *747 * Return: Completion status. '0' on Success; Error code otherwise.748 */749int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,750 u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)751{752 struct fsl_mc_command cmd = { 0 };753 struct dpsw_cmd_vlan_manage_if *cmd_params;754 755 /* prepare command */756 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,757 cmd_flags,758 token);759 cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;760 cmd_params->vlan_id = cpu_to_le16(vlan_id);761 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);762 763 /* send command to mc*/764 return mc_send_command(mc_io, &cmd);765}766 767/**768 * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.769 * @mc_io: Pointer to MC portal's I/O object770 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'771 * @token: Token of DPSW object772 * @vlan_id: VLAN Identifier773 * @cfg: Set of interfaces that should be removed774 *775 * Interfaces must belong to this VLAN, otherwise an error776 * is returned and an the command is ignored777 *778 * Return: Completion status. '0' on Success; Error code otherwise.779 */780int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,781 u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)782{783 struct fsl_mc_command cmd = { 0 };784 struct dpsw_cmd_vlan_manage_if *cmd_params;785 786 /* prepare command */787 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,788 cmd_flags,789 token);790 cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;791 cmd_params->vlan_id = cpu_to_le16(vlan_id);792 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);793 794 /* send command to mc*/795 return mc_send_command(mc_io, &cmd);796}797 798/**799 * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be800 * converted from transmitted as untagged to transmit as tagged.801 * @mc_io: Pointer to MC portal's I/O object802 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'803 * @token: Token of DPSW object804 * @vlan_id: VLAN Identifier805 * @cfg: Set of interfaces that should be removed806 *807 * Interfaces provided by API have to belong to this VLAN and808 * configured untagged, otherwise an error is returned and the809 * command is ignored810 *811 * Return: Completion status. '0' on Success; Error code otherwise.812 */813int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,814 u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)815{816 struct fsl_mc_command cmd = { 0 };817 struct dpsw_cmd_vlan_manage_if *cmd_params;818 819 /* prepare command */820 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,821 cmd_flags,822 token);823 cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;824 cmd_params->vlan_id = cpu_to_le16(vlan_id);825 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);826 827 /* send command to mc*/828 return mc_send_command(mc_io, &cmd);829}830 831/**832 * dpsw_vlan_remove() - Remove an entire VLAN833 * @mc_io: Pointer to MC portal's I/O object834 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'835 * @token: Token of DPSW object836 * @vlan_id: VLAN Identifier837 *838 * Return: Completion status. '0' on Success; Error code otherwise.839 */840int dpsw_vlan_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,841 u16 vlan_id)842{843 struct fsl_mc_command cmd = { 0 };844 struct dpsw_cmd_vlan_remove *cmd_params;845 846 /* prepare command */847 cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,848 cmd_flags,849 token);850 cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params;851 cmd_params->vlan_id = cpu_to_le16(vlan_id);852 853 /* send command to mc*/854 return mc_send_command(mc_io, &cmd);855}856 857/**858 * dpsw_fdb_add() - Add FDB to switch and Returns handle to FDB table for859 * the reference860 * @mc_io: Pointer to MC portal's I/O object861 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'862 * @token: Token of DPSW object863 * @fdb_id: Returned Forwarding Database Identifier864 * @cfg: FDB Configuration865 *866 * Return: Completion status. '0' on Success; Error code otherwise.867 */868int dpsw_fdb_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *fdb_id,869 const struct dpsw_fdb_cfg *cfg)870{871 struct dpsw_cmd_fdb_add *cmd_params;872 struct dpsw_rsp_fdb_add *rsp_params;873 struct fsl_mc_command cmd = { 0 };874 int err;875 876 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD,877 cmd_flags,878 token);879 cmd_params = (struct dpsw_cmd_fdb_add *)cmd.params;880 cmd_params->fdb_ageing_time = cpu_to_le16(cfg->fdb_ageing_time);881 cmd_params->num_fdb_entries = cpu_to_le16(cfg->num_fdb_entries);882 883 err = mc_send_command(mc_io, &cmd);884 if (err)885 return err;886 887 rsp_params = (struct dpsw_rsp_fdb_add *)cmd.params;888 *fdb_id = le16_to_cpu(rsp_params->fdb_id);889 890 return 0;891}892 893/**894 * dpsw_fdb_remove() - Remove FDB from switch895 * @mc_io: Pointer to MC portal's I/O object896 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'897 * @token: Token of DPSW object898 * @fdb_id: Forwarding Database Identifier899 *900 * Return: Completion status. '0' on Success; Error code otherwise.901 */902int dpsw_fdb_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id)903{904 struct dpsw_cmd_fdb_remove *cmd_params;905 struct fsl_mc_command cmd = { 0 };906 907 /* prepare command */908 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE,909 cmd_flags,910 token);911 cmd_params = (struct dpsw_cmd_fdb_remove *)cmd.params;912 cmd_params->fdb_id = cpu_to_le16(fdb_id);913 914 return mc_send_command(mc_io, &cmd);915}916 917/**918 * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table919 * @mc_io: Pointer to MC portal's I/O object920 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'921 * @token: Token of DPSW object922 * @fdb_id: Forwarding Database Identifier923 * @cfg: Unicast entry configuration924 *925 * Return: Completion status. '0' on Success; Error code otherwise.926 */927int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,928 u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg)929{930 struct fsl_mc_command cmd = { 0 };931 struct dpsw_cmd_fdb_unicast_op *cmd_params;932 int i;933 934 /* prepare command */935 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,936 cmd_flags,937 token);938 cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;939 cmd_params->fdb_id = cpu_to_le16(fdb_id);940 cmd_params->if_egress = cpu_to_le16(cfg->if_egress);941 for (i = 0; i < 6; i++)942 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];943 dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);944 945 /* send command to mc*/946 return mc_send_command(mc_io, &cmd);947}948 949/**950 * dpsw_fdb_dump() - Dump the content of FDB table into memory.951 * @mc_io: Pointer to MC portal's I/O object952 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'953 * @token: Token of DPSW object954 * @fdb_id: Forwarding Database Identifier955 * @iova_addr: Data will be stored here as an array of struct fdb_dump_entry956 * @iova_size: Memory size allocated at iova_addr957 * @num_entries:Number of entries written at iova_addr958 *959 * Return: Completion status. '0' on Success; Error code otherwise.960 *961 * The memory allocated at iova_addr must be initialized with zero before962 * command execution. If the FDB table does not fit into memory MC will stop963 * after the memory is filled up.964 * The struct fdb_dump_entry array must be parsed until the end of memory965 * area or until an entry with mac_addr set to zero is found.966 */967int dpsw_fdb_dump(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id,968 u64 iova_addr, u32 iova_size, u16 *num_entries)969{970 struct dpsw_cmd_fdb_dump *cmd_params;971 struct dpsw_rsp_fdb_dump *rsp_params;972 struct fsl_mc_command cmd = { 0 };973 int err;974 975 /* prepare command */976 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP,977 cmd_flags,978 token);979 cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params;980 cmd_params->fdb_id = cpu_to_le16(fdb_id);981 cmd_params->iova_addr = cpu_to_le64(iova_addr);982 cmd_params->iova_size = cpu_to_le32(iova_size);983 984 /* send command to mc */985 err = mc_send_command(mc_io, &cmd);986 if (err)987 return err;988 989 rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params;990 *num_entries = le16_to_cpu(rsp_params->num_entries);991 992 return 0;993}994 995/**996 * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table997 * @mc_io: Pointer to MC portal's I/O object998 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'999 * @token: Token of DPSW object1000 * @fdb_id: Forwarding Database Identifier1001 * @cfg: Unicast entry configuration1002 *1003 * Return: Completion status. '0' on Success; Error code otherwise.1004 */1005int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1006 u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg)1007{1008 struct fsl_mc_command cmd = { 0 };1009 struct dpsw_cmd_fdb_unicast_op *cmd_params;1010 int i;1011 1012 /* prepare command */1013 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,1014 cmd_flags,1015 token);1016 cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;1017 cmd_params->fdb_id = cpu_to_le16(fdb_id);1018 for (i = 0; i < 6; i++)1019 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];1020 cmd_params->if_egress = cpu_to_le16(cfg->if_egress);1021 dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);1022 1023 /* send command to mc*/1024 return mc_send_command(mc_io, &cmd);1025}1026 1027/**1028 * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group1029 * @mc_io: Pointer to MC portal's I/O object1030 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1031 * @token: Token of DPSW object1032 * @fdb_id: Forwarding Database Identifier1033 * @cfg: Multicast entry configuration1034 *1035 * If group doesn't exist, it will be created.1036 * It adds only interfaces not belonging to this multicast group1037 * yet, otherwise error will be generated and the command is1038 * ignored.1039 * This function may be called numerous times always providing1040 * required interfaces delta.1041 *1042 * Return: Completion status. '0' on Success; Error code otherwise.1043 */1044int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1045 u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg)1046{1047 struct fsl_mc_command cmd = { 0 };1048 struct dpsw_cmd_fdb_multicast_op *cmd_params;1049 int i;1050 1051 /* prepare command */1052 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,1053 cmd_flags,1054 token);1055 cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;1056 cmd_params->fdb_id = cpu_to_le16(fdb_id);1057 cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);1058 dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);1059 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);1060 for (i = 0; i < 6; i++)1061 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];1062 1063 /* send command to mc*/1064 return mc_send_command(mc_io, &cmd);1065}1066 1067/**1068 * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast1069 * group.1070 * @mc_io: Pointer to MC portal's I/O object1071 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1072 * @token: Token of DPSW object1073 * @fdb_id: Forwarding Database Identifier1074 * @cfg: Multicast entry configuration1075 *1076 * Interfaces provided by this API have to exist in the group,1077 * otherwise an error will be returned and an entire command1078 * ignored. If there is no interface left in the group,1079 * an entire group is deleted1080 *1081 * Return: Completion status. '0' on Success; Error code otherwise.1082 */1083int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1084 u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg)1085{1086 struct fsl_mc_command cmd = { 0 };1087 struct dpsw_cmd_fdb_multicast_op *cmd_params;1088 int i;1089 1090 /* prepare command */1091 cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,1092 cmd_flags,1093 token);1094 cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;1095 cmd_params->fdb_id = cpu_to_le16(fdb_id);1096 cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);1097 dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);1098 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);1099 for (i = 0; i < 6; i++)1100 cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];1101 1102 /* send command to mc*/1103 return mc_send_command(mc_io, &cmd);1104}1105 1106/**1107 * dpsw_ctrl_if_get_attributes() - Obtain control interface attributes1108 * @mc_io: Pointer to MC portal's I/O object1109 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1110 * @token: Token of DPSW object1111 * @attr: Returned control interface attributes1112 *1113 * Return: '0' on Success; Error code otherwise.1114 */1115int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags,1116 u16 token, struct dpsw_ctrl_if_attr *attr)1117{1118 struct dpsw_rsp_ctrl_if_get_attr *rsp_params;1119 struct fsl_mc_command cmd = { 0 };1120 int err;1121 1122 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR,1123 cmd_flags, token);1124 1125 err = mc_send_command(mc_io, &cmd);1126 if (err)1127 return err;1128 1129 rsp_params = (struct dpsw_rsp_ctrl_if_get_attr *)cmd.params;1130 attr->rx_fqid = le32_to_cpu(rsp_params->rx_fqid);1131 attr->rx_err_fqid = le32_to_cpu(rsp_params->rx_err_fqid);1132 attr->tx_err_conf_fqid = le32_to_cpu(rsp_params->tx_err_conf_fqid);1133 1134 return 0;1135}1136 1137/**1138 * dpsw_ctrl_if_set_pools() - Set control interface buffer pools1139 * @mc_io: Pointer to MC portal's I/O object1140 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1141 * @token: Token of DPSW object1142 * @cfg: Buffer pools configuration1143 *1144 * Return: '0' on Success; Error code otherwise.1145 */1146int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1147 const struct dpsw_ctrl_if_pools_cfg *cfg)1148{1149 struct dpsw_cmd_ctrl_if_set_pools *cmd_params;1150 struct fsl_mc_command cmd = { 0 };1151 int i;1152 1153 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_POOLS,1154 cmd_flags, token);1155 cmd_params = (struct dpsw_cmd_ctrl_if_set_pools *)cmd.params;1156 cmd_params->num_dpbp = cfg->num_dpbp;1157 for (i = 0; i < DPSW_MAX_DPBP; i++) {1158 cmd_params->dpbp_id[i] = cpu_to_le32(cfg->pools[i].dpbp_id);1159 cmd_params->buffer_size[i] =1160 cpu_to_le16(cfg->pools[i].buffer_size);1161 cmd_params->backup_pool_mask |=1162 DPSW_BACKUP_POOL(cfg->pools[i].backup_pool, i);1163 }1164 1165 return mc_send_command(mc_io, &cmd);1166}1167 1168/**1169 * dpsw_ctrl_if_set_queue() - Set Rx queue configuration1170 * @mc_io: Pointer to MC portal's I/O object1171 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1172 * @token: Token of dpsw object1173 * @qtype: dpsw_queue_type of the targeted queue1174 * @cfg: Rx queue configuration1175 *1176 * Return: '0' on Success; Error code otherwise.1177 */1178int dpsw_ctrl_if_set_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1179 enum dpsw_queue_type qtype,1180 const struct dpsw_ctrl_if_queue_cfg *cfg)1181{1182 struct dpsw_cmd_ctrl_if_set_queue *cmd_params;1183 struct fsl_mc_command cmd = { 0 };1184 1185 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_QUEUE,1186 cmd_flags,1187 token);1188 cmd_params = (struct dpsw_cmd_ctrl_if_set_queue *)cmd.params;1189 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);1190 cmd_params->dest_priority = cfg->dest_cfg.priority;1191 cmd_params->qtype = qtype;1192 cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);1193 cmd_params->options = cpu_to_le32(cfg->options);1194 dpsw_set_field(cmd_params->dest_type,1195 DEST_TYPE,1196 cfg->dest_cfg.dest_type);1197 1198 return mc_send_command(mc_io, &cmd);1199}1200 1201/**1202 * dpsw_get_api_version() - Get Data Path Switch API version1203 * @mc_io: Pointer to MC portal's I/O object1204 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1205 * @major_ver: Major version of data path switch API1206 * @minor_ver: Minor version of data path switch API1207 *1208 * Return: '0' on Success; Error code otherwise.1209 */1210int dpsw_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,1211 u16 *major_ver, u16 *minor_ver)1212{1213 struct fsl_mc_command cmd = { 0 };1214 struct dpsw_rsp_get_api_version *rsp_params;1215 int err;1216 1217 cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,1218 cmd_flags,1219 0);1220 1221 err = mc_send_command(mc_io, &cmd);1222 if (err)1223 return err;1224 1225 rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params;1226 *major_ver = le16_to_cpu(rsp_params->version_major);1227 *minor_ver = le16_to_cpu(rsp_params->version_minor);1228 1229 return 0;1230}1231 1232/**1233 * dpsw_if_get_port_mac_addr() - Retrieve MAC address associated to the physical port1234 * @mc_io: Pointer to MC portal's I/O object1235 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1236 * @token: Token of DPSW object1237 * @if_id: Interface Identifier1238 * @mac_addr: MAC address of the physical port, if any, otherwise 01239 *1240 * Return: Completion status. '0' on Success; Error code otherwise.1241 */1242int dpsw_if_get_port_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1243 u16 if_id, u8 mac_addr[6])1244{1245 struct dpsw_rsp_if_get_mac_addr *rsp_params;1246 struct fsl_mc_command cmd = { 0 };1247 struct dpsw_cmd_if *cmd_params;1248 int err, i;1249 1250 /* prepare command */1251 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_PORT_MAC_ADDR,1252 cmd_flags,1253 token);1254 cmd_params = (struct dpsw_cmd_if *)cmd.params;1255 cmd_params->if_id = cpu_to_le16(if_id);1256 1257 /* send command to mc*/1258 err = mc_send_command(mc_io, &cmd);1259 if (err)1260 return err;1261 1262 /* retrieve response parameters */1263 rsp_params = (struct dpsw_rsp_if_get_mac_addr *)cmd.params;1264 for (i = 0; i < 6; i++)1265 mac_addr[5 - i] = rsp_params->mac_addr[i];1266 1267 return 0;1268}1269 1270/**1271 * dpsw_ctrl_if_enable() - Enable control interface1272 * @mc_io: Pointer to MC portal's I/O object1273 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1274 * @token: Token of DPSW object1275 *1276 * Return: '0' on Success; Error code otherwise.1277 */1278int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)1279{1280 struct fsl_mc_command cmd = { 0 };1281 1282 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_ENABLE, cmd_flags,1283 token);1284 1285 return mc_send_command(mc_io, &cmd);1286}1287 1288/**1289 * dpsw_ctrl_if_disable() - Function disables control interface1290 * @mc_io: Pointer to MC portal's I/O object1291 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1292 * @token: Token of DPSW object1293 *1294 * Return: '0' on Success; Error code otherwise.1295 */1296int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)1297{1298 struct fsl_mc_command cmd = { 0 };1299 1300 cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_DISABLE,1301 cmd_flags,1302 token);1303 1304 return mc_send_command(mc_io, &cmd);1305}1306 1307/**1308 * dpsw_set_egress_flood() - Set egress parameters associated with an FDB ID1309 * @mc_io: Pointer to MC portal's I/O object1310 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1311 * @token: Token of DPSW object1312 * @cfg: Egress flooding configuration1313 *1314 * Return: '0' on Success; Error code otherwise.1315 */1316int dpsw_set_egress_flood(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1317 const struct dpsw_egress_flood_cfg *cfg)1318{1319 struct dpsw_cmd_set_egress_flood *cmd_params;1320 struct fsl_mc_command cmd = { 0 };1321 1322 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_EGRESS_FLOOD, cmd_flags, token);1323 cmd_params = (struct dpsw_cmd_set_egress_flood *)cmd.params;1324 cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);1325 cmd_params->flood_type = cfg->flood_type;1326 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);1327 1328 return mc_send_command(mc_io, &cmd);1329}1330 1331/**1332 * dpsw_if_set_learning_mode() - Configure the learning mode on an interface.1333 * If this API is used, it will take precedence over the FDB configuration.1334 * @mc_io: Pointer to MC portal's I/O object1335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1336 * @token: Token of DPSW object1337 * @if_id: InterfaceID1338 * @mode: Learning mode1339 *1340 * Return: Completion status. '0' on Success; Error code otherwise.1341 */1342int dpsw_if_set_learning_mode(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1343 u16 if_id, enum dpsw_learning_mode mode)1344{1345 struct dpsw_cmd_if_set_learning_mode *cmd_params;1346 struct fsl_mc_command cmd = { 0 };1347 1348 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LEARNING_MODE,1349 cmd_flags,1350 token);1351 cmd_params = (struct dpsw_cmd_if_set_learning_mode *)cmd.params;1352 cmd_params->if_id = cpu_to_le16(if_id);1353 dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode);1354 1355 return mc_send_command(mc_io, &cmd);1356}1357 1358/**1359 * dpsw_acl_add() - Create an ACL table1360 * @mc_io: Pointer to MC portal's I/O object1361 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1362 * @token: Token of DPSW object1363 * @acl_id: Returned ACL ID, for future references1364 * @cfg: ACL configuration1365 *1366 * Create Access Control List table. Multiple ACLs can be created and1367 * co-exist in L2 switch1368 *1369 * Return: '0' on Success; Error code otherwise.1370 */1371int dpsw_acl_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *acl_id,1372 const struct dpsw_acl_cfg *cfg)1373{1374 struct dpsw_cmd_acl_add *cmd_params;1375 struct dpsw_rsp_acl_add *rsp_params;1376 struct fsl_mc_command cmd = { 0 };1377 int err;1378 1379 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD, cmd_flags, token);1380 cmd_params = (struct dpsw_cmd_acl_add *)cmd.params;1381 cmd_params->max_entries = cpu_to_le16(cfg->max_entries);1382 1383 err = mc_send_command(mc_io, &cmd);1384 if (err)1385 return err;1386 1387 rsp_params = (struct dpsw_rsp_acl_add *)cmd.params;1388 *acl_id = le16_to_cpu(rsp_params->acl_id);1389 1390 return 0;1391}1392 1393/**1394 * dpsw_acl_remove() - Remove an ACL table from L2 switch.1395 * @mc_io: Pointer to MC portal's I/O object1396 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1397 * @token: Token of DPSW object1398 * @acl_id: ACL ID1399 *1400 * Return: '0' on Success; Error code otherwise.1401 */1402int dpsw_acl_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1403 u16 acl_id)1404{1405 struct dpsw_cmd_acl_remove *cmd_params;1406 struct fsl_mc_command cmd = { 0 };1407 1408 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE, cmd_flags,1409 token);1410 cmd_params = (struct dpsw_cmd_acl_remove *)cmd.params;1411 cmd_params->acl_id = cpu_to_le16(acl_id);1412 1413 return mc_send_command(mc_io, &cmd);1414}1415 1416/**1417 * dpsw_acl_add_if() - Associate interface/interfaces with an ACL table.1418 * @mc_io: Pointer to MC portal's I/O object1419 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1420 * @token: Token of DPSW object1421 * @acl_id: ACL ID1422 * @cfg: Interfaces list1423 *1424 * Return: '0' on Success; Error code otherwise.1425 */1426int dpsw_acl_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1427 u16 acl_id, const struct dpsw_acl_if_cfg *cfg)1428{1429 struct dpsw_cmd_acl_if *cmd_params;1430 struct fsl_mc_command cmd = { 0 };1431 1432 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_IF, cmd_flags,1433 token);1434 cmd_params = (struct dpsw_cmd_acl_if *)cmd.params;1435 cmd_params->acl_id = cpu_to_le16(acl_id);1436 cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);1437 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);1438 1439 return mc_send_command(mc_io, &cmd);1440}1441 1442/**1443 * dpsw_acl_remove_if() - De-associate interface/interfaces from an ACL table1444 * @mc_io: Pointer to MC portal's I/O object1445 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1446 * @token: Token of DPSW object1447 * @acl_id: ACL ID1448 * @cfg: Interfaces list1449 *1450 * Return: '0' on Success; Error code otherwise.1451 */1452int dpsw_acl_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1453 u16 acl_id, const struct dpsw_acl_if_cfg *cfg)1454{1455 struct dpsw_cmd_acl_if *cmd_params;1456 struct fsl_mc_command cmd = { 0 };1457 1458 /* prepare command */1459 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_IF, cmd_flags,1460 token);1461 cmd_params = (struct dpsw_cmd_acl_if *)cmd.params;1462 cmd_params->acl_id = cpu_to_le16(acl_id);1463 cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);1464 build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);1465 1466 /* send command to mc*/1467 return mc_send_command(mc_io, &cmd);1468}1469 1470/**1471 * dpsw_acl_prepare_entry_cfg() - Setup an ACL entry1472 * @key: Key1473 * @entry_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA1474 *1475 * This function has to be called before adding or removing acl_entry1476 *1477 */1478void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,1479 u8 *entry_cfg_buf)1480{1481 struct dpsw_prep_acl_entry *ext_params;1482 int i;1483 1484 ext_params = (struct dpsw_prep_acl_entry *)entry_cfg_buf;1485 1486 for (i = 0; i < 6; i++) {1487 ext_params->match_l2_dest_mac[i] = key->match.l2_dest_mac[5 - i];1488 ext_params->match_l2_source_mac[i] = key->match.l2_source_mac[5 - i];1489 ext_params->mask_l2_dest_mac[i] = key->mask.l2_dest_mac[5 - i];1490 ext_params->mask_l2_source_mac[i] = key->mask.l2_source_mac[5 - i];1491 }1492 1493 ext_params->match_l2_tpid = cpu_to_le16(key->match.l2_tpid);1494 ext_params->match_l2_vlan_id = cpu_to_le16(key->match.l2_vlan_id);1495 ext_params->match_l3_dest_ip = cpu_to_le32(key->match.l3_dest_ip);1496 ext_params->match_l3_source_ip = cpu_to_le32(key->match.l3_source_ip);1497 ext_params->match_l4_dest_port = cpu_to_le16(key->match.l4_dest_port);1498 ext_params->match_l4_source_port = cpu_to_le16(key->match.l4_source_port);1499 ext_params->match_l2_ether_type = cpu_to_le16(key->match.l2_ether_type);1500 ext_params->match_l2_pcp_dei = key->match.l2_pcp_dei;1501 ext_params->match_l3_dscp = key->match.l3_dscp;1502 1503 ext_params->mask_l2_tpid = cpu_to_le16(key->mask.l2_tpid);1504 ext_params->mask_l2_vlan_id = cpu_to_le16(key->mask.l2_vlan_id);1505 ext_params->mask_l3_dest_ip = cpu_to_le32(key->mask.l3_dest_ip);1506 ext_params->mask_l3_source_ip = cpu_to_le32(key->mask.l3_source_ip);1507 ext_params->mask_l4_dest_port = cpu_to_le16(key->mask.l4_dest_port);1508 ext_params->mask_l4_source_port = cpu_to_le16(key->mask.l4_source_port);1509 ext_params->mask_l2_ether_type = cpu_to_le16(key->mask.l2_ether_type);1510 ext_params->mask_l2_pcp_dei = key->mask.l2_pcp_dei;1511 ext_params->mask_l3_dscp = key->mask.l3_dscp;1512 ext_params->match_l3_protocol = key->match.l3_protocol;1513 ext_params->mask_l3_protocol = key->mask.l3_protocol;1514}1515 1516/**1517 * dpsw_acl_add_entry() - Add a rule to the ACL table.1518 * @mc_io: Pointer to MC portal's I/O object1519 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1520 * @token: Token of DPSW object1521 * @acl_id: ACL ID1522 * @cfg: Entry configuration1523 *1524 * warning: This function has to be called after dpsw_acl_prepare_entry_cfg()1525 *1526 * Return: '0' on Success; Error code otherwise.1527 */1528int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1529 u16 acl_id, const struct dpsw_acl_entry_cfg *cfg)1530{1531 struct dpsw_cmd_acl_entry *cmd_params;1532 struct fsl_mc_command cmd = { 0 };1533 1534 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_ENTRY, cmd_flags,1535 token);1536 cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params;1537 cmd_params->acl_id = cpu_to_le16(acl_id);1538 cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id);1539 cmd_params->precedence = cpu_to_le32(cfg->precedence);1540 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);1541 dpsw_set_field(cmd_params->result_action,1542 RESULT_ACTION,1543 cfg->result.action);1544 1545 return mc_send_command(mc_io, &cmd);1546}1547 1548/**1549 * dpsw_acl_remove_entry() - Removes an entry from ACL.1550 * @mc_io: Pointer to MC portal's I/O object1551 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1552 * @token: Token of DPSW object1553 * @acl_id: ACL ID1554 * @cfg: Entry configuration1555 *1556 * warning: This function has to be called after dpsw_acl_set_entry_cfg()1557 *1558 * Return: '0' on Success; Error code otherwise.1559 */1560int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1561 u16 acl_id, const struct dpsw_acl_entry_cfg *cfg)1562{1563 struct dpsw_cmd_acl_entry *cmd_params;1564 struct fsl_mc_command cmd = { 0 };1565 1566 /* prepare command */1567 cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY,1568 cmd_flags,1569 token);1570 cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params;1571 cmd_params->acl_id = cpu_to_le16(acl_id);1572 cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id);1573 cmd_params->precedence = cpu_to_le32(cfg->precedence);1574 cmd_params->key_iova = cpu_to_le64(cfg->key_iova);1575 dpsw_set_field(cmd_params->result_action,1576 RESULT_ACTION,1577 cfg->result.action);1578 1579 /* send command to mc*/1580 return mc_send_command(mc_io, &cmd);1581}1582 1583/**1584 * dpsw_set_reflection_if() - Set target interface for traffic mirrored1585 * @mc_io: Pointer to MC portal's I/O object1586 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1587 * @token: Token of DPSW object1588 * @if_id: Interface Id1589 *1590 * Only one mirroring destination is allowed per switch1591 *1592 * Return: Completion status. '0' on Success; Error code otherwise.1593 */1594int dpsw_set_reflection_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1595 u16 if_id)1596{1597 struct dpsw_cmd_set_reflection_if *cmd_params;1598 struct fsl_mc_command cmd = { 0 };1599 1600 cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_REFLECTION_IF,1601 cmd_flags,1602 token);1603 cmd_params = (struct dpsw_cmd_set_reflection_if *)cmd.params;1604 cmd_params->if_id = cpu_to_le16(if_id);1605 1606 return mc_send_command(mc_io, &cmd);1607}1608 1609/**1610 * dpsw_if_add_reflection() - Setup mirroring rule1611 * @mc_io: Pointer to MC portal's I/O object1612 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1613 * @token: Token of DPSW object1614 * @if_id: Interface Identifier1615 * @cfg: Reflection configuration1616 *1617 * Return: Completion status. '0' on Success; Error code otherwise.1618 */1619int dpsw_if_add_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1620 u16 if_id, const struct dpsw_reflection_cfg *cfg)1621{1622 struct dpsw_cmd_if_reflection *cmd_params;1623 struct fsl_mc_command cmd = { 0 };1624 1625 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ADD_REFLECTION,1626 cmd_flags,1627 token);1628 cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params;1629 cmd_params->if_id = cpu_to_le16(if_id);1630 cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);1631 dpsw_set_field(cmd_params->filter, FILTER, cfg->filter);1632 1633 return mc_send_command(mc_io, &cmd);1634}1635 1636/**1637 * dpsw_if_remove_reflection() - Remove mirroring rule1638 * @mc_io: Pointer to MC portal's I/O object1639 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'1640 * @token: Token of DPSW object1641 * @if_id: Interface Identifier1642 * @cfg: Reflection configuration1643 *1644 * Return: Completion status. '0' on Success; Error code otherwise.1645 */1646int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,1647 u16 if_id, const struct dpsw_reflection_cfg *cfg)1648{1649 struct dpsw_cmd_if_reflection *cmd_params;1650 struct fsl_mc_command cmd = { 0 };1651 1652 cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_REMOVE_REFLECTION,1653 cmd_flags,1654 token);1655 cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params;1656 cmd_params->if_id = cpu_to_le16(if_id);1657 cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);1658 dpsw_set_field(cmd_params->filter, FILTER, cfg->filter);1659 1660 return mc_send_command(mc_io, &cmd);1661}1662