1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2014-2016 Freescale Semiconductor Inc. 4 * Copyright 2017-2021 NXP 5 * 6 */ 7 8 #include <linux/fsl/mc.h> 9 #include "dpsw.h" 10 #include "dpsw-cmd.h" 11 12 static void build_if_id_bitmap(__le64 *bmap, 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 object 24 * @mc_io: Pointer to MC portal's I/O object 25 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 26 * @dpsw_id: DPSW unique ID 27 * @token: Returned token; use in subsequent API calls 28 * 29 * This function can be used to open a control session for an 30 * already created object; an object may have been declared in 31 * 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 MC 34 * portal; this token must be used in all subsequent commands for 35 * this specific object 36 * 37 * Return: '0' on Success; Error code otherwise. 38 */ 39 int 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 object 65 * @mc_io: Pointer to MC portal's I/O object 66 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 67 * @token: Token of DPSW object 68 * 69 * After this function is called, no further operations are 70 * allowed on the object without opening a new control session. 71 * 72 * Return: '0' on Success; Error code otherwise. 73 */ 74 int 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 functionality 89 * @mc_io: Pointer to MC portal's I/O object 90 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 91 * @token: Token of DPSW object 92 * 93 * Return: Completion status. '0' on Success; Error code otherwise. 94 */ 95 int 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 functionality 110 * @mc_io: Pointer to MC portal's I/O object 111 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 112 * @token: Token of DPSW object 113 * 114 * Return: Completion status. '0' on Success; Error code otherwise. 115 */ 116 int 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 object 132 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 133 * @token: Token of DPSW object 134 * 135 * Return: '0' on Success; Error code otherwise. 136 */ 137 int 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 object 153 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 154 * @token: Token of DPCI object 155 * @irq_index: The interrupt index to configure 156 * @en: Interrupt state - enable = 1, disable = 0 157 * 158 * Allows GPP software to control when interrupts are generated. 159 * Each interrupt can have up to 32 causes. The enable/disable control's the 160 * overall interrupt state. if the interrupt is disabled no causes will cause 161 * an interrupt 162 * 163 * Return: '0' on Success; Error code otherwise. 164 */ 165 int 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 object 186 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 187 * @token: Token of DPCI object 188 * @irq_index: The interrupt index to configure 189 * @mask: Event mask to trigger interrupt; 190 * each bit: 191 * 0 = ignore event 192 * 1 = consider event for asserting IRQ 193 * 194 * Every interrupt can have up to 32 causes and the interrupt model supports 195 * masking/unmasking each cause independently 196 * 197 * Return: '0' on Success; Error code otherwise. 198 */ 199 int 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 interrupts 219 * @mc_io: Pointer to MC portal's I/O object 220 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 221 * @token: Token of DPSW object 222 * @irq_index: The interrupt index to configure 223 * @status: Returned interrupts status - one bit per cause: 224 * 0 = no interrupt pending 225 * 1 = interrupt pending 226 * 227 * Return: '0' on Success; Error code otherwise. 228 */ 229 int 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 status 259 * @mc_io: Pointer to MC portal's I/O object 260 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 261 * @token: Token of DPCI object 262 * @irq_index: The interrupt index to configure 263 * @status: bits to clear (W1C) - one bit per cause: 264 * 0 = don't change 265 * 1 = clear status bit 266 * 267 * Return: '0' on Success; Error code otherwise. 268 */ 269 int 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 attributes 289 * @mc_io: Pointer to MC portal's I/O object 290 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 291 * @token: Token of DPSW object 292 * @attr: Returned DPSW attributes 293 * 294 * Return: Completion status. '0' on Success; Error code otherwise. 295 */ 296 int 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 object 336 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 337 * @token: Token of DPSW object 338 * @if_id: Interface id 339 * @cfg: Link configuration 340 * 341 * Return: '0' on Success; Error code otherwise. 342 */ 343 int 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 state 364 * @mc_io: Pointer to MC portal's I/O object 365 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 366 * @token: Token of DPSW object 367 * @if_id: Interface id 368 * @state: Link state 1 - linkup, 0 - link down or disconnected 369 * 370 * Return: '0' on Success; Error code otherwise. 371 */ 372 int 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 object 404 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 405 * @token: Token of DPSW object 406 * @if_id: Interface Identifier 407 * @cfg: Tag Control Information Configuration 408 * 409 * Return: Completion status. '0' on Success; Error code otherwise. 410 */ 411 int 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 object 436 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 437 * @token: Token of DPSW object 438 * @if_id: Interface Identifier 439 * @cfg: Tag Control Information Configuration 440 * 441 * Return: Completion status. '0' on Success; Error code otherwise. 442 */ 443 int 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 object 475 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 476 * @token: Token of DPSW object 477 * @if_id: Interface Identifier 478 * @cfg: STP State configuration parameters 479 * 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 */ 485 int 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 interface 506 * @mc_io: Pointer to MC portal's I/O object 507 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 508 * @token: Token of DPSW object 509 * @if_id: Interface Identifier 510 * @type: Counter type 511 * @counter: return value 512 * 513 * Return: Completion status. '0' on Success; Error code otherwise. 514 */ 515 int 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 Interface 545 * @mc_io: Pointer to MC portal's I/O object 546 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 547 * @token: Token of DPSW object 548 * @if_id: Interface Identifier 549 * 550 * Return: Completion status. '0' on Success; Error code otherwise. 551 */ 552 int 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 Interface 570 * @mc_io: Pointer to MC portal's I/O object 571 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 572 * @token: Token of DPSW object 573 * @if_id: Interface Identifier 574 * 575 * Return: Completion status. '0' on Success; Error code otherwise. 576 */ 577 int 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 interface 595 * @mc_io: Pointer to MC portal's I/O object 596 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 597 * @token: Token of DPSW object 598 * @if_id: Interface Identifier 599 * @attr: Returned interface attributes 600 * 601 * Return: Completion status. '0' on Success; Error code otherwise. 602 */ 603 int 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 object 637 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 638 * @token: Token of DPSW object 639 * @if_id: Interface Identifier 640 * @frame_length: Maximum Frame Length 641 * 642 * Return: Completion status. '0' on Success; Error code otherwise. 643 */ 644 int 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 object 665 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 666 * @token: Token of DPSW object 667 * @vlan_id: VLAN Identifier 668 * @cfg: VLAN configuration 669 * 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 learning 674 * is obtained by calling dpsw_vlan_add for multiple VLAN IDs 675 * with same fdb_id 676 * 677 * Return: Completion status. '0' on Success; Error code otherwise. 678 */ 679 int 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 object 700 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 701 * @token: Token of DPSW object 702 * @vlan_id: VLAN Identifier 703 * @cfg: Set of interfaces to add 704 * 705 * It adds only interfaces not belonging to this VLAN yet, 706 * otherwise an error is generated and an entire command is 707 * ignored. This function can be called numerous times always 708 * providing required interfaces delta. 709 * 710 * Return: Completion status. '0' on Success; Error code otherwise. 711 */ 712 int 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 be 734 * transmitted as untagged. 735 * @mc_io: Pointer to MC portal's I/O object 736 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 737 * @token: Token of DPSW object 738 * @vlan_id: VLAN Identifier 739 * @cfg: Set of interfaces that should be transmitted as untagged 740 * 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 is 744 * configured untagged already generates an error and the entire 745 * command is ignored. 746 * 747 * Return: Completion status. '0' on Success; Error code otherwise. 748 */ 749 int 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 object 770 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 771 * @token: Token of DPSW object 772 * @vlan_id: VLAN Identifier 773 * @cfg: Set of interfaces that should be removed 774 * 775 * Interfaces must belong to this VLAN, otherwise an error 776 * is returned and an the command is ignored 777 * 778 * Return: Completion status. '0' on Success; Error code otherwise. 779 */ 780 int 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 be 800 * converted from transmitted as untagged to transmit as tagged. 801 * @mc_io: Pointer to MC portal's I/O object 802 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 803 * @token: Token of DPSW object 804 * @vlan_id: VLAN Identifier 805 * @cfg: Set of interfaces that should be removed 806 * 807 * Interfaces provided by API have to belong to this VLAN and 808 * configured untagged, otherwise an error is returned and the 809 * command is ignored 810 * 811 * Return: Completion status. '0' on Success; Error code otherwise. 812 */ 813 int 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 VLAN 833 * @mc_io: Pointer to MC portal's I/O object 834 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 835 * @token: Token of DPSW object 836 * @vlan_id: VLAN Identifier 837 * 838 * Return: Completion status. '0' on Success; Error code otherwise. 839 */ 840 int 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 for 859 * the reference 860 * @mc_io: Pointer to MC portal's I/O object 861 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 862 * @token: Token of DPSW object 863 * @fdb_id: Returned Forwarding Database Identifier 864 * @cfg: FDB Configuration 865 * 866 * Return: Completion status. '0' on Success; Error code otherwise. 867 */ 868 int 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 switch 895 * @mc_io: Pointer to MC portal's I/O object 896 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 897 * @token: Token of DPSW object 898 * @fdb_id: Forwarding Database Identifier 899 * 900 * Return: Completion status. '0' on Success; Error code otherwise. 901 */ 902 int 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 table 919 * @mc_io: Pointer to MC portal's I/O object 920 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 921 * @token: Token of DPSW object 922 * @fdb_id: Forwarding Database Identifier 923 * @cfg: Unicast entry configuration 924 * 925 * Return: Completion status. '0' on Success; Error code otherwise. 926 */ 927 int 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 object 952 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 953 * @token: Token of DPSW object 954 * @fdb_id: Forwarding Database Identifier 955 * @iova_addr: Data will be stored here as an array of struct fdb_dump_entry 956 * @iova_size: Memory size allocated at iova_addr 957 * @num_entries:Number of entries written at iova_addr 958 * 959 * Return: Completion status. '0' on Success; Error code otherwise. 960 * 961 * The memory allocated at iova_addr must be initialized with zero before 962 * command execution. If the FDB table does not fit into memory MC will stop 963 * after the memory is filled up. 964 * The struct fdb_dump_entry array must be parsed until the end of memory 965 * area or until an entry with mac_addr set to zero is found. 966 */ 967 int 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 table 997 * @mc_io: Pointer to MC portal's I/O object 998 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 999 * @token: Token of DPSW object 1000 * @fdb_id: Forwarding Database Identifier 1001 * @cfg: Unicast entry configuration 1002 * 1003 * Return: Completion status. '0' on Success; Error code otherwise. 1004 */ 1005 int 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 group 1029 * @mc_io: Pointer to MC portal's I/O object 1030 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1031 * @token: Token of DPSW object 1032 * @fdb_id: Forwarding Database Identifier 1033 * @cfg: Multicast entry configuration 1034 * 1035 * If group doesn't exist, it will be created. 1036 * It adds only interfaces not belonging to this multicast group 1037 * yet, otherwise error will be generated and the command is 1038 * ignored. 1039 * This function may be called numerous times always providing 1040 * required interfaces delta. 1041 * 1042 * Return: Completion status. '0' on Success; Error code otherwise. 1043 */ 1044 int 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 multicast 1069 * group. 1070 * @mc_io: Pointer to MC portal's I/O object 1071 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1072 * @token: Token of DPSW object 1073 * @fdb_id: Forwarding Database Identifier 1074 * @cfg: Multicast entry configuration 1075 * 1076 * Interfaces provided by this API have to exist in the group, 1077 * otherwise an error will be returned and an entire command 1078 * ignored. If there is no interface left in the group, 1079 * an entire group is deleted 1080 * 1081 * Return: Completion status. '0' on Success; Error code otherwise. 1082 */ 1083 int 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 attributes 1108 * @mc_io: Pointer to MC portal's I/O object 1109 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1110 * @token: Token of DPSW object 1111 * @attr: Returned control interface attributes 1112 * 1113 * Return: '0' on Success; Error code otherwise. 1114 */ 1115 int 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 pools 1139 * @mc_io: Pointer to MC portal's I/O object 1140 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1141 * @token: Token of DPSW object 1142 * @cfg: Buffer pools configuration 1143 * 1144 * Return: '0' on Success; Error code otherwise. 1145 */ 1146 int 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 configuration 1170 * @mc_io: Pointer to MC portal's I/O object 1171 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1172 * @token: Token of dpsw object 1173 * @qtype: dpsw_queue_type of the targeted queue 1174 * @cfg: Rx queue configuration 1175 * 1176 * Return: '0' on Success; Error code otherwise. 1177 */ 1178 int 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 version 1203 * @mc_io: Pointer to MC portal's I/O object 1204 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1205 * @major_ver: Major version of data path switch API 1206 * @minor_ver: Minor version of data path switch API 1207 * 1208 * Return: '0' on Success; Error code otherwise. 1209 */ 1210 int 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 port 1234 * @mc_io: Pointer to MC portal's I/O object 1235 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1236 * @token: Token of DPSW object 1237 * @if_id: Interface Identifier 1238 * @mac_addr: MAC address of the physical port, if any, otherwise 0 1239 * 1240 * Return: Completion status. '0' on Success; Error code otherwise. 1241 */ 1242 int 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 interface 1272 * @mc_io: Pointer to MC portal's I/O object 1273 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1274 * @token: Token of DPSW object 1275 * 1276 * Return: '0' on Success; Error code otherwise. 1277 */ 1278 int 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 interface 1290 * @mc_io: Pointer to MC portal's I/O object 1291 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1292 * @token: Token of DPSW object 1293 * 1294 * Return: '0' on Success; Error code otherwise. 1295 */ 1296 int 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 ID 1309 * @mc_io: Pointer to MC portal's I/O object 1310 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1311 * @token: Token of DPSW object 1312 * @cfg: Egress flooding configuration 1313 * 1314 * Return: '0' on Success; Error code otherwise. 1315 */ 1316 int 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 object 1335 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1336 * @token: Token of DPSW object 1337 * @if_id: InterfaceID 1338 * @mode: Learning mode 1339 * 1340 * Return: Completion status. '0' on Success; Error code otherwise. 1341 */ 1342 int 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 table 1360 * @mc_io: Pointer to MC portal's I/O object 1361 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1362 * @token: Token of DPSW object 1363 * @acl_id: Returned ACL ID, for future references 1364 * @cfg: ACL configuration 1365 * 1366 * Create Access Control List table. Multiple ACLs can be created and 1367 * co-exist in L2 switch 1368 * 1369 * Return: '0' on Success; Error code otherwise. 1370 */ 1371 int 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 object 1396 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1397 * @token: Token of DPSW object 1398 * @acl_id: ACL ID 1399 * 1400 * Return: '0' on Success; Error code otherwise. 1401 */ 1402 int 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 object 1419 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1420 * @token: Token of DPSW object 1421 * @acl_id: ACL ID 1422 * @cfg: Interfaces list 1423 * 1424 * Return: '0' on Success; Error code otherwise. 1425 */ 1426 int 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 table 1444 * @mc_io: Pointer to MC portal's I/O object 1445 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1446 * @token: Token of DPSW object 1447 * @acl_id: ACL ID 1448 * @cfg: Interfaces list 1449 * 1450 * Return: '0' on Success; Error code otherwise. 1451 */ 1452 int 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 entry 1472 * @key: Key 1473 * @entry_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA 1474 * 1475 * This function has to be called before adding or removing acl_entry 1476 * 1477 */ 1478 void 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 object 1519 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1520 * @token: Token of DPSW object 1521 * @acl_id: ACL ID 1522 * @cfg: Entry configuration 1523 * 1524 * warning: This function has to be called after dpsw_acl_prepare_entry_cfg() 1525 * 1526 * Return: '0' on Success; Error code otherwise. 1527 */ 1528 int 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 object 1551 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1552 * @token: Token of DPSW object 1553 * @acl_id: ACL ID 1554 * @cfg: Entry configuration 1555 * 1556 * warning: This function has to be called after dpsw_acl_set_entry_cfg() 1557 * 1558 * Return: '0' on Success; Error code otherwise. 1559 */ 1560 int 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