1 /*- 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * BSD LICENSE 6 * 7 * Copyright 2013-2016 Freescale Semiconductor Inc. 8 * Copyright 2016 NXP. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are met: 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * * Neither the name of the above-listed copyright holders nor the 18 * names of any contributors may be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * GPL LICENSE SUMMARY 22 * 23 * ALTERNATIVELY, this software may be distributed under the terms of the 24 * GNU General Public License ("GPL") as published by the Free Software 25 * Foundation, either version 2 of that License or (at your option) any 26 * later version. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 #include <fsl_mc_sys.h> 41 #include <fsl_mc_cmd.h> 42 #include <fsl_dpni.h> 43 #include <fsl_dpni_cmd.h> 44 45 /** 46 * dpni_open() - Open a control session for the specified object 47 * @mc_io: Pointer to MC portal's I/O object 48 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 49 * @dpni_id: DPNI unique ID 50 * @token: Returned token; use in subsequent API calls 51 * 52 * This function can be used to open a control session for an 53 * already created object; an object may have been declared in 54 * the DPL or by calling the dpni_create() function. 55 * This function returns a unique authentication token, 56 * associated with the specific object ID and the specific MC 57 * portal; this token must be used in all subsequent commands for 58 * this specific object. 59 * 60 * Return: '0' on Success; Error code otherwise. 61 */ 62 int dpni_open(struct fsl_mc_io *mc_io, 63 uint32_t cmd_flags, 64 int dpni_id, 65 uint16_t *token) 66 { 67 struct mc_command cmd = { 0 }; 68 struct dpni_cmd_open *cmd_params; 69 70 int err; 71 72 /* prepare command */ 73 cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN, 74 cmd_flags, 75 0); 76 cmd_params = (struct dpni_cmd_open *)cmd.params; 77 cmd_params->dpni_id = cpu_to_le32(dpni_id); 78 79 /* send command to mc*/ 80 err = mc_send_command(mc_io, &cmd); 81 if (err) 82 return err; 83 84 /* retrieve response parameters */ 85 *token = mc_cmd_hdr_read_token(&cmd); 86 87 return 0; 88 } 89 90 /** 91 * dpni_close() - Close the control session of the object 92 * @mc_io: Pointer to MC portal's I/O object 93 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 94 * @token: Token of DPNI object 95 * 96 * After this function is called, no further operations are 97 * allowed on the object without opening a new control session. 98 * 99 * Return: '0' on Success; Error code otherwise. 100 */ 101 int dpni_close(struct fsl_mc_io *mc_io, 102 uint32_t cmd_flags, 103 uint16_t token) 104 { 105 struct mc_command cmd = { 0 }; 106 107 /* prepare command */ 108 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE, 109 cmd_flags, 110 token); 111 112 /* send command to mc*/ 113 return mc_send_command(mc_io, &cmd); 114 } 115 116 /** 117 * dpni_create() - Create the DPNI object 118 * @mc_io: Pointer to MC portal's I/O object 119 * @dprc_token: Parent container token; '0' for default container 120 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 121 * @cfg: Configuration structure 122 * @obj_id: Returned object id 123 * 124 * Create the DPNI object, allocate required resources and 125 * perform required initialization. 126 * 127 * The object can be created either by declaring it in the 128 * DPL file, or by calling this function. 129 * 130 * The function accepts an authentication token of a parent 131 * container that this object should be assigned to. The token 132 * can be '0' so the object will be assigned to the default container. 133 * The newly created object can be opened with the returned 134 * object id and using the container's associated tokens and MC portals. 135 * 136 * Return: '0' on Success; Error code otherwise. 137 */ 138 int dpni_create(struct fsl_mc_io *mc_io, 139 uint16_t dprc_token, 140 uint32_t cmd_flags, 141 const struct dpni_cfg *cfg, 142 uint32_t *obj_id) 143 { 144 struct dpni_cmd_create *cmd_params; 145 struct mc_command cmd = { 0 }; 146 int err; 147 148 /* prepare command */ 149 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE, 150 cmd_flags, 151 dprc_token); 152 cmd_params = (struct dpni_cmd_create *)cmd.params; 153 cmd_params->options = cpu_to_le32(cfg->options); 154 cmd_params->num_queues = cfg->num_queues; 155 cmd_params->num_tcs = cfg->num_tcs; 156 cmd_params->mac_filter_entries = cfg->mac_filter_entries; 157 cmd_params->vlan_filter_entries = cfg->vlan_filter_entries; 158 cmd_params->qos_entries = cfg->qos_entries; 159 cmd_params->fs_entries = cpu_to_le16(cfg->fs_entries); 160 161 /* send command to mc*/ 162 err = mc_send_command(mc_io, &cmd); 163 if (err) 164 return err; 165 166 /* retrieve response parameters */ 167 *obj_id = mc_cmd_read_object_id(&cmd); 168 169 return 0; 170 } 171 172 /** 173 * dpni_destroy() - Destroy the DPNI object and release all its resources. 174 * @mc_io: Pointer to MC portal's I/O object 175 * @dprc_token: Parent container token; '0' for default container 176 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 177 * @object_id: The object id; it must be a valid id within the container that 178 * created this object; 179 * 180 * The function accepts the authentication token of the parent container that 181 * created the object (not the one that currently owns the object). The object 182 * is searched within parent using the provided 'object_id'. 183 * All tokens to the object must be closed before calling destroy. 184 * 185 * Return: '0' on Success; error code otherwise. 186 */ 187 int dpni_destroy(struct fsl_mc_io *mc_io, 188 uint16_t dprc_token, 189 uint32_t cmd_flags, 190 uint32_t object_id) 191 { 192 struct dpni_cmd_destroy *cmd_params; 193 struct mc_command cmd = { 0 }; 194 195 /* prepare command */ 196 cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY, 197 cmd_flags, 198 dprc_token); 199 /* set object id to destroy */ 200 cmd_params = (struct dpni_cmd_destroy *)cmd.params; 201 cmd_params->dpsw_id = cpu_to_le32(object_id); 202 203 /* send command to mc*/ 204 return mc_send_command(mc_io, &cmd); 205 } 206 207 /** 208 * dpni_set_pools() - Set buffer pools configuration 209 * @mc_io: Pointer to MC portal's I/O object 210 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 211 * @token: Token of DPNI object 212 * @cfg: Buffer pools configuration 213 * 214 * mandatory for DPNI operation 215 * warning:Allowed only when DPNI is disabled 216 * 217 * Return: '0' on Success; Error code otherwise. 218 */ 219 int dpni_set_pools(struct fsl_mc_io *mc_io, 220 uint32_t cmd_flags, 221 uint16_t token, 222 const struct dpni_pools_cfg *cfg) 223 { 224 struct mc_command cmd = { 0 }; 225 struct dpni_cmd_set_pools *cmd_params; 226 int i; 227 228 /* prepare command */ 229 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS, 230 cmd_flags, 231 token); 232 cmd_params = (struct dpni_cmd_set_pools *)cmd.params; 233 cmd_params->num_dpbp = cfg->num_dpbp; 234 for (i = 0; i < DPNI_MAX_DPBP; i++) { 235 cmd_params->pool[i].dpbp_id = 236 cpu_to_le16(cfg->pools[i].dpbp_id); 237 cmd_params->pool[i].priority_mask = 238 cfg->pools[i].priority_mask; 239 cmd_params->buffer_size[i] = 240 cpu_to_le16(cfg->pools[i].buffer_size); 241 cmd_params->backup_pool_mask |= 242 DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i); 243 } 244 245 /* send command to mc*/ 246 return mc_send_command(mc_io, &cmd); 247 } 248 249 /** 250 * dpni_enable() - Enable the DPNI, allow sending and receiving frames. 251 * @mc_io: Pointer to MC portal's I/O object 252 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 253 * @token: Token of DPNI object 254 * 255 * Return: '0' on Success; Error code otherwise. 256 */ 257 int dpni_enable(struct fsl_mc_io *mc_io, 258 uint32_t cmd_flags, 259 uint16_t token) 260 { 261 struct mc_command cmd = { 0 }; 262 263 /* prepare command */ 264 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE, 265 cmd_flags, 266 token); 267 268 /* send command to mc*/ 269 return mc_send_command(mc_io, &cmd); 270 } 271 272 /** 273 * dpni_disable() - Disable the DPNI, stop sending and receiving frames. 274 * @mc_io: Pointer to MC portal's I/O object 275 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 276 * @token: Token of DPNI object 277 * 278 * Return: '0' on Success; Error code otherwise. 279 */ 280 int dpni_disable(struct fsl_mc_io *mc_io, 281 uint32_t cmd_flags, 282 uint16_t token) 283 { 284 struct mc_command cmd = { 0 }; 285 286 /* prepare command */ 287 cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE, 288 cmd_flags, 289 token); 290 291 /* send command to mc*/ 292 return mc_send_command(mc_io, &cmd); 293 } 294 295 /** 296 * dpni_is_enabled() - Check if the DPNI is enabled. 297 * @mc_io: Pointer to MC portal's I/O object 298 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 299 * @token: Token of DPNI object 300 * @en: Returns '1' if object is enabled; '0' otherwise 301 * 302 * Return: '0' on Success; Error code otherwise. 303 */ 304 int dpni_is_enabled(struct fsl_mc_io *mc_io, 305 uint32_t cmd_flags, 306 uint16_t token, 307 int *en) 308 { 309 struct mc_command cmd = { 0 }; 310 struct dpni_rsp_is_enabled *rsp_params; 311 int err; 312 313 /* prepare command */ 314 cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED, 315 cmd_flags, 316 token); 317 318 /* send command to mc*/ 319 err = mc_send_command(mc_io, &cmd); 320 if (err) 321 return err; 322 323 /* retrieve response parameters */ 324 rsp_params = (struct dpni_rsp_is_enabled *)cmd.params; 325 *en = dpni_get_field(rsp_params->enabled, ENABLE); 326 327 return 0; 328 } 329 330 /** 331 * dpni_reset() - Reset the DPNI, returns the object to initial state. 332 * @mc_io: Pointer to MC portal's I/O object 333 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 334 * @token: Token of DPNI object 335 * 336 * Return: '0' on Success; Error code otherwise. 337 */ 338 int dpni_reset(struct fsl_mc_io *mc_io, 339 uint32_t cmd_flags, 340 uint16_t token) 341 { 342 struct mc_command cmd = { 0 }; 343 344 /* prepare command */ 345 cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET, 346 cmd_flags, 347 token); 348 349 /* send command to mc*/ 350 return mc_send_command(mc_io, &cmd); 351 } 352 353 /** 354 * dpni_get_attributes() - Retrieve DPNI attributes. 355 * @mc_io: Pointer to MC portal's I/O object 356 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 357 * @token: Token of DPNI object 358 * @attr: Object's attributes 359 * 360 * Return: '0' on Success; Error code otherwise. 361 */ 362 int dpni_get_attributes(struct fsl_mc_io *mc_io, 363 uint32_t cmd_flags, 364 uint16_t token, 365 struct dpni_attr *attr) 366 { 367 struct mc_command cmd = { 0 }; 368 struct dpni_rsp_get_attr *rsp_params; 369 370 int err; 371 372 /* prepare command */ 373 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR, 374 cmd_flags, 375 token); 376 377 /* send command to mc*/ 378 err = mc_send_command(mc_io, &cmd); 379 if (err) 380 return err; 381 382 /* retrieve response parameters */ 383 rsp_params = (struct dpni_rsp_get_attr *)cmd.params; 384 attr->options = le32_to_cpu(rsp_params->options); 385 attr->num_queues = rsp_params->num_queues; 386 attr->num_rx_tcs = rsp_params->num_rx_tcs; 387 attr->num_tx_tcs = rsp_params->num_tx_tcs; 388 attr->mac_filter_entries = rsp_params->mac_filter_entries; 389 attr->vlan_filter_entries = rsp_params->vlan_filter_entries; 390 attr->qos_entries = rsp_params->qos_entries; 391 attr->fs_entries = le16_to_cpu(rsp_params->fs_entries); 392 attr->qos_key_size = rsp_params->qos_key_size; 393 attr->fs_key_size = rsp_params->fs_key_size; 394 attr->wriop_version = le16_to_cpu(rsp_params->wriop_version); 395 396 return 0; 397 } 398 399 /** 400 * dpni_set_errors_behavior() - Set errors behavior 401 * @mc_io: Pointer to MC portal's I/O object 402 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 403 * @token: Token of DPNI object 404 * @cfg: Errors configuration 405 * 406 * This function may be called numerous times with different 407 * error masks 408 * 409 * Return: '0' on Success; Error code otherwise. 410 */ 411 int dpni_set_errors_behavior(struct fsl_mc_io *mc_io, 412 uint32_t cmd_flags, 413 uint16_t token, 414 struct dpni_error_cfg *cfg) 415 { 416 struct mc_command cmd = { 0 }; 417 struct dpni_cmd_set_errors_behavior *cmd_params; 418 419 /* prepare command */ 420 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR, 421 cmd_flags, 422 token); 423 cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params; 424 cmd_params->errors = cpu_to_le32(cfg->errors); 425 dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action); 426 dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation); 427 428 /* send command to mc*/ 429 return mc_send_command(mc_io, &cmd); 430 } 431 432 /** 433 * dpni_get_buffer_layout() - Retrieve buffer layout attributes. 434 * @mc_io: Pointer to MC portal's I/O object 435 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 436 * @token: Token of DPNI object 437 * @qtype: Type of queue to retrieve configuration for 438 * @layout: Returns buffer layout attributes 439 * 440 * Return: '0' on Success; Error code otherwise. 441 */ 442 int dpni_get_buffer_layout(struct fsl_mc_io *mc_io, 443 uint32_t cmd_flags, 444 uint16_t token, 445 enum dpni_queue_type qtype, 446 struct dpni_buffer_layout *layout) 447 { 448 struct mc_command cmd = { 0 }; 449 struct dpni_cmd_get_buffer_layout *cmd_params; 450 struct dpni_rsp_get_buffer_layout *rsp_params; 451 int err; 452 453 /* prepare command */ 454 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT, 455 cmd_flags, 456 token); 457 cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params; 458 cmd_params->qtype = qtype; 459 460 /* send command to mc*/ 461 err = mc_send_command(mc_io, &cmd); 462 if (err) 463 return err; 464 465 /* retrieve response parameters */ 466 rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params; 467 layout->pass_timestamp = dpni_get_field(rsp_params->flags, PASS_TS); 468 layout->pass_parser_result = dpni_get_field(rsp_params->flags, PASS_PR); 469 layout->pass_frame_status = dpni_get_field(rsp_params->flags, PASS_FS); 470 layout->private_data_size = le16_to_cpu(rsp_params->private_data_size); 471 layout->data_align = le16_to_cpu(rsp_params->data_align); 472 layout->data_head_room = le16_to_cpu(rsp_params->head_room); 473 layout->data_tail_room = le16_to_cpu(rsp_params->tail_room); 474 475 return 0; 476 } 477 478 /** 479 * dpni_set_buffer_layout() - Set buffer layout configuration. 480 * @mc_io: Pointer to MC portal's I/O object 481 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 482 * @token: Token of DPNI object 483 * @qtype: Type of queue this configuration applies to 484 * @layout: Buffer layout configuration 485 * 486 * Return: '0' on Success; Error code otherwise. 487 * 488 * @warning Allowed only when DPNI is disabled 489 */ 490 int dpni_set_buffer_layout(struct fsl_mc_io *mc_io, 491 uint32_t cmd_flags, 492 uint16_t token, 493 enum dpni_queue_type qtype, 494 const struct dpni_buffer_layout *layout) 495 { 496 struct mc_command cmd = { 0 }; 497 struct dpni_cmd_set_buffer_layout *cmd_params; 498 499 /* prepare command */ 500 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT, 501 cmd_flags, 502 token); 503 cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params; 504 cmd_params->qtype = qtype; 505 cmd_params->options = cpu_to_le16(layout->options); 506 dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp); 507 dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result); 508 dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status); 509 cmd_params->private_data_size = cpu_to_le16(layout->private_data_size); 510 cmd_params->data_align = cpu_to_le16(layout->data_align); 511 cmd_params->head_room = cpu_to_le16(layout->data_head_room); 512 cmd_params->tail_room = cpu_to_le16(layout->data_tail_room); 513 514 /* send command to mc*/ 515 return mc_send_command(mc_io, &cmd); 516 } 517 518 /** 519 * dpni_set_offload() - Set DPNI offload configuration. 520 * @mc_io: Pointer to MC portal's I/O object 521 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 522 * @token: Token of DPNI object 523 * @type: Type of DPNI offload 524 * @config: Offload configuration. 525 * For checksum offloads, non-zero value enables the offload 526 * 527 * Return: '0' on Success; Error code otherwise. 528 * 529 * @warning Allowed only when DPNI is disabled 530 */ 531 532 int dpni_set_offload(struct fsl_mc_io *mc_io, 533 uint32_t cmd_flags, 534 uint16_t token, 535 enum dpni_offload type, 536 uint32_t config) 537 { 538 struct mc_command cmd = { 0 }; 539 struct dpni_cmd_set_offload *cmd_params; 540 541 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD, 542 cmd_flags, 543 token); 544 cmd_params = (struct dpni_cmd_set_offload *)cmd.params; 545 cmd_params->dpni_offload = type; 546 cmd_params->config = cpu_to_le32(config); 547 548 return mc_send_command(mc_io, &cmd); 549 } 550 551 /** 552 * dpni_get_offload() - Get DPNI offload configuration. 553 * @mc_io: Pointer to MC portal's I/O object 554 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 555 * @token: Token of DPNI object 556 * @type: Type of DPNI offload 557 * @config: Offload configuration. 558 * For checksum offloads, a value of 1 indicates that the 559 * offload is enabled. 560 * 561 * Return: '0' on Success; Error code otherwise. 562 * 563 * @warning Allowed only when DPNI is disabled 564 */ 565 int dpni_get_offload(struct fsl_mc_io *mc_io, 566 uint32_t cmd_flags, 567 uint16_t token, 568 enum dpni_offload type, 569 uint32_t *config) 570 { 571 struct mc_command cmd = { 0 }; 572 struct dpni_cmd_get_offload *cmd_params; 573 struct dpni_rsp_get_offload *rsp_params; 574 int err; 575 576 /* prepare command */ 577 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD, 578 cmd_flags, 579 token); 580 cmd_params = (struct dpni_cmd_get_offload *)cmd.params; 581 cmd_params->dpni_offload = type; 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_offload *)cmd.params; 590 *config = le32_to_cpu(rsp_params->config); 591 592 return 0; 593 } 594 595 /** 596 * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used 597 * for enqueue operations 598 * @mc_io: Pointer to MC portal's I/O object 599 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 600 * @token: Token of DPNI object 601 * @qtype: Type of queue to receive QDID for 602 * @qdid: Returned virtual QDID value that should be used as an argument 603 * in all enqueue operations 604 * 605 * Return: '0' on Success; Error code otherwise. 606 */ 607 int dpni_get_qdid(struct fsl_mc_io *mc_io, 608 uint32_t cmd_flags, 609 uint16_t token, 610 enum dpni_queue_type qtype, 611 uint16_t *qdid) 612 { 613 struct mc_command cmd = { 0 }; 614 struct dpni_cmd_get_qdid *cmd_params; 615 struct dpni_rsp_get_qdid *rsp_params; 616 int err; 617 618 /* prepare command */ 619 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID, 620 cmd_flags, 621 token); 622 cmd_params = (struct dpni_cmd_get_qdid *)cmd.params; 623 cmd_params->qtype = qtype; 624 625 /* send command to mc*/ 626 err = mc_send_command(mc_io, &cmd); 627 if (err) 628 return err; 629 630 /* retrieve response parameters */ 631 rsp_params = (struct dpni_rsp_get_qdid *)cmd.params; 632 *qdid = le16_to_cpu(rsp_params->qdid); 633 634 return 0; 635 } 636 637 /** 638 * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer) 639 * @mc_io: Pointer to MC portal's I/O object 640 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 641 * @token: Token of DPNI object 642 * @data_offset: Tx data offset (from start of buffer) 643 * 644 * Return: '0' on Success; Error code otherwise. 645 */ 646 int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io, 647 uint32_t cmd_flags, 648 uint16_t token, 649 uint16_t *data_offset) 650 { 651 struct mc_command cmd = { 0 }; 652 struct dpni_rsp_get_tx_data_offset *rsp_params; 653 int err; 654 655 /* prepare command */ 656 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET, 657 cmd_flags, 658 token); 659 660 /* send command to mc*/ 661 err = mc_send_command(mc_io, &cmd); 662 if (err) 663 return err; 664 665 /* retrieve response parameters */ 666 rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params; 667 *data_offset = le16_to_cpu(rsp_params->data_offset); 668 669 return 0; 670 } 671 672 /** 673 * dpni_set_link_cfg() - set the link configuration. 674 * @mc_io: Pointer to MC portal's I/O object 675 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 676 * @token: Token of DPNI object 677 * @cfg: Link configuration 678 * 679 * Return: '0' on Success; Error code otherwise. 680 */ 681 int dpni_set_link_cfg(struct fsl_mc_io *mc_io, 682 uint32_t cmd_flags, 683 uint16_t token, 684 const struct dpni_link_cfg *cfg) 685 { 686 struct mc_command cmd = { 0 }; 687 struct dpni_cmd_set_link_cfg *cmd_params; 688 689 /* prepare command */ 690 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG, 691 cmd_flags, 692 token); 693 cmd_params = (struct dpni_cmd_set_link_cfg *)cmd.params; 694 cmd_params->rate = cpu_to_le32(cfg->rate); 695 cmd_params->options = cpu_to_le64(cfg->options); 696 697 /* send command to mc*/ 698 return mc_send_command(mc_io, &cmd); 699 } 700 701 /** 702 * dpni_get_link_state() - Return the link state (either up or down) 703 * @mc_io: Pointer to MC portal's I/O object 704 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 705 * @token: Token of DPNI object 706 * @state: Returned link state; 707 * 708 * Return: '0' on Success; Error code otherwise. 709 */ 710 int dpni_get_link_state(struct fsl_mc_io *mc_io, 711 uint32_t cmd_flags, 712 uint16_t token, 713 struct dpni_link_state *state) 714 { 715 struct mc_command cmd = { 0 }; 716 struct dpni_rsp_get_link_state *rsp_params; 717 int err; 718 719 /* prepare command */ 720 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE, 721 cmd_flags, 722 token); 723 724 /* send command to mc*/ 725 err = mc_send_command(mc_io, &cmd); 726 if (err) 727 return err; 728 729 /* retrieve response parameters */ 730 rsp_params = (struct dpni_rsp_get_link_state *)cmd.params; 731 state->up = dpni_get_field(rsp_params->flags, LINK_STATE); 732 state->rate = le32_to_cpu(rsp_params->rate); 733 state->options = le64_to_cpu(rsp_params->options); 734 735 return 0; 736 } 737 738 /** 739 * dpni_set_max_frame_length() - Set the maximum received frame length. 740 * @mc_io: Pointer to MC portal's I/O object 741 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 742 * @token: Token of DPNI object 743 * @max_frame_length: Maximum received frame length (in bytes); 744 * frame is discarded if its length exceeds this value 745 * 746 * Return: '0' on Success; Error code otherwise. 747 */ 748 int dpni_set_max_frame_length(struct fsl_mc_io *mc_io, 749 uint32_t cmd_flags, 750 uint16_t token, 751 uint16_t max_frame_length) 752 { 753 struct mc_command cmd = { 0 }; 754 struct dpni_cmd_set_max_frame_length *cmd_params; 755 756 /* prepare command */ 757 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH, 758 cmd_flags, 759 token); 760 cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params; 761 cmd_params->max_frame_length = cpu_to_le16(max_frame_length); 762 763 /* send command to mc*/ 764 return mc_send_command(mc_io, &cmd); 765 } 766 767 /** 768 * dpni_get_max_frame_length() - Get the maximum received frame length. 769 * @mc_io: Pointer to MC portal's I/O object 770 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 771 * @token: Token of DPNI object 772 * @max_frame_length: Maximum received frame length (in bytes); 773 * frame is discarded if its length exceeds this value 774 * 775 * Return: '0' on Success; Error code otherwise. 776 */ 777 int dpni_get_max_frame_length(struct fsl_mc_io *mc_io, 778 uint32_t cmd_flags, 779 uint16_t token, 780 uint16_t *max_frame_length) 781 { 782 struct mc_command cmd = { 0 }; 783 struct dpni_rsp_get_max_frame_length *rsp_params; 784 int err; 785 786 /* prepare command */ 787 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH, 788 cmd_flags, 789 token); 790 791 /* send command to mc*/ 792 err = mc_send_command(mc_io, &cmd); 793 if (err) 794 return err; 795 796 /* retrieve response parameters */ 797 rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params; 798 *max_frame_length = le16_to_cpu(rsp_params->max_frame_length); 799 800 return 0; 801 } 802 803 /** 804 * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode 805 * @mc_io: Pointer to MC portal's I/O object 806 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 807 * @token: Token of DPNI object 808 * @en: Set to '1' to enable; '0' to disable 809 * 810 * Return: '0' on Success; Error code otherwise. 811 */ 812 int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io, 813 uint32_t cmd_flags, 814 uint16_t token, 815 int en) 816 { 817 struct mc_command cmd = { 0 }; 818 struct dpni_cmd_set_multicast_promisc *cmd_params; 819 820 /* prepare command */ 821 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC, 822 cmd_flags, 823 token); 824 cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params; 825 dpni_set_field(cmd_params->enable, ENABLE, en); 826 827 /* send command to mc*/ 828 return mc_send_command(mc_io, &cmd); 829 } 830 831 /** 832 * dpni_get_multicast_promisc() - Get multicast promiscuous mode 833 * @mc_io: Pointer to MC portal's I/O object 834 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 835 * @token: Token of DPNI object 836 * @en: Returns '1' if enabled; '0' otherwise 837 * 838 * Return: '0' on Success; Error code otherwise. 839 */ 840 int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io, 841 uint32_t cmd_flags, 842 uint16_t token, 843 int *en) 844 { 845 struct mc_command cmd = { 0 }; 846 struct dpni_rsp_get_multicast_promisc *rsp_params; 847 int err; 848 849 /* prepare command */ 850 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC, 851 cmd_flags, 852 token); 853 854 /* send command to mc*/ 855 err = mc_send_command(mc_io, &cmd); 856 if (err) 857 return err; 858 859 /* retrieve response parameters */ 860 rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params; 861 *en = dpni_get_field(rsp_params->enabled, ENABLE); 862 863 return 0; 864 } 865 866 /** 867 * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode 868 * @mc_io: Pointer to MC portal's I/O object 869 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 870 * @token: Token of DPNI object 871 * @en: Set to '1' to enable; '0' to disable 872 * 873 * Return: '0' on Success; Error code otherwise. 874 */ 875 int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io, 876 uint32_t cmd_flags, 877 uint16_t token, 878 int en) 879 { 880 struct mc_command cmd = { 0 }; 881 struct dpni_cmd_set_unicast_promisc *cmd_params; 882 883 /* prepare command */ 884 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC, 885 cmd_flags, 886 token); 887 cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params; 888 dpni_set_field(cmd_params->enable, ENABLE, en); 889 890 /* send command to mc*/ 891 return mc_send_command(mc_io, &cmd); 892 } 893 894 /** 895 * dpni_get_unicast_promisc() - Get unicast promiscuous mode 896 * @mc_io: Pointer to MC portal's I/O object 897 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 898 * @token: Token of DPNI object 899 * @en: Returns '1' if enabled; '0' otherwise 900 * 901 * Return: '0' on Success; Error code otherwise. 902 */ 903 int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io, 904 uint32_t cmd_flags, 905 uint16_t token, 906 int *en) 907 { 908 struct mc_command cmd = { 0 }; 909 struct dpni_rsp_get_unicast_promisc *rsp_params; 910 int err; 911 912 /* prepare command */ 913 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC, 914 cmd_flags, 915 token); 916 917 /* send command to mc*/ 918 err = mc_send_command(mc_io, &cmd); 919 if (err) 920 return err; 921 922 /* retrieve response parameters */ 923 rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params; 924 *en = dpni_get_field(rsp_params->enabled, ENABLE); 925 926 return 0; 927 } 928 929 /** 930 * dpni_set_primary_mac_addr() - Set the primary MAC address 931 * @mc_io: Pointer to MC portal's I/O object 932 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 933 * @token: Token of DPNI object 934 * @mac_addr: MAC address to set as primary address 935 * 936 * Return: '0' on Success; Error code otherwise. 937 */ 938 int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io, 939 uint32_t cmd_flags, 940 uint16_t token, 941 const uint8_t mac_addr[6]) 942 { 943 struct mc_command cmd = { 0 }; 944 struct dpni_cmd_set_primary_mac_addr *cmd_params; 945 int i; 946 947 /* prepare command */ 948 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC, 949 cmd_flags, 950 token); 951 cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params; 952 for (i = 0; i < 6; i++) 953 cmd_params->mac_addr[i] = mac_addr[5 - i]; 954 955 /* send command to mc*/ 956 return mc_send_command(mc_io, &cmd); 957 } 958 959 /** 960 * dpni_get_primary_mac_addr() - Get the primary MAC address 961 * @mc_io: Pointer to MC portal's I/O object 962 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 963 * @token: Token of DPNI object 964 * @mac_addr: Returned MAC address 965 * 966 * Return: '0' on Success; Error code otherwise. 967 */ 968 int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io, 969 uint32_t cmd_flags, 970 uint16_t token, 971 uint8_t mac_addr[6]) 972 { 973 struct mc_command cmd = { 0 }; 974 struct dpni_rsp_get_primary_mac_addr *rsp_params; 975 int i, err; 976 977 /* prepare command */ 978 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC, 979 cmd_flags, 980 token); 981 982 /* send command to mc*/ 983 err = mc_send_command(mc_io, &cmd); 984 if (err) 985 return err; 986 987 /* retrieve response parameters */ 988 rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params; 989 for (i = 0; i < 6; i++) 990 mac_addr[5 - i] = rsp_params->mac_addr[i]; 991 992 return 0; 993 } 994 995 /** 996 * dpni_add_mac_addr() - Add MAC address filter 997 * @mc_io: Pointer to MC portal's I/O object 998 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 999 * @token: Token of DPNI object 1000 * @mac_addr: MAC address to add 1001 * 1002 * Return: '0' on Success; Error code otherwise. 1003 */ 1004 int dpni_add_mac_addr(struct fsl_mc_io *mc_io, 1005 uint32_t cmd_flags, 1006 uint16_t token, 1007 const uint8_t mac_addr[6]) 1008 { 1009 struct mc_command cmd = { 0 }; 1010 struct dpni_cmd_add_mac_addr *cmd_params; 1011 int i; 1012 1013 /* prepare command */ 1014 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR, 1015 cmd_flags, 1016 token); 1017 cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params; 1018 for (i = 0; i < 6; i++) 1019 cmd_params->mac_addr[i] = mac_addr[5 - i]; 1020 1021 /* send command to mc*/ 1022 return mc_send_command(mc_io, &cmd); 1023 } 1024 1025 /** 1026 * dpni_remove_mac_addr() - Remove MAC address filter 1027 * @mc_io: Pointer to MC portal's I/O object 1028 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1029 * @token: Token of DPNI object 1030 * @mac_addr: MAC address to remove 1031 * 1032 * Return: '0' on Success; Error code otherwise. 1033 */ 1034 int dpni_remove_mac_addr(struct fsl_mc_io *mc_io, 1035 uint32_t cmd_flags, 1036 uint16_t token, 1037 const uint8_t mac_addr[6]) 1038 { 1039 struct mc_command cmd = { 0 }; 1040 struct dpni_cmd_remove_mac_addr *cmd_params; 1041 int i; 1042 1043 /* prepare command */ 1044 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR, 1045 cmd_flags, 1046 token); 1047 cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params; 1048 for (i = 0; i < 6; i++) 1049 cmd_params->mac_addr[i] = mac_addr[5 - i]; 1050 1051 /* send command to mc*/ 1052 return mc_send_command(mc_io, &cmd); 1053 } 1054 1055 /** 1056 * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters 1057 * @mc_io: Pointer to MC portal's I/O object 1058 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1059 * @token: Token of DPNI object 1060 * @unicast: Set to '1' to clear unicast addresses 1061 * @multicast: Set to '1' to clear multicast addresses 1062 * 1063 * The primary MAC address is not cleared by this operation. 1064 * 1065 * Return: '0' on Success; Error code otherwise. 1066 */ 1067 int dpni_clear_mac_filters(struct fsl_mc_io *mc_io, 1068 uint32_t cmd_flags, 1069 uint16_t token, 1070 int unicast, 1071 int multicast) 1072 { 1073 struct mc_command cmd = { 0 }; 1074 struct dpni_cmd_clear_mac_filters *cmd_params; 1075 1076 /* prepare command */ 1077 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS, 1078 cmd_flags, 1079 token); 1080 cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params; 1081 dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast); 1082 dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast); 1083 1084 /* send command to mc*/ 1085 return mc_send_command(mc_io, &cmd); 1086 } 1087 1088 /** 1089 * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical 1090 * port the DPNI is attached to 1091 * @mc_io: Pointer to MC portal's I/O object 1092 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1093 * @token: Token of DPNI object 1094 * @mac_addr: MAC address of the physical port, if any, otherwise 0 1095 * 1096 * The primary MAC address is not cleared by this operation. 1097 * 1098 * Return: '0' on Success; Error code otherwise. 1099 */ 1100 int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io, 1101 uint32_t cmd_flags, 1102 uint16_t token, 1103 uint8_t mac_addr[6]) 1104 { 1105 struct mc_command cmd = { 0 }; 1106 struct dpni_rsp_get_port_mac_addr *rsp_params; 1107 int i, err; 1108 1109 /* prepare command */ 1110 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR, 1111 cmd_flags, 1112 token); 1113 1114 /* send command to mc*/ 1115 err = mc_send_command(mc_io, &cmd); 1116 if (err) 1117 return err; 1118 1119 /* retrieve response parameters */ 1120 rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params; 1121 for (i = 0; i < 6; i++) 1122 mac_addr[5 - i] = rsp_params->mac_addr[i]; 1123 1124 return 0; 1125 } 1126 1127 /** 1128 * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode 1129 * @mc_io: Pointer to MC portal's I/O object 1130 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1131 * @token: Token of DPNI object 1132 * @en: Set to '1' to enable; '0' to disable 1133 * 1134 * Return: '0' on Success; Error code otherwise. 1135 */ 1136 int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io, 1137 uint32_t cmd_flags, 1138 uint16_t token, 1139 int en) 1140 { 1141 struct dpni_cmd_enable_vlan_filter *cmd_params; 1142 struct mc_command cmd = { 0 }; 1143 1144 /* prepare command */ 1145 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER, 1146 cmd_flags, 1147 token); 1148 cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params; 1149 dpni_set_field(cmd_params->en, ENABLE, en); 1150 1151 /* send command to mc*/ 1152 return mc_send_command(mc_io, &cmd); 1153 } 1154 1155 /** 1156 * dpni_add_vlan_id() - Add VLAN ID filter 1157 * @mc_io: Pointer to MC portal's I/O object 1158 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1159 * @token: Token of DPNI object 1160 * @vlan_id: VLAN ID to add 1161 * 1162 * Return: '0' on Success; Error code otherwise. 1163 */ 1164 int dpni_add_vlan_id(struct fsl_mc_io *mc_io, 1165 uint32_t cmd_flags, 1166 uint16_t token, 1167 uint16_t vlan_id) 1168 { 1169 struct dpni_cmd_vlan_id *cmd_params; 1170 struct mc_command cmd = { 0 }; 1171 1172 /* prepare command */ 1173 cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID, 1174 cmd_flags, 1175 token); 1176 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params; 1177 cmd_params->vlan_id = cpu_to_le16(vlan_id); 1178 1179 /* send command to mc*/ 1180 return mc_send_command(mc_io, &cmd); 1181 } 1182 1183 /** 1184 * dpni_remove_vlan_id() - Remove VLAN ID filter 1185 * @mc_io: Pointer to MC portal's I/O object 1186 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1187 * @token: Token of DPNI object 1188 * @vlan_id: VLAN ID to remove 1189 * 1190 * Return: '0' on Success; Error code otherwise. 1191 */ 1192 int dpni_remove_vlan_id(struct fsl_mc_io *mc_io, 1193 uint32_t cmd_flags, 1194 uint16_t token, 1195 uint16_t vlan_id) 1196 { 1197 struct dpni_cmd_vlan_id *cmd_params; 1198 struct mc_command cmd = { 0 }; 1199 1200 /* prepare command */ 1201 cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID, 1202 cmd_flags, 1203 token); 1204 cmd_params = (struct dpni_cmd_vlan_id *)cmd.params; 1205 cmd_params->vlan_id = cpu_to_le16(vlan_id); 1206 1207 /* send command to mc*/ 1208 return mc_send_command(mc_io, &cmd); 1209 } 1210 1211 /** 1212 * dpni_clear_vlan_filters() - Clear all VLAN filters 1213 * @mc_io: Pointer to MC portal's I/O object 1214 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1215 * @token: Token of DPNI object 1216 * 1217 * Return: '0' on Success; Error code otherwise. 1218 */ 1219 int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io, 1220 uint32_t cmd_flags, 1221 uint16_t token) 1222 { 1223 struct mc_command cmd = { 0 }; 1224 1225 /* prepare command */ 1226 cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_VLAN_FILTERS, 1227 cmd_flags, 1228 token); 1229 1230 /* send command to mc*/ 1231 return mc_send_command(mc_io, &cmd); 1232 } 1233 1234 /** 1235 * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration 1236 * @mc_io: Pointer to MC portal's I/O object 1237 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1238 * @token: Token of DPNI object 1239 * @tc_id: Traffic class selection (0-7) 1240 * @cfg: Traffic class distribution configuration 1241 * 1242 * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpkg_prepare_key_cfg() 1243 * first to prepare the key_cfg_iova parameter 1244 * 1245 * Return: '0' on Success; error code otherwise. 1246 */ 1247 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io, 1248 uint32_t cmd_flags, 1249 uint16_t token, 1250 uint8_t tc_id, 1251 const struct dpni_rx_tc_dist_cfg *cfg) 1252 { 1253 struct mc_command cmd = { 0 }; 1254 struct dpni_cmd_set_rx_tc_dist *cmd_params; 1255 1256 /* prepare command */ 1257 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST, 1258 cmd_flags, 1259 token); 1260 cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params; 1261 cmd_params->dist_size = cpu_to_le16(cfg->dist_size); 1262 cmd_params->tc_id = tc_id; 1263 cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id); 1264 cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); 1265 dpni_set_field(cmd_params->flags, 1266 DIST_MODE, 1267 cfg->dist_mode); 1268 dpni_set_field(cmd_params->flags, 1269 MISS_ACTION, 1270 cfg->fs_cfg.miss_action); 1271 dpni_set_field(cmd_params->keep_hash_key, 1272 KEEP_HASH_KEY, 1273 cfg->fs_cfg.keep_hash_key); 1274 1275 /* send command to mc*/ 1276 return mc_send_command(mc_io, &cmd); 1277 } 1278 1279 /** 1280 * dpni_set_tx_confirmation_mode() - Tx confirmation mode 1281 * @mc_io: Pointer to MC portal's I/O object 1282 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1283 * @token: Token of DPNI object 1284 * @mode: Tx confirmation mode 1285 * 1286 * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not 1287 * selected at DPNI creation. 1288 * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all 1289 * transmit confirmation (including the private confirmation queues), regardless 1290 * of previous settings; Note that in this case, Tx error frames are still 1291 * enqueued to the general transmit errors queue. 1292 * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all 1293 * Tx confirmations to a shared Tx conf queue. 'index' field in dpni_get_queue 1294 * command will be ignored. 1295 * 1296 * Return: '0' on Success; Error code otherwise. 1297 */ 1298 int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io, 1299 uint32_t cmd_flags, 1300 uint16_t token, 1301 enum dpni_confirmation_mode mode) 1302 { 1303 struct dpni_tx_confirmation_mode *cmd_params; 1304 struct mc_command cmd = { 0 }; 1305 1306 /* prepare command */ 1307 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE, 1308 cmd_flags, 1309 token); 1310 cmd_params = (struct dpni_tx_confirmation_mode *)cmd.params; 1311 cmd_params->confirmation_mode = mode; 1312 1313 /* send command to mc*/ 1314 return mc_send_command(mc_io, &cmd); 1315 } 1316 1317 /** 1318 * dpni_set_congestion_notification() - Set traffic class congestion 1319 * notification configuration 1320 * @mc_io: Pointer to MC portal's I/O object 1321 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1322 * @token: Token of DPNI object 1323 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported 1324 * @tc_id: Traffic class selection (0-7) 1325 * @cfg: congestion notification configuration 1326 * 1327 * Return: '0' on Success; error code otherwise. 1328 */ 1329 int dpni_set_congestion_notification(struct fsl_mc_io *mc_io, 1330 uint32_t cmd_flags, 1331 uint16_t token, 1332 enum dpni_queue_type qtype, 1333 uint8_t tc_id, 1334 const struct dpni_congestion_notification_cfg *cfg) 1335 { 1336 struct dpni_cmd_set_congestion_notification *cmd_params; 1337 struct mc_command cmd = { 0 }; 1338 1339 /* prepare command */ 1340 cmd.header = mc_encode_cmd_header( 1341 DPNI_CMDID_SET_CONGESTION_NOTIFICATION, 1342 cmd_flags, 1343 token); 1344 cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params; 1345 cmd_params->qtype = qtype; 1346 cmd_params->tc = tc_id; 1347 cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); 1348 cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode); 1349 cmd_params->dest_priority = cfg->dest_cfg.priority; 1350 cmd_params->message_iova = cpu_to_le64(cfg->message_iova); 1351 cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx); 1352 cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry); 1353 cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit); 1354 dpni_set_field(cmd_params->type_units, 1355 DEST_TYPE, 1356 cfg->dest_cfg.dest_type); 1357 dpni_set_field(cmd_params->type_units, 1358 CONG_UNITS, 1359 cfg->units); 1360 1361 /* send command to mc*/ 1362 return mc_send_command(mc_io, &cmd); 1363 } 1364 1365 /** 1366 * dpni_get_congestion_notification() - Get traffic class congestion 1367 * notification configuration 1368 * @mc_io: Pointer to MC portal's I/O object 1369 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1370 * @token: Token of DPNI object 1371 * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported 1372 * @tc_id: Traffic class selection (0-7) 1373 * @cfg: congestion notification configuration 1374 * 1375 * Return: '0' on Success; error code otherwise. 1376 */ 1377 int dpni_get_congestion_notification(struct fsl_mc_io *mc_io, 1378 uint32_t cmd_flags, 1379 uint16_t token, 1380 enum dpni_queue_type qtype, 1381 uint8_t tc_id, 1382 struct dpni_congestion_notification_cfg *cfg) 1383 { 1384 struct dpni_rsp_get_congestion_notification *rsp_params; 1385 struct dpni_cmd_get_congestion_notification *cmd_params; 1386 struct mc_command cmd = { 0 }; 1387 int err; 1388 1389 /* prepare command */ 1390 cmd.header = mc_encode_cmd_header( 1391 DPNI_CMDID_GET_CONGESTION_NOTIFICATION, 1392 cmd_flags, 1393 token); 1394 cmd_params = (struct dpni_cmd_get_congestion_notification *)cmd.params; 1395 cmd_params->qtype = qtype; 1396 cmd_params->tc = tc_id; 1397 1398 /* send command to mc*/ 1399 err = mc_send_command(mc_io, &cmd); 1400 if (err) 1401 return err; 1402 1403 rsp_params = (struct dpni_rsp_get_congestion_notification *)cmd.params; 1404 cfg->units = dpni_get_field(rsp_params->type_units, CONG_UNITS); 1405 cfg->threshold_entry = le32_to_cpu(rsp_params->threshold_entry); 1406 cfg->threshold_exit = le32_to_cpu(rsp_params->threshold_exit); 1407 cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx); 1408 cfg->message_iova = le64_to_cpu(rsp_params->message_iova); 1409 cfg->notification_mode = le16_to_cpu(rsp_params->notification_mode); 1410 cfg->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id); 1411 cfg->dest_cfg.priority = rsp_params->dest_priority; 1412 cfg->dest_cfg.dest_type = dpni_get_field(rsp_params->type_units, 1413 DEST_TYPE); 1414 1415 return 0; 1416 } 1417 1418 /** 1419 * dpni_get_api_version() - Get Data Path Network Interface API version 1420 * @mc_io: Pointer to MC portal's I/O object 1421 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1422 * @major_ver: Major version of data path network interface API 1423 * @minor_ver: Minor version of data path network interface API 1424 * 1425 * Return: '0' on Success; Error code otherwise. 1426 */ 1427 int dpni_get_api_version(struct fsl_mc_io *mc_io, 1428 uint32_t cmd_flags, 1429 uint16_t *major_ver, 1430 uint16_t *minor_ver) 1431 { 1432 struct dpni_rsp_get_api_version *rsp_params; 1433 struct mc_command cmd = { 0 }; 1434 int err; 1435 1436 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION, 1437 cmd_flags, 1438 0); 1439 1440 err = mc_send_command(mc_io, &cmd); 1441 if (err) 1442 return err; 1443 1444 rsp_params = (struct dpni_rsp_get_api_version *)cmd.params; 1445 *major_ver = le16_to_cpu(rsp_params->major); 1446 *minor_ver = le16_to_cpu(rsp_params->minor); 1447 1448 return 0; 1449 } 1450 1451 /** 1452 * dpni_set_queue() - Set queue parameters 1453 * @mc_io: Pointer to MC portal's I/O object 1454 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1455 * @token: Token of DPNI object 1456 * @qtype: Type of queue - all queue types are supported, although 1457 * the command is ignored for Tx 1458 * @tc: Traffic class, in range 0 to NUM_TCS - 1 1459 * @index: Selects the specific queue out of the set allocated for the 1460 * same TC. Value must be in range 0 to NUM_QUEUES - 1 1461 * @options: A combination of DPNI_QUEUE_OPT_ values that control what 1462 * configuration options are set on the queue 1463 * @queue: Queue structure 1464 * 1465 * Return: '0' on Success; Error code otherwise. 1466 */ 1467 int dpni_set_queue(struct fsl_mc_io *mc_io, 1468 uint32_t cmd_flags, 1469 uint16_t token, 1470 enum dpni_queue_type qtype, 1471 uint8_t tc, 1472 uint8_t index, 1473 uint8_t options, 1474 const struct dpni_queue *queue) 1475 { 1476 struct mc_command cmd = { 0 }; 1477 struct dpni_cmd_set_queue *cmd_params; 1478 1479 /* prepare command */ 1480 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE, 1481 cmd_flags, 1482 token); 1483 cmd_params = (struct dpni_cmd_set_queue *)cmd.params; 1484 cmd_params->qtype = qtype; 1485 cmd_params->tc = tc; 1486 cmd_params->index = index; 1487 cmd_params->options = options; 1488 cmd_params->dest_id = cpu_to_le32(queue->destination.id); 1489 cmd_params->dest_prio = queue->destination.priority; 1490 dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type); 1491 dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control); 1492 dpni_set_field(cmd_params->flags, HOLD_ACTIVE, 1493 queue->destination.hold_active); 1494 cmd_params->flc = cpu_to_le64(queue->flc.value); 1495 cmd_params->user_context = cpu_to_le64(queue->user_context); 1496 1497 /* send command to mc */ 1498 return mc_send_command(mc_io, &cmd); 1499 } 1500 1501 /** 1502 * dpni_get_queue() - Get queue parameters 1503 * @mc_io: Pointer to MC portal's I/O object 1504 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1505 * @token: Token of DPNI object 1506 * @qtype: Type of queue - all queue types are supported 1507 * @tc: Traffic class, in range 0 to NUM_TCS - 1 1508 * @index: Selects the specific queue out of the set allocated for the 1509 * same TC. Value must be in range 0 to NUM_QUEUES - 1 1510 * @queue: Queue configuration structure 1511 * @qid: Queue identification 1512 * 1513 * Return: '0' on Success; Error code otherwise. 1514 */ 1515 int dpni_get_queue(struct fsl_mc_io *mc_io, 1516 uint32_t cmd_flags, 1517 uint16_t token, 1518 enum dpni_queue_type qtype, 1519 uint8_t tc, 1520 uint8_t index, 1521 struct dpni_queue *queue, 1522 struct dpni_queue_id *qid) 1523 { 1524 struct mc_command cmd = { 0 }; 1525 struct dpni_cmd_get_queue *cmd_params; 1526 struct dpni_rsp_get_queue *rsp_params; 1527 int err; 1528 1529 /* prepare command */ 1530 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE, 1531 cmd_flags, 1532 token); 1533 cmd_params = (struct dpni_cmd_get_queue *)cmd.params; 1534 cmd_params->qtype = qtype; 1535 cmd_params->tc = tc; 1536 cmd_params->index = index; 1537 1538 /* send command to mc */ 1539 err = mc_send_command(mc_io, &cmd); 1540 if (err) 1541 return err; 1542 1543 /* retrieve response parameters */ 1544 rsp_params = (struct dpni_rsp_get_queue *)cmd.params; 1545 queue->destination.id = le32_to_cpu(rsp_params->dest_id); 1546 queue->destination.priority = rsp_params->dest_prio; 1547 queue->destination.type = dpni_get_field(rsp_params->flags, 1548 DEST_TYPE); 1549 queue->flc.stash_control = dpni_get_field(rsp_params->flags, 1550 STASH_CTRL); 1551 queue->destination.hold_active = dpni_get_field(rsp_params->flags, 1552 HOLD_ACTIVE); 1553 queue->flc.value = le64_to_cpu(rsp_params->flc); 1554 queue->user_context = le64_to_cpu(rsp_params->user_context); 1555 qid->fqid = le32_to_cpu(rsp_params->fqid); 1556 qid->qdbin = le16_to_cpu(rsp_params->qdbin); 1557 1558 return 0; 1559 } 1560 1561 /** 1562 * dpni_get_statistics() - Get DPNI statistics 1563 * @mc_io: Pointer to MC portal's I/O object 1564 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1565 * @token: Token of DPNI object 1566 * @page: Selects the statistics page to retrieve, see 1567 * DPNI_GET_STATISTICS output. Pages are numbered 0 to 2. 1568 * @param: Custom parameter for some pages used to select 1569 * a certain statistic source, for example the TC. 1570 * @stat: Structure containing the statistics 1571 * 1572 * Return: '0' on Success; Error code otherwise. 1573 */ 1574 int dpni_get_statistics(struct fsl_mc_io *mc_io, 1575 uint32_t cmd_flags, 1576 uint16_t token, 1577 uint8_t page, 1578 uint8_t param, 1579 union dpni_statistics *stat) 1580 { 1581 struct mc_command cmd = { 0 }; 1582 struct dpni_cmd_get_statistics *cmd_params; 1583 struct dpni_rsp_get_statistics *rsp_params; 1584 int i, err; 1585 1586 /* prepare command */ 1587 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS, 1588 cmd_flags, 1589 token); 1590 cmd_params = (struct dpni_cmd_get_statistics *)cmd.params; 1591 cmd_params->page_number = page; 1592 cmd_params->param = param; 1593 1594 /* send command to mc */ 1595 err = mc_send_command(mc_io, &cmd); 1596 if (err) 1597 return err; 1598 1599 /* retrieve response parameters */ 1600 rsp_params = (struct dpni_rsp_get_statistics *)cmd.params; 1601 for (i = 0; i < DPNI_STATISTICS_CNT; i++) 1602 stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]); 1603 1604 return 0; 1605 } 1606 1607 /** 1608 * dpni_reset_statistics() - Clears DPNI statistics 1609 * @mc_io: Pointer to MC portal's I/O object 1610 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1611 * @token: Token of DPNI object 1612 * 1613 * Return: '0' on Success; Error code otherwise. 1614 */ 1615 int dpni_reset_statistics(struct fsl_mc_io *mc_io, 1616 uint32_t cmd_flags, 1617 uint16_t token) 1618 { 1619 struct mc_command cmd = { 0 }; 1620 1621 /* prepare command */ 1622 cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS, 1623 cmd_flags, 1624 token); 1625 1626 /* send command to mc*/ 1627 return mc_send_command(mc_io, &cmd); 1628 } 1629 1630 /** 1631 * dpni_set_taildrop() - Set taildrop per queue or TC 1632 * 1633 * Setting a per-TC taildrop (cg_point = DPNI_CP_GROUP) will reset any current 1634 * congestion notification or early drop (WRED) configuration previously applied 1635 * to the same TC. 1636 * 1637 * @mc_io: Pointer to MC portal's I/O object 1638 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1639 * @token: Token of DPNI object 1640 * @cg_point: Congestion point, DPNI_CP_QUEUE is only supported in 1641 * combination with DPNI_QUEUE_RX. 1642 * @q_type: Queue type, can be DPNI_QUEUE_RX or DPNI_QUEUE_TX. 1643 * @tc: Traffic class to apply this taildrop to 1644 * @q_index: Index of the queue if the DPNI supports multiple queues for 1645 * traffic distribution. 1646 * Ignored if CONGESTION_POINT is not DPNI_CP_QUEUE. 1647 * @taildrop: Taildrop structure 1648 * 1649 * Return: '0' on Success; Error code otherwise. 1650 */ 1651 int dpni_set_taildrop(struct fsl_mc_io *mc_io, 1652 uint32_t cmd_flags, 1653 uint16_t token, 1654 enum dpni_congestion_point cg_point, 1655 enum dpni_queue_type qtype, 1656 uint8_t tc, 1657 uint8_t index, 1658 struct dpni_taildrop *taildrop) 1659 { 1660 struct mc_command cmd = { 0 }; 1661 struct dpni_cmd_set_taildrop *cmd_params; 1662 1663 /* prepare command */ 1664 cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP, 1665 cmd_flags, 1666 token); 1667 cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params; 1668 cmd_params->congestion_point = cg_point; 1669 cmd_params->qtype = qtype; 1670 cmd_params->tc = tc; 1671 cmd_params->index = index; 1672 cmd_params->units = taildrop->units; 1673 cmd_params->threshold = cpu_to_le32(taildrop->threshold); 1674 dpni_set_field(cmd_params->enable_oal_lo, ENABLE, taildrop->enable); 1675 dpni_set_field(cmd_params->enable_oal_lo, OAL_LO, taildrop->oal); 1676 dpni_set_field(cmd_params->oal_hi, 1677 OAL_HI, 1678 taildrop->oal >> DPNI_OAL_LO_SIZE); 1679 1680 /* send command to mc */ 1681 return mc_send_command(mc_io, &cmd); 1682 } 1683 1684 /** 1685 * dpni_get_taildrop() - Get taildrop information 1686 * @mc_io: Pointer to MC portal's I/O object 1687 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1688 * @token: Token of DPNI object 1689 * @cg_point: Congestion point 1690 * @q_type: Queue type on which the taildrop is configured. 1691 * Only Rx queues are supported for now 1692 * @tc: Traffic class to apply this taildrop to 1693 * @q_index: Index of the queue if the DPNI supports multiple queues for 1694 * traffic distribution. Ignored if CONGESTION_POINT is not 0. 1695 * @taildrop: Taildrop structure 1696 * 1697 * Return: '0' on Success; Error code otherwise. 1698 */ 1699 int dpni_get_taildrop(struct fsl_mc_io *mc_io, 1700 uint32_t cmd_flags, 1701 uint16_t token, 1702 enum dpni_congestion_point cg_point, 1703 enum dpni_queue_type qtype, 1704 uint8_t tc, 1705 uint8_t index, 1706 struct dpni_taildrop *taildrop) 1707 { 1708 struct mc_command cmd = { 0 }; 1709 struct dpni_cmd_get_taildrop *cmd_params; 1710 struct dpni_rsp_get_taildrop *rsp_params; 1711 uint8_t oal_lo, oal_hi; 1712 int err; 1713 1714 /* prepare command */ 1715 cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP, 1716 cmd_flags, 1717 token); 1718 cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params; 1719 cmd_params->congestion_point = cg_point; 1720 cmd_params->qtype = qtype; 1721 cmd_params->tc = tc; 1722 cmd_params->index = index; 1723 1724 /* send command to mc */ 1725 err = mc_send_command(mc_io, &cmd); 1726 if (err) 1727 return err; 1728 1729 /* retrieve response parameters */ 1730 rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params; 1731 taildrop->enable = dpni_get_field(rsp_params->enable_oal_lo, ENABLE); 1732 taildrop->units = rsp_params->units; 1733 taildrop->threshold = le32_to_cpu(rsp_params->threshold); 1734 oal_lo = dpni_get_field(rsp_params->enable_oal_lo, OAL_LO); 1735 oal_hi = dpni_get_field(rsp_params->oal_hi, OAL_HI); 1736 taildrop->oal = oal_hi << DPNI_OAL_LO_SIZE | oal_lo; 1737 1738 /* Fill the first 4 bits, 'oal' is a 2's complement value of 12 bits */ 1739 if (taildrop->oal >= 0x0800) 1740 taildrop->oal |= 0xF000; 1741 1742 return 0; 1743 } 1744