root/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qlcnic_dcb_get_num_app
  2. qlcnic_dcb_pfc_hdr_valid
  3. qlcnic_dcb_tsa_hdr_valid
  4. qlcnic_dcb_get_prio_map_app
  5. qlcnic_dcb_prio_count
  6. __qlcnic_init_dcbnl_ops
  7. qlcnic_set_dcb_ops
  8. qlcnic_register_dcb
  9. __qlcnic_dcb_free
  10. __qlcnic_dcb_get_info
  11. __qlcnic_dcb_attach
  12. __qlcnic_dcb_query_hw_capability
  13. __qlcnic_dcb_get_capability
  14. qlcnic_82xx_dcb_get_hw_capability
  15. qlcnic_82xx_dcb_query_cee_param
  16. qlcnic_82xx_dcb_get_cee_cfg
  17. qlcnic_dcb_aen_work
  18. qlcnic_82xx_dcb_aen_handler
  19. qlcnic_83xx_dcb_get_hw_capability
  20. qlcnic_83xx_dcb_query_cee_param
  21. qlcnic_83xx_dcb_get_cee_cfg
  22. qlcnic_83xx_dcb_aen_handler
  23. qlcnic_dcb_fill_cee_tc_params
  24. qlcnic_dcb_fill_cee_pg_params
  25. qlcnic_dcb_fill_cee_app_params
  26. qlcnic_dcb_map_cee_params
  27. qlcnic_dcb_data_cee_param_map
  28. qlcnic_dcb_get_state
  29. qlcnic_dcb_get_perm_hw_addr
  30. qlcnic_dcb_get_pg_tc_cfg_tx
  31. qlcnic_dcb_get_pg_bwg_cfg_tx
  32. qlcnic_dcb_get_pfc_cfg
  33. qlcnic_dcb_get_capability
  34. qlcnic_dcb_get_num_tcs
  35. qlcnic_dcb_get_app
  36. qlcnic_dcb_get_pfc_state
  37. qlcnic_dcb_get_dcbx
  38. qlcnic_dcb_get_feat_cfg
  39. qlcnic_dcb_get_pg_tc_cfg_rx
  40. qlcnic_dcb_get_pg_bwg_cfg_rx
  41. qlcnic_dcb_peer_app_info
  42. qlcnic_dcb_peer_app_table
  43. qlcnic_dcb_cee_peer_get_pg
  44. qlcnic_dcb_cee_peer_get_pfc

   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 
  54 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops;
  55 
  56 static void qlcnic_dcb_aen_work(struct work_struct *);
  57 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter *);
  58 
  59 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb *);
  60 static void __qlcnic_dcb_free(struct qlcnic_dcb *);
  61 static int __qlcnic_dcb_attach(struct qlcnic_dcb *);
  62 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb *, char *);
  63 static void __qlcnic_dcb_get_info(struct qlcnic_dcb *);
  64 
  65 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb *);
  66 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
  67 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
  68 static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
  69 
  70 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *);
  71 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8);
  72 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *);
  73 static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *);
  74 
  75 struct 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 
  84 struct 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 
  92 struct 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 
  98 struct 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 
 106 enum qlcnic_dcb_selector {
 107         QLC_SELECTOR_DEF = 0x0,
 108         QLC_SELECTOR_ETHER,
 109         QLC_SELECTOR_TCP,
 110         QLC_SELECTOR_UDP,
 111 };
 112 
 113 enum qlcnic_dcb_prio_type {
 114         QLC_PRIO_NONE = 0,
 115         QLC_PRIO_GROUP,
 116         QLC_PRIO_LINK,
 117 };
 118 
 119 enum qlcnic_dcb_pfc_type {
 120         QLC_PFC_DISABLED = 0,
 121         QLC_PFC_FULL,
 122         QLC_PFC_TX,
 123         QLC_PFC_RX
 124 };
 125 
 126 struct qlcnic_dcb_prio_cfg {
 127         bool valid;
 128         enum qlcnic_dcb_pfc_type pfc_type;
 129 };
 130 
 131 struct 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 
 138 struct 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 
 148 struct qlcnic_dcb_app {
 149         bool valid;
 150         enum qlcnic_dcb_selector selector;
 151         u16 protocol;
 152         u8 priority;
 153 };
 154 
 155 struct 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 
 163 struct 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 
 170 static 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 
 183 static 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 
 196 static 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 
 204 static 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 
 213 static 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 
 222 static 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 
 231 static 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 
 242 static 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 
 248 static 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 
 256 int 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 
 275 static 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 
 302 static 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 
 308 static 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;
 334 out_free_cfg:
 335         kfree(dcb->cfg);
 336         dcb->cfg = NULL;
 337 
 338 out_free_wq:
 339         destroy_workqueue(dcb->wq);
 340         dcb->wq = NULL;
 341 
 342         return err;
 343 }
 344 
 345 static 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 
 371 static 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 
 404 static 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 
 424 static 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);
 484 out:
 485         qlcnic_free_mbx_args(&cmd);
 486 
 487 out_free_rsp:
 488         dma_free_coherent(dev, size, addr, cardrsp_phys_addr);
 489 
 490         return err;
 491 }
 492 
 493 static 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 
 524 static 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 
 534 static 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 
 542 static 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 
 565 static 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         }
 622 out:
 623         qlcnic_free_mbx_args(&cmd);
 624 
 625         return err;
 626 }
 627 
 628 static 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 
 641 static 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 
 656 static 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 
 687 static 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 
 710 static void
 711 qlcnic_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 
 743 static 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 
 770 static 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 
 780 static 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 
 787 static 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 
 792 static void
 793 qlcnic_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 
 830 static 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 
 854 static 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 
 880 static 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 
 909 static 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 
 929 static 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 
 943 static 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 
 954 static 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 
 965 static 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 
1002 static inline void
1003 qlcnic_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 
1009 static inline void
1010 qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device *netdev, int pgid, u8 *bw_pct)
1011 {
1012         *bw_pct = 0;
1013 }
1014 
1015 static 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 
1039 static 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 
1065 static 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 
1096 static 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 
1127 static 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 };

/* [<][>][^][v][top][bottom][index][help] */