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