linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
<<
>>
Prefs
   1/*
   2 * QLogic qlcnic NIC Driver
   3 * Copyright (c)  2009-2013 QLogic Corporation
   4 *
   5 * See LICENSE.qlcnic for copyright and licensing details.
   6 */
   7
   8#include <linux/types.h>
   9#include "qlcnic.h"
  10
  11#define QLC_DCB_NUM_PARAM               3
  12#define QLC_DCB_LOCAL_IDX               0
  13#define QLC_DCB_OPER_IDX                1
  14#define QLC_DCB_PEER_IDX                2
  15
  16#define QLC_DCB_GET_MAP(V)              (1 << V)
  17
  18#define QLC_DCB_FW_VER                  0x2
  19#define QLC_DCB_MAX_TC                  0x8
  20#define QLC_DCB_MAX_APP                 0x8
  21#define QLC_DCB_MAX_PRIO                QLC_DCB_MAX_TC
  22#define QLC_DCB_MAX_PG                  QLC_DCB_MAX_TC
  23
  24#define QLC_DCB_TSA_SUPPORT(V)          (V & 0x1)
  25#define QLC_DCB_ETS_SUPPORT(V)          ((V >> 1) & 0x1)
  26#define QLC_DCB_VERSION_SUPPORT(V)      ((V >> 2) & 0xf)
  27#define QLC_DCB_MAX_NUM_TC(V)           ((V >> 20) & 0xf)
  28#define QLC_DCB_MAX_NUM_ETS_TC(V)       ((V >> 24) & 0xf)
  29#define QLC_DCB_MAX_NUM_PFC_TC(V)       ((V >> 28) & 0xf)
  30#define QLC_DCB_GET_TC_PRIO(X, P)       ((X >> (P * 3)) & 0x7)
  31#define QLC_DCB_GET_PGID_PRIO(X, P)     ((X >> (P * 8)) & 0xff)
  32#define QLC_DCB_GET_BWPER_PG(X, P)      ((X >> (P * 8)) & 0xff)
  33#define QLC_DCB_GET_TSA_PG(X, P)        ((X >> (P * 8)) & 0xff)
  34#define QLC_DCB_GET_PFC_PRIO(X, P)      (((X >> 24) >> P) & 0x1)
  35#define QLC_DCB_GET_PROTO_ID_APP(X)     ((X >> 8) & 0xffff)
  36#define QLC_DCB_GET_SELECTOR_APP(X)     (X & 0xff)
  37
  38#define QLC_DCB_LOCAL_PARAM_FWID        0x3
  39#define QLC_DCB_OPER_PARAM_FWID         0x1
  40#define QLC_DCB_PEER_PARAM_FWID         0x2
  41
  42#define QLC_83XX_DCB_GET_NUMAPP(X)      ((X >> 2) & 0xf)
  43#define QLC_83XX_DCB_TSA_VALID(X)       (X & 0x1)
  44#define QLC_83XX_DCB_PFC_VALID(X)       ((X >> 1) & 0x1)
  45#define QLC_83XX_DCB_GET_PRIOMAP_APP(X) (X >> 24)
  46
  47#define QLC_82XX_DCB_GET_NUMAPP(X)      ((X >> 12) & 0xf)
  48#define QLC_82XX_DCB_TSA_VALID(X)       ((X >> 4) & 0x1)
  49#define QLC_82XX_DCB_PFC_VALID(X)       ((X >> 5) & 0x1)
  50#define QLC_82XX_DCB_GET_PRIOVAL_APP(X) ((X >> 24) & 0x7)
  51#define QLC_82XX_DCB_GET_PRIOMAP_APP(X) (1 << X)
  52#define QLC_82XX_DCB_PRIO_TC_MAP        (0x76543210)
  53
  54static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
  55
  56static void qlcnic_dcb_aen_work(struct work_struct *);
  57static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
  58
  59static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
  60static void __qlcnic_dcb_free(struct qlcnic_dcb *);
  61static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
  62static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
  63static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
  64
  65static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
  66static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
  67static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
  68static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
  69
  70static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
  71static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
  72static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
  73static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
  74
  75struct qlcnic_dcb_capability {
  76        bool    tsa_capability;
  77        bool    ets_capability;
  78        u8      max_num_tc;
  79        u8      max_ets_tc;
  80        u8      max_pfc_tc;
  81        u8      dcb_capability;
  82};
  83
  84struct qlcnic_dcb_param {
  85        u32 hdr_prio_pfc_map[2];
  86        u32 prio_pg_map[2];
  87        u32 pg_bw_map[2];
  88        u32 pg_tsa_map[2];
  89        u32 app[QLC_DCB_MAX_APP];
  90};
  91
  92struct qlcnic_dcb_mbx_params {
  93        /* 1st local, 2nd operational 3rd remote */
  94        struct qlcnic_dcb_param type[3];
  95        u32 prio_tc_map;
  96};
  97
  98struct qlcnic_82xx_dcb_param_mbx_le {
  99        __le32 hdr_prio_pfc_map[2];
 100        __le32 prio_pg_map[2];
 101        __le32 pg_bw_map[2];
 102        __le32 pg_tsa_map[2];
 103        __le32 app[QLC_DCB_MAX_APP];
 104};
 105
 106enum qlcnic_dcb_selector {
 107        QLC_SELECTOR_DEF = 0x0,
 108        QLC_SELECTOR_ETHER,
 109        QLC_SELECTOR_TCP,
 110        QLC_SELECTOR_UDP,
 111};
 112
 113enum qlcnic_dcb_prio_type {
 114        QLC_PRIO_NONE = 0,
 115        QLC_PRIO_GROUP,
 116        QLC_PRIO_LINK,
 117};
 118
 119enum qlcnic_dcb_pfc_type {
 120        QLC_PFC_DISABLED = 0,
 121        QLC_PFC_FULL,
 122        QLC_PFC_TX,
 123        QLC_PFC_RX
 124};
 125
 126struct qlcnic_dcb_prio_cfg {
 127        bool valid;
 128        enum qlcnic_dcb_pfc_type pfc_type;
 129};
 130
 131struct qlcnic_dcb_pg_cfg {
 132        bool valid;
 133        u8 total_bw_percent;            /* of Link/ port BW */
 134        u8 prio_count;
 135        u8 tsa_type;
 136};
 137
 138struct qlcnic_dcb_tc_cfg {
 139        bool valid;
 140        struct qlcnic_dcb_prio_cfg prio_cfg[QLC_DCB_MAX_PRIO];
 141        enum qlcnic_dcb_prio_type prio_type;    /* always prio_link */
 142        u8 link_percent;                        /* % of link bandwidth */
 143        u8 bwg_percent;                         /* % of BWG's bandwidth */
 144        u8 up_tc_map;
 145        u8 pgid;
 146};
 147
 148struct qlcnic_dcb_app {
 149        bool valid;
 150        enum qlcnic_dcb_selector selector;
 151        u16 protocol;
 152        u8 priority;
 153};
 154
 155struct qlcnic_dcb_cee {
 156        struct qlcnic_dcb_tc_cfg tc_cfg[QLC_DCB_MAX_TC];
 157        struct qlcnic_dcb_pg_cfg pg_cfg[QLC_DCB_MAX_PG];
 158        struct qlcnic_dcb_app app[QLC_DCB_MAX_APP];
 159        bool tc_param_valid;
 160        bool pfc_mode_enable;
 161};
 162
 163struct qlcnic_dcb_cfg {
 164        /* 0 - local, 1 - operational, 2 - remote */
 165        struct qlcnic_dcb_cee type[QLC_DCB_NUM_PARAM];
 166        struct qlcnic_dcb_capability capability;
 167        u32 version;
 168};
 169
 170static const struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = {
 171        .init_dcbnl_ops         = __qlcnic_init_dcbnl_ops,
 172        .free                   = __qlcnic_dcb_free,
 173        .attach                 = __qlcnic_dcb_attach,
 174        .query_hw_capability    = __qlcnic_dcb_query_hw_capability,
 175        .get_info               = __qlcnic_dcb_get_info,
 176
 177        .get_hw_capability      = qlcnic_83xx_dcb_get_hw_capability,
 178        .query_cee_param        = qlcnic_83xx_dcb_query_cee_param,
 179        .get_cee_cfg            = qlcnic_83xx_dcb_get_cee_cfg,
 180        .aen_handler            = qlcnic_83xx_dcb_aen_handler,
 181};
 182
 183static const struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops = {
 184        .init_dcbnl_ops         = __qlcnic_init_dcbnl_ops,
 185        .free                   = __qlcnic_dcb_free,
 186        .attach                 = __qlcnic_dcb_attach,
 187        .query_hw_capability    = __qlcnic_dcb_query_hw_capability,
 188        .get_info               = __qlcnic_dcb_get_info,
 189
 190        .get_hw_capability      = qlcnic_82xx_dcb_get_hw_capability,
 191        .query_cee_param        = qlcnic_82xx_dcb_query_cee_param,
 192        .get_cee_cfg            = qlcnic_82xx_dcb_get_cee_cfg,
 193        .aen_handler            = qlcnic_82xx_dcb_aen_handler,
 194};
 195
 196static u8 qlcnic_dcb_get_num_app(struct qlcnic_adapter *adapter, u32 val)
 197{
 198        if (qlcnic_82xx_check(adapter))
 199                return QLC_82XX_DCB_GET_NUMAPP(val);
 200        else
 201                return QLC_83XX_DCB_GET_NUMAPP(val);
 202}
 203
 204static inline u8 qlcnic_dcb_pfc_hdr_valid(struct qlcnic_adapter *adapter,
 205                                          u32 val)
 206{
 207        if (qlcnic_82xx_check(adapter))
 208                return QLC_82XX_DCB_PFC_VALID(val);
 209        else
 210                return QLC_83XX_DCB_PFC_VALID(val);
 211}
 212
 213static inline u8 qlcnic_dcb_tsa_hdr_valid(struct qlcnic_adapter *adapter,
 214                                          u32 val)
 215{
 216        if (qlcnic_82xx_check(adapter))
 217                return QLC_82XX_DCB_TSA_VALID(val);
 218        else
 219                return QLC_83XX_DCB_TSA_VALID(val);
 220}
 221
 222static inline u8 qlcnic_dcb_get_prio_map_app(struct qlcnic_adapter *adapter,
 223                                             u32 val)
 224{
 225        if (qlcnic_82xx_check(adapter))
 226                return QLC_82XX_DCB_GET_PRIOMAP_APP(val);
 227        else
 228                return QLC_83XX_DCB_GET_PRIOMAP_APP(val);
 229}
 230
 231static int qlcnic_dcb_prio_count(u8 up_tc_map)
 232{
 233        int j;
 234
 235        for (j = 0; j < QLC_DCB_MAX_TC; j++)
 236                if (up_tc_map & QLC_DCB_GET_MAP(j))
 237                        break;
 238
 239        return j;
 240}
 241
 242static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *dcb)
 243{
 244        if (test_bit(QLCNIC_DCB_STATE, &dcb->state))
 245                dcb->adapter->netdev->dcbnl_ops = &qlcnic_dcbnl_ops;
 246}
 247
 248static void qlcnic_set_dcb_ops(struct qlcnic_adapter *adapter)
 249{
 250        if (qlcnic_82xx_check(adapter))
 251                adapter->dcb->ops = &qlcnic_82xx_dcb_ops;
 252        else if (qlcnic_83xx_check(adapter))
 253                adapter->dcb->ops = &qlcnic_83xx_dcb_ops;
 254}
 255
 256int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 257{
 258        struct qlcnic_dcb *dcb;
 259
 260        if (qlcnic_sriov_vf_check(adapter))
 261                return 0;
 262
 263        dcb = kzalloc(sizeof(struct qlcnic_dcb), GFP_ATOMIC);
 264        if (!dcb)
 265                return -ENOMEM;
 266
 267        adapter->dcb = dcb;
 268        dcb->adapter = adapter;
 269        qlcnic_set_dcb_ops(adapter);
 270        dcb->state = 0;
 271
 272        return 0;
 273}
 274
 275static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb)
 276{
 277        struct qlcnic_adapter *adapter;
 278
 279        if (!dcb)
 280                return;
 281
 282        adapter = dcb->adapter;
 283
 284        while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 285                usleep_range(10000, 11000);
 286
 287        cancel_delayed_work_sync(&dcb->aen_work);
 288
 289        if (dcb->wq) {
 290                destroy_workqueue(dcb->wq);
 291                dcb->wq = NULL;
 292        }
 293
 294        kfree(dcb->cfg);
 295        dcb->cfg = NULL;
 296        kfree(dcb->param);
 297        dcb->param = NULL;
 298        kfree(dcb);
 299        adapter->dcb = NULL;
 300}
 301
 302static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb)
 303{
 304        qlcnic_dcb_get_hw_capability(dcb);
 305        qlcnic_dcb_get_cee_cfg(dcb);
 306}
 307
 308static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb)
 309{
 310        int err = 0;
 311
 312        INIT_DELAYED_WORK(&dcb->aen_work, qlcnic_dcb_aen_work);
 313
 314        dcb->wq = create_singlethread_workqueue("qlcnic-dcb");
 315        if (!dcb->wq) {
 316                dev_err(&dcb->adapter->pdev->dev,
 317                        "DCB workqueue allocation failed. DCB will be disabled\n");
 318                return -1;
 319        }
 320
 321        dcb->cfg = kzalloc(sizeof(struct qlcnic_dcb_cfg), GFP_ATOMIC);
 322        if (!dcb->cfg) {
 323                err = -ENOMEM;
 324                goto out_free_wq;
 325        }
 326
 327        dcb->param = kzalloc(sizeof(struct qlcnic_dcb_mbx_params), GFP_ATOMIC);
 328        if (!dcb->param) {
 329                err = -ENOMEM;
 330                goto out_free_cfg;
 331        }
 332
 333        return 0;
 334out_free_cfg:
 335        kfree(dcb->cfg);
 336        dcb->cfg = NULL;
 337
 338out_free_wq:
 339        destroy_workqueue(dcb->wq);
 340        dcb->wq = NULL;
 341
 342        return err;
 343}
 344
 345static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *dcb, char *buf)
 346{
 347        struct qlcnic_adapter *adapter = dcb->adapter;
 348        struct qlcnic_cmd_args cmd;
 349        u32 mbx_out;
 350        int err;
 351
 352        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_CAP);
 353        if (err)
 354                return err;
 355
 356        err = qlcnic_issue_cmd(adapter, &cmd);
 357        if (err) {
 358                dev_err(&adapter->pdev->dev,
 359                        "Failed to query DCBX capability, err %d\n", err);
 360        } else {
 361                mbx_out = cmd.rsp.arg[1];
 362                if (buf)
 363                        memcpy(buf, &mbx_out, sizeof(u32));
 364        }
 365
 366        qlcnic_free_mbx_args(&cmd);
 367
 368        return err;
 369}
 370
 371static int __qlcnic_dcb_get_capability(struct qlcnic_dcb *dcb, u32 *val)
 372{
 373        struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 374        u32 mbx_out;
 375        int err;
 376
 377        memset(cap, 0, sizeof(struct qlcnic_dcb_capability));
 378
 379        err = qlcnic_dcb_query_hw_capability(dcb, (char *)val);
 380        if (err)
 381                return err;
 382
 383        mbx_out = *val;
 384        if (QLC_DCB_TSA_SUPPORT(mbx_out))
 385                cap->tsa_capability = true;
 386
 387        if (QLC_DCB_ETS_SUPPORT(mbx_out))
 388                cap->ets_capability = true;
 389
 390        cap->max_num_tc = QLC_DCB_MAX_NUM_TC(mbx_out);
 391        cap->max_ets_tc = QLC_DCB_MAX_NUM_ETS_TC(mbx_out);
 392        cap->max_pfc_tc = QLC_DCB_MAX_NUM_PFC_TC(mbx_out);
 393
 394        if (cap->max_num_tc > QLC_DCB_MAX_TC ||
 395            cap->max_ets_tc > cap->max_num_tc ||
 396            cap->max_pfc_tc > cap->max_num_tc) {
 397                dev_err(&dcb->adapter->pdev->dev, "Invalid DCB configuration\n");
 398                return -EINVAL;
 399        }
 400
 401        return err;
 402}
 403
 404static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 405{
 406        struct qlcnic_dcb_cfg *cfg = dcb->cfg;
 407        struct qlcnic_dcb_capability *cap;
 408        u32 mbx_out;
 409        int err;
 410
 411        err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 412        if (err)
 413                return err;
 414
 415        cap = &cfg->capability;
 416        cap->dcb_capability = DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_LLD_MANAGED;
 417
 418        if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
 419                set_bit(QLCNIC_DCB_STATE, &dcb->state);
 420
 421        return err;
 422}
 423
 424static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 425                                           char *buf, u8 type)
 426{
 427        u16 size = sizeof(struct qlcnic_82xx_dcb_param_mbx_le);
 428        struct qlcnic_adapter *adapter = dcb->adapter;
 429        struct qlcnic_82xx_dcb_param_mbx_le *prsp_le;
 430        struct device *dev = &adapter->pdev->dev;
 431        dma_addr_t cardrsp_phys_addr;
 432        struct qlcnic_dcb_param rsp;
 433        struct qlcnic_cmd_args cmd;
 434        u64 phys_addr;
 435        void *addr;
 436        int err, i;
 437
 438        switch (type) {
 439        case QLC_DCB_LOCAL_PARAM_FWID:
 440        case QLC_DCB_OPER_PARAM_FWID:
 441        case QLC_DCB_PEER_PARAM_FWID:
 442                break;
 443        default:
 444                dev_err(dev, "Invalid parameter type %d\n", type);
 445                return -EINVAL;
 446        }
 447
 448        addr = dma_alloc_coherent(dev, size, &cardrsp_phys_addr, GFP_KERNEL);
 449        if (addr == NULL)
 450                return -ENOMEM;
 451
 452        prsp_le = addr;
 453
 454        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
 455        if (err)
 456                goto out_free_rsp;
 457
 458        phys_addr = cardrsp_phys_addr;
 459        cmd.req.arg[1] = size | (type << 16);
 460        cmd.req.arg[2] = MSD(phys_addr);
 461        cmd.req.arg[3] = LSD(phys_addr);
 462
 463        err = qlcnic_issue_cmd(adapter, &cmd);
 464        if (err) {
 465                dev_err(dev, "Failed to query DCBX parameter, err %d\n", err);
 466                goto out;
 467        }
 468
 469        memset(&rsp, 0, sizeof(struct qlcnic_dcb_param));
 470        rsp.hdr_prio_pfc_map[0] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[0]);
 471        rsp.hdr_prio_pfc_map[1] = le32_to_cpu(prsp_le->hdr_prio_pfc_map[1]);
 472        rsp.prio_pg_map[0] = le32_to_cpu(prsp_le->prio_pg_map[0]);
 473        rsp.prio_pg_map[1] = le32_to_cpu(prsp_le->prio_pg_map[1]);
 474        rsp.pg_bw_map[0] = le32_to_cpu(prsp_le->pg_bw_map[0]);
 475        rsp.pg_bw_map[1] = le32_to_cpu(prsp_le->pg_bw_map[1]);
 476        rsp.pg_tsa_map[0] = le32_to_cpu(prsp_le->pg_tsa_map[0]);
 477        rsp.pg_tsa_map[1] = le32_to_cpu(prsp_le->pg_tsa_map[1]);
 478
 479        for (i = 0; i < QLC_DCB_MAX_APP; i++)
 480                rsp.app[i] = le32_to_cpu(prsp_le->app[i]);
 481
 482        if (buf)
 483                memcpy(buf, &rsp, size);
 484out:
 485        qlcnic_free_mbx_args(&cmd);
 486
 487out_free_rsp:
 488        dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
 489
 490        return err;
 491}
 492
 493static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 494{
 495        struct qlcnic_dcb_mbx_params *mbx;
 496        int err;
 497
 498        mbx = dcb->param;
 499        if (!mbx)
 500                return 0;
 501
 502        err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[0],
 503                                         QLC_DCB_LOCAL_PARAM_FWID);
 504        if (err)
 505                return err;
 506
 507        err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[1],
 508                                         QLC_DCB_OPER_PARAM_FWID);
 509        if (err)
 510                return err;
 511
 512        err = qlcnic_dcb_query_cee_param(dcb, (char *)&mbx->type[2],
 513                                         QLC_DCB_PEER_PARAM_FWID);
 514        if (err)
 515                return err;
 516
 517        mbx->prio_tc_map = QLC_82XX_DCB_PRIO_TC_MAP;
 518
 519        qlcnic_dcb_data_cee_param_map(dcb->adapter);
 520
 521        return err;
 522}
 523
 524static void qlcnic_dcb_aen_work(struct work_struct *work)
 525{
 526        struct qlcnic_dcb *dcb;
 527
 528        dcb = container_of(work, struct qlcnic_dcb, aen_work.work);
 529
 530        qlcnic_dcb_get_cee_cfg(dcb);
 531        clear_bit(QLCNIC_DCB_AEN_MODE, &dcb->state);
 532}
 533
 534static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 535{
 536        if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 537                return;
 538
 539        queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 540}
 541
 542static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
 543{
 544        struct qlcnic_dcb_capability *cap = &dcb->cfg->capability;
 545        u32 mbx_out;
 546        int err;
 547
 548        err = __qlcnic_dcb_get_capability(dcb, &mbx_out);
 549        if (err)
 550                return err;
 551
 552        if (mbx_out & BIT_2)
 553                cap->dcb_capability = DCB_CAP_DCBX_VER_CEE;
 554        if (mbx_out & BIT_3)
 555                cap->dcb_capability |= DCB_CAP_DCBX_VER_IEEE;
 556        if (cap->dcb_capability)
 557                cap->dcb_capability |= DCB_CAP_DCBX_LLD_MANAGED;
 558
 559        if (cap->dcb_capability && cap->tsa_capability && cap->ets_capability)
 560                set_bit(QLCNIC_DCB_STATE, &dcb->state);
 561
 562        return err;
 563}
 564
 565static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *dcb,
 566                                           char *buf, u8 idx)
 567{
 568        struct qlcnic_adapter *adapter = dcb->adapter;
 569        struct qlcnic_dcb_mbx_params mbx_out;
 570        int err, i, j, k, max_app, size;
 571        struct qlcnic_dcb_param *each;
 572        struct qlcnic_cmd_args cmd;
 573        u32 val;
 574        char *p;
 575
 576        size = 0;
 577        memset(&mbx_out, 0, sizeof(struct qlcnic_dcb_mbx_params));
 578        memset(buf, 0, sizeof(struct qlcnic_dcb_mbx_params));
 579
 580        err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DCB_QUERY_PARAM);
 581        if (err)
 582                return err;
 583
 584        cmd.req.arg[0] |= QLC_DCB_FW_VER << 29;
 585        err = qlcnic_issue_cmd(adapter, &cmd);
 586        if (err) {
 587                dev_err(&adapter->pdev->dev,
 588                        "Failed to query DCBX param, err %d\n", err);
 589                goto out;
 590        }
 591
 592        mbx_out.prio_tc_map = cmd.rsp.arg[1];
 593        p = memcpy(buf, &mbx_out, sizeof(u32));
 594        k = 2;
 595        p += sizeof(u32);
 596
 597        for (j = 0; j < QLC_DCB_NUM_PARAM; j++) {
 598                each = &mbx_out.type[j];
 599
 600                each->hdr_prio_pfc_map[0] = cmd.rsp.arg[k++];
 601                each->hdr_prio_pfc_map[1] = cmd.rsp.arg[k++];
 602                each->prio_pg_map[0] = cmd.rsp.arg[k++];
 603                each->prio_pg_map[1] = cmd.rsp.arg[k++];
 604                each->pg_bw_map[0] = cmd.rsp.arg[k++];
 605                each->pg_bw_map[1] = cmd.rsp.arg[k++];
 606                each->pg_tsa_map[0] = cmd.rsp.arg[k++];
 607                each->pg_tsa_map[1] = cmd.rsp.arg[k++];
 608                val = each->hdr_prio_pfc_map[0];
 609
 610                max_app = qlcnic_dcb_get_num_app(adapter, val);
 611                for (i = 0; i < max_app; i++)
 612                        each->app[i] = cmd.rsp.arg[i + k];
 613
 614                size = 16 * sizeof(u32);
 615                memcpy(p, &each->hdr_prio_pfc_map[0], size);
 616                p += size;
 617                if (j == 0)
 618                        k = 18;
 619                else
 620                        k = 34;
 621        }
 622out:
 623        qlcnic_free_mbx_args(&cmd);
 624
 625        return err;
 626}
 627
 628static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb)
 629{
 630        int err;
 631
 632        err = qlcnic_dcb_query_cee_param(dcb, (char *)dcb->param, 0);
 633        if (err)
 634                return err;
 635
 636        qlcnic_dcb_data_cee_param_map(dcb->adapter);
 637
 638        return err;
 639}
 640
 641static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data)
 642{
 643        u32 *val = data;
 644
 645        if (test_and_set_bit(QLCNIC_DCB_AEN_MODE, &dcb->state))
 646                return;
 647
 648        if (*val & BIT_8)
 649                set_bit(QLCNIC_DCB_STATE, &dcb->state);
 650        else
 651                clear_bit(QLCNIC_DCB_STATE, &dcb->state);
 652
 653        queue_delayed_work(dcb->wq, &dcb->aen_work, 0);
 654}
 655
 656static void qlcnic_dcb_fill_cee_tc_params(struct qlcnic_dcb_mbx_params *mbx,
 657                                          struct qlcnic_dcb_param *each,
 658                                          struct qlcnic_dcb_cee *type)
 659{
 660        struct qlcnic_dcb_tc_cfg *tc_cfg;
 661        u8 i, tc, pgid;
 662
 663        for (i = 0; i < QLC_DCB_MAX_PRIO; i++) {
 664                tc = QLC_DCB_GET_TC_PRIO(mbx->prio_tc_map, i);
 665                tc_cfg = &type->tc_cfg[tc];
 666                tc_cfg->valid = true;
 667                tc_cfg->up_tc_map |= QLC_DCB_GET_MAP(i);
 668
 669                if (QLC_DCB_GET_PFC_PRIO(each->hdr_prio_pfc_map[1], i) &&
 670                    type->pfc_mode_enable) {
 671                        tc_cfg->prio_cfg[i].valid = true;
 672                        tc_cfg->prio_cfg[i].pfc_type = QLC_PFC_FULL;
 673                }
 674
 675                if (i < 4)
 676                        pgid = QLC_DCB_GET_PGID_PRIO(each->prio_pg_map[0], i);
 677                else
 678                        pgid = QLC_DCB_GET_PGID_PRIO(each->prio_pg_map[1], i);
 679
 680                tc_cfg->pgid = pgid;
 681
 682                tc_cfg->prio_type = QLC_PRIO_LINK;
 683                type->pg_cfg[tc_cfg->pgid].prio_count++;
 684        }
 685}
 686
 687static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param *each,
 688                                          struct qlcnic_dcb_cee *type)
 689{
 690        struct qlcnic_dcb_pg_cfg *pg_cfg;
 691        u8 i, tsa, bw_per;
 692
 693        for (i = 0; i < QLC_DCB_MAX_PG; i++) {
 694                pg_cfg = &type->pg_cfg[i];
 695                pg_cfg->valid = true;
 696
 697                if (i < 4) {
 698                        bw_per = QLC_DCB_GET_BWPER_PG(each->pg_bw_map[0], i);
 699                        tsa = QLC_DCB_GET_TSA_PG(each->pg_tsa_map[0], i);
 700                } else {
 701                        bw_per = QLC_DCB_GET_BWPER_PG(each->pg_bw_map[1], i);
 702                        tsa = QLC_DCB_GET_TSA_PG(each->pg_tsa_map[1], i);
 703                }
 704
 705                pg_cfg->total_bw_percent = bw_per;
 706                pg_cfg->tsa_type = tsa;
 707        }
 708}
 709
 710static void
 711qlcnic_dcb_fill_cee_app_params(struct qlcnic_adapter *adapter, u8 idx,
 712                               struct qlcnic_dcb_param *each,
 713                               struct qlcnic_dcb_cee *type)
 714{
 715        struct qlcnic_dcb_app *app;
 716        u8 i, num_app, map, cnt;
 717        struct dcb_app new_app;
 718
 719        num_app = qlcnic_dcb_get_num_app(adapter, each->hdr_prio_pfc_map[0]);
 720        for (i = 0; i < num_app; i++) {
 721                app = &type->app[i];
 722                app->valid = true;
 723
 724                /* Only for CEE (-1) */
 725                app->selector = QLC_DCB_GET_SELECTOR_APP(each->app[i]) - 1;
 726                new_app.selector = app->selector;
 727                app->protocol = QLC_DCB_GET_PROTO_ID_APP(each->app[i]);
 728                new_app.protocol = app->protocol;
 729                map = qlcnic_dcb_get_prio_map_app(adapter, each->app[i]);
 730                cnt = qlcnic_dcb_prio_count(map);
 731
 732                if (cnt >= QLC_DCB_MAX_TC)
 733                        cnt = 0;
 734
 735                app->priority = cnt;
 736                new_app.priority = cnt;
 737
 738                if (idx == QLC_DCB_OPER_IDX && adapter->netdev->dcbnl_ops)
 739                        dcb_setapp(adapter->netdev, &new_app);
 740        }
 741}
 742
 743static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter *adapter, u8 idx)
 744{
 745        struct qlcnic_dcb_mbx_params *mbx = adapter->dcb->param;
 746        struct qlcnic_dcb_param *each = &mbx->type[idx];
 747        struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 748        struct qlcnic_dcb_cee *type = &cfg->type[idx];
 749
 750        type->tc_param_valid = false;
 751        type->pfc_mode_enable = false;
 752        memset(type->tc_cfg, 0,
 753               sizeof(struct qlcnic_dcb_tc_cfg) * QLC_DCB_MAX_TC);
 754        memset(type->pg_cfg, 0,
 755               sizeof(struct qlcnic_dcb_pg_cfg) * QLC_DCB_MAX_TC);
 756
 757        if (qlcnic_dcb_pfc_hdr_valid(adapter, each->hdr_prio_pfc_map[0]) &&
 758            cfg->capability.max_pfc_tc)
 759                type->pfc_mode_enable = true;
 760
 761        if (qlcnic_dcb_tsa_hdr_valid(adapter, each->hdr_prio_pfc_map[0]) &&
 762            cfg->capability.max_ets_tc)
 763                type->tc_param_valid = true;
 764
 765        qlcnic_dcb_fill_cee_tc_params(mbx, each, type);
 766        qlcnic_dcb_fill_cee_pg_params(each, type);
 767        qlcnic_dcb_fill_cee_app_params(adapter, idx, each, type);
 768}
 769
 770static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *adapter)
 771{
 772        int i;
 773
 774        for (i = 0; i < QLC_DCB_NUM_PARAM; i++)
 775                qlcnic_dcb_map_cee_params(adapter, i);
 776
 777        dcbnl_cee_notify(adapter->netdev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0);
 778}
 779
 780static u8 qlcnic_dcb_get_state(struct net_device *netdev)
 781{
 782        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 783
 784        return test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state);
 785}
 786
 787static void qlcnic_dcb_get_perm_hw_addr(struct net_device *netdev, u8 *addr)
 788{
 789        memcpy(addr, netdev->perm_addr, netdev->addr_len);
 790}
 791
 792static void
 793qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
 794                            u8 *pgid, u8 *bw_per, u8 *up_tc_map)
 795{
 796        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 797        struct qlcnic_dcb_tc_cfg *tc_cfg, *temp;
 798        struct qlcnic_dcb_cee *type;
 799        u8 i, cnt, pg;
 800
 801        type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 802        *prio = *pgid = *bw_per = *up_tc_map = 0;
 803
 804        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 805            !type->tc_param_valid)
 806                return;
 807
 808        if (tc < 0 || (tc >= QLC_DCB_MAX_TC))
 809                return;
 810
 811        tc_cfg = &type->tc_cfg[tc];
 812        if (!tc_cfg->valid)
 813                return;
 814
 815        *pgid = tc_cfg->pgid;
 816        *prio = tc_cfg->prio_type;
 817        *up_tc_map = tc_cfg->up_tc_map;
 818        pg = *pgid;
 819
 820        for (i = 0, cnt = 0; i < QLC_DCB_MAX_TC; i++) {
 821                temp = &type->tc_cfg[i];
 822                if (temp->valid && (pg == temp->pgid))
 823                        cnt++;
 824        }
 825
 826        tc_cfg->bwg_percent = (100 / cnt);
 827        *bw_per = tc_cfg->bwg_percent;
 828}
 829
 830static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
 831                                         u8 *bw_pct)
 832{
 833        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 834        struct qlcnic_dcb_pg_cfg *pgcfg;
 835        struct qlcnic_dcb_cee *type;
 836
 837        *bw_pct = 0;
 838        type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 839
 840        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 841            !type->tc_param_valid)
 842                return;
 843
 844        if (pgid < 0 || pgid >= QLC_DCB_MAX_PG)
 845                return;
 846
 847        pgcfg = &type->pg_cfg[pgid];
 848        if (!pgcfg->valid)
 849                return;
 850
 851        *bw_pct = pgcfg->total_bw_percent;
 852}
 853
 854static void qlcnic_dcb_get_pfc_cfg(struct net_device *netdev, int prio,
 855                                   u8 *setting)
 856{
 857        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 858        struct qlcnic_dcb_tc_cfg *tc_cfg;
 859        u8 val = QLC_DCB_GET_MAP(prio);
 860        struct qlcnic_dcb_cee *type;
 861        u8 i;
 862
 863        *setting = 0;
 864        type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 865
 866        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state) ||
 867            !type->pfc_mode_enable)
 868                return;
 869
 870        for (i = 0; i < QLC_DCB_MAX_TC; i++) {
 871                tc_cfg = &type->tc_cfg[i];
 872                if (!tc_cfg->valid)
 873                        continue;
 874
 875                if ((val & tc_cfg->up_tc_map) && (tc_cfg->prio_cfg[prio].valid))
 876                        *setting = tc_cfg->prio_cfg[prio].pfc_type;
 877        }
 878}
 879
 880static u8 qlcnic_dcb_get_capability(struct net_device *netdev, int capid,
 881                                    u8 *cap)
 882{
 883        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 884
 885        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 886                return 1;
 887
 888        switch (capid) {
 889        case DCB_CAP_ATTR_PG:
 890        case DCB_CAP_ATTR_UP2TC:
 891        case DCB_CAP_ATTR_PFC:
 892        case DCB_CAP_ATTR_GSP:
 893                *cap = true;
 894                break;
 895        case DCB_CAP_ATTR_PG_TCS:
 896        case DCB_CAP_ATTR_PFC_TCS:
 897                *cap = 0x80;    /* 8 priorities for PGs */
 898                break;
 899        case DCB_CAP_ATTR_DCBX:
 900                *cap = adapter->dcb->cfg->capability.dcb_capability;
 901                break;
 902        default:
 903                *cap = false;
 904        }
 905
 906        return 0;
 907}
 908
 909static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
 910{
 911        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 912        struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 913
 914        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 915                return -EINVAL;
 916
 917        switch (attr) {
 918        case DCB_NUMTCS_ATTR_PG:
 919                *num = cfg->capability.max_ets_tc;
 920                return 0;
 921        case DCB_NUMTCS_ATTR_PFC:
 922                *num = cfg->capability.max_pfc_tc;
 923                return 0;
 924        default:
 925                return -EINVAL;
 926        }
 927}
 928
 929static int qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
 930{
 931        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 932        struct dcb_app app = {
 933                                .selector = idtype,
 934                                .protocol = id,
 935                             };
 936
 937        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 938                return -EINVAL;
 939
 940        return dcb_getapp(netdev, &app);
 941}
 942
 943static u8 qlcnic_dcb_get_pfc_state(struct net_device *netdev)
 944{
 945        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 946        struct qlcnic_dcb *dcb = adapter->dcb;
 947
 948        if (!test_bit(QLCNIC_DCB_STATE, &dcb->state))
 949                return 0;
 950
 951        return dcb->cfg->type[QLC_DCB_OPER_IDX].pfc_mode_enable;
 952}
 953
 954static u8 qlcnic_dcb_get_dcbx(struct net_device *netdev)
 955{
 956        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 957        struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
 958
 959        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 960                return 0;
 961
 962        return cfg->capability.dcb_capability;
 963}
 964
 965static u8 qlcnic_dcb_get_feat_cfg(struct net_device *netdev, int fid, u8 *flag)
 966{
 967        struct qlcnic_adapter *adapter = netdev_priv(netdev);
 968        struct qlcnic_dcb_cee *type;
 969
 970        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
 971                return 1;
 972
 973        type = &adapter->dcb->cfg->type[QLC_DCB_OPER_IDX];
 974        *flag = 0;
 975
 976        switch (fid) {
 977        case DCB_FEATCFG_ATTR_PG:
 978                if (type->tc_param_valid)
 979                        *flag |= DCB_FEATCFG_ENABLE;
 980                else
 981                        *flag |= DCB_FEATCFG_ERROR;
 982                break;
 983        case DCB_FEATCFG_ATTR_PFC:
 984                if (type->pfc_mode_enable) {
 985                        if (type->tc_cfg[0].prio_cfg[0].pfc_type)
 986                                *flag |= DCB_FEATCFG_ENABLE;
 987                } else {
 988                        *flag |= DCB_FEATCFG_ERROR;
 989                }
 990                break;
 991        case DCB_FEATCFG_ATTR_APP:
 992                *flag |= DCB_FEATCFG_ENABLE;
 993                break;
 994        default:
 995                netdev_err(netdev, "Invalid Feature ID %d\n", fid);
 996                return 1;
 997        }
 998
 999        return 0;
1000}
1001
1002static inline void
1003qlcnic_dcb_get_pg_tc_cfg_rx(struct net_device *netdev, int prio, u8 *prio_type,
1004                            u8 *pgid, u8 *bw_pct, u8 *up_map)
1005{
1006        *prio_type = *pgid = *bw_pct = *up_map = 0;
1007}
1008
1009static inline void
1010qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device *netdev, int pgid, u8 *bw_pct)
1011{
1012        *bw_pct = 0;
1013}
1014
1015static int qlcnic_dcb_peer_app_info(struct net_device *netdev,
1016                                    struct dcb_peer_app_info *info,
1017                                    u16 *app_count)
1018{
1019        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1020        struct qlcnic_dcb_cee *peer;
1021        int i;
1022
1023        memset(info, 0, sizeof(*info));
1024        *app_count = 0;
1025
1026        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
1027                return 0;
1028
1029        peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
1030
1031        for (i = 0; i < QLC_DCB_MAX_APP; i++) {
1032                if (peer->app[i].valid)
1033                        (*app_count)++;
1034        }
1035
1036        return 0;
1037}
1038
1039static int qlcnic_dcb_peer_app_table(struct net_device *netdev,
1040                                     struct dcb_app *table)
1041{
1042        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1043        struct qlcnic_dcb_cee *peer;
1044        struct qlcnic_dcb_app *app;
1045        int i, j;
1046
1047        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
1048                return 0;
1049
1050        peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
1051
1052        for (i = 0, j = 0; i < QLC_DCB_MAX_APP; i++) {
1053                app = &peer->app[i];
1054                if (!app->valid)
1055                        continue;
1056
1057                table[j].selector = app->selector;
1058                table[j].priority = app->priority;
1059                table[j++].protocol = app->protocol;
1060        }
1061
1062        return 0;
1063}
1064
1065static int qlcnic_dcb_cee_peer_get_pg(struct net_device *netdev,
1066                                      struct cee_pg *pg)
1067{
1068        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1069        struct qlcnic_dcb_cee *peer;
1070        u8 i, j, k, map;
1071
1072        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
1073                return 0;
1074
1075        peer = &adapter->dcb->cfg->type[QLC_DCB_PEER_IDX];
1076
1077        for (i = 0, j = 0; i < QLC_DCB_MAX_PG; i++) {
1078                if (!peer->pg_cfg[i].valid)
1079                        continue;
1080
1081                pg->pg_bw[j] = peer->pg_cfg[i].total_bw_percent;
1082
1083                for (k = 0; k < QLC_DCB_MAX_TC; k++) {
1084                        if (peer->tc_cfg[i].valid &&
1085                            (peer->tc_cfg[i].pgid == i)) {
1086                                map = peer->tc_cfg[i].up_tc_map;
1087                                pg->prio_pg[j++] = map;
1088                                break;
1089                        }
1090                }
1091        }
1092
1093        return 0;
1094}
1095
1096static int qlcnic_dcb_cee_peer_get_pfc(struct net_device *netdev,
1097                                       struct cee_pfc *pfc)
1098{
1099        struct qlcnic_adapter *adapter = netdev_priv(netdev);
1100        struct qlcnic_dcb_cfg *cfg = adapter->dcb->cfg;
1101        struct qlcnic_dcb_tc_cfg *tc;
1102        struct qlcnic_dcb_cee *peer;
1103        u8 i, setting, prio;
1104
1105        pfc->pfc_en = 0;
1106
1107        if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
1108                return 0;
1109
1110        peer = &cfg->type[QLC_DCB_PEER_IDX];
1111
1112        for (i = 0; i < QLC_DCB_MAX_TC; i++) {
1113                tc = &peer->tc_cfg[i];
1114                prio = qlcnic_dcb_prio_count(tc->up_tc_map);
1115
1116                setting = 0;
1117                qlcnic_dcb_get_pfc_cfg(netdev, prio, &setting);
1118                if (setting)
1119                        pfc->pfc_en |= QLC_DCB_GET_MAP(i);
1120        }
1121
1122        pfc->tcs_supported = cfg->capability.max_pfc_tc;
1123
1124        return 0;
1125}
1126
1127static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops = {
1128        .getstate               = qlcnic_dcb_get_state,
1129        .getpermhwaddr          = qlcnic_dcb_get_perm_hw_addr,
1130        .getpgtccfgtx           = qlcnic_dcb_get_pg_tc_cfg_tx,
1131        .getpgbwgcfgtx          = qlcnic_dcb_get_pg_bwg_cfg_tx,
1132        .getpfccfg              = qlcnic_dcb_get_pfc_cfg,
1133        .getcap                 = qlcnic_dcb_get_capability,
1134        .getnumtcs              = qlcnic_dcb_get_num_tcs,
1135        .getapp                 = qlcnic_dcb_get_app,
1136        .getpfcstate            = qlcnic_dcb_get_pfc_state,
1137        .getdcbx                = qlcnic_dcb_get_dcbx,
1138        .getfeatcfg             = qlcnic_dcb_get_feat_cfg,
1139
1140        .getpgtccfgrx           = qlcnic_dcb_get_pg_tc_cfg_rx,
1141        .getpgbwgcfgrx          = qlcnic_dcb_get_pg_bwg_cfg_rx,
1142
1143        .peer_getappinfo        = qlcnic_dcb_peer_app_info,
1144        .peer_getapptable       = qlcnic_dcb_peer_app_table,
1145        .cee_peer_getpg         = qlcnic_dcb_cee_peer_get_pg,
1146        .cee_peer_getpfc        = qlcnic_dcb_cee_peer_get_pfc,
1147};
1148