linux/drivers/net/ethernet/freescale/dpaa2/dpni.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
   2/* Copyright 2013-2016 Freescale Semiconductor Inc.
   3 * Copyright 2016 NXP
   4 * Copyright 2020 NXP
   5 */
   6#include <linux/kernel.h>
   7#include <linux/errno.h>
   8#include <linux/fsl/mc.h>
   9#include "dpni.h"
  10#include "dpni-cmd.h"
  11
  12/**
  13 * dpni_prepare_key_cfg() - function prepare extract parameters
  14 * @cfg: defining a full Key Generation profile (rule)
  15 * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
  16 *
  17 * This function has to be called before the following functions:
  18 *      - dpni_set_rx_tc_dist()
  19 *      - dpni_set_qos_table()
  20 */
  21int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg, u8 *key_cfg_buf)
  22{
  23        int i, j;
  24        struct dpni_ext_set_rx_tc_dist *dpni_ext;
  25        struct dpni_dist_extract *extr;
  26
  27        if (cfg->num_extracts > DPKG_MAX_NUM_OF_EXTRACTS)
  28                return -EINVAL;
  29
  30        dpni_ext = (struct dpni_ext_set_rx_tc_dist *)key_cfg_buf;
  31        dpni_ext->num_extracts = cfg->num_extracts;
  32
  33        for (i = 0; i < cfg->num_extracts; i++) {
  34                extr = &dpni_ext->extracts[i];
  35
  36                switch (cfg->extracts[i].type) {
  37                case DPKG_EXTRACT_FROM_HDR:
  38                        extr->prot = cfg->extracts[i].extract.from_hdr.prot;
  39                        dpni_set_field(extr->efh_type, EFH_TYPE,
  40                                       cfg->extracts[i].extract.from_hdr.type);
  41                        extr->size = cfg->extracts[i].extract.from_hdr.size;
  42                        extr->offset = cfg->extracts[i].extract.from_hdr.offset;
  43                        extr->field = cpu_to_le32(
  44                                cfg->extracts[i].extract.from_hdr.field);
  45                        extr->hdr_index =
  46                                cfg->extracts[i].extract.from_hdr.hdr_index;
  47                        break;
  48                case DPKG_EXTRACT_FROM_DATA:
  49                        extr->size = cfg->extracts[i].extract.from_data.size;
  50                        extr->offset =
  51                                cfg->extracts[i].extract.from_data.offset;
  52                        break;
  53                case DPKG_EXTRACT_FROM_PARSE:
  54                        extr->size = cfg->extracts[i].extract.from_parse.size;
  55                        extr->offset =
  56                                cfg->extracts[i].extract.from_parse.offset;
  57                        break;
  58                default:
  59                        return -EINVAL;
  60                }
  61
  62                extr->num_of_byte_masks = cfg->extracts[i].num_of_byte_masks;
  63                dpni_set_field(extr->extract_type, EXTRACT_TYPE,
  64                               cfg->extracts[i].type);
  65
  66                for (j = 0; j < DPKG_NUM_OF_MASKS; j++) {
  67                        extr->masks[j].mask = cfg->extracts[i].masks[j].mask;
  68                        extr->masks[j].offset =
  69                                cfg->extracts[i].masks[j].offset;
  70                }
  71        }
  72
  73        return 0;
  74}
  75
  76/**
  77 * dpni_open() - Open a control session for the specified object
  78 * @mc_io:      Pointer to MC portal's I/O object
  79 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
  80 * @dpni_id:    DPNI unique ID
  81 * @token:      Returned token; use in subsequent API calls
  82 *
  83 * This function can be used to open a control session for an
  84 * already created object; an object may have been declared in
  85 * the DPL or by calling the dpni_create() function.
  86 * This function returns a unique authentication token,
  87 * associated with the specific object ID and the specific MC
  88 * portal; this token must be used in all subsequent commands for
  89 * this specific object.
  90 *
  91 * Return:      '0' on Success; Error code otherwise.
  92 */
  93int dpni_open(struct fsl_mc_io *mc_io,
  94              u32 cmd_flags,
  95              int dpni_id,
  96              u16 *token)
  97{
  98        struct fsl_mc_command cmd = { 0 };
  99        struct dpni_cmd_open *cmd_params;
 100
 101        int err;
 102
 103        /* prepare command */
 104        cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
 105                                          cmd_flags,
 106                                          0);
 107        cmd_params = (struct dpni_cmd_open *)cmd.params;
 108        cmd_params->dpni_id = cpu_to_le32(dpni_id);
 109
 110        /* send command to mc*/
 111        err = mc_send_command(mc_io, &cmd);
 112        if (err)
 113                return err;
 114
 115        /* retrieve response parameters */
 116        *token = mc_cmd_hdr_read_token(&cmd);
 117
 118        return 0;
 119}
 120
 121/**
 122 * dpni_close() - Close the control session of the object
 123 * @mc_io:      Pointer to MC portal's I/O object
 124 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 125 * @token:      Token of DPNI object
 126 *
 127 * After this function is called, no further operations are
 128 * allowed on the object without opening a new control session.
 129 *
 130 * Return:      '0' on Success; Error code otherwise.
 131 */
 132int dpni_close(struct fsl_mc_io *mc_io,
 133               u32 cmd_flags,
 134               u16 token)
 135{
 136        struct fsl_mc_command cmd = { 0 };
 137
 138        /* prepare command */
 139        cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
 140                                          cmd_flags,
 141                                          token);
 142
 143        /* send command to mc*/
 144        return mc_send_command(mc_io, &cmd);
 145}
 146
 147/**
 148 * dpni_set_pools() - Set buffer pools configuration
 149 * @mc_io:      Pointer to MC portal's I/O object
 150 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 151 * @token:      Token of DPNI object
 152 * @cfg:        Buffer pools configuration
 153 *
 154 * mandatory for DPNI operation
 155 * warning:Allowed only when DPNI is disabled
 156 *
 157 * Return:      '0' on Success; Error code otherwise.
 158 */
 159int dpni_set_pools(struct fsl_mc_io *mc_io,
 160                   u32 cmd_flags,
 161                   u16 token,
 162                   const struct dpni_pools_cfg *cfg)
 163{
 164        struct fsl_mc_command cmd = { 0 };
 165        struct dpni_cmd_set_pools *cmd_params;
 166        int i;
 167
 168        /* prepare command */
 169        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
 170                                          cmd_flags,
 171                                          token);
 172        cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
 173        cmd_params->num_dpbp = cfg->num_dpbp;
 174        for (i = 0; i < DPNI_MAX_DPBP; i++) {
 175                cmd_params->dpbp_id[i] = cpu_to_le32(cfg->pools[i].dpbp_id);
 176                cmd_params->buffer_size[i] =
 177                        cpu_to_le16(cfg->pools[i].buffer_size);
 178                cmd_params->backup_pool_mask |=
 179                        DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i);
 180        }
 181
 182        /* send command to mc*/
 183        return mc_send_command(mc_io, &cmd);
 184}
 185
 186/**
 187 * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
 188 * @mc_io:      Pointer to MC portal's I/O object
 189 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 190 * @token:              Token of DPNI object
 191 *
 192 * Return:      '0' on Success; Error code otherwise.
 193 */
 194int dpni_enable(struct fsl_mc_io *mc_io,
 195                u32 cmd_flags,
 196                u16 token)
 197{
 198        struct fsl_mc_command cmd = { 0 };
 199
 200        /* prepare command */
 201        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
 202                                          cmd_flags,
 203                                          token);
 204
 205        /* send command to mc*/
 206        return mc_send_command(mc_io, &cmd);
 207}
 208
 209/**
 210 * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
 211 * @mc_io:      Pointer to MC portal's I/O object
 212 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 213 * @token:      Token of DPNI object
 214 *
 215 * Return:      '0' on Success; Error code otherwise.
 216 */
 217int dpni_disable(struct fsl_mc_io *mc_io,
 218                 u32 cmd_flags,
 219                 u16 token)
 220{
 221        struct fsl_mc_command cmd = { 0 };
 222
 223        /* prepare command */
 224        cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
 225                                          cmd_flags,
 226                                          token);
 227
 228        /* send command to mc*/
 229        return mc_send_command(mc_io, &cmd);
 230}
 231
 232/**
 233 * dpni_is_enabled() - Check if the DPNI is enabled.
 234 * @mc_io:      Pointer to MC portal's I/O object
 235 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 236 * @token:      Token of DPNI object
 237 * @en:         Returns '1' if object is enabled; '0' otherwise
 238 *
 239 * Return:      '0' on Success; Error code otherwise.
 240 */
 241int dpni_is_enabled(struct fsl_mc_io *mc_io,
 242                    u32 cmd_flags,
 243                    u16 token,
 244                    int *en)
 245{
 246        struct fsl_mc_command cmd = { 0 };
 247        struct dpni_rsp_is_enabled *rsp_params;
 248        int err;
 249
 250        /* prepare command */
 251        cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED,
 252                                          cmd_flags,
 253                                          token);
 254
 255        /* send command to mc*/
 256        err = mc_send_command(mc_io, &cmd);
 257        if (err)
 258                return err;
 259
 260        /* retrieve response parameters */
 261        rsp_params = (struct dpni_rsp_is_enabled *)cmd.params;
 262        *en = dpni_get_field(rsp_params->enabled, ENABLE);
 263
 264        return 0;
 265}
 266
 267/**
 268 * dpni_reset() - Reset the DPNI, returns the object to initial state.
 269 * @mc_io:      Pointer to MC portal's I/O object
 270 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 271 * @token:      Token of DPNI object
 272 *
 273 * Return:      '0' on Success; Error code otherwise.
 274 */
 275int dpni_reset(struct fsl_mc_io *mc_io,
 276               u32 cmd_flags,
 277               u16 token)
 278{
 279        struct fsl_mc_command cmd = { 0 };
 280
 281        /* prepare command */
 282        cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
 283                                          cmd_flags,
 284                                          token);
 285
 286        /* send command to mc*/
 287        return mc_send_command(mc_io, &cmd);
 288}
 289
 290/**
 291 * dpni_set_irq_enable() - Set overall interrupt state.
 292 * @mc_io:      Pointer to MC portal's I/O object
 293 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 294 * @token:      Token of DPNI object
 295 * @irq_index:  The interrupt index to configure
 296 * @en:         Interrupt state: - enable = 1, disable = 0
 297 *
 298 * Allows GPP software to control when interrupts are generated.
 299 * Each interrupt can have up to 32 causes.  The enable/disable control's the
 300 * overall interrupt state. if the interrupt is disabled no causes will cause
 301 * an interrupt.
 302 *
 303 * Return:      '0' on Success; Error code otherwise.
 304 */
 305int dpni_set_irq_enable(struct fsl_mc_io *mc_io,
 306                        u32 cmd_flags,
 307                        u16 token,
 308                        u8 irq_index,
 309                        u8 en)
 310{
 311        struct fsl_mc_command cmd = { 0 };
 312        struct dpni_cmd_set_irq_enable *cmd_params;
 313
 314        /* prepare command */
 315        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_ENABLE,
 316                                          cmd_flags,
 317                                          token);
 318        cmd_params = (struct dpni_cmd_set_irq_enable *)cmd.params;
 319        dpni_set_field(cmd_params->enable, ENABLE, en);
 320        cmd_params->irq_index = irq_index;
 321
 322        /* send command to mc*/
 323        return mc_send_command(mc_io, &cmd);
 324}
 325
 326/**
 327 * dpni_get_irq_enable() - Get 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:         Returned interrupt state - enable = 1, disable = 0
 333 *
 334 * Return:      '0' on Success; Error code otherwise.
 335 */
 336int dpni_get_irq_enable(struct fsl_mc_io *mc_io,
 337                        u32 cmd_flags,
 338                        u16 token,
 339                        u8 irq_index,
 340                        u8 *en)
 341{
 342        struct fsl_mc_command cmd = { 0 };
 343        struct dpni_cmd_get_irq_enable *cmd_params;
 344        struct dpni_rsp_get_irq_enable *rsp_params;
 345
 346        int err;
 347
 348        /* prepare command */
 349        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_ENABLE,
 350                                          cmd_flags,
 351                                          token);
 352        cmd_params = (struct dpni_cmd_get_irq_enable *)cmd.params;
 353        cmd_params->irq_index = irq_index;
 354
 355        /* send command to mc*/
 356        err = mc_send_command(mc_io, &cmd);
 357        if (err)
 358                return err;
 359
 360        /* retrieve response parameters */
 361        rsp_params = (struct dpni_rsp_get_irq_enable *)cmd.params;
 362        *en = dpni_get_field(rsp_params->enabled, ENABLE);
 363
 364        return 0;
 365}
 366
 367/**
 368 * dpni_set_irq_mask() - Set interrupt mask.
 369 * @mc_io:      Pointer to MC portal's I/O object
 370 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 371 * @token:      Token of DPNI object
 372 * @irq_index:  The interrupt index to configure
 373 * @mask:       event mask to trigger interrupt;
 374 *                      each bit:
 375 *                              0 = ignore event
 376 *                              1 = consider event for asserting IRQ
 377 *
 378 * Every interrupt can have up to 32 causes and the interrupt model supports
 379 * masking/unmasking each cause independently
 380 *
 381 * Return:      '0' on Success; Error code otherwise.
 382 */
 383int dpni_set_irq_mask(struct fsl_mc_io *mc_io,
 384                      u32 cmd_flags,
 385                      u16 token,
 386                      u8 irq_index,
 387                      u32 mask)
 388{
 389        struct fsl_mc_command cmd = { 0 };
 390        struct dpni_cmd_set_irq_mask *cmd_params;
 391
 392        /* prepare command */
 393        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_MASK,
 394                                          cmd_flags,
 395                                          token);
 396        cmd_params = (struct dpni_cmd_set_irq_mask *)cmd.params;
 397        cmd_params->mask = cpu_to_le32(mask);
 398        cmd_params->irq_index = irq_index;
 399
 400        /* send command to mc*/
 401        return mc_send_command(mc_io, &cmd);
 402}
 403
 404/**
 405 * dpni_get_irq_mask() - Get interrupt mask.
 406 * @mc_io:      Pointer to MC portal's I/O object
 407 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 408 * @token:      Token of DPNI object
 409 * @irq_index:  The interrupt index to configure
 410 * @mask:       Returned event mask to trigger interrupt
 411 *
 412 * Every interrupt can have up to 32 causes and the interrupt model supports
 413 * masking/unmasking each cause independently
 414 *
 415 * Return:      '0' on Success; Error code otherwise.
 416 */
 417int dpni_get_irq_mask(struct fsl_mc_io *mc_io,
 418                      u32 cmd_flags,
 419                      u16 token,
 420                      u8 irq_index,
 421                      u32 *mask)
 422{
 423        struct fsl_mc_command cmd = { 0 };
 424        struct dpni_cmd_get_irq_mask *cmd_params;
 425        struct dpni_rsp_get_irq_mask *rsp_params;
 426        int err;
 427
 428        /* prepare command */
 429        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_MASK,
 430                                          cmd_flags,
 431                                          token);
 432        cmd_params = (struct dpni_cmd_get_irq_mask *)cmd.params;
 433        cmd_params->irq_index = irq_index;
 434
 435        /* send command to mc*/
 436        err = mc_send_command(mc_io, &cmd);
 437        if (err)
 438                return err;
 439
 440        /* retrieve response parameters */
 441        rsp_params = (struct dpni_rsp_get_irq_mask *)cmd.params;
 442        *mask = le32_to_cpu(rsp_params->mask);
 443
 444        return 0;
 445}
 446
 447/**
 448 * dpni_get_irq_status() - Get the current status of any pending interrupts.
 449 * @mc_io:      Pointer to MC portal's I/O object
 450 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 451 * @token:      Token of DPNI object
 452 * @irq_index:  The interrupt index to configure
 453 * @status:     Returned interrupts status - one bit per cause:
 454 *                      0 = no interrupt pending
 455 *                      1 = interrupt pending
 456 *
 457 * Return:      '0' on Success; Error code otherwise.
 458 */
 459int dpni_get_irq_status(struct fsl_mc_io *mc_io,
 460                        u32 cmd_flags,
 461                        u16 token,
 462                        u8 irq_index,
 463                        u32 *status)
 464{
 465        struct fsl_mc_command cmd = { 0 };
 466        struct dpni_cmd_get_irq_status *cmd_params;
 467        struct dpni_rsp_get_irq_status *rsp_params;
 468        int err;
 469
 470        /* prepare command */
 471        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_STATUS,
 472                                          cmd_flags,
 473                                          token);
 474        cmd_params = (struct dpni_cmd_get_irq_status *)cmd.params;
 475        cmd_params->status = cpu_to_le32(*status);
 476        cmd_params->irq_index = irq_index;
 477
 478        /* send command to mc*/
 479        err = mc_send_command(mc_io, &cmd);
 480        if (err)
 481                return err;
 482
 483        /* retrieve response parameters */
 484        rsp_params = (struct dpni_rsp_get_irq_status *)cmd.params;
 485        *status = le32_to_cpu(rsp_params->status);
 486
 487        return 0;
 488}
 489
 490/**
 491 * dpni_clear_irq_status() - Clear a pending interrupt's status
 492 * @mc_io:      Pointer to MC portal's I/O object
 493 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 494 * @token:      Token of DPNI object
 495 * @irq_index:  The interrupt index to configure
 496 * @status:     bits to clear (W1C) - one bit per cause:
 497 *                      0 = don't change
 498 *                      1 = clear status bit
 499 *
 500 * Return:      '0' on Success; Error code otherwise.
 501 */
 502int dpni_clear_irq_status(struct fsl_mc_io *mc_io,
 503                          u32 cmd_flags,
 504                          u16 token,
 505                          u8 irq_index,
 506                          u32 status)
 507{
 508        struct fsl_mc_command cmd = { 0 };
 509        struct dpni_cmd_clear_irq_status *cmd_params;
 510
 511        /* prepare command */
 512        cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLEAR_IRQ_STATUS,
 513                                          cmd_flags,
 514                                          token);
 515        cmd_params = (struct dpni_cmd_clear_irq_status *)cmd.params;
 516        cmd_params->irq_index = irq_index;
 517        cmd_params->status = cpu_to_le32(status);
 518
 519        /* send command to mc*/
 520        return mc_send_command(mc_io, &cmd);
 521}
 522
 523/**
 524 * dpni_get_attributes() - Retrieve DPNI attributes.
 525 * @mc_io:      Pointer to MC portal's I/O object
 526 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 527 * @token:      Token of DPNI object
 528 * @attr:       Object's attributes
 529 *
 530 * Return:      '0' on Success; Error code otherwise.
 531 */
 532int dpni_get_attributes(struct fsl_mc_io *mc_io,
 533                        u32 cmd_flags,
 534                        u16 token,
 535                        struct dpni_attr *attr)
 536{
 537        struct fsl_mc_command cmd = { 0 };
 538        struct dpni_rsp_get_attr *rsp_params;
 539
 540        int err;
 541
 542        /* prepare command */
 543        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
 544                                          cmd_flags,
 545                                          token);
 546
 547        /* send command to mc*/
 548        err = mc_send_command(mc_io, &cmd);
 549        if (err)
 550                return err;
 551
 552        /* retrieve response parameters */
 553        rsp_params = (struct dpni_rsp_get_attr *)cmd.params;
 554        attr->options = le32_to_cpu(rsp_params->options);
 555        attr->num_queues = rsp_params->num_queues;
 556        attr->num_tcs = rsp_params->num_tcs;
 557        attr->mac_filter_entries = rsp_params->mac_filter_entries;
 558        attr->vlan_filter_entries = rsp_params->vlan_filter_entries;
 559        attr->qos_entries = rsp_params->qos_entries;
 560        attr->fs_entries = le16_to_cpu(rsp_params->fs_entries);
 561        attr->qos_key_size = rsp_params->qos_key_size;
 562        attr->fs_key_size = rsp_params->fs_key_size;
 563        attr->wriop_version = le16_to_cpu(rsp_params->wriop_version);
 564
 565        return 0;
 566}
 567
 568/**
 569 * dpni_set_errors_behavior() - Set errors behavior
 570 * @mc_io:      Pointer to MC portal's I/O object
 571 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 572 * @token:      Token of DPNI object
 573 * @cfg:        Errors configuration
 574 *
 575 * this function may be called numerous times with different
 576 * error masks
 577 *
 578 * Return:      '0' on Success; Error code otherwise.
 579 */
 580int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
 581                             u32 cmd_flags,
 582                             u16 token,
 583                             struct dpni_error_cfg *cfg)
 584{
 585        struct fsl_mc_command cmd = { 0 };
 586        struct dpni_cmd_set_errors_behavior *cmd_params;
 587
 588        /* prepare command */
 589        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
 590                                          cmd_flags,
 591                                          token);
 592        cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params;
 593        cmd_params->errors = cpu_to_le32(cfg->errors);
 594        dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action);
 595        dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation);
 596
 597        /* send command to mc*/
 598        return mc_send_command(mc_io, &cmd);
 599}
 600
 601/**
 602 * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
 603 * @mc_io:      Pointer to MC portal's I/O object
 604 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 605 * @token:      Token of DPNI object
 606 * @qtype:      Type of queue to retrieve configuration for
 607 * @layout:     Returns buffer layout attributes
 608 *
 609 * Return:      '0' on Success; Error code otherwise.
 610 */
 611int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
 612                           u32 cmd_flags,
 613                           u16 token,
 614                           enum dpni_queue_type qtype,
 615                           struct dpni_buffer_layout *layout)
 616{
 617        struct fsl_mc_command cmd = { 0 };
 618        struct dpni_cmd_get_buffer_layout *cmd_params;
 619        struct dpni_rsp_get_buffer_layout *rsp_params;
 620        int err;
 621
 622        /* prepare command */
 623        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
 624                                          cmd_flags,
 625                                          token);
 626        cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params;
 627        cmd_params->qtype = qtype;
 628
 629        /* send command to mc*/
 630        err = mc_send_command(mc_io, &cmd);
 631        if (err)
 632                return err;
 633
 634        /* retrieve response parameters */
 635        rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params;
 636        layout->pass_timestamp = dpni_get_field(rsp_params->flags, PASS_TS);
 637        layout->pass_parser_result = dpni_get_field(rsp_params->flags, PASS_PR);
 638        layout->pass_frame_status = dpni_get_field(rsp_params->flags, PASS_FS);
 639        layout->private_data_size = le16_to_cpu(rsp_params->private_data_size);
 640        layout->data_align = le16_to_cpu(rsp_params->data_align);
 641        layout->data_head_room = le16_to_cpu(rsp_params->head_room);
 642        layout->data_tail_room = le16_to_cpu(rsp_params->tail_room);
 643
 644        return 0;
 645}
 646
 647/**
 648 * dpni_set_buffer_layout() - Set buffer layout configuration.
 649 * @mc_io:      Pointer to MC portal's I/O object
 650 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 651 * @token:      Token of DPNI object
 652 * @qtype:      Type of queue this configuration applies to
 653 * @layout:     Buffer layout configuration
 654 *
 655 * Return:      '0' on Success; Error code otherwise.
 656 *
 657 * @warning     Allowed only when DPNI is disabled
 658 */
 659int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
 660                           u32 cmd_flags,
 661                           u16 token,
 662                           enum dpni_queue_type qtype,
 663                           const struct dpni_buffer_layout *layout)
 664{
 665        struct fsl_mc_command cmd = { 0 };
 666        struct dpni_cmd_set_buffer_layout *cmd_params;
 667
 668        /* prepare command */
 669        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
 670                                          cmd_flags,
 671                                          token);
 672        cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params;
 673        cmd_params->qtype = qtype;
 674        cmd_params->options = cpu_to_le16(layout->options);
 675        dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp);
 676        dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result);
 677        dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status);
 678        cmd_params->private_data_size = cpu_to_le16(layout->private_data_size);
 679        cmd_params->data_align = cpu_to_le16(layout->data_align);
 680        cmd_params->head_room = cpu_to_le16(layout->data_head_room);
 681        cmd_params->tail_room = cpu_to_le16(layout->data_tail_room);
 682
 683        /* send command to mc*/
 684        return mc_send_command(mc_io, &cmd);
 685}
 686
 687/**
 688 * dpni_set_offload() - Set DPNI offload configuration.
 689 * @mc_io:      Pointer to MC portal's I/O object
 690 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 691 * @token:      Token of DPNI object
 692 * @type:       Type of DPNI offload
 693 * @config:     Offload configuration.
 694 *              For checksum offloads, non-zero value enables the offload
 695 *
 696 * Return:     '0' on Success; Error code otherwise.
 697 *
 698 * @warning    Allowed only when DPNI is disabled
 699 */
 700
 701int dpni_set_offload(struct fsl_mc_io *mc_io,
 702                     u32 cmd_flags,
 703                     u16 token,
 704                     enum dpni_offload type,
 705                     u32 config)
 706{
 707        struct fsl_mc_command cmd = { 0 };
 708        struct dpni_cmd_set_offload *cmd_params;
 709
 710        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
 711                                          cmd_flags,
 712                                          token);
 713        cmd_params = (struct dpni_cmd_set_offload *)cmd.params;
 714        cmd_params->dpni_offload = type;
 715        cmd_params->config = cpu_to_le32(config);
 716
 717        return mc_send_command(mc_io, &cmd);
 718}
 719
 720int dpni_get_offload(struct fsl_mc_io *mc_io,
 721                     u32 cmd_flags,
 722                     u16 token,
 723                     enum dpni_offload type,
 724                     u32 *config)
 725{
 726        struct fsl_mc_command cmd = { 0 };
 727        struct dpni_cmd_get_offload *cmd_params;
 728        struct dpni_rsp_get_offload *rsp_params;
 729        int err;
 730
 731        /* prepare command */
 732        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
 733                                          cmd_flags,
 734                                          token);
 735        cmd_params = (struct dpni_cmd_get_offload *)cmd.params;
 736        cmd_params->dpni_offload = type;
 737
 738        /* send command to mc*/
 739        err = mc_send_command(mc_io, &cmd);
 740        if (err)
 741                return err;
 742
 743        /* retrieve response parameters */
 744        rsp_params = (struct dpni_rsp_get_offload *)cmd.params;
 745        *config = le32_to_cpu(rsp_params->config);
 746
 747        return 0;
 748}
 749
 750/**
 751 * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
 752 *                      for enqueue operations
 753 * @mc_io:      Pointer to MC portal's I/O object
 754 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 755 * @token:      Token of DPNI object
 756 * @qtype:      Type of queue to receive QDID for
 757 * @qdid:       Returned virtual QDID value that should be used as an argument
 758 *                      in all enqueue operations
 759 *
 760 * Return:      '0' on Success; Error code otherwise.
 761 */
 762int dpni_get_qdid(struct fsl_mc_io *mc_io,
 763                  u32 cmd_flags,
 764                  u16 token,
 765                  enum dpni_queue_type qtype,
 766                  u16 *qdid)
 767{
 768        struct fsl_mc_command cmd = { 0 };
 769        struct dpni_cmd_get_qdid *cmd_params;
 770        struct dpni_rsp_get_qdid *rsp_params;
 771        int err;
 772
 773        /* prepare command */
 774        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
 775                                          cmd_flags,
 776                                          token);
 777        cmd_params = (struct dpni_cmd_get_qdid *)cmd.params;
 778        cmd_params->qtype = qtype;
 779
 780        /* send command to mc*/
 781        err = mc_send_command(mc_io, &cmd);
 782        if (err)
 783                return err;
 784
 785        /* retrieve response parameters */
 786        rsp_params = (struct dpni_rsp_get_qdid *)cmd.params;
 787        *qdid = le16_to_cpu(rsp_params->qdid);
 788
 789        return 0;
 790}
 791
 792/**
 793 * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
 794 * @mc_io:      Pointer to MC portal's I/O object
 795 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 796 * @token:      Token of DPNI object
 797 * @data_offset: Tx data offset (from start of buffer)
 798 *
 799 * Return:      '0' on Success; Error code otherwise.
 800 */
 801int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
 802                            u32 cmd_flags,
 803                            u16 token,
 804                            u16 *data_offset)
 805{
 806        struct fsl_mc_command cmd = { 0 };
 807        struct dpni_rsp_get_tx_data_offset *rsp_params;
 808        int err;
 809
 810        /* prepare command */
 811        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
 812                                          cmd_flags,
 813                                          token);
 814
 815        /* send command to mc*/
 816        err = mc_send_command(mc_io, &cmd);
 817        if (err)
 818                return err;
 819
 820        /* retrieve response parameters */
 821        rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params;
 822        *data_offset = le16_to_cpu(rsp_params->data_offset);
 823
 824        return 0;
 825}
 826
 827/**
 828 * dpni_set_link_cfg() - set the link configuration.
 829 * @mc_io:      Pointer to MC portal's I/O object
 830 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 831 * @token:      Token of DPNI object
 832 * @cfg:        Link configuration
 833 *
 834 * Return:      '0' on Success; Error code otherwise.
 835 */
 836int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
 837                      u32 cmd_flags,
 838                      u16 token,
 839                      const struct dpni_link_cfg *cfg)
 840{
 841        struct fsl_mc_command cmd = { 0 };
 842        struct dpni_cmd_link_cfg *cmd_params;
 843
 844        /* prepare command */
 845        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
 846                                          cmd_flags,
 847                                          token);
 848        cmd_params = (struct dpni_cmd_link_cfg *)cmd.params;
 849        cmd_params->rate = cpu_to_le32(cfg->rate);
 850        cmd_params->options = cpu_to_le64(cfg->options);
 851
 852        /* send command to mc*/
 853        return mc_send_command(mc_io, &cmd);
 854}
 855
 856/**
 857 * dpni_get_link_cfg() - return the link configuration
 858 * @mc_io:      Pointer to MC portal's I/O object
 859 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 860 * @token:      Token of DPNI object
 861 * @cfg:        Link configuration from dpni object
 862 *
 863 * Return:      '0' on Success; Error code otherwise.
 864 */
 865int dpni_get_link_cfg(struct fsl_mc_io *mc_io,
 866                      u32 cmd_flags,
 867                      u16 token,
 868                      struct dpni_link_cfg *cfg)
 869{
 870        struct fsl_mc_command cmd = { 0 };
 871        struct dpni_cmd_link_cfg *rsp_params;
 872        int err;
 873
 874        /* prepare command */
 875        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG,
 876                                          cmd_flags,
 877                                          token);
 878
 879        /* send command to mc*/
 880        err = mc_send_command(mc_io, &cmd);
 881        if (err)
 882                return err;
 883
 884        /* retrieve response parameters */
 885        rsp_params = (struct dpni_cmd_link_cfg *)cmd.params;
 886        cfg->rate = le32_to_cpu(rsp_params->rate);
 887        cfg->options = le64_to_cpu(rsp_params->options);
 888
 889        return err;
 890}
 891
 892/**
 893 * dpni_get_link_state() - Return the link state (either up or down)
 894 * @mc_io:      Pointer to MC portal's I/O object
 895 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
 896 * @token:      Token of DPNI object
 897 * @state:      Returned link state;
 898 *
 899 * Return:      '0' on Success; Error code otherwise.
 900 */
 901int dpni_get_link_state(struct fsl_mc_io *mc_io,
 902                        u32 cmd_flags,
 903                        u16 token,
 904                        struct dpni_link_state *state)
 905{
 906        struct fsl_mc_command cmd = { 0 };
 907        struct dpni_rsp_get_link_state *rsp_params;
 908        int err;
 909
 910        /* prepare command */
 911        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
 912                                          cmd_flags,
 913                                          token);
 914
 915        /* send command to mc*/
 916        err = mc_send_command(mc_io, &cmd);
 917        if (err)
 918                return err;
 919
 920        /* retrieve response parameters */
 921        rsp_params = (struct dpni_rsp_get_link_state *)cmd.params;
 922        state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
 923        state->rate = le32_to_cpu(rsp_params->rate);
 924        state->options = le64_to_cpu(rsp_params->options);
 925
 926        return 0;
 927}
 928
 929/**
 930 * dpni_set_max_frame_length() - Set the maximum received frame length.
 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 * @max_frame_length:   Maximum received frame length (in
 935 *                              bytes); frame is discarded if its
 936 *                              length exceeds this value
 937 *
 938 * Return:      '0' on Success; Error code otherwise.
 939 */
 940int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
 941                              u32 cmd_flags,
 942                              u16 token,
 943                              u16 max_frame_length)
 944{
 945        struct fsl_mc_command cmd = { 0 };
 946        struct dpni_cmd_set_max_frame_length *cmd_params;
 947
 948        /* prepare command */
 949        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
 950                                          cmd_flags,
 951                                          token);
 952        cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params;
 953        cmd_params->max_frame_length = cpu_to_le16(max_frame_length);
 954
 955        /* send command to mc*/
 956        return mc_send_command(mc_io, &cmd);
 957}
 958
 959/**
 960 * dpni_get_max_frame_length() - Get the maximum received frame length.
 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 * @max_frame_length:   Maximum received frame length (in
 965 *                              bytes); frame is discarded if its
 966 *                              length exceeds this value
 967 *
 968 * Return:      '0' on Success; Error code otherwise.
 969 */
 970int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
 971                              u32 cmd_flags,
 972                              u16 token,
 973                              u16 *max_frame_length)
 974{
 975        struct fsl_mc_command cmd = { 0 };
 976        struct dpni_rsp_get_max_frame_length *rsp_params;
 977        int err;
 978
 979        /* prepare command */
 980        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
 981                                          cmd_flags,
 982                                          token);
 983
 984        /* send command to mc*/
 985        err = mc_send_command(mc_io, &cmd);
 986        if (err)
 987                return err;
 988
 989        /* retrieve response parameters */
 990        rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params;
 991        *max_frame_length = le16_to_cpu(rsp_params->max_frame_length);
 992
 993        return 0;
 994}
 995
 996/**
 997 * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode
 998 * @mc_io:      Pointer to MC portal's I/O object
 999 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1000 * @token:      Token of DPNI object
1001 * @en:         Set to '1' to enable; '0' to disable
1002 *
1003 * Return:      '0' on Success; Error code otherwise.
1004 */
1005int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
1006                               u32 cmd_flags,
1007                               u16 token,
1008                               int en)
1009{
1010        struct fsl_mc_command cmd = { 0 };
1011        struct dpni_cmd_set_multicast_promisc *cmd_params;
1012
1013        /* prepare command */
1014        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC,
1015                                          cmd_flags,
1016                                          token);
1017        cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params;
1018        dpni_set_field(cmd_params->enable, ENABLE, en);
1019
1020        /* send command to mc*/
1021        return mc_send_command(mc_io, &cmd);
1022}
1023
1024/**
1025 * dpni_get_multicast_promisc() - Get multicast promiscuous mode
1026 * @mc_io:      Pointer to MC portal's I/O object
1027 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1028 * @token:      Token of DPNI object
1029 * @en:         Returns '1' if enabled; '0' otherwise
1030 *
1031 * Return:      '0' on Success; Error code otherwise.
1032 */
1033int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
1034                               u32 cmd_flags,
1035                               u16 token,
1036                               int *en)
1037{
1038        struct fsl_mc_command cmd = { 0 };
1039        struct dpni_rsp_get_multicast_promisc *rsp_params;
1040        int err;
1041
1042        /* prepare command */
1043        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC,
1044                                          cmd_flags,
1045                                          token);
1046
1047        /* send command to mc*/
1048        err = mc_send_command(mc_io, &cmd);
1049        if (err)
1050                return err;
1051
1052        /* retrieve response parameters */
1053        rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params;
1054        *en = dpni_get_field(rsp_params->enabled, ENABLE);
1055
1056        return 0;
1057}
1058
1059/**
1060 * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
1061 * @mc_io:      Pointer to MC portal's I/O object
1062 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1063 * @token:      Token of DPNI object
1064 * @en:         Set to '1' to enable; '0' to disable
1065 *
1066 * Return:      '0' on Success; Error code otherwise.
1067 */
1068int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
1069                             u32 cmd_flags,
1070                             u16 token,
1071                             int en)
1072{
1073        struct fsl_mc_command cmd = { 0 };
1074        struct dpni_cmd_set_unicast_promisc *cmd_params;
1075
1076        /* prepare command */
1077        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
1078                                          cmd_flags,
1079                                          token);
1080        cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params;
1081        dpni_set_field(cmd_params->enable, ENABLE, en);
1082
1083        /* send command to mc*/
1084        return mc_send_command(mc_io, &cmd);
1085}
1086
1087/**
1088 * dpni_get_unicast_promisc() - Get unicast promiscuous mode
1089 * @mc_io:      Pointer to MC portal's I/O object
1090 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1091 * @token:      Token of DPNI object
1092 * @en:         Returns '1' if enabled; '0' otherwise
1093 *
1094 * Return:      '0' on Success; Error code otherwise.
1095 */
1096int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
1097                             u32 cmd_flags,
1098                             u16 token,
1099                             int *en)
1100{
1101        struct fsl_mc_command cmd = { 0 };
1102        struct dpni_rsp_get_unicast_promisc *rsp_params;
1103        int err;
1104
1105        /* prepare command */
1106        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
1107                                          cmd_flags,
1108                                          token);
1109
1110        /* send command to mc*/
1111        err = mc_send_command(mc_io, &cmd);
1112        if (err)
1113                return err;
1114
1115        /* retrieve response parameters */
1116        rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params;
1117        *en = dpni_get_field(rsp_params->enabled, ENABLE);
1118
1119        return 0;
1120}
1121
1122/**
1123 * dpni_set_primary_mac_addr() - Set the primary MAC address
1124 * @mc_io:      Pointer to MC portal's I/O object
1125 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1126 * @token:      Token of DPNI object
1127 * @mac_addr:   MAC address to set as primary address
1128 *
1129 * Return:      '0' on Success; Error code otherwise.
1130 */
1131int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
1132                              u32 cmd_flags,
1133                              u16 token,
1134                              const u8 mac_addr[6])
1135{
1136        struct fsl_mc_command cmd = { 0 };
1137        struct dpni_cmd_set_primary_mac_addr *cmd_params;
1138        int i;
1139
1140        /* prepare command */
1141        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
1142                                          cmd_flags,
1143                                          token);
1144        cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params;
1145        for (i = 0; i < 6; i++)
1146                cmd_params->mac_addr[i] = mac_addr[5 - i];
1147
1148        /* send command to mc*/
1149        return mc_send_command(mc_io, &cmd);
1150}
1151
1152/**
1153 * dpni_get_primary_mac_addr() - Get the primary MAC address
1154 * @mc_io:      Pointer to MC portal's I/O object
1155 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1156 * @token:      Token of DPNI object
1157 * @mac_addr:   Returned MAC address
1158 *
1159 * Return:      '0' on Success; Error code otherwise.
1160 */
1161int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
1162                              u32 cmd_flags,
1163                              u16 token,
1164                              u8 mac_addr[6])
1165{
1166        struct fsl_mc_command cmd = { 0 };
1167        struct dpni_rsp_get_primary_mac_addr *rsp_params;
1168        int i, err;
1169
1170        /* prepare command */
1171        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
1172                                          cmd_flags,
1173                                          token);
1174
1175        /* send command to mc*/
1176        err = mc_send_command(mc_io, &cmd);
1177        if (err)
1178                return err;
1179
1180        /* retrieve response parameters */
1181        rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params;
1182        for (i = 0; i < 6; i++)
1183                mac_addr[5 - i] = rsp_params->mac_addr[i];
1184
1185        return 0;
1186}
1187
1188/**
1189 * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
1190 *                      port the DPNI is attached to
1191 * @mc_io:      Pointer to MC portal's I/O object
1192 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1193 * @token:      Token of DPNI object
1194 * @mac_addr:   MAC address of the physical port, if any, otherwise 0
1195 *
1196 * The primary MAC address is not cleared by this operation.
1197 *
1198 * Return:      '0' on Success; Error code otherwise.
1199 */
1200int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
1201                           u32 cmd_flags,
1202                           u16 token,
1203                           u8 mac_addr[6])
1204{
1205        struct fsl_mc_command cmd = { 0 };
1206        struct dpni_rsp_get_port_mac_addr *rsp_params;
1207        int i, err;
1208
1209        /* prepare command */
1210        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
1211                                          cmd_flags,
1212                                          token);
1213
1214        /* send command to mc*/
1215        err = mc_send_command(mc_io, &cmd);
1216        if (err)
1217                return err;
1218
1219        /* retrieve response parameters */
1220        rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params;
1221        for (i = 0; i < 6; i++)
1222                mac_addr[5 - i] = rsp_params->mac_addr[i];
1223
1224        return 0;
1225}
1226
1227/**
1228 * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode
1229 * @mc_io:      Pointer to MC portal's I/O object
1230 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1231 * @token:      Token of DPNI object
1232 * @en:         Set to '1' to enable; '0' to disable
1233 *
1234 * Return:      '0' on Success; Error code otherwise.
1235 */
1236int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io,
1237                            u32 cmd_flags,
1238                            u16 token,
1239                            u32 en)
1240{
1241        struct dpni_cmd_enable_vlan_filter *cmd_params;
1242        struct fsl_mc_command cmd = { 0 };
1243
1244        /* prepare command */
1245        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER,
1246                                          cmd_flags,
1247                                          token);
1248        cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params;
1249        dpni_set_field(cmd_params->en, ENABLE, en);
1250
1251        /* send command to mc*/
1252        return mc_send_command(mc_io, &cmd);
1253}
1254
1255/**
1256 * dpni_add_vlan_id() - Add VLAN ID filter
1257 * @mc_io:      Pointer to MC portal's I/O object
1258 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1259 * @token:      Token of DPNI object
1260 * @vlan_id:    VLAN ID to add
1261 * @flags:   0 - tc_id and flow_id will be ignored.
1262 * Pkt with this vlan_id will be passed to the next
1263 * classification stages
1264 * DPNI_VLAN_SET_QUEUE_ACTION
1265 * Pkt with this vlan_id will be forward directly to
1266 * queue defined by the tc_id and flow_id
1267 *
1268 * @tc_id: Traffic class selection (0-7)
1269 * @flow_id: Selects the specific queue out of the set allocated for the
1270 *           same as tc_id. Value must be in range 0 to NUM_QUEUES - 1
1271 *
1272 * Return:      '0' on Success; Error code otherwise.
1273 */
1274int dpni_add_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1275                     u16 vlan_id, u8 flags, u8 tc_id, u8 flow_id)
1276{
1277        struct dpni_cmd_vlan_id *cmd_params;
1278        struct fsl_mc_command cmd = { 0 };
1279
1280        /* prepare command */
1281        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID,
1282                                          cmd_flags,
1283                                          token);
1284        cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1285        cmd_params->flags = flags;
1286        cmd_params->tc_id = tc_id;
1287        cmd_params->flow_id =  flow_id;
1288        cmd_params->vlan_id = cpu_to_le16(vlan_id);
1289
1290        /* send command to mc*/
1291        return mc_send_command(mc_io, &cmd);
1292}
1293
1294/**
1295 * dpni_remove_vlan_id() - Remove VLAN ID filter
1296 * @mc_io:      Pointer to MC portal's I/O object
1297 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1298 * @token:      Token of DPNI object
1299 * @vlan_id:    VLAN ID to remove
1300 *
1301 * Return:      '0' on Success; Error code otherwise.
1302 */
1303int dpni_remove_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1304                        u16 vlan_id)
1305{
1306        struct dpni_cmd_vlan_id *cmd_params;
1307        struct fsl_mc_command cmd = { 0 };
1308
1309        /* prepare command */
1310        cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID,
1311                                          cmd_flags,
1312                                          token);
1313        cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1314        cmd_params->vlan_id = cpu_to_le16(vlan_id);
1315
1316        /* send command to mc*/
1317        return mc_send_command(mc_io, &cmd);
1318}
1319
1320/**
1321 * dpni_add_mac_addr() - Add MAC address filter
1322 * @mc_io:      Pointer to MC portal's I/O object
1323 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1324 * @token:      Token of DPNI object
1325 * @mac_addr:   MAC address to add
1326 *
1327 * Return:      '0' on Success; Error code otherwise.
1328 */
1329int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
1330                      u32 cmd_flags,
1331                      u16 token,
1332                      const u8 mac_addr[6])
1333{
1334        struct fsl_mc_command cmd = { 0 };
1335        struct dpni_cmd_add_mac_addr *cmd_params;
1336        int i;
1337
1338        /* prepare command */
1339        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
1340                                          cmd_flags,
1341                                          token);
1342        cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params;
1343        for (i = 0; i < 6; i++)
1344                cmd_params->mac_addr[i] = mac_addr[5 - i];
1345
1346        /* send command to mc*/
1347        return mc_send_command(mc_io, &cmd);
1348}
1349
1350/**
1351 * dpni_remove_mac_addr() - Remove MAC address filter
1352 * @mc_io:      Pointer to MC portal's I/O object
1353 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1354 * @token:      Token of DPNI object
1355 * @mac_addr:   MAC address to remove
1356 *
1357 * Return:      '0' on Success; Error code otherwise.
1358 */
1359int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
1360                         u32 cmd_flags,
1361                         u16 token,
1362                         const u8 mac_addr[6])
1363{
1364        struct fsl_mc_command cmd = { 0 };
1365        struct dpni_cmd_remove_mac_addr *cmd_params;
1366        int i;
1367
1368        /* prepare command */
1369        cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
1370                                          cmd_flags,
1371                                          token);
1372        cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params;
1373        for (i = 0; i < 6; i++)
1374                cmd_params->mac_addr[i] = mac_addr[5 - i];
1375
1376        /* send command to mc*/
1377        return mc_send_command(mc_io, &cmd);
1378}
1379
1380/**
1381 * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
1382 * @mc_io:      Pointer to MC portal's I/O object
1383 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1384 * @token:      Token of DPNI object
1385 * @unicast:    Set to '1' to clear unicast addresses
1386 * @multicast:  Set to '1' to clear multicast addresses
1387 *
1388 * The primary MAC address is not cleared by this operation.
1389 *
1390 * Return:      '0' on Success; Error code otherwise.
1391 */
1392int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
1393                           u32 cmd_flags,
1394                           u16 token,
1395                           int unicast,
1396                           int multicast)
1397{
1398        struct fsl_mc_command cmd = { 0 };
1399        struct dpni_cmd_clear_mac_filters *cmd_params;
1400
1401        /* prepare command */
1402        cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
1403                                          cmd_flags,
1404                                          token);
1405        cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params;
1406        dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast);
1407        dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast);
1408
1409        /* send command to mc*/
1410        return mc_send_command(mc_io, &cmd);
1411}
1412
1413/**
1414 * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
1415 * @mc_io:      Pointer to MC portal's I/O object
1416 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1417 * @token:      Token of DPNI object
1418 * @tc_id:      Traffic class selection (0-7)
1419 * @cfg:        Traffic class distribution configuration
1420 *
1421 * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
1422 *                      first to prepare the key_cfg_iova parameter
1423 *
1424 * Return:      '0' on Success; error code otherwise.
1425 */
1426int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
1427                        u32 cmd_flags,
1428                        u16 token,
1429                        u8 tc_id,
1430                        const struct dpni_rx_tc_dist_cfg *cfg)
1431{
1432        struct fsl_mc_command cmd = { 0 };
1433        struct dpni_cmd_set_rx_tc_dist *cmd_params;
1434
1435        /* prepare command */
1436        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
1437                                          cmd_flags,
1438                                          token);
1439        cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params;
1440        cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1441        cmd_params->tc_id = tc_id;
1442        dpni_set_field(cmd_params->flags, DIST_MODE, cfg->dist_mode);
1443        dpni_set_field(cmd_params->flags, MISS_ACTION, cfg->fs_cfg.miss_action);
1444        cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id);
1445        cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1446
1447        /* send command to mc*/
1448        return mc_send_command(mc_io, &cmd);
1449}
1450
1451/**
1452 * dpni_set_congestion_notification() - Set traffic class congestion
1453 *                                      notification configuration
1454 * @mc_io:      Pointer to MC portal's I/O object
1455 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1456 * @token:      Token of DPNI object
1457 * @qtype:      Type of queue - Rx, Tx and Tx confirm types are supported
1458 * @tc_id:      Traffic class selection (0-7)
1459 * @cfg:        Congestion notification configuration
1460 *
1461 * Return:      '0' on Success; error code otherwise.
1462 */
1463int dpni_set_congestion_notification(
1464                        struct fsl_mc_io *mc_io,
1465                        u32 cmd_flags,
1466                        u16 token,
1467                        enum dpni_queue_type qtype,
1468                        u8 tc_id,
1469                        const struct dpni_congestion_notification_cfg *cfg)
1470{
1471        struct dpni_cmd_set_congestion_notification *cmd_params;
1472        struct fsl_mc_command cmd = { 0 };
1473
1474        /* prepare command */
1475        cmd.header =
1476                mc_encode_cmd_header(DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
1477                                     cmd_flags,
1478                                     token);
1479        cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
1480        cmd_params->qtype = qtype;
1481        cmd_params->tc = tc_id;
1482        cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
1483        cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
1484        cmd_params->dest_priority = cfg->dest_cfg.priority;
1485        dpni_set_field(cmd_params->type_units, DEST_TYPE,
1486                       cfg->dest_cfg.dest_type);
1487        dpni_set_field(cmd_params->type_units, CONG_UNITS, cfg->units);
1488        cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
1489        cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
1490        cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
1491        cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
1492
1493        /* send command to mc*/
1494        return mc_send_command(mc_io, &cmd);
1495}
1496
1497/**
1498 * dpni_set_queue() - Set queue parameters
1499 * @mc_io:      Pointer to MC portal's I/O object
1500 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1501 * @token:      Token of DPNI object
1502 * @qtype:      Type of queue - all queue types are supported, although
1503 *              the command is ignored for Tx
1504 * @tc:         Traffic class, in range 0 to NUM_TCS - 1
1505 * @index:      Selects the specific queue out of the set allocated for the
1506 *              same TC. Value must be in range 0 to NUM_QUEUES - 1
1507 * @options:    A combination of DPNI_QUEUE_OPT_ values that control what
1508 *              configuration options are set on the queue
1509 * @queue:      Queue structure
1510 *
1511 * Return:      '0' on Success; Error code otherwise.
1512 */
1513int dpni_set_queue(struct fsl_mc_io *mc_io,
1514                   u32 cmd_flags,
1515                   u16 token,
1516                   enum dpni_queue_type qtype,
1517                   u8 tc,
1518                   u8 index,
1519                   u8 options,
1520                   const struct dpni_queue *queue)
1521{
1522        struct fsl_mc_command cmd = { 0 };
1523        struct dpni_cmd_set_queue *cmd_params;
1524
1525        /* prepare command */
1526        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
1527                                          cmd_flags,
1528                                          token);
1529        cmd_params = (struct dpni_cmd_set_queue *)cmd.params;
1530        cmd_params->qtype = qtype;
1531        cmd_params->tc = tc;
1532        cmd_params->index = index;
1533        cmd_params->options = options;
1534        cmd_params->dest_id = cpu_to_le32(queue->destination.id);
1535        cmd_params->dest_prio = queue->destination.priority;
1536        dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type);
1537        dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control);
1538        dpni_set_field(cmd_params->flags, HOLD_ACTIVE,
1539                       queue->destination.hold_active);
1540        cmd_params->flc = cpu_to_le64(queue->flc.value);
1541        cmd_params->user_context = cpu_to_le64(queue->user_context);
1542
1543        /* send command to mc */
1544        return mc_send_command(mc_io, &cmd);
1545}
1546
1547/**
1548 * dpni_get_queue() - Get queue parameters
1549 * @mc_io:      Pointer to MC portal's I/O object
1550 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1551 * @token:      Token of DPNI object
1552 * @qtype:      Type of queue - all queue types are supported
1553 * @tc:         Traffic class, in range 0 to NUM_TCS - 1
1554 * @index:      Selects the specific queue out of the set allocated for the
1555 *              same TC. Value must be in range 0 to NUM_QUEUES - 1
1556 * @queue:      Queue configuration structure
1557 * @qid:        Queue identification
1558 *
1559 * Return:      '0' on Success; Error code otherwise.
1560 */
1561int dpni_get_queue(struct fsl_mc_io *mc_io,
1562                   u32 cmd_flags,
1563                   u16 token,
1564                   enum dpni_queue_type qtype,
1565                   u8 tc,
1566                   u8 index,
1567                   struct dpni_queue *queue,
1568                   struct dpni_queue_id *qid)
1569{
1570        struct fsl_mc_command cmd = { 0 };
1571        struct dpni_cmd_get_queue *cmd_params;
1572        struct dpni_rsp_get_queue *rsp_params;
1573        int err;
1574
1575        /* prepare command */
1576        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
1577                                          cmd_flags,
1578                                          token);
1579        cmd_params = (struct dpni_cmd_get_queue *)cmd.params;
1580        cmd_params->qtype = qtype;
1581        cmd_params->tc = tc;
1582        cmd_params->index = index;
1583
1584        /* send command to mc */
1585        err = mc_send_command(mc_io, &cmd);
1586        if (err)
1587                return err;
1588
1589        /* retrieve response parameters */
1590        rsp_params = (struct dpni_rsp_get_queue *)cmd.params;
1591        queue->destination.id = le32_to_cpu(rsp_params->dest_id);
1592        queue->destination.priority = rsp_params->dest_prio;
1593        queue->destination.type = dpni_get_field(rsp_params->flags,
1594                                                 DEST_TYPE);
1595        queue->flc.stash_control = dpni_get_field(rsp_params->flags,
1596                                                  STASH_CTRL);
1597        queue->destination.hold_active = dpni_get_field(rsp_params->flags,
1598                                                        HOLD_ACTIVE);
1599        queue->flc.value = le64_to_cpu(rsp_params->flc);
1600        queue->user_context = le64_to_cpu(rsp_params->user_context);
1601        qid->fqid = le32_to_cpu(rsp_params->fqid);
1602        qid->qdbin = le16_to_cpu(rsp_params->qdbin);
1603
1604        return 0;
1605}
1606
1607/**
1608 * dpni_get_statistics() - Get 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 * @page:       Selects the statistics page to retrieve, see
1613 *              DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.
1614 * @stat:       Structure containing the statistics
1615 *
1616 * Return:      '0' on Success; Error code otherwise.
1617 */
1618int dpni_get_statistics(struct fsl_mc_io *mc_io,
1619                        u32 cmd_flags,
1620                        u16 token,
1621                        u8 page,
1622                        union dpni_statistics *stat)
1623{
1624        struct fsl_mc_command cmd = { 0 };
1625        struct dpni_cmd_get_statistics *cmd_params;
1626        struct dpni_rsp_get_statistics *rsp_params;
1627        int i, err;
1628
1629        /* prepare command */
1630        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
1631                                          cmd_flags,
1632                                          token);
1633        cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
1634        cmd_params->page_number = page;
1635
1636        /* send command to mc */
1637        err = mc_send_command(mc_io, &cmd);
1638        if (err)
1639                return err;
1640
1641        /* retrieve response parameters */
1642        rsp_params = (struct dpni_rsp_get_statistics *)cmd.params;
1643        for (i = 0; i < DPNI_STATISTICS_CNT; i++)
1644                stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]);
1645
1646        return 0;
1647}
1648
1649/**
1650 * dpni_set_taildrop() - Set taildrop per queue or TC
1651 * @mc_io:      Pointer to MC portal's I/O object
1652 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1653 * @token:      Token of DPNI object
1654 * @cg_point:   Congestion point
1655 * @qtype:      Queue type on which the taildrop is configured.
1656 *              Only Rx queues are supported for now
1657 * @tc:         Traffic class to apply this taildrop to
1658 * @index:      Index of the queue if the DPNI supports multiple queues for
1659 *              traffic distribution. Ignored if CONGESTION_POINT is not 0.
1660 * @taildrop:   Taildrop structure
1661 *
1662 * Return:      '0' on Success; Error code otherwise.
1663 */
1664int dpni_set_taildrop(struct fsl_mc_io *mc_io,
1665                      u32 cmd_flags,
1666                      u16 token,
1667                      enum dpni_congestion_point cg_point,
1668                      enum dpni_queue_type qtype,
1669                      u8 tc,
1670                      u8 index,
1671                      struct dpni_taildrop *taildrop)
1672{
1673        struct fsl_mc_command cmd = { 0 };
1674        struct dpni_cmd_set_taildrop *cmd_params;
1675
1676        /* prepare command */
1677        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP,
1678                                          cmd_flags,
1679                                          token);
1680        cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params;
1681        cmd_params->congestion_point = cg_point;
1682        cmd_params->qtype = qtype;
1683        cmd_params->tc = tc;
1684        cmd_params->index = index;
1685        dpni_set_field(cmd_params->enable, ENABLE, taildrop->enable);
1686        cmd_params->units = taildrop->units;
1687        cmd_params->threshold = cpu_to_le32(taildrop->threshold);
1688
1689        /* send command to mc */
1690        return mc_send_command(mc_io, &cmd);
1691}
1692
1693/**
1694 * dpni_get_taildrop() - Get taildrop information
1695 * @mc_io:      Pointer to MC portal's I/O object
1696 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1697 * @token:      Token of DPNI object
1698 * @cg_point:   Congestion point
1699 * @qtype:      Queue type on which the taildrop is configured.
1700 *              Only Rx queues are supported for now
1701 * @tc:         Traffic class to apply this taildrop to
1702 * @index:      Index of the queue if the DPNI supports multiple queues for
1703 *              traffic distribution. Ignored if CONGESTION_POINT is not 0.
1704 * @taildrop:   Taildrop structure
1705 *
1706 * Return:      '0' on Success; Error code otherwise.
1707 */
1708int dpni_get_taildrop(struct fsl_mc_io *mc_io,
1709                      u32 cmd_flags,
1710                      u16 token,
1711                      enum dpni_congestion_point cg_point,
1712                      enum dpni_queue_type qtype,
1713                      u8 tc,
1714                      u8 index,
1715                      struct dpni_taildrop *taildrop)
1716{
1717        struct fsl_mc_command cmd = { 0 };
1718        struct dpni_cmd_get_taildrop *cmd_params;
1719        struct dpni_rsp_get_taildrop *rsp_params;
1720        int err;
1721
1722        /* prepare command */
1723        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP,
1724                                          cmd_flags,
1725                                          token);
1726        cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params;
1727        cmd_params->congestion_point = cg_point;
1728        cmd_params->qtype = qtype;
1729        cmd_params->tc = tc;
1730        cmd_params->index = index;
1731
1732        /* send command to mc */
1733        err = mc_send_command(mc_io, &cmd);
1734        if (err)
1735                return err;
1736
1737        /* retrieve response parameters */
1738        rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params;
1739        taildrop->enable = dpni_get_field(rsp_params->enable, ENABLE);
1740        taildrop->units = rsp_params->units;
1741        taildrop->threshold = le32_to_cpu(rsp_params->threshold);
1742
1743        return 0;
1744}
1745
1746/**
1747 * dpni_get_api_version() - Get Data Path Network Interface API version
1748 * @mc_io:      Pointer to MC portal's I/O object
1749 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1750 * @major_ver:  Major version of data path network interface API
1751 * @minor_ver:  Minor version of data path network interface API
1752 *
1753 * Return:      '0' on Success; Error code otherwise.
1754 */
1755int dpni_get_api_version(struct fsl_mc_io *mc_io,
1756                         u32 cmd_flags,
1757                         u16 *major_ver,
1758                         u16 *minor_ver)
1759{
1760        struct dpni_rsp_get_api_version *rsp_params;
1761        struct fsl_mc_command cmd = { 0 };
1762        int err;
1763
1764        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
1765                                          cmd_flags, 0);
1766
1767        err = mc_send_command(mc_io, &cmd);
1768        if (err)
1769                return err;
1770
1771        rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
1772        *major_ver = le16_to_cpu(rsp_params->major);
1773        *minor_ver = le16_to_cpu(rsp_params->minor);
1774
1775        return 0;
1776}
1777
1778/**
1779 * dpni_set_rx_fs_dist() - Set Rx flow steering distribution
1780 * @mc_io:      Pointer to MC portal's I/O object
1781 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1782 * @token:      Token of DPNI object
1783 * @cfg: Distribution configuration
1784 *
1785 * If the FS is already enabled with a previous call the classification
1786 * key will be changed but all the table rules are kept. If the
1787 * existing rules do not match the key the results will not be
1788 * predictable. It is the user responsibility to keep key integrity.
1789 * If cfg.enable is set to 1 the command will create a flow steering table
1790 * and will classify packets according to this table. The packets that
1791 * miss all the table rules will be classified according to settings
1792 * made in dpni_set_rx_hash_dist()
1793 * If cfg.enable is set to 0 the command will clear flow steering table.
1794 * The packets will be classified according to settings made in
1795 * dpni_set_rx_hash_dist()
1796 */
1797int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io,
1798                        u32 cmd_flags,
1799                        u16 token,
1800                        const struct dpni_rx_dist_cfg *cfg)
1801{
1802        struct dpni_cmd_set_rx_fs_dist *cmd_params;
1803        struct fsl_mc_command cmd = { 0 };
1804
1805        /* prepare command */
1806        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST,
1807                                          cmd_flags,
1808                                          token);
1809        cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params;
1810        cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1811        dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
1812        cmd_params->tc = cfg->tc;
1813        cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id);
1814        cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1815
1816        /* send command to mc*/
1817        return mc_send_command(mc_io, &cmd);
1818}
1819
1820/**
1821 * dpni_set_rx_hash_dist() - Set Rx hash distribution
1822 * @mc_io:      Pointer to MC portal's I/O object
1823 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1824 * @token:      Token of DPNI object
1825 * @cfg: Distribution configuration
1826 * If cfg.enable is set to 1 the packets will be classified using a hash
1827 * function based on the key received in cfg.key_cfg_iova parameter.
1828 * If cfg.enable is set to 0 the packets will be sent to the default queue
1829 */
1830int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io,
1831                          u32 cmd_flags,
1832                          u16 token,
1833                          const struct dpni_rx_dist_cfg *cfg)
1834{
1835        struct dpni_cmd_set_rx_hash_dist *cmd_params;
1836        struct fsl_mc_command cmd = { 0 };
1837
1838        /* prepare command */
1839        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST,
1840                                          cmd_flags,
1841                                          token);
1842        cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params;
1843        cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1844        dpni_set_field(cmd_params->enable, RX_HASH_DIST_ENABLE, cfg->enable);
1845        cmd_params->tc = cfg->tc;
1846        cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1847
1848        /* send command to mc*/
1849        return mc_send_command(mc_io, &cmd);
1850}
1851
1852/**
1853 * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
1854 *                      (to select a flow ID)
1855 * @mc_io:      Pointer to MC portal's I/O object
1856 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1857 * @token:      Token of DPNI object
1858 * @tc_id:      Traffic class selection (0-7)
1859 * @index:      Location in the FS table where to insert the entry.
1860 *              Only relevant if MASKING is enabled for FS
1861 *              classification on this DPNI, it is ignored for exact match.
1862 * @cfg:        Flow steering rule to add
1863 * @action:     Action to be taken as result of a classification hit
1864 *
1865 * Return:      '0' on Success; Error code otherwise.
1866 */
1867int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
1868                      u32 cmd_flags,
1869                      u16 token,
1870                      u8 tc_id,
1871                      u16 index,
1872                      const struct dpni_rule_cfg *cfg,
1873                      const struct dpni_fs_action_cfg *action)
1874{
1875        struct dpni_cmd_add_fs_entry *cmd_params;
1876        struct fsl_mc_command cmd = { 0 };
1877
1878        /* prepare command */
1879        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
1880                                          cmd_flags,
1881                                          token);
1882        cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
1883        cmd_params->tc_id = tc_id;
1884        cmd_params->key_size = cfg->key_size;
1885        cmd_params->index = cpu_to_le16(index);
1886        cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1887        cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1888        cmd_params->options = cpu_to_le16(action->options);
1889        cmd_params->flow_id = cpu_to_le16(action->flow_id);
1890        cmd_params->flc = cpu_to_le64(action->flc);
1891
1892        /* send command to mc*/
1893        return mc_send_command(mc_io, &cmd);
1894}
1895
1896/**
1897 * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
1898 *                          traffic class
1899 * @mc_io:      Pointer to MC portal's I/O object
1900 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1901 * @token:      Token of DPNI object
1902 * @tc_id:      Traffic class selection (0-7)
1903 * @cfg:        Flow steering rule to remove
1904 *
1905 * Return:      '0' on Success; Error code otherwise.
1906 */
1907int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
1908                         u32 cmd_flags,
1909                         u16 token,
1910                         u8 tc_id,
1911                         const struct dpni_rule_cfg *cfg)
1912{
1913        struct dpni_cmd_remove_fs_entry *cmd_params;
1914        struct fsl_mc_command cmd = { 0 };
1915
1916        /* prepare command */
1917        cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
1918                                          cmd_flags,
1919                                          token);
1920        cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
1921        cmd_params->tc_id = tc_id;
1922        cmd_params->key_size = cfg->key_size;
1923        cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1924        cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1925
1926        /* send command to mc*/
1927        return mc_send_command(mc_io, &cmd);
1928}
1929
1930/**
1931 * dpni_set_qos_table() - Set QoS mapping table
1932 * @mc_io:      Pointer to MC portal's I/O object
1933 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1934 * @token:      Token of DPNI object
1935 * @cfg:        QoS table configuration
1936 *
1937 * This function and all QoS-related functions require that
1938 *'max_tcs > 1' was set at DPNI creation.
1939 *
1940 * warning: Before calling this function, call dpkg_prepare_key_cfg() to
1941 *                      prepare the key_cfg_iova parameter
1942 *
1943 * Return:      '0' on Success; Error code otherwise.
1944 */
1945int dpni_set_qos_table(struct fsl_mc_io *mc_io,
1946                       u32 cmd_flags,
1947                       u16 token,
1948                       const struct dpni_qos_tbl_cfg *cfg)
1949{
1950        struct dpni_cmd_set_qos_table *cmd_params;
1951        struct fsl_mc_command cmd = { 0 };
1952
1953        /* prepare command */
1954        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL,
1955                                          cmd_flags,
1956                                          token);
1957        cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params;
1958        cmd_params->default_tc = cfg->default_tc;
1959        cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1960        dpni_set_field(cmd_params->discard_on_miss, DISCARD_ON_MISS,
1961                       cfg->discard_on_miss);
1962
1963        /* send command to mc*/
1964        return mc_send_command(mc_io, &cmd);
1965}
1966
1967/**
1968 * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class)
1969 * @mc_io:      Pointer to MC portal's I/O object
1970 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
1971 * @token:      Token of DPNI object
1972 * @cfg:        QoS rule to add
1973 * @tc_id:      Traffic class selection (0-7)
1974 * @index:      Location in the QoS table where to insert the entry.
1975 *              Only relevant if MASKING is enabled for QoS classification on
1976 *              this DPNI, it is ignored for exact match.
1977 *
1978 * Return:      '0' on Success; Error code otherwise.
1979 */
1980int dpni_add_qos_entry(struct fsl_mc_io *mc_io,
1981                       u32 cmd_flags,
1982                       u16 token,
1983                       const struct dpni_rule_cfg *cfg,
1984                       u8 tc_id,
1985                       u16 index)
1986{
1987        struct dpni_cmd_add_qos_entry *cmd_params;
1988        struct fsl_mc_command cmd = { 0 };
1989
1990        /* prepare command */
1991        cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT,
1992                                          cmd_flags,
1993                                          token);
1994        cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params;
1995        cmd_params->tc_id = tc_id;
1996        cmd_params->key_size = cfg->key_size;
1997        cmd_params->index = cpu_to_le16(index);
1998        cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1999        cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2000
2001        /* send command to mc*/
2002        return mc_send_command(mc_io, &cmd);
2003}
2004
2005/**
2006 * dpni_remove_qos_entry() - Remove QoS mapping entry
2007 * @mc_io:      Pointer to MC portal's I/O object
2008 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
2009 * @token:      Token of DPNI object
2010 * @cfg:        QoS rule to remove
2011 *
2012 * Return:      '0' on Success; Error code otherwise.
2013 */
2014int dpni_remove_qos_entry(struct fsl_mc_io *mc_io,
2015                          u32 cmd_flags,
2016                          u16 token,
2017                          const struct dpni_rule_cfg *cfg)
2018{
2019        struct dpni_cmd_remove_qos_entry *cmd_params;
2020        struct fsl_mc_command cmd = { 0 };
2021
2022        /* prepare command */
2023        cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT,
2024                                          cmd_flags,
2025                                          token);
2026        cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params;
2027        cmd_params->key_size = cfg->key_size;
2028        cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
2029        cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2030
2031        /* send command to mc*/
2032        return mc_send_command(mc_io, &cmd);
2033}
2034
2035/**
2036 * dpni_clear_qos_table() - Clear all QoS mapping entries
2037 * @mc_io:      Pointer to MC portal's I/O object
2038 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
2039 * @token:      Token of DPNI object
2040 *
2041 * Following this function call, all frames are directed to
2042 * the default traffic class (0)
2043 *
2044 * Return:      '0' on Success; Error code otherwise.
2045 */
2046int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
2047                         u32 cmd_flags,
2048                         u16 token)
2049{
2050        struct fsl_mc_command cmd = { 0 };
2051
2052        /* prepare command */
2053        cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL,
2054                                          cmd_flags,
2055                                          token);
2056
2057        /* send command to mc*/
2058        return mc_send_command(mc_io, &cmd);
2059}
2060
2061/**
2062 * dpni_set_tx_shaping() - Set the transmit shaping
2063 * @mc_io:              Pointer to MC portal's I/O object
2064 * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
2065 * @token:              Token of DPNI object
2066 * @tx_cr_shaper:       TX committed rate shaping configuration
2067 * @tx_er_shaper:       TX excess rate shaping configuration
2068 * @coupled:            Committed and excess rate shapers are coupled
2069 *
2070 * Return:      '0' on Success; Error code otherwise.
2071 */
2072int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
2073                        u32 cmd_flags,
2074                        u16 token,
2075                        const struct dpni_tx_shaping_cfg *tx_cr_shaper,
2076                        const struct dpni_tx_shaping_cfg *tx_er_shaper,
2077                        int coupled)
2078{
2079        struct dpni_cmd_set_tx_shaping *cmd_params;
2080        struct fsl_mc_command cmd = { 0 };
2081
2082        /* prepare command */
2083        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,
2084                                          cmd_flags,
2085                                          token);
2086        cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;
2087        cmd_params->tx_cr_max_burst_size = cpu_to_le16(tx_cr_shaper->max_burst_size);
2088        cmd_params->tx_er_max_burst_size = cpu_to_le16(tx_er_shaper->max_burst_size);
2089        cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit);
2090        cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit);
2091        dpni_set_field(cmd_params->coupled, COUPLED, coupled);
2092
2093        /* send command to mc*/
2094        return mc_send_command(mc_io, &cmd);
2095}
2096
2097/**
2098 * dpni_get_single_step_cfg() - return current configuration for
2099 *                              single step PTP
2100 * @mc_io:      Pointer to MC portal's I/O object
2101 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
2102 * @token:      Token of DPNI object
2103 * @ptp_cfg:    ptp single step configuration
2104 *
2105 * Return:      '0' on Success; Error code otherwise.
2106 *
2107 */
2108int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
2109                             u32 cmd_flags,
2110                             u16 token,
2111                             struct dpni_single_step_cfg *ptp_cfg)
2112{
2113        struct dpni_rsp_single_step_cfg *rsp_params;
2114        struct fsl_mc_command cmd = { 0 };
2115        int err;
2116
2117        /* prepare command */
2118        cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
2119                                          cmd_flags, token);
2120        /* send command to mc*/
2121        err =  mc_send_command(mc_io, &cmd);
2122        if (err)
2123                return err;
2124
2125        /* read command response */
2126        rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
2127        ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
2128        ptp_cfg->en = dpni_get_field(le16_to_cpu(rsp_params->flags),
2129                                     PTP_ENABLE) ? 1 : 0;
2130        ptp_cfg->ch_update = dpni_get_field(le16_to_cpu(rsp_params->flags),
2131                                            PTP_CH_UPDATE) ? 1 : 0;
2132        ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
2133
2134        return err;
2135}
2136
2137/**
2138 * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
2139 * @mc_io:      Pointer to MC portal's I/O object
2140 * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
2141 * @token:      Token of DPNI object
2142 * @ptp_cfg:    ptp single step configuration
2143 *
2144 * Return:      '0' on Success; Error code otherwise.
2145 *
2146 * The function has effect only when dpni object is connected to a dpmac
2147 * object. If the dpni is not connected to a dpmac the configuration will
2148 * be stored inside and applied when connection is made.
2149 */
2150int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
2151                             u32 cmd_flags,
2152                             u16 token,
2153                             struct dpni_single_step_cfg *ptp_cfg)
2154{
2155        struct dpni_cmd_single_step_cfg *cmd_params;
2156        struct fsl_mc_command cmd = { 0 };
2157        u16 flags;
2158
2159        /* prepare command */
2160        cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
2161                                          cmd_flags, token);
2162        cmd_params = (struct dpni_cmd_single_step_cfg *)cmd.params;
2163        cmd_params->offset = cpu_to_le16(ptp_cfg->offset);
2164        cmd_params->peer_delay = cpu_to_le32(ptp_cfg->peer_delay);
2165
2166        flags = le16_to_cpu(cmd_params->flags);
2167        dpni_set_field(flags, PTP_ENABLE, !!ptp_cfg->en);
2168        dpni_set_field(flags, PTP_CH_UPDATE, !!ptp_cfg->ch_update);
2169        cmd_params->flags = cpu_to_le16(flags);
2170
2171        /* send command to mc*/
2172        return mc_send_command(mc_io, &cmd);
2173}
2174