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