linux/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2013-2014 Chelsio Communications.  All rights reserved.
   3 *
   4 *  Written by Anish Bhatt (anish@chelsio.com)
   5 *             Casey Leedom (leedom@chelsio.com)
   6 *
   7 *  This program is free software; you can redistribute it and/or modify it
   8 *  under the terms and conditions of the GNU General Public License,
   9 *  version 2, as published by the Free Software Foundation.
  10 *
  11 *  This program is distributed in the hope it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 *  more details.
  15 *
  16 *  The full GNU General Public License is included in this distribution in
  17 *  the file called "COPYING".
  18 *
  19 */
  20
  21#include "cxgb4.h"
  22
  23/* DCBx version control
  24 */
  25const char * const dcb_ver_array[] = {
  26        "Unknown",
  27        "DCBx-CIN",
  28        "DCBx-CEE 1.01",
  29        "DCBx-IEEE",
  30        "", "", "",
  31        "Auto Negotiated"
  32};
  33
  34static inline bool cxgb4_dcb_state_synced(enum cxgb4_dcb_state state)
  35{
  36        if (state == CXGB4_DCB_STATE_FW_ALLSYNCED ||
  37            state == CXGB4_DCB_STATE_HOST)
  38                return true;
  39        else
  40                return false;
  41}
  42
  43/* Initialize a port's Data Center Bridging state.
  44 */
  45void cxgb4_dcb_state_init(struct net_device *dev)
  46{
  47        struct port_info *pi = netdev2pinfo(dev);
  48        struct port_dcb_info *dcb = &pi->dcb;
  49        int version_temp = dcb->dcb_version;
  50
  51        memset(dcb, 0, sizeof(struct port_dcb_info));
  52        dcb->state = CXGB4_DCB_STATE_START;
  53        if (version_temp)
  54                dcb->dcb_version = version_temp;
  55
  56        netdev_dbg(dev, "%s: Initializing DCB state for port[%d]\n",
  57                    __func__, pi->port_id);
  58}
  59
  60void cxgb4_dcb_version_init(struct net_device *dev)
  61{
  62        struct port_info *pi = netdev2pinfo(dev);
  63        struct port_dcb_info *dcb = &pi->dcb;
  64
  65        /* Any writes here are only done on kernels that exlicitly need
  66         * a specific version, say < 2.6.38 which only support CEE
  67         */
  68        dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
  69}
  70
  71static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
  72{
  73        struct port_info *pi = netdev2pinfo(dev);
  74        struct adapter *adap = pi->adapter;
  75        struct port_dcb_info *dcb = &pi->dcb;
  76        struct dcb_app app;
  77        int i, err;
  78
  79        /* zero priority implies remove */
  80        app.priority = 0;
  81
  82        for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
  83                /* Check if app list is exhausted */
  84                if (!dcb->app_priority[i].protocolid)
  85                        break;
  86
  87                app.protocol = dcb->app_priority[i].protocolid;
  88
  89                if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
  90                        app.priority = dcb->app_priority[i].user_prio_map;
  91                        app.selector = dcb->app_priority[i].sel_field + 1;
  92                        err = dcb_ieee_delapp(dev, &app);
  93                } else {
  94                        app.selector = !!(dcb->app_priority[i].sel_field);
  95                        err = dcb_setapp(dev, &app);
  96                }
  97
  98                if (err) {
  99                        dev_err(adap->pdev_dev,
 100                                "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
 101                                dcb_ver_array[dcb->dcb_version], app.selector,
 102                                app.protocol, -err);
 103                        break;
 104                }
 105        }
 106}
 107
 108/* Reset a port's Data Center Bridging state.  Typically used after a
 109 * Link Down event.
 110 */
 111void cxgb4_dcb_reset(struct net_device *dev)
 112{
 113        cxgb4_dcb_cleanup_apps(dev);
 114        cxgb4_dcb_state_init(dev);
 115}
 116
 117/* update the dcb port support, if version is IEEE then set it to
 118 * FW_PORT_DCB_VER_IEEE and if DCB_CAP_DCBX_VER_CEE is already set then
 119 * clear that. and if it is set to CEE then set dcb supported to
 120 * DCB_CAP_DCBX_VER_CEE & if DCB_CAP_DCBX_VER_IEEE is set, clear it
 121 */
 122static inline void cxgb4_dcb_update_support(struct port_dcb_info *dcb)
 123{
 124        if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
 125                if (dcb->supported & DCB_CAP_DCBX_VER_CEE)
 126                        dcb->supported &= ~DCB_CAP_DCBX_VER_CEE;
 127                dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
 128        } else if (dcb->dcb_version == FW_PORT_DCB_VER_CEE1D01) {
 129                if (dcb->supported & DCB_CAP_DCBX_VER_IEEE)
 130                        dcb->supported &= ~DCB_CAP_DCBX_VER_IEEE;
 131                dcb->supported |= DCB_CAP_DCBX_VER_CEE;
 132        }
 133}
 134
 135/* Finite State machine for Data Center Bridging.
 136 */
 137void cxgb4_dcb_state_fsm(struct net_device *dev,
 138                         enum cxgb4_dcb_state_input transition_to)
 139{
 140        struct port_info *pi = netdev2pinfo(dev);
 141        struct port_dcb_info *dcb = &pi->dcb;
 142        struct adapter *adap = pi->adapter;
 143        enum cxgb4_dcb_state current_state = dcb->state;
 144
 145        netdev_dbg(dev, "%s: State change from %d to %d for %s\n",
 146                    __func__, dcb->state, transition_to, dev->name);
 147
 148        switch (current_state) {
 149        case CXGB4_DCB_STATE_START: {
 150                switch (transition_to) {
 151                case CXGB4_DCB_INPUT_FW_DISABLED: {
 152                        /* we're going to use Host DCB */
 153                        dcb->state = CXGB4_DCB_STATE_HOST;
 154                        dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
 155                        break;
 156                }
 157
 158                case CXGB4_DCB_INPUT_FW_ENABLED: {
 159                        /* we're going to use Firmware DCB */
 160                        dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
 161                        dcb->supported = DCB_CAP_DCBX_LLD_MANAGED;
 162                        if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE)
 163                                dcb->supported |= DCB_CAP_DCBX_VER_IEEE;
 164                        else
 165                                dcb->supported |= DCB_CAP_DCBX_VER_CEE;
 166                        break;
 167                }
 168
 169                case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 170                        /* expected transition */
 171                        break;
 172                }
 173
 174                case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 175                        dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
 176                        break;
 177                }
 178
 179                default:
 180                        goto bad_state_input;
 181                }
 182                break;
 183        }
 184
 185        case CXGB4_DCB_STATE_FW_INCOMPLETE: {
 186                if (transition_to != CXGB4_DCB_INPUT_FW_DISABLED) {
 187                        /* during this CXGB4_DCB_STATE_FW_INCOMPLETE state,
 188                         * check if the dcb version is changed (there can be
 189                         * mismatch in default config & the negotiated switch
 190                         * configuration at FW, so update the dcb support
 191                         * accordingly.
 192                         */
 193                        cxgb4_dcb_update_support(dcb);
 194                }
 195                switch (transition_to) {
 196                case CXGB4_DCB_INPUT_FW_ENABLED: {
 197                        /* we're alreaady in firmware DCB mode */
 198                        break;
 199                }
 200
 201                case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 202                        /* we're already incomplete */
 203                        break;
 204                }
 205
 206                case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 207                        dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
 208                        dcb->enabled = 1;
 209                        linkwatch_fire_event(dev);
 210                        break;
 211                }
 212
 213                default:
 214                        goto bad_state_input;
 215                }
 216                break;
 217        }
 218
 219        case CXGB4_DCB_STATE_FW_ALLSYNCED: {
 220                switch (transition_to) {
 221                case CXGB4_DCB_INPUT_FW_ENABLED: {
 222                        /* we're alreaady in firmware DCB mode */
 223                        break;
 224                }
 225
 226                case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
 227                        /* We were successfully running with firmware DCB but
 228                         * now it's telling us that it's in an "incomplete
 229                         * state.  We need to reset back to a ground state
 230                         * of incomplete.
 231                         */
 232                        cxgb4_dcb_reset(dev);
 233                        dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
 234                        dcb->supported = CXGB4_DCBX_FW_SUPPORT;
 235                        linkwatch_fire_event(dev);
 236                        break;
 237                }
 238
 239                case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
 240                        /* we're already all sync'ed
 241                         * this is only applicable for IEEE or
 242                         * when another VI already completed negotiaton
 243                         */
 244                        dcb->enabled = 1;
 245                        linkwatch_fire_event(dev);
 246                        break;
 247                }
 248
 249                default:
 250                        goto bad_state_input;
 251                }
 252                break;
 253        }
 254
 255        case CXGB4_DCB_STATE_HOST: {
 256                switch (transition_to) {
 257                case CXGB4_DCB_INPUT_FW_DISABLED: {
 258                        /* we're alreaady in Host DCB mode */
 259                        break;
 260                }
 261
 262                default:
 263                        goto bad_state_input;
 264                }
 265                break;
 266        }
 267
 268        default:
 269                goto bad_state_transition;
 270        }
 271        return;
 272
 273bad_state_input:
 274        dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
 275                transition_to);
 276        return;
 277
 278bad_state_transition:
 279        dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
 280                current_state, transition_to);
 281}
 282
 283/* Handle a DCB/DCBX update message from the firmware.
 284 */
 285void cxgb4_dcb_handle_fw_update(struct adapter *adap,
 286                                const struct fw_port_cmd *pcmd)
 287{
 288        const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
 289        int port = FW_PORT_CMD_PORTID_G(be32_to_cpu(pcmd->op_to_portid));
 290        struct net_device *dev = adap->port[adap->chan_map[port]];
 291        struct port_info *pi = netdev_priv(dev);
 292        struct port_dcb_info *dcb = &pi->dcb;
 293        int dcb_type = pcmd->u.dcb.pgid.type;
 294        int dcb_running_version;
 295
 296        /* Handle Firmware DCB Control messages separately since they drive
 297         * our state machine.
 298         */
 299        if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
 300                enum cxgb4_dcb_state_input input =
 301                        ((pcmd->u.dcb.control.all_syncd_pkd &
 302                          FW_PORT_CMD_ALL_SYNCD_F)
 303                         ? CXGB4_DCB_INPUT_FW_ALLSYNCED
 304                         : CXGB4_DCB_INPUT_FW_INCOMPLETE);
 305
 306                if (dcb->dcb_version != FW_PORT_DCB_VER_UNKNOWN) {
 307                        dcb_running_version = FW_PORT_CMD_DCB_VERSION_G(
 308                                be16_to_cpu(
 309                                pcmd->u.dcb.control.dcb_version_to_app_state));
 310                        if (dcb_running_version == FW_PORT_DCB_VER_CEE1D01 ||
 311                            dcb_running_version == FW_PORT_DCB_VER_IEEE) {
 312                                dcb->dcb_version = dcb_running_version;
 313                                dev_warn(adap->pdev_dev, "Interface %s is running %s\n",
 314                                         dev->name,
 315                                         dcb_ver_array[dcb->dcb_version]);
 316                        } else {
 317                                dev_warn(adap->pdev_dev,
 318                                         "Something screwed up, requested firmware for %s, but firmware returned %s instead\n",
 319                                         dcb_ver_array[dcb->dcb_version],
 320                                         dcb_ver_array[dcb_running_version]);
 321                                dcb->dcb_version = FW_PORT_DCB_VER_UNKNOWN;
 322                        }
 323                }
 324
 325                cxgb4_dcb_state_fsm(dev, input);
 326                return;
 327        }
 328
 329        /* It's weird, and almost certainly an error, to get Firmware DCB
 330         * messages when we either haven't been told whether we're going to be
 331         * doing Host or Firmware DCB; and even worse when we've been told
 332         * that we're doing Host DCB!
 333         */
 334        if (dcb->state == CXGB4_DCB_STATE_START ||
 335            dcb->state == CXGB4_DCB_STATE_HOST) {
 336                dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
 337                        dcb->state);
 338                return;
 339        }
 340
 341        /* Now handle the general Firmware DCB update messages ...
 342         */
 343        switch (dcb_type) {
 344        case FW_PORT_DCB_TYPE_PGID:
 345                dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
 346                dcb->msgs |= CXGB4_DCB_FW_PGID;
 347                break;
 348
 349        case FW_PORT_DCB_TYPE_PGRATE:
 350                dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
 351                memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
 352                       sizeof(dcb->pgrate));
 353                memcpy(dcb->tsa, &fwdcb->pgrate.tsa,
 354                       sizeof(dcb->tsa));
 355                dcb->msgs |= CXGB4_DCB_FW_PGRATE;
 356                if (dcb->msgs & CXGB4_DCB_FW_PGID)
 357                        IEEE_FAUX_SYNC(dev, dcb);
 358                break;
 359
 360        case FW_PORT_DCB_TYPE_PRIORATE:
 361                memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
 362                       sizeof(dcb->priorate));
 363                dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
 364                break;
 365
 366        case FW_PORT_DCB_TYPE_PFC:
 367                dcb->pfcen = fwdcb->pfc.pfcen;
 368                dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
 369                dcb->msgs |= CXGB4_DCB_FW_PFC;
 370                IEEE_FAUX_SYNC(dev, dcb);
 371                break;
 372
 373        case FW_PORT_DCB_TYPE_APP_ID: {
 374                const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
 375                int idx = fwap->idx;
 376                struct app_priority *ap = &dcb->app_priority[idx];
 377
 378                struct dcb_app app = {
 379                        .protocol = be16_to_cpu(fwap->protocolid),
 380                };
 381                int err;
 382
 383                /* Convert from firmware format to relevant format
 384                 * when using app selector
 385                 */
 386                if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
 387                        app.selector = (fwap->sel_field + 1);
 388                        app.priority = ffs(fwap->user_prio_map) - 1;
 389                        err = dcb_ieee_setapp(dev, &app);
 390                        IEEE_FAUX_SYNC(dev, dcb);
 391                } else {
 392                        /* Default is CEE */
 393                        app.selector = !!(fwap->sel_field);
 394                        app.priority = fwap->user_prio_map;
 395                        err = dcb_setapp(dev, &app);
 396                }
 397
 398                if (err)
 399                        dev_err(adap->pdev_dev,
 400                                "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
 401                                app.selector, app.protocol, app.priority, -err);
 402
 403                ap->user_prio_map = fwap->user_prio_map;
 404                ap->sel_field = fwap->sel_field;
 405                ap->protocolid = be16_to_cpu(fwap->protocolid);
 406                dcb->msgs |= CXGB4_DCB_FW_APP_ID;
 407                break;
 408        }
 409
 410        default:
 411                dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
 412                        dcb_type);
 413                break;
 414        }
 415}
 416
 417/* Data Center Bridging netlink operations.
 418 */
 419
 420
 421/* Get current DCB enabled/disabled state.
 422 */
 423static u8 cxgb4_getstate(struct net_device *dev)
 424{
 425        struct port_info *pi = netdev2pinfo(dev);
 426
 427        return pi->dcb.enabled;
 428}
 429
 430/* Set DCB enabled/disabled.
 431 */
 432static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
 433{
 434        struct port_info *pi = netdev2pinfo(dev);
 435
 436        /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
 437        if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
 438                pi->dcb.enabled = enabled;
 439                return 0;
 440        }
 441
 442        /* Firmware doesn't provide any mechanism to control the DCB state.
 443         */
 444        if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
 445                return 1;
 446
 447        return 0;
 448}
 449
 450static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
 451                             u8 *prio_type, u8 *pgid, u8 *bw_per,
 452                             u8 *up_tc_map, int local)
 453{
 454        struct fw_port_cmd pcmd;
 455        struct port_info *pi = netdev2pinfo(dev);
 456        struct adapter *adap = pi->adapter;
 457        int err;
 458
 459        *prio_type = *pgid = *bw_per = *up_tc_map = 0;
 460
 461        if (local)
 462                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 463        else
 464                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 465
 466        pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 467        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 468        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 469                dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 470                return;
 471        }
 472        *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
 473
 474        if (local)
 475                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 476        else
 477                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 478        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 479        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 480        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 481                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 482                        -err);
 483                return;
 484        }
 485
 486        *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
 487        *up_tc_map = (1 << tc);
 488
 489        /* prio_type is link strict */
 490        if (*pgid != 0xF)
 491                *prio_type = 0x2;
 492}
 493
 494static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
 495                                u8 *prio_type, u8 *pgid, u8 *bw_per,
 496                                u8 *up_tc_map)
 497{
 498        /* tc 0 is written at MSB position */
 499        return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
 500                                up_tc_map, 1);
 501}
 502
 503
 504static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
 505                                u8 *prio_type, u8 *pgid, u8 *bw_per,
 506                                u8 *up_tc_map)
 507{
 508        /* tc 0 is written at MSB position */
 509        return cxgb4_getpgtccfg(dev, (7 - tc), prio_type, pgid, bw_per,
 510                                up_tc_map, 0);
 511}
 512
 513static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
 514                                u8 prio_type, u8 pgid, u8 bw_per,
 515                                u8 up_tc_map)
 516{
 517        struct fw_port_cmd pcmd;
 518        struct port_info *pi = netdev2pinfo(dev);
 519        struct adapter *adap = pi->adapter;
 520        int fw_tc = 7 - tc;
 521        u32 _pgid;
 522        int err;
 523
 524        if (pgid == DCB_ATTR_VALUE_UNDEFINED)
 525                return;
 526        if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
 527                return;
 528
 529        INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 530        pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 531
 532        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 533        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 534                dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 535                return;
 536        }
 537
 538        _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
 539        _pgid &= ~(0xF << (fw_tc * 4));
 540        _pgid |= pgid << (fw_tc * 4);
 541        pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
 542
 543        INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 544
 545        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 546        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 547                dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
 548                        -err);
 549                return;
 550        }
 551
 552        memset(&pcmd, 0, sizeof(struct fw_port_cmd));
 553
 554        INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 555        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 556
 557        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 558        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 559                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 560                        -err);
 561                return;
 562        }
 563
 564        pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
 565
 566        INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 567        if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 568                pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 569
 570        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 571        if (err != FW_PORT_DCB_CFG_SUCCESS)
 572                dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
 573                        -err);
 574}
 575
 576static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
 577                              int local)
 578{
 579        struct fw_port_cmd pcmd;
 580        struct port_info *pi = netdev2pinfo(dev);
 581        struct adapter *adap = pi->adapter;
 582        int err;
 583
 584        if (local)
 585                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 586        else
 587                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 588
 589        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 590        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 591        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 592                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 593                        -err);
 594                return;
 595        }
 596
 597        *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
 598}
 599
 600static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
 601{
 602        return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
 603}
 604
 605static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
 606{
 607        return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
 608}
 609
 610static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
 611                                 u8 bw_per)
 612{
 613        struct fw_port_cmd pcmd;
 614        struct port_info *pi = netdev2pinfo(dev);
 615        struct adapter *adap = pi->adapter;
 616        int err;
 617
 618        INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 619        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 620
 621        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 622        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 623                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 624                        -err);
 625                return;
 626        }
 627
 628        pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
 629
 630        INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 631        if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 632                pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 633
 634        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 635
 636        if (err != FW_PORT_DCB_CFG_SUCCESS)
 637                dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
 638                        -err);
 639}
 640
 641/* Return whether the specified Traffic Class Priority has Priority Pause
 642 * Frames enabled.
 643 */
 644static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
 645{
 646        struct port_info *pi = netdev2pinfo(dev);
 647        struct port_dcb_info *dcb = &pi->dcb;
 648
 649        if (!cxgb4_dcb_state_synced(dcb->state) ||
 650            priority >= CXGB4_MAX_PRIORITY)
 651                *pfccfg = 0;
 652        else
 653                *pfccfg = (pi->dcb.pfcen >> (7 - priority)) & 1;
 654}
 655
 656/* Enable/disable Priority Pause Frames for the specified Traffic Class
 657 * Priority.
 658 */
 659static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
 660{
 661        struct fw_port_cmd pcmd;
 662        struct port_info *pi = netdev2pinfo(dev);
 663        struct adapter *adap = pi->adapter;
 664        int err;
 665
 666        if (!cxgb4_dcb_state_synced(pi->dcb.state) ||
 667            priority >= CXGB4_MAX_PRIORITY)
 668                return;
 669
 670        INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 671        if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 672                pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 673
 674        pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
 675        pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
 676
 677        if (pfccfg)
 678                pcmd.u.dcb.pfc.pfcen |= (1 << (7 - priority));
 679        else
 680                pcmd.u.dcb.pfc.pfcen &= (~(1 << (7 - priority)));
 681
 682        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 683        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 684                dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
 685                return;
 686        }
 687
 688        pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
 689}
 690
 691static u8 cxgb4_setall(struct net_device *dev)
 692{
 693        return 0;
 694}
 695
 696/* Return DCB capabilities.
 697 */
 698static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
 699{
 700        struct port_info *pi = netdev2pinfo(dev);
 701
 702        switch (cap_id) {
 703        case DCB_CAP_ATTR_PG:
 704        case DCB_CAP_ATTR_PFC:
 705                *caps = true;
 706                break;
 707
 708        case DCB_CAP_ATTR_PG_TCS:
 709                /* 8 priorities for PG represented by bitmap */
 710                *caps = 0x80;
 711                break;
 712
 713        case DCB_CAP_ATTR_PFC_TCS:
 714                /* 8 priorities for PFC represented by bitmap */
 715                *caps = 0x80;
 716                break;
 717
 718        case DCB_CAP_ATTR_GSP:
 719                *caps = true;
 720                break;
 721
 722        case DCB_CAP_ATTR_UP2TC:
 723        case DCB_CAP_ATTR_BCN:
 724                *caps = false;
 725                break;
 726
 727        case DCB_CAP_ATTR_DCBX:
 728                *caps = pi->dcb.supported;
 729                break;
 730
 731        default:
 732                *caps = false;
 733        }
 734
 735        return 0;
 736}
 737
 738/* Return the number of Traffic Classes for the indicated Traffic Class ID.
 739 */
 740static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
 741{
 742        struct port_info *pi = netdev2pinfo(dev);
 743
 744        switch (tcs_id) {
 745        case DCB_NUMTCS_ATTR_PG:
 746                if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
 747                        *num = pi->dcb.pg_num_tcs_supported;
 748                else
 749                        *num = 0x8;
 750                break;
 751
 752        case DCB_NUMTCS_ATTR_PFC:
 753                *num = 0x8;
 754                break;
 755
 756        default:
 757                return -EINVAL;
 758        }
 759
 760        return 0;
 761}
 762
 763/* Set the number of Traffic Classes supported for the indicated Traffic Class
 764 * ID.
 765 */
 766static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
 767{
 768        /* Setting the number of Traffic Classes isn't supported.
 769         */
 770        return -ENOSYS;
 771}
 772
 773/* Return whether Priority Flow Control is enabled.  */
 774static u8 cxgb4_getpfcstate(struct net_device *dev)
 775{
 776        struct port_info *pi = netdev2pinfo(dev);
 777
 778        if (!cxgb4_dcb_state_synced(pi->dcb.state))
 779                return false;
 780
 781        return pi->dcb.pfcen != 0;
 782}
 783
 784/* Enable/disable Priority Flow Control. */
 785static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
 786{
 787        /* We can't enable/disable Priority Flow Control but we also can't
 788         * return an error ...
 789         */
 790}
 791
 792/* Return the Application User Priority Map associated with the specified
 793 * Application ID.
 794 */
 795static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 796                          int peer)
 797{
 798        struct port_info *pi = netdev2pinfo(dev);
 799        struct adapter *adap = pi->adapter;
 800        int i;
 801
 802        if (!cxgb4_dcb_state_synced(pi->dcb.state))
 803                return 0;
 804
 805        for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
 806                struct fw_port_cmd pcmd;
 807                int err;
 808
 809                if (peer)
 810                        INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 811                else
 812                        INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 813
 814                pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 815                pcmd.u.dcb.app_priority.idx = i;
 816
 817                err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 818                if (err != FW_PORT_DCB_CFG_SUCCESS) {
 819                        dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
 820                                -err);
 821                        return err;
 822                }
 823                if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
 824                        if (pcmd.u.dcb.app_priority.sel_field == app_idtype)
 825                                return pcmd.u.dcb.app_priority.user_prio_map;
 826
 827                /* exhausted app list */
 828                if (!pcmd.u.dcb.app_priority.protocolid)
 829                        break;
 830        }
 831
 832        return -EEXIST;
 833}
 834
 835/* Return the Application User Priority Map associated with the specified
 836 * Application ID.
 837 */
 838static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
 839{
 840        /* Convert app_idtype to firmware format before querying */
 841        return __cxgb4_getapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
 842                              app_idtype : 3, app_id, 0);
 843}
 844
 845/* Write a new Application User Priority Map for the specified Application ID
 846 */
 847static int __cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 848                          u8 app_prio)
 849{
 850        struct fw_port_cmd pcmd;
 851        struct port_info *pi = netdev2pinfo(dev);
 852        struct adapter *adap = pi->adapter;
 853        int i, err;
 854
 855
 856        if (!cxgb4_dcb_state_synced(pi->dcb.state))
 857                return -EINVAL;
 858
 859        /* DCB info gets thrown away on link up */
 860        if (!netif_carrier_ok(dev))
 861                return -ENOLINK;
 862
 863        for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
 864                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 865                pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 866                pcmd.u.dcb.app_priority.idx = i;
 867                err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 868
 869                if (err != FW_PORT_DCB_CFG_SUCCESS) {
 870                        dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
 871                                -err);
 872                        return err;
 873                }
 874                if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
 875                        /* overwrite existing app table */
 876                        pcmd.u.dcb.app_priority.protocolid = 0;
 877                        break;
 878                }
 879                /* find first empty slot */
 880                if (!pcmd.u.dcb.app_priority.protocolid)
 881                        break;
 882        }
 883
 884        if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
 885                /* no empty slots available */
 886                dev_err(adap->pdev_dev, "DCB app table full\n");
 887                return -EBUSY;
 888        }
 889
 890        /* write out new app table entry */
 891        INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
 892        if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
 893                pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY_F);
 894
 895        pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
 896        pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
 897        pcmd.u.dcb.app_priority.sel_field = app_idtype;
 898        pcmd.u.dcb.app_priority.user_prio_map = app_prio;
 899        pcmd.u.dcb.app_priority.idx = i;
 900
 901        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 902        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 903                dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
 904                        -err);
 905                return err;
 906        }
 907
 908        return 0;
 909}
 910
 911/* Priority for CEE inside dcb_app is bitmask, with 0 being an invalid value */
 912static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
 913                        u8 app_prio)
 914{
 915        int ret;
 916        struct dcb_app app = {
 917                .selector = app_idtype,
 918                .protocol = app_id,
 919                .priority = app_prio,
 920        };
 921
 922        if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
 923            app_idtype != DCB_APP_IDTYPE_PORTNUM)
 924                return -EINVAL;
 925
 926        /* Convert app_idtype to a format that firmware understands */
 927        ret = __cxgb4_setapp(dev, app_idtype == DCB_APP_IDTYPE_ETHTYPE ?
 928                              app_idtype : 3, app_id, app_prio);
 929        if (ret)
 930                return ret;
 931
 932        return dcb_setapp(dev, &app);
 933}
 934
 935/* Return whether IEEE Data Center Bridging has been negotiated.
 936 */
 937static inline int
 938cxgb4_ieee_negotiation_complete(struct net_device *dev,
 939                                enum cxgb4_dcb_fw_msgs dcb_subtype)
 940{
 941        struct port_info *pi = netdev2pinfo(dev);
 942        struct port_dcb_info *dcb = &pi->dcb;
 943
 944        if (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED)
 945                if (dcb_subtype && !(dcb->msgs & dcb_subtype))
 946                        return 0;
 947
 948        return (cxgb4_dcb_state_synced(dcb->state) &&
 949                (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
 950}
 951
 952static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
 953                               int local)
 954{
 955        struct port_info *pi = netdev2pinfo(dev);
 956        struct port_dcb_info *dcb = &pi->dcb;
 957        struct adapter *adap = pi->adapter;
 958        uint32_t tc_info;
 959        struct fw_port_cmd pcmd;
 960        int i, bwg, err;
 961
 962        if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
 963                return 0;
 964
 965        ets->ets_cap =  dcb->pg_num_tcs_supported;
 966
 967        if (local) {
 968                ets->willing = 1;
 969                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 970        } else {
 971                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 972        }
 973
 974        pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
 975        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 976        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 977                dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
 978                return err;
 979        }
 980
 981        tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
 982
 983        if (local)
 984                INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
 985        else
 986                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
 987
 988        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
 989        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
 990        if (err != FW_PORT_DCB_CFG_SUCCESS) {
 991                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
 992                        -err);
 993                return err;
 994        }
 995
 996        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 997                bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
 998                ets->prio_tc[i] = bwg;
 999                ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1000                ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
1001                ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
1002        }
1003
1004        return 0;
1005}
1006
1007static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
1008{
1009        return cxgb4_ieee_read_ets(dev, ets, 1);
1010}
1011
1012/* We reuse this for peer PFC as well, as we can't have it enabled one way */
1013static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
1014{
1015        struct port_info *pi = netdev2pinfo(dev);
1016        struct port_dcb_info *dcb = &pi->dcb;
1017
1018        memset(pfc, 0, sizeof(struct ieee_pfc));
1019
1020        if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
1021                return 0;
1022
1023        pfc->pfc_cap = dcb->pfc_num_tcs_supported;
1024        pfc->pfc_en = bitswap_1(dcb->pfcen);
1025
1026        return 0;
1027}
1028
1029static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
1030{
1031        return cxgb4_ieee_read_ets(dev, ets, 0);
1032}
1033
1034/* Fill in the Application User Priority Map associated with the
1035 * specified Application.
1036 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1037 */
1038static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
1039{
1040        int prio;
1041
1042        if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1043                return -EINVAL;
1044        if (!(app->selector && app->protocol))
1045                return -EINVAL;
1046
1047        /* Try querying firmware first, use firmware format */
1048        prio = __cxgb4_getapp(dev, app->selector - 1, app->protocol, 0);
1049
1050        if (prio < 0)
1051                prio = dcb_ieee_getapp_mask(dev, app);
1052
1053        app->priority = ffs(prio) - 1;
1054        return 0;
1055}
1056
1057/* Write a new Application User Priority Map for the specified Application ID.
1058 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
1059 */
1060static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
1061{
1062        int ret;
1063
1064        if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
1065                return -EINVAL;
1066        if (!(app->selector && app->protocol))
1067                return -EINVAL;
1068
1069        if (!(app->selector > IEEE_8021QAZ_APP_SEL_ETHERTYPE  &&
1070              app->selector < IEEE_8021QAZ_APP_SEL_ANY))
1071                return -EINVAL;
1072
1073        /* change selector to a format that firmware understands */
1074        ret = __cxgb4_setapp(dev, app->selector - 1, app->protocol,
1075                             (1 << app->priority));
1076        if (ret)
1077                return ret;
1078
1079        return dcb_ieee_setapp(dev, app);
1080}
1081
1082/* Return our DCBX parameters.
1083 */
1084static u8 cxgb4_getdcbx(struct net_device *dev)
1085{
1086        struct port_info *pi = netdev2pinfo(dev);
1087
1088        /* This is already set by cxgb4_set_dcb_caps, so just return it */
1089        return pi->dcb.supported;
1090}
1091
1092/* Set our DCBX parameters.
1093 */
1094static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
1095{
1096        struct port_info *pi = netdev2pinfo(dev);
1097
1098        /* Filter out requests which exceed our capabilities.
1099         */
1100        if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
1101            != dcb_request)
1102                return 1;
1103
1104        /* Can't enable DCB if we haven't successfully negotiated it.
1105         */
1106        if (!cxgb4_dcb_state_synced(pi->dcb.state))
1107                return 1;
1108
1109        /* There's currently no mechanism to allow for the firmware DCBX
1110         * negotiation to be changed from the Host Driver.  If the caller
1111         * requests exactly the same parameters that we already have then
1112         * we'll allow them to be successfully "set" ...
1113         */
1114        if (dcb_request != pi->dcb.supported)
1115                return 1;
1116
1117        pi->dcb.supported = dcb_request;
1118        return 0;
1119}
1120
1121static int cxgb4_getpeer_app(struct net_device *dev,
1122                             struct dcb_peer_app_info *info, u16 *app_count)
1123{
1124        struct fw_port_cmd pcmd;
1125        struct port_info *pi = netdev2pinfo(dev);
1126        struct adapter *adap = pi->adapter;
1127        int i, err = 0;
1128
1129        if (!cxgb4_dcb_state_synced(pi->dcb.state))
1130                return 1;
1131
1132        info->willing = 0;
1133        info->error = 0;
1134
1135        *app_count = 0;
1136        for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1137                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1138                pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1139                pcmd.u.dcb.app_priority.idx = *app_count;
1140                err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1141
1142                if (err != FW_PORT_DCB_CFG_SUCCESS) {
1143                        dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1144                                -err);
1145                        return err;
1146                }
1147
1148                /* find first empty slot */
1149                if (!pcmd.u.dcb.app_priority.protocolid)
1150                        break;
1151        }
1152        *app_count = i;
1153        return err;
1154}
1155
1156static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
1157{
1158        struct fw_port_cmd pcmd;
1159        struct port_info *pi = netdev2pinfo(dev);
1160        struct adapter *adap = pi->adapter;
1161        int i, err = 0;
1162
1163        if (!cxgb4_dcb_state_synced(pi->dcb.state))
1164                return 1;
1165
1166        for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
1167                INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1168                pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
1169                pcmd.u.dcb.app_priority.idx = i;
1170                err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1171
1172                if (err != FW_PORT_DCB_CFG_SUCCESS) {
1173                        dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
1174                                -err);
1175                        return err;
1176                }
1177
1178                /* find first empty slot */
1179                if (!pcmd.u.dcb.app_priority.protocolid)
1180                        break;
1181
1182                table[i].selector = (pcmd.u.dcb.app_priority.sel_field + 1);
1183                table[i].protocol =
1184                        be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
1185                table[i].priority =
1186                        ffs(pcmd.u.dcb.app_priority.user_prio_map) - 1;
1187        }
1188        return err;
1189}
1190
1191/* Return Priority Group information.
1192 */
1193static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
1194{
1195        struct fw_port_cmd pcmd;
1196        struct port_info *pi = netdev2pinfo(dev);
1197        struct adapter *adap = pi->adapter;
1198        u32 pgid;
1199        int i, err;
1200
1201        /* We're always "willing" -- the Switch Fabric always dictates the
1202         * DCBX parameters to us.
1203         */
1204        pg->willing = true;
1205
1206        INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1207        pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
1208        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1209        if (err != FW_PORT_DCB_CFG_SUCCESS) {
1210                dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
1211                return err;
1212        }
1213        pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
1214
1215        for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1216                pg->prio_pg[7 - i] = (pgid >> (i * 4)) & 0xF;
1217
1218        INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
1219        pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
1220        err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
1221        if (err != FW_PORT_DCB_CFG_SUCCESS) {
1222                dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
1223                        -err);
1224                return err;
1225        }
1226
1227        for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
1228                pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
1229
1230        pg->tcs_supported = pcmd.u.dcb.pgrate.num_tcs_supported;
1231
1232        return 0;
1233}
1234
1235/* Return Priority Flow Control information.
1236 */
1237static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1238{
1239        struct port_info *pi = netdev2pinfo(dev);
1240
1241        cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1242
1243        /* Firmware sends this to us in a formwat that is a bit flipped version
1244         * of spec, correct it before we send it to host. This is taken care of
1245         * by bit shifting in other uses of pfcen
1246         */
1247        pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
1248
1249        pfc->tcs_supported = pi->dcb.pfc_num_tcs_supported;
1250
1251        return 0;
1252}
1253
1254const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1255        .ieee_getets            = cxgb4_ieee_get_ets,
1256        .ieee_getpfc            = cxgb4_ieee_get_pfc,
1257        .ieee_getapp            = cxgb4_ieee_getapp,
1258        .ieee_setapp            = cxgb4_ieee_setapp,
1259        .ieee_peer_getets       = cxgb4_ieee_peer_ets,
1260        .ieee_peer_getpfc       = cxgb4_ieee_get_pfc,
1261
1262        /* CEE std */
1263        .getstate               = cxgb4_getstate,
1264        .setstate               = cxgb4_setstate,
1265        .getpgtccfgtx           = cxgb4_getpgtccfg_tx,
1266        .getpgbwgcfgtx          = cxgb4_getpgbwgcfg_tx,
1267        .getpgtccfgrx           = cxgb4_getpgtccfg_rx,
1268        .getpgbwgcfgrx          = cxgb4_getpgbwgcfg_rx,
1269        .setpgtccfgtx           = cxgb4_setpgtccfg_tx,
1270        .setpgbwgcfgtx          = cxgb4_setpgbwgcfg_tx,
1271        .setpfccfg              = cxgb4_setpfccfg,
1272        .getpfccfg              = cxgb4_getpfccfg,
1273        .setall                 = cxgb4_setall,
1274        .getcap                 = cxgb4_getcap,
1275        .getnumtcs              = cxgb4_getnumtcs,
1276        .setnumtcs              = cxgb4_setnumtcs,
1277        .getpfcstate            = cxgb4_getpfcstate,
1278        .setpfcstate            = cxgb4_setpfcstate,
1279        .getapp                 = cxgb4_getapp,
1280        .setapp                 = cxgb4_setapp,
1281
1282        /* DCBX configuration */
1283        .getdcbx                = cxgb4_getdcbx,
1284        .setdcbx                = cxgb4_setdcbx,
1285
1286        /* peer apps */
1287        .peer_getappinfo        = cxgb4_getpeer_app,
1288        .peer_getapptable       = cxgb4_getpeerapp_tbl,
1289
1290        /* CEE peer */
1291        .cee_peer_getpg         = cxgb4_cee_peer_getpg,
1292        .cee_peer_getpfc        = cxgb4_cee_peer_getpfc,
1293};
1294