2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
5 * See LICENSE.qlcnic for copyright and licensing details.
8 #include <linux/types.h>
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
16 #define QLC_DCB_GET_MAP(V) (1 << V)
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
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)
38 #define QLC_DCB_LOCAL_PARAM_FWID 0x3
39 #define QLC_DCB_OPER_PARAM_FWID 0x1
40 #define QLC_DCB_PEER_PARAM_FWID 0x2
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)
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)
54 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops
;
56 static void qlcnic_dcb_aen_work(struct work_struct
*);
57 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*);
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
*);
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 *);
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 *);
75 struct qlcnic_dcb_capability
{
84 struct qlcnic_dcb_param
{
85 u32 hdr_prio_pfc_map
[2];
89 u32 app
[QLC_DCB_MAX_APP
];
92 struct qlcnic_dcb_mbx_params
{
93 /* 1st local, 2nd operational 3rd remote */
94 struct qlcnic_dcb_param type
[3];
98 struct qlcnic_82xx_dcb_param_mbx_le
{
99 __le32 hdr_prio_pfc_map
[2];
100 __le32 prio_pg_map
[2];
102 __le32 pg_tsa_map
[2];
103 __le32 app
[QLC_DCB_MAX_APP
];
106 enum qlcnic_dcb_selector
{
107 QLC_SELECTOR_DEF
= 0x0,
113 enum qlcnic_dcb_prio_type
{
119 enum qlcnic_dcb_pfc_type
{
120 QLC_PFC_DISABLED
= 0,
126 struct qlcnic_dcb_prio_cfg
{
128 enum qlcnic_dcb_pfc_type pfc_type
;
131 struct qlcnic_dcb_pg_cfg
{
133 u8 total_bw_percent
; /* of Link/ port BW */
138 struct qlcnic_dcb_tc_cfg
{
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 */
148 struct qlcnic_dcb_app
{
150 enum qlcnic_dcb_selector selector
;
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
];
160 bool pfc_mode_enable
;
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
;
170 static 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
,
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
,
183 static 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
,
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
,
196 static u8
qlcnic_dcb_get_num_app(struct qlcnic_adapter
*adapter
, u32 val
)
198 if (qlcnic_82xx_check(adapter
))
199 return QLC_82XX_DCB_GET_NUMAPP(val
);
201 return QLC_83XX_DCB_GET_NUMAPP(val
);
204 static inline u8
qlcnic_dcb_pfc_hdr_valid(struct qlcnic_adapter
*adapter
,
207 if (qlcnic_82xx_check(adapter
))
208 return QLC_82XX_DCB_PFC_VALID(val
);
210 return QLC_83XX_DCB_PFC_VALID(val
);
213 static inline u8
qlcnic_dcb_tsa_hdr_valid(struct qlcnic_adapter
*adapter
,
216 if (qlcnic_82xx_check(adapter
))
217 return QLC_82XX_DCB_TSA_VALID(val
);
219 return QLC_83XX_DCB_TSA_VALID(val
);
222 static inline u8
qlcnic_dcb_get_prio_map_app(struct qlcnic_adapter
*adapter
,
225 if (qlcnic_82xx_check(adapter
))
226 return QLC_82XX_DCB_GET_PRIOMAP_APP(val
);
228 return QLC_83XX_DCB_GET_PRIOMAP_APP(val
);
231 static int qlcnic_dcb_prio_count(u8 up_tc_map
)
235 for (j
= 0; j
< QLC_DCB_MAX_TC
; j
++)
236 if (up_tc_map
& QLC_DCB_GET_MAP(j
))
242 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb
*dcb
)
244 if (test_bit(QLCNIC_DCB_STATE
, &dcb
->state
))
245 dcb
->adapter
->netdev
->dcbnl_ops
= &qlcnic_dcbnl_ops
;
248 static void qlcnic_set_dcb_ops(struct qlcnic_adapter
*adapter
)
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
;
256 int qlcnic_register_dcb(struct qlcnic_adapter
*adapter
)
258 struct qlcnic_dcb
*dcb
;
260 if (qlcnic_sriov_vf_check(adapter
))
263 dcb
= kzalloc(sizeof(struct qlcnic_dcb
), GFP_ATOMIC
);
268 dcb
->adapter
= adapter
;
269 qlcnic_set_dcb_ops(adapter
);
275 static void __qlcnic_dcb_free(struct qlcnic_dcb
*dcb
)
277 struct qlcnic_adapter
*adapter
;
282 adapter
= dcb
->adapter
;
284 while (test_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
285 usleep_range(10000, 11000);
287 cancel_delayed_work_sync(&dcb
->aen_work
);
290 destroy_workqueue(dcb
->wq
);
302 static void __qlcnic_dcb_get_info(struct qlcnic_dcb
*dcb
)
304 qlcnic_dcb_get_hw_capability(dcb
);
305 qlcnic_dcb_get_cee_cfg(dcb
);
308 static int __qlcnic_dcb_attach(struct qlcnic_dcb
*dcb
)
312 INIT_DELAYED_WORK(&dcb
->aen_work
, qlcnic_dcb_aen_work
);
314 dcb
->wq
= create_singlethread_workqueue("qlcnic-dcb");
316 dev_err(&dcb
->adapter
->pdev
->dev
,
317 "DCB workqueue allocation failed. DCB will be disabled\n");
321 dcb
->cfg
= kzalloc(sizeof(struct qlcnic_dcb_cfg
), GFP_ATOMIC
);
327 dcb
->param
= kzalloc(sizeof(struct qlcnic_dcb_mbx_params
), GFP_ATOMIC
);
333 qlcnic_dcb_get_info(dcb
);
341 destroy_workqueue(dcb
->wq
);
347 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb
*dcb
, char *buf
)
349 struct qlcnic_adapter
*adapter
= dcb
->adapter
;
350 struct qlcnic_cmd_args cmd
;
354 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_CAP
);
358 err
= qlcnic_issue_cmd(adapter
, &cmd
);
360 dev_err(&adapter
->pdev
->dev
,
361 "Failed to query DCBX capability, err %d\n", err
);
363 mbx_out
= cmd
.rsp
.arg
[1];
365 memcpy(buf
, &mbx_out
, sizeof(u32
));
368 qlcnic_free_mbx_args(&cmd
);
373 static int __qlcnic_dcb_get_capability(struct qlcnic_dcb
*dcb
, u32
*val
)
375 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
379 memset(cap
, 0, sizeof(struct qlcnic_dcb_capability
));
381 err
= qlcnic_dcb_query_hw_capability(dcb
, (char *)val
);
386 if (QLC_DCB_TSA_SUPPORT(mbx_out
))
387 cap
->tsa_capability
= true;
389 if (QLC_DCB_ETS_SUPPORT(mbx_out
))
390 cap
->ets_capability
= true;
392 cap
->max_num_tc
= QLC_DCB_MAX_NUM_TC(mbx_out
);
393 cap
->max_ets_tc
= QLC_DCB_MAX_NUM_ETS_TC(mbx_out
);
394 cap
->max_pfc_tc
= QLC_DCB_MAX_NUM_PFC_TC(mbx_out
);
396 if (cap
->max_num_tc
> QLC_DCB_MAX_TC
||
397 cap
->max_ets_tc
> cap
->max_num_tc
||
398 cap
->max_pfc_tc
> cap
->max_num_tc
) {
399 dev_err(&dcb
->adapter
->pdev
->dev
, "Invalid DCB configuration\n");
406 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
408 struct qlcnic_dcb_cfg
*cfg
= dcb
->cfg
;
409 struct qlcnic_dcb_capability
*cap
;
413 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
417 cap
= &cfg
->capability
;
418 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
| DCB_CAP_DCBX_LLD_MANAGED
;
420 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
421 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
426 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
429 u16 size
= sizeof(struct qlcnic_82xx_dcb_param_mbx_le
);
430 struct qlcnic_adapter
*adapter
= dcb
->adapter
;
431 struct qlcnic_82xx_dcb_param_mbx_le
*prsp_le
;
432 struct device
*dev
= &adapter
->pdev
->dev
;
433 dma_addr_t cardrsp_phys_addr
;
434 struct qlcnic_dcb_param rsp
;
435 struct qlcnic_cmd_args cmd
;
441 case QLC_DCB_LOCAL_PARAM_FWID
:
442 case QLC_DCB_OPER_PARAM_FWID
:
443 case QLC_DCB_PEER_PARAM_FWID
:
446 dev_err(dev
, "Invalid parameter type %d\n", type
);
450 addr
= dma_alloc_coherent(dev
, size
, &cardrsp_phys_addr
, GFP_KERNEL
);
456 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
460 phys_addr
= cardrsp_phys_addr
;
461 cmd
.req
.arg
[1] = size
| (type
<< 16);
462 cmd
.req
.arg
[2] = MSD(phys_addr
);
463 cmd
.req
.arg
[3] = LSD(phys_addr
);
465 err
= qlcnic_issue_cmd(adapter
, &cmd
);
467 dev_err(dev
, "Failed to query DCBX parameter, err %d\n", err
);
471 memset(&rsp
, 0, sizeof(struct qlcnic_dcb_param
));
472 rsp
.hdr_prio_pfc_map
[0] = le32_to_cpu(prsp_le
->hdr_prio_pfc_map
[0]);
473 rsp
.hdr_prio_pfc_map
[1] = le32_to_cpu(prsp_le
->hdr_prio_pfc_map
[1]);
474 rsp
.prio_pg_map
[0] = le32_to_cpu(prsp_le
->prio_pg_map
[0]);
475 rsp
.prio_pg_map
[1] = le32_to_cpu(prsp_le
->prio_pg_map
[1]);
476 rsp
.pg_bw_map
[0] = le32_to_cpu(prsp_le
->pg_bw_map
[0]);
477 rsp
.pg_bw_map
[1] = le32_to_cpu(prsp_le
->pg_bw_map
[1]);
478 rsp
.pg_tsa_map
[0] = le32_to_cpu(prsp_le
->pg_tsa_map
[0]);
479 rsp
.pg_tsa_map
[1] = le32_to_cpu(prsp_le
->pg_tsa_map
[1]);
481 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++)
482 rsp
.app
[i
] = le32_to_cpu(prsp_le
->app
[i
]);
485 memcpy(buf
, &rsp
, size
);
487 qlcnic_free_mbx_args(&cmd
);
490 dma_free_coherent(dev
, size
, addr
, cardrsp_phys_addr
);
495 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
497 struct qlcnic_dcb_mbx_params
*mbx
;
504 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[0],
505 QLC_DCB_LOCAL_PARAM_FWID
);
509 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[1],
510 QLC_DCB_OPER_PARAM_FWID
);
514 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[2],
515 QLC_DCB_PEER_PARAM_FWID
);
519 mbx
->prio_tc_map
= QLC_82XX_DCB_PRIO_TC_MAP
;
521 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
526 static void qlcnic_dcb_aen_work(struct work_struct
*work
)
528 struct qlcnic_dcb
*dcb
;
530 dcb
= container_of(work
, struct qlcnic_dcb
, aen_work
.work
);
532 qlcnic_dcb_get_cee_cfg(dcb
);
533 clear_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
);
536 static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
538 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
541 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
544 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
546 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
550 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
555 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
;
557 cap
->dcb_capability
|= DCB_CAP_DCBX_VER_IEEE
;
558 if (cap
->dcb_capability
)
559 cap
->dcb_capability
|= DCB_CAP_DCBX_LLD_MANAGED
;
561 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
562 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
567 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
570 struct qlcnic_adapter
*adapter
= dcb
->adapter
;
571 struct qlcnic_dcb_mbx_params mbx_out
;
572 int err
, i
, j
, k
, max_app
, size
;
573 struct qlcnic_dcb_param
*each
;
574 struct qlcnic_cmd_args cmd
;
579 memset(&mbx_out
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
580 memset(buf
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
582 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
586 cmd
.req
.arg
[0] |= QLC_DCB_FW_VER
<< 29;
587 err
= qlcnic_issue_cmd(adapter
, &cmd
);
589 dev_err(&adapter
->pdev
->dev
,
590 "Failed to query DCBX param, err %d\n", err
);
594 mbx_out
.prio_tc_map
= cmd
.rsp
.arg
[1];
595 p
= memcpy(buf
, &mbx_out
, sizeof(u32
));
599 for (j
= 0; j
< QLC_DCB_NUM_PARAM
; j
++) {
600 each
= &mbx_out
.type
[j
];
602 each
->hdr_prio_pfc_map
[0] = cmd
.rsp
.arg
[k
++];
603 each
->hdr_prio_pfc_map
[1] = cmd
.rsp
.arg
[k
++];
604 each
->prio_pg_map
[0] = cmd
.rsp
.arg
[k
++];
605 each
->prio_pg_map
[1] = cmd
.rsp
.arg
[k
++];
606 each
->pg_bw_map
[0] = cmd
.rsp
.arg
[k
++];
607 each
->pg_bw_map
[1] = cmd
.rsp
.arg
[k
++];
608 each
->pg_tsa_map
[0] = cmd
.rsp
.arg
[k
++];
609 each
->pg_tsa_map
[1] = cmd
.rsp
.arg
[k
++];
610 val
= each
->hdr_prio_pfc_map
[0];
612 max_app
= qlcnic_dcb_get_num_app(adapter
, val
);
613 for (i
= 0; i
< max_app
; i
++)
614 each
->app
[i
] = cmd
.rsp
.arg
[i
+ k
];
616 size
= 16 * sizeof(u32
);
617 memcpy(p
, &each
->hdr_prio_pfc_map
[0], size
);
625 qlcnic_free_mbx_args(&cmd
);
630 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
634 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)dcb
->param
, 0);
638 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
643 static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
647 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
651 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
653 clear_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
655 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
658 static void qlcnic_dcb_fill_cee_tc_params(struct qlcnic_dcb_mbx_params
*mbx
,
659 struct qlcnic_dcb_param
*each
,
660 struct qlcnic_dcb_cee
*type
)
662 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
665 for (i
= 0; i
< QLC_DCB_MAX_PRIO
; i
++) {
666 tc
= QLC_DCB_GET_TC_PRIO(mbx
->prio_tc_map
, i
);
667 tc_cfg
= &type
->tc_cfg
[tc
];
668 tc_cfg
->valid
= true;
669 tc_cfg
->up_tc_map
|= QLC_DCB_GET_MAP(i
);
671 if (QLC_DCB_GET_PFC_PRIO(each
->hdr_prio_pfc_map
[1], i
) &&
672 type
->pfc_mode_enable
) {
673 tc_cfg
->prio_cfg
[i
].valid
= true;
674 tc_cfg
->prio_cfg
[i
].pfc_type
= QLC_PFC_FULL
;
678 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[0], i
);
680 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[1], i
);
684 tc_cfg
->prio_type
= QLC_PRIO_LINK
;
685 type
->pg_cfg
[tc_cfg
->pgid
].prio_count
++;
689 static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param
*each
,
690 struct qlcnic_dcb_cee
*type
)
692 struct qlcnic_dcb_pg_cfg
*pg_cfg
;
695 for (i
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
696 pg_cfg
= &type
->pg_cfg
[i
];
697 pg_cfg
->valid
= true;
700 bw_per
= QLC_DCB_GET_BWPER_PG(each
->pg_bw_map
[0], i
);
701 tsa
= QLC_DCB_GET_TSA_PG(each
->pg_tsa_map
[0], i
);
703 bw_per
= QLC_DCB_GET_BWPER_PG(each
->pg_bw_map
[1], i
);
704 tsa
= QLC_DCB_GET_TSA_PG(each
->pg_tsa_map
[1], i
);
707 pg_cfg
->total_bw_percent
= bw_per
;
708 pg_cfg
->tsa_type
= tsa
;
713 qlcnic_dcb_fill_cee_app_params(struct qlcnic_adapter
*adapter
, u8 idx
,
714 struct qlcnic_dcb_param
*each
,
715 struct qlcnic_dcb_cee
*type
)
717 struct qlcnic_dcb_app
*app
;
718 u8 i
, num_app
, map
, cnt
;
719 struct dcb_app new_app
;
721 num_app
= qlcnic_dcb_get_num_app(adapter
, each
->hdr_prio_pfc_map
[0]);
722 for (i
= 0; i
< num_app
; i
++) {
726 /* Only for CEE (-1) */
727 app
->selector
= QLC_DCB_GET_SELECTOR_APP(each
->app
[i
]) - 1;
728 new_app
.selector
= app
->selector
;
729 app
->protocol
= QLC_DCB_GET_PROTO_ID_APP(each
->app
[i
]);
730 new_app
.protocol
= app
->protocol
;
731 map
= qlcnic_dcb_get_prio_map_app(adapter
, each
->app
[i
]);
732 cnt
= qlcnic_dcb_prio_count(map
);
734 if (cnt
>= QLC_DCB_MAX_TC
)
738 new_app
.priority
= cnt
;
740 if (idx
== QLC_DCB_OPER_IDX
&& adapter
->netdev
->dcbnl_ops
)
741 dcb_setapp(adapter
->netdev
, &new_app
);
745 static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter
*adapter
, u8 idx
)
747 struct qlcnic_dcb_mbx_params
*mbx
= adapter
->dcb
->param
;
748 struct qlcnic_dcb_param
*each
= &mbx
->type
[idx
];
749 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
750 struct qlcnic_dcb_cee
*type
= &cfg
->type
[idx
];
752 type
->tc_param_valid
= false;
753 type
->pfc_mode_enable
= false;
754 memset(type
->tc_cfg
, 0,
755 sizeof(struct qlcnic_dcb_tc_cfg
) * QLC_DCB_MAX_TC
);
756 memset(type
->pg_cfg
, 0,
757 sizeof(struct qlcnic_dcb_pg_cfg
) * QLC_DCB_MAX_TC
);
759 if (qlcnic_dcb_pfc_hdr_valid(adapter
, each
->hdr_prio_pfc_map
[0]) &&
760 cfg
->capability
.max_pfc_tc
)
761 type
->pfc_mode_enable
= true;
763 if (qlcnic_dcb_tsa_hdr_valid(adapter
, each
->hdr_prio_pfc_map
[0]) &&
764 cfg
->capability
.max_ets_tc
)
765 type
->tc_param_valid
= true;
767 qlcnic_dcb_fill_cee_tc_params(mbx
, each
, type
);
768 qlcnic_dcb_fill_cee_pg_params(each
, type
);
769 qlcnic_dcb_fill_cee_app_params(adapter
, idx
, each
, type
);
772 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*adapter
)
776 for (i
= 0; i
< QLC_DCB_NUM_PARAM
; i
++)
777 qlcnic_dcb_map_cee_params(adapter
, i
);
779 dcbnl_cee_notify(adapter
->netdev
, RTM_GETDCB
, DCB_CMD_CEE_GET
, 0, 0);
782 static u8
qlcnic_dcb_get_state(struct net_device
*netdev
)
784 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
786 return test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
);
789 static void qlcnic_dcb_get_perm_hw_addr(struct net_device
*netdev
, u8
*addr
)
791 memcpy(addr
, netdev
->perm_addr
, netdev
->addr_len
);
795 qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device
*netdev
, int tc
, u8
*prio
,
796 u8
*pgid
, u8
*bw_per
, u8
*up_tc_map
)
798 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
799 struct qlcnic_dcb_tc_cfg
*tc_cfg
, *temp
;
800 struct qlcnic_dcb_cee
*type
;
803 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
804 *prio
= *pgid
= *bw_per
= *up_tc_map
= 0;
806 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
807 !type
->tc_param_valid
)
810 if (tc
< 0 || (tc
> QLC_DCB_MAX_TC
))
813 tc_cfg
= &type
->tc_cfg
[tc
];
817 *pgid
= tc_cfg
->pgid
;
818 *prio
= tc_cfg
->prio_type
;
819 *up_tc_map
= tc_cfg
->up_tc_map
;
822 for (i
= 0, cnt
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
823 temp
= &type
->tc_cfg
[i
];
824 if (temp
->valid
&& (pg
== temp
->pgid
))
828 tc_cfg
->bwg_percent
= (100 / cnt
);
829 *bw_per
= tc_cfg
->bwg_percent
;
832 static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
835 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
836 struct qlcnic_dcb_pg_cfg
*pgcfg
;
837 struct qlcnic_dcb_cee
*type
;
840 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
842 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
843 !type
->tc_param_valid
)
846 if (pgid
< 0 || pgid
> QLC_DCB_MAX_PG
)
849 pgcfg
= &type
->pg_cfg
[pgid
];
853 *bw_pct
= pgcfg
->total_bw_percent
;
856 static void qlcnic_dcb_get_pfc_cfg(struct net_device
*netdev
, int prio
,
859 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
860 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
861 u8 val
= QLC_DCB_GET_MAP(prio
);
862 struct qlcnic_dcb_cee
*type
;
866 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
868 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
869 !type
->pfc_mode_enable
)
872 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
873 tc_cfg
= &type
->tc_cfg
[i
];
877 if ((val
& tc_cfg
->up_tc_map
) && (tc_cfg
->prio_cfg
[prio
].valid
))
878 *setting
= tc_cfg
->prio_cfg
[prio
].pfc_type
;
882 static u8
qlcnic_dcb_get_capability(struct net_device
*netdev
, int capid
,
885 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
887 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
891 case DCB_CAP_ATTR_PG
:
892 case DCB_CAP_ATTR_UP2TC
:
893 case DCB_CAP_ATTR_PFC
:
894 case DCB_CAP_ATTR_GSP
:
897 case DCB_CAP_ATTR_PG_TCS
:
898 case DCB_CAP_ATTR_PFC_TCS
:
899 *cap
= 0x80; /* 8 priorities for PGs */
901 case DCB_CAP_ATTR_DCBX
:
902 *cap
= adapter
->dcb
->cfg
->capability
.dcb_capability
;
911 static int qlcnic_dcb_get_num_tcs(struct net_device
*netdev
, int attr
, u8
*num
)
913 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
914 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
916 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
920 case DCB_NUMTCS_ATTR_PG
:
921 *num
= cfg
->capability
.max_ets_tc
;
923 case DCB_NUMTCS_ATTR_PFC
:
924 *num
= cfg
->capability
.max_pfc_tc
;
931 static u8
qlcnic_dcb_get_app(struct net_device
*netdev
, u8 idtype
, u16 id
)
933 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
934 struct dcb_app app
= {
939 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
942 return dcb_getapp(netdev
, &app
);
945 static u8
qlcnic_dcb_get_pfc_state(struct net_device
*netdev
)
947 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
948 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
950 if (!test_bit(QLCNIC_DCB_STATE
, &dcb
->state
))
953 return dcb
->cfg
->type
[QLC_DCB_OPER_IDX
].pfc_mode_enable
;
956 static u8
qlcnic_dcb_get_dcbx(struct net_device
*netdev
)
958 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
959 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
961 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
964 return cfg
->capability
.dcb_capability
;
967 static u8
qlcnic_dcb_get_feat_cfg(struct net_device
*netdev
, int fid
, u8
*flag
)
969 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
970 struct qlcnic_dcb_cee
*type
;
972 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
975 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
979 case DCB_FEATCFG_ATTR_PG
:
980 if (type
->tc_param_valid
)
981 *flag
|= DCB_FEATCFG_ENABLE
;
983 *flag
|= DCB_FEATCFG_ERROR
;
985 case DCB_FEATCFG_ATTR_PFC
:
986 if (type
->pfc_mode_enable
) {
987 if (type
->tc_cfg
[0].prio_cfg
[0].pfc_type
)
988 *flag
|= DCB_FEATCFG_ENABLE
;
990 *flag
|= DCB_FEATCFG_ERROR
;
993 case DCB_FEATCFG_ATTR_APP
:
994 *flag
|= DCB_FEATCFG_ENABLE
;
997 netdev_err(netdev
, "Invalid Feature ID %d\n", fid
);
1005 qlcnic_dcb_get_pg_tc_cfg_rx(struct net_device
*netdev
, int prio
, u8
*prio_type
,
1006 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1008 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1012 qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
, u8
*bw_pct
)
1017 static int qlcnic_dcb_peer_app_info(struct net_device
*netdev
,
1018 struct dcb_peer_app_info
*info
,
1021 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1022 struct qlcnic_dcb_cee
*peer
;
1027 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1030 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1032 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1033 if (peer
->app
[i
].valid
)
1040 static int qlcnic_dcb_peer_app_table(struct net_device
*netdev
,
1041 struct dcb_app
*table
)
1043 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1044 struct qlcnic_dcb_cee
*peer
;
1045 struct qlcnic_dcb_app
*app
;
1048 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1051 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1053 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1054 app
= &peer
->app
[i
];
1058 table
[j
].selector
= app
->selector
;
1059 table
[j
].priority
= app
->priority
;
1060 table
[j
++].protocol
= app
->protocol
;
1066 static int qlcnic_dcb_cee_peer_get_pg(struct net_device
*netdev
,
1069 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1070 struct qlcnic_dcb_cee
*peer
;
1073 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1076 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1078 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
1079 if (!peer
->pg_cfg
[i
].valid
)
1082 pg
->pg_bw
[j
] = peer
->pg_cfg
[i
].total_bw_percent
;
1084 for (k
= 0; k
< QLC_DCB_MAX_TC
; k
++) {
1085 if (peer
->tc_cfg
[i
].valid
&&
1086 (peer
->tc_cfg
[i
].pgid
== i
)) {
1087 map
= peer
->tc_cfg
[i
].up_tc_map
;
1088 pg
->prio_pg
[j
++] = map
;
1097 static int qlcnic_dcb_cee_peer_get_pfc(struct net_device
*netdev
,
1098 struct cee_pfc
*pfc
)
1100 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1101 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
1102 struct qlcnic_dcb_tc_cfg
*tc
;
1103 struct qlcnic_dcb_cee
*peer
;
1104 u8 i
, setting
, prio
;
1108 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1111 peer
= &cfg
->type
[QLC_DCB_PEER_IDX
];
1113 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
1114 tc
= &peer
->tc_cfg
[i
];
1115 prio
= qlcnic_dcb_prio_count(tc
->up_tc_map
);
1118 qlcnic_dcb_get_pfc_cfg(netdev
, prio
, &setting
);
1120 pfc
->pfc_en
|= QLC_DCB_GET_MAP(i
);
1123 pfc
->tcs_supported
= cfg
->capability
.max_pfc_tc
;
1128 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops
= {
1129 .getstate
= qlcnic_dcb_get_state
,
1130 .getpermhwaddr
= qlcnic_dcb_get_perm_hw_addr
,
1131 .getpgtccfgtx
= qlcnic_dcb_get_pg_tc_cfg_tx
,
1132 .getpgbwgcfgtx
= qlcnic_dcb_get_pg_bwg_cfg_tx
,
1133 .getpfccfg
= qlcnic_dcb_get_pfc_cfg
,
1134 .getcap
= qlcnic_dcb_get_capability
,
1135 .getnumtcs
= qlcnic_dcb_get_num_tcs
,
1136 .getapp
= qlcnic_dcb_get_app
,
1137 .getpfcstate
= qlcnic_dcb_get_pfc_state
,
1138 .getdcbx
= qlcnic_dcb_get_dcbx
,
1139 .getfeatcfg
= qlcnic_dcb_get_feat_cfg
,
1141 .getpgtccfgrx
= qlcnic_dcb_get_pg_tc_cfg_rx
,
1142 .getpgbwgcfgrx
= qlcnic_dcb_get_pg_bwg_cfg_rx
,
1144 .peer_getappinfo
= qlcnic_dcb_peer_app_info
,
1145 .peer_getapptable
= qlcnic_dcb_peer_app_table
,
1146 .cee_peer_getpg
= qlcnic_dcb_cee_peer_get_pg
,
1147 .cee_peer_getpfc
= qlcnic_dcb_cee_peer_get_pfc
,