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_AEN_BIT 0x2
19 #define QLC_DCB_FW_VER 0x2
20 #define QLC_DCB_MAX_TC 0x8
21 #define QLC_DCB_MAX_APP 0x8
22 #define QLC_DCB_MAX_PRIO QLC_DCB_MAX_TC
23 #define QLC_DCB_MAX_PG QLC_DCB_MAX_TC
25 #define QLC_DCB_TSA_SUPPORT(V) (V & 0x1)
26 #define QLC_DCB_ETS_SUPPORT(V) ((V >> 1) & 0x1)
27 #define QLC_DCB_VERSION_SUPPORT(V) ((V >> 2) & 0xf)
28 #define QLC_DCB_MAX_NUM_TC(V) ((V >> 20) & 0xf)
29 #define QLC_DCB_MAX_NUM_ETS_TC(V) ((V >> 24) & 0xf)
30 #define QLC_DCB_MAX_NUM_PFC_TC(V) ((V >> 28) & 0xf)
31 #define QLC_DCB_GET_TC_PRIO(X, P) ((X >> (P * 3)) & 0x7)
32 #define QLC_DCB_GET_PGID_PRIO(X, P) ((X >> (P * 8)) & 0xff)
33 #define QLC_DCB_GET_BWPER_PG(X, P) ((X >> (P * 8)) & 0xff)
34 #define QLC_DCB_GET_TSA_PG(X, P) ((X >> (P * 8)) & 0xff)
35 #define QLC_DCB_GET_PFC_PRIO(X, P) (((X >> 24) >> P) & 0x1)
36 #define QLC_DCB_GET_PROTO_ID_APP(X) ((X >> 8) & 0xffff)
37 #define QLC_DCB_GET_SELECTOR_APP(X) (X & 0xff)
39 #define QLC_DCB_LOCAL_PARAM_FWID 0x3
40 #define QLC_DCB_OPER_PARAM_FWID 0x1
41 #define QLC_DCB_PEER_PARAM_FWID 0x2
43 #define QLC_83XX_DCB_GET_NUMAPP(X) ((X >> 2) & 0xf)
44 #define QLC_83XX_DCB_TSA_VALID(X) (X & 0x1)
45 #define QLC_83XX_DCB_PFC_VALID(X) ((X >> 1) & 0x1)
46 #define QLC_83XX_DCB_GET_PRIOMAP_APP(X) (X >> 24)
48 #define QLC_82XX_DCB_GET_NUMAPP(X) ((X >> 12) & 0xf)
49 #define QLC_82XX_DCB_TSA_VALID(X) ((X >> 4) & 0x1)
50 #define QLC_82XX_DCB_PFC_VALID(X) ((X >> 5) & 0x1)
51 #define QLC_82XX_DCB_GET_PRIOVAL_APP(X) ((X >> 24) & 0x7)
52 #define QLC_82XX_DCB_GET_PRIOMAP_APP(X) (1 << X)
53 #define QLC_82XX_DCB_PRIO_TC_MAP (0x76543210)
55 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops
;
57 static void qlcnic_dcb_aen_work(struct work_struct
*);
58 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*);
60 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter
*);
61 static void __qlcnic_dcb_free(struct qlcnic_adapter
*);
62 static int __qlcnic_dcb_attach(struct qlcnic_adapter
*);
63 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter
*, char *);
64 static void __qlcnic_dcb_get_info(struct qlcnic_adapter
*);
66 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter
*);
67 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter
*, char *, u8
);
68 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter
*);
69 static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter
*, void *);
71 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter
*);
72 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter
*, char *, u8
);
73 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter
*);
74 static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter
*, bool);
75 static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter
*, void *);
77 struct qlcnic_dcb_capability
{
86 struct qlcnic_dcb_param
{
87 u32 hdr_prio_pfc_map
[2];
91 u32 app
[QLC_DCB_MAX_APP
];
94 struct qlcnic_dcb_mbx_params
{
95 /* 1st local, 2nd operational 3rd remote */
96 struct qlcnic_dcb_param type
[3];
100 struct qlcnic_82xx_dcb_param_mbx_le
{
101 __le32 hdr_prio_pfc_map
[2];
102 __le32 prio_pg_map
[2];
104 __le32 pg_tsa_map
[2];
105 __le32 app
[QLC_DCB_MAX_APP
];
108 enum qlcnic_dcb_selector
{
109 QLC_SELECTOR_DEF
= 0x0,
115 enum qlcnic_dcb_prio_type
{
121 enum qlcnic_dcb_pfc_type
{
122 QLC_PFC_DISABLED
= 0,
128 struct qlcnic_dcb_prio_cfg
{
130 enum qlcnic_dcb_pfc_type pfc_type
;
133 struct qlcnic_dcb_pg_cfg
{
135 u8 total_bw_percent
; /* of Link/ port BW */
140 struct qlcnic_dcb_tc_cfg
{
142 struct qlcnic_dcb_prio_cfg prio_cfg
[QLC_DCB_MAX_PRIO
];
143 enum qlcnic_dcb_prio_type prio_type
; /* always prio_link */
144 u8 link_percent
; /* % of link bandwidth */
145 u8 bwg_percent
; /* % of BWG's bandwidth */
150 struct qlcnic_dcb_app
{
152 enum qlcnic_dcb_selector selector
;
157 struct qlcnic_dcb_cee
{
158 struct qlcnic_dcb_tc_cfg tc_cfg
[QLC_DCB_MAX_TC
];
159 struct qlcnic_dcb_pg_cfg pg_cfg
[QLC_DCB_MAX_PG
];
160 struct qlcnic_dcb_app app
[QLC_DCB_MAX_APP
];
162 bool pfc_mode_enable
;
165 struct qlcnic_dcb_cfg
{
166 /* 0 - local, 1 - operational, 2 - remote */
167 struct qlcnic_dcb_cee type
[QLC_DCB_NUM_PARAM
];
168 struct qlcnic_dcb_capability capability
;
172 static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops
= {
173 .init_dcbnl_ops
= __qlcnic_init_dcbnl_ops
,
174 .free
= __qlcnic_dcb_free
,
175 .attach
= __qlcnic_dcb_attach
,
176 .query_hw_capability
= __qlcnic_dcb_query_hw_capability
,
177 .get_info
= __qlcnic_dcb_get_info
,
179 .get_hw_capability
= qlcnic_83xx_dcb_get_hw_capability
,
180 .query_cee_param
= qlcnic_83xx_dcb_query_cee_param
,
181 .get_cee_cfg
= qlcnic_83xx_dcb_get_cee_cfg
,
182 .register_aen
= qlcnic_83xx_dcb_register_aen
,
183 .handle_aen
= qlcnic_83xx_dcb_handle_aen
,
186 static struct qlcnic_dcb_ops qlcnic_82xx_dcb_ops
= {
187 .init_dcbnl_ops
= __qlcnic_init_dcbnl_ops
,
188 .free
= __qlcnic_dcb_free
,
189 .attach
= __qlcnic_dcb_attach
,
190 .query_hw_capability
= __qlcnic_dcb_query_hw_capability
,
191 .get_info
= __qlcnic_dcb_get_info
,
193 .get_hw_capability
= qlcnic_82xx_dcb_get_hw_capability
,
194 .query_cee_param
= qlcnic_82xx_dcb_query_cee_param
,
195 .get_cee_cfg
= qlcnic_82xx_dcb_get_cee_cfg
,
196 .handle_aen
= qlcnic_82xx_dcb_handle_aen
,
199 static u8
qlcnic_dcb_get_num_app(struct qlcnic_adapter
*adapter
, u32 val
)
201 if (qlcnic_82xx_check(adapter
))
202 return QLC_82XX_DCB_GET_NUMAPP(val
);
204 return QLC_83XX_DCB_GET_NUMAPP(val
);
207 static inline u8
qlcnic_dcb_pfc_hdr_valid(struct qlcnic_adapter
*adapter
,
210 if (qlcnic_82xx_check(adapter
))
211 return QLC_82XX_DCB_PFC_VALID(val
);
213 return QLC_83XX_DCB_PFC_VALID(val
);
216 static inline u8
qlcnic_dcb_tsa_hdr_valid(struct qlcnic_adapter
*adapter
,
219 if (qlcnic_82xx_check(adapter
))
220 return QLC_82XX_DCB_TSA_VALID(val
);
222 return QLC_83XX_DCB_TSA_VALID(val
);
225 static inline u8
qlcnic_dcb_get_prio_map_app(struct qlcnic_adapter
*adapter
,
228 if (qlcnic_82xx_check(adapter
))
229 return QLC_82XX_DCB_GET_PRIOMAP_APP(val
);
231 return QLC_83XX_DCB_GET_PRIOMAP_APP(val
);
234 static int qlcnic_dcb_prio_count(u8 up_tc_map
)
238 for (j
= 0; j
< QLC_DCB_MAX_TC
; j
++)
239 if (up_tc_map
& QLC_DCB_GET_MAP(j
))
245 static inline void __qlcnic_init_dcbnl_ops(struct qlcnic_adapter
*adapter
)
247 if (test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
248 adapter
->netdev
->dcbnl_ops
= &qlcnic_dcbnl_ops
;
251 void qlcnic_set_dcb_ops(struct qlcnic_adapter
*adapter
)
253 if (qlcnic_82xx_check(adapter
))
254 adapter
->dcb
->ops
= &qlcnic_82xx_dcb_ops
;
255 else if (qlcnic_83xx_check(adapter
))
256 adapter
->dcb
->ops
= &qlcnic_83xx_dcb_ops
;
259 int __qlcnic_register_dcb(struct qlcnic_adapter
*adapter
)
261 struct qlcnic_dcb
*dcb
;
263 dcb
= kzalloc(sizeof(struct qlcnic_dcb
), GFP_ATOMIC
);
268 dcb
->adapter
= adapter
;
269 qlcnic_set_dcb_ops(adapter
);
274 static void __qlcnic_dcb_free(struct qlcnic_adapter
*adapter
)
276 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
281 qlcnic_dcb_register_aen(adapter
, 0);
283 while (test_bit(__QLCNIC_DCB_IN_AEN
, &adapter
->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_adapter
*adapter
)
303 qlcnic_dcb_get_hw_capability(adapter
);
304 qlcnic_dcb_get_cee_cfg(adapter
);
305 qlcnic_dcb_register_aen(adapter
, 1);
308 static int __qlcnic_dcb_attach(struct qlcnic_adapter
*adapter
)
310 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
313 INIT_DELAYED_WORK(&dcb
->aen_work
, qlcnic_dcb_aen_work
);
315 dcb
->wq
= create_singlethread_workqueue("qlcnic-dcb");
317 dev_err(&adapter
->pdev
->dev
,
318 "DCB workqueue allocation failed. DCB will be disabled\n");
322 dcb
->cfg
= kzalloc(sizeof(struct qlcnic_dcb_cfg
), GFP_ATOMIC
);
328 dcb
->param
= kzalloc(sizeof(struct qlcnic_dcb_mbx_params
), GFP_ATOMIC
);
334 qlcnic_dcb_get_info(adapter
);
342 destroy_workqueue(dcb
->wq
);
348 static int __qlcnic_dcb_query_hw_capability(struct qlcnic_adapter
*adapter
,
351 struct qlcnic_cmd_args cmd
;
355 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_CAP
);
359 err
= qlcnic_issue_cmd(adapter
, &cmd
);
361 dev_err(&adapter
->pdev
->dev
,
362 "Failed to query DCBX capability, err %d\n", err
);
364 mbx_out
= cmd
.rsp
.arg
[1];
366 memcpy(buf
, &mbx_out
, sizeof(u32
));
369 qlcnic_free_mbx_args(&cmd
);
374 static int __qlcnic_dcb_get_capability(struct qlcnic_adapter
*adapter
, u32
*val
)
376 struct qlcnic_dcb_capability
*cap
= &adapter
->dcb
->cfg
->capability
;
380 memset(cap
, 0, sizeof(struct qlcnic_dcb_capability
));
382 err
= qlcnic_dcb_query_hw_capability(adapter
, (char *)val
);
387 if (QLC_DCB_TSA_SUPPORT(mbx_out
))
388 cap
->tsa_capability
= true;
390 if (QLC_DCB_ETS_SUPPORT(mbx_out
))
391 cap
->ets_capability
= true;
393 cap
->max_num_tc
= QLC_DCB_MAX_NUM_TC(mbx_out
);
394 cap
->max_ets_tc
= QLC_DCB_MAX_NUM_ETS_TC(mbx_out
);
395 cap
->max_pfc_tc
= QLC_DCB_MAX_NUM_PFC_TC(mbx_out
);
397 if (cap
->max_num_tc
> QLC_DCB_MAX_TC
||
398 cap
->max_ets_tc
> cap
->max_num_tc
||
399 cap
->max_pfc_tc
> cap
->max_num_tc
) {
400 dev_err(&adapter
->pdev
->dev
, "Invalid DCB configuration\n");
407 static int qlcnic_82xx_dcb_get_hw_capability(struct qlcnic_adapter
*adapter
)
409 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
410 struct qlcnic_dcb_capability
*cap
;
414 err
= __qlcnic_dcb_get_capability(adapter
, &mbx_out
);
418 cap
= &cfg
->capability
;
419 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
| DCB_CAP_DCBX_LLD_MANAGED
;
421 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
422 set_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
427 static int qlcnic_82xx_dcb_query_cee_param(struct qlcnic_adapter
*adapter
,
430 u16 size
= sizeof(struct qlcnic_82xx_dcb_param_mbx_le
);
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(&adapter
->pdev
->dev
, size
, &cardrsp_phys_addr
,
457 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
461 phys_addr
= cardrsp_phys_addr
;
462 cmd
.req
.arg
[1] = size
| (type
<< 16);
463 cmd
.req
.arg
[2] = MSD(phys_addr
);
464 cmd
.req
.arg
[3] = LSD(phys_addr
);
466 err
= qlcnic_issue_cmd(adapter
, &cmd
);
468 dev_err(dev
, "Failed to query DCBX parameter, err %d\n", err
);
472 memset(&rsp
, 0, sizeof(struct qlcnic_dcb_param
));
473 rsp
.hdr_prio_pfc_map
[0] = le32_to_cpu(prsp_le
->hdr_prio_pfc_map
[0]);
474 rsp
.hdr_prio_pfc_map
[1] = le32_to_cpu(prsp_le
->hdr_prio_pfc_map
[1]);
475 rsp
.prio_pg_map
[0] = le32_to_cpu(prsp_le
->prio_pg_map
[0]);
476 rsp
.prio_pg_map
[1] = le32_to_cpu(prsp_le
->prio_pg_map
[1]);
477 rsp
.pg_bw_map
[0] = le32_to_cpu(prsp_le
->pg_bw_map
[0]);
478 rsp
.pg_bw_map
[1] = le32_to_cpu(prsp_le
->pg_bw_map
[1]);
479 rsp
.pg_tsa_map
[0] = le32_to_cpu(prsp_le
->pg_tsa_map
[0]);
480 rsp
.pg_tsa_map
[1] = le32_to_cpu(prsp_le
->pg_tsa_map
[1]);
482 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++)
483 rsp
.app
[i
] = le32_to_cpu(prsp_le
->app
[i
]);
486 memcpy(buf
, &rsp
, size
);
488 qlcnic_free_mbx_args(&cmd
);
491 dma_free_coherent(&adapter
->pdev
->dev
, size
, addr
, cardrsp_phys_addr
);
496 static int qlcnic_82xx_dcb_get_cee_cfg(struct qlcnic_adapter
*adapter
)
498 struct qlcnic_dcb_mbx_params
*mbx
;
501 mbx
= adapter
->dcb
->param
;
505 err
= qlcnic_dcb_query_cee_param(adapter
, (char *)&mbx
->type
[0],
506 QLC_DCB_LOCAL_PARAM_FWID
);
510 err
= qlcnic_dcb_query_cee_param(adapter
, (char *)&mbx
->type
[1],
511 QLC_DCB_OPER_PARAM_FWID
);
515 err
= qlcnic_dcb_query_cee_param(adapter
, (char *)&mbx
->type
[2],
516 QLC_DCB_PEER_PARAM_FWID
);
520 mbx
->prio_tc_map
= QLC_82XX_DCB_PRIO_TC_MAP
;
522 qlcnic_dcb_data_cee_param_map(adapter
);
527 static void qlcnic_dcb_aen_work(struct work_struct
*work
)
529 struct qlcnic_adapter
*adapter
;
530 struct qlcnic_dcb
*dcb
;
532 dcb
= container_of(work
, struct qlcnic_dcb
, aen_work
.work
);
533 adapter
= dcb
->adapter
;
535 qlcnic_dcb_get_cee_cfg(adapter
);
536 clear_bit(__QLCNIC_DCB_IN_AEN
, &adapter
->state
);
539 static void qlcnic_82xx_dcb_handle_aen(struct qlcnic_adapter
*adapter
,
542 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
544 if (test_and_set_bit(__QLCNIC_DCB_IN_AEN
, &adapter
->state
))
547 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
550 static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_adapter
*adapter
)
552 struct qlcnic_dcb_capability
*cap
= &adapter
->dcb
->cfg
->capability
;
556 err
= __qlcnic_dcb_get_capability(adapter
, &mbx_out
);
561 cap
->dcb_capability
= DCB_CAP_DCBX_VER_CEE
;
563 cap
->dcb_capability
|= DCB_CAP_DCBX_VER_IEEE
;
564 if (cap
->dcb_capability
)
565 cap
->dcb_capability
|= DCB_CAP_DCBX_LLD_MANAGED
;
567 if (cap
->dcb_capability
&& cap
->tsa_capability
&& cap
->ets_capability
)
568 set_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
573 static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_adapter
*adapter
,
576 struct qlcnic_dcb_mbx_params mbx_out
;
577 int err
, i
, j
, k
, max_app
, size
;
578 struct qlcnic_dcb_param
*each
;
579 struct qlcnic_cmd_args cmd
;
584 memset(&mbx_out
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
585 memset(buf
, 0, sizeof(struct qlcnic_dcb_mbx_params
));
587 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, QLCNIC_CMD_DCB_QUERY_PARAM
);
591 cmd
.req
.arg
[0] |= QLC_DCB_FW_VER
<< 29;
592 err
= qlcnic_issue_cmd(adapter
, &cmd
);
594 dev_err(&adapter
->pdev
->dev
,
595 "Failed to query DCBX param, err %d\n", err
);
599 mbx_out
.prio_tc_map
= cmd
.rsp
.arg
[1];
600 p
= memcpy(buf
, &mbx_out
, sizeof(u32
));
604 for (j
= 0; j
< QLC_DCB_NUM_PARAM
; j
++) {
605 each
= &mbx_out
.type
[j
];
607 each
->hdr_prio_pfc_map
[0] = cmd
.rsp
.arg
[k
++];
608 each
->hdr_prio_pfc_map
[1] = cmd
.rsp
.arg
[k
++];
609 each
->prio_pg_map
[0] = cmd
.rsp
.arg
[k
++];
610 each
->prio_pg_map
[1] = cmd
.rsp
.arg
[k
++];
611 each
->pg_bw_map
[0] = cmd
.rsp
.arg
[k
++];
612 each
->pg_bw_map
[1] = cmd
.rsp
.arg
[k
++];
613 each
->pg_tsa_map
[0] = cmd
.rsp
.arg
[k
++];
614 each
->pg_tsa_map
[1] = cmd
.rsp
.arg
[k
++];
615 val
= each
->hdr_prio_pfc_map
[0];
617 max_app
= qlcnic_dcb_get_num_app(adapter
, val
);
618 for (i
= 0; i
< max_app
; i
++)
619 each
->app
[i
] = cmd
.rsp
.arg
[i
+ k
];
621 size
= 16 * sizeof(u32
);
622 memcpy(p
, &each
->hdr_prio_pfc_map
[0], size
);
630 qlcnic_free_mbx_args(&cmd
);
635 static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_adapter
*adapter
)
637 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
640 err
= qlcnic_dcb_query_cee_param(adapter
, (char *)dcb
->param
, 0);
644 qlcnic_dcb_data_cee_param_map(adapter
);
649 static int qlcnic_83xx_dcb_register_aen(struct qlcnic_adapter
*adapter
,
652 u8 val
= (flag
? QLCNIC_CMD_INIT_NIC_FUNC
: QLCNIC_CMD_STOP_NIC_FUNC
);
653 struct qlcnic_cmd_args cmd
;
656 err
= qlcnic_alloc_mbx_args(&cmd
, adapter
, val
);
660 cmd
.req
.arg
[1] = QLC_DCB_AEN_BIT
;
662 err
= qlcnic_issue_cmd(adapter
, &cmd
);
664 dev_err(&adapter
->pdev
->dev
, "Failed to %s DCBX AEN, err %d\n",
665 (flag
? "register" : "unregister"), err
);
667 qlcnic_free_mbx_args(&cmd
);
672 static void qlcnic_83xx_dcb_handle_aen(struct qlcnic_adapter
*adapter
,
675 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
678 if (test_and_set_bit(__QLCNIC_DCB_IN_AEN
, &adapter
->state
))
682 set_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
684 clear_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
686 queue_delayed_work(dcb
->wq
, &dcb
->aen_work
, 0);
689 static void qlcnic_dcb_fill_cee_tc_params(struct qlcnic_dcb_mbx_params
*mbx
,
690 struct qlcnic_dcb_param
*each
,
691 struct qlcnic_dcb_cee
*type
)
693 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
696 for (i
= 0; i
< QLC_DCB_MAX_PRIO
; i
++) {
697 tc
= QLC_DCB_GET_TC_PRIO(mbx
->prio_tc_map
, i
);
698 tc_cfg
= &type
->tc_cfg
[tc
];
699 tc_cfg
->valid
= true;
700 tc_cfg
->up_tc_map
|= QLC_DCB_GET_MAP(i
);
702 if (QLC_DCB_GET_PFC_PRIO(each
->hdr_prio_pfc_map
[1], i
) &&
703 type
->pfc_mode_enable
) {
704 tc_cfg
->prio_cfg
[i
].valid
= true;
705 tc_cfg
->prio_cfg
[i
].pfc_type
= QLC_PFC_FULL
;
709 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[0], i
);
711 pgid
= QLC_DCB_GET_PGID_PRIO(each
->prio_pg_map
[1], i
);
715 tc_cfg
->prio_type
= QLC_PRIO_LINK
;
716 type
->pg_cfg
[tc_cfg
->pgid
].prio_count
++;
720 static void qlcnic_dcb_fill_cee_pg_params(struct qlcnic_dcb_param
*each
,
721 struct qlcnic_dcb_cee
*type
)
723 struct qlcnic_dcb_pg_cfg
*pg_cfg
;
726 for (i
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
727 pg_cfg
= &type
->pg_cfg
[i
];
728 pg_cfg
->valid
= true;
731 bw_per
= QLC_DCB_GET_BWPER_PG(each
->pg_bw_map
[0], i
);
732 tsa
= QLC_DCB_GET_TSA_PG(each
->pg_tsa_map
[0], i
);
734 bw_per
= QLC_DCB_GET_BWPER_PG(each
->pg_bw_map
[1], i
);
735 tsa
= QLC_DCB_GET_TSA_PG(each
->pg_tsa_map
[1], i
);
738 pg_cfg
->total_bw_percent
= bw_per
;
739 pg_cfg
->tsa_type
= tsa
;
744 qlcnic_dcb_fill_cee_app_params(struct qlcnic_adapter
*adapter
, u8 idx
,
745 struct qlcnic_dcb_param
*each
,
746 struct qlcnic_dcb_cee
*type
)
748 struct qlcnic_dcb_app
*app
;
749 u8 i
, num_app
, map
, cnt
;
750 struct dcb_app new_app
;
752 num_app
= qlcnic_dcb_get_num_app(adapter
, each
->hdr_prio_pfc_map
[0]);
753 for (i
= 0; i
< num_app
; i
++) {
757 /* Only for CEE (-1) */
758 app
->selector
= QLC_DCB_GET_SELECTOR_APP(each
->app
[i
]) - 1;
759 new_app
.selector
= app
->selector
;
760 app
->protocol
= QLC_DCB_GET_PROTO_ID_APP(each
->app
[i
]);
761 new_app
.protocol
= app
->protocol
;
762 map
= qlcnic_dcb_get_prio_map_app(adapter
, each
->app
[i
]);
763 cnt
= qlcnic_dcb_prio_count(map
);
765 if (cnt
>= QLC_DCB_MAX_TC
)
769 new_app
.priority
= cnt
;
771 if (idx
== QLC_DCB_OPER_IDX
&& adapter
->netdev
->dcbnl_ops
)
772 dcb_setapp(adapter
->netdev
, &new_app
);
776 static void qlcnic_dcb_map_cee_params(struct qlcnic_adapter
*adapter
, u8 idx
)
778 struct qlcnic_dcb_mbx_params
*mbx
= adapter
->dcb
->param
;
779 struct qlcnic_dcb_param
*each
= &mbx
->type
[idx
];
780 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
781 struct qlcnic_dcb_cee
*type
= &cfg
->type
[idx
];
783 type
->tc_param_valid
= false;
784 type
->pfc_mode_enable
= false;
785 memset(type
->tc_cfg
, 0,
786 sizeof(struct qlcnic_dcb_tc_cfg
) * QLC_DCB_MAX_TC
);
787 memset(type
->pg_cfg
, 0,
788 sizeof(struct qlcnic_dcb_pg_cfg
) * QLC_DCB_MAX_TC
);
790 if (qlcnic_dcb_pfc_hdr_valid(adapter
, each
->hdr_prio_pfc_map
[0]) &&
791 cfg
->capability
.max_pfc_tc
)
792 type
->pfc_mode_enable
= true;
794 if (qlcnic_dcb_tsa_hdr_valid(adapter
, each
->hdr_prio_pfc_map
[0]) &&
795 cfg
->capability
.max_ets_tc
)
796 type
->tc_param_valid
= true;
798 qlcnic_dcb_fill_cee_tc_params(mbx
, each
, type
);
799 qlcnic_dcb_fill_cee_pg_params(each
, type
);
800 qlcnic_dcb_fill_cee_app_params(adapter
, idx
, each
, type
);
803 static void qlcnic_dcb_data_cee_param_map(struct qlcnic_adapter
*adapter
)
807 for (i
= 0; i
< QLC_DCB_NUM_PARAM
; i
++)
808 qlcnic_dcb_map_cee_params(adapter
, i
);
810 dcbnl_cee_notify(adapter
->netdev
, RTM_GETDCB
, DCB_CMD_CEE_GET
, 0, 0);
813 static u8
qlcnic_dcb_get_state(struct net_device
*netdev
)
815 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
817 return test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
);
820 static void qlcnic_dcb_get_perm_hw_addr(struct net_device
*netdev
, u8
*addr
)
822 memcpy(addr
, netdev
->dev_addr
, netdev
->addr_len
);
826 qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device
*netdev
, int tc
, u8
*prio
,
827 u8
*pgid
, u8
*bw_per
, u8
*up_tc_map
)
829 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
830 struct qlcnic_dcb_tc_cfg
*tc_cfg
, *temp
;
831 struct qlcnic_dcb_cee
*type
;
834 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
835 *prio
= *pgid
= *bw_per
= *up_tc_map
= 0;
837 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
) ||
838 !type
->tc_param_valid
)
841 if (tc
< 0 || (tc
> QLC_DCB_MAX_TC
))
844 tc_cfg
= &type
->tc_cfg
[tc
];
848 *pgid
= tc_cfg
->pgid
;
849 *prio
= tc_cfg
->prio_type
;
850 *up_tc_map
= tc_cfg
->up_tc_map
;
853 for (i
= 0, cnt
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
854 temp
= &type
->tc_cfg
[i
];
855 if (temp
->valid
&& (pg
== temp
->pgid
))
859 tc_cfg
->bwg_percent
= (100 / cnt
);
860 *bw_per
= tc_cfg
->bwg_percent
;
863 static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device
*netdev
, int pgid
,
866 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
867 struct qlcnic_dcb_pg_cfg
*pgcfg
;
868 struct qlcnic_dcb_cee
*type
;
871 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
873 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
) ||
874 !type
->tc_param_valid
)
877 if (pgid
< 0 || pgid
> QLC_DCB_MAX_PG
)
880 pgcfg
= &type
->pg_cfg
[pgid
];
884 *bw_pct
= pgcfg
->total_bw_percent
;
887 static void qlcnic_dcb_get_pfc_cfg(struct net_device
*netdev
, int prio
,
890 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
891 struct qlcnic_dcb_tc_cfg
*tc_cfg
;
892 u8 val
= QLC_DCB_GET_MAP(prio
);
893 struct qlcnic_dcb_cee
*type
;
897 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
899 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
) ||
900 !type
->pfc_mode_enable
)
903 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
904 tc_cfg
= &type
->tc_cfg
[i
];
908 if ((val
& tc_cfg
->up_tc_map
) && (tc_cfg
->prio_cfg
[prio
].valid
))
909 *setting
= tc_cfg
->prio_cfg
[prio
].pfc_type
;
913 static u8
qlcnic_dcb_get_capability(struct net_device
*netdev
, int capid
,
916 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
918 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
922 case DCB_CAP_ATTR_PG
:
923 case DCB_CAP_ATTR_UP2TC
:
924 case DCB_CAP_ATTR_PFC
:
925 case DCB_CAP_ATTR_GSP
:
928 case DCB_CAP_ATTR_PG_TCS
:
929 case DCB_CAP_ATTR_PFC_TCS
:
930 *cap
= 0x80; /* 8 priorities for PGs */
932 case DCB_CAP_ATTR_DCBX
:
933 *cap
= adapter
->dcb
->cfg
->capability
.dcb_capability
;
942 static int qlcnic_dcb_get_num_tcs(struct net_device
*netdev
, int attr
, u8
*num
)
944 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
945 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
947 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
951 case DCB_NUMTCS_ATTR_PG
:
952 *num
= cfg
->capability
.max_ets_tc
;
954 case DCB_NUMTCS_ATTR_PFC
:
955 *num
= cfg
->capability
.max_pfc_tc
;
962 static u8
qlcnic_dcb_get_app(struct net_device
*netdev
, u8 idtype
, u16 id
)
964 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
965 struct dcb_app app
= {
970 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
973 return dcb_getapp(netdev
, &app
);
976 static u8
qlcnic_dcb_get_pfc_state(struct net_device
*netdev
)
978 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
979 struct qlcnic_dcb
*dcb
= adapter
->dcb
;
981 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
984 return dcb
->cfg
->type
[QLC_DCB_OPER_IDX
].pfc_mode_enable
;
987 static u8
qlcnic_dcb_get_dcbx(struct net_device
*netdev
)
989 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
990 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
992 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
995 return cfg
->capability
.dcb_capability
;
998 static u8
qlcnic_dcb_get_feat_cfg(struct net_device
*netdev
, int fid
, u8
*flag
)
1000 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1001 struct qlcnic_dcb_cee
*type
;
1003 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
1006 type
= &adapter
->dcb
->cfg
->type
[QLC_DCB_OPER_IDX
];
1010 case DCB_FEATCFG_ATTR_PG
:
1011 if (type
->tc_param_valid
)
1012 *flag
|= DCB_FEATCFG_ENABLE
;
1014 *flag
|= DCB_FEATCFG_ERROR
;
1016 case DCB_FEATCFG_ATTR_PFC
:
1017 if (type
->pfc_mode_enable
) {
1018 if (type
->tc_cfg
[0].prio_cfg
[0].pfc_type
)
1019 *flag
|= DCB_FEATCFG_ENABLE
;
1021 *flag
|= DCB_FEATCFG_ERROR
;
1024 case DCB_FEATCFG_ATTR_APP
:
1025 *flag
|= DCB_FEATCFG_ENABLE
;
1028 netdev_err(netdev
, "Invalid Feature ID %d\n", fid
);
1036 qlcnic_dcb_get_pg_tc_cfg_rx(struct net_device
*netdev
, int prio
, u8
*prio_type
,
1037 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1039 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1043 qlcnic_dcb_get_pg_bwg_cfg_rx(struct net_device
*netdev
, int pgid
, u8
*bw_pct
)
1048 static int qlcnic_dcb_peer_app_info(struct net_device
*netdev
,
1049 struct dcb_peer_app_info
*info
,
1052 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1053 struct qlcnic_dcb_cee
*peer
;
1058 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
1061 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1063 for (i
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1064 if (peer
->app
[i
].valid
)
1071 static int qlcnic_dcb_peer_app_table(struct net_device
*netdev
,
1072 struct dcb_app
*table
)
1074 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1075 struct qlcnic_dcb_cee
*peer
;
1076 struct qlcnic_dcb_app
*app
;
1079 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
1082 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1084 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_APP
; i
++) {
1085 app
= &peer
->app
[i
];
1089 table
[j
].selector
= app
->selector
;
1090 table
[j
].priority
= app
->priority
;
1091 table
[j
++].protocol
= app
->protocol
;
1097 static int qlcnic_dcb_cee_peer_get_pg(struct net_device
*netdev
,
1100 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1101 struct qlcnic_dcb_cee
*peer
;
1104 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
1107 peer
= &adapter
->dcb
->cfg
->type
[QLC_DCB_PEER_IDX
];
1109 for (i
= 0, j
= 0; i
< QLC_DCB_MAX_PG
; i
++) {
1110 if (!peer
->pg_cfg
[i
].valid
)
1113 pg
->pg_bw
[j
] = peer
->pg_cfg
[i
].total_bw_percent
;
1115 for (k
= 0; k
< QLC_DCB_MAX_TC
; k
++) {
1116 if (peer
->tc_cfg
[i
].valid
&&
1117 (peer
->tc_cfg
[i
].pgid
== i
)) {
1118 map
= peer
->tc_cfg
[i
].up_tc_map
;
1119 pg
->prio_pg
[j
++] = map
;
1128 static int qlcnic_dcb_cee_peer_get_pfc(struct net_device
*netdev
,
1129 struct cee_pfc
*pfc
)
1131 struct qlcnic_adapter
*adapter
= netdev_priv(netdev
);
1132 struct qlcnic_dcb_cfg
*cfg
= adapter
->dcb
->cfg
;
1133 struct qlcnic_dcb_tc_cfg
*tc
;
1134 struct qlcnic_dcb_cee
*peer
;
1135 u8 i
, setting
, prio
;
1139 if (!test_bit(__QLCNIC_DCB_STATE
, &adapter
->state
))
1142 peer
= &cfg
->type
[QLC_DCB_PEER_IDX
];
1144 for (i
= 0; i
< QLC_DCB_MAX_TC
; i
++) {
1145 tc
= &peer
->tc_cfg
[i
];
1146 prio
= qlcnic_dcb_prio_count(tc
->up_tc_map
);
1149 qlcnic_dcb_get_pfc_cfg(netdev
, prio
, &setting
);
1151 pfc
->pfc_en
|= QLC_DCB_GET_MAP(i
);
1154 pfc
->tcs_supported
= cfg
->capability
.max_pfc_tc
;
1159 static const struct dcbnl_rtnl_ops qlcnic_dcbnl_ops
= {
1160 .getstate
= qlcnic_dcb_get_state
,
1161 .getpermhwaddr
= qlcnic_dcb_get_perm_hw_addr
,
1162 .getpgtccfgtx
= qlcnic_dcb_get_pg_tc_cfg_tx
,
1163 .getpgbwgcfgtx
= qlcnic_dcb_get_pg_bwg_cfg_tx
,
1164 .getpfccfg
= qlcnic_dcb_get_pfc_cfg
,
1165 .getcap
= qlcnic_dcb_get_capability
,
1166 .getnumtcs
= qlcnic_dcb_get_num_tcs
,
1167 .getapp
= qlcnic_dcb_get_app
,
1168 .getpfcstate
= qlcnic_dcb_get_pfc_state
,
1169 .getdcbx
= qlcnic_dcb_get_dcbx
,
1170 .getfeatcfg
= qlcnic_dcb_get_feat_cfg
,
1172 .getpgtccfgrx
= qlcnic_dcb_get_pg_tc_cfg_rx
,
1173 .getpgbwgcfgrx
= qlcnic_dcb_get_pg_bwg_cfg_rx
,
1175 .peer_getappinfo
= qlcnic_dcb_peer_app_info
,
1176 .peer_getapptable
= qlcnic_dcb_peer_app_table
,
1177 .cee_peer_getpg
= qlcnic_dcb_cee_peer_get_pg
,
1178 .cee_peer_getpfc
= qlcnic_dcb_cee_peer_get_pfc
,