1 // SPDX-License-Identifier: GPL-2.0-only
3 * QLogic qlcnic NIC Driver
4 * Copyright (c) 2009-2013 QLogic Corporation
7 #include <linux/types.h>
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
15 #define QLC_DCB_GET_MAP(V) (1 << V)
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
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)
37 #define QLC_DCB_LOCAL_PARAM_FWID 0x3
38 #define QLC_DCB_OPER_PARAM_FWID 0x1
39 #define QLC_DCB_PEER_PARAM_FWID 0x2
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)
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)
53 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops
;
55 static void qlcnic_dcb_aen_work(struct work_struct
*);
56 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*);
58 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb
*);
59 static void __qlcnic_dcb_free(struct qlcnic_dcb
*);
60 static int __qlcnic_dcb_attach(struct qlcnic_dcb
*);
61 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb
*, char *);
62 static void __qlcnic_dcb_get_info(struct qlcnic_dcb
*);
64 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb
*);
65 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb
*, char *, u8
);
66 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb
*);
67 static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb
*, void *);
69 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb
*);
70 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb
*, char *, u8
);
71 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb
*);
72 static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb
*, void *);
74 struct qlcnic_dcb_capability
{
83 struct qlcnic_dcb_param
{
84 u32 hdr_prio_pfc_map
[2];
88 u32 app
[QLC_DCB_MAX_APP
];
91 struct qlcnic_dcb_mbx_params
{
92 /* 1st local, 2nd operational 3rd remote */
93 struct qlcnic_dcb_param type
[3];
97 struct qlcnic_82xx_dcb_param_mbx_le
{
98 __le32 hdr_prio_pfc_map
[2];
99 __le32 prio_pg_map
[2];
101 __le32 pg_tsa_map
[2];
102 __le32 app
[QLC_DCB_MAX_APP
];
105 enum qlcnic_dcb_selector
{
106 QLC_SELECTOR_DEF
= 0x0,
112 enum qlcnic_dcb_prio_type
{
118 enum qlcnic_dcb_pfc_type
{
119 QLC_PFC_DISABLED
= 0,
125 struct qlcnic_dcb_prio_cfg
{
127 enum qlcnic_dcb_pfc_type pfc_type
;
130 struct qlcnic_dcb_pg_cfg
{
132 u8 total_bw_percent
; /* of Link/ port BW */
137 struct qlcnic_dcb_tc_cfg
{
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 */
147 struct qlcnic_dcb_app
{
149 enum qlcnic_dcb_selector selector
;
154 struct 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
];
159 bool pfc_mode_enable
;
162 struct 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
;
169 static 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
,
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
,
182 static 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
,
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
,
195 static u8
qlcnic_dcb_get_num_app(struct qlcnic_adapter
*adapter
, u32 val
)
197 if (qlcnic_82xx_check(adapter
))
198 return QLC_82XX_DCB_GET_NUMAPP(val
);
200 return QLC_83XX_DCB_GET_NUMAPP(val
);
203 static inline u8
qlcnic_dcb_pfc_hdr_valid(struct qlcnic_adapter
*adapter
,
206 if (qlcnic_82xx_check(adapter
))
207 return QLC_82XX_DCB_PFC_VALID(val
);
209 return QLC_83XX_DCB_PFC_VALID(val
);
212 static inline u8
qlcnic_dcb_tsa_hdr_valid(struct qlcnic_adapter
*adapter
,
215 if (qlcnic_82xx_check(adapter
))
216 return QLC_82XX_DCB_TSA_VALID(val
);
218 return QLC_83XX_DCB_TSA_VALID(val
);
221 static inline u8
qlcnic_dcb_get_prio_map_app(struct qlcnic_adapter
*adapter
,
224 if (qlcnic_82xx_check(adapter
))
225 return QLC_82XX_DCB_GET_PRIOMAP_APP(val
);
227 return QLC_83XX_DCB_GET_PRIOMAP_APP(val
);
230 static int qlcnic_dcb_prio_count(u8 up_tc_map
)
234 for (j
= 0; j
< QLC_DCB_MAX_TC
; j
++)
235 if (up_tc_map
& QLC_DCB_GET_MAP(j
))
241 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_dcb
*dcb
)
243 if (test_bit(QLCNIC_DCB_STATE
, &dcb
->state
))
244 dcb
->adapter
->netdev
->dcbnl_ops
= &qlcnic_dcbnl_ops
;
247 static void qlcnic_set_dcb_ops(struct qlcnic_adapter
*adapter
)
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
;
255 int qlcnic_register_dcb(struct qlcnic_adapter
*adapter
)
257 struct qlcnic_dcb
*dcb
;
259 if (qlcnic_sriov_vf_check(adapter
))
262 dcb
= kzalloc(sizeof(struct qlcnic_dcb
), GFP_ATOMIC
);
267 dcb
->adapter
= adapter
;
268 qlcnic_set_dcb_ops(adapter
);
274 static void __qlcnic_dcb_free(struct qlcnic_dcb
*dcb
)
276 struct qlcnic_adapter
*adapter
;
281 adapter
= dcb
->adapter
;
283 while (test_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
284 usleep_range(10000, 11000);
286 cancel_delayed_work_sync(&dcb
->aen_work
);
289 destroy_workqueue(dcb
->wq
);
301 static void __qlcnic_dcb_get_info(struct qlcnic_dcb
*dcb
)
303 qlcnic_dcb_get_hw_capability(dcb
);
304 qlcnic_dcb_get_cee_cfg(dcb
);
307 static int __qlcnic_dcb_attach(struct qlcnic_dcb
*dcb
)
311 INIT_DELAYED_WORK(&dcb
->aen_work
, qlcnic_dcb_aen_work
);
313 dcb
->wq
= create_singlethread_workqueue("qlcnic-dcb");
315 dev_err(&dcb
->adapter
->pdev
->dev
,
316 "DCB workqueue allocation failed. DCB will be disabled\n");
320 dcb
->cfg
= kzalloc(sizeof(struct qlcnic_dcb_cfg
), GFP_ATOMIC
);
326 dcb
->param
= kzalloc(sizeof(struct qlcnic_dcb_mbx_params
), GFP_ATOMIC
);
338 destroy_workqueue(dcb
->wq
);
344 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb
*dcb
, char *buf
)
346 struct qlcnic_adapter
*adapter
= dcb
->adapter
;
347 struct qlcnic_cmd_args cmd
;
351 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_CAP
);
355 err
= qlcnic_issue_cmd(adapter
, &cmd
);
357 dev_err(&adapter
->pdev
->dev
,
358 "Failed to query DCBX capability, err %d\n", err
);
360 mbx_out
= cmd
.rsp
.arg
[1];
362 memcpy(buf
, &mbx_out
, sizeof(u32
));
365 qlcnic_free_mbx_args(&cmd
);
370 static int __qlcnic_dcb_get_capability(struct qlcnic_dcb
*dcb
, u32
*val
)
372 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
376 memset(cap
, 0, sizeof(struct qlcnic_dcb_capability
));
378 err
= qlcnic_dcb_query_hw_capability(dcb
, (char *)val
);
383 if (QLC_DCB_TSA_SUPPORT(mbx_out
))
384 cap
->tsa_capability
= true;
386 if (QLC_DCB_ETS_SUPPORT(mbx_out
))
387 cap
->ets_capability
= true;
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
);
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");
403 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
405 struct qlcnic_dcb_cfg
*cfg
= dcb
->cfg
;
406 struct qlcnic_dcb_capability
*cap
;
410 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
414 cap
= &cfg
->capability
;
415 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
| DCB_CAP_DCBX_LLD_MANAGED
;
417 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
418 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
423 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
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
;
438 case QLC_DCB_LOCAL_PARAM_FWID
:
439 case QLC_DCB_OPER_PARAM_FWID
:
440 case QLC_DCB_PEER_PARAM_FWID
:
443 dev_err(dev
, "Invalid parameter type %d\n", type
);
447 addr
= dma_alloc_coherent(dev
, size
, &cardrsp_phys_addr
, GFP_KERNEL
);
453 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
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
);
462 err
= qlcnic_issue_cmd(adapter
, &cmd
);
464 dev_err(dev
, "Failed to query DCBX parameter, err %d\n", err
);
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]);
478 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++)
479 rsp
.app
[i
] = le32_to_cpu(prsp_le
->app
[i
]);
482 memcpy(buf
, &rsp
, size
);
484 qlcnic_free_mbx_args(&cmd
);
487 dma_free_coherent(dev
, size
, addr
, cardrsp_phys_addr
);
492 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
494 struct qlcnic_dcb_mbx_params
*mbx
;
501 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[0],
502 QLC_DCB_LOCAL_PARAM_FWID
);
506 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[1],
507 QLC_DCB_OPER_PARAM_FWID
);
511 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[2],
512 QLC_DCB_PEER_PARAM_FWID
);
516 mbx
->prio_tc_map
= QLC_82XX_DCB_PRIO_TC_MAP
;
518 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
523 static void qlcnic_dcb_aen_work(struct work_struct
*work
)
525 struct qlcnic_dcb
*dcb
;
527 dcb
= container_of(work
, struct qlcnic_dcb
, aen_work
.work
);
529 qlcnic_dcb_get_cee_cfg(dcb
);
530 clear_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
);
533 static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
535 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
538 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
541 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
543 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
547 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
552 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
;
554 cap
->dcb_capability
|= DCB_CAP_DCBX_VER_IEEE
;
555 if (cap
->dcb_capability
)
556 cap
->dcb_capability
|= DCB_CAP_DCBX_LLD_MANAGED
;
558 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
559 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
564 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
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
;
576 memset(&mbx_out
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
577 memset(buf
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
579 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
583 cmd
.req
.arg
[0] |= QLC_DCB_FW_VER
<< 29;
584 err
= qlcnic_issue_cmd(adapter
, &cmd
);
586 dev_err(&adapter
->pdev
->dev
,
587 "Failed to query DCBX param, err %d\n", err
);
591 mbx_out
.prio_tc_map
= cmd
.rsp
.arg
[1];
592 p
= memcpy(buf
, &mbx_out
, sizeof(u32
));
596 for (j
= 0; j
< QLC_DCB_NUM_PARAM
; j
++) {
597 each
= &mbx_out
.type
[j
];
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];
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
];
613 size
= 16 * sizeof(u32
);
614 memcpy(p
, &each
->hdr_prio_pfc_map
[0], size
);
622 qlcnic_free_mbx_args(&cmd
);
627 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
631 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)dcb
->param
, 0);
635 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
640 static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
644 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
648 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
650 clear_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
652 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
655 static 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
)
659 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
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
);
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
;
675 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[0], i
);
677 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[1], i
);
681 tc_cfg
->prio_type
= QLC_PRIO_LINK
;
682 type
->pg_cfg
[tc_cfg
->pgid
].prio_count
++;
686 static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param
*each
,
687 struct qlcnic_dcb_cee
*type
)
689 struct qlcnic_dcb_pg_cfg
*pg_cfg
;
692 for (i
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
693 pg_cfg
= &type
->pg_cfg
[i
];
694 pg_cfg
->valid
= true;
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
);
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
);
704 pg_cfg
->total_bw_percent
= bw_per
;
705 pg_cfg
->tsa_type
= tsa
;
710 qlcnic_dcb_fill_cee_app_params(struct qlcnic_adapter
*adapter
, u8 idx
,
711 struct qlcnic_dcb_param
*each
,
712 struct qlcnic_dcb_cee
*type
)
714 struct qlcnic_dcb_app
*app
;
715 u8 i
, num_app
, map
, cnt
;
716 struct dcb_app new_app
;
718 num_app
= qlcnic_dcb_get_num_app(adapter
, each
->hdr_prio_pfc_map
[0]);
719 for (i
= 0; i
< num_app
; i
++) {
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
);
731 if (cnt
>= QLC_DCB_MAX_TC
)
735 new_app
.priority
= cnt
;
737 if (idx
== QLC_DCB_OPER_IDX
&& adapter
->netdev
->dcbnl_ops
)
738 dcb_setapp(adapter
->netdev
, &new_app
);
742 static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter
*adapter
, u8 idx
)
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
];
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
);
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;
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;
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
);
769 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*adapter
)
773 for (i
= 0; i
< QLC_DCB_NUM_PARAM
; i
++)
774 qlcnic_dcb_map_cee_params(adapter
, i
);
776 dcbnl_cee_notify(adapter
->netdev
, RTM_GETDCB
, DCB_CMD_CEE_GET
, 0, 0);
779 static u8
qlcnic_dcb_get_state(struct net_device
*netdev
)
781 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
783 return test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
);
786 static void qlcnic_dcb_get_perm_hw_addr(struct net_device
*netdev
, u8
*addr
)
788 memcpy(addr
, netdev
->perm_addr
, netdev
->addr_len
);
792 qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device
*netdev
, int tc
, u8
*prio
,
793 u8
*pgid
, u8
*bw_per
, u8
*up_tc_map
)
795 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
796 struct qlcnic_dcb_tc_cfg
*tc_cfg
, *temp
;
797 struct qlcnic_dcb_cee
*type
;
800 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
801 *prio
= *pgid
= *bw_per
= *up_tc_map
= 0;
803 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
804 !type
->tc_param_valid
)
807 if (tc
< 0 || (tc
>= QLC_DCB_MAX_TC
))
810 tc_cfg
= &type
->tc_cfg
[tc
];
814 *pgid
= tc_cfg
->pgid
;
815 *prio
= tc_cfg
->prio_type
;
816 *up_tc_map
= tc_cfg
->up_tc_map
;
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
))
825 tc_cfg
->bwg_percent
= (100 / cnt
);
826 *bw_per
= tc_cfg
->bwg_percent
;
829 static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
832 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
833 struct qlcnic_dcb_pg_cfg
*pgcfg
;
834 struct qlcnic_dcb_cee
*type
;
837 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
839 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
840 !type
->tc_param_valid
)
843 if (pgid
< 0 || pgid
>= QLC_DCB_MAX_PG
)
846 pgcfg
= &type
->pg_cfg
[pgid
];
850 *bw_pct
= pgcfg
->total_bw_percent
;
853 static void qlcnic_dcb_get_pfc_cfg(struct net_device
*netdev
, int prio
,
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
;
863 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
865 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
866 !type
->pfc_mode_enable
)
869 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
870 tc_cfg
= &type
->tc_cfg
[i
];
874 if ((val
& tc_cfg
->up_tc_map
) && (tc_cfg
->prio_cfg
[prio
].valid
))
875 *setting
= tc_cfg
->prio_cfg
[prio
].pfc_type
;
879 static u8
qlcnic_dcb_get_capability(struct net_device
*netdev
, int capid
,
882 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
884 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
888 case DCB_CAP_ATTR_PG
:
889 case DCB_CAP_ATTR_UP2TC
:
890 case DCB_CAP_ATTR_PFC
:
891 case DCB_CAP_ATTR_GSP
:
894 case DCB_CAP_ATTR_PG_TCS
:
895 case DCB_CAP_ATTR_PFC_TCS
:
896 *cap
= 0x80; /* 8 priorities for PGs */
898 case DCB_CAP_ATTR_DCBX
:
899 *cap
= adapter
->dcb
->cfg
->capability
.dcb_capability
;
908 static int qlcnic_dcb_get_num_tcs(struct net_device
*netdev
, int attr
, u8
*num
)
910 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
911 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
913 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
917 case DCB_NUMTCS_ATTR_PG
:
918 *num
= cfg
->capability
.max_ets_tc
;
920 case DCB_NUMTCS_ATTR_PFC
:
921 *num
= cfg
->capability
.max_pfc_tc
;
928 static int qlcnic_dcb_get_app(struct net_device
*netdev
, u8 idtype
, u16 id
)
930 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
931 struct dcb_app app
= {
936 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
939 return dcb_getapp(netdev
, &app
);
942 static u8
qlcnic_dcb_get_pfc_state(struct net_device
*netdev
)
944 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
945 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
947 if (!test_bit(QLCNIC_DCB_STATE
, &dcb
->state
))
950 return dcb
->cfg
->type
[QLC_DCB_OPER_IDX
].pfc_mode_enable
;
953 static u8
qlcnic_dcb_get_dcbx(struct net_device
*netdev
)
955 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
956 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
958 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
961 return cfg
->capability
.dcb_capability
;
964 static u8
qlcnic_dcb_get_feat_cfg(struct net_device
*netdev
, int fid
, u8
*flag
)
966 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
967 struct qlcnic_dcb_cee
*type
;
969 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
972 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
976 case DCB_FEATCFG_ATTR_PG
:
977 if (type
->tc_param_valid
)
978 *flag
|= DCB_FEATCFG_ENABLE
;
980 *flag
|= DCB_FEATCFG_ERROR
;
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
;
987 *flag
|= DCB_FEATCFG_ERROR
;
990 case DCB_FEATCFG_ATTR_APP
:
991 *flag
|= DCB_FEATCFG_ENABLE
;
994 netdev_err(netdev
, "Invalid Feature ID %d\n", fid
);
1002 qlcnic_dcb_get_pg_tc_cfg_rx(struct net_device
*netdev
, int prio
, u8
*prio_type
,
1003 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1005 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1009 qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
, u8
*bw_pct
)
1014 static int qlcnic_dcb_peer_app_info(struct net_device
*netdev
,
1015 struct dcb_peer_app_info
*info
,
1018 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1019 struct qlcnic_dcb_cee
*peer
;
1022 memset(info
, 0, sizeof(*info
));
1025 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1028 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1030 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1031 if (peer
->app
[i
].valid
)
1038 static int qlcnic_dcb_peer_app_table(struct net_device
*netdev
,
1039 struct dcb_app
*table
)
1041 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1042 struct qlcnic_dcb_cee
*peer
;
1043 struct qlcnic_dcb_app
*app
;
1046 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1049 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1051 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1052 app
= &peer
->app
[i
];
1056 table
[j
].selector
= app
->selector
;
1057 table
[j
].priority
= app
->priority
;
1058 table
[j
++].protocol
= app
->protocol
;
1064 static int qlcnic_dcb_cee_peer_get_pg(struct net_device
*netdev
,
1067 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1068 struct qlcnic_dcb_cee
*peer
;
1071 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1074 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1076 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
1077 if (!peer
->pg_cfg
[i
].valid
)
1080 pg
->pg_bw
[j
] = peer
->pg_cfg
[i
].total_bw_percent
;
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
;
1095 static int qlcnic_dcb_cee_peer_get_pfc(struct net_device
*netdev
,
1096 struct cee_pfc
*pfc
)
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
;
1106 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1109 peer
= &cfg
->type
[QLC_DCB_PEER_IDX
];
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
);
1116 qlcnic_dcb_get_pfc_cfg(netdev
, prio
, &setting
);
1118 pfc
->pfc_en
|= QLC_DCB_GET_MAP(i
);
1121 pfc
->tcs_supported
= cfg
->capability
.max_pfc_tc
;
1126 static 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
,
1139 .getpgtccfgrx
= qlcnic_dcb_get_pg_tc_cfg_rx
,
1140 .getpgbwgcfgrx
= qlcnic_dcb_get_pg_bwg_cfg_rx
,
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
,