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