1 /* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
9 #include <linux/types.h>
10 #include <asm/byteorder.h>
11 #include <linux/bitops.h>
12 #include <linux/dcbnl.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/string.h>
23 #include <linux/qed/qed_eth_if.h>
26 #define QED_DCBX_MAX_MIB_READ_TRY (100)
27 #define QED_ETH_TYPE_DEFAULT (0)
28 #define QED_ETH_TYPE_ROCE (0x8915)
29 #define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7)
30 #define QED_ETH_TYPE_FCOE (0x8906)
31 #define QED_TCP_PORT_ISCSI (0xCBC)
33 #define QED_DCBX_INVALID_PRIORITY 0xFF
35 /* Get Traffic Class from priority traffic class table, 4 bits represent
36 * the traffic class corresponding to the priority.
38 #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \
39 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
41 static const struct qed_dcbx_app_metadata qed_dcbx_app_update
[] = {
42 {DCBX_PROTOCOL_ISCSI
, "ISCSI", QED_PCI_DEFAULT
},
43 {DCBX_PROTOCOL_FCOE
, "FCOE", QED_PCI_DEFAULT
},
44 {DCBX_PROTOCOL_ROCE
, "ROCE", QED_PCI_DEFAULT
},
45 {DCBX_PROTOCOL_ROCE_V2
, "ROCE_V2", QED_PCI_DEFAULT
},
46 {DCBX_PROTOCOL_ETH
, "ETH", QED_PCI_ETH
}
49 static bool qed_dcbx_app_ethtype(u32 app_info_bitmap
)
51 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
55 static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap
)
57 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
60 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
61 return qed_dcbx_app_ethtype(app_info_bitmap
);
63 return !!(mfw_val
== DCBX_APP_SF_IEEE_ETHTYPE
);
66 static bool qed_dcbx_app_port(u32 app_info_bitmap
)
68 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
72 static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap
, u8 type
)
74 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
77 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
78 return qed_dcbx_app_port(app_info_bitmap
);
80 return !!(mfw_val
== type
|| mfw_val
== DCBX_APP_SF_IEEE_TCP_UDP_PORT
);
83 static bool qed_dcbx_default_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
88 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
90 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
92 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_DEFAULT
));
95 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
100 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
101 DCBX_APP_SF_IEEE_TCP_PORT
);
103 port
= qed_dcbx_app_port(app_info_bitmap
);
105 return !!(port
&& (proto_id
== QED_TCP_PORT_ISCSI
));
108 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
113 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
115 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
117 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_FCOE
));
120 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
125 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
127 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
129 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_ROCE
));
132 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
137 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
138 DCBX_APP_SF_IEEE_UDP_PORT
);
140 port
= qed_dcbx_app_port(app_info_bitmap
);
142 return !!(port
&& (proto_id
== QED_UDP_PORT_TYPE_ROCE_V2
));
146 qed_dcbx_dp_protocol(struct qed_hwfn
*p_hwfn
, struct qed_dcbx_results
*p_data
)
148 enum dcbx_protocol_type id
;
151 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "DCBX negotiated: %d\n",
152 p_data
->dcbx_enabled
);
154 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
155 id
= qed_dcbx_app_update
[i
].id
;
157 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
158 "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
159 qed_dcbx_app_update
[i
].name
, p_data
->arr
[id
].update
,
160 p_data
->arr
[id
].enable
, p_data
->arr
[id
].priority
,
161 p_data
->arr
[id
].tc
, p_hwfn
->hw_info
.num_tc
);
166 qed_dcbx_set_params(struct qed_dcbx_results
*p_data
,
167 struct qed_hw_info
*p_info
,
172 enum dcbx_protocol_type type
,
173 enum qed_pci_personality personality
)
175 /* PF update ramrod data */
176 p_data
->arr
[type
].update
= update
;
177 p_data
->arr
[type
].enable
= enable
;
178 p_data
->arr
[type
].priority
= prio
;
179 p_data
->arr
[type
].tc
= tc
;
182 if (p_info
->personality
== personality
) {
183 if (personality
== QED_PCI_ETH
)
184 p_info
->non_offload_tc
= tc
;
186 p_info
->offload_tc
= tc
;
190 /* Update app protocol data and hw_info fields with the TLV info */
192 qed_dcbx_update_app_info(struct qed_dcbx_results
*p_data
,
193 struct qed_hwfn
*p_hwfn
,
196 u8 prio
, u8 tc
, enum dcbx_protocol_type type
)
198 struct qed_hw_info
*p_info
= &p_hwfn
->hw_info
;
199 enum qed_pci_personality personality
;
200 enum dcbx_protocol_type id
;
204 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
205 id
= qed_dcbx_app_update
[i
].id
;
210 personality
= qed_dcbx_app_update
[i
].personality
;
211 name
= qed_dcbx_app_update
[i
].name
;
213 qed_dcbx_set_params(p_data
, p_info
, enable
, update
,
214 prio
, tc
, type
, personality
);
219 qed_dcbx_get_app_protocol_type(struct qed_hwfn
*p_hwfn
,
221 u16 id
, enum dcbx_protocol_type
*type
, bool ieee
)
223 if (qed_dcbx_fcoe_tlv(app_prio_bitmap
, id
, ieee
)) {
224 *type
= DCBX_PROTOCOL_FCOE
;
225 } else if (qed_dcbx_roce_tlv(app_prio_bitmap
, id
, ieee
)) {
226 *type
= DCBX_PROTOCOL_ROCE
;
227 } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap
, id
, ieee
)) {
228 *type
= DCBX_PROTOCOL_ISCSI
;
229 } else if (qed_dcbx_default_tlv(app_prio_bitmap
, id
, ieee
)) {
230 *type
= DCBX_PROTOCOL_ETH
;
231 } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap
, id
, ieee
)) {
232 *type
= DCBX_PROTOCOL_ROCE_V2
;
234 *type
= DCBX_MAX_PROTOCOL_TYPE
;
236 "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
237 id
, app_prio_bitmap
);
244 /* Parse app TLV's to update TC information in hw_info structure for
245 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
248 qed_dcbx_process_tlv(struct qed_hwfn
*p_hwfn
,
249 struct qed_dcbx_results
*p_data
,
250 struct dcbx_app_priority_entry
*p_tbl
,
251 u32 pri_tc_tbl
, int count
, u8 dcbx_version
)
254 enum dcbx_protocol_type type
;
260 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Num APP entries = %d\n", count
);
262 ieee
= (dcbx_version
== DCBX_CONFIG_VERSION_IEEE
);
264 for (i
= 0; i
< count
; i
++) {
265 protocol_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
266 DCBX_APP_PROTOCOL_ID
);
267 priority_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
269 priority
= ffs(priority_map
) - 1;
271 DP_ERR(p_hwfn
, "Invalid priority\n");
275 tc
= QED_DCBX_PRIO2TC(pri_tc_tbl
, priority
);
276 if (qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
277 protocol_id
, &type
, ieee
)) {
278 /* ETH always have the enable bit reset, as it gets
279 * vlan information per packet. For other protocols,
280 * should be set according to the dcbx_enabled
281 * indication, but we only got here if there was an
282 * app tlv for the protocol, so dcbx must be enabled.
284 enable
= !(type
== DCBX_PROTOCOL_ETH
);
286 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
291 /* If RoCE-V2 TLV is not detected, driver need to use RoCE app
292 * data for RoCE-v2 not the default app data.
294 if (!p_data
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
295 p_data
->arr
[DCBX_PROTOCOL_ROCE
].update
) {
296 tc
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].tc
;
297 priority
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
298 qed_dcbx_update_app_info(p_data
, p_hwfn
, true, true,
299 priority
, tc
, DCBX_PROTOCOL_ROCE_V2
);
302 /* Update ramrod protocol data and hw_info fields
303 * with default info when corresponding APP TLV's are not detected.
304 * The enabled field has a different logic for ethernet as only for
305 * ethernet dcb should disabled by default, as the information arrives
306 * from the OS (unless an explicit app tlv was present).
308 tc
= p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
;
309 priority
= p_data
->arr
[DCBX_PROTOCOL_ETH
].priority
;
310 for (type
= 0; type
< DCBX_MAX_PROTOCOL_TYPE
; type
++) {
311 if (p_data
->arr
[type
].update
)
314 enable
= !(type
== DCBX_PROTOCOL_ETH
);
315 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
322 /* Parse app TLV's to update TC information in hw_info structure for
323 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
325 static int qed_dcbx_process_mib_info(struct qed_hwfn
*p_hwfn
)
327 struct dcbx_app_priority_feature
*p_app
;
328 struct dcbx_app_priority_entry
*p_tbl
;
329 struct qed_dcbx_results data
= { 0 };
330 struct dcbx_ets_feature
*p_ets
;
331 struct qed_hw_info
*p_info
;
332 u32 pri_tc_tbl
, flags
;
337 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
338 dcbx_version
= QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
);
340 p_app
= &p_hwfn
->p_dcbx_info
->operational
.features
.app
;
341 p_tbl
= p_app
->app_pri_tbl
;
343 p_ets
= &p_hwfn
->p_dcbx_info
->operational
.features
.ets
;
344 pri_tc_tbl
= p_ets
->pri_tc_tbl
[0];
346 p_info
= &p_hwfn
->hw_info
;
347 num_entries
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_NUM_ENTRIES
);
349 rc
= qed_dcbx_process_tlv(p_hwfn
, &data
, p_tbl
, pri_tc_tbl
,
350 num_entries
, dcbx_version
);
354 p_info
->num_tc
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
355 data
.pf_id
= p_hwfn
->rel_pf_id
;
356 data
.dcbx_enabled
= !!dcbx_version
;
358 qed_dcbx_dp_protocol(p_hwfn
, &data
);
360 memcpy(&p_hwfn
->p_dcbx_info
->results
, &data
,
361 sizeof(struct qed_dcbx_results
));
367 qed_dcbx_copy_mib(struct qed_hwfn
*p_hwfn
,
368 struct qed_ptt
*p_ptt
,
369 struct qed_dcbx_mib_meta_data
*p_data
,
370 enum qed_mib_read_type type
)
372 u32 prefix_seq_num
, suffix_seq_num
;
376 /* The data is considered to be valid only if both sequence numbers are
380 if (type
== QED_DCBX_REMOTE_LLDP_MIB
) {
381 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_remote
,
382 p_data
->addr
, p_data
->size
);
383 prefix_seq_num
= p_data
->lldp_remote
->prefix_seq_num
;
384 suffix_seq_num
= p_data
->lldp_remote
->suffix_seq_num
;
386 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->mib
,
387 p_data
->addr
, p_data
->size
);
388 prefix_seq_num
= p_data
->mib
->prefix_seq_num
;
389 suffix_seq_num
= p_data
->mib
->suffix_seq_num
;
395 "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
396 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
397 } while ((prefix_seq_num
!= suffix_seq_num
) &&
398 (read_count
< QED_DCBX_MAX_MIB_READ_TRY
));
400 if (read_count
>= QED_DCBX_MAX_MIB_READ_TRY
) {
402 "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
403 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
412 qed_dcbx_get_priority_info(struct qed_hwfn
*p_hwfn
,
413 struct qed_dcbx_app_prio
*p_prio
,
414 struct qed_dcbx_results
*p_results
)
418 p_prio
->roce
= QED_DCBX_INVALID_PRIORITY
;
419 p_prio
->roce_v2
= QED_DCBX_INVALID_PRIORITY
;
420 p_prio
->iscsi
= QED_DCBX_INVALID_PRIORITY
;
421 p_prio
->fcoe
= QED_DCBX_INVALID_PRIORITY
;
423 if (p_results
->arr
[DCBX_PROTOCOL_ROCE
].update
&&
424 p_results
->arr
[DCBX_PROTOCOL_ROCE
].enable
)
425 p_prio
->roce
= p_results
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
427 if (p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
428 p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].enable
) {
429 val
= p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].priority
;
430 p_prio
->roce_v2
= val
;
433 if (p_results
->arr
[DCBX_PROTOCOL_ISCSI
].update
&&
434 p_results
->arr
[DCBX_PROTOCOL_ISCSI
].enable
)
435 p_prio
->iscsi
= p_results
->arr
[DCBX_PROTOCOL_ISCSI
].priority
;
437 if (p_results
->arr
[DCBX_PROTOCOL_FCOE
].update
&&
438 p_results
->arr
[DCBX_PROTOCOL_FCOE
].enable
)
439 p_prio
->fcoe
= p_results
->arr
[DCBX_PROTOCOL_FCOE
].priority
;
441 if (p_results
->arr
[DCBX_PROTOCOL_ETH
].update
&&
442 p_results
->arr
[DCBX_PROTOCOL_ETH
].enable
)
443 p_prio
->eth
= p_results
->arr
[DCBX_PROTOCOL_ETH
].priority
;
445 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
446 "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
447 p_prio
->iscsi
, p_prio
->roce
, p_prio
->roce_v2
, p_prio
->fcoe
,
452 qed_dcbx_get_app_data(struct qed_hwfn
*p_hwfn
,
453 struct dcbx_app_priority_feature
*p_app
,
454 struct dcbx_app_priority_entry
*p_tbl
,
455 struct qed_dcbx_params
*p_params
, bool ieee
)
457 struct qed_app_entry
*entry
;
461 p_params
->app_willing
= QED_MFW_GET_FIELD(p_app
->flags
,
463 p_params
->app_valid
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ENABLED
);
464 p_params
->app_error
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ERROR
);
465 p_params
->num_app_entries
= QED_MFW_GET_FIELD(p_app
->flags
,
466 DCBX_APP_NUM_ENTRIES
);
467 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
468 entry
= &p_params
->app_entry
[i
];
473 sf_ieee
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
476 case DCBX_APP_SF_IEEE_RESERVED
:
478 val
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
480 entry
->sf_ieee
= val
?
481 QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
482 QED_DCBX_SF_IEEE_ETHTYPE
;
484 case DCBX_APP_SF_IEEE_ETHTYPE
:
485 entry
->sf_ieee
= QED_DCBX_SF_IEEE_ETHTYPE
;
487 case DCBX_APP_SF_IEEE_TCP_PORT
:
488 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_PORT
;
490 case DCBX_APP_SF_IEEE_UDP_PORT
:
491 entry
->sf_ieee
= QED_DCBX_SF_IEEE_UDP_PORT
;
493 case DCBX_APP_SF_IEEE_TCP_UDP_PORT
:
494 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_UDP_PORT
;
498 entry
->ethtype
= !(QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
502 pri_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
503 entry
->prio
= ffs(pri_map
) - 1;
504 entry
->proto_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
505 DCBX_APP_PROTOCOL_ID
);
506 qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
508 &entry
->proto_type
, ieee
);
511 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
512 "APP params: willing %d, valid %d error = %d\n",
513 p_params
->app_willing
, p_params
->app_valid
,
514 p_params
->app_error
);
518 qed_dcbx_get_pfc_data(struct qed_hwfn
*p_hwfn
,
519 u32 pfc
, struct qed_dcbx_params
*p_params
)
523 p_params
->pfc
.willing
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_WILLING
);
524 p_params
->pfc
.max_tc
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_CAPS
);
525 p_params
->pfc
.enabled
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_ENABLED
);
526 pfc_map
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_PRI_EN_BITMAP
);
527 p_params
->pfc
.prio
[0] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_0
);
528 p_params
->pfc
.prio
[1] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_1
);
529 p_params
->pfc
.prio
[2] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_2
);
530 p_params
->pfc
.prio
[3] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_3
);
531 p_params
->pfc
.prio
[4] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_4
);
532 p_params
->pfc
.prio
[5] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_5
);
533 p_params
->pfc
.prio
[6] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_6
);
534 p_params
->pfc
.prio
[7] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_7
);
536 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
537 "PFC params: willing %d, pfc_bitmap %d\n",
538 p_params
->pfc
.willing
, pfc_map
);
542 qed_dcbx_get_ets_data(struct qed_hwfn
*p_hwfn
,
543 struct dcbx_ets_feature
*p_ets
,
544 struct qed_dcbx_params
*p_params
)
546 u32 bw_map
[2], tsa_map
[2], pri_map
;
549 p_params
->ets_willing
= QED_MFW_GET_FIELD(p_ets
->flags
,
551 p_params
->ets_enabled
= QED_MFW_GET_FIELD(p_ets
->flags
,
553 p_params
->ets_cbs
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_CBS
);
554 p_params
->max_ets_tc
= QED_MFW_GET_FIELD(p_ets
->flags
,
556 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
557 "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
558 p_params
->ets_willing
,
560 p_ets
->pri_tc_tbl
[0], p_params
->max_ets_tc
);
562 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
563 * encoded in a type u32 array of size 2.
565 bw_map
[0] = be32_to_cpu(p_ets
->tc_bw_tbl
[0]);
566 bw_map
[1] = be32_to_cpu(p_ets
->tc_bw_tbl
[1]);
567 tsa_map
[0] = be32_to_cpu(p_ets
->tc_tsa_tbl
[0]);
568 tsa_map
[1] = be32_to_cpu(p_ets
->tc_tsa_tbl
[1]);
569 pri_map
= p_ets
->pri_tc_tbl
[0];
570 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
571 p_params
->ets_tc_bw_tbl
[i
] = ((u8
*)bw_map
)[i
];
572 p_params
->ets_tc_tsa_tbl
[i
] = ((u8
*)tsa_map
)[i
];
573 p_params
->ets_pri_tc_tbl
[i
] = QED_DCBX_PRIO2TC(pri_map
, i
);
574 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
575 "elem %d bw_tbl %x tsa_tbl %x\n",
576 i
, p_params
->ets_tc_bw_tbl
[i
],
577 p_params
->ets_tc_tsa_tbl
[i
]);
582 qed_dcbx_get_common_params(struct qed_hwfn
*p_hwfn
,
583 struct dcbx_app_priority_feature
*p_app
,
584 struct dcbx_app_priority_entry
*p_tbl
,
585 struct dcbx_ets_feature
*p_ets
,
586 u32 pfc
, struct qed_dcbx_params
*p_params
, bool ieee
)
588 qed_dcbx_get_app_data(p_hwfn
, p_app
, p_tbl
, p_params
, ieee
);
589 qed_dcbx_get_ets_data(p_hwfn
, p_ets
, p_params
);
590 qed_dcbx_get_pfc_data(p_hwfn
, pfc
, p_params
);
594 qed_dcbx_get_local_params(struct qed_hwfn
*p_hwfn
,
595 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
597 struct dcbx_features
*p_feat
;
599 p_feat
= &p_hwfn
->p_dcbx_info
->local_admin
.features
;
600 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
601 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
602 p_feat
->pfc
, ¶ms
->local
.params
, false);
603 params
->local
.valid
= true;
607 qed_dcbx_get_remote_params(struct qed_hwfn
*p_hwfn
,
608 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
610 struct dcbx_features
*p_feat
;
612 p_feat
= &p_hwfn
->p_dcbx_info
->remote
.features
;
613 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
614 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
615 p_feat
->pfc
, ¶ms
->remote
.params
, false);
616 params
->remote
.valid
= true;
620 qed_dcbx_get_operational_params(struct qed_hwfn
*p_hwfn
,
621 struct qed_ptt
*p_ptt
,
622 struct qed_dcbx_get
*params
)
624 struct qed_dcbx_operational_params
*p_operational
;
625 struct qed_dcbx_results
*p_results
;
626 struct dcbx_features
*p_feat
;
631 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
633 /* If DCBx version is non zero, then negotiation
634 * was successfuly performed
636 p_operational
= ¶ms
->operational
;
637 enabled
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) !=
638 DCBX_CONFIG_VERSION_DISABLED
);
640 p_operational
->enabled
= enabled
;
641 p_operational
->valid
= false;
645 p_feat
= &p_hwfn
->p_dcbx_info
->operational
.features
;
646 p_results
= &p_hwfn
->p_dcbx_info
->results
;
648 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
649 DCBX_CONFIG_VERSION_IEEE
);
650 p_operational
->ieee
= val
;
651 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
652 DCBX_CONFIG_VERSION_CEE
);
653 p_operational
->cee
= val
;
655 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Version support: ieee %d, cee %d\n",
656 p_operational
->ieee
, p_operational
->cee
);
658 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
659 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
660 p_feat
->pfc
, ¶ms
->operational
.params
,
661 p_operational
->ieee
);
662 qed_dcbx_get_priority_info(p_hwfn
, &p_operational
->app_prio
, p_results
);
663 err
= QED_MFW_GET_FIELD(p_feat
->app
.flags
, DCBX_APP_ERROR
);
664 p_operational
->err
= err
;
665 p_operational
->enabled
= enabled
;
666 p_operational
->valid
= true;
670 qed_dcbx_get_local_lldp_params(struct qed_hwfn
*p_hwfn
,
671 struct qed_ptt
*p_ptt
,
672 struct qed_dcbx_get
*params
)
674 struct lldp_config_params_s
*p_local
;
676 p_local
= &p_hwfn
->p_dcbx_info
->lldp_local
[LLDP_NEAREST_BRIDGE
];
678 memcpy(params
->lldp_local
.local_chassis_id
, p_local
->local_chassis_id
,
679 ARRAY_SIZE(p_local
->local_chassis_id
));
680 memcpy(params
->lldp_local
.local_port_id
, p_local
->local_port_id
,
681 ARRAY_SIZE(p_local
->local_port_id
));
685 qed_dcbx_get_remote_lldp_params(struct qed_hwfn
*p_hwfn
,
686 struct qed_ptt
*p_ptt
,
687 struct qed_dcbx_get
*params
)
689 struct lldp_status_params_s
*p_remote
;
691 p_remote
= &p_hwfn
->p_dcbx_info
->lldp_remote
[LLDP_NEAREST_BRIDGE
];
693 memcpy(params
->lldp_remote
.peer_chassis_id
, p_remote
->peer_chassis_id
,
694 ARRAY_SIZE(p_remote
->peer_chassis_id
));
695 memcpy(params
->lldp_remote
.peer_port_id
, p_remote
->peer_port_id
,
696 ARRAY_SIZE(p_remote
->peer_port_id
));
700 qed_dcbx_get_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
701 struct qed_dcbx_get
*p_params
,
702 enum qed_mib_read_type type
)
705 case QED_DCBX_REMOTE_MIB
:
706 qed_dcbx_get_remote_params(p_hwfn
, p_ptt
, p_params
);
708 case QED_DCBX_LOCAL_MIB
:
709 qed_dcbx_get_local_params(p_hwfn
, p_ptt
, p_params
);
711 case QED_DCBX_OPERATIONAL_MIB
:
712 qed_dcbx_get_operational_params(p_hwfn
, p_ptt
, p_params
);
714 case QED_DCBX_REMOTE_LLDP_MIB
:
715 qed_dcbx_get_remote_lldp_params(p_hwfn
, p_ptt
, p_params
);
717 case QED_DCBX_LOCAL_LLDP_MIB
:
718 qed_dcbx_get_local_lldp_params(p_hwfn
, p_ptt
, p_params
);
721 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
730 qed_dcbx_read_local_lldp_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
732 struct qed_dcbx_mib_meta_data data
;
735 memset(&data
, 0, sizeof(data
));
736 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
738 data
.lldp_local
= p_hwfn
->p_dcbx_info
->lldp_local
;
739 data
.size
= sizeof(struct lldp_config_params_s
);
740 qed_memcpy_from(p_hwfn
, p_ptt
, data
.lldp_local
, data
.addr
, data
.size
);
746 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn
*p_hwfn
,
747 struct qed_ptt
*p_ptt
,
748 enum qed_mib_read_type type
)
750 struct qed_dcbx_mib_meta_data data
;
753 memset(&data
, 0, sizeof(data
));
754 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
756 data
.lldp_remote
= p_hwfn
->p_dcbx_info
->lldp_remote
;
757 data
.size
= sizeof(struct lldp_status_params_s
);
758 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
764 qed_dcbx_read_operational_mib(struct qed_hwfn
*p_hwfn
,
765 struct qed_ptt
*p_ptt
,
766 enum qed_mib_read_type type
)
768 struct qed_dcbx_mib_meta_data data
;
771 memset(&data
, 0, sizeof(data
));
772 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
773 offsetof(struct public_port
, operational_dcbx_mib
);
774 data
.mib
= &p_hwfn
->p_dcbx_info
->operational
;
775 data
.size
= sizeof(struct dcbx_mib
);
776 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
782 qed_dcbx_read_remote_mib(struct qed_hwfn
*p_hwfn
,
783 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
785 struct qed_dcbx_mib_meta_data data
;
788 memset(&data
, 0, sizeof(data
));
789 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
790 offsetof(struct public_port
, remote_dcbx_mib
);
791 data
.mib
= &p_hwfn
->p_dcbx_info
->remote
;
792 data
.size
= sizeof(struct dcbx_mib
);
793 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
799 qed_dcbx_read_local_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
801 struct qed_dcbx_mib_meta_data data
;
804 memset(&data
, 0, sizeof(data
));
805 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
806 offsetof(struct public_port
, local_admin_dcbx_mib
);
807 data
.local_admin
= &p_hwfn
->p_dcbx_info
->local_admin
;
808 data
.size
= sizeof(struct dcbx_local_params
);
809 qed_memcpy_from(p_hwfn
, p_ptt
, data
.local_admin
, data
.addr
, data
.size
);
814 static int qed_dcbx_read_mib(struct qed_hwfn
*p_hwfn
,
815 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
820 case QED_DCBX_OPERATIONAL_MIB
:
821 rc
= qed_dcbx_read_operational_mib(p_hwfn
, p_ptt
, type
);
823 case QED_DCBX_REMOTE_MIB
:
824 rc
= qed_dcbx_read_remote_mib(p_hwfn
, p_ptt
, type
);
826 case QED_DCBX_LOCAL_MIB
:
827 rc
= qed_dcbx_read_local_mib(p_hwfn
, p_ptt
);
829 case QED_DCBX_REMOTE_LLDP_MIB
:
830 rc
= qed_dcbx_read_remote_lldp_mib(p_hwfn
, p_ptt
, type
);
832 case QED_DCBX_LOCAL_LLDP_MIB
:
833 rc
= qed_dcbx_read_local_lldp_mib(p_hwfn
, p_ptt
);
836 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
843 * Reconfigure QM and invoke PF update ramrod command if operational MIB
844 * change is detected.
847 qed_dcbx_mib_update_event(struct qed_hwfn
*p_hwfn
,
848 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
852 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
856 if (type
== QED_DCBX_OPERATIONAL_MIB
) {
857 rc
= qed_dcbx_process_mib_info(p_hwfn
);
859 /* reconfigure tcs of QM queues according
860 * to negotiation results
862 qed_qm_reconf(p_hwfn
, p_ptt
);
864 /* update storm FW with negotiation results */
865 qed_sp_pf_update(p_hwfn
);
872 int qed_dcbx_info_alloc(struct qed_hwfn
*p_hwfn
)
876 p_hwfn
->p_dcbx_info
= kzalloc(sizeof(*p_hwfn
->p_dcbx_info
), GFP_KERNEL
);
877 if (!p_hwfn
->p_dcbx_info
) {
879 "Failed to allocate 'struct qed_dcbx_info'\n");
886 void qed_dcbx_info_free(struct qed_hwfn
*p_hwfn
,
887 struct qed_dcbx_info
*p_dcbx_info
)
889 kfree(p_hwfn
->p_dcbx_info
);
892 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data
*p_data
,
893 struct qed_dcbx_results
*p_src
,
894 enum dcbx_protocol_type type
)
896 p_data
->dcb_enable_flag
= p_src
->arr
[type
].enable
;
897 p_data
->dcb_priority
= p_src
->arr
[type
].priority
;
898 p_data
->dcb_tc
= p_src
->arr
[type
].tc
;
901 /* Set pf update ramrod command params */
902 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results
*p_src
,
903 struct pf_update_ramrod_data
*p_dest
)
905 struct protocol_dcb_data
*p_dcb_data
;
906 bool update_flag
= false;
908 p_dest
->pf_id
= p_src
->pf_id
;
910 update_flag
= p_src
->arr
[DCBX_PROTOCOL_FCOE
].update
;
911 p_dest
->update_fcoe_dcb_data_flag
= update_flag
;
913 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
;
914 p_dest
->update_roce_dcb_data_flag
= update_flag
;
915 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
;
916 p_dest
->update_roce_dcb_data_flag
= update_flag
;
918 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ISCSI
].update
;
919 p_dest
->update_iscsi_dcb_data_flag
= update_flag
;
920 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ETH
].update
;
921 p_dest
->update_eth_dcb_data_flag
= update_flag
;
923 p_dcb_data
= &p_dest
->fcoe_dcb_data
;
924 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_FCOE
);
925 p_dcb_data
= &p_dest
->roce_dcb_data
;
927 if (p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
)
928 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
930 if (p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
)
931 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
932 DCBX_PROTOCOL_ROCE_V2
);
934 p_dcb_data
= &p_dest
->iscsi_dcb_data
;
935 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ISCSI
);
936 p_dcb_data
= &p_dest
->eth_dcb_data
;
937 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ETH
);
941 static int qed_dcbx_query_params(struct qed_hwfn
*p_hwfn
,
942 struct qed_dcbx_get
*p_get
,
943 enum qed_mib_read_type type
)
945 struct qed_ptt
*p_ptt
;
948 p_ptt
= qed_ptt_acquire(p_hwfn
);
952 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
956 rc
= qed_dcbx_get_params(p_hwfn
, p_ptt
, p_get
, type
);
959 qed_ptt_release(p_hwfn
, p_ptt
);
964 qed_dcbx_set_pfc_data(struct qed_hwfn
*p_hwfn
,
965 u32
*pfc
, struct qed_dcbx_params
*p_params
)
970 if (p_params
->pfc
.willing
)
971 *pfc
|= DCBX_PFC_WILLING_MASK
;
973 *pfc
&= ~DCBX_PFC_WILLING_MASK
;
975 if (p_params
->pfc
.enabled
)
976 *pfc
|= DCBX_PFC_ENABLED_MASK
;
978 *pfc
&= ~DCBX_PFC_ENABLED_MASK
;
980 *pfc
&= ~DCBX_PFC_CAPS_MASK
;
981 *pfc
|= (u32
)p_params
->pfc
.max_tc
<< DCBX_PFC_CAPS_SHIFT
;
983 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
984 if (p_params
->pfc
.prio
[i
])
987 *pfc
|= (pfc_map
<< DCBX_PFC_PRI_EN_BITMAP_SHIFT
);
989 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "pfc = 0x%x\n", *pfc
);
993 qed_dcbx_set_ets_data(struct qed_hwfn
*p_hwfn
,
994 struct dcbx_ets_feature
*p_ets
,
995 struct qed_dcbx_params
*p_params
)
997 u8
*bw_map
, *tsa_map
;
1001 if (p_params
->ets_willing
)
1002 p_ets
->flags
|= DCBX_ETS_WILLING_MASK
;
1004 p_ets
->flags
&= ~DCBX_ETS_WILLING_MASK
;
1006 if (p_params
->ets_cbs
)
1007 p_ets
->flags
|= DCBX_ETS_CBS_MASK
;
1009 p_ets
->flags
&= ~DCBX_ETS_CBS_MASK
;
1011 if (p_params
->ets_enabled
)
1012 p_ets
->flags
|= DCBX_ETS_ENABLED_MASK
;
1014 p_ets
->flags
&= ~DCBX_ETS_ENABLED_MASK
;
1016 p_ets
->flags
&= ~DCBX_ETS_MAX_TCS_MASK
;
1017 p_ets
->flags
|= (u32
)p_params
->max_ets_tc
<< DCBX_ETS_MAX_TCS_SHIFT
;
1019 bw_map
= (u8
*)&p_ets
->tc_bw_tbl
[0];
1020 tsa_map
= (u8
*)&p_ets
->tc_tsa_tbl
[0];
1021 p_ets
->pri_tc_tbl
[0] = 0;
1022 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1023 bw_map
[i
] = p_params
->ets_tc_bw_tbl
[i
];
1024 tsa_map
[i
] = p_params
->ets_tc_tsa_tbl
[i
];
1025 /* Copy the priority value to the corresponding 4 bits in the
1026 * traffic class table.
1028 val
= (((u32
)p_params
->ets_pri_tc_tbl
[i
]) << ((7 - i
) * 4));
1029 p_ets
->pri_tc_tbl
[0] |= val
;
1031 for (i
= 0; i
< 2; i
++) {
1032 p_ets
->tc_bw_tbl
[i
] = cpu_to_be32(p_ets
->tc_bw_tbl
[i
]);
1033 p_ets
->tc_tsa_tbl
[i
] = cpu_to_be32(p_ets
->tc_tsa_tbl
[i
]);
1038 qed_dcbx_set_app_data(struct qed_hwfn
*p_hwfn
,
1039 struct dcbx_app_priority_feature
*p_app
,
1040 struct qed_dcbx_params
*p_params
, bool ieee
)
1045 if (p_params
->app_willing
)
1046 p_app
->flags
|= DCBX_APP_WILLING_MASK
;
1048 p_app
->flags
&= ~DCBX_APP_WILLING_MASK
;
1050 if (p_params
->app_valid
)
1051 p_app
->flags
|= DCBX_APP_ENABLED_MASK
;
1053 p_app
->flags
&= ~DCBX_APP_ENABLED_MASK
;
1055 p_app
->flags
&= ~DCBX_APP_NUM_ENTRIES_MASK
;
1056 p_app
->flags
|= (u32
)p_params
->num_app_entries
<<
1057 DCBX_APP_NUM_ENTRIES_SHIFT
;
1059 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
1060 entry
= &p_app
->app_pri_tbl
[i
].entry
;
1062 *entry
&= ~DCBX_APP_SF_IEEE_MASK
;
1063 switch (p_params
->app_entry
[i
].sf_ieee
) {
1064 case QED_DCBX_SF_IEEE_ETHTYPE
:
1065 *entry
|= ((u32
)DCBX_APP_SF_IEEE_ETHTYPE
<<
1066 DCBX_APP_SF_IEEE_SHIFT
);
1068 case QED_DCBX_SF_IEEE_TCP_PORT
:
1069 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_PORT
<<
1070 DCBX_APP_SF_IEEE_SHIFT
);
1072 case QED_DCBX_SF_IEEE_UDP_PORT
:
1073 *entry
|= ((u32
)DCBX_APP_SF_IEEE_UDP_PORT
<<
1074 DCBX_APP_SF_IEEE_SHIFT
);
1076 case QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
1077 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_UDP_PORT
<<
1078 DCBX_APP_SF_IEEE_SHIFT
);
1082 *entry
&= ~DCBX_APP_SF_MASK
;
1083 if (p_params
->app_entry
[i
].ethtype
)
1084 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1087 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1091 *entry
&= ~DCBX_APP_PROTOCOL_ID_MASK
;
1092 *entry
|= ((u32
)p_params
->app_entry
[i
].proto_id
<<
1093 DCBX_APP_PROTOCOL_ID_SHIFT
);
1094 *entry
&= ~DCBX_APP_PRI_MAP_MASK
;
1095 *entry
|= ((u32
)(p_params
->app_entry
[i
].prio
) <<
1096 DCBX_APP_PRI_MAP_SHIFT
);
1101 qed_dcbx_set_local_params(struct qed_hwfn
*p_hwfn
,
1102 struct dcbx_local_params
*local_admin
,
1103 struct qed_dcbx_set
*params
)
1107 local_admin
->flags
= 0;
1108 memcpy(&local_admin
->features
,
1109 &p_hwfn
->p_dcbx_info
->operational
.features
,
1110 sizeof(local_admin
->features
));
1112 if (params
->enabled
) {
1113 local_admin
->config
= params
->ver_num
;
1114 ieee
= !!(params
->ver_num
& DCBX_CONFIG_VERSION_IEEE
);
1116 local_admin
->config
= DCBX_CONFIG_VERSION_DISABLED
;
1119 if (params
->override_flags
& QED_DCBX_OVERRIDE_PFC_CFG
)
1120 qed_dcbx_set_pfc_data(p_hwfn
, &local_admin
->features
.pfc
,
1121 ¶ms
->config
.params
);
1123 if (params
->override_flags
& QED_DCBX_OVERRIDE_ETS_CFG
)
1124 qed_dcbx_set_ets_data(p_hwfn
, &local_admin
->features
.ets
,
1125 ¶ms
->config
.params
);
1127 if (params
->override_flags
& QED_DCBX_OVERRIDE_APP_CFG
)
1128 qed_dcbx_set_app_data(p_hwfn
, &local_admin
->features
.app
,
1129 ¶ms
->config
.params
, ieee
);
1132 int qed_dcbx_config_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
1133 struct qed_dcbx_set
*params
, bool hw_commit
)
1135 struct dcbx_local_params local_admin
;
1136 struct qed_dcbx_mib_meta_data data
;
1137 u32 resp
= 0, param
= 0;
1141 memcpy(&p_hwfn
->p_dcbx_info
->set
, params
,
1142 sizeof(struct qed_dcbx_set
));
1146 /* clear set-parmas cache */
1147 memset(&p_hwfn
->p_dcbx_info
->set
, 0, sizeof(p_hwfn
->p_dcbx_info
->set
));
1149 memset(&local_admin
, 0, sizeof(local_admin
));
1150 qed_dcbx_set_local_params(p_hwfn
, &local_admin
, params
);
1152 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1153 offsetof(struct public_port
, local_admin_dcbx_mib
);
1154 data
.local_admin
= &local_admin
;
1155 data
.size
= sizeof(struct dcbx_local_params
);
1156 qed_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.local_admin
, data
.size
);
1158 rc
= qed_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_DCBX
,
1159 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT
, &resp
, ¶m
);
1161 DP_NOTICE(p_hwfn
, "Failed to send DCBX update request\n");
1166 int qed_dcbx_get_config_params(struct qed_hwfn
*p_hwfn
,
1167 struct qed_dcbx_set
*params
)
1169 struct qed_dcbx_get
*dcbx_info
;
1172 if (p_hwfn
->p_dcbx_info
->set
.config
.valid
) {
1173 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
,
1174 sizeof(struct qed_dcbx_set
));
1178 dcbx_info
= kmalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1180 DP_ERR(p_hwfn
, "Failed to allocate struct qed_dcbx_info\n");
1184 rc
= qed_dcbx_query_params(p_hwfn
, dcbx_info
, QED_DCBX_OPERATIONAL_MIB
);
1190 p_hwfn
->p_dcbx_info
->set
.override_flags
= 0;
1191 p_hwfn
->p_dcbx_info
->set
.ver_num
= DCBX_CONFIG_VERSION_DISABLED
;
1192 if (dcbx_info
->operational
.cee
)
1193 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1194 if (dcbx_info
->operational
.ieee
)
1195 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1197 p_hwfn
->p_dcbx_info
->set
.enabled
= dcbx_info
->operational
.enabled
;
1198 memcpy(&p_hwfn
->p_dcbx_info
->set
.config
.params
,
1199 &dcbx_info
->operational
.params
,
1200 sizeof(struct qed_dcbx_admin_params
));
1201 p_hwfn
->p_dcbx_info
->set
.config
.valid
= true;
1203 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
, sizeof(struct qed_dcbx_set
));
1210 static struct qed_dcbx_get
*qed_dcbnl_get_dcbx(struct qed_hwfn
*hwfn
,
1211 enum qed_mib_read_type type
)
1213 struct qed_dcbx_get
*dcbx_info
;
1215 dcbx_info
= kmalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1217 DP_ERR(hwfn
->cdev
, "Failed to allocate memory for dcbx_info\n");
1221 if (qed_dcbx_query_params(hwfn
, dcbx_info
, type
)) {
1226 if ((type
== QED_DCBX_OPERATIONAL_MIB
) &&
1227 !dcbx_info
->operational
.enabled
) {
1228 DP_INFO(hwfn
, "DCBX is not enabled/operational\n");
1236 static u8
qed_dcbnl_getstate(struct qed_dev
*cdev
)
1238 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1239 struct qed_dcbx_get
*dcbx_info
;
1242 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1246 enabled
= dcbx_info
->operational
.enabled
;
1247 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", enabled
);
1253 static u8
qed_dcbnl_setstate(struct qed_dev
*cdev
, u8 state
)
1255 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1256 struct qed_dcbx_set dcbx_set
;
1257 struct qed_ptt
*ptt
;
1260 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", state
);
1262 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1263 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1267 dcbx_set
.enabled
= !!state
;
1269 ptt
= qed_ptt_acquire(hwfn
);
1273 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1275 qed_ptt_release(hwfn
, ptt
);
1280 static void qed_dcbnl_getpgtccfgtx(struct qed_dev
*cdev
, int tc
, u8
*prio_type
,
1281 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1283 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1284 struct qed_dcbx_get
*dcbx_info
;
1286 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tc = %d\n", tc
);
1287 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1288 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1289 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1293 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1297 *pgid
= dcbx_info
->operational
.params
.ets_pri_tc_tbl
[tc
];
1301 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8
*bw_pct
)
1303 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1304 struct qed_dcbx_get
*dcbx_info
;
1307 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d\n", pgid
);
1308 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1309 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1313 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1317 *bw_pct
= dcbx_info
->operational
.params
.ets_tc_bw_tbl
[pgid
];
1318 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "bw_pct = %d\n", *bw_pct
);
1322 static void qed_dcbnl_getpgtccfgrx(struct qed_dev
*cdev
, int tc
, u8
*prio
,
1323 u8
*bwg_id
, u8
*bw_pct
, u8
*up_map
)
1325 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1326 *prio
= *bwg_id
= *bw_pct
= *up_map
= 0;
1329 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev
*cdev
,
1330 int bwg_id
, u8
*bw_pct
)
1332 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1336 static void qed_dcbnl_getpfccfg(struct qed_dev
*cdev
,
1337 int priority
, u8
*setting
)
1339 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1340 struct qed_dcbx_get
*dcbx_info
;
1342 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d\n", priority
);
1343 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1344 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1348 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1352 *setting
= dcbx_info
->operational
.params
.pfc
.prio
[priority
];
1353 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "setting = %d\n", *setting
);
1357 static void qed_dcbnl_setpfccfg(struct qed_dev
*cdev
, int priority
, u8 setting
)
1359 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1360 struct qed_dcbx_set dcbx_set
;
1361 struct qed_ptt
*ptt
;
1364 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d setting = %d\n",
1366 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1367 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1371 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1372 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1376 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1377 dcbx_set
.config
.params
.pfc
.prio
[priority
] = !!setting
;
1379 ptt
= qed_ptt_acquire(hwfn
);
1383 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1385 qed_ptt_release(hwfn
, ptt
);
1388 static u8
qed_dcbnl_getcap(struct qed_dev
*cdev
, int capid
, u8
*cap
)
1390 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1391 struct qed_dcbx_get
*dcbx_info
;
1394 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "capid = %d\n", capid
);
1395 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1400 case DCB_CAP_ATTR_PG
:
1401 case DCB_CAP_ATTR_PFC
:
1402 case DCB_CAP_ATTR_UP2TC
:
1403 case DCB_CAP_ATTR_GSP
:
1406 case DCB_CAP_ATTR_PG_TCS
:
1407 case DCB_CAP_ATTR_PFC_TCS
:
1410 case DCB_CAP_ATTR_DCBX
:
1411 *cap
= (DCB_CAP_DCBX_LLD_MANAGED
| DCB_CAP_DCBX_VER_CEE
|
1412 DCB_CAP_DCBX_VER_IEEE
);
1419 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "id = %d caps = %d\n", capid
, *cap
);
1425 static int qed_dcbnl_getnumtcs(struct qed_dev
*cdev
, int tcid
, u8
*num
)
1427 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1428 struct qed_dcbx_get
*dcbx_info
;
1431 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d\n", tcid
);
1432 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1437 case DCB_NUMTCS_ATTR_PG
:
1438 *num
= dcbx_info
->operational
.params
.max_ets_tc
;
1440 case DCB_NUMTCS_ATTR_PFC
:
1441 *num
= dcbx_info
->operational
.params
.pfc
.max_tc
;
1448 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "numtcs = %d\n", *num
);
1453 static u8
qed_dcbnl_getpfcstate(struct qed_dev
*cdev
)
1455 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1456 struct qed_dcbx_get
*dcbx_info
;
1459 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1463 enabled
= dcbx_info
->operational
.params
.pfc
.enabled
;
1464 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d\n", enabled
);
1470 static u8
qed_dcbnl_getdcbx(struct qed_dev
*cdev
)
1472 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1473 struct qed_dcbx_get
*dcbx_info
;
1476 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1480 if (dcbx_info
->operational
.enabled
)
1481 mode
|= DCB_CAP_DCBX_LLD_MANAGED
;
1482 if (dcbx_info
->operational
.ieee
)
1483 mode
|= DCB_CAP_DCBX_VER_IEEE
;
1484 if (dcbx_info
->operational
.cee
)
1485 mode
|= DCB_CAP_DCBX_VER_CEE
;
1487 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "dcb mode = %d\n", mode
);
1493 static void qed_dcbnl_setpgtccfgtx(struct qed_dev
*cdev
,
1495 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1497 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1498 struct qed_dcbx_set dcbx_set
;
1499 struct qed_ptt
*ptt
;
1502 DP_VERBOSE(hwfn
, QED_MSG_DCB
,
1503 "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n",
1504 tc
, pri_type
, pgid
, bw_pct
, up_map
);
1506 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1507 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1511 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1512 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1516 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1517 dcbx_set
.config
.params
.ets_pri_tc_tbl
[tc
] = pgid
;
1519 ptt
= qed_ptt_acquire(hwfn
);
1523 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1525 qed_ptt_release(hwfn
, ptt
);
1528 static void qed_dcbnl_setpgtccfgrx(struct qed_dev
*cdev
, int prio
,
1529 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1531 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1534 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1536 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1537 struct qed_dcbx_set dcbx_set
;
1538 struct qed_ptt
*ptt
;
1541 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d bw_pct = %d\n", pgid
, bw_pct
);
1542 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1543 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1547 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1548 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1552 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1553 dcbx_set
.config
.params
.ets_tc_bw_tbl
[pgid
] = bw_pct
;
1555 ptt
= qed_ptt_acquire(hwfn
);
1559 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1561 qed_ptt_release(hwfn
, ptt
);
1564 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1566 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1569 static u8
qed_dcbnl_setall(struct qed_dev
*cdev
)
1571 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1572 struct qed_dcbx_set dcbx_set
;
1573 struct qed_ptt
*ptt
;
1576 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1577 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1581 ptt
= qed_ptt_acquire(hwfn
);
1585 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 1);
1587 qed_ptt_release(hwfn
, ptt
);
1592 static int qed_dcbnl_setnumtcs(struct qed_dev
*cdev
, int tcid
, u8 num
)
1594 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1595 struct qed_dcbx_set dcbx_set
;
1596 struct qed_ptt
*ptt
;
1599 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d num = %d\n", tcid
, num
);
1600 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1601 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1606 case DCB_NUMTCS_ATTR_PG
:
1607 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1608 dcbx_set
.config
.params
.max_ets_tc
= num
;
1610 case DCB_NUMTCS_ATTR_PFC
:
1611 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1612 dcbx_set
.config
.params
.pfc
.max_tc
= num
;
1615 DP_INFO(hwfn
, "Invalid tcid %d\n", tcid
);
1619 ptt
= qed_ptt_acquire(hwfn
);
1623 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1625 qed_ptt_release(hwfn
, ptt
);
1630 static void qed_dcbnl_setpfcstate(struct qed_dev
*cdev
, u8 state
)
1632 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1633 struct qed_dcbx_set dcbx_set
;
1634 struct qed_ptt
*ptt
;
1637 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new state = %d\n", state
);
1639 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1640 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1644 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1645 dcbx_set
.config
.params
.pfc
.enabled
= !!state
;
1647 ptt
= qed_ptt_acquire(hwfn
);
1651 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1653 qed_ptt_release(hwfn
, ptt
);
1656 static int qed_dcbnl_getapp(struct qed_dev
*cdev
, u8 idtype
, u16 idval
)
1658 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1659 struct qed_dcbx_get
*dcbx_info
;
1660 struct qed_app_entry
*entry
;
1665 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1669 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1670 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1671 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
1672 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
)) {
1678 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1679 DP_ERR(cdev
, "App entry (%d, %d) not found\n", idtype
, idval
);
1689 static int qed_dcbnl_setapp(struct qed_dev
*cdev
,
1690 u8 idtype
, u16 idval
, u8 pri_map
)
1692 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1693 struct qed_dcbx_set dcbx_set
;
1694 struct qed_app_entry
*entry
;
1695 struct qed_ptt
*ptt
;
1699 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1700 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1704 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1705 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1706 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
1707 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
))
1709 /* First empty slot */
1710 if (!entry
->proto_id
) {
1711 dcbx_set
.config
.params
.num_app_entries
++;
1716 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1717 DP_ERR(cdev
, "App table is full\n");
1721 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1722 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
1723 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= idval
;
1724 dcbx_set
.config
.params
.app_entry
[i
].prio
= pri_map
;
1726 ptt
= qed_ptt_acquire(hwfn
);
1730 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1732 qed_ptt_release(hwfn
, ptt
);
1737 static u8
qed_dcbnl_setdcbx(struct qed_dev
*cdev
, u8 mode
)
1739 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1740 struct qed_dcbx_set dcbx_set
;
1741 struct qed_ptt
*ptt
;
1744 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new mode = %x\n", mode
);
1746 if (!(mode
& DCB_CAP_DCBX_VER_IEEE
) && !(mode
& DCB_CAP_DCBX_VER_CEE
)) {
1747 DP_INFO(hwfn
, "Allowed mode is cee, ieee or both\n");
1751 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1752 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1756 dcbx_set
.ver_num
= 0;
1757 if (mode
& DCB_CAP_DCBX_VER_CEE
) {
1758 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1759 dcbx_set
.enabled
= true;
1762 if (mode
& DCB_CAP_DCBX_VER_IEEE
) {
1763 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1764 dcbx_set
.enabled
= true;
1767 ptt
= qed_ptt_acquire(hwfn
);
1771 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1773 qed_ptt_release(hwfn
, ptt
);
1778 static u8
qed_dcbnl_getfeatcfg(struct qed_dev
*cdev
, int featid
, u8
*flags
)
1780 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1781 struct qed_dcbx_get
*dcbx_info
;
1783 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "Feature id = %d\n", featid
);
1784 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1790 case DCB_FEATCFG_ATTR_PG
:
1791 if (dcbx_info
->operational
.params
.ets_enabled
)
1792 *flags
= DCB_FEATCFG_ENABLE
;
1794 *flags
= DCB_FEATCFG_ERROR
;
1796 case DCB_FEATCFG_ATTR_PFC
:
1797 if (dcbx_info
->operational
.params
.pfc
.enabled
)
1798 *flags
= DCB_FEATCFG_ENABLE
;
1800 *flags
= DCB_FEATCFG_ERROR
;
1802 case DCB_FEATCFG_ATTR_APP
:
1803 if (dcbx_info
->operational
.params
.app_valid
)
1804 *flags
= DCB_FEATCFG_ENABLE
;
1806 *flags
= DCB_FEATCFG_ERROR
;
1809 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1814 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "flags = %d\n", *flags
);
1820 static u8
qed_dcbnl_setfeatcfg(struct qed_dev
*cdev
, int featid
, u8 flags
)
1822 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1823 struct qed_dcbx_set dcbx_set
;
1824 bool enabled
, willing
;
1825 struct qed_ptt
*ptt
;
1828 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "featid = %d flags = %d\n",
1830 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1831 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1835 enabled
= !!(flags
& DCB_FEATCFG_ENABLE
);
1836 willing
= !!(flags
& DCB_FEATCFG_WILLING
);
1838 case DCB_FEATCFG_ATTR_PG
:
1839 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1840 dcbx_set
.config
.params
.ets_enabled
= enabled
;
1841 dcbx_set
.config
.params
.ets_willing
= willing
;
1843 case DCB_FEATCFG_ATTR_PFC
:
1844 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1845 dcbx_set
.config
.params
.pfc
.enabled
= enabled
;
1846 dcbx_set
.config
.params
.pfc
.willing
= willing
;
1848 case DCB_FEATCFG_ATTR_APP
:
1849 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1850 dcbx_set
.config
.params
.app_willing
= willing
;
1853 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1857 ptt
= qed_ptt_acquire(hwfn
);
1861 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1863 qed_ptt_release(hwfn
, ptt
);
1868 static int qed_dcbnl_peer_getappinfo(struct qed_dev
*cdev
,
1869 struct dcb_peer_app_info
*info
,
1872 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1873 struct qed_dcbx_get
*dcbx_info
;
1875 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1879 info
->willing
= dcbx_info
->remote
.params
.app_willing
;
1880 info
->error
= dcbx_info
->remote
.params
.app_error
;
1881 *app_count
= dcbx_info
->remote
.params
.num_app_entries
;
1887 static int qed_dcbnl_peer_getapptable(struct qed_dev
*cdev
,
1888 struct dcb_app
*table
)
1890 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1891 struct qed_dcbx_get
*dcbx_info
;
1894 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1898 for (i
= 0; i
< dcbx_info
->remote
.params
.num_app_entries
; i
++) {
1899 if (dcbx_info
->remote
.params
.app_entry
[i
].ethtype
)
1900 table
[i
].selector
= DCB_APP_IDTYPE_ETHTYPE
;
1902 table
[i
].selector
= DCB_APP_IDTYPE_PORTNUM
;
1903 table
[i
].priority
= dcbx_info
->remote
.params
.app_entry
[i
].prio
;
1905 dcbx_info
->remote
.params
.app_entry
[i
].proto_id
;
1913 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev
*cdev
, struct cee_pfc
*pfc
)
1915 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1916 struct qed_dcbx_get
*dcbx_info
;
1919 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1923 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1924 if (dcbx_info
->remote
.params
.pfc
.prio
[i
])
1925 pfc
->pfc_en
|= BIT(i
);
1927 pfc
->tcs_supported
= dcbx_info
->remote
.params
.pfc
.max_tc
;
1928 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d tcs_supported = %d\n",
1929 pfc
->pfc_en
, pfc
->tcs_supported
);
1935 static int qed_dcbnl_cee_peer_getpg(struct qed_dev
*cdev
, struct cee_pg
*pg
)
1937 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1938 struct qed_dcbx_get
*dcbx_info
;
1941 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1945 pg
->willing
= dcbx_info
->remote
.params
.ets_willing
;
1946 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1947 pg
->pg_bw
[i
] = dcbx_info
->remote
.params
.ets_tc_bw_tbl
[i
];
1948 pg
->prio_pg
[i
] = dcbx_info
->remote
.params
.ets_pri_tc_tbl
[i
];
1951 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "willing = %d", pg
->willing
);
1957 static int qed_dcbnl_get_ieee_pfc(struct qed_dev
*cdev
,
1958 struct ieee_pfc
*pfc
, bool remote
)
1960 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1961 struct qed_dcbx_params
*params
;
1962 struct qed_dcbx_get
*dcbx_info
;
1965 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1969 if (!dcbx_info
->operational
.ieee
) {
1970 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1975 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1976 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
1977 QED_DCBX_REMOTE_MIB
);
1983 params
= &dcbx_info
->remote
.params
;
1985 params
= &dcbx_info
->operational
.params
;
1988 pfc
->pfc_cap
= params
->pfc
.max_tc
;
1990 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1991 if (params
->pfc
.prio
[i
])
1992 pfc
->pfc_en
|= BIT(i
);
1999 static int qed_dcbnl_ieee_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2001 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, false);
2004 static int qed_dcbnl_ieee_setpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2006 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2007 struct qed_dcbx_get
*dcbx_info
;
2008 struct qed_dcbx_set dcbx_set
;
2009 struct qed_ptt
*ptt
;
2012 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2016 if (!dcbx_info
->operational
.ieee
) {
2017 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2024 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2025 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2029 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
2030 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
2031 dcbx_set
.config
.params
.pfc
.prio
[i
] = !!(pfc
->pfc_en
& BIT(i
));
2033 ptt
= qed_ptt_acquire(hwfn
);
2037 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2039 qed_ptt_release(hwfn
, ptt
);
2044 static int qed_dcbnl_get_ieee_ets(struct qed_dev
*cdev
,
2045 struct ieee_ets
*ets
, bool remote
)
2047 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2048 struct qed_dcbx_get
*dcbx_info
;
2049 struct qed_dcbx_params
*params
;
2052 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2056 if (!dcbx_info
->operational
.ieee
) {
2057 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2063 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
2064 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
2065 QED_DCBX_REMOTE_MIB
);
2071 params
= &dcbx_info
->remote
.params
;
2073 params
= &dcbx_info
->operational
.params
;
2076 ets
->ets_cap
= params
->max_ets_tc
;
2077 ets
->willing
= params
->ets_willing
;
2078 ets
->cbs
= params
->ets_cbs
;
2079 memcpy(ets
->tc_tx_bw
, params
->ets_tc_bw_tbl
, sizeof(ets
->tc_tx_bw
));
2080 memcpy(ets
->tc_tsa
, params
->ets_tc_tsa_tbl
, sizeof(ets
->tc_tsa
));
2081 memcpy(ets
->prio_tc
, params
->ets_pri_tc_tbl
, sizeof(ets
->prio_tc
));
2087 static int qed_dcbnl_ieee_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2089 return qed_dcbnl_get_ieee_ets(cdev
, ets
, false);
2092 static int qed_dcbnl_ieee_setets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2094 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2095 struct qed_dcbx_get
*dcbx_info
;
2096 struct qed_dcbx_set dcbx_set
;
2097 struct qed_ptt
*ptt
;
2100 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2104 if (!dcbx_info
->operational
.ieee
) {
2105 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2112 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2113 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2117 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
2118 dcbx_set
.config
.params
.max_ets_tc
= ets
->ets_cap
;
2119 dcbx_set
.config
.params
.ets_willing
= ets
->willing
;
2120 dcbx_set
.config
.params
.ets_cbs
= ets
->cbs
;
2121 memcpy(dcbx_set
.config
.params
.ets_tc_bw_tbl
, ets
->tc_tx_bw
,
2122 sizeof(ets
->tc_tx_bw
));
2123 memcpy(dcbx_set
.config
.params
.ets_tc_tsa_tbl
, ets
->tc_tsa
,
2124 sizeof(ets
->tc_tsa
));
2125 memcpy(dcbx_set
.config
.params
.ets_pri_tc_tbl
, ets
->prio_tc
,
2126 sizeof(ets
->prio_tc
));
2128 ptt
= qed_ptt_acquire(hwfn
);
2132 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2134 qed_ptt_release(hwfn
, ptt
);
2139 int qed_dcbnl_ieee_peer_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2141 return qed_dcbnl_get_ieee_ets(cdev
, ets
, true);
2144 int qed_dcbnl_ieee_peer_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2146 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, true);
2149 int qed_dcbnl_ieee_getapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2151 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2152 struct qed_dcbx_get
*dcbx_info
;
2153 struct qed_app_entry
*entry
;
2158 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2162 if (!dcbx_info
->operational
.ieee
) {
2163 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2168 /* ieee defines the selector field value for ethertype to be 1 */
2169 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2170 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2171 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
2172 if ((entry
->ethtype
== ethtype
) &&
2173 (entry
->proto_id
== app
->protocol
)) {
2179 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2180 DP_ERR(cdev
, "App entry (%d, %d) not found\n", app
->selector
,
2186 app
->priority
= ffs(prio
) - 1;
2193 int qed_dcbnl_ieee_setapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2195 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2196 struct qed_dcbx_get
*dcbx_info
;
2197 struct qed_dcbx_set dcbx_set
;
2198 struct qed_app_entry
*entry
;
2199 struct qed_ptt
*ptt
;
2203 if (app
->priority
< 0 || app
->priority
>= QED_MAX_PFC_PRIORITIES
) {
2204 DP_INFO(hwfn
, "Invalid priority %d\n", app
->priority
);
2208 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2212 if (!dcbx_info
->operational
.ieee
) {
2213 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2220 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2221 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2225 /* ieee defines the selector field value for ethertype to be 1 */
2226 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2227 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2228 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
2229 if ((entry
->ethtype
== ethtype
) &&
2230 (entry
->proto_id
== app
->protocol
))
2232 /* First empty slot */
2233 if (!entry
->proto_id
) {
2234 dcbx_set
.config
.params
.num_app_entries
++;
2239 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2240 DP_ERR(cdev
, "App table is full\n");
2244 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
2245 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
2246 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= app
->protocol
;
2247 dcbx_set
.config
.params
.app_entry
[i
].prio
= BIT(app
->priority
);
2249 ptt
= qed_ptt_acquire(hwfn
);
2253 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2255 qed_ptt_release(hwfn
, ptt
);
2260 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass
= {
2261 .getstate
= qed_dcbnl_getstate
,
2262 .setstate
= qed_dcbnl_setstate
,
2263 .getpgtccfgtx
= qed_dcbnl_getpgtccfgtx
,
2264 .getpgbwgcfgtx
= qed_dcbnl_getpgbwgcfgtx
,
2265 .getpgtccfgrx
= qed_dcbnl_getpgtccfgrx
,
2266 .getpgbwgcfgrx
= qed_dcbnl_getpgbwgcfgrx
,
2267 .getpfccfg
= qed_dcbnl_getpfccfg
,
2268 .setpfccfg
= qed_dcbnl_setpfccfg
,
2269 .getcap
= qed_dcbnl_getcap
,
2270 .getnumtcs
= qed_dcbnl_getnumtcs
,
2271 .getpfcstate
= qed_dcbnl_getpfcstate
,
2272 .getdcbx
= qed_dcbnl_getdcbx
,
2273 .setpgtccfgtx
= qed_dcbnl_setpgtccfgtx
,
2274 .setpgtccfgrx
= qed_dcbnl_setpgtccfgrx
,
2275 .setpgbwgcfgtx
= qed_dcbnl_setpgbwgcfgtx
,
2276 .setpgbwgcfgrx
= qed_dcbnl_setpgbwgcfgrx
,
2277 .setall
= qed_dcbnl_setall
,
2278 .setnumtcs
= qed_dcbnl_setnumtcs
,
2279 .setpfcstate
= qed_dcbnl_setpfcstate
,
2280 .setapp
= qed_dcbnl_setapp
,
2281 .setdcbx
= qed_dcbnl_setdcbx
,
2282 .setfeatcfg
= qed_dcbnl_setfeatcfg
,
2283 .getfeatcfg
= qed_dcbnl_getfeatcfg
,
2284 .getapp
= qed_dcbnl_getapp
,
2285 .peer_getappinfo
= qed_dcbnl_peer_getappinfo
,
2286 .peer_getapptable
= qed_dcbnl_peer_getapptable
,
2287 .cee_peer_getpfc
= qed_dcbnl_cee_peer_getpfc
,
2288 .cee_peer_getpg
= qed_dcbnl_cee_peer_getpg
,
2289 .ieee_getpfc
= qed_dcbnl_ieee_getpfc
,
2290 .ieee_setpfc
= qed_dcbnl_ieee_setpfc
,
2291 .ieee_getets
= qed_dcbnl_ieee_getets
,
2292 .ieee_setets
= qed_dcbnl_ieee_setets
,
2293 .ieee_peer_getpfc
= qed_dcbnl_ieee_peer_getpfc
,
2294 .ieee_peer_getets
= qed_dcbnl_ieee_peer_getets
,
2295 .ieee_getapp
= qed_dcbnl_ieee_getapp
,
2296 .ieee_setapp
= qed_dcbnl_ieee_setapp
,