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_hwrm_queue_pri2cos_cfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
26 struct hwrm_queue_pri2cos_cfg_input req
= {0};
30 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PRI2COS_CFG
, -1, -1);
31 req
.flags
= cpu_to_le32(QUEUE_PRI2COS_CFG_REQ_FLAGS_PATH_BIDIR
|
32 QUEUE_PRI2COS_CFG_REQ_FLAGS_IVLAN
);
34 pri2cos
= &req
.pri0_cos_queue_id
;
35 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
36 req
.enables
|= cpu_to_le32(
37 QUEUE_PRI2COS_CFG_REQ_ENABLES_PRI0_COS_QUEUE_ID
<< i
);
39 pri2cos
[i
] = bp
->q_info
[ets
->prio_tc
[i
]].queue_id
;
41 rc
= hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
45 static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
47 struct hwrm_queue_pri2cos_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
48 struct hwrm_queue_pri2cos_qcfg_input req
= {0};
51 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PRI2COS_QCFG
, -1, -1);
52 req
.flags
= cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN
);
54 mutex_lock(&bp
->hwrm_cmd_lock
);
55 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
57 u8
*pri2cos
= &resp
->pri0_cos_queue_id
;
60 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
61 u8 queue_id
= pri2cos
[i
];
63 for (j
= 0; j
< bp
->max_tc
; j
++) {
64 if (bp
->q_info
[j
].queue_id
== queue_id
) {
71 mutex_unlock(&bp
->hwrm_cmd_lock
);
75 static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt
*bp
, struct ieee_ets
*ets
,
78 struct hwrm_queue_cos2bw_cfg_input req
= {0};
79 struct bnxt_cos2bw_cfg cos2bw
;
83 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_COS2BW_CFG
, -1, -1);
85 for (i
= 0; i
< max_tc
; i
++, data
+= sizeof(cos2bw
) - 4) {
86 req
.enables
|= cpu_to_le32(
87 QUEUE_COS2BW_CFG_REQ_ENABLES_COS_QUEUE_ID0_VALID
<< i
);
89 memset(&cos2bw
, 0, sizeof(cos2bw
));
90 cos2bw
.queue_id
= bp
->q_info
[i
].queue_id
;
91 if (ets
->tc_tsa
[i
] == IEEE_8021QAZ_TSA_STRICT
) {
93 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP
;
97 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_ETS
;
98 cos2bw
.bw_weight
= ets
->tc_tx_bw
[i
];
99 /* older firmware requires min_bw to be set to the
100 * same weight value in percent.
103 cpu_to_le32((ets
->tc_tx_bw
[i
] * 100) |
104 BW_VALUE_UNIT_PERCENT1_100
);
106 memcpy(data
, &cos2bw
.queue_id
, sizeof(cos2bw
) - 4);
108 req
.queue_id0
= cos2bw
.queue_id
;
112 rc
= hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
116 static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt
*bp
, struct ieee_ets
*ets
)
118 struct hwrm_queue_cos2bw_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
119 struct hwrm_queue_cos2bw_qcfg_input req
= {0};
120 struct bnxt_cos2bw_cfg cos2bw
;
124 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_COS2BW_QCFG
, -1, -1);
126 mutex_lock(&bp
->hwrm_cmd_lock
);
127 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
129 mutex_unlock(&bp
->hwrm_cmd_lock
);
133 data
= &resp
->queue_id0
+ offsetof(struct bnxt_cos2bw_cfg
, queue_id
);
134 for (i
= 0; i
< bp
->max_tc
; i
++, data
+= sizeof(cos2bw
) - 4) {
137 memcpy(&cos2bw
.queue_id
, data
, sizeof(cos2bw
) - 4);
139 cos2bw
.queue_id
= resp
->queue_id0
;
141 for (j
= 0; j
< bp
->max_tc
; j
++) {
142 if (bp
->q_info
[j
].queue_id
!= cos2bw
.queue_id
)
145 QUEUE_COS2BW_QCFG_RESP_QUEUE_ID0_TSA_ASSIGN_SP
) {
146 ets
->tc_tsa
[j
] = IEEE_8021QAZ_TSA_STRICT
;
148 ets
->tc_tsa
[j
] = IEEE_8021QAZ_TSA_ETS
;
149 ets
->tc_tx_bw
[j
] = cos2bw
.bw_weight
;
153 mutex_unlock(&bp
->hwrm_cmd_lock
);
157 static int bnxt_hwrm_queue_cfg(struct bnxt
*bp
, unsigned int lltc_mask
)
159 struct hwrm_queue_cfg_input req
= {0};
162 if (netif_running(bp
->dev
))
165 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_CFG
, -1, -1);
166 req
.flags
= cpu_to_le32(QUEUE_CFG_REQ_FLAGS_PATH_BIDIR
);
167 req
.enables
= cpu_to_le32(QUEUE_CFG_REQ_ENABLES_SERVICE_PROFILE
);
169 /* Configure lossless queues to lossy first */
170 req
.service_profile
= QUEUE_CFG_REQ_SERVICE_PROFILE_LOSSY
;
171 for (i
= 0; i
< bp
->max_tc
; i
++) {
172 if (BNXT_LLQ(bp
->q_info
[i
].queue_profile
)) {
173 req
.queue_id
= cpu_to_le32(bp
->q_info
[i
].queue_id
);
174 hwrm_send_message(bp
, &req
, sizeof(req
),
176 bp
->q_info
[i
].queue_profile
=
177 QUEUE_CFG_REQ_SERVICE_PROFILE_LOSSY
;
181 /* Now configure desired queues to lossless */
182 req
.service_profile
= QUEUE_CFG_REQ_SERVICE_PROFILE_LOSSLESS
;
183 for (i
= 0; i
< bp
->max_tc
; i
++) {
184 if (lltc_mask
& (1 << i
)) {
185 req
.queue_id
= cpu_to_le32(bp
->q_info
[i
].queue_id
);
186 hwrm_send_message(bp
, &req
, sizeof(req
),
188 bp
->q_info
[i
].queue_profile
=
189 QUEUE_CFG_REQ_SERVICE_PROFILE_LOSSLESS
;
192 if (netif_running(bp
->dev
))
198 static int bnxt_hwrm_queue_pfc_cfg(struct bnxt
*bp
, struct ieee_pfc
*pfc
)
200 struct hwrm_queue_pfcenable_cfg_input req
= {0};
201 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
202 unsigned int tc_mask
= 0, pri_mask
= 0;
203 u8 i
, pri
, lltc_count
= 0;
204 bool need_q_recfg
= false;
210 for (i
= 0; i
< bp
->max_tc
; i
++) {
211 for (pri
= 0; pri
< IEEE_8021QAZ_MAX_TCS
; pri
++) {
212 if ((pfc
->pfc_en
& (1 << pri
)) &&
213 (my_ets
->prio_tc
[pri
] == i
)) {
214 pri_mask
|= 1 << pri
;
218 if (tc_mask
& (1 << i
))
221 if (lltc_count
> bp
->max_lltc
)
224 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PFCENABLE_CFG
, -1, -1);
225 req
.flags
= cpu_to_le32(pri_mask
);
226 rc
= hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
230 for (i
= 0; i
< bp
->max_tc
; i
++) {
231 if (tc_mask
& (1 << i
)) {
232 if (!BNXT_LLQ(bp
->q_info
[i
].queue_profile
))
238 rc
= bnxt_hwrm_queue_cfg(bp
, tc_mask
);
243 static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt
*bp
, struct ieee_pfc
*pfc
)
245 struct hwrm_queue_pfcenable_qcfg_output
*resp
= bp
->hwrm_cmd_resp_addr
;
246 struct hwrm_queue_pfcenable_qcfg_input req
= {0};
250 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_QUEUE_PFCENABLE_QCFG
, -1, -1);
252 mutex_lock(&bp
->hwrm_cmd_lock
);
253 rc
= _hwrm_send_message(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
255 mutex_unlock(&bp
->hwrm_cmd_lock
);
259 pri_mask
= le32_to_cpu(resp
->flags
);
260 pfc
->pfc_en
= pri_mask
;
261 mutex_unlock(&bp
->hwrm_cmd_lock
);
265 static int bnxt_hwrm_set_dcbx_app(struct bnxt
*bp
, struct dcb_app
*app
,
268 struct hwrm_fw_set_structured_data_input set
= {0};
269 struct hwrm_fw_get_structured_data_input get
= {0};
270 struct hwrm_struct_data_dcbx_app
*fw_app
;
271 struct hwrm_struct_hdr
*data
;
276 if (bp
->hwrm_spec_code
< 0x10601)
279 n
= IEEE_8021QAZ_MAX_TCS
;
280 data_len
= sizeof(*data
) + sizeof(*fw_app
) * n
;
281 data
= dma_zalloc_coherent(&bp
->pdev
->dev
, data_len
, &mapping
,
286 bnxt_hwrm_cmd_hdr_init(bp
, &get
, HWRM_FW_GET_STRUCTURED_DATA
, -1, -1);
287 get
.dest_data_addr
= cpu_to_le64(mapping
);
288 get
.structure_id
= cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP
);
289 get
.subtype
= cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL
);
291 rc
= hwrm_send_message(bp
, &get
, sizeof(get
), HWRM_CMD_TIMEOUT
);
295 fw_app
= (struct hwrm_struct_data_dcbx_app
*)(data
+ 1);
297 if (data
->struct_id
!= cpu_to_le16(STRUCT_HDR_STRUCT_ID_DCBX_APP
)) {
303 for (i
= 0; i
< n
; i
++, fw_app
++) {
304 if (fw_app
->protocol_id
== cpu_to_be16(app
->protocol
) &&
305 fw_app
->protocol_selector
== app
->selector
&&
306 fw_app
->priority
== app
->priority
) {
316 fw_app
->protocol_id
= cpu_to_be16(app
->protocol
);
317 fw_app
->protocol_selector
= app
->selector
;
318 fw_app
->priority
= app
->priority
;
323 /* not found, nothing to delete */
327 len
= (n
- 1 - i
) * sizeof(*fw_app
);
329 memmove(fw_app
, fw_app
+ 1, len
);
331 memset(fw_app
+ n
, 0, sizeof(*fw_app
));
334 data
->len
= cpu_to_le16(sizeof(*fw_app
) * n
);
335 data
->subtype
= cpu_to_le16(HWRM_STRUCT_DATA_SUBTYPE_HOST_OPERATIONAL
);
337 bnxt_hwrm_cmd_hdr_init(bp
, &set
, HWRM_FW_SET_STRUCTURED_DATA
, -1, -1);
338 set
.src_data_addr
= cpu_to_le64(mapping
);
339 set
.data_len
= cpu_to_le16(sizeof(*data
) + sizeof(*fw_app
) * n
);
341 rc
= hwrm_send_message(bp
, &set
, sizeof(set
), HWRM_CMD_TIMEOUT
);
346 dma_free_coherent(&bp
->pdev
->dev
, data_len
, data
, mapping
);
350 static int bnxt_ets_validate(struct bnxt
*bp
, struct ieee_ets
*ets
, u8
*tc
)
352 int total_ets_bw
= 0;
356 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++) {
357 if (ets
->prio_tc
[i
] > bp
->max_tc
) {
358 netdev_err(bp
->dev
, "priority to TC mapping exceeds TC count %d\n",
362 if (ets
->prio_tc
[i
] > max_tc
)
363 max_tc
= ets
->prio_tc
[i
];
365 if ((ets
->tc_tx_bw
[i
] || ets
->tc_tsa
[i
]) && i
> bp
->max_tc
)
368 switch (ets
->tc_tsa
[i
]) {
369 case IEEE_8021QAZ_TSA_STRICT
:
371 case IEEE_8021QAZ_TSA_ETS
:
372 total_ets_bw
+= ets
->tc_tx_bw
[i
];
378 if (total_ets_bw
> 100)
385 static int bnxt_dcbnl_ieee_getets(struct net_device
*dev
, struct ieee_ets
*ets
)
387 struct bnxt
*bp
= netdev_priv(dev
);
388 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
390 ets
->ets_cap
= bp
->max_tc
;
395 if (bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
)
398 my_ets
= kzalloc(sizeof(*my_ets
), GFP_KERNEL
);
401 rc
= bnxt_hwrm_queue_cos2bw_qcfg(bp
, my_ets
);
404 rc
= bnxt_hwrm_queue_pri2cos_qcfg(bp
, my_ets
);
409 ets
->cbs
= my_ets
->cbs
;
410 memcpy(ets
->tc_tx_bw
, my_ets
->tc_tx_bw
, sizeof(ets
->tc_tx_bw
));
411 memcpy(ets
->tc_rx_bw
, my_ets
->tc_rx_bw
, sizeof(ets
->tc_rx_bw
));
412 memcpy(ets
->tc_tsa
, my_ets
->tc_tsa
, sizeof(ets
->tc_tsa
));
413 memcpy(ets
->prio_tc
, my_ets
->prio_tc
, sizeof(ets
->prio_tc
));
417 static int bnxt_dcbnl_ieee_setets(struct net_device
*dev
, struct ieee_ets
*ets
)
419 struct bnxt
*bp
= netdev_priv(dev
);
420 struct ieee_ets
*my_ets
= bp
->ieee_ets
;
424 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
425 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
428 rc
= bnxt_ets_validate(bp
, ets
, &max_tc
);
431 my_ets
= kzalloc(sizeof(*my_ets
), GFP_KERNEL
);
434 /* initialize PRI2TC mappings to invalid value */
435 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++)
436 my_ets
->prio_tc
[i
] = IEEE_8021QAZ_MAX_TCS
;
437 bp
->ieee_ets
= my_ets
;
439 rc
= bnxt_setup_mq_tc(dev
, max_tc
);
442 rc
= bnxt_hwrm_queue_cos2bw_cfg(bp
, ets
, max_tc
);
445 rc
= bnxt_hwrm_queue_pri2cos_cfg(bp
, ets
);
448 memcpy(my_ets
, ets
, sizeof(*my_ets
));
453 static int bnxt_dcbnl_ieee_getpfc(struct net_device
*dev
, struct ieee_pfc
*pfc
)
455 struct bnxt
*bp
= netdev_priv(dev
);
456 __le64
*stats
= (__le64
*)bp
->hw_rx_port_stats
;
457 struct ieee_pfc
*my_pfc
= bp
->ieee_pfc
;
461 pfc
->pfc_cap
= bp
->max_lltc
;
464 if (bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
)
467 my_pfc
= kzalloc(sizeof(*my_pfc
), GFP_KERNEL
);
470 bp
->ieee_pfc
= my_pfc
;
471 rc
= bnxt_hwrm_queue_pfc_qcfg(bp
, my_pfc
);
476 pfc
->pfc_en
= my_pfc
->pfc_en
;
477 pfc
->mbc
= my_pfc
->mbc
;
478 pfc
->delay
= my_pfc
->delay
;
483 rx_off
= BNXT_RX_STATS_OFFSET(rx_pfc_ena_frames_pri0
);
484 tx_off
= BNXT_TX_STATS_OFFSET(tx_pfc_ena_frames_pri0
);
485 for (i
= 0; i
< IEEE_8021QAZ_MAX_TCS
; i
++, rx_off
++, tx_off
++) {
486 pfc
->requests
[i
] = le64_to_cpu(*(stats
+ tx_off
));
487 pfc
->indications
[i
] = le64_to_cpu(*(stats
+ rx_off
));
493 static int bnxt_dcbnl_ieee_setpfc(struct net_device
*dev
, struct ieee_pfc
*pfc
)
495 struct bnxt
*bp
= netdev_priv(dev
);
496 struct ieee_pfc
*my_pfc
= bp
->ieee_pfc
;
499 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
500 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
504 my_pfc
= kzalloc(sizeof(*my_pfc
), GFP_KERNEL
);
507 bp
->ieee_pfc
= my_pfc
;
509 rc
= bnxt_hwrm_queue_pfc_cfg(bp
, pfc
);
511 memcpy(my_pfc
, pfc
, sizeof(*my_pfc
));
516 static int bnxt_dcbnl_ieee_setapp(struct net_device
*dev
, struct dcb_app
*app
)
518 struct bnxt
*bp
= netdev_priv(dev
);
521 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
522 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
525 rc
= dcb_ieee_setapp(dev
, app
);
529 if ((app
->selector
== IEEE_8021QAZ_APP_SEL_ETHERTYPE
&&
530 app
->protocol
== ETH_P_IBOE
) ||
531 (app
->selector
== IEEE_8021QAZ_APP_SEL_DGRAM
&&
532 app
->protocol
== ROCE_V2_UDP_DPORT
))
533 rc
= bnxt_hwrm_set_dcbx_app(bp
, app
, true);
538 static int bnxt_dcbnl_ieee_delapp(struct net_device
*dev
, struct dcb_app
*app
)
540 struct bnxt
*bp
= netdev_priv(dev
);
543 if (!(bp
->dcbx_cap
& DCB_CAP_DCBX_VER_IEEE
) ||
544 !(bp
->dcbx_cap
& DCB_CAP_DCBX_HOST
))
547 rc
= dcb_ieee_delapp(dev
, app
);
550 if ((app
->selector
== IEEE_8021QAZ_APP_SEL_ETHERTYPE
&&
551 app
->protocol
== ETH_P_IBOE
) ||
552 (app
->selector
== IEEE_8021QAZ_APP_SEL_DGRAM
&&
553 app
->protocol
== ROCE_V2_UDP_DPORT
))
554 rc
= bnxt_hwrm_set_dcbx_app(bp
, app
, false);
559 static u8
bnxt_dcbnl_getdcbx(struct net_device
*dev
)
561 struct bnxt
*bp
= netdev_priv(dev
);
566 static u8
bnxt_dcbnl_setdcbx(struct net_device
*dev
, u8 mode
)
568 struct bnxt
*bp
= netdev_priv(dev
);
570 /* All firmware DCBX settings are set in NVRAM */
571 if (bp
->dcbx_cap
& DCB_CAP_DCBX_LLD_MANAGED
)
574 if (mode
& DCB_CAP_DCBX_HOST
) {
575 if (BNXT_VF(bp
) || (bp
->flags
& BNXT_FLAG_FW_LLDP_AGENT
))
578 /* only support IEEE */
579 if ((mode
& DCB_CAP_DCBX_VER_CEE
) ||
580 !(mode
& DCB_CAP_DCBX_VER_IEEE
))
584 if (mode
== bp
->dcbx_cap
)
591 static const struct dcbnl_rtnl_ops dcbnl_ops
= {
592 .ieee_getets
= bnxt_dcbnl_ieee_getets
,
593 .ieee_setets
= bnxt_dcbnl_ieee_setets
,
594 .ieee_getpfc
= bnxt_dcbnl_ieee_getpfc
,
595 .ieee_setpfc
= bnxt_dcbnl_ieee_setpfc
,
596 .ieee_setapp
= bnxt_dcbnl_ieee_setapp
,
597 .ieee_delapp
= bnxt_dcbnl_ieee_delapp
,
598 .getdcbx
= bnxt_dcbnl_getdcbx
,
599 .setdcbx
= bnxt_dcbnl_setdcbx
,
602 void bnxt_dcb_init(struct bnxt
*bp
)
604 if (bp
->hwrm_spec_code
< 0x10501)
607 bp
->dcbx_cap
= DCB_CAP_DCBX_VER_IEEE
;
608 if (BNXT_PF(bp
) && !(bp
->flags
& BNXT_FLAG_FW_LLDP_AGENT
))
609 bp
->dcbx_cap
|= DCB_CAP_DCBX_HOST
;
610 else if (bp
->flags
& BNXT_FLAG_FW_DCBX_AGENT
)
611 bp
->dcbx_cap
|= DCB_CAP_DCBX_LLD_MANAGED
;
612 bp
->dev
->dcbnl_ops
= &dcbnl_ops
;
615 void bnxt_dcb_free(struct bnxt
*bp
)
625 void bnxt_dcb_init(struct bnxt
*bp
)
629 void bnxt_dcb_free(struct bnxt
*bp
)