1 /* Broadcom NetXtreme-C/E network driver.
3 * Copyright (c) 2014-2016 Broadcom Corporation
4 * Copyright (c) 2016-2017 Broadcom Limited
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
11 #include <linux/netdevice.h>
12 #include <linux/types.h>
13 #include <linux/errno.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/interrupt.h>
16 #include <linux/pci.h>
17 #include <linux/etherdevice.h>
18 #include <rdma/ib_verbs.h>
23 #ifdef CONFIG_BNXT_DCB
24 static int bnxt_queue_to_tc(struct bnxt
*bp
, u8 queue_id
)
28 for (i
= 0; i
< bp
->max_tc
; i
++) {
29 if (bp
->q_info
[i
].queue_id
== queue_id
) {
30 for (j
= 0; j
< bp
->max_tc
; j
++) {
31 if (bp
->tc_to_qidx
[j
] == i
)
39 static int bnxt_hwrm_queue_pri2cos_cfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
41 struct hwrm_queue_pri2cos_cfg_input req
= {0};
45 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PRI2COS_CFG
, -1, -1);
46 req
.flags
= cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_FLAGS_PATH_BIDIR
|
47 QUEUE_PRI2COS_CFG_REQ_FLAGS_IVLAN
);
49 pri2cos
= &req
.pri0_cos_queue_id
;
50 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
53 req
.enables
|= cpu_to_le32(
54 QUEUE_PRI2COS_CFG_REQ_ENABLES_PRI0_COS_QUEUE_ID
<< i
);
56 qidx
= bp
->tc_to_qidx
[ets
->prio_tc
[i
]];
57 pri2cos
[i
] = bp
->q_info
[qidx
].queue_id
;
59 return hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
62 static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
64 struct hwrm_queue_pri2cos_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
65 struct hwrm_queue_pri2cos_qcfg_input req
= {0};
68 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PRI2COS_QCFG
, -1, -1);
69 req
.flags
= cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN
);
71 mutex_lock(&bp
->hwrm_cmd_lock
);
72 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
74 u8
*pri2cos
= &resp
->pri0_cos_queue_id
;
77 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
78 u8 queue_id
= pri2cos
[i
];
81 tc
= bnxt_queue_to_tc(bp
, queue_id
);
86 mutex_unlock(&bp
->hwrm_cmd_lock
);
90 static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt
*bp
, struct ieee_ets
*ets
,
93 struct hwrm_queue_cos2bw_cfg_input req
= {0};
94 struct bnxt_cos2bw_cfg cos2bw
;
98 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_COS2BW_CFG
, -1, -1);
99 for (i
= 0; i
< max_tc
; i
++) {
100 u8 qidx
= bp
->tc_to_qidx
[i
];
102 req
.enables
|= cpu_to_le32(
103 QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID
<<
106 memset(&cos2bw
, 0, sizeof(cos2bw
));
107 cos2bw
.queue_id
= bp
->q_info
[qidx
].queue_id
;
108 if (ets
->tc_tsa
[i
] == IEEE_8021QAZ_TSA_STRICT
) {
110 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP
;
114 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_ETS
;
115 cos2bw
.bw_weight
= ets
->tc_tx_bw
[i
];
116 /* older firmware requires min_bw to be set to the
117 * same weight value in percent.
120 cpu_to_le32((ets
->tc_tx_bw
[i
] * 100) |
121 BW_VALUE_UNIT_PERCENT1_100
);
123 data
= &req
.unused_0
+ qidx
* (sizeof(cos2bw
) - 4);
124 memcpy(data
, &cos2bw
.queue_id
, sizeof(cos2bw
) - 4);
126 req
.queue_id0
= cos2bw
.queue_id
;
130 return hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
133 static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
135 struct hwrm_queue_cos2bw_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
136 struct hwrm_queue_cos2bw_qcfg_input req
= {0};
137 struct bnxt_cos2bw_cfg cos2bw
;
141 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_COS2BW_QCFG
, -1, -1);
143 mutex_lock(&bp
->hwrm_cmd_lock
);
144 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
146 mutex_unlock(&bp
->hwrm_cmd_lock
);
150 data
= &resp
->queue_id0
+ offsetof(struct bnxt_cos2bw_cfg
, queue_id
);
151 for (i
= 0; i
< bp
->max_tc
; i
++, data
+= sizeof(cos2bw
) - 4) {
154 memcpy(&cos2bw
.queue_id
, data
, sizeof(cos2bw
) - 4);
156 cos2bw
.queue_id
= resp
->queue_id0
;
158 tc
= bnxt_queue_to_tc(bp
, cos2bw
.queue_id
);
163 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP
) {
164 ets
->tc_tsa
[tc
] = IEEE_8021QAZ_TSA_STRICT
;
166 ets
->tc_tsa
[tc
] = IEEE_8021QAZ_TSA_ETS
;
167 ets
->tc_tx_bw
[tc
] = cos2bw
.bw_weight
;
170 mutex_unlock(&bp
->hwrm_cmd_lock
);
174 static int bnxt_queue_remap(struct bnxt
*bp
, unsigned int lltc_mask
)
176 unsigned long qmap
= 0;
177 int max
= bp
->max_tc
;
180 /* Assign lossless TCs first */
181 for (i
= 0, j
= 0; i
< max
; ) {
182 if (lltc_mask
& (1 << i
)) {
183 if (BNXT_LLQ(bp
->q_info
[j
].queue_profile
)) {
184 bp
->tc_to_qidx
[i
] = j
;
194 for (i
= 0, j
= 0; i
< max
; i
++) {
195 if (lltc_mask
& (1 << i
))
197 j
= find_next_zero_bit(&qmap
, max
, j
);
198 bp
->tc_to_qidx
[i
] = j
;
203 if (netif_running(bp
->dev
)) {
204 bnxt_close_nic(bp
, false, false);
205 rc
= bnxt_open_nic(bp
, false, false);
207 netdev_warn(bp
->dev
, "failed to open NIC, rc = %d\n", rc
);
212 int tc
= netdev_get_num_tc(bp
->dev
);
216 rc
= bnxt_hwrm_queue_cos2bw_cfg(bp
, bp
->ieee_ets
, tc
);
218 netdev_warn(bp
->dev
, "failed to config BW, rc = %d\n", rc
);
221 rc
= bnxt_hwrm_queue_pri2cos_cfg(bp
, bp
->ieee_ets
);
223 netdev_warn(bp
->dev
, "failed to config prio, rc = %d\n", rc
);
230 static int bnxt_hwrm_queue_pfc_cfg(struct bnxt
*bp
, struct ieee_pfc
*pfc
)
232 struct hwrm_queue_pfcenable_cfg_input req
= {0};
233 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
234 unsigned int tc_mask
= 0, pri_mask
= 0;
235 u8 i
, pri
, lltc_count
= 0;
236 bool need_q_remap
= false;
241 for (i
= 0; i
< bp
->max_tc
; i
++) {
242 for (pri
= 0; pri
< IEEE_8021QAZ_MAX_TCS
; pri
++) {
243 if ((pfc
->pfc_en
& (1 << pri
)) &&
244 (my_ets
->prio_tc
[pri
] == i
)) {
245 pri_mask
|= 1 << pri
;
249 if (tc_mask
& (1 << i
))
252 if (lltc_count
> bp
->max_lltc
)
255 for (i
= 0; i
< bp
->max_tc
; i
++) {
256 if (tc_mask
& (1 << i
)) {
257 u8 qidx
= bp
->tc_to_qidx
[i
];
259 if (!BNXT_LLQ(bp
->q_info
[qidx
].queue_profile
)) {
267 bnxt_queue_remap(bp
, tc_mask
);
269 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PFCENABLE_CFG
, -1, -1);
270 req
.flags
= cpu_to_le32(pri_mask
);
271 return hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
274 static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt
*bp
, struct ieee_pfc
*pfc
)
276 struct hwrm_queue_pfcenable_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
277 struct hwrm_queue_pfcenable_qcfg_input req
= {0};
281 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PFCENABLE_QCFG
, -1, -1);
283 mutex_lock(&bp
->hwrm_cmd_lock
);
284 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
286 mutex_unlock(&bp
->hwrm_cmd_lock
);
290 pri_mask
= le32_to_cpu(resp
->flags
);
291 pfc
->pfc_en
= pri_mask
;
292 mutex_unlock(&bp
->hwrm_cmd_lock
);
296 static int bnxt_hwrm_set_dcbx_app(struct bnxt
*bp
, struct dcb_app
*app
,
299 struct hwrm_fw_set_structured_data_input set
= {0};
300 struct hwrm_fw_get_structured_data_input get
= {0};
301 struct hwrm_struct_data_dcbx_app
*fw_app
;
302 struct hwrm_struct_hdr
*data
;
307 if (bp
->hwrm_spec_code
< 0x10601)
310 n
= IEEE_8021QAZ_MAX_TCS
;
311 data_len
= sizeof(*data
) + sizeof(*fw_app
) * n
;
312 data
= dma_alloc_coherent(&bp
->pdev
->dev
, data_len
, &mapping
,
317 bnxt_hwrm_cmd_hdr_init(bp
, &get
, HWRM_FW_GET_STRUCTURED_DATA
, -1, -1);
318 get
.dest_data_addr
= cpu_to_le64(mapping
);
319 get
.structure_id
= cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP
);
320 get
.subtype
= cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL
);
322 rc
= hwrm_send_message(bp
, &get
, sizeof(get
), HWRM_CMD_TIMEOUT
);
326 fw_app
= (struct hwrm_struct_data_dcbx_app
*)(data
+ 1);
328 if (data
->struct_id
!= cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP
)) {
334 for (i
= 0; i
< n
; i
++, fw_app
++) {
335 if (fw_app
->protocol_id
== cpu_to_be16(app
->protocol
) &&
336 fw_app
->protocol_selector
== app
->selector
&&
337 fw_app
->priority
== app
->priority
) {
347 fw_app
->protocol_id
= cpu_to_be16(app
->protocol
);
348 fw_app
->protocol_selector
= app
->selector
;
349 fw_app
->priority
= app
->priority
;
354 /* not found, nothing to delete */
358 len
= (n
- 1 - i
) * sizeof(*fw_app
);
360 memmove(fw_app
, fw_app
+ 1, len
);
362 memset(fw_app
+ n
, 0, sizeof(*fw_app
));
365 data
->len
= cpu_to_le16(sizeof(*fw_app
) * n
);
366 data
->subtype
= cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL
);
368 bnxt_hwrm_cmd_hdr_init(bp
, &set
, HWRM_FW_SET_STRUCTURED_DATA
, -1, -1);
369 set
.src_data_addr
= cpu_to_le64(mapping
);
370 set
.data_len
= cpu_to_le16(sizeof(*data
) + sizeof(*fw_app
) * n
);
372 rc
= hwrm_send_message(bp
, &set
, sizeof(set
), HWRM_CMD_TIMEOUT
);
375 dma_free_coherent(&bp
->pdev
->dev
, data_len
, data
, mapping
);
379 static int bnxt_hwrm_queue_dscp_qcaps(struct bnxt
*bp
)
381 struct hwrm_queue_dscp_qcaps_output
*resp
= bp
->hwrm_cmd_resp_addr
;
382 struct hwrm_queue_dscp_qcaps_input req
= {0};
385 bp
->max_dscp_value
= 0;
386 if (bp
->hwrm_spec_code
< 0x10800 || BNXT_VF(bp
))
389 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_DSCP_QCAPS
, -1, -1);
390 mutex_lock(&bp
->hwrm_cmd_lock
);
391 rc
= _hwrm_send_message_silent(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
393 bp
->max_dscp_value
= (1 << resp
->num_dscp_bits
) - 1;
394 if (bp
->max_dscp_value
< 0x3f)
395 bp
->max_dscp_value
= 0;
398 mutex_unlock(&bp
->hwrm_cmd_lock
);
402 static int bnxt_hwrm_queue_dscp2pri_cfg(struct bnxt
*bp
, struct dcb_app
*app
,
405 struct hwrm_queue_dscp2pri_cfg_input req
= {0};
406 struct bnxt_dscp2pri_entry
*dscp2pri
;
410 if (bp
->hwrm_spec_code
< 0x10800)
413 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_DSCP2PRI_CFG
, -1, -1);
414 dscp2pri
= dma_alloc_coherent(&bp
->pdev
->dev
, sizeof(*dscp2pri
),
415 &mapping
, GFP_KERNEL
);
419 req
.src_data_addr
= cpu_to_le64(mapping
);
420 dscp2pri
->dscp
= app
->protocol
;
422 dscp2pri
->mask
= 0x3f;
425 dscp2pri
->pri
= app
->priority
;
426 req
.entry_cnt
= cpu_to_le16(1);
427 rc
= hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
428 dma_free_coherent(&bp
->pdev
->dev
, sizeof(*dscp2pri
), dscp2pri
,
433 static int bnxt_ets_validate(struct bnxt
*bp
, struct ieee_ets
*ets
, u8
*tc
)
435 int total_ets_bw
= 0;
439 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
440 if (ets
->prio_tc
[i
] > bp
->max_tc
) {
441 netdev_err(bp
->dev
, "priority to TC mapping exceeds TC count %d\n",
445 if (ets
->prio_tc
[i
] > max_tc
)
446 max_tc
= ets
->prio_tc
[i
];
448 if ((ets
->tc_tx_bw
[i
] || ets
->tc_tsa
[i
]) && i
> bp
->max_tc
)
451 switch (ets
->tc_tsa
[i
]) {
452 case IEEE_8021QAZ_TSA_STRICT
:
454 case IEEE_8021QAZ_TSA_ETS
:
455 total_ets_bw
+= ets
->tc_tx_bw
[i
];
461 if (total_ets_bw
> 100)
464 if (max_tc
>= bp
->max_tc
)
471 static int bnxt_dcbnl_ieee_getets(struct net_device
*dev
, struct ieee_ets
*ets
)
473 struct bnxt
*bp
= netdev_priv(dev
);
474 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
477 ets
->ets_cap
= bp
->max_tc
;
480 if (bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
)
483 my_ets
= kzalloc(sizeof(*my_ets
), GFP_KERNEL
);
486 rc
= bnxt_hwrm_queue_cos2bw_qcfg(bp
, my_ets
);
489 rc
= bnxt_hwrm_queue_pri2cos_qcfg(bp
, my_ets
);
494 bp
->ieee_ets
= my_ets
;
497 ets
->cbs
= my_ets
->cbs
;
498 memcpy(ets
->tc_tx_bw
, my_ets
->tc_tx_bw
, sizeof(ets
->tc_tx_bw
));
499 memcpy(ets
->tc_rx_bw
, my_ets
->tc_rx_bw
, sizeof(ets
->tc_rx_bw
));
500 memcpy(ets
->tc_tsa
, my_ets
->tc_tsa
, sizeof(ets
->tc_tsa
));
501 memcpy(ets
->prio_tc
, my_ets
->prio_tc
, sizeof(ets
->prio_tc
));
508 static int bnxt_dcbnl_ieee_setets(struct net_device
*dev
, struct ieee_ets
*ets
)
510 struct bnxt
*bp
= netdev_priv(dev
);
511 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
515 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
516 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
519 rc
= bnxt_ets_validate(bp
, ets
, &max_tc
);
522 my_ets
= kzalloc(sizeof(*my_ets
), GFP_KERNEL
);
525 /* initialize PRI2TC mappings to invalid value */
526 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++)
527 my_ets
->prio_tc
[i
] = IEEE_8021QAZ_MAX_TCS
;
528 bp
->ieee_ets
= my_ets
;
530 rc
= bnxt_setup_mq_tc(dev
, max_tc
);
533 rc
= bnxt_hwrm_queue_cos2bw_cfg(bp
, ets
, max_tc
);
536 rc
= bnxt_hwrm_queue_pri2cos_cfg(bp
, ets
);
539 memcpy(my_ets
, ets
, sizeof(*my_ets
));
544 static int bnxt_dcbnl_ieee_getpfc(struct net_device
*dev
, struct ieee_pfc
*pfc
)
546 struct bnxt
*bp
= netdev_priv(dev
);
547 __le64
*stats
= bp
->port_stats
.hw_stats
;
548 struct ieee_pfc
*my_pfc
= bp
->ieee_pfc
;
552 pfc
->pfc_cap
= bp
->max_lltc
;
555 if (bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
)
558 my_pfc
= kzalloc(sizeof(*my_pfc
), GFP_KERNEL
);
561 bp
->ieee_pfc
= my_pfc
;
562 rc
= bnxt_hwrm_queue_pfc_qcfg(bp
, my_pfc
);
567 pfc
->pfc_en
= my_pfc
->pfc_en
;
568 pfc
->mbc
= my_pfc
->mbc
;
569 pfc
->delay
= my_pfc
->delay
;
574 rx_off
= BNXT_RX_STATS_OFFSET(rx_pfc_ena_frames_pri0
);
575 tx_off
= BNXT_TX_STATS_OFFSET(tx_pfc_ena_frames_pri0
);
576 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++, rx_off
++, tx_off
++) {
577 pfc
->requests
[i
] = le64_to_cpu(*(stats
+ tx_off
));
578 pfc
->indications
[i
] = le64_to_cpu(*(stats
+ rx_off
));
584 static int bnxt_dcbnl_ieee_setpfc(struct net_device
*dev
, struct ieee_pfc
*pfc
)
586 struct bnxt
*bp
= netdev_priv(dev
);
587 struct ieee_pfc
*my_pfc
= bp
->ieee_pfc
;
590 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
591 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
595 my_pfc
= kzalloc(sizeof(*my_pfc
), GFP_KERNEL
);
598 bp
->ieee_pfc
= my_pfc
;
600 rc
= bnxt_hwrm_queue_pfc_cfg(bp
, pfc
);
602 memcpy(my_pfc
, pfc
, sizeof(*my_pfc
));
607 static int bnxt_dcbnl_ieee_dscp_app_prep(struct bnxt
*bp
, struct dcb_app
*app
)
609 if (app
->selector
== IEEE_8021QAZ_APP_SEL_DSCP
) {
610 if (!bp
->max_dscp_value
)
612 if (app
->protocol
> bp
->max_dscp_value
)
618 static int bnxt_dcbnl_ieee_setapp(struct net_device
*dev
, struct dcb_app
*app
)
620 struct bnxt
*bp
= netdev_priv(dev
);
623 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
624 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
627 rc
= bnxt_dcbnl_ieee_dscp_app_prep(bp
, app
);
631 rc
= dcb_ieee_setapp(dev
, app
);
635 if ((app
->selector
== IEEE_8021QAZ_APP_SEL_ETHERTYPE
&&
636 app
->protocol
== ETH_P_IBOE
) ||
637 (app
->selector
== IEEE_8021QAZ_APP_SEL_DGRAM
&&
638 app
->protocol
== ROCE_V2_UDP_DPORT
))
639 rc
= bnxt_hwrm_set_dcbx_app(bp
, app
, true);
641 if (app
->selector
== IEEE_8021QAZ_APP_SEL_DSCP
)
642 rc
= bnxt_hwrm_queue_dscp2pri_cfg(bp
, app
, true);
647 static int bnxt_dcbnl_ieee_delapp(struct net_device
*dev
, struct dcb_app
*app
)
649 struct bnxt
*bp
= netdev_priv(dev
);
652 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
653 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
656 rc
= bnxt_dcbnl_ieee_dscp_app_prep(bp
, app
);
660 rc
= dcb_ieee_delapp(dev
, app
);
663 if ((app
->selector
== IEEE_8021QAZ_APP_SEL_ETHERTYPE
&&
664 app
->protocol
== ETH_P_IBOE
) ||
665 (app
->selector
== IEEE_8021QAZ_APP_SEL_DGRAM
&&
666 app
->protocol
== ROCE_V2_UDP_DPORT
))
667 rc
= bnxt_hwrm_set_dcbx_app(bp
, app
, false);
669 if (app
->selector
== IEEE_8021QAZ_APP_SEL_DSCP
)
670 rc
= bnxt_hwrm_queue_dscp2pri_cfg(bp
, app
, false);
675 static u8
bnxt_dcbnl_getdcbx(struct net_device
*dev
)
677 struct bnxt
*bp
= netdev_priv(dev
);
682 static u8
bnxt_dcbnl_setdcbx(struct net_device
*dev
, u8 mode
)
684 struct bnxt
*bp
= netdev_priv(dev
);
686 /* All firmware DCBX settings are set in NVRAM */
687 if (bp
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
)
690 if (mode
& DCB_CAP_DCBX_HOST
) {
691 if (BNXT_VF(bp
) || (bp
->fw_cap
& BNXT_FW_CAP_LLDP_AGENT
))
694 /* only support IEEE */
695 if ((mode
& DCB_CAP_DCBX_VER_CEE
) ||
696 !(mode
& DCB_CAP_DCBX_VER_IEEE
))
700 if (mode
== bp
->dcbx_cap
)
707 static const struct dcbnl_rtnl_ops dcbnl_ops
= {
708 .ieee_getets
= bnxt_dcbnl_ieee_getets
,
709 .ieee_setets
= bnxt_dcbnl_ieee_setets
,
710 .ieee_getpfc
= bnxt_dcbnl_ieee_getpfc
,
711 .ieee_setpfc
= bnxt_dcbnl_ieee_setpfc
,
712 .ieee_setapp
= bnxt_dcbnl_ieee_setapp
,
713 .ieee_delapp
= bnxt_dcbnl_ieee_delapp
,
714 .getdcbx
= bnxt_dcbnl_getdcbx
,
715 .setdcbx
= bnxt_dcbnl_setdcbx
,
718 void bnxt_dcb_init(struct bnxt
*bp
)
721 if (bp
->hwrm_spec_code
< 0x10501)
724 bnxt_hwrm_queue_dscp_qcaps(bp
);
725 bp
->dcbx_cap
= DCB_CAP_DCBX_VER_IEEE
;
726 if (BNXT_PF(bp
) && !(bp
->fw_cap
& BNXT_FW_CAP_LLDP_AGENT
))
727 bp
->dcbx_cap
|= DCB_CAP_DCBX_HOST
;
728 else if (bp
->fw_cap
& BNXT_FW_CAP_DCBX_AGENT
)
729 bp
->dcbx_cap
|= DCB_CAP_DCBX_LLD_MANAGED
;
730 bp
->dev
->dcbnl_ops
= &dcbnl_ops
;
733 void bnxt_dcb_free(struct bnxt
*bp
)
743 void bnxt_dcb_init(struct bnxt
*bp
)
747 void bnxt_dcb_free(struct bnxt
*bp
)