1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2013-2016 Freescale Semiconductor Inc. 4 * Copyright 2018-2021 NXP 5 * 6 */ 7 #include <fsl_mc_sys.h> 8 #include <fsl_mc_cmd.h> 9 #include <fsl_dpdmux.h> 10 #include <fsl_dpdmux_cmd.h> 11 12 /** @addtogroup dpdmux 13 * @{ 14 */ 15 16 /** 17 * dpdmux_open() - Open a control session for the specified object 18 * @mc_io: Pointer to MC portal's I/O object 19 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 20 * @dpdmux_id: DPDMUX unique ID 21 * @token: Returned token; use in subsequent API calls 22 * 23 * This function can be used to open a control session for an 24 * already created object; an object may have been declared in 25 * the DPL or by calling the dpdmux_create() function. 26 * This function returns a unique authentication token, 27 * associated with the specific object ID and the specific MC 28 * portal; this token must be used in all subsequent commands for 29 * this specific object. 30 * 31 * Return: '0' on Success; Error code otherwise. 32 */ 33 int dpdmux_open(struct fsl_mc_io *mc_io, 34 uint32_t cmd_flags, 35 int dpdmux_id, 36 uint16_t *token) 37 { 38 struct mc_command cmd = { 0 }; 39 struct dpdmux_cmd_open *cmd_params; 40 int err; 41 42 /* prepare command */ 43 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_OPEN, 44 cmd_flags, 45 0); 46 cmd_params = (struct dpdmux_cmd_open *)cmd.params; 47 cmd_params->dpdmux_id = cpu_to_le32(dpdmux_id); 48 49 /* send command to mc*/ 50 err = mc_send_command(mc_io, &cmd); 51 if (err) 52 return err; 53 54 /* retrieve response parameters */ 55 *token = mc_cmd_hdr_read_token(&cmd); 56 57 return 0; 58 } 59 60 /** 61 * dpdmux_close() - Close the control session of the object 62 * @mc_io: Pointer to MC portal's I/O object 63 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 64 * @token: Token of DPDMUX object 65 * 66 * After this function is called, no further operations are 67 * allowed on the object without opening a new control session. 68 * 69 * Return: '0' on Success; Error code otherwise. 70 */ 71 int dpdmux_close(struct fsl_mc_io *mc_io, 72 uint32_t cmd_flags, 73 uint16_t token) 74 { 75 struct mc_command cmd = { 0 }; 76 77 /* prepare command */ 78 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CLOSE, 79 cmd_flags, 80 token); 81 82 /* send command to mc*/ 83 return mc_send_command(mc_io, &cmd); 84 } 85 86 /** 87 * dpdmux_create() - Create the DPDMUX object 88 * @mc_io: Pointer to MC portal's I/O object 89 * @dprc_token: Parent container token; '0' for default container 90 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 91 * @cfg: Configuration structure 92 * @obj_id: returned object id 93 * 94 * Create the DPDMUX object, allocate required resources and 95 * perform required initialization. 96 * 97 * The object can be created either by declaring it in the 98 * DPL file, or by calling this function. 99 * 100 * The function accepts an authentication token of a parent 101 * container that this object should be assigned to. The token 102 * can be '0' so the object will be assigned to the default container. 103 * The newly created object can be opened with the returned 104 * object id and using the container's associated tokens and MC portals. 105 * 106 * Return: '0' on Success; Error code otherwise. 107 */ 108 int dpdmux_create(struct fsl_mc_io *mc_io, 109 uint16_t dprc_token, 110 uint32_t cmd_flags, 111 const struct dpdmux_cfg *cfg, 112 uint32_t *obj_id) 113 { 114 struct mc_command cmd = { 0 }; 115 struct dpdmux_cmd_create *cmd_params; 116 int err; 117 118 /* prepare command */ 119 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CREATE, 120 cmd_flags, 121 dprc_token); 122 cmd_params = (struct dpdmux_cmd_create *)cmd.params; 123 cmd_params->method = cfg->method; 124 cmd_params->manip = cfg->manip; 125 cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); 126 cmd_params->default_if = cpu_to_le16(cfg->default_if); 127 cmd_params->adv_max_dmat_entries = 128 cpu_to_le16(cfg->adv.max_dmat_entries); 129 cmd_params->adv_max_mc_groups = cpu_to_le16(cfg->adv.max_mc_groups); 130 cmd_params->adv_max_vlan_ids = cpu_to_le16(cfg->adv.max_vlan_ids); 131 cmd_params->mem_size = cpu_to_le16(cfg->adv.mem_size); 132 cmd_params->options = cpu_to_le64(cfg->adv.options); 133 134 /* send command to mc*/ 135 err = mc_send_command(mc_io, &cmd); 136 if (err) 137 return err; 138 139 /* retrieve response parameters */ 140 *obj_id = mc_cmd_read_object_id(&cmd); 141 142 return 0; 143 } 144 145 /** 146 * dpdmux_destroy() - Destroy the DPDMUX object and release all its resources. 147 * @mc_io: Pointer to MC portal's I/O object 148 * @dprc_token: Parent container token; '0' for default container 149 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 150 * @object_id: The object id; it must be a valid id within the container that 151 * created this object; 152 * 153 * The function accepts the authentication token of the parent container that 154 * created the object (not the one that currently owns the object). The object 155 * is searched within parent using the provided 'object_id'. 156 * All tokens to the object must be closed before calling destroy. 157 * 158 * Return: '0' on Success; error code otherwise. 159 */ 160 int dpdmux_destroy(struct fsl_mc_io *mc_io, 161 uint16_t dprc_token, 162 uint32_t cmd_flags, 163 uint32_t object_id) 164 { 165 struct mc_command cmd = { 0 }; 166 struct dpdmux_cmd_destroy *cmd_params; 167 168 /* prepare command */ 169 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_DESTROY, 170 cmd_flags, 171 dprc_token); 172 cmd_params = (struct dpdmux_cmd_destroy *)cmd.params; 173 cmd_params->dpdmux_id = cpu_to_le32(object_id); 174 175 /* send command to mc*/ 176 return mc_send_command(mc_io, &cmd); 177 } 178 179 /** 180 * dpdmux_enable() - Enable DPDMUX functionality 181 * @mc_io: Pointer to MC portal's I/O object 182 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 183 * @token: Token of DPDMUX object 184 * 185 * Return: '0' on Success; Error code otherwise. 186 */ 187 int dpdmux_enable(struct fsl_mc_io *mc_io, 188 uint32_t cmd_flags, 189 uint16_t token) 190 { 191 struct mc_command cmd = { 0 }; 192 193 /* prepare command */ 194 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ENABLE, 195 cmd_flags, 196 token); 197 198 /* send command to mc*/ 199 return mc_send_command(mc_io, &cmd); 200 } 201 202 /** 203 * dpdmux_disable() - Disable DPDMUX functionality 204 * @mc_io: Pointer to MC portal's I/O object 205 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 206 * @token: Token of DPDMUX object 207 * 208 * Return: '0' on Success; Error code otherwise. 209 */ 210 int dpdmux_disable(struct fsl_mc_io *mc_io, 211 uint32_t cmd_flags, 212 uint16_t token) 213 { 214 struct mc_command cmd = { 0 }; 215 216 /* prepare command */ 217 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_DISABLE, 218 cmd_flags, 219 token); 220 221 /* send command to mc*/ 222 return mc_send_command(mc_io, &cmd); 223 } 224 225 /** 226 * dpdmux_is_enabled() - Check if the DPDMUX is enabled. 227 * @mc_io: Pointer to MC portal's I/O object 228 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 229 * @token: Token of DPDMUX object 230 * @en: Returns '1' if object is enabled; '0' otherwise 231 * 232 * Return: '0' on Success; Error code otherwise. 233 */ 234 int dpdmux_is_enabled(struct fsl_mc_io *mc_io, 235 uint32_t cmd_flags, 236 uint16_t token, 237 int *en) 238 { 239 struct mc_command cmd = { 0 }; 240 struct dpdmux_rsp_is_enabled *rsp_params; 241 int err; 242 243 /* prepare command */ 244 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IS_ENABLED, 245 cmd_flags, 246 token); 247 248 /* send command to mc*/ 249 err = mc_send_command(mc_io, &cmd); 250 if (err) 251 return err; 252 253 /* retrieve response parameters */ 254 rsp_params = (struct dpdmux_rsp_is_enabled *)cmd.params; 255 *en = dpdmux_get_field(rsp_params->en, ENABLE); 256 257 return 0; 258 } 259 260 /** 261 * dpdmux_reset() - Reset the DPDMUX, returns the object to initial state. 262 * @mc_io: Pointer to MC portal's I/O object 263 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 264 * @token: Token of DPDMUX object 265 * 266 * Return: '0' on Success; Error code otherwise. 267 */ 268 int dpdmux_reset(struct fsl_mc_io *mc_io, 269 uint32_t cmd_flags, 270 uint16_t token) 271 { 272 struct mc_command cmd = { 0 }; 273 274 /* prepare command */ 275 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_RESET, 276 cmd_flags, 277 token); 278 279 /* send command to mc*/ 280 return mc_send_command(mc_io, &cmd); 281 } 282 283 /** 284 * dpdmux_set_resetable() - Set overall resetable DPDMUX parameters. 285 * @mc_io: Pointer to MC portal's I/O object 286 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 287 * @token: Token of DPDMUX object 288 * @skip_reset_flags: By default all are 0. 289 * By setting 1 will deactivate the reset. 290 * The flags are: 291 * DPDMUX_SKIP_DEFAULT_INTERFACE 0x01 292 * DPDMUX_SKIP_UNICAST_RULES 0x02 293 * DPDMUX_SKIP_MULTICAST_RULES 0x04 294 * 295 * For example, by default, through DPDMUX_RESET the default 296 * interface will be restored with the one from create. 297 * By setting DPDMUX_SKIP_DEFAULT_INTERFACE flag, 298 * through DPDMUX_RESET the default interface will not be modified. 299 * 300 * Return: '0' on Success; Error code otherwise. 301 */ 302 int dpdmux_set_resetable(struct fsl_mc_io *mc_io, 303 uint32_t cmd_flags, 304 uint16_t token, 305 uint8_t skip_reset_flags) 306 { 307 struct mc_command cmd = { 0 }; 308 struct dpdmux_cmd_set_skip_reset_flags *cmd_params; 309 310 /* prepare command */ 311 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_RESETABLE, 312 cmd_flags, 313 token); 314 cmd_params = (struct dpdmux_cmd_set_skip_reset_flags *)cmd.params; 315 dpdmux_set_field(cmd_params->skip_reset_flags, 316 SKIP_RESET_FLAGS, 317 skip_reset_flags); 318 319 /* send command to mc*/ 320 return mc_send_command(mc_io, &cmd); 321 } 322 323 /** 324 * dpdmux_get_resetable() - Get overall resetable parameters. 325 * @mc_io: Pointer to MC portal's I/O object 326 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 327 * @token: Token of DPDMUX object 328 * @skip_reset_flags: Get the reset flags. 329 * 330 * The flags are: 331 * DPDMUX_SKIP_DEFAULT_INTERFACE 0x01 332 * DPDMUX_SKIP_UNICAST_RULES 0x02 333 * DPDMUX_SKIP_MULTICAST_RULES 0x04 334 * 335 * Return: '0' on Success; Error code otherwise. 336 */ 337 int dpdmux_get_resetable(struct fsl_mc_io *mc_io, 338 uint32_t cmd_flags, 339 uint16_t token, 340 uint8_t *skip_reset_flags) 341 { 342 struct mc_command cmd = { 0 }; 343 struct dpdmux_rsp_get_skip_reset_flags *rsp_params; 344 int err; 345 346 /* prepare command */ 347 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_RESETABLE, 348 cmd_flags, 349 token); 350 351 /* send command to mc*/ 352 err = mc_send_command(mc_io, &cmd); 353 if (err) 354 return err; 355 356 /* retrieve response parameters */ 357 rsp_params = (struct dpdmux_rsp_get_skip_reset_flags *)cmd.params; 358 *skip_reset_flags = dpdmux_get_field(rsp_params->skip_reset_flags, 359 SKIP_RESET_FLAGS); 360 361 return 0; 362 } 363 364 /** 365 * dpdmux_get_attributes() - Retrieve DPDMUX attributes 366 * @mc_io: Pointer to MC portal's I/O object 367 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 368 * @token: Token of DPDMUX object 369 * @attr: Returned object's attributes 370 * 371 * Return: '0' on Success; Error code otherwise. 372 */ 373 int dpdmux_get_attributes(struct fsl_mc_io *mc_io, 374 uint32_t cmd_flags, 375 uint16_t token, 376 struct dpdmux_attr *attr) 377 { 378 struct mc_command cmd = { 0 }; 379 struct dpdmux_rsp_get_attr *rsp_params; 380 int err; 381 382 /* prepare command */ 383 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_ATTR, 384 cmd_flags, 385 token); 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 dpdmux_rsp_get_attr *)cmd.params; 394 attr->id = le32_to_cpu(rsp_params->id); 395 attr->options = le64_to_cpu(rsp_params->options); 396 attr->method = rsp_params->method; 397 attr->manip = rsp_params->manip; 398 attr->num_ifs = le16_to_cpu(rsp_params->num_ifs); 399 attr->mem_size = le16_to_cpu(rsp_params->mem_size); 400 attr->default_if = le16_to_cpu(rsp_params->default_if); 401 attr->max_dmat_entries = le16_to_cpu(rsp_params->max_dmat_entries); 402 attr->max_mc_groups = le16_to_cpu(rsp_params->max_mc_groups); 403 attr->max_vlan_ids = le16_to_cpu(rsp_params->max_vlan_ids); 404 405 return 0; 406 } 407 408 /** 409 * dpdmux_if_enable() - Enable Interface 410 * @mc_io: Pointer to MC portal's I/O object 411 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 412 * @token: Token of DPDMUX object 413 * @if_id: Interface Identifier 414 * 415 * Return: Completion status. '0' on Success; Error code otherwise. 416 */ 417 int dpdmux_if_enable(struct fsl_mc_io *mc_io, 418 uint32_t cmd_flags, 419 uint16_t token, 420 uint16_t if_id) 421 { 422 struct dpdmux_cmd_if *cmd_params; 423 struct mc_command cmd = { 0 }; 424 425 /* prepare command */ 426 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_ENABLE, 427 cmd_flags, 428 token); 429 cmd_params = (struct dpdmux_cmd_if *)cmd.params; 430 cmd_params->if_id = cpu_to_le16(if_id); 431 432 /* send command to mc*/ 433 return mc_send_command(mc_io, &cmd); 434 } 435 436 /** 437 * dpdmux_if_disable() - Disable Interface 438 * @mc_io: Pointer to MC portal's I/O object 439 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 440 * @token: Token of DPDMUX object 441 * @if_id: Interface Identifier 442 * 443 * Return: Completion status. '0' on Success; Error code otherwise. 444 */ 445 int dpdmux_if_disable(struct fsl_mc_io *mc_io, 446 uint32_t cmd_flags, 447 uint16_t token, 448 uint16_t if_id) 449 { 450 struct dpdmux_cmd_if *cmd_params; 451 struct mc_command cmd = { 0 }; 452 453 /* prepare command */ 454 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_DISABLE, 455 cmd_flags, 456 token); 457 cmd_params = (struct dpdmux_cmd_if *)cmd.params; 458 cmd_params->if_id = cpu_to_le16(if_id); 459 460 /* send command to mc*/ 461 return mc_send_command(mc_io, &cmd); 462 } 463 464 /** 465 * dpdmux_set_max_frame_length() - Set the maximum frame length in DPDMUX 466 * @mc_io: Pointer to MC portal's I/O object 467 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 468 * @token: Token of DPDMUX object 469 * @max_frame_length: The required maximum frame length 470 * 471 * Update the maximum frame length on all DMUX interfaces. 472 * In case of VEPA, the maximum frame length on all dmux interfaces 473 * will be updated with the minimum value of the mfls of the connected 474 * dpnis and the actual value of dmux mfl. 475 * 476 * If dpdmux object is created using DPDMUX_OPT_AUTO_MAX_FRAME_LEN and maximum 477 * frame length is changed for a dpni connected to dpdmux interface the change 478 * is propagated through dpdmux interfaces and will overwrite the value set using 479 * this API. 480 * 481 * Return: '0' on Success; Error code otherwise. 482 */ 483 int dpdmux_set_max_frame_length(struct fsl_mc_io *mc_io, 484 uint32_t cmd_flags, 485 uint16_t token, 486 uint16_t max_frame_length) 487 { 488 struct mc_command cmd = { 0 }; 489 struct dpdmux_cmd_set_max_frame_length *cmd_params; 490 491 /* prepare command */ 492 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_MAX_FRAME_LENGTH, 493 cmd_flags, 494 token); 495 cmd_params = (struct dpdmux_cmd_set_max_frame_length *)cmd.params; 496 cmd_params->max_frame_length = cpu_to_le16(max_frame_length); 497 498 /* send command to mc*/ 499 return mc_send_command(mc_io, &cmd); 500 } 501 502 /** 503 * dpdmux_get_max_frame_length() - Return the maximum frame length for DPDMUX 504 * interface 505 * @mc_io: Pointer to MC portal's I/O object 506 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 507 * @token: Token of DPDMUX object 508 * @if_id: Interface id 509 * @max_frame_length: maximum frame length 510 * 511 * When dpdmux object is in VEPA mode this function will ignore if_id parameter 512 * and will return maximum frame length for uplink interface (if_id==0). 513 * 514 * Return: '0' on Success; Error code otherwise. 515 */ 516 int dpdmux_get_max_frame_length(struct fsl_mc_io *mc_io, 517 uint32_t cmd_flags, 518 uint16_t token, 519 uint16_t if_id, 520 uint16_t *max_frame_length) 521 { 522 struct mc_command cmd = { 0 }; 523 struct dpdmux_cmd_get_max_frame_len *cmd_params; 524 struct dpdmux_rsp_get_max_frame_len *rsp_params; 525 int err = 0; 526 527 /* prepare command */ 528 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_MAX_FRAME_LENGTH, 529 cmd_flags, 530 token); 531 cmd_params = (struct dpdmux_cmd_get_max_frame_len *)cmd.params; 532 cmd_params->if_id = cpu_to_le16(if_id); 533 534 err = mc_send_command(mc_io, &cmd); 535 if (err) 536 return err; 537 538 rsp_params = (struct dpdmux_rsp_get_max_frame_len *)cmd.params; 539 *max_frame_length = le16_to_cpu(rsp_params->max_len); 540 541 /* send command to mc*/ 542 return err; 543 } 544 545 /** 546 * dpdmux_ul_reset_counters() - Function resets the uplink counter 547 * @mc_io: Pointer to MC portal's I/O object 548 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 549 * @token: Token of DPDMUX object 550 * 551 * Return: '0' on Success; Error code otherwise. 552 */ 553 int dpdmux_ul_reset_counters(struct fsl_mc_io *mc_io, 554 uint32_t cmd_flags, 555 uint16_t token) 556 { 557 struct mc_command cmd = { 0 }; 558 559 /* prepare command */ 560 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_UL_RESET_COUNTERS, 561 cmd_flags, 562 token); 563 564 /* send command to mc*/ 565 return mc_send_command(mc_io, &cmd); 566 } 567 568 /** 569 * dpdmux_if_set_accepted_frames() - Set the accepted frame types 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 DPDMUX object 573 * @if_id: Interface ID (0 for uplink, or 1-num_ifs); 574 * @cfg: Frame types configuration 575 * 576 * if 'DPDMUX_ADMIT_ONLY_VLAN_TAGGED' is set - untagged frames or 577 * priority-tagged frames are discarded. 578 * if 'DPDMUX_ADMIT_ONLY_UNTAGGED' is set - untagged frames or 579 * priority-tagged frames are accepted. 580 * if 'DPDMUX_ADMIT_ALL' is set (default mode) - all VLAN tagged, 581 * untagged and priority-tagged frame are accepted; 582 * 583 * Return: '0' on Success; Error code otherwise. 584 */ 585 int dpdmux_if_set_accepted_frames(struct fsl_mc_io *mc_io, 586 uint32_t cmd_flags, 587 uint16_t token, 588 uint16_t if_id, 589 const struct dpdmux_accepted_frames *cfg) 590 { 591 struct mc_command cmd = { 0 }; 592 struct dpdmux_cmd_if_set_accepted_frames *cmd_params; 593 594 /* prepare command */ 595 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_SET_ACCEPTED_FRAMES, 596 cmd_flags, 597 token); 598 cmd_params = (struct dpdmux_cmd_if_set_accepted_frames *)cmd.params; 599 cmd_params->if_id = cpu_to_le16(if_id); 600 dpdmux_set_field(cmd_params->frames_options, 601 ACCEPTED_FRAMES_TYPE, 602 cfg->type); 603 dpdmux_set_field(cmd_params->frames_options, 604 UNACCEPTED_FRAMES_ACTION, 605 cfg->unaccept_act); 606 607 /* send command to mc*/ 608 return mc_send_command(mc_io, &cmd); 609 } 610 611 /** 612 * dpdmux_if_get_attributes() - Obtain DPDMUX interface attributes 613 * @mc_io: Pointer to MC portal's I/O object 614 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 615 * @token: Token of DPDMUX object 616 * @if_id: Interface ID (0 for uplink, or 1-num_ifs); 617 * @attr: Interface attributes 618 * 619 * Return: '0' on Success; Error code otherwise. 620 */ 621 int dpdmux_if_get_attributes(struct fsl_mc_io *mc_io, 622 uint32_t cmd_flags, 623 uint16_t token, 624 uint16_t if_id, 625 struct dpdmux_if_attr *attr) 626 { 627 struct mc_command cmd = { 0 }; 628 struct dpdmux_cmd_if *cmd_params; 629 struct dpdmux_rsp_if_get_attr *rsp_params; 630 int err; 631 632 /* prepare command */ 633 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_ATTR, 634 cmd_flags, 635 token); 636 cmd_params = (struct dpdmux_cmd_if *)cmd.params; 637 cmd_params->if_id = cpu_to_le16(if_id); 638 639 /* send command to mc*/ 640 err = mc_send_command(mc_io, &cmd); 641 if (err) 642 return err; 643 644 /* retrieve response parameters */ 645 rsp_params = (struct dpdmux_rsp_if_get_attr *)cmd.params; 646 attr->rate = le32_to_cpu(rsp_params->rate); 647 attr->enabled = dpdmux_get_field(rsp_params->enabled, ENABLE); 648 attr->is_default = dpdmux_get_field(rsp_params->enabled, IS_DEFAULT); 649 attr->accept_frame_type = dpdmux_get_field( 650 rsp_params->accepted_frames_type, 651 ACCEPTED_FRAMES_TYPE); 652 653 return 0; 654 } 655 656 /** 657 * dpdmux_if_remove_l2_rule() - Remove L2 rule from DPDMUX table 658 * @mc_io: Pointer to MC portal's I/O object 659 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 660 * @token: Token of DPDMUX object 661 * @if_id: Destination interface ID 662 * @rule: L2 rule 663 * 664 * Function removes a L2 rule from DPDMUX table 665 * or adds an interface to an existing multicast address 666 * 667 * Return: '0' on Success; Error code otherwise. 668 */ 669 int dpdmux_if_remove_l2_rule(struct fsl_mc_io *mc_io, 670 uint32_t cmd_flags, 671 uint16_t token, 672 uint16_t if_id, 673 const struct dpdmux_l2_rule *rule) 674 { 675 struct mc_command cmd = { 0 }; 676 struct dpdmux_cmd_if_l2_rule *cmd_params; 677 678 /* prepare command */ 679 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_REMOVE_L2_RULE, 680 cmd_flags, 681 token); 682 cmd_params = (struct dpdmux_cmd_if_l2_rule *)cmd.params; 683 cmd_params->if_id = cpu_to_le16(if_id); 684 cmd_params->vlan_id = cpu_to_le16(rule->vlan_id); 685 cmd_params->mac_addr5 = rule->mac_addr[5]; 686 cmd_params->mac_addr4 = rule->mac_addr[4]; 687 cmd_params->mac_addr3 = rule->mac_addr[3]; 688 cmd_params->mac_addr2 = rule->mac_addr[2]; 689 cmd_params->mac_addr1 = rule->mac_addr[1]; 690 cmd_params->mac_addr0 = rule->mac_addr[0]; 691 692 /* send command to mc*/ 693 return mc_send_command(mc_io, &cmd); 694 } 695 696 /** 697 * dpdmux_if_add_l2_rule() - Add L2 rule into DPDMUX table 698 * @mc_io: Pointer to MC portal's I/O object 699 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 700 * @token: Token of DPDMUX object 701 * @if_id: Destination interface ID 702 * @rule: L2 rule 703 * 704 * Function adds a L2 rule into DPDMUX table 705 * or adds an interface to an existing multicast address 706 * 707 * Return: '0' on Success; Error code otherwise. 708 */ 709 int dpdmux_if_add_l2_rule(struct fsl_mc_io *mc_io, 710 uint32_t cmd_flags, 711 uint16_t token, 712 uint16_t if_id, 713 const struct dpdmux_l2_rule *rule) 714 { 715 struct mc_command cmd = { 0 }; 716 struct dpdmux_cmd_if_l2_rule *cmd_params; 717 718 /* prepare command */ 719 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_ADD_L2_RULE, 720 cmd_flags, 721 token); 722 cmd_params = (struct dpdmux_cmd_if_l2_rule *)cmd.params; 723 cmd_params->if_id = cpu_to_le16(if_id); 724 cmd_params->vlan_id = cpu_to_le16(rule->vlan_id); 725 cmd_params->mac_addr5 = rule->mac_addr[5]; 726 cmd_params->mac_addr4 = rule->mac_addr[4]; 727 cmd_params->mac_addr3 = rule->mac_addr[3]; 728 cmd_params->mac_addr2 = rule->mac_addr[2]; 729 cmd_params->mac_addr1 = rule->mac_addr[1]; 730 cmd_params->mac_addr0 = rule->mac_addr[0]; 731 732 /* send command to mc*/ 733 return mc_send_command(mc_io, &cmd); 734 } 735 736 /** 737 * dpdmux_if_get_counter() - Functions obtains specific counter of an interface 738 * @mc_io: Pointer to MC portal's I/O object 739 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 740 * @token: Token of DPDMUX object 741 * @if_id: Interface Id 742 * @counter_type: counter type 743 * @counter: Returned specific counter information 744 * 745 * Return: '0' on Success; Error code otherwise. 746 */ 747 int dpdmux_if_get_counter(struct fsl_mc_io *mc_io, 748 uint32_t cmd_flags, 749 uint16_t token, 750 uint16_t if_id, 751 enum dpdmux_counter_type counter_type, 752 uint64_t *counter) 753 { 754 struct mc_command cmd = { 0 }; 755 struct dpdmux_cmd_if_get_counter *cmd_params; 756 struct dpdmux_rsp_if_get_counter *rsp_params; 757 int err; 758 759 /* prepare command */ 760 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_COUNTER, 761 cmd_flags, 762 token); 763 cmd_params = (struct dpdmux_cmd_if_get_counter *)cmd.params; 764 cmd_params->if_id = cpu_to_le16(if_id); 765 cmd_params->counter_type = counter_type; 766 767 /* send command to mc*/ 768 err = mc_send_command(mc_io, &cmd); 769 if (err) 770 return err; 771 772 /* retrieve response parameters */ 773 rsp_params = (struct dpdmux_rsp_if_get_counter *)cmd.params; 774 *counter = le64_to_cpu(rsp_params->counter); 775 776 return 0; 777 } 778 779 /** 780 * dpdmux_if_set_link_cfg() - set the link configuration. 781 * @mc_io: Pointer to MC portal's I/O object 782 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 783 * @token: Token of DPSW object 784 * @if_id: interface id 785 * @cfg: Link configuration 786 * 787 * Return: '0' on Success; Error code otherwise. 788 */ 789 int dpdmux_if_set_link_cfg(struct fsl_mc_io *mc_io, 790 uint32_t cmd_flags, 791 uint16_t token, 792 uint16_t if_id, 793 struct dpdmux_link_cfg *cfg) 794 { 795 struct mc_command cmd = { 0 }; 796 struct dpdmux_cmd_if_set_link_cfg *cmd_params; 797 798 /* prepare command */ 799 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_SET_LINK_CFG, 800 cmd_flags, 801 token); 802 cmd_params = (struct dpdmux_cmd_if_set_link_cfg *)cmd.params; 803 cmd_params->if_id = cpu_to_le16(if_id); 804 cmd_params->rate = cpu_to_le32(cfg->rate); 805 cmd_params->options = cpu_to_le64(cfg->options); 806 cmd_params->advertising = cpu_to_le64(cfg->advertising); 807 808 /* send command to mc*/ 809 return mc_send_command(mc_io, &cmd); 810 } 811 812 /** 813 * dpdmux_if_get_link_state - Return the link state 814 * @mc_io: Pointer to MC portal's I/O object 815 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 816 * @token: Token of DPSW object 817 * @if_id: interface id 818 * @state: link state 819 * 820 * @returns '0' on Success; Error code otherwise. 821 */ 822 int dpdmux_if_get_link_state(struct fsl_mc_io *mc_io, 823 uint32_t cmd_flags, 824 uint16_t token, 825 uint16_t if_id, 826 struct dpdmux_link_state *state) 827 { 828 struct mc_command cmd = { 0 }; 829 struct dpdmux_cmd_if_get_link_state *cmd_params; 830 struct dpdmux_rsp_if_get_link_state *rsp_params; 831 int err; 832 833 /* prepare command */ 834 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_LINK_STATE, 835 cmd_flags, 836 token); 837 cmd_params = (struct dpdmux_cmd_if_get_link_state *)cmd.params; 838 cmd_params->if_id = cpu_to_le16(if_id); 839 840 /* send command to mc*/ 841 err = mc_send_command(mc_io, &cmd); 842 if (err) 843 return err; 844 845 /* retrieve response parameters */ 846 rsp_params = (struct dpdmux_rsp_if_get_link_state *)cmd.params; 847 state->rate = le32_to_cpu(rsp_params->rate); 848 state->options = le64_to_cpu(rsp_params->options); 849 state->up = dpdmux_get_field(rsp_params->up, UP); 850 state->state_valid = dpdmux_get_field(rsp_params->up, STATE_VALID); 851 state->supported = le64_to_cpu(rsp_params->supported); 852 state->advertising = le64_to_cpu(rsp_params->advertising); 853 854 return 0; 855 } 856 857 /** 858 * dpdmux_if_set_default - Set default interface 859 * @mc_io: Pointer to MC portal's I/O object 860 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 861 * @token: Token of DPSW object 862 * @if_id: interface id 863 * 864 * @returns '0' on Success; Error code otherwise. 865 */ 866 int dpdmux_if_set_default(struct fsl_mc_io *mc_io, 867 uint32_t cmd_flags, 868 uint16_t token, 869 uint16_t if_id) 870 { 871 struct dpdmux_cmd_if *cmd_params; 872 struct mc_command cmd = { 0 }; 873 874 /* prepare command */ 875 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_SET_DEFAULT, 876 cmd_flags, 877 token); 878 cmd_params = (struct dpdmux_cmd_if *)cmd.params; 879 cmd_params->if_id = cpu_to_le16(if_id); 880 881 /* send command to mc*/ 882 return mc_send_command(mc_io, &cmd); 883 } 884 885 /** 886 * dpdmux_if_get_default - Get default interface 887 * @mc_io: Pointer to MC portal's I/O object 888 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 889 * @token: Token of DPSW object 890 * @if_id: interface id 891 * 892 * @returns '0' on Success; Error code otherwise. 893 */ 894 int dpdmux_if_get_default(struct fsl_mc_io *mc_io, 895 uint32_t cmd_flags, 896 uint16_t token, 897 uint16_t *if_id) 898 { 899 struct dpdmux_cmd_if *rsp_params; 900 struct mc_command cmd = { 0 }; 901 int err; 902 903 /* prepare command */ 904 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_DEFAULT, 905 cmd_flags, 906 token); 907 908 /* send command to mc*/ 909 err = mc_send_command(mc_io, &cmd); 910 if (err) 911 return err; 912 913 /* retrieve response parameters */ 914 rsp_params = (struct dpdmux_cmd_if *)cmd.params; 915 *if_id = le16_to_cpu(rsp_params->if_id); 916 917 return 0; 918 } 919 920 /** 921 * dpdmux_set_custom_key - Set a custom classification key. 922 * 923 * This API is only available for DPDMUX instance created with 924 * DPDMUX_METHOD_CUSTOM. This API must be called before populating the 925 * classification table using dpdmux_add_custom_cls_entry. 926 * 927 * Calls to dpdmux_set_custom_key remove all existing classification entries 928 * that may have been added previously using dpdmux_add_custom_cls_entry. 929 * 930 * @mc_io: Pointer to MC portal's I/O object 931 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 932 * @token: Token of DPSW object 933 * @if_id: Interface id 934 * @key_cfg_iova: DMA address of a configuration structure set up using 935 * dpkg_prepare_key_cfg. Maximum key size is 24 bytes 936 * 937 * @returns '0' on Success; Error code otherwise. 938 */ 939 int dpdmux_set_custom_key(struct fsl_mc_io *mc_io, 940 uint32_t cmd_flags, 941 uint16_t token, 942 uint64_t key_cfg_iova) 943 { 944 struct dpdmux_set_custom_key *cmd_params; 945 struct mc_command cmd = { 0 }; 946 947 /* prepare command */ 948 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_CUSTOM_KEY, 949 cmd_flags, 950 token); 951 cmd_params = (struct dpdmux_set_custom_key *)cmd.params; 952 cmd_params->key_cfg_iova = cpu_to_le64(key_cfg_iova); 953 954 /* send command to mc*/ 955 return mc_send_command(mc_io, &cmd); 956 } 957 958 /** 959 * dpdmux_add_custom_cls_entry - Adds a custom classification entry. 960 * 961 * This API is only available for DPDMUX instances created with 962 * DPDMUX_METHOD_CUSTOM. Before calling this function a classification key 963 * composition rule must be set up using dpdmux_set_custom_key. 964 * 965 * @mc_io: Pointer to MC portal's I/O object 966 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 967 * @token: Token of DPSW object 968 * @rule: Classification rule to insert. Rules cannot be duplicated, if a 969 * matching rule already exists, the action will be replaced. 970 * @action: Action to perform for matching traffic. 971 * 972 * @returns '0' on Success; Error code otherwise. 973 */ 974 int dpdmux_add_custom_cls_entry(struct fsl_mc_io *mc_io, 975 uint32_t cmd_flags, 976 uint16_t token, 977 struct dpdmux_rule_cfg *rule, 978 struct dpdmux_cls_action *action) 979 { 980 struct dpdmux_cmd_add_custom_cls_entry *cmd_params; 981 struct mc_command cmd = { 0 }; 982 983 /* prepare command */ 984 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ADD_CUSTOM_CLS_ENTRY, 985 cmd_flags, 986 token); 987 988 cmd_params = (struct dpdmux_cmd_add_custom_cls_entry *)cmd.params; 989 cmd_params->key_size = rule->key_size; 990 cmd_params->entry_index = rule->entry_index; 991 cmd_params->dest_if = cpu_to_le16(action->dest_if); 992 cmd_params->key_iova = cpu_to_le64(rule->key_iova); 993 cmd_params->mask_iova = cpu_to_le64(rule->mask_iova); 994 995 /* send command to mc*/ 996 return mc_send_command(mc_io, &cmd); 997 } 998 999 /** 1000 * dpdmux_remove_custom_cls_entry - Removes a custom classification entry. 1001 * 1002 * This API is only available for DPDMUX instances created with 1003 * DPDMUX_METHOD_CUSTOM. The API can be used to remove classification 1004 * entries previously inserted using dpdmux_add_custom_cls_entry. 1005 * 1006 * @mc_io: Pointer to MC portal's I/O object 1007 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1008 * @token: Token of DPSW object 1009 * @rule: Classification rule to remove 1010 * 1011 * @returns '0' on Success; Error code otherwise. 1012 */ 1013 int dpdmux_remove_custom_cls_entry(struct fsl_mc_io *mc_io, 1014 uint32_t cmd_flags, 1015 uint16_t token, 1016 struct dpdmux_rule_cfg *rule) 1017 { 1018 struct dpdmux_cmd_remove_custom_cls_entry *cmd_params; 1019 struct mc_command cmd = { 0 }; 1020 1021 /* prepare command */ 1022 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_REMOVE_CUSTOM_CLS_ENTRY, 1023 cmd_flags, 1024 token); 1025 cmd_params = (struct dpdmux_cmd_remove_custom_cls_entry *)cmd.params; 1026 cmd_params->key_size = rule->key_size; 1027 cmd_params->key_iova = cpu_to_le64(rule->key_iova); 1028 cmd_params->mask_iova = cpu_to_le64(rule->mask_iova); 1029 1030 /* send command to mc*/ 1031 return mc_send_command(mc_io, &cmd); 1032 } 1033 1034 /** 1035 * dpdmux_get_api_version() - Get Data Path Demux API version 1036 * @mc_io: Pointer to MC portal's I/O object 1037 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1038 * @major_ver: Major version of data path demux API 1039 * @minor_ver: Minor version of data path demux API 1040 * 1041 * Return: '0' on Success; Error code otherwise. 1042 */ 1043 int dpdmux_get_api_version(struct fsl_mc_io *mc_io, 1044 uint32_t cmd_flags, 1045 uint16_t *major_ver, 1046 uint16_t *minor_ver) 1047 { 1048 struct mc_command cmd = { 0 }; 1049 struct dpdmux_rsp_get_api_version *rsp_params; 1050 int err; 1051 1052 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_API_VERSION, 1053 cmd_flags, 1054 0); 1055 1056 err = mc_send_command(mc_io, &cmd); 1057 if (err) 1058 return err; 1059 1060 rsp_params = (struct dpdmux_rsp_get_api_version *)cmd.params; 1061 *major_ver = le16_to_cpu(rsp_params->major); 1062 *minor_ver = le16_to_cpu(rsp_params->minor); 1063 1064 return 0; 1065 } 1066 1067 /** 1068 * dpdmux_if_set_errors_behavior() - Set errors behavior 1069 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1070 * @token: Token of DPSW object 1071 * @if_id: Interface Identifier 1072 * @cfg: Errors configuration 1073 * 1074 * Provides a set of frame errors that will be rejected or accepted by the 1075 * dpdmux interface. The frame with this errors will no longer be dropped by 1076 * the dpdmux interface. When frame has parsing error the distribution to 1077 * expected interface may fail. If the frame must be distributed using the 1078 * information from a header that was not parsed due errors the frame may 1079 * be discarded or end up on a default interface because needed data was not 1080 * parsed properly. 1081 * This function may be called numerous times with different error masks 1082 * 1083 * Return: '0' on Success; Error code otherwise. 1084 */ 1085 int dpdmux_if_set_errors_behavior(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 1086 uint16_t token, uint16_t if_id, struct dpdmux_error_cfg *cfg) 1087 { 1088 struct mc_command cmd = { 0 }; 1089 struct dpdmux_cmd_set_errors_behavior *cmd_params; 1090 1091 /* prepare command */ 1092 cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_ERRORS_BEHAVIOR, 1093 cmd_flags, 1094 token); 1095 cmd_params = (struct dpdmux_cmd_set_errors_behavior *)cmd.params; 1096 cmd_params->errors = cpu_to_le32(cfg->errors); 1097 dpdmux_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action); 1098 cmd_params->if_id = cpu_to_le16(if_id); 1099 1100 /* send command to mc*/ 1101 return mc_send_command(mc_io, &cmd); 1102 } 1103