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 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
,
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 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
,
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
);
339 destroy_workqueue(dcb
->wq
);
345 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_dcb
*dcb
, char *buf
)
347 struct qlcnic_adapter
*adapter
= dcb
->adapter
;
348 struct qlcnic_cmd_args cmd
;
352 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_CAP
);
356 err
= qlcnic_issue_cmd(adapter
, &cmd
);
358 dev_err(&adapter
->pdev
->dev
,
359 "Failed to query DCBX capability, err %d\n", err
);
361 mbx_out
= cmd
.rsp
.arg
[1];
363 memcpy(buf
, &mbx_out
, sizeof(u32
));
366 qlcnic_free_mbx_args(&cmd
);
371 static int __qlcnic_dcb_get_capability(struct qlcnic_dcb
*dcb
, u32
*val
)
373 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
377 memset(cap
, 0, sizeof(struct qlcnic_dcb_capability
));
379 err
= qlcnic_dcb_query_hw_capability(dcb
, (char *)val
);
384 if (QLC_DCB_TSA_SUPPORT(mbx_out
))
385 cap
->tsa_capability
= true;
387 if (QLC_DCB_ETS_SUPPORT(mbx_out
))
388 cap
->ets_capability
= true;
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
);
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");
404 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
406 struct qlcnic_dcb_cfg
*cfg
= dcb
->cfg
;
407 struct qlcnic_dcb_capability
*cap
;
411 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
415 cap
= &cfg
->capability
;
416 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
| DCB_CAP_DCBX_LLD_MANAGED
;
418 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
419 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
424 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
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
;
439 case QLC_DCB_LOCAL_PARAM_FWID
:
440 case QLC_DCB_OPER_PARAM_FWID
:
441 case QLC_DCB_PEER_PARAM_FWID
:
444 dev_err(dev
, "Invalid parameter type %d\n", type
);
448 addr
= dma_alloc_coherent(dev
, size
, &cardrsp_phys_addr
, GFP_KERNEL
);
454 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
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
);
463 err
= qlcnic_issue_cmd(adapter
, &cmd
);
465 dev_err(dev
, "Failed to query DCBX parameter, err %d\n", err
);
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]);
479 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++)
480 rsp
.app
[i
] = le32_to_cpu(prsp_le
->app
[i
]);
483 memcpy(buf
, &rsp
, size
);
485 qlcnic_free_mbx_args(&cmd
);
488 dma_free_coherent(dev
, size
, addr
, cardrsp_phys_addr
);
493 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
495 struct qlcnic_dcb_mbx_params
*mbx
;
502 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[0],
503 QLC_DCB_LOCAL_PARAM_FWID
);
507 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[1],
508 QLC_DCB_OPER_PARAM_FWID
);
512 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)&mbx
->type
[2],
513 QLC_DCB_PEER_PARAM_FWID
);
517 mbx
->prio_tc_map
= QLC_82XX_DCB_PRIO_TC_MAP
;
519 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
524 static void qlcnic_dcb_aen_work(struct work_struct
*work
)
526 struct qlcnic_dcb
*dcb
;
528 dcb
= container_of(work
, struct qlcnic_dcb
, aen_work
.work
);
530 qlcnic_dcb_get_cee_cfg(dcb
);
531 clear_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
);
534 static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
536 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
539 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
542 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb
*dcb
)
544 struct qlcnic_dcb_capability
*cap
= &dcb
->cfg
->capability
;
548 err
= __qlcnic_dcb_get_capability(dcb
, &mbx_out
);
553 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
;
555 cap
->dcb_capability
|= DCB_CAP_DCBX_VER_IEEE
;
556 if (cap
->dcb_capability
)
557 cap
->dcb_capability
|= DCB_CAP_DCBX_LLD_MANAGED
;
559 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
560 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
565 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb
*dcb
,
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
;
577 memset(&mbx_out
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
578 memset(buf
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
580 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
584 cmd
.req
.arg
[0] |= QLC_DCB_FW_VER
<< 29;
585 err
= qlcnic_issue_cmd(adapter
, &cmd
);
587 dev_err(&adapter
->pdev
->dev
,
588 "Failed to query DCBX param, err %d\n", err
);
592 mbx_out
.prio_tc_map
= cmd
.rsp
.arg
[1];
593 p
= memcpy(buf
, &mbx_out
, sizeof(u32
));
597 for (j
= 0; j
< QLC_DCB_NUM_PARAM
; j
++) {
598 each
= &mbx_out
.type
[j
];
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];
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
];
614 size
= 16 * sizeof(u32
);
615 memcpy(p
, &each
->hdr_prio_pfc_map
[0], size
);
623 qlcnic_free_mbx_args(&cmd
);
628 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb
*dcb
)
632 err
= qlcnic_dcb_query_cee_param(dcb
, (char *)dcb
->param
, 0);
636 qlcnic_dcb_data_cee_param_map(dcb
->adapter
);
641 static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb
*dcb
, void *data
)
645 if (test_and_set_bit(QLCNIC_DCB_AEN_MODE
, &dcb
->state
))
649 set_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
651 clear_bit(QLCNIC_DCB_STATE
, &dcb
->state
);
653 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
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
)
660 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
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
);
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
;
676 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[0], i
);
678 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[1], i
);
682 tc_cfg
->prio_type
= QLC_PRIO_LINK
;
683 type
->pg_cfg
[tc_cfg
->pgid
].prio_count
++;
687 static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param
*each
,
688 struct qlcnic_dcb_cee
*type
)
690 struct qlcnic_dcb_pg_cfg
*pg_cfg
;
693 for (i
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
694 pg_cfg
= &type
->pg_cfg
[i
];
695 pg_cfg
->valid
= true;
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
);
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
);
705 pg_cfg
->total_bw_percent
= bw_per
;
706 pg_cfg
->tsa_type
= tsa
;
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
)
715 struct qlcnic_dcb_app
*app
;
716 u8 i
, num_app
, map
, cnt
;
717 struct dcb_app new_app
;
719 num_app
= qlcnic_dcb_get_num_app(adapter
, each
->hdr_prio_pfc_map
[0]);
720 for (i
= 0; i
< num_app
; i
++) {
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
);
732 if (cnt
>= QLC_DCB_MAX_TC
)
736 new_app
.priority
= cnt
;
738 if (idx
== QLC_DCB_OPER_IDX
&& adapter
->netdev
->dcbnl_ops
)
739 dcb_setapp(adapter
->netdev
, &new_app
);
743 static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter
*adapter
, u8 idx
)
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
];
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
);
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;
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;
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
);
770 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*adapter
)
774 for (i
= 0; i
< QLC_DCB_NUM_PARAM
; i
++)
775 qlcnic_dcb_map_cee_params(adapter
, i
);
777 dcbnl_cee_notify(adapter
->netdev
, RTM_GETDCB
, DCB_CMD_CEE_GET
, 0, 0);
780 static u8
qlcnic_dcb_get_state(struct net_device
*netdev
)
782 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
784 return test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
);
787 static void qlcnic_dcb_get_perm_hw_addr(struct net_device
*netdev
, u8
*addr
)
789 memcpy(addr
, netdev
->perm_addr
, netdev
->addr_len
);
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
)
796 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
797 struct qlcnic_dcb_tc_cfg
*tc_cfg
, *temp
;
798 struct qlcnic_dcb_cee
*type
;
801 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
802 *prio
= *pgid
= *bw_per
= *up_tc_map
= 0;
804 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
805 !type
->tc_param_valid
)
808 if (tc
< 0 || (tc
>= QLC_DCB_MAX_TC
))
811 tc_cfg
= &type
->tc_cfg
[tc
];
815 *pgid
= tc_cfg
->pgid
;
816 *prio
= tc_cfg
->prio_type
;
817 *up_tc_map
= tc_cfg
->up_tc_map
;
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
))
826 tc_cfg
->bwg_percent
= (100 / cnt
);
827 *bw_per
= tc_cfg
->bwg_percent
;
830 static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
833 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
834 struct qlcnic_dcb_pg_cfg
*pgcfg
;
835 struct qlcnic_dcb_cee
*type
;
838 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
840 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
841 !type
->tc_param_valid
)
844 if (pgid
< 0 || pgid
>= QLC_DCB_MAX_PG
)
847 pgcfg
= &type
->pg_cfg
[pgid
];
851 *bw_pct
= pgcfg
->total_bw_percent
;
854 static void qlcnic_dcb_get_pfc_cfg(struct net_device
*netdev
, int prio
,
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
;
864 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
866 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
) ||
867 !type
->pfc_mode_enable
)
870 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
871 tc_cfg
= &type
->tc_cfg
[i
];
875 if ((val
& tc_cfg
->up_tc_map
) && (tc_cfg
->prio_cfg
[prio
].valid
))
876 *setting
= tc_cfg
->prio_cfg
[prio
].pfc_type
;
880 static u8
qlcnic_dcb_get_capability(struct net_device
*netdev
, int capid
,
883 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
885 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
889 case DCB_CAP_ATTR_PG
:
890 case DCB_CAP_ATTR_UP2TC
:
891 case DCB_CAP_ATTR_PFC
:
892 case DCB_CAP_ATTR_GSP
:
895 case DCB_CAP_ATTR_PG_TCS
:
896 case DCB_CAP_ATTR_PFC_TCS
:
897 *cap
= 0x80; /* 8 priorities for PGs */
899 case DCB_CAP_ATTR_DCBX
:
900 *cap
= adapter
->dcb
->cfg
->capability
.dcb_capability
;
909 static int qlcnic_dcb_get_num_tcs(struct net_device
*netdev
, int attr
, u8
*num
)
911 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
912 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
914 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
918 case DCB_NUMTCS_ATTR_PG
:
919 *num
= cfg
->capability
.max_ets_tc
;
921 case DCB_NUMTCS_ATTR_PFC
:
922 *num
= cfg
->capability
.max_pfc_tc
;
929 static int qlcnic_dcb_get_app(struct net_device
*netdev
, u8 idtype
, u16 id
)
931 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
932 struct dcb_app app
= {
937 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
940 return dcb_getapp(netdev
, &app
);
943 static u8
qlcnic_dcb_get_pfc_state(struct net_device
*netdev
)
945 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
946 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
948 if (!test_bit(QLCNIC_DCB_STATE
, &dcb
->state
))
951 return dcb
->cfg
->type
[QLC_DCB_OPER_IDX
].pfc_mode_enable
;
954 static u8
qlcnic_dcb_get_dcbx(struct net_device
*netdev
)
956 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
957 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
959 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
962 return cfg
->capability
.dcb_capability
;
965 static u8
qlcnic_dcb_get_feat_cfg(struct net_device
*netdev
, int fid
, u8
*flag
)
967 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
968 struct qlcnic_dcb_cee
*type
;
970 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
973 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
977 case DCB_FEATCFG_ATTR_PG
:
978 if (type
->tc_param_valid
)
979 *flag
|= DCB_FEATCFG_ENABLE
;
981 *flag
|= DCB_FEATCFG_ERROR
;
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
;
988 *flag
|= DCB_FEATCFG_ERROR
;
991 case DCB_FEATCFG_ATTR_APP
:
992 *flag
|= DCB_FEATCFG_ENABLE
;
995 netdev_err(netdev
, "Invalid Feature ID %d\n", fid
);
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
)
1006 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1010 qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
, u8
*bw_pct
)
1015 static int qlcnic_dcb_peer_app_info(struct net_device
*netdev
,
1016 struct dcb_peer_app_info
*info
,
1019 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1020 struct qlcnic_dcb_cee
*peer
;
1023 memset(info
, 0, sizeof(*info
));
1026 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1029 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1031 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1032 if (peer
->app
[i
].valid
)
1039 static int qlcnic_dcb_peer_app_table(struct net_device
*netdev
,
1040 struct dcb_app
*table
)
1042 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1043 struct qlcnic_dcb_cee
*peer
;
1044 struct qlcnic_dcb_app
*app
;
1047 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1050 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1052 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1053 app
= &peer
->app
[i
];
1057 table
[j
].selector
= app
->selector
;
1058 table
[j
].priority
= app
->priority
;
1059 table
[j
++].protocol
= app
->protocol
;
1065 static int qlcnic_dcb_cee_peer_get_pg(struct net_device
*netdev
,
1068 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1069 struct qlcnic_dcb_cee
*peer
;
1072 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1075 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1077 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
1078 if (!peer
->pg_cfg
[i
].valid
)
1081 pg
->pg_bw
[j
] = peer
->pg_cfg
[i
].total_bw_percent
;
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
;
1096 static int qlcnic_dcb_cee_peer_get_pfc(struct net_device
*netdev
,
1097 struct cee_pfc
*pfc
)
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
;
1107 if (!test_bit(QLCNIC_DCB_STATE
, &adapter
->dcb
->state
))
1110 peer
= &cfg
->type
[QLC_DCB_PEER_IDX
];
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
);
1117 qlcnic_dcb_get_pfc_cfg(netdev
, prio
, &setting
);
1119 pfc
->pfc_en
|= QLC_DCB_GET_MAP(i
);
1122 pfc
->tcs_supported
= cfg
->capability
.max_pfc_tc
;
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
,
1140 .getpgtccfgrx
= qlcnic_dcb_get_pg_tc_cfg_rx
,
1141 .getpgbwgcfgrx
= qlcnic_dcb_get_pg_bwg_cfg_rx
,
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
,