1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2013-2016 Freescale Semiconductor Inc. 4 * Copyright 2016-2021 NXP 5 * 6 */ 7 #include <fsl_mc_sys.h> 8 #include <fsl_mc_cmd.h> 9 #include <fsl_dpni.h> 10 #include <fsl_dpni_cmd.h> 11 12 /** 13 * dpni_open() - Open a control session for the specified object 14 * @mc_io: Pointer to MC portal's I/O object 15 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 16 * @dpni_id: DPNI unique ID 17 * @token: Returned token; use in subsequent API calls 18 * 19 * This function can be used to open a control session for an 20 * already created object; an object may have been declared in 21 * the DPL or by calling the dpni_create() function. 22 * This function returns a unique authentication token, 23 * associated with the specific object ID and the specific MC 24 * portal; this token must be used in all subsequent commands for 25 * this specific object. 26 * 27 * Return: '0' on Success; Error code otherwise. 28 */ 29 int dpni_open(struct fsl_mc_io *mc_io, 30 uint32_t cmd_flags, 31 int dpni_id, 32 uint16_t *token) 33 { 34 struct mc_command cmd = { 0 }; 35 struct dpni_cmd_open *cmd_params; 36 37 int err; 38 39 /* prepare command */ 40 cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN, 41 cmd_flags, 42 0); 43 cmd_params = (struct dpni_cmd_open *)cmd.params; 44 cmd_params->dpni_id = cpu_to_le32(dpni_id); 45 46 /* send command to mc*/ 47 err = mc_send_command(mc_io, &cmd); 48 if (err) 49 return err; 50 51 /* retrieve response parameters */ 52 *token = mc_cmd_hdr_read_token(&cmd); 53 54 return 0; 55 } 56 57 /** 58 * dpni_close() - Close the control session of the object 59 * @mc_io: Pointer to MC portal's I/O object 60 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 61 * @token: Token of DPNI object 62 * 63 * After this function is called, no further operations are 64 * allowed on the object without opening a new control session. 65 * 66 * Return: '0' on Success; Error code otherwise. 67 */ 68 int dpni_close(struct fsl_mc_io *mc_io, 69 uint32_t cmd_flags, 70 uint16_t token) 71 { 72 struct mc_command cmd = { 0 }; 73 74 /* prepare command */ 75 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE, 76 cmd_flags, 77 token); 78 79 /* send command to mc*/ 80 return mc_send_command(mc_io, &cmd); 81 } 82 83 /** 84 * dpni_create() - Create the DPNI object 85 * @mc_io: Pointer to MC portal's I/O object 86 * @dprc_token: Parent container token; '0' for default container 87 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 88 * @cfg: Configuration structure 89 * @obj_id: Returned object id 90 * 91 * Create the DPNI object, allocate required resources and 92 * perform required initialization. 93 * 94 * The object can be created either by declaring it in the 95 * DPL file, or by calling this function. 96 * 97 * The function accepts an authentication token of a parent 98 * container that this object should be assigned to. The token 99 * can be '0' so the object will be assigned to the default container. 100 * The newly created object can be opened with the returned 101 * object id and using the container's associated tokens and MC portals. 102 * 103 * Return: '0' on Success; Error code otherwise. 104 */ 105 int dpni_create(struct fsl_mc_io *mc_io, 106 uint16_t dprc_token, 107 uint32_t cmd_flags, 108 const struct dpni_cfg *cfg, 109 uint32_t *obj_id) 110 { 111 struct dpni_cmd_create *cmd_params; 112 struct mc_command cmd = { 0 }; 113 int err; 114 115 /* prepare command */ 116 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE, 117 cmd_flags, 118 dprc_token); 119 cmd_params = (struct dpni_cmd_create *)cmd.params; 120 cmd_params->options = cpu_to_le32(cfg->options); 121 cmd_params->num_queues = cfg->num_queues; 122 cmd_params->num_tcs = cfg->num_tcs; 123 cmd_params->mac_filter_entries = cfg->mac_filter_entries; 124 cmd_params->num_rx_tcs = cfg->num_rx_tcs; 125 cmd_params->vlan_filter_entries = cfg->vlan_filter_entries; 126 cmd_params->qos_entries = cfg->qos_entries; 127 cmd_params->fs_entries = cpu_to_le16(cfg->fs_entries); 128 cmd_params->num_cgs = cfg->num_cgs; 129 cmd_params->num_opr = cfg->num_opr; 130 cmd_params->dist_key_size = cfg->dist_key_size; 131 cmd_params->num_channels = cfg->num_channels; 132 133 /* send command to mc*/ 134 err = mc_send_command(mc_io, &cmd); 135 if (err) 136 return err; 137 138 /* retrieve response parameters */ 139 *obj_id = mc_cmd_read_object_id(&cmd); 140 141 return 0; 142 } 143 144 /** 145 * dpni_destroy() - Destroy the DPNI object and release all its resources. 146 * @mc_io: Pointer to MC portal's I/O object 147 * @dprc_token: Parent container token; '0' for default container 148 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 149 * @object_id: The object id; it must be a valid id within the container that 150 * created this object; 151 * 152 * The function accepts the authentication token of the parent container that 153 * created the object (not the one that currently owns the object). The object 154 * is searched within parent using the provided 'object_id'. 155 * All tokens to the object must be closed before calling destroy. 156 * 157 * Return: '0' on Success; error code otherwise. 158 */ 159 int dpni_destroy(struct fsl_mc_io *mc_io, 160 uint16_t dprc_token, 161 uint32_t cmd_flags, 162 uint32_t object_id) 163 { 164 struct dpni_cmd_destroy *cmd_params; 165 struct mc_command cmd = { 0 }; 166 167 /* prepare command */ 168 cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY, 169 cmd_flags, 170 dprc_token); 171 /* set object id to destroy */ 172 cmd_params = (struct dpni_cmd_destroy *)cmd.params; 173 cmd_params->dpsw_id = cpu_to_le32(object_id); 174 175 /* send command to mc*/ 176 return mc_send_command(mc_io, &cmd); 177 } 178 179 /** 180 * dpni_set_pools() - Set buffer pools configuration 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 DPNI object 184 * @cfg: Buffer pools configuration 185 * 186 * mandatory for DPNI operation 187 * warning:Allowed only when DPNI is disabled 188 * 189 * Return: '0' on Success; Error code otherwise. 190 */ 191 int dpni_set_pools(struct fsl_mc_io *mc_io, 192 uint32_t cmd_flags, 193 uint16_t token, 194 const struct dpni_pools_cfg *cfg) 195 { 196 struct mc_command cmd = { 0 }; 197 struct dpni_cmd_set_pools *cmd_params; 198 int i; 199 200 /* prepare command */ 201 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS, 202 cmd_flags, 203 token); 204 cmd_params = (struct dpni_cmd_set_pools *)cmd.params; 205 cmd_params->num_dpbp = cfg->num_dpbp; 206 cmd_params->pool_options = cfg->pool_options; 207 for (i = 0; i < DPNI_MAX_DPBP; i++) { 208 cmd_params->pool[i].dpbp_id = 209 cpu_to_le16(cfg->pools[i].dpbp_id); 210 cmd_params->pool[i].priority_mask = 211 cfg->pools[i].priority_mask; 212 cmd_params->buffer_size[i] = 213 cpu_to_le16(cfg->pools[i].buffer_size); 214 cmd_params->backup_pool_mask |= 215 DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i); 216 } 217 218 /* send command to mc*/ 219 return mc_send_command(mc_io, &cmd); 220 } 221 222 /** 223 * dpni_enable() - Enable the DPNI, allow sending and receiving frames. 224 * @mc_io: Pointer to MC portal's I/O object 225 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 226 * @token: Token of DPNI object 227 * 228 * Return: '0' on Success; Error code otherwise. 229 */ 230 int dpni_enable(struct fsl_mc_io *mc_io, 231 uint32_t cmd_flags, 232 uint16_t token) 233 { 234 struct mc_command cmd = { 0 }; 235 236 /* prepare command */ 237 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE, 238 cmd_flags, 239 token); 240 241 /* send command to mc*/ 242 return mc_send_command(mc_io, &cmd); 243 } 244 245 /** 246 * dpni_disable() - Disable the DPNI, stop sending and receiving frames. 247 * @mc_io: Pointer to MC portal's I/O object 248 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 249 * @token: Token of DPNI object 250 * 251 * Return: '0' on Success; Error code otherwise. 252 */ 253 int dpni_disable(struct fsl_mc_io *mc_io, 254 uint32_t cmd_flags, 255 uint16_t token) 256 { 257 struct mc_command cmd = { 0 }; 258 259 /* prepare command */ 260 cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE, 261 cmd_flags, 262 token); 263 264 /* send command to mc*/ 265 return mc_send_command(mc_io, &cmd); 266 } 267 268 /** 269 * dpni_is_enabled() - Check if the DPNI is enabled. 270 * @mc_io: Pointer to MC portal's I/O object 271 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 272 * @token: Token of DPNI object 273 * @en: Returns '1' if object is enabled; '0' otherwise 274 * 275 * Return: '0' on Success; Error code otherwise. 276 */ 277 int dpni_is_enabled(struct fsl_mc_io *mc_io, 278 uint32_t cmd_flags, 279 uint16_t token, 280 int *en) 281 { 282 struct mc_command cmd = { 0 }; 283 struct dpni_rsp_is_enabled *rsp_params; 284 int err; 285 286 /* prepare command */ 287 cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, 288 cmd_flags, 289 token); 290 291 /* send command to mc*/ 292 err = mc_send_command(mc_io, &cmd); 293 if (err) 294 return err; 295 296 /* retrieve response parameters */ 297 rsp_params = (struct dpni_rsp_is_enabled *)cmd.params; 298 *en = dpni_get_field(rsp_params->enabled, ENABLE); 299 300 return 0; 301 } 302 303 /** 304 * dpni_reset() - Reset the DPNI, returns the object to initial state. 305 * @mc_io: Pointer to MC portal's I/O object 306 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 307 * @token: Token of DPNI object 308 * 309 * Return: '0' on Success; Error code otherwise. 310 */ 311 int dpni_reset(struct fsl_mc_io *mc_io, 312 uint32_t cmd_flags, 313 uint16_t token) 314 { 315 struct mc_command cmd = { 0 }; 316 317 /* prepare command */ 318 cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET, 319 cmd_flags, 320 token); 321 322 /* send command to mc*/ 323 return mc_send_command(mc_io, &cmd); 324 } 325 326 /** 327 * dpni_set_irq_enable() - Set overall interrupt state. 328 * @mc_io: Pointer to MC portal's I/O object 329 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 330 * @token: Token of DPNI object 331 * @irq_index: The interrupt index to configure 332 * @en: Interrupt state: - enable = 1, disable = 0 333 * 334 * Allows GPP software to control when interrupts are generated. 335 * Each interrupt can have up to 32 causes. The enable/disable control's the 336 * overall interrupt state. if the interrupt is disabled no causes will cause 337 * an interrupt. 338 * 339 * Return: '0' on Success; Error code otherwise. 340 */ 341 int dpni_set_irq_enable(struct fsl_mc_io *mc_io, 342 uint32_t cmd_flags, 343 uint16_t token, 344 uint8_t irq_index, 345 uint8_t en) 346 { 347 struct mc_command cmd = { 0 }; 348 struct dpni_cmd_set_irq_enable *cmd_params; 349 350 /* prepare command */ 351 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_ENABLE, 352 cmd_flags, 353 token); 354 cmd_params = (struct dpni_cmd_set_irq_enable *)cmd.params; 355 dpni_set_field(cmd_params->enable, ENABLE, en); 356 cmd_params->irq_index = irq_index; 357 358 /* send command to mc*/ 359 return mc_send_command(mc_io, &cmd); 360 } 361 362 /** 363 * dpni_get_irq_enable() - Get overall interrupt 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 DPNI object 367 * @irq_index: The interrupt index to configure 368 * @en: Returned interrupt state - enable = 1, disable = 0 369 * 370 * Return: '0' on Success; Error code otherwise. 371 */ 372 int dpni_get_irq_enable(struct fsl_mc_io *mc_io, 373 uint32_t cmd_flags, 374 uint16_t token, 375 uint8_t irq_index, 376 uint8_t *en) 377 { 378 struct mc_command cmd = { 0 }; 379 struct dpni_cmd_get_irq_enable *cmd_params; 380 struct dpni_rsp_get_irq_enable *rsp_params; 381 382 int err; 383 384 /* prepare command */ 385 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_ENABLE, 386 cmd_flags, 387 token); 388 cmd_params = (struct dpni_cmd_get_irq_enable *)cmd.params; 389 cmd_params->irq_index = irq_index; 390 391 /* send command to mc*/ 392 err = mc_send_command(mc_io, &cmd); 393 if (err) 394 return err; 395 396 /* retrieve response parameters */ 397 rsp_params = (struct dpni_rsp_get_irq_enable *)cmd.params; 398 *en = dpni_get_field(rsp_params->enabled, ENABLE); 399 400 return 0; 401 } 402 403 /** 404 * dpni_set_irq_mask() - Set interrupt mask. 405 * @mc_io: Pointer to MC portal's I/O object 406 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 407 * @token: Token of DPNI object 408 * @irq_index: The interrupt index to configure 409 * @mask: Event mask to trigger interrupt; 410 * each bit: 411 * 0 = ignore event 412 * 1 = consider event for asserting IRQ 413 * 414 * Every interrupt can have up to 32 causes and the interrupt model supports 415 * masking/unmasking each cause independently 416 * 417 * Return: '0' on Success; Error code otherwise. 418 */ 419 int dpni_set_irq_mask(struct fsl_mc_io *mc_io, 420 uint32_t cmd_flags, 421 uint16_t token, 422 uint8_t irq_index, 423 uint32_t mask) 424 { 425 struct mc_command cmd = { 0 }; 426 struct dpni_cmd_set_irq_mask *cmd_params; 427 428 /* prepare command */ 429 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_MASK, 430 cmd_flags, 431 token); 432 cmd_params = (struct dpni_cmd_set_irq_mask *)cmd.params; 433 cmd_params->mask = cpu_to_le32(mask); 434 cmd_params->irq_index = irq_index; 435 436 /* send command to mc*/ 437 return mc_send_command(mc_io, &cmd); 438 } 439 440 /** 441 * dpni_get_irq_mask() - Get interrupt mask. 442 * @mc_io: Pointer to MC portal's I/O object 443 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 444 * @token: Token of DPNI object 445 * @irq_index: The interrupt index to configure 446 * @mask: Returned event mask to trigger interrupt 447 * 448 * Every interrupt can have up to 32 causes and the interrupt model supports 449 * masking/unmasking each cause independently 450 * 451 * Return: '0' on Success; Error code otherwise. 452 */ 453 int dpni_get_irq_mask(struct fsl_mc_io *mc_io, 454 uint32_t cmd_flags, 455 uint16_t token, 456 uint8_t irq_index, 457 uint32_t *mask) 458 { 459 struct mc_command cmd = { 0 }; 460 struct dpni_cmd_get_irq_mask *cmd_params; 461 struct dpni_rsp_get_irq_mask *rsp_params; 462 int err; 463 464 /* prepare command */ 465 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_MASK, 466 cmd_flags, 467 token); 468 cmd_params = (struct dpni_cmd_get_irq_mask *)cmd.params; 469 cmd_params->irq_index = irq_index; 470 471 /* send command to mc*/ 472 err = mc_send_command(mc_io, &cmd); 473 if (err) 474 return err; 475 476 /* retrieve response parameters */ 477 rsp_params = (struct dpni_rsp_get_irq_mask *)cmd.params; 478 *mask = le32_to_cpu(rsp_params->mask); 479 480 return 0; 481 } 482 483 /** 484 * dpni_get_irq_status() - Get the current status of any pending interrupts. 485 * @mc_io: Pointer to MC portal's I/O object 486 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 487 * @token: Token of DPNI object 488 * @irq_index: The interrupt index to configure 489 * @status: Returned interrupts status - one bit per cause: 490 * 0 = no interrupt pending 491 * 1 = interrupt pending 492 * 493 * Return: '0' on Success; Error code otherwise. 494 */ 495 int dpni_get_irq_status(struct fsl_mc_io *mc_io, 496 uint32_t cmd_flags, 497 uint16_t token, 498 uint8_t irq_index, 499 uint32_t *status) 500 { 501 struct mc_command cmd = { 0 }; 502 struct dpni_cmd_get_irq_status *cmd_params; 503 struct dpni_rsp_get_irq_status *rsp_params; 504 int err; 505 506 /* prepare command */ 507 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_STATUS, 508 cmd_flags, 509 token); 510 cmd_params = (struct dpni_cmd_get_irq_status *)cmd.params; 511 cmd_params->status = cpu_to_le32(*status); 512 cmd_params->irq_index = irq_index; 513 514 /* send command to mc*/ 515 err = mc_send_command(mc_io, &cmd); 516 if (err) 517 return err; 518 519 /* retrieve response parameters */ 520 rsp_params = (struct dpni_rsp_get_irq_status *)cmd.params; 521 *status = le32_to_cpu(rsp_params->status); 522 523 return 0; 524 } 525 526 /** 527 * dpni_clear_irq_status() - Clear a pending interrupt's status 528 * @mc_io: Pointer to MC portal's I/O object 529 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 530 * @token: Token of DPNI object 531 * @irq_index: The interrupt index to configure 532 * @status: bits to clear (W1C) - one bit per cause: 533 * 0 = don't change 534 * 1 = clear status bit 535 * 536 * Return: '0' on Success; Error code otherwise. 537 */ 538 int dpni_clear_irq_status(struct fsl_mc_io *mc_io, 539 uint32_t cmd_flags, 540 uint16_t token, 541 uint8_t irq_index, 542 uint32_t status) 543 { 544 struct mc_command cmd = { 0 }; 545 struct dpni_cmd_clear_irq_status *cmd_params; 546 547 /* prepare command */ 548 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLEAR_IRQ_STATUS, 549 cmd_flags, 550 token); 551 cmd_params = (struct dpni_cmd_clear_irq_status *)cmd.params; 552 cmd_params->irq_index = irq_index; 553 cmd_params->status = cpu_to_le32(status); 554 555 /* send command to mc*/ 556 return mc_send_command(mc_io, &cmd); 557 } 558 559 /** 560 * dpni_get_attributes() - Retrieve DPNI attributes. 561 * @mc_io: Pointer to MC portal's I/O object 562 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 563 * @token: Token of DPNI object 564 * @attr: Object's attributes 565 * 566 * Return: '0' on Success; Error code otherwise. 567 */ 568 int dpni_get_attributes(struct fsl_mc_io *mc_io, 569 uint32_t cmd_flags, 570 uint16_t token, 571 struct dpni_attr *attr) 572 { 573 struct mc_command cmd = { 0 }; 574 struct dpni_rsp_get_attr *rsp_params; 575 576 int err; 577 578 /* prepare command */ 579 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR, 580 cmd_flags, 581 token); 582 583 /* send command to mc*/ 584 err = mc_send_command(mc_io, &cmd); 585 if (err) 586 return err; 587 588 /* retrieve response parameters */ 589 rsp_params = (struct dpni_rsp_get_attr *)cmd.params; 590 attr->options = le32_to_cpu(rsp_params->options); 591 attr->num_queues = rsp_params->num_queues; 592 attr->num_rx_tcs = rsp_params->num_rx_tcs; 593 attr->num_tx_tcs = rsp_params->num_tx_tcs; 594 attr->mac_filter_entries = rsp_params->mac_filter_entries; 595 attr->vlan_filter_entries = rsp_params->vlan_filter_entries; 596 attr->num_channels = rsp_params->num_channels; 597 attr->qos_entries = rsp_params->qos_entries; 598 attr->fs_entries = le16_to_cpu(rsp_params->fs_entries); 599 attr->qos_key_size = rsp_params->qos_key_size; 600 attr->fs_key_size = rsp_params->fs_key_size; 601 attr->wriop_version = le16_to_cpu(rsp_params->wriop_version); 602 attr->num_cgs = rsp_params->num_cgs; 603 604 return 0; 605 } 606 607 /** 608 * dpni_set_errors_behavior() - Set errors behavior 609 * @mc_io: Pointer to MC portal's I/O object 610 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 611 * @token: Token of DPNI object 612 * @cfg: Errors configuration 613 * 614 * This function may be called numerous times with different 615 * error masks 616 * 617 * Return: '0' on Success; Error code otherwise. 618 */ 619 int dpni_set_errors_behavior(struct fsl_mc_io *mc_io, 620 uint32_t cmd_flags, 621 uint16_t token, 622 struct dpni_error_cfg *cfg) 623 { 624 struct mc_command cmd = { 0 }; 625 struct dpni_cmd_set_errors_behavior *cmd_params; 626 627 /* prepare command */ 628 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR, 629 cmd_flags, 630 token); 631 cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params; 632 cmd_params->errors = cpu_to_le32(cfg->errors); 633 dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action); 634 dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation); 635 636 /* send command to mc*/ 637 return mc_send_command(mc_io, &cmd); 638 } 639 640 /** 641 * dpni_get_buffer_layout() - Retrieve buffer layout attributes. 642 * @mc_io: Pointer to MC portal's I/O object 643 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 644 * @token: Token of DPNI object 645 * @qtype: Type of queue to retrieve configuration for 646 * @layout: Returns buffer layout attributes 647 * 648 * Return: '0' on Success; Error code otherwise. 649 */ 650 int dpni_get_buffer_layout(struct fsl_mc_io *mc_io, 651 uint32_t cmd_flags, 652 uint16_t token, 653 enum dpni_queue_type qtype, 654 struct dpni_buffer_layout *layout) 655 { 656 struct mc_command cmd = { 0 }; 657 struct dpni_cmd_get_buffer_layout *cmd_params; 658 struct dpni_rsp_get_buffer_layout *rsp_params; 659 int err; 660 661 /* prepare command */ 662 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT, 663 cmd_flags, 664 token); 665 cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params; 666 cmd_params->qtype = qtype; 667 668 /* send command to mc*/ 669 err = mc_send_command(mc_io, &cmd); 670 if (err) 671 return err; 672 673 /* retrieve response parameters */ 674 rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params; 675 layout->pass_timestamp = 676 (int)dpni_get_field(rsp_params->flags, PASS_TS); 677 layout->pass_parser_result = 678 (int)dpni_get_field(rsp_params->flags, PASS_PR); 679 layout->pass_frame_status = 680 (int)dpni_get_field(rsp_params->flags, PASS_FS); 681 layout->pass_sw_opaque = 682 (int)dpni_get_field(rsp_params->flags, PASS_SWO); 683 layout->private_data_size = le16_to_cpu(rsp_params->private_data_size); 684 layout->data_align = le16_to_cpu(rsp_params->data_align); 685 layout->data_head_room = le16_to_cpu(rsp_params->head_room); 686 layout->data_tail_room = le16_to_cpu(rsp_params->tail_room); 687 688 return 0; 689 } 690 691 /** 692 * dpni_set_buffer_layout() - Set buffer layout configuration. 693 * @mc_io: Pointer to MC portal's I/O object 694 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 695 * @token: Token of DPNI object 696 * @qtype: Type of queue this configuration applies to 697 * @layout: Buffer layout configuration 698 * 699 * Return: '0' on Success; Error code otherwise. 700 * 701 * @warning Allowed only when DPNI is disabled 702 */ 703 int dpni_set_buffer_layout(struct fsl_mc_io *mc_io, 704 uint32_t cmd_flags, 705 uint16_t token, 706 enum dpni_queue_type qtype, 707 const struct dpni_buffer_layout *layout) 708 { 709 struct mc_command cmd = { 0 }; 710 struct dpni_cmd_set_buffer_layout *cmd_params; 711 712 /* prepare command */ 713 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT, 714 cmd_flags, 715 token); 716 cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params; 717 cmd_params->qtype = qtype; 718 cmd_params->options = cpu_to_le16((uint16_t)layout->options); 719 dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp); 720 dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result); 721 dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status); 722 dpni_set_field(cmd_params->flags, PASS_SWO, layout->pass_sw_opaque); 723 cmd_params->private_data_size = cpu_to_le16(layout->private_data_size); 724 cmd_params->data_align = cpu_to_le16(layout->data_align); 725 cmd_params->head_room = cpu_to_le16(layout->data_head_room); 726 cmd_params->tail_room = cpu_to_le16(layout->data_tail_room); 727 728 /* send command to mc*/ 729 return mc_send_command(mc_io, &cmd); 730 } 731 732 /** 733 * dpni_set_offload() - Set DPNI offload configuration. 734 * @mc_io: Pointer to MC portal's I/O object 735 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 736 * @token: Token of DPNI object 737 * @type: Type of DPNI offload 738 * @config: Offload configuration. 739 * For checksum offloads, non-zero value enables the offload 740 * 741 * Return: '0' on Success; Error code otherwise. 742 * 743 * @warning Allowed only when DPNI is disabled 744 */ 745 746 int dpni_set_offload(struct fsl_mc_io *mc_io, 747 uint32_t cmd_flags, 748 uint16_t token, 749 enum dpni_offload type, 750 uint32_t config) 751 { 752 struct mc_command cmd = { 0 }; 753 struct dpni_cmd_set_offload *cmd_params; 754 755 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD, 756 cmd_flags, 757 token); 758 cmd_params = (struct dpni_cmd_set_offload *)cmd.params; 759 cmd_params->dpni_offload = type; 760 cmd_params->config = cpu_to_le32(config); 761 762 return mc_send_command(mc_io, &cmd); 763 } 764 765 /** 766 * dpni_get_offload() - Get DPNI offload configuration. 767 * @mc_io: Pointer to MC portal's I/O object 768 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 769 * @token: Token of DPNI object 770 * @type: Type of DPNI offload 771 * @config: Offload configuration. 772 * For checksum offloads, a value of 1 indicates that the 773 * offload is enabled. 774 * 775 * Return: '0' on Success; Error code otherwise. 776 * 777 * @warning Allowed only when DPNI is disabled 778 */ 779 int dpni_get_offload(struct fsl_mc_io *mc_io, 780 uint32_t cmd_flags, 781 uint16_t token, 782 enum dpni_offload type, 783 uint32_t *config) 784 { 785 struct mc_command cmd = { 0 }; 786 struct dpni_cmd_get_offload *cmd_params; 787 struct dpni_rsp_get_offload *rsp_params; 788 int err; 789 790 /* prepare command */ 791 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD, 792 cmd_flags, 793 token); 794 cmd_params = (struct dpni_cmd_get_offload *)cmd.params; 795 cmd_params->dpni_offload = type; 796 797 /* send command to mc*/ 798 err = mc_send_command(mc_io, &cmd); 799 if (err) 800 return err; 801 802 /* retrieve response parameters */ 803 rsp_params = (struct dpni_rsp_get_offload *)cmd.params; 804 *config = le32_to_cpu(rsp_params->config); 805 806 return 0; 807 } 808 809 /** 810 * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used 811 * for enqueue operations 812 * @mc_io: Pointer to MC portal's I/O object 813 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 814 * @token: Token of DPNI object 815 * @qtype: Type of queue to receive QDID for 816 * @qdid: Returned virtual QDID value that should be used as an argument 817 * in all enqueue operations 818 * 819 * Return: '0' on Success; Error code otherwise. 820 * 821 * If dpni object is created using multiple Tc channels this function will return 822 * qdid value for the first channel 823 */ 824 int dpni_get_qdid(struct fsl_mc_io *mc_io, 825 uint32_t cmd_flags, 826 uint16_t token, 827 enum dpni_queue_type qtype, 828 uint16_t *qdid) 829 { 830 struct mc_command cmd = { 0 }; 831 struct dpni_cmd_get_qdid *cmd_params; 832 struct dpni_rsp_get_qdid *rsp_params; 833 int err; 834 835 /* prepare command */ 836 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID, 837 cmd_flags, 838 token); 839 cmd_params = (struct dpni_cmd_get_qdid *)cmd.params; 840 cmd_params->qtype = qtype; 841 842 /* send command to mc*/ 843 err = mc_send_command(mc_io, &cmd); 844 if (err) 845 return err; 846 847 /* retrieve response parameters */ 848 rsp_params = (struct dpni_rsp_get_qdid *)cmd.params; 849 *qdid = le16_to_cpu(rsp_params->qdid); 850 851 return 0; 852 } 853 854 /** 855 * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer) 856 * @mc_io: Pointer to MC portal's I/O object 857 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 858 * @token: Token of DPNI object 859 * @data_offset: Tx data offset (from start of buffer) 860 * 861 * Return: '0' on Success; Error code otherwise. 862 */ 863 int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io, 864 uint32_t cmd_flags, 865 uint16_t token, 866 uint16_t *data_offset) 867 { 868 struct mc_command cmd = { 0 }; 869 struct dpni_rsp_get_tx_data_offset *rsp_params; 870 int err; 871 872 /* prepare command */ 873 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET, 874 cmd_flags, 875 token); 876 877 /* send command to mc*/ 878 err = mc_send_command(mc_io, &cmd); 879 if (err) 880 return err; 881 882 /* retrieve response parameters */ 883 rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params; 884 *data_offset = le16_to_cpu(rsp_params->data_offset); 885 886 return 0; 887 } 888 889 /** 890 * dpni_set_link_cfg() - set the link configuration. 891 * @mc_io: Pointer to MC portal's I/O object 892 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 893 * @token: Token of DPNI object 894 * @cfg: Link configuration 895 * 896 * Return: '0' on Success; Error code otherwise. 897 */ 898 int dpni_set_link_cfg(struct fsl_mc_io *mc_io, 899 uint32_t cmd_flags, 900 uint16_t token, 901 const struct dpni_link_cfg *cfg) 902 { 903 struct mc_command cmd = { 0 }; 904 struct dpni_cmd_set_link_cfg *cmd_params; 905 906 /* prepare command */ 907 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG, 908 cmd_flags, 909 token); 910 cmd_params = (struct dpni_cmd_set_link_cfg *)cmd.params; 911 cmd_params->rate = cpu_to_le32(cfg->rate); 912 cmd_params->options = cpu_to_le64(cfg->options); 913 cmd_params->advertising = cpu_to_le64(cfg->advertising); 914 915 /* send command to mc*/ 916 return mc_send_command(mc_io, &cmd); 917 } 918 919 /** 920 * dpni_get_link_cfg() - return the link configuration configured by 921 * dpni_set_link_cfg(). 922 * @mc_io: Pointer to MC portal's I/O object 923 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 924 * @token: Token of DPNI object 925 * @cfg: Link configuration from dpni object 926 * 927 * Return: '0' on Success; Error code otherwise. 928 */ 929 int dpni_get_link_cfg(struct fsl_mc_io *mc_io, 930 uint32_t cmd_flags, 931 uint16_t token, 932 struct dpni_link_cfg *cfg) 933 { 934 struct mc_command cmd = { 0 }; 935 struct dpni_cmd_set_link_cfg *rsp_params; 936 int err; 937 938 /* prepare command */ 939 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG, 940 cmd_flags, 941 token); 942 943 /* send command to mc*/ 944 err = mc_send_command(mc_io, &cmd); 945 if (err) 946 return err; 947 948 /* retrieve response parameters */ 949 rsp_params = (struct dpni_cmd_set_link_cfg *)cmd.params; 950 cfg->advertising = le64_to_cpu(rsp_params->advertising); 951 cfg->options = le64_to_cpu(rsp_params->options); 952 cfg->rate = le32_to_cpu(rsp_params->rate); 953 954 return err; 955 } 956 957 /** 958 * dpni_get_link_state() - Return the link state (either up or down) 959 * @mc_io: Pointer to MC portal's I/O object 960 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 961 * @token: Token of DPNI object 962 * @state: Returned link state; 963 * 964 * Return: '0' on Success; Error code otherwise. 965 */ 966 int dpni_get_link_state(struct fsl_mc_io *mc_io, 967 uint32_t cmd_flags, 968 uint16_t token, 969 struct dpni_link_state *state) 970 { 971 struct mc_command cmd = { 0 }; 972 struct dpni_rsp_get_link_state *rsp_params; 973 int err; 974 975 /* prepare command */ 976 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE, 977 cmd_flags, 978 token); 979 980 /* send command to mc*/ 981 err = mc_send_command(mc_io, &cmd); 982 if (err) 983 return err; 984 985 /* retrieve response parameters */ 986 rsp_params = (struct dpni_rsp_get_link_state *)cmd.params; 987 state->up = dpni_get_field(rsp_params->flags, LINK_STATE); 988 state->state_valid = dpni_get_field(rsp_params->flags, STATE_VALID); 989 state->rate = le32_to_cpu(rsp_params->rate); 990 state->options = le64_to_cpu(rsp_params->options); 991 state->supported = le64_to_cpu(rsp_params->supported); 992 state->advertising = le64_to_cpu(rsp_params->advertising); 993 994 return 0; 995 } 996 997 /** 998 * dpni_set_tx_shaping() - Set the transmit shaping 999 * @mc_io: Pointer to MC portal's I/O object 1000 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1001 * @token: Token of DPNI object 1002 * @tx_cr_shaper: TX committed rate shaping configuration 1003 * @tx_er_shaper: TX excess rate shaping configuration 1004 * @param: Special parameters 1005 * bit0: Committed and excess rates are coupled 1006 * bit1: 1 modify LNI shaper, 0 modify channel shaper 1007 * bit8-15: Tx channel to be shaped. Used only if bit1 is set to zero 1008 * bits16-26: OAL (Overhead accounting length 11bit value). Used only 1009 * when bit1 is set. 1010 * 1011 * Return: '0' on Success; Error code otherwise. 1012 */ 1013 int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, 1014 uint32_t cmd_flags, 1015 uint16_t token, 1016 const struct dpni_tx_shaping_cfg *tx_cr_shaper, 1017 const struct dpni_tx_shaping_cfg *tx_er_shaper, 1018 uint32_t param) 1019 { 1020 struct dpni_cmd_set_tx_shaping *cmd_params; 1021 struct mc_command cmd = { 0 }; 1022 int coupled, lni_shaper; 1023 uint8_t channel_id; 1024 uint16_t oal; 1025 1026 /* prepare command */ 1027 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING, 1028 cmd_flags, 1029 token); 1030 cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params; 1031 cmd_params->tx_cr_max_burst_size = 1032 cpu_to_le16(tx_cr_shaper->max_burst_size); 1033 cmd_params->tx_er_max_burst_size = 1034 cpu_to_le16(tx_er_shaper->max_burst_size); 1035 cmd_params->tx_cr_rate_limit = 1036 cpu_to_le32(tx_cr_shaper->rate_limit); 1037 cmd_params->tx_er_rate_limit = 1038 cpu_to_le32(tx_er_shaper->rate_limit); 1039 1040 coupled = !!(param & 0x01); 1041 dpni_set_field(cmd_params->options, COUPLED, coupled); 1042 1043 lni_shaper = !!((param >> 1) & 0x01); 1044 dpni_set_field(cmd_params->options, LNI_SHAPER, lni_shaper); 1045 1046 channel_id = (param >> 8) & 0xff; 1047 cmd_params->channel_id = channel_id; 1048 1049 oal = (param >> 16) & 0x7FF; 1050 cmd_params->oal = cpu_to_le16(oal); 1051 1052 /* send command to mc*/ 1053 return mc_send_command(mc_io, &cmd); 1054 } 1055 1056 /** 1057 * dpni_set_max_frame_length() - Set the maximum received frame length. 1058 * @mc_io: Pointer to MC portal's I/O object 1059 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1060 * @token: Token of DPNI object 1061 * @max_frame_length: Maximum received frame length (in bytes); 1062 * frame is discarded if its length exceeds this value 1063 * 1064 * Return: '0' on Success; Error code otherwise. 1065 */ 1066 int dpni_set_max_frame_length(struct fsl_mc_io *mc_io, 1067 uint32_t cmd_flags, 1068 uint16_t token, 1069 uint16_t max_frame_length) 1070 { 1071 struct mc_command cmd = { 0 }; 1072 struct dpni_cmd_set_max_frame_length *cmd_params; 1073 1074 /* prepare command */ 1075 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH, 1076 cmd_flags, 1077 token); 1078 cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params; 1079 cmd_params->max_frame_length = cpu_to_le16(max_frame_length); 1080 1081 /* send command to mc*/ 1082 return mc_send_command(mc_io, &cmd); 1083 } 1084 1085 /** 1086 * dpni_get_max_frame_length() - Get the maximum received frame length. 1087 * @mc_io: Pointer to MC portal's I/O object 1088 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1089 * @token: Token of DPNI object 1090 * @max_frame_length: Maximum received frame length (in bytes); 1091 * frame is discarded if its length exceeds this value 1092 * 1093 * Return: '0' on Success; Error code otherwise. 1094 */ 1095 int dpni_get_max_frame_length(struct fsl_mc_io *mc_io, 1096 uint32_t cmd_flags, 1097 uint16_t token, 1098 uint16_t *max_frame_length) 1099 { 1100 struct mc_command cmd = { 0 }; 1101 struct dpni_rsp_get_max_frame_length *rsp_params; 1102 int err; 1103 1104 /* prepare command */ 1105 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH, 1106 cmd_flags, 1107 token); 1108 1109 /* send command to mc*/ 1110 err = mc_send_command(mc_io, &cmd); 1111 if (err) 1112 return err; 1113 1114 /* retrieve response parameters */ 1115 rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params; 1116 *max_frame_length = le16_to_cpu(rsp_params->max_frame_length); 1117 1118 return 0; 1119 } 1120 1121 /** 1122 * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode 1123 * @mc_io: Pointer to MC portal's I/O object 1124 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1125 * @token: Token of DPNI object 1126 * @en: Set to '1' to enable; '0' to disable 1127 * 1128 * Return: '0' on Success; Error code otherwise. 1129 */ 1130 int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io, 1131 uint32_t cmd_flags, 1132 uint16_t token, 1133 int en) 1134 { 1135 struct mc_command cmd = { 0 }; 1136 struct dpni_cmd_set_multicast_promisc *cmd_params; 1137 1138 /* prepare command */ 1139 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC, 1140 cmd_flags, 1141 token); 1142 cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params; 1143 dpni_set_field(cmd_params->enable, ENABLE, en); 1144 1145 /* send command to mc*/ 1146 return mc_send_command(mc_io, &cmd); 1147 } 1148 1149 /** 1150 * dpni_get_multicast_promisc() - Get multicast promiscuous mode 1151 * @mc_io: Pointer to MC portal's I/O object 1152 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1153 * @token: Token of DPNI object 1154 * @en: Returns '1' if enabled; '0' otherwise 1155 * 1156 * Return: '0' on Success; Error code otherwise. 1157 */ 1158 int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io, 1159 uint32_t cmd_flags, 1160 uint16_t token, 1161 int *en) 1162 { 1163 struct mc_command cmd = { 0 }; 1164 struct dpni_rsp_get_multicast_promisc *rsp_params; 1165 int err; 1166 1167 /* prepare command */ 1168 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC, 1169 cmd_flags, 1170 token); 1171 1172 /* send command to mc*/ 1173 err = mc_send_command(mc_io, &cmd); 1174 if (err) 1175 return err; 1176 1177 /* retrieve response parameters */ 1178 rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params; 1179 *en = dpni_get_field(rsp_params->enabled, ENABLE); 1180 1181 return 0; 1182 } 1183 1184 /** 1185 * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode 1186 * @mc_io: Pointer to MC portal's I/O object 1187 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1188 * @token: Token of DPNI object 1189 * @en: Set to '1' to enable; '0' to disable 1190 * 1191 * Return: '0' on Success; Error code otherwise. 1192 */ 1193 int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io, 1194 uint32_t cmd_flags, 1195 uint16_t token, 1196 int en) 1197 { 1198 struct mc_command cmd = { 0 }; 1199 struct dpni_cmd_set_unicast_promisc *cmd_params; 1200 1201 /* prepare command */ 1202 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC, 1203 cmd_flags, 1204 token); 1205 cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params; 1206 dpni_set_field(cmd_params->enable, ENABLE, en); 1207 1208 /* send command to mc*/ 1209 return mc_send_command(mc_io, &cmd); 1210 } 1211 1212 /** 1213 * dpni_get_unicast_promisc() - Get unicast promiscuous mode 1214 * @mc_io: Pointer to MC portal's I/O object 1215 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1216 * @token: Token of DPNI object 1217 * @en: Returns '1' if enabled; '0' otherwise 1218 * 1219 * Return: '0' on Success; Error code otherwise. 1220 */ 1221 int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io, 1222 uint32_t cmd_flags, 1223 uint16_t token, 1224 int *en) 1225 { 1226 struct mc_command cmd = { 0 }; 1227 struct dpni_rsp_get_unicast_promisc *rsp_params; 1228 int err; 1229 1230 /* prepare command */ 1231 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC, 1232 cmd_flags, 1233 token); 1234 1235 /* send command to mc*/ 1236 err = mc_send_command(mc_io, &cmd); 1237 if (err) 1238 return err; 1239 1240 /* retrieve response parameters */ 1241 rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params; 1242 *en = dpni_get_field(rsp_params->enabled, ENABLE); 1243 1244 return 0; 1245 } 1246 1247 /** 1248 * dpni_set_primary_mac_addr() - Set the primary MAC address 1249 * @mc_io: Pointer to MC portal's I/O object 1250 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1251 * @token: Token of DPNI object 1252 * @mac_addr: MAC address to set as primary address 1253 * 1254 * Return: '0' on Success; Error code otherwise. 1255 */ 1256 int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, 1257 uint32_t cmd_flags, 1258 uint16_t token, 1259 const uint8_t mac_addr[6]) 1260 { 1261 struct mc_command cmd = { 0 }; 1262 struct dpni_cmd_set_primary_mac_addr *cmd_params; 1263 int i; 1264 1265 /* prepare command */ 1266 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC, 1267 cmd_flags, 1268 token); 1269 cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params; 1270 for (i = 0; i < 6; i++) 1271 cmd_params->mac_addr[i] = mac_addr[5 - i]; 1272 1273 /* send command to mc*/ 1274 return mc_send_command(mc_io, &cmd); 1275 } 1276 1277 /** 1278 * dpni_get_primary_mac_addr() - Get the primary MAC address 1279 * @mc_io: Pointer to MC portal's I/O object 1280 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1281 * @token: Token of DPNI object 1282 * @mac_addr: Returned MAC address 1283 * 1284 * Return: '0' on Success; Error code otherwise. 1285 */ 1286 int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io, 1287 uint32_t cmd_flags, 1288 uint16_t token, 1289 uint8_t mac_addr[6]) 1290 { 1291 struct mc_command cmd = { 0 }; 1292 struct dpni_rsp_get_primary_mac_addr *rsp_params; 1293 int i, err; 1294 1295 /* prepare command */ 1296 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC, 1297 cmd_flags, 1298 token); 1299 1300 /* send command to mc*/ 1301 err = mc_send_command(mc_io, &cmd); 1302 if (err) 1303 return err; 1304 1305 /* retrieve response parameters */ 1306 rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params; 1307 for (i = 0; i < 6; i++) 1308 mac_addr[5 - i] = rsp_params->mac_addr[i]; 1309 1310 return 0; 1311 } 1312 1313 /** 1314 * dpni_add_mac_addr() - Add MAC address filter 1315 * @mc_io: Pointer to MC portal's I/O object 1316 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1317 * @token: Token of DPNI object 1318 * @mac_addr: MAC address to add 1319 * @flags : 0 - tc_id and flow_id will be ignored. 1320 * Pkt with this mac_id will be passed to the next 1321 * classification stages 1322 * DPNI_MAC_SET_QUEUE_ACTION 1323 * Pkt with this mac will be forward directly to 1324 * queue defined by the tc_id and flow_id 1325 * @tc_id : Traffic class selection (0-7) 1326 * @flow_id : Selects the specific queue out of the set allocated for the 1327 * same as tc_id. Value must be in range 0 to NUM_QUEUES - 1 1328 * Return: '0' on Success; Error code otherwise. 1329 */ 1330 int dpni_add_mac_addr(struct fsl_mc_io *mc_io, 1331 uint32_t cmd_flags, 1332 uint16_t token, 1333 const uint8_t mac_addr[6], 1334 uint8_t flags, 1335 uint8_t tc_id, 1336 uint8_t flow_id) 1337 { 1338 struct mc_command cmd = { 0 }; 1339 struct dpni_cmd_add_mac_addr *cmd_params; 1340 int i; 1341 1342 /* prepare command */ 1343 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR, 1344 cmd_flags, 1345 token); 1346 cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params; 1347 cmd_params->flags = flags; 1348 cmd_params->tc_id = tc_id; 1349 cmd_params->fq_id = flow_id; 1350 1351 for (i = 0; i < 6; i++) 1352 cmd_params->mac_addr[i] = mac_addr[5 - i]; 1353 1354 /* send command to mc*/ 1355 return mc_send_command(mc_io, &cmd); 1356 } 1357 1358 /** 1359 * dpni_remove_mac_addr() - Remove MAC address filter 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 DPNI object 1363 * @mac_addr: MAC address to remove 1364 * 1365 * Return: '0' on Success; Error code otherwise. 1366 */ 1367 int dpni_remove_mac_addr(struct fsl_mc_io *mc_io, 1368 uint32_t cmd_flags, 1369 uint16_t token, 1370 const uint8_t mac_addr[6]) 1371 { 1372 struct mc_command cmd = { 0 }; 1373 struct dpni_cmd_remove_mac_addr *cmd_params; 1374 int i; 1375 1376 /* prepare command */ 1377 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR, 1378 cmd_flags, 1379 token); 1380 cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params; 1381 for (i = 0; i < 6; i++) 1382 cmd_params->mac_addr[i] = mac_addr[5 - i]; 1383 1384 /* send command to mc*/ 1385 return mc_send_command(mc_io, &cmd); 1386 } 1387 1388 /** 1389 * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters 1390 * @mc_io: Pointer to MC portal's I/O object 1391 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1392 * @token: Token of DPNI object 1393 * @unicast: Set to '1' to clear unicast addresses 1394 * @multicast: Set to '1' to clear multicast addresses 1395 * 1396 * The primary MAC address is not cleared by this operation. 1397 * 1398 * Return: '0' on Success; Error code otherwise. 1399 */ 1400 int dpni_clear_mac_filters(struct fsl_mc_io *mc_io, 1401 uint32_t cmd_flags, 1402 uint16_t token, 1403 int unicast, 1404 int multicast) 1405 { 1406 struct mc_command cmd = { 0 }; 1407 struct dpni_cmd_clear_mac_filters *cmd_params; 1408 1409 /* prepare command */ 1410 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS, 1411 cmd_flags, 1412 token); 1413 cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params; 1414 dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast); 1415 dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast); 1416 1417 /* send command to mc*/ 1418 return mc_send_command(mc_io, &cmd); 1419 } 1420 1421 /** 1422 * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical 1423 * port the DPNI is attached to 1424 * @mc_io: Pointer to MC portal's I/O object 1425 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1426 * @token: Token of DPNI object 1427 * @mac_addr: MAC address of the physical port, if any, otherwise 0 1428 * 1429 * The primary MAC address is not cleared by this operation. 1430 * 1431 * Return: '0' on Success; Error code otherwise. 1432 */ 1433 int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io, 1434 uint32_t cmd_flags, 1435 uint16_t token, 1436 uint8_t mac_addr[6]) 1437 { 1438 struct mc_command cmd = { 0 }; 1439 struct dpni_rsp_get_port_mac_addr *rsp_params; 1440 int i, err; 1441 1442 /* prepare command */ 1443 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR, 1444 cmd_flags, 1445 token); 1446 1447 /* send command to mc*/ 1448 err = mc_send_command(mc_io, &cmd); 1449 if (err) 1450 return err; 1451 1452 /* retrieve response parameters */ 1453 rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params; 1454 for (i = 0; i < 6; i++) 1455 mac_addr[5 - i] = rsp_params->mac_addr[i]; 1456 1457 return 0; 1458 } 1459 1460 /** 1461 * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode 1462 * @mc_io: Pointer to MC portal's I/O object 1463 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1464 * @token: Token of DPNI object 1465 * @en: Set to '1' to enable; '0' to disable 1466 * 1467 * Return: '0' on Success; Error code otherwise. 1468 */ 1469 int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io, 1470 uint32_t cmd_flags, 1471 uint16_t token, 1472 int en) 1473 { 1474 struct dpni_cmd_enable_vlan_filter *cmd_params; 1475 struct mc_command cmd = { 0 }; 1476 1477 /* prepare command */ 1478 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER, 1479 cmd_flags, 1480 token); 1481 cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params; 1482 dpni_set_field(cmd_params->en, ENABLE, en); 1483 1484 /* send command to mc*/ 1485 return mc_send_command(mc_io, &cmd); 1486 } 1487 1488 /** 1489 * dpni_add_vlan_id() - Add VLAN ID filter 1490 * @mc_io: Pointer to MC portal's I/O object 1491 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1492 * @token: Token of DPNI object 1493 * @vlan_id: VLAN ID to add 1494 * @flags: 0 - tc_id and flow_id will be ignored. 1495 * Pkt with this vlan_id will be passed to the next 1496 * classification stages 1497 * DPNI_VLAN_SET_QUEUE_ACTION 1498 * Pkt with this vlan_id will be forward directly to 1499 * queue defined by the tc_id and flow_id 1500 * 1501 * @tc_id: Traffic class selection (0-7) 1502 * @flow_id: Selects the specific queue out of the set allocated for the 1503 * same as tc_id. Value must be in range 0 to NUM_QUEUES - 1 1504 * 1505 * Return: '0' on Success; Error code otherwise. 1506 */ 1507 int dpni_add_vlan_id(struct fsl_mc_io *mc_io, 1508 uint32_t cmd_flags, 1509 uint16_t token, 1510 uint16_t vlan_id, 1511 uint8_t flags, 1512 uint8_t tc_id, 1513 uint8_t flow_id) 1514 { 1515 struct dpni_cmd_vlan_id *cmd_params; 1516 struct mc_command cmd = { 0 }; 1517 1518 /* prepare command */ 1519 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID, 1520 cmd_flags, 1521 token); 1522 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params; 1523 cmd_params->flags = flags; 1524 cmd_params->tc_id = tc_id; 1525 cmd_params->flow_id = flow_id; 1526 cmd_params->vlan_id = cpu_to_le16(vlan_id); 1527 1528 /* send command to mc*/ 1529 return mc_send_command(mc_io, &cmd); 1530 } 1531 1532 /** 1533 * dpni_remove_vlan_id() - Remove VLAN ID filter 1534 * @mc_io: Pointer to MC portal's I/O object 1535 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1536 * @token: Token of DPNI object 1537 * @vlan_id: VLAN ID to remove 1538 * 1539 * Return: '0' on Success; Error code otherwise. 1540 */ 1541 int dpni_remove_vlan_id(struct fsl_mc_io *mc_io, 1542 uint32_t cmd_flags, 1543 uint16_t token, 1544 uint16_t vlan_id) 1545 { 1546 struct dpni_cmd_vlan_id *cmd_params; 1547 struct mc_command cmd = { 0 }; 1548 1549 /* prepare command */ 1550 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID, 1551 cmd_flags, 1552 token); 1553 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params; 1554 cmd_params->vlan_id = cpu_to_le16(vlan_id); 1555 1556 /* send command to mc*/ 1557 return mc_send_command(mc_io, &cmd); 1558 } 1559 1560 /** 1561 * dpni_clear_vlan_filters() - Clear all VLAN filters 1562 * @mc_io: Pointer to MC portal's I/O object 1563 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1564 * @token: Token of DPNI object 1565 * 1566 * Return: '0' on Success; Error code otherwise. 1567 */ 1568 int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io, 1569 uint32_t cmd_flags, 1570 uint16_t token) 1571 { 1572 struct mc_command cmd = { 0 }; 1573 1574 /* prepare command */ 1575 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_VLAN_FILTERS, 1576 cmd_flags, 1577 token); 1578 1579 /* send command to mc*/ 1580 return mc_send_command(mc_io, &cmd); 1581 } 1582 1583 /** 1584 * dpni_set_tx_priorities() - Set transmission TC priority configuration 1585 * @mc_io: Pointer to MC portal's I/O object 1586 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1587 * @token: Token of DPNI object 1588 * @cfg: Transmission selection configuration 1589 * 1590 * warning: Allowed only when DPNI is disabled 1591 * 1592 * Return: '0' on Success; Error code otherwise. 1593 */ 1594 int dpni_set_tx_priorities(struct fsl_mc_io *mc_io, 1595 uint32_t cmd_flags, 1596 uint16_t token, 1597 const struct dpni_tx_priorities_cfg *cfg) 1598 { 1599 struct dpni_cmd_set_tx_priorities *cmd_params; 1600 struct mc_command cmd = { 0 }; 1601 int i; 1602 1603 /* prepare command */ 1604 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_PRIORITIES, 1605 cmd_flags, 1606 token); 1607 cmd_params = (struct dpni_cmd_set_tx_priorities *)cmd.params; 1608 cmd_params->channel_idx = cfg->channel_idx; 1609 dpni_set_field(cmd_params->flags, 1610 SEPARATE_GRP, 1611 cfg->separate_groups); 1612 cmd_params->prio_group_A = cfg->prio_group_A; 1613 cmd_params->prio_group_B = cfg->prio_group_B; 1614 1615 for (i = 0; i + 1 < DPNI_MAX_TC; i = i + 2) { 1616 dpni_set_field(cmd_params->modes[i / 2], 1617 MODE_1, 1618 cfg->tc_sched[i].mode); 1619 dpni_set_field(cmd_params->modes[i / 2], 1620 MODE_2, 1621 cfg->tc_sched[i + 1].mode); 1622 } 1623 1624 for (i = 0; i < DPNI_MAX_TC; i++) { 1625 cmd_params->delta_bandwidth[i] = 1626 cpu_to_le16(cfg->tc_sched[i].delta_bandwidth); 1627 } 1628 1629 /* send command to mc*/ 1630 return mc_send_command(mc_io, &cmd); 1631 } 1632 1633 /** 1634 * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration 1635 * @mc_io: Pointer to MC portal's I/O object 1636 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1637 * @token: Token of DPNI object 1638 * @tc_id: Traffic class selection (0-7) 1639 * @cfg: Traffic class distribution configuration 1640 * 1641 * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpkg_prepare_key_cfg() 1642 * first to prepare the key_cfg_iova parameter 1643 * 1644 * Return: '0' on Success; error code otherwise. 1645 */ 1646 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io, 1647 uint32_t cmd_flags, 1648 uint16_t token, 1649 uint8_t tc_id, 1650 const struct dpni_rx_tc_dist_cfg *cfg) 1651 { 1652 struct mc_command cmd = { 0 }; 1653 struct dpni_cmd_set_rx_tc_dist *cmd_params; 1654 1655 /* prepare command */ 1656 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST, 1657 cmd_flags, 1658 token); 1659 cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params; 1660 cmd_params->dist_size = cpu_to_le16(cfg->dist_size); 1661 cmd_params->tc_id = tc_id; 1662 cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id); 1663 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); 1664 dpni_set_field(cmd_params->flags, 1665 DIST_MODE, 1666 cfg->dist_mode); 1667 dpni_set_field(cmd_params->flags, 1668 MISS_ACTION, 1669 cfg->fs_cfg.miss_action); 1670 dpni_set_field(cmd_params->keep_hash_key, 1671 KEEP_HASH_KEY, 1672 cfg->fs_cfg.keep_hash_key); 1673 dpni_set_field(cmd_params->keep_hash_key, 1674 KEEP_ENTRIES, 1675 cfg->fs_cfg.keep_entries); 1676 1677 /* send command to mc*/ 1678 return mc_send_command(mc_io, &cmd); 1679 } 1680 1681 /** 1682 * dpni_set_tx_confirmation_mode() - Tx confirmation mode 1683 * @mc_io: Pointer to MC portal's I/O object 1684 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1685 * @token: Token of DPNI object 1686 * @mode: Tx confirmation mode 1687 * 1688 * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not 1689 * selected at DPNI creation. 1690 * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all 1691 * transmit confirmation (including the private confirmation queues), regardless 1692 * of previous settings; Note that in this case, Tx error frames are still 1693 * enqueued to the general transmit errors queue. 1694 * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all 1695 * Tx confirmations to a shared Tx conf queue. 'index' field in dpni_get_queue 1696 * command will be ignored. 1697 * 1698 * Return: '0' on Success; Error code otherwise. 1699 */ 1700 int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io, 1701 uint32_t cmd_flags, 1702 uint16_t token, 1703 enum dpni_confirmation_mode mode) 1704 { 1705 struct dpni_tx_confirmation_mode *cmd_params; 1706 struct mc_command cmd = { 0 }; 1707 1708 /* prepare command */ 1709 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE, 1710 cmd_flags, 1711 token); 1712 cmd_params = (struct dpni_tx_confirmation_mode *)cmd.params; 1713 cmd_params->confirmation_mode = mode; 1714 1715 /* send command to mc*/ 1716 return mc_send_command(mc_io, &cmd); 1717 } 1718 1719 /** 1720 * dpni_get_tx_confirmation_mode() - Get Tx confirmation mode 1721 * @mc_io: Pointer to MC portal's I/O object 1722 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1723 * @token: Token of DPNI object 1724 * @mode: Tx confirmation mode 1725 * 1726 * Return: '0' on Success; Error code otherwise. 1727 */ 1728 int dpni_get_tx_confirmation_mode(struct fsl_mc_io *mc_io, 1729 uint32_t cmd_flags, 1730 uint16_t token, 1731 enum dpni_confirmation_mode *mode) 1732 { 1733 struct dpni_tx_confirmation_mode *rsp_params; 1734 struct mc_command cmd = { 0 }; 1735 int err; 1736 1737 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONFIRMATION_MODE, 1738 cmd_flags, 1739 token); 1740 1741 err = mc_send_command(mc_io, &cmd); 1742 if (err) 1743 return err; 1744 1745 rsp_params = (struct dpni_tx_confirmation_mode *)cmd.params; 1746 *mode = rsp_params->confirmation_mode; 1747 1748 return 0; 1749 } 1750 1751 /** 1752 * dpni_set_qos_table() - Set QoS mapping table 1753 * @mc_io: Pointer to MC portal's I/O object 1754 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1755 * @token: Token of DPNI object 1756 * @cfg: QoS table configuration 1757 * 1758 * This function and all QoS-related functions require that 1759 *'max_tcs > 1' was set at DPNI creation. 1760 * 1761 * warning: Before calling this function, call dpkg_prepare_key_cfg() to 1762 * prepare the key_cfg_iova parameter 1763 * 1764 * Return: '0' on Success; Error code otherwise. 1765 */ 1766 int dpni_set_qos_table(struct fsl_mc_io *mc_io, 1767 uint32_t cmd_flags, 1768 uint16_t token, 1769 const struct dpni_qos_tbl_cfg *cfg) 1770 { 1771 struct dpni_cmd_set_qos_table *cmd_params; 1772 struct mc_command cmd = { 0 }; 1773 1774 /* prepare command */ 1775 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL, 1776 cmd_flags, 1777 token); 1778 cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params; 1779 cmd_params->default_tc = cfg->default_tc; 1780 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); 1781 dpni_set_field(cmd_params->discard_on_miss, 1782 ENABLE, 1783 cfg->discard_on_miss); 1784 dpni_set_field(cmd_params->discard_on_miss, 1785 KEEP_QOS_ENTRIES, 1786 cfg->keep_entries); 1787 1788 /* send command to mc*/ 1789 return mc_send_command(mc_io, &cmd); 1790 } 1791 1792 /** 1793 * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class) 1794 * @mc_io: Pointer to MC portal's I/O object 1795 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1796 * @token: Token of DPNI object 1797 * @cfg: QoS rule to add 1798 * @tc_id: Traffic class selection (0-7) 1799 * @index: Location in the QoS table where to insert the entry. 1800 * Only relevant if MASKING is enabled for QoS classification on 1801 * this DPNI, it is ignored for exact match. 1802 * 1803 * Return: '0' on Success; Error code otherwise. 1804 */ 1805 int dpni_add_qos_entry(struct fsl_mc_io *mc_io, 1806 uint32_t cmd_flags, 1807 uint16_t token, 1808 const struct dpni_rule_cfg *cfg, 1809 uint8_t tc_id, 1810 uint16_t index, 1811 uint8_t flags, 1812 uint8_t flow_id) 1813 { 1814 struct dpni_cmd_add_qos_entry *cmd_params; 1815 struct mc_command cmd = { 0 }; 1816 1817 /* prepare command */ 1818 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT, 1819 cmd_flags, 1820 token); 1821 cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params; 1822 cmd_params->flags = flags; 1823 cmd_params->flow_id = flow_id; 1824 cmd_params->tc_id = tc_id; 1825 cmd_params->key_size = cfg->key_size; 1826 cmd_params->index = cpu_to_le16(index); 1827 cmd_params->key_iova = cpu_to_le64(cfg->key_iova); 1828 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); 1829 1830 /* send command to mc*/ 1831 return mc_send_command(mc_io, &cmd); 1832 } 1833 1834 /** 1835 * dpni_remove_qos_entry() - Remove QoS mapping entry 1836 * @mc_io: Pointer to MC portal's I/O object 1837 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1838 * @token: Token of DPNI object 1839 * @cfg: QoS rule to remove 1840 * 1841 * Return: '0' on Success; Error code otherwise. 1842 */ 1843 int dpni_remove_qos_entry(struct fsl_mc_io *mc_io, 1844 uint32_t cmd_flags, 1845 uint16_t token, 1846 const struct dpni_rule_cfg *cfg) 1847 { 1848 struct dpni_cmd_remove_qos_entry *cmd_params; 1849 struct mc_command cmd = { 0 }; 1850 1851 /* prepare command */ 1852 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT, 1853 cmd_flags, 1854 token); 1855 cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params; 1856 cmd_params->key_size = cfg->key_size; 1857 cmd_params->key_iova = cpu_to_le64(cfg->key_iova); 1858 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); 1859 1860 /* send command to mc*/ 1861 return mc_send_command(mc_io, &cmd); 1862 } 1863 1864 /** 1865 * dpni_clear_qos_table() - Clear all QoS mapping entries 1866 * @mc_io: Pointer to MC portal's I/O object 1867 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1868 * @token: Token of DPNI object 1869 * 1870 * Following this function call, all frames are directed to 1871 * the default traffic class (0) 1872 * 1873 * Return: '0' on Success; Error code otherwise. 1874 */ 1875 int dpni_clear_qos_table(struct fsl_mc_io *mc_io, 1876 uint32_t cmd_flags, 1877 uint16_t token) 1878 { 1879 struct mc_command cmd = { 0 }; 1880 1881 /* prepare command */ 1882 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL, 1883 cmd_flags, 1884 token); 1885 1886 /* send command to mc*/ 1887 return mc_send_command(mc_io, &cmd); 1888 } 1889 1890 /** 1891 * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class 1892 * (to select a flow ID) 1893 * @mc_io: Pointer to MC portal's I/O object 1894 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1895 * @token: Token of DPNI object 1896 * @tc_id: Traffic class selection (0-7) 1897 * @index: Location in the QoS table where to insert the entry. 1898 * Only relevant if MASKING is enabled for QoS classification 1899 * on this DPNI, it is ignored for exact match. 1900 * @cfg: Flow steering rule to add 1901 * @action: Action to be taken as result of a classification hit 1902 * 1903 * Return: '0' on Success; Error code otherwise. 1904 */ 1905 int dpni_add_fs_entry(struct fsl_mc_io *mc_io, 1906 uint32_t cmd_flags, 1907 uint16_t token, 1908 uint8_t tc_id, 1909 uint16_t index, 1910 const struct dpni_rule_cfg *cfg, 1911 const struct dpni_fs_action_cfg *action) 1912 { 1913 struct dpni_cmd_add_fs_entry *cmd_params; 1914 struct mc_command cmd = { 0 }; 1915 1916 /* prepare command */ 1917 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT, 1918 cmd_flags, 1919 token); 1920 cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params; 1921 cmd_params->tc_id = tc_id; 1922 cmd_params->key_size = cfg->key_size; 1923 cmd_params->index = cpu_to_le16(index); 1924 cmd_params->key_iova = cpu_to_le64(cfg->key_iova); 1925 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); 1926 cmd_params->options = cpu_to_le16(action->options); 1927 cmd_params->flow_id = cpu_to_le16(action->flow_id); 1928 cmd_params->flc = cpu_to_le64(action->flc); 1929 cmd_params->redir_token = cpu_to_le16(action->redirect_obj_token); 1930 1931 /* send command to mc*/ 1932 return mc_send_command(mc_io, &cmd); 1933 } 1934 1935 /** 1936 * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific 1937 * traffic class 1938 * @mc_io: Pointer to MC portal's I/O object 1939 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1940 * @token: Token of DPNI object 1941 * @tc_id: Traffic class selection (0-7) 1942 * @cfg: Flow steering rule to remove 1943 * 1944 * Return: '0' on Success; Error code otherwise. 1945 */ 1946 int dpni_remove_fs_entry(struct fsl_mc_io *mc_io, 1947 uint32_t cmd_flags, 1948 uint16_t token, 1949 uint8_t tc_id, 1950 const struct dpni_rule_cfg *cfg) 1951 { 1952 struct dpni_cmd_remove_fs_entry *cmd_params; 1953 struct mc_command cmd = { 0 }; 1954 1955 /* prepare command */ 1956 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT, 1957 cmd_flags, 1958 token); 1959 cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params; 1960 cmd_params->tc_id = tc_id; 1961 cmd_params->key_size = cfg->key_size; 1962 cmd_params->key_iova = cpu_to_le64(cfg->key_iova); 1963 cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); 1964 1965 /* send command to mc*/ 1966 return mc_send_command(mc_io, &cmd); 1967 } 1968 1969 /** 1970 * dpni_clear_fs_entries() - Clear all Flow Steering entries of a specific 1971 * traffic class 1972 * @mc_io: Pointer to MC portal's I/O object 1973 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1974 * @token: Token of DPNI object 1975 * @tc_id: Traffic class selection (0-7) 1976 * 1977 * Return: '0' on Success; Error code otherwise. 1978 */ 1979 int dpni_clear_fs_entries(struct fsl_mc_io *mc_io, 1980 uint32_t cmd_flags, 1981 uint16_t token, 1982 uint8_t tc_id) 1983 { 1984 struct dpni_cmd_clear_fs_entries *cmd_params; 1985 struct mc_command cmd = { 0 }; 1986 1987 /* prepare command */ 1988 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_FS_ENT, 1989 cmd_flags, 1990 token); 1991 cmd_params = (struct dpni_cmd_clear_fs_entries *)cmd.params; 1992 cmd_params->tc_id = tc_id; 1993 1994 /* send command to mc*/ 1995 return mc_send_command(mc_io, &cmd); 1996 } 1997 1998 /** 1999 * dpni_set_rx_tc_policing() - Set Rx traffic class policing configuration 2000 * @mc_io: Pointer to MC portal's I/O object 2001 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2002 * @token: Token of DPNI object 2003 * @tc_id: Traffic class selection (0-7) 2004 * @cfg: Traffic class policing configuration 2005 * 2006 * Return: '0' on Success; error code otherwise. 2007 */ 2008 int dpni_set_rx_tc_policing(struct fsl_mc_io *mc_io, 2009 uint32_t cmd_flags, 2010 uint16_t token, 2011 uint8_t tc_id, 2012 const struct dpni_rx_tc_policing_cfg *cfg) 2013 { 2014 struct dpni_cmd_set_rx_tc_policing *cmd_params; 2015 struct mc_command cmd = { 0 }; 2016 2017 /* prepare command */ 2018 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_POLICING, 2019 cmd_flags, 2020 token); 2021 cmd_params = (struct dpni_cmd_set_rx_tc_policing *)cmd.params; 2022 dpni_set_field(cmd_params->mode_color, COLOR, cfg->default_color); 2023 dpni_set_field(cmd_params->mode_color, MODE, cfg->mode); 2024 dpni_set_field(cmd_params->units, UNITS, cfg->units); 2025 cmd_params->options = cpu_to_le32(cfg->options); 2026 cmd_params->cir = cpu_to_le32(cfg->cir); 2027 cmd_params->cbs = cpu_to_le32(cfg->cbs); 2028 cmd_params->eir = cpu_to_le32(cfg->eir); 2029 cmd_params->ebs = cpu_to_le32(cfg->ebs); 2030 cmd_params->tc_id = tc_id; 2031 2032 /* send command to mc*/ 2033 return mc_send_command(mc_io, &cmd); 2034 } 2035 2036 /** 2037 * dpni_get_rx_tc_policing() - Get Rx traffic class policing configuration 2038 * @mc_io: Pointer to MC portal's I/O object 2039 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2040 * @token: Token of DPNI object 2041 * @tc_id: Traffic class selection (0-7) 2042 * @cfg: Traffic class policing configuration 2043 * 2044 * Return: '0' on Success; error code otherwise. 2045 */ 2046 int dpni_get_rx_tc_policing(struct fsl_mc_io *mc_io, 2047 uint32_t cmd_flags, 2048 uint16_t token, 2049 uint8_t tc_id, 2050 struct dpni_rx_tc_policing_cfg *cfg) 2051 { 2052 struct dpni_rsp_get_rx_tc_policing *rsp_params; 2053 struct dpni_cmd_get_rx_tc_policing *cmd_params; 2054 struct mc_command cmd = { 0 }; 2055 int err; 2056 2057 /* prepare command */ 2058 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_TC_POLICING, 2059 cmd_flags, 2060 token); 2061 cmd_params = (struct dpni_cmd_get_rx_tc_policing *)cmd.params; 2062 cmd_params->tc_id = tc_id; 2063 2064 2065 /* send command to mc*/ 2066 err = mc_send_command(mc_io, &cmd); 2067 if (err) 2068 return err; 2069 2070 rsp_params = (struct dpni_rsp_get_rx_tc_policing *)cmd.params; 2071 cfg->options = le32_to_cpu(rsp_params->options); 2072 cfg->cir = le32_to_cpu(rsp_params->cir); 2073 cfg->cbs = le32_to_cpu(rsp_params->cbs); 2074 cfg->eir = le32_to_cpu(rsp_params->eir); 2075 cfg->ebs = le32_to_cpu(rsp_params->ebs); 2076 cfg->units = dpni_get_field(rsp_params->units, UNITS); 2077 cfg->mode = dpni_get_field(rsp_params->mode_color, MODE); 2078 cfg->default_color = dpni_get_field(rsp_params->mode_color, COLOR); 2079 2080 return 0; 2081 } 2082 2083 /** 2084 * dpni_prepare_early_drop() - prepare an early drop. 2085 * @cfg: Early-drop configuration 2086 * @early_drop_buf: Zeroed 256 bytes of memory before mapping it to DMA 2087 * 2088 * This function has to be called before dpni_set_rx_tc_early_drop or 2089 * dpni_set_tx_tc_early_drop 2090 * 2091 */ 2092 void dpni_prepare_early_drop(const struct dpni_early_drop_cfg *cfg, 2093 uint8_t *early_drop_buf) 2094 { 2095 struct dpni_early_drop *ext_params; 2096 2097 ext_params = (struct dpni_early_drop *)early_drop_buf; 2098 2099 dpni_set_field(ext_params->flags, DROP_ENABLE, cfg->enable); 2100 dpni_set_field(ext_params->flags, DROP_UNITS, cfg->units); 2101 ext_params->green_drop_probability = cfg->green.drop_probability; 2102 ext_params->green_max_threshold = cpu_to_le64(cfg->green.max_threshold); 2103 ext_params->green_min_threshold = cpu_to_le64(cfg->green.min_threshold); 2104 ext_params->yellow_drop_probability = cfg->yellow.drop_probability; 2105 ext_params->yellow_max_threshold = 2106 cpu_to_le64(cfg->yellow.max_threshold); 2107 ext_params->yellow_min_threshold = 2108 cpu_to_le64(cfg->yellow.min_threshold); 2109 ext_params->red_drop_probability = cfg->red.drop_probability; 2110 ext_params->red_max_threshold = cpu_to_le64(cfg->red.max_threshold); 2111 ext_params->red_min_threshold = cpu_to_le64(cfg->red.min_threshold); 2112 } 2113 2114 /** 2115 * dpni_extract_early_drop() - extract the early drop configuration. 2116 * @cfg: Early-drop configuration 2117 * @early_drop_buf: Zeroed 256 bytes of memory before mapping it to DMA 2118 * 2119 * This function has to be called after dpni_get_rx_tc_early_drop or 2120 * dpni_get_tx_tc_early_drop 2121 * 2122 */ 2123 void dpni_extract_early_drop(struct dpni_early_drop_cfg *cfg, 2124 const uint8_t *early_drop_buf) 2125 { 2126 const struct dpni_early_drop *ext_params; 2127 2128 ext_params = (const struct dpni_early_drop *)early_drop_buf; 2129 2130 cfg->enable = dpni_get_field(ext_params->flags, DROP_ENABLE); 2131 cfg->units = dpni_get_field(ext_params->flags, DROP_UNITS); 2132 cfg->green.drop_probability = ext_params->green_drop_probability; 2133 cfg->green.max_threshold = le64_to_cpu(ext_params->green_max_threshold); 2134 cfg->green.min_threshold = le64_to_cpu(ext_params->green_min_threshold); 2135 cfg->yellow.drop_probability = ext_params->yellow_drop_probability; 2136 cfg->yellow.max_threshold = 2137 le64_to_cpu(ext_params->yellow_max_threshold); 2138 cfg->yellow.min_threshold = 2139 le64_to_cpu(ext_params->yellow_min_threshold); 2140 cfg->red.drop_probability = ext_params->red_drop_probability; 2141 cfg->red.max_threshold = le64_to_cpu(ext_params->red_max_threshold); 2142 cfg->red.min_threshold = le64_to_cpu(ext_params->red_min_threshold); 2143 } 2144 2145 /** 2146 * dpni_set_early_drop() - Set traffic class early-drop configuration 2147 * @mc_io: Pointer to MC portal's I/O object 2148 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2149 * @token: Token of DPNI object 2150 * @qtype: Type of queue - only Rx and Tx types are supported 2151 * @param: Traffic class and channel ID. 2152 * MSB - channel id; used only for DPNI_QUEUE_TX and DPNI_QUEUE_TX_CONFIRM, 2153 * ignored for the rest 2154 * LSB - traffic class 2155 * Use macro DPNI_BUILD_PARAM() to build correct value. 2156 * If dpni uses a single channel (uses only channel zero) the parameter can receive 2157 * traffic class directly. 2158 * @early_drop_iova: I/O virtual address of 256 bytes DMA-able memory filled 2159 * with the early-drop configuration by calling dpni_prepare_early_drop() 2160 * 2161 * warning: Before calling this function, call dpni_prepare_early_drop() to 2162 * prepare the early_drop_iova parameter 2163 * 2164 * Return: '0' on Success; error code otherwise. 2165 */ 2166 int dpni_set_early_drop(struct fsl_mc_io *mc_io, 2167 uint32_t cmd_flags, 2168 uint16_t token, 2169 enum dpni_queue_type qtype, 2170 uint16_t param, 2171 uint64_t early_drop_iova) 2172 { 2173 struct dpni_cmd_early_drop *cmd_params; 2174 struct mc_command cmd = { 0 }; 2175 2176 /* prepare command */ 2177 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_EARLY_DROP, 2178 cmd_flags, 2179 token); 2180 cmd_params = (struct dpni_cmd_early_drop *)cmd.params; 2181 cmd_params->qtype = qtype; 2182 cmd_params->tc = (uint8_t)(param & 0xff); 2183 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2184 cmd_params->early_drop_iova = cpu_to_le64(early_drop_iova); 2185 2186 /* send command to mc*/ 2187 return mc_send_command(mc_io, &cmd); 2188 } 2189 2190 /** 2191 * dpni_get_early_drop() - Get Rx traffic class early-drop configuration 2192 * @mc_io: Pointer to MC portal's I/O object 2193 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2194 * @token: Token of DPNI object 2195 * @qtype: Type of queue - only Rx and Tx types are supported 2196 * @param: Traffic class and channel ID. 2197 * MSB - channel id; used only for DPNI_QUEUE_TX and DPNI_QUEUE_TX_CONFIRM, 2198 * ignored for the rest 2199 * LSB - traffic class 2200 * Use macro DPNI_BUILD_PARAM() to build correct value. 2201 * If dpni uses a single channel (uses only channel zero) the parameter can receive 2202 * traffic class directly. 2203 * @early_drop_iova: I/O virtual address of 256 bytes DMA-able memory 2204 * 2205 * warning: After calling this function, call dpni_extract_early_drop() to 2206 * get the early drop configuration 2207 * 2208 * Return: '0' on Success; error code otherwise. 2209 */ 2210 int dpni_get_early_drop(struct fsl_mc_io *mc_io, 2211 uint32_t cmd_flags, 2212 uint16_t token, 2213 enum dpni_queue_type qtype, 2214 uint16_t param, 2215 uint64_t early_drop_iova) 2216 { 2217 struct dpni_cmd_early_drop *cmd_params; 2218 struct mc_command cmd = { 0 }; 2219 2220 /* prepare command */ 2221 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_EARLY_DROP, 2222 cmd_flags, 2223 token); 2224 cmd_params = (struct dpni_cmd_early_drop *)cmd.params; 2225 cmd_params->qtype = qtype; 2226 cmd_params->tc = (uint8_t)(param & 0xff); 2227 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2228 cmd_params->early_drop_iova = cpu_to_le64(early_drop_iova); 2229 2230 /* send command to mc*/ 2231 return mc_send_command(mc_io, &cmd); 2232 } 2233 2234 /** 2235 * dpni_set_congestion_notification() - Set traffic class congestion 2236 * notification configuration 2237 * @mc_io: Pointer to MC portal's I/O object 2238 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2239 * @token: Token of DPNI object 2240 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported 2241 * @tc_id: Traffic class selection (0-7) 2242 * @cfg: congestion notification configuration 2243 * 2244 * Return: '0' on Success; error code otherwise. 2245 */ 2246 int dpni_set_congestion_notification(struct fsl_mc_io *mc_io, 2247 uint32_t cmd_flags, 2248 uint16_t token, 2249 enum dpni_queue_type qtype, 2250 uint16_t param, 2251 const struct dpni_congestion_notification_cfg *cfg) 2252 { 2253 struct dpni_cmd_set_congestion_notification *cmd_params; 2254 struct mc_command cmd = { 0 }; 2255 2256 /* prepare command */ 2257 cmd.header = mc_encode_cmd_header( 2258 DPNI_CMDID_SET_CONGESTION_NOTIFICATION, 2259 cmd_flags, 2260 token); 2261 cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params; 2262 cmd_params->qtype = qtype; 2263 cmd_params->tc = (uint8_t)(param & 0xff); 2264 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2265 cmd_params->congestion_point = cfg->cg_point; 2266 cmd_params->cgid = (uint8_t)cfg->cgid; 2267 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); 2268 cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode); 2269 cmd_params->dest_priority = cfg->dest_cfg.priority; 2270 cmd_params->message_iova = cpu_to_le64(cfg->message_iova); 2271 cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx); 2272 cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry); 2273 cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit); 2274 dpni_set_field(cmd_params->type_units, 2275 DEST_TYPE, 2276 cfg->dest_cfg.dest_type); 2277 dpni_set_field(cmd_params->type_units, 2278 CONG_UNITS, 2279 cfg->units); 2280 2281 /* send command to mc*/ 2282 return mc_send_command(mc_io, &cmd); 2283 } 2284 2285 /** 2286 * dpni_get_congestion_notification() - Get traffic class congestion 2287 * notification configuration 2288 * @mc_io: Pointer to MC portal's I/O object 2289 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2290 * @token: Token of DPNI object 2291 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported 2292 * @param: Traffic class and channel. Bits[0-7] contain traaffic class, 2293 * byte[8-15] contains channel id 2294 * @cfg: congestion notification configuration 2295 * 2296 * Return: '0' on Success; error code otherwise. 2297 */ 2298 int dpni_get_congestion_notification(struct fsl_mc_io *mc_io, 2299 uint32_t cmd_flags, 2300 uint16_t token, 2301 enum dpni_queue_type qtype, 2302 uint16_t param, 2303 struct dpni_congestion_notification_cfg *cfg) 2304 { 2305 struct dpni_rsp_get_congestion_notification *rsp_params; 2306 struct dpni_cmd_get_congestion_notification *cmd_params; 2307 struct mc_command cmd = { 0 }; 2308 int err; 2309 2310 /* prepare command */ 2311 cmd.header = mc_encode_cmd_header( 2312 DPNI_CMDID_GET_CONGESTION_NOTIFICATION, 2313 cmd_flags, 2314 token); 2315 cmd_params = (struct dpni_cmd_get_congestion_notification *)cmd.params; 2316 cmd_params->qtype = qtype; 2317 cmd_params->tc = (uint8_t)(param & 0xff); 2318 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2319 cmd_params->congestion_point = cfg->cg_point; 2320 cmd_params->cgid = cfg->cgid; 2321 2322 /* send command to mc*/ 2323 err = mc_send_command(mc_io, &cmd); 2324 if (err) 2325 return err; 2326 2327 rsp_params = (struct dpni_rsp_get_congestion_notification *)cmd.params; 2328 cfg->units = dpni_get_field(rsp_params->type_units, CONG_UNITS); 2329 cfg->threshold_entry = le32_to_cpu(rsp_params->threshold_entry); 2330 cfg->threshold_exit = le32_to_cpu(rsp_params->threshold_exit); 2331 cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx); 2332 cfg->message_iova = le64_to_cpu(rsp_params->message_iova); 2333 cfg->notification_mode = le16_to_cpu(rsp_params->notification_mode); 2334 cfg->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id); 2335 cfg->dest_cfg.priority = rsp_params->dest_priority; 2336 cfg->dest_cfg.dest_type = dpni_get_field(rsp_params->type_units, 2337 DEST_TYPE); 2338 2339 return 0; 2340 } 2341 2342 /** 2343 * dpni_get_api_version() - Get Data Path Network Interface API version 2344 * @mc_io: Pointer to MC portal's I/O object 2345 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2346 * @major_ver: Major version of data path network interface API 2347 * @minor_ver: Minor version of data path network interface API 2348 * 2349 * Return: '0' on Success; Error code otherwise. 2350 */ 2351 int dpni_get_api_version(struct fsl_mc_io *mc_io, 2352 uint32_t cmd_flags, 2353 uint16_t *major_ver, 2354 uint16_t *minor_ver) 2355 { 2356 struct dpni_rsp_get_api_version *rsp_params; 2357 struct mc_command cmd = { 0 }; 2358 int err; 2359 2360 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION, 2361 cmd_flags, 2362 0); 2363 2364 err = mc_send_command(mc_io, &cmd); 2365 if (err) 2366 return err; 2367 2368 rsp_params = (struct dpni_rsp_get_api_version *)cmd.params; 2369 *major_ver = le16_to_cpu(rsp_params->major); 2370 *minor_ver = le16_to_cpu(rsp_params->minor); 2371 2372 return 0; 2373 } 2374 2375 /** 2376 * dpni_set_queue() - Set queue parameters 2377 * @mc_io: Pointer to MC portal's I/O object 2378 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2379 * @token: Token of DPNI object 2380 * @qtype: Type of queue - all queue types are supported, although 2381 * the command is ignored for Tx 2382 * @tc: Traffic class, in range 0 to NUM_TCS - 1 2383 * @index: Selects the specific queue out of the set allocated for the 2384 * same TC. Value must be in range 0 to NUM_QUEUES - 1 2385 * @options: A combination of DPNI_QUEUE_OPT_ values that control what 2386 * configuration options are set on the queue 2387 * @queue: Queue structure 2388 * 2389 * Return: '0' on Success; Error code otherwise. 2390 */ 2391 int dpni_set_queue(struct fsl_mc_io *mc_io, 2392 uint32_t cmd_flags, 2393 uint16_t token, 2394 enum dpni_queue_type qtype, 2395 uint16_t param, 2396 uint8_t index, 2397 uint8_t options, 2398 const struct dpni_queue *queue) 2399 { 2400 struct mc_command cmd = { 0 }; 2401 struct dpni_cmd_set_queue *cmd_params; 2402 2403 /* prepare command */ 2404 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE, 2405 cmd_flags, 2406 token); 2407 cmd_params = (struct dpni_cmd_set_queue *)cmd.params; 2408 cmd_params->qtype = qtype; 2409 cmd_params->tc = (uint8_t)(param & 0xff); 2410 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2411 cmd_params->index = index; 2412 cmd_params->options = options; 2413 cmd_params->dest_id = cpu_to_le32(queue->destination.id); 2414 cmd_params->dest_prio = queue->destination.priority; 2415 dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type); 2416 dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control); 2417 dpni_set_field(cmd_params->flags, HOLD_ACTIVE, 2418 queue->destination.hold_active); 2419 cmd_params->flc = cpu_to_le64(queue->flc.value); 2420 cmd_params->user_context = cpu_to_le64(queue->user_context); 2421 cmd_params->cgid = queue->cgid; 2422 2423 /* send command to mc */ 2424 return mc_send_command(mc_io, &cmd); 2425 } 2426 2427 /** 2428 * dpni_get_queue() - Get queue parameters 2429 * @mc_io: Pointer to MC portal's I/O object 2430 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2431 * @token: Token of DPNI object 2432 * @qtype: Type of queue - all queue types are supported 2433 * @param: Traffic class and channel ID. 2434 * MSB - channel id; used only for DPNI_QUEUE_TX and DPNI_QUEUE_TX_CONFIRM, 2435 * ignored for the rest 2436 * LSB - traffic class 2437 * Use macro DPNI_BUILD_PARAM() to build correct value. 2438 * If dpni uses a single channel (uses only channel zero) the parameter can receive 2439 * traffic class directly. 2440 * @index: Selects the specific queue out of the set allocated for the 2441 * same TC. Value must be in range 0 to NUM_QUEUES - 1 2442 * @queue: Queue configuration structure 2443 * @qid: Queue identification 2444 * 2445 * Return: '0' on Success; Error code otherwise. 2446 */ 2447 int dpni_get_queue(struct fsl_mc_io *mc_io, 2448 uint32_t cmd_flags, 2449 uint16_t token, 2450 enum dpni_queue_type qtype, 2451 uint16_t param, 2452 uint8_t index, 2453 struct dpni_queue *queue, 2454 struct dpni_queue_id *qid) 2455 { 2456 struct mc_command cmd = { 0 }; 2457 struct dpni_cmd_get_queue *cmd_params; 2458 struct dpni_rsp_get_queue *rsp_params; 2459 int err; 2460 2461 /* prepare command */ 2462 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE, 2463 cmd_flags, 2464 token); 2465 cmd_params = (struct dpni_cmd_get_queue *)cmd.params; 2466 cmd_params->qtype = qtype; 2467 cmd_params->tc = (uint8_t)(param & 0xff); 2468 cmd_params->index = index; 2469 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2470 2471 /* send command to mc */ 2472 err = mc_send_command(mc_io, &cmd); 2473 if (err) 2474 return err; 2475 2476 /* retrieve response parameters */ 2477 rsp_params = (struct dpni_rsp_get_queue *)cmd.params; 2478 queue->destination.id = le32_to_cpu(rsp_params->dest_id); 2479 queue->destination.priority = rsp_params->dest_prio; 2480 queue->destination.type = dpni_get_field(rsp_params->flags, 2481 DEST_TYPE); 2482 queue->flc.stash_control = dpni_get_field(rsp_params->flags, 2483 STASH_CTRL); 2484 queue->destination.hold_active = dpni_get_field(rsp_params->flags, 2485 HOLD_ACTIVE); 2486 queue->flc.value = le64_to_cpu(rsp_params->flc); 2487 queue->user_context = le64_to_cpu(rsp_params->user_context); 2488 qid->fqid = le32_to_cpu(rsp_params->fqid); 2489 qid->qdbin = le16_to_cpu(rsp_params->qdbin); 2490 if (dpni_get_field(rsp_params->flags, CGID_VALID)) 2491 queue->cgid = rsp_params->cgid; 2492 else 2493 queue->cgid = -1; 2494 2495 return 0; 2496 } 2497 2498 /** 2499 * dpni_get_statistics() - Get DPNI statistics 2500 * @mc_io: Pointer to MC portal's I/O object 2501 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2502 * @token: Token of DPNI object 2503 * @page: Selects the statistics page to retrieve, see 2504 * DPNI_GET_STATISTICS output. Pages are numbered 0 to 6. 2505 * @param: Custom parameter for some pages used to select 2506 * a certain statistic source, for example the TC. 2507 * - page_0: not used 2508 * - page_1: not used 2509 * - page_2: not used 2510 * - page_3: high_byte - channel_id, low_byte - traffic class 2511 * - page_4: high_byte - queue_index have meaning only if dpni is 2512 * created using option DPNI_OPT_CUSTOM_CG, low_byte - traffic class 2513 * - page_5: not used 2514 * - page_6: not used 2515 * @stat: Structure containing the statistics 2516 * 2517 * Return: '0' on Success; Error code otherwise. 2518 */ 2519 int dpni_get_statistics(struct fsl_mc_io *mc_io, 2520 uint32_t cmd_flags, 2521 uint16_t token, 2522 uint8_t page, 2523 uint16_t param, 2524 union dpni_statistics *stat) 2525 { 2526 struct mc_command cmd = { 0 }; 2527 struct dpni_cmd_get_statistics *cmd_params; 2528 struct dpni_rsp_get_statistics *rsp_params; 2529 int i, err; 2530 2531 /* prepare command */ 2532 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS, 2533 cmd_flags, 2534 token); 2535 cmd_params = (struct dpni_cmd_get_statistics *)cmd.params; 2536 cmd_params->page_number = page; 2537 cmd_params->param = param; 2538 2539 /* send command to mc */ 2540 err = mc_send_command(mc_io, &cmd); 2541 if (err) 2542 return err; 2543 2544 /* retrieve response parameters */ 2545 rsp_params = (struct dpni_rsp_get_statistics *)cmd.params; 2546 for (i = 0; i < DPNI_STATISTICS_CNT; i++) 2547 stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]); 2548 2549 return 0; 2550 } 2551 2552 /** 2553 * dpni_reset_statistics() - Clears DPNI statistics 2554 * @mc_io: Pointer to MC portal's I/O object 2555 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2556 * @token: Token of DPNI object 2557 * 2558 * Return: '0' on Success; Error code otherwise. 2559 */ 2560 int dpni_reset_statistics(struct fsl_mc_io *mc_io, 2561 uint32_t cmd_flags, 2562 uint16_t token) 2563 { 2564 struct mc_command cmd = { 0 }; 2565 2566 /* prepare command */ 2567 cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS, 2568 cmd_flags, 2569 token); 2570 2571 /* send command to mc*/ 2572 return mc_send_command(mc_io, &cmd); 2573 } 2574 2575 /** 2576 * dpni_set_taildrop() - Set taildrop per congestion group 2577 * 2578 * Setting a per-TC taildrop (cg_point = DPNI_CP_GROUP) will reset any current 2579 * congestion notification or early drop (WRED) configuration previously applied 2580 * to the same TC. 2581 * 2582 * @mc_io: Pointer to MC portal's I/O object 2583 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2584 * @token: Token of DPNI object 2585 * @cg_point: Congestion group identifier DPNI_CP_QUEUE is only supported in 2586 * combination with DPNI_QUEUE_RX. 2587 * @q_type: Queue type, can be DPNI_QUEUE_RX or DPNI_QUEUE_TX. 2588 * @tc: Traffic class to apply this taildrop to 2589 * @index/cgid: Index of the queue if the DPNI supports multiple queues for 2590 * traffic distribution. 2591 * If CONGESTION_POINT is DPNI_CP_CONGESTION_GROUP then it 2592 * represent the cgid of the congestion point 2593 * @taildrop: Taildrop structure 2594 * 2595 * Return: '0' on Success; Error code otherwise. 2596 */ 2597 int dpni_set_taildrop(struct fsl_mc_io *mc_io, 2598 uint32_t cmd_flags, 2599 uint16_t token, 2600 enum dpni_congestion_point cg_point, 2601 enum dpni_queue_type qtype, 2602 uint16_t param, 2603 uint8_t index, 2604 struct dpni_taildrop *taildrop) 2605 { 2606 struct mc_command cmd = { 0 }; 2607 struct dpni_cmd_set_taildrop *cmd_params; 2608 2609 /* prepare command */ 2610 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP, 2611 cmd_flags, 2612 token); 2613 cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params; 2614 cmd_params->congestion_point = cg_point; 2615 cmd_params->qtype = qtype; 2616 cmd_params->tc = (uint8_t)(param & 0xff); 2617 cmd_params->channel_id = (uint8_t)((param >> 8) & 0xff); 2618 cmd_params->index = index; 2619 cmd_params->units = taildrop->units; 2620 cmd_params->threshold = cpu_to_le32(taildrop->threshold); 2621 dpni_set_field(cmd_params->enable_oal_lo, ENABLE, taildrop->enable); 2622 dpni_set_field(cmd_params->enable_oal_lo, OAL_LO, taildrop->oal); 2623 dpni_set_field(cmd_params->oal_hi, 2624 OAL_HI, 2625 taildrop->oal >> DPNI_OAL_LO_SIZE); 2626 2627 /* send command to mc */ 2628 return mc_send_command(mc_io, &cmd); 2629 } 2630 2631 /** 2632 * dpni_get_taildrop() - Get taildrop information 2633 * @mc_io: Pointer to MC portal's I/O object 2634 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2635 * @token: Token of DPNI object 2636 * @cg_point: Congestion point 2637 * @q_type: Queue type on which the taildrop is configured. 2638 * Only Rx queues are supported for now 2639 * @tc: Traffic class to apply this taildrop to 2640 * @q_index: Index of the queue if the DPNI supports multiple queues for 2641 * traffic distribution. Ignored if CONGESTION_POINT is not 0. 2642 * @taildrop: Taildrop structure 2643 * 2644 * Return: '0' on Success; Error code otherwise. 2645 */ 2646 int dpni_get_taildrop(struct fsl_mc_io *mc_io, 2647 uint32_t cmd_flags, 2648 uint16_t token, 2649 enum dpni_congestion_point cg_point, 2650 enum dpni_queue_type qtype, 2651 uint8_t tc, 2652 uint8_t index, 2653 struct dpni_taildrop *taildrop) 2654 { 2655 struct mc_command cmd = { 0 }; 2656 struct dpni_cmd_get_taildrop *cmd_params; 2657 struct dpni_rsp_get_taildrop *rsp_params; 2658 uint8_t oal_lo, oal_hi; 2659 int err; 2660 2661 /* prepare command */ 2662 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP, 2663 cmd_flags, 2664 token); 2665 cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params; 2666 cmd_params->congestion_point = cg_point; 2667 cmd_params->qtype = qtype; 2668 cmd_params->tc = tc; 2669 cmd_params->index = index; 2670 2671 /* send command to mc */ 2672 err = mc_send_command(mc_io, &cmd); 2673 if (err) 2674 return err; 2675 2676 /* retrieve response parameters */ 2677 rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params; 2678 taildrop->enable = dpni_get_field(rsp_params->enable_oal_lo, ENABLE); 2679 taildrop->units = rsp_params->units; 2680 taildrop->threshold = le32_to_cpu(rsp_params->threshold); 2681 oal_lo = dpni_get_field(rsp_params->enable_oal_lo, OAL_LO); 2682 oal_hi = dpni_get_field(rsp_params->oal_hi, OAL_HI); 2683 taildrop->oal = oal_hi << DPNI_OAL_LO_SIZE | oal_lo; 2684 2685 /* Fill the first 4 bits, 'oal' is a 2's complement value of 12 bits */ 2686 if (taildrop->oal >= 0x0800) 2687 taildrop->oal |= 0xF000; 2688 2689 return 0; 2690 } 2691 2692 /** 2693 * dpni_set_opr() - Set Order Restoration configuration. 2694 * @mc_io: Pointer to MC portal's I/O object 2695 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2696 * @token: Token of DPNI object 2697 * @tc: Traffic class, in range 0 to NUM_TCS - 1 2698 * @index: Selects the specific queue out of the set allocated 2699 * for the same TC. Value must be in range 0 to 2700 * NUM_QUEUES - 1 2701 * @options: Configuration mode options 2702 * can be OPR_OPT_CREATE or OPR_OPT_RETIRE 2703 * @cfg: Configuration options for the OPR 2704 * 2705 * Return: '0' on Success; Error code otherwise. 2706 */ 2707 int dpni_set_opr(struct fsl_mc_io *mc_io, 2708 uint32_t cmd_flags, 2709 uint16_t token, 2710 uint8_t tc, 2711 uint8_t index, 2712 uint8_t options, 2713 struct opr_cfg *cfg, 2714 uint8_t opr_id) 2715 { 2716 struct dpni_cmd_set_opr *cmd_params; 2717 struct mc_command cmd = { 0 }; 2718 2719 /* prepare command */ 2720 cmd.header = mc_encode_cmd_header( 2721 DPNI_CMDID_SET_OPR, 2722 cmd_flags, 2723 token); 2724 cmd_params = (struct dpni_cmd_set_opr *)cmd.params; 2725 cmd_params->tc_id = tc; 2726 cmd_params->index = index; 2727 cmd_params->options = options; 2728 cmd_params->opr_id = opr_id; 2729 cmd_params->oloe = cfg->oloe; 2730 cmd_params->oeane = cfg->oeane; 2731 cmd_params->olws = cfg->olws; 2732 cmd_params->oa = cfg->oa; 2733 cmd_params->oprrws = cfg->oprrws; 2734 2735 /* send command to mc*/ 2736 return mc_send_command(mc_io, &cmd); 2737 } 2738 2739 /** 2740 * dpni_get_opr() - Retrieve Order Restoration config and query. 2741 * @mc_io: Pointer to MC portal's I/O object 2742 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2743 * @token: Token of DPNI object 2744 * @tc: Traffic class, in range 0 to NUM_TCS - 1 2745 * @index: Selects the specific queue out of the set allocated 2746 * for the same TC. Value must be in range 0 to 2747 * NUM_QUEUES - 1 2748 * @cfg: Returned OPR configuration 2749 * @qry: Returned OPR query 2750 * 2751 * Return: '0' on Success; Error code otherwise. 2752 */ 2753 int dpni_get_opr(struct fsl_mc_io *mc_io, 2754 uint32_t cmd_flags, 2755 uint16_t token, 2756 uint8_t tc, 2757 uint8_t index, 2758 struct opr_cfg *cfg, 2759 struct opr_qry *qry, 2760 uint8_t flags, 2761 uint8_t opr_id) 2762 { 2763 struct dpni_rsp_get_opr *rsp_params; 2764 struct dpni_cmd_get_opr *cmd_params; 2765 struct mc_command cmd = { 0 }; 2766 int err; 2767 2768 /* prepare command */ 2769 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OPR, 2770 cmd_flags, 2771 token); 2772 cmd_params = (struct dpni_cmd_get_opr *)cmd.params; 2773 cmd_params->index = index; 2774 cmd_params->tc_id = tc; 2775 cmd_params->flags = flags; 2776 cmd_params->opr_id = opr_id; 2777 2778 /* send command to mc*/ 2779 err = mc_send_command(mc_io, &cmd); 2780 if (err) 2781 return err; 2782 2783 /* retrieve response parameters */ 2784 rsp_params = (struct dpni_rsp_get_opr *)cmd.params; 2785 cfg->oloe = rsp_params->oloe; 2786 cfg->oeane = rsp_params->oeane; 2787 cfg->olws = rsp_params->olws; 2788 cfg->oa = rsp_params->oa; 2789 cfg->oprrws = rsp_params->oprrws; 2790 qry->rip = dpni_get_field(rsp_params->flags, RIP); 2791 qry->enable = dpni_get_field(rsp_params->flags, OPR_ENABLE); 2792 qry->nesn = le16_to_cpu(rsp_params->nesn); 2793 qry->ndsn = le16_to_cpu(rsp_params->ndsn); 2794 qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq); 2795 qry->tseq_nlis = dpni_get_field(rsp_params->tseq_nlis, TSEQ_NLIS); 2796 qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq); 2797 qry->hseq_nlis = dpni_get_field(rsp_params->hseq_nlis, HSEQ_NLIS); 2798 qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr); 2799 qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr); 2800 qry->opr_vid = le16_to_cpu(rsp_params->opr_vid); 2801 qry->opr_id = le16_to_cpu(rsp_params->opr_id); 2802 2803 return 0; 2804 } 2805 2806 int dpni_load_sw_sequence(struct fsl_mc_io *mc_io, 2807 uint32_t cmd_flags, 2808 uint16_t token, 2809 struct dpni_load_ss_cfg *cfg) 2810 { 2811 struct dpni_load_sw_sequence *cmd_params; 2812 struct mc_command cmd = { 0 }; 2813 2814 /* prepare command */ 2815 cmd.header = mc_encode_cmd_header(DPNI_CMDID_LOAD_SW_SEQUENCE, 2816 cmd_flags, 2817 token); 2818 cmd_params = (struct dpni_load_sw_sequence *)cmd.params; 2819 cmd_params->dest = cfg->dest; 2820 cmd_params->ss_offset = cpu_to_le16(cfg->ss_offset); 2821 cmd_params->ss_size = cpu_to_le16(cfg->ss_size); 2822 cmd_params->ss_iova = cpu_to_le64(cfg->ss_iova); 2823 2824 /* send command to mc*/ 2825 return mc_send_command(mc_io, &cmd); 2826 } 2827 2828 int dpni_enable_sw_sequence(struct fsl_mc_io *mc_io, 2829 uint32_t cmd_flags, 2830 uint16_t token, 2831 struct dpni_enable_ss_cfg *cfg) 2832 { 2833 struct dpni_enable_sw_sequence *cmd_params; 2834 struct mc_command cmd = { 0 }; 2835 2836 /* prepare command */ 2837 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_SW_SEQUENCE, 2838 cmd_flags, 2839 token); 2840 cmd_params = (struct dpni_enable_sw_sequence *)cmd.params; 2841 cmd_params->dest = cfg->dest; 2842 cmd_params->set_start = cfg->set_start; 2843 cmd_params->hxs = cpu_to_le16(cfg->hxs); 2844 cmd_params->ss_offset = cpu_to_le16(cfg->ss_offset); 2845 cmd_params->param_offset = cfg->param_offset; 2846 cmd_params->param_size = cfg->param_size; 2847 cmd_params->param_iova = cpu_to_le64(cfg->param_iova); 2848 2849 /* send command to mc*/ 2850 return mc_send_command(mc_io, &cmd); 2851 } 2852 2853 /** 2854 * dpni_get_sw_sequence_layout() - Get the soft sequence layout 2855 * @mc_io: Pointer to MC portal's I/O object 2856 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2857 * @token: Token of DPNI object 2858 * @src: Source of the layout (WRIOP Rx or Tx) 2859 * @ss_layout_iova: I/O virtual address of 264 bytes DMA-able memory 2860 * 2861 * warning: After calling this function, call dpni_extract_sw_sequence_layout() 2862 * to get the layout. 2863 * 2864 * Return: '0' on Success; error code otherwise. 2865 */ 2866 int dpni_get_sw_sequence_layout(struct fsl_mc_io *mc_io, 2867 uint32_t cmd_flags, 2868 uint16_t token, 2869 enum dpni_soft_sequence_dest src, 2870 uint64_t ss_layout_iova) 2871 { 2872 struct dpni_get_sw_sequence_layout *cmd_params; 2873 struct mc_command cmd = { 0 }; 2874 2875 /* prepare command */ 2876 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SW_SEQUENCE_LAYOUT, 2877 cmd_flags, 2878 token); 2879 2880 cmd_params = (struct dpni_get_sw_sequence_layout *)cmd.params; 2881 cmd_params->src = src; 2882 cmd_params->layout_iova = cpu_to_le64(ss_layout_iova); 2883 2884 /* send command to mc*/ 2885 return mc_send_command(mc_io, &cmd); 2886 } 2887 2888 /** 2889 * dpni_extract_sw_sequence_layout() - extract the software sequence layout 2890 * @layout: software sequence layout 2891 * @sw_sequence_layout_buf: Zeroed 264 bytes of memory before mapping it 2892 * to DMA 2893 * 2894 * This function has to be called after dpni_get_sw_sequence_layout 2895 * 2896 */ 2897 void dpni_extract_sw_sequence_layout(struct dpni_sw_sequence_layout *layout, 2898 const uint8_t *sw_sequence_layout_buf) 2899 { 2900 const struct dpni_sw_sequence_layout_entry *ext_params; 2901 int i; 2902 uint16_t ss_size, ss_offset; 2903 2904 ext_params = (const struct dpni_sw_sequence_layout_entry *) 2905 sw_sequence_layout_buf; 2906 2907 for (i = 0; i < DPNI_SW_SEQUENCE_LAYOUT_SIZE; i++) { 2908 ss_offset = le16_to_cpu(ext_params[i].ss_offset); 2909 ss_size = le16_to_cpu(ext_params[i].ss_size); 2910 2911 if (ss_offset == 0 && ss_size == 0) { 2912 layout->num_ss = i; 2913 return; 2914 } 2915 2916 layout->ss[i].ss_offset = ss_offset; 2917 layout->ss[i].ss_size = ss_size; 2918 layout->ss[i].param_offset = ext_params[i].param_offset; 2919 layout->ss[i].param_size = ext_params[i].param_size; 2920 } 2921 } 2922 /** 2923 * dpni_set_rx_fs_dist() - Set Rx traffic class FS distribution 2924 * @mc_io: Pointer to MC portal's I/O object 2925 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2926 * @token: Token of DPNI object 2927 * @cfg: Distribution configuration 2928 * If the FS is already enabled with a previous call the classification 2929 * key will be changed but all the table rules are kept. If the 2930 * existing rules do not match the key the results will not be 2931 * predictable. It is the user responsibility to keep keyintegrity. 2932 * If cfg.enable is set to 1 the command will create a flow steering table 2933 * and will classify packets according to this table. The packets 2934 * that miss all the table rules will be classified according to 2935 * settings made in dpni_set_rx_hash_dist() 2936 * If cfg.enable is set to 0 the command will clear flow steering table. The 2937 * packets will be classified according to settings made in 2938 * dpni_set_rx_hash_dist() 2939 */ 2940 int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 2941 uint16_t token, const struct dpni_rx_dist_cfg *cfg) 2942 { 2943 struct dpni_cmd_set_rx_fs_dist *cmd_params; 2944 struct mc_command cmd = { 0 }; 2945 2946 /* prepare command */ 2947 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST, 2948 cmd_flags, 2949 token); 2950 cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params; 2951 cmd_params->dist_size = cpu_to_le16(cfg->dist_size); 2952 dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable); 2953 cmd_params->tc = cfg->tc; 2954 cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id); 2955 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); 2956 2957 /* send command to mc*/ 2958 return mc_send_command(mc_io, &cmd); 2959 } 2960 2961 /** 2962 * dpni_set_rx_hash_dist() - Set Rx traffic class HASH distribution 2963 * @mc_io: Pointer to MC portal's I/O object 2964 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2965 * @token: Token of DPNI object 2966 * @cfg: Distribution configuration 2967 * If cfg.enable is set to 1 the packets will be classified using a hash 2968 * function based on the key received in cfg.key_cfg_iova parameter. 2969 * If cfg.enable is set to 0 the packets will be sent to the queue configured in 2970 * dpni_set_rx_dist_default_queue() call 2971 */ 2972 int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 2973 uint16_t token, const struct dpni_rx_dist_cfg *cfg) 2974 { 2975 struct dpni_cmd_set_rx_hash_dist *cmd_params; 2976 struct mc_command cmd = { 0 }; 2977 2978 /* prepare command */ 2979 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST, 2980 cmd_flags, 2981 token); 2982 cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params; 2983 cmd_params->dist_size = cpu_to_le16(cfg->dist_size); 2984 dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable); 2985 cmd_params->tc_id = cfg->tc; 2986 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); 2987 2988 /* send command to mc*/ 2989 return mc_send_command(mc_io, &cmd); 2990 } 2991 2992 /** 2993 * dpni_add_custom_tpid() - Configures a distinct Ethertype value (or TPID 2994 * value) to indicate VLAN tag in adition to the common TPID values 2995 * 0x81000 and 0x88A8 2996 * @mc_io: Pointer to MC portal's I/O object 2997 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 2998 * @token: Token of DPNI object 2999 * @tpid: New value for TPID 3000 * 3001 * Only two custom values are accepted. If the function is called for the third 3002 * time it will return error. 3003 * To replace an existing value use dpni_remove_custom_tpid() to remove a 3004 * previous TPID and after that use again the function. 3005 * 3006 * Return: '0' on Success; Error code otherwise. 3007 */ 3008 int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 3009 uint16_t token, uint16_t tpid) 3010 { 3011 struct dpni_cmd_add_custom_tpid *cmd_params; 3012 struct mc_command cmd = { 0 }; 3013 3014 /* prepare command */ 3015 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_CUSTOM_TPID, 3016 cmd_flags, 3017 token); 3018 cmd_params = (struct dpni_cmd_add_custom_tpid *)cmd.params; 3019 cmd_params->tpid = cpu_to_le16(tpid); 3020 3021 /* send command to mc*/ 3022 return mc_send_command(mc_io, &cmd); 3023 } 3024 3025 /** 3026 * dpni_remove_custom_tpid() - Removes a distinct Ethertype value added 3027 * previously with dpni_add_custom_tpid() 3028 * @mc_io: Pointer to MC portal's I/O object 3029 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 3030 * @token: Token of DPNI object 3031 * @tpid: New value for TPID 3032 * 3033 * Use this function when a TPID value added with dpni_add_custom_tpid() needs 3034 * to be replaced. 3035 * 3036 * Return: '0' on Success; Error code otherwise. 3037 */ 3038 int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 3039 uint16_t token, uint16_t tpid) 3040 { 3041 struct dpni_cmd_remove_custom_tpid *cmd_params; 3042 struct mc_command cmd = { 0 }; 3043 3044 /* prepare command */ 3045 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_CUSTOM_TPID, 3046 cmd_flags, 3047 token); 3048 cmd_params = (struct dpni_cmd_remove_custom_tpid *)cmd.params; 3049 cmd_params->tpid = cpu_to_le16(tpid); 3050 3051 /* send command to mc*/ 3052 return mc_send_command(mc_io, &cmd); 3053 } 3054 3055 /** 3056 * dpni_get_custom_tpid() - Returns custom TPID (vlan tags) values configured to 3057 * detect 802.1q frames 3058 * @mc_io: Pointer to MC portal's I/O object 3059 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 3060 * @token: Token of DPNI object 3061 * @tpid: TPID values. Only nonzero members of the structure are valid. 3062 * 3063 * Return: '0' on Success; Error code otherwise. 3064 */ 3065 int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 3066 uint16_t token, struct dpni_custom_tpid_cfg *tpid) 3067 { 3068 struct dpni_rsp_get_custom_tpid *rsp_params; 3069 struct mc_command cmd = { 0 }; 3070 int err; 3071 3072 /* prepare command */ 3073 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_CUSTOM_TPID, 3074 cmd_flags, 3075 token); 3076 3077 /* send command to mc*/ 3078 err = mc_send_command(mc_io, &cmd); 3079 if (err) 3080 return err; 3081 3082 /* read command response */ 3083 rsp_params = (struct dpni_rsp_get_custom_tpid *)cmd.params; 3084 tpid->tpid1 = le16_to_cpu(rsp_params->tpid1); 3085 tpid->tpid2 = le16_to_cpu(rsp_params->tpid2); 3086 3087 return err; 3088 } 3089 3090 /** 3091 * dpni_set_port_cfg() - performs configurations at physical port connected on 3092 * this dpni. The command have effect only if dpni is connected to 3093 * another dpni object 3094 * @mc_io: Pointer to MC portal's I/O object 3095 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 3096 * @token: Token of DPNI object 3097 * @flags: Valid fields from port_cfg structure 3098 * @port_cfg: Configuration data; one or more of DPNI_PORT_CFG_ 3099 * The command can be called only when dpni is connected to a dpmac object. If 3100 * the dpni is unconnected or the endpoint is not a dpni it will return error. 3101 * If dpmac endpoint is disconnected the settings will be lost 3102 */ 3103 int dpni_set_port_cfg(struct fsl_mc_io *mc_io, uint32_t cmd_flags, 3104 uint16_t token, uint32_t flags, struct dpni_port_cfg *port_cfg) 3105 { 3106 struct dpni_cmd_set_port_cfg *cmd_params; 3107 struct mc_command cmd = { 0 }; 3108 3109 /* prepare command */ 3110 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PORT_CFG, 3111 cmd_flags, token); 3112 3113 cmd_params = (struct dpni_cmd_set_port_cfg *)cmd.params; 3114 cmd_params->flags = cpu_to_le32(flags); 3115 dpni_set_field(cmd_params->bit_params, PORT_LOOPBACK_EN, 3116 !!port_cfg->loopback_en); 3117 3118 /* send command to MC */ 3119 return mc_send_command(mc_io, &cmd); 3120 } 3121 3122