cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qlcnic_dcb.c (28408B)


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