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>
22 #include "qed_sriov.h"
24 #include <linux/qed/qed_eth_if.h>
27 #define QED_DCBX_MAX_MIB_READ_TRY (100)
28 #define QED_ETH_TYPE_DEFAULT (0)
29 #define QED_ETH_TYPE_ROCE (0x8915)
30 #define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7)
31 #define QED_ETH_TYPE_FCOE (0x8906)
32 #define QED_TCP_PORT_ISCSI (0xCBC)
34 #define QED_DCBX_INVALID_PRIORITY 0xFF
36 /* Get Traffic Class from priority traffic class table, 4 bits represent
37 * the traffic class corresponding to the priority.
39 #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \
40 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
42 static const struct qed_dcbx_app_metadata qed_dcbx_app_update
[] = {
43 {DCBX_PROTOCOL_ISCSI
, "ISCSI", QED_PCI_DEFAULT
},
44 {DCBX_PROTOCOL_FCOE
, "FCOE", QED_PCI_DEFAULT
},
45 {DCBX_PROTOCOL_ROCE
, "ROCE", QED_PCI_DEFAULT
},
46 {DCBX_PROTOCOL_ROCE_V2
, "ROCE_V2", QED_PCI_DEFAULT
},
47 {DCBX_PROTOCOL_ETH
, "ETH", QED_PCI_ETH
}
50 static bool qed_dcbx_app_ethtype(u32 app_info_bitmap
)
52 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
56 static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap
)
58 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
61 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
62 return qed_dcbx_app_ethtype(app_info_bitmap
);
64 return !!(mfw_val
== DCBX_APP_SF_IEEE_ETHTYPE
);
67 static bool qed_dcbx_app_port(u32 app_info_bitmap
)
69 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
73 static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap
, u8 type
)
75 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
78 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
79 return qed_dcbx_app_port(app_info_bitmap
);
81 return !!(mfw_val
== type
|| mfw_val
== DCBX_APP_SF_IEEE_TCP_UDP_PORT
);
84 static bool qed_dcbx_default_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
89 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
91 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
93 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_DEFAULT
));
96 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
101 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
102 DCBX_APP_SF_IEEE_TCP_PORT
);
104 port
= qed_dcbx_app_port(app_info_bitmap
);
106 return !!(port
&& (proto_id
== QED_TCP_PORT_ISCSI
));
109 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
114 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
116 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
118 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_FCOE
));
121 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
126 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
128 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
130 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_ROCE
));
133 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
138 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
139 DCBX_APP_SF_IEEE_UDP_PORT
);
141 port
= qed_dcbx_app_port(app_info_bitmap
);
143 return !!(port
&& (proto_id
== QED_UDP_PORT_TYPE_ROCE_V2
));
147 qed_dcbx_dp_protocol(struct qed_hwfn
*p_hwfn
, struct qed_dcbx_results
*p_data
)
149 enum dcbx_protocol_type id
;
152 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "DCBX negotiated: %d\n",
153 p_data
->dcbx_enabled
);
155 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
156 id
= qed_dcbx_app_update
[i
].id
;
158 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
159 "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
160 qed_dcbx_app_update
[i
].name
, p_data
->arr
[id
].update
,
161 p_data
->arr
[id
].enable
, p_data
->arr
[id
].priority
,
162 p_data
->arr
[id
].tc
, p_hwfn
->hw_info
.num_tc
);
167 qed_dcbx_set_params(struct qed_dcbx_results
*p_data
,
168 struct qed_hw_info
*p_info
,
173 enum dcbx_protocol_type type
,
174 enum qed_pci_personality personality
)
176 /* PF update ramrod data */
177 p_data
->arr
[type
].update
= update
;
178 p_data
->arr
[type
].enable
= enable
;
179 p_data
->arr
[type
].priority
= prio
;
180 p_data
->arr
[type
].tc
= tc
;
183 if (p_info
->personality
== personality
) {
184 if (personality
== QED_PCI_ETH
)
185 p_info
->non_offload_tc
= tc
;
187 p_info
->offload_tc
= tc
;
191 /* Update app protocol data and hw_info fields with the TLV info */
193 qed_dcbx_update_app_info(struct qed_dcbx_results
*p_data
,
194 struct qed_hwfn
*p_hwfn
,
197 u8 prio
, u8 tc
, enum dcbx_protocol_type type
)
199 struct qed_hw_info
*p_info
= &p_hwfn
->hw_info
;
200 enum qed_pci_personality personality
;
201 enum dcbx_protocol_type id
;
205 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
206 id
= qed_dcbx_app_update
[i
].id
;
211 personality
= qed_dcbx_app_update
[i
].personality
;
212 name
= qed_dcbx_app_update
[i
].name
;
214 qed_dcbx_set_params(p_data
, p_info
, enable
, update
,
215 prio
, tc
, type
, personality
);
220 qed_dcbx_get_app_protocol_type(struct qed_hwfn
*p_hwfn
,
222 u16 id
, enum dcbx_protocol_type
*type
, bool ieee
)
224 if (qed_dcbx_fcoe_tlv(app_prio_bitmap
, id
, ieee
)) {
225 *type
= DCBX_PROTOCOL_FCOE
;
226 } else if (qed_dcbx_roce_tlv(app_prio_bitmap
, id
, ieee
)) {
227 *type
= DCBX_PROTOCOL_ROCE
;
228 } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap
, id
, ieee
)) {
229 *type
= DCBX_PROTOCOL_ISCSI
;
230 } else if (qed_dcbx_default_tlv(app_prio_bitmap
, id
, ieee
)) {
231 *type
= DCBX_PROTOCOL_ETH
;
232 } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap
, id
, ieee
)) {
233 *type
= DCBX_PROTOCOL_ROCE_V2
;
235 *type
= DCBX_MAX_PROTOCOL_TYPE
;
237 "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
238 id
, app_prio_bitmap
);
245 /* Parse app TLV's to update TC information in hw_info structure for
246 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
249 qed_dcbx_process_tlv(struct qed_hwfn
*p_hwfn
,
250 struct qed_dcbx_results
*p_data
,
251 struct dcbx_app_priority_entry
*p_tbl
,
252 u32 pri_tc_tbl
, int count
, u8 dcbx_version
)
255 enum dcbx_protocol_type type
;
261 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Num APP entries = %d\n", count
);
263 ieee
= (dcbx_version
== DCBX_CONFIG_VERSION_IEEE
);
265 for (i
= 0; i
< count
; i
++) {
266 protocol_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
267 DCBX_APP_PROTOCOL_ID
);
268 priority_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
270 priority
= ffs(priority_map
) - 1;
272 DP_ERR(p_hwfn
, "Invalid priority\n");
276 tc
= QED_DCBX_PRIO2TC(pri_tc_tbl
, priority
);
277 if (qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
278 protocol_id
, &type
, ieee
)) {
279 /* ETH always have the enable bit reset, as it gets
280 * vlan information per packet. For other protocols,
281 * should be set according to the dcbx_enabled
282 * indication, but we only got here if there was an
283 * app tlv for the protocol, so dcbx must be enabled.
285 enable
= !(type
== DCBX_PROTOCOL_ETH
);
287 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
292 /* If RoCE-V2 TLV is not detected, driver need to use RoCE app
293 * data for RoCE-v2 not the default app data.
295 if (!p_data
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
296 p_data
->arr
[DCBX_PROTOCOL_ROCE
].update
) {
297 tc
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].tc
;
298 priority
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
299 qed_dcbx_update_app_info(p_data
, p_hwfn
, true, true,
300 priority
, tc
, DCBX_PROTOCOL_ROCE_V2
);
303 /* Update ramrod protocol data and hw_info fields
304 * with default info when corresponding APP TLV's are not detected.
305 * The enabled field has a different logic for ethernet as only for
306 * ethernet dcb should disabled by default, as the information arrives
307 * from the OS (unless an explicit app tlv was present).
309 tc
= p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
;
310 priority
= p_data
->arr
[DCBX_PROTOCOL_ETH
].priority
;
311 for (type
= 0; type
< DCBX_MAX_PROTOCOL_TYPE
; type
++) {
312 if (p_data
->arr
[type
].update
)
315 enable
= !(type
== DCBX_PROTOCOL_ETH
);
316 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
323 /* Parse app TLV's to update TC information in hw_info structure for
324 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
326 static int qed_dcbx_process_mib_info(struct qed_hwfn
*p_hwfn
)
328 struct dcbx_app_priority_feature
*p_app
;
329 struct dcbx_app_priority_entry
*p_tbl
;
330 struct qed_dcbx_results data
= { 0 };
331 struct dcbx_ets_feature
*p_ets
;
332 struct qed_hw_info
*p_info
;
333 u32 pri_tc_tbl
, flags
;
338 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
339 dcbx_version
= QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
);
341 p_app
= &p_hwfn
->p_dcbx_info
->operational
.features
.app
;
342 p_tbl
= p_app
->app_pri_tbl
;
344 p_ets
= &p_hwfn
->p_dcbx_info
->operational
.features
.ets
;
345 pri_tc_tbl
= p_ets
->pri_tc_tbl
[0];
347 p_info
= &p_hwfn
->hw_info
;
348 num_entries
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_NUM_ENTRIES
);
350 rc
= qed_dcbx_process_tlv(p_hwfn
, &data
, p_tbl
, pri_tc_tbl
,
351 num_entries
, dcbx_version
);
355 p_info
->num_tc
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
356 data
.pf_id
= p_hwfn
->rel_pf_id
;
357 data
.dcbx_enabled
= !!dcbx_version
;
359 qed_dcbx_dp_protocol(p_hwfn
, &data
);
361 memcpy(&p_hwfn
->p_dcbx_info
->results
, &data
,
362 sizeof(struct qed_dcbx_results
));
368 qed_dcbx_copy_mib(struct qed_hwfn
*p_hwfn
,
369 struct qed_ptt
*p_ptt
,
370 struct qed_dcbx_mib_meta_data
*p_data
,
371 enum qed_mib_read_type type
)
373 u32 prefix_seq_num
, suffix_seq_num
;
377 /* The data is considered to be valid only if both sequence numbers are
381 if (type
== QED_DCBX_REMOTE_LLDP_MIB
) {
382 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_remote
,
383 p_data
->addr
, p_data
->size
);
384 prefix_seq_num
= p_data
->lldp_remote
->prefix_seq_num
;
385 suffix_seq_num
= p_data
->lldp_remote
->suffix_seq_num
;
387 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->mib
,
388 p_data
->addr
, p_data
->size
);
389 prefix_seq_num
= p_data
->mib
->prefix_seq_num
;
390 suffix_seq_num
= p_data
->mib
->suffix_seq_num
;
396 "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
397 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
398 } while ((prefix_seq_num
!= suffix_seq_num
) &&
399 (read_count
< QED_DCBX_MAX_MIB_READ_TRY
));
401 if (read_count
>= QED_DCBX_MAX_MIB_READ_TRY
) {
403 "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
404 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
413 qed_dcbx_get_priority_info(struct qed_hwfn
*p_hwfn
,
414 struct qed_dcbx_app_prio
*p_prio
,
415 struct qed_dcbx_results
*p_results
)
419 p_prio
->roce
= QED_DCBX_INVALID_PRIORITY
;
420 p_prio
->roce_v2
= QED_DCBX_INVALID_PRIORITY
;
421 p_prio
->iscsi
= QED_DCBX_INVALID_PRIORITY
;
422 p_prio
->fcoe
= QED_DCBX_INVALID_PRIORITY
;
424 if (p_results
->arr
[DCBX_PROTOCOL_ROCE
].update
&&
425 p_results
->arr
[DCBX_PROTOCOL_ROCE
].enable
)
426 p_prio
->roce
= p_results
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
428 if (p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
429 p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].enable
) {
430 val
= p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].priority
;
431 p_prio
->roce_v2
= val
;
434 if (p_results
->arr
[DCBX_PROTOCOL_ISCSI
].update
&&
435 p_results
->arr
[DCBX_PROTOCOL_ISCSI
].enable
)
436 p_prio
->iscsi
= p_results
->arr
[DCBX_PROTOCOL_ISCSI
].priority
;
438 if (p_results
->arr
[DCBX_PROTOCOL_FCOE
].update
&&
439 p_results
->arr
[DCBX_PROTOCOL_FCOE
].enable
)
440 p_prio
->fcoe
= p_results
->arr
[DCBX_PROTOCOL_FCOE
].priority
;
442 if (p_results
->arr
[DCBX_PROTOCOL_ETH
].update
&&
443 p_results
->arr
[DCBX_PROTOCOL_ETH
].enable
)
444 p_prio
->eth
= p_results
->arr
[DCBX_PROTOCOL_ETH
].priority
;
446 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
447 "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
448 p_prio
->iscsi
, p_prio
->roce
, p_prio
->roce_v2
, p_prio
->fcoe
,
453 qed_dcbx_get_app_data(struct qed_hwfn
*p_hwfn
,
454 struct dcbx_app_priority_feature
*p_app
,
455 struct dcbx_app_priority_entry
*p_tbl
,
456 struct qed_dcbx_params
*p_params
, bool ieee
)
458 struct qed_app_entry
*entry
;
462 p_params
->app_willing
= QED_MFW_GET_FIELD(p_app
->flags
,
464 p_params
->app_valid
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ENABLED
);
465 p_params
->app_error
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ERROR
);
466 p_params
->num_app_entries
= QED_MFW_GET_FIELD(p_app
->flags
,
467 DCBX_APP_NUM_ENTRIES
);
468 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
469 entry
= &p_params
->app_entry
[i
];
474 sf_ieee
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
477 case DCBX_APP_SF_IEEE_RESERVED
:
479 val
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
481 entry
->sf_ieee
= val
?
482 QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
483 QED_DCBX_SF_IEEE_ETHTYPE
;
485 case DCBX_APP_SF_IEEE_ETHTYPE
:
486 entry
->sf_ieee
= QED_DCBX_SF_IEEE_ETHTYPE
;
488 case DCBX_APP_SF_IEEE_TCP_PORT
:
489 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_PORT
;
491 case DCBX_APP_SF_IEEE_UDP_PORT
:
492 entry
->sf_ieee
= QED_DCBX_SF_IEEE_UDP_PORT
;
494 case DCBX_APP_SF_IEEE_TCP_UDP_PORT
:
495 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_UDP_PORT
;
499 entry
->ethtype
= !(QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
503 pri_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
504 entry
->prio
= ffs(pri_map
) - 1;
505 entry
->proto_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
506 DCBX_APP_PROTOCOL_ID
);
507 qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
509 &entry
->proto_type
, ieee
);
512 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
513 "APP params: willing %d, valid %d error = %d\n",
514 p_params
->app_willing
, p_params
->app_valid
,
515 p_params
->app_error
);
519 qed_dcbx_get_pfc_data(struct qed_hwfn
*p_hwfn
,
520 u32 pfc
, struct qed_dcbx_params
*p_params
)
524 p_params
->pfc
.willing
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_WILLING
);
525 p_params
->pfc
.max_tc
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_CAPS
);
526 p_params
->pfc
.enabled
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_ENABLED
);
527 pfc_map
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_PRI_EN_BITMAP
);
528 p_params
->pfc
.prio
[0] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_0
);
529 p_params
->pfc
.prio
[1] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_1
);
530 p_params
->pfc
.prio
[2] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_2
);
531 p_params
->pfc
.prio
[3] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_3
);
532 p_params
->pfc
.prio
[4] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_4
);
533 p_params
->pfc
.prio
[5] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_5
);
534 p_params
->pfc
.prio
[6] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_6
);
535 p_params
->pfc
.prio
[7] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_7
);
537 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
538 "PFC params: willing %d, pfc_bitmap %d\n",
539 p_params
->pfc
.willing
, pfc_map
);
543 qed_dcbx_get_ets_data(struct qed_hwfn
*p_hwfn
,
544 struct dcbx_ets_feature
*p_ets
,
545 struct qed_dcbx_params
*p_params
)
547 u32 bw_map
[2], tsa_map
[2], pri_map
;
550 p_params
->ets_willing
= QED_MFW_GET_FIELD(p_ets
->flags
,
552 p_params
->ets_enabled
= QED_MFW_GET_FIELD(p_ets
->flags
,
554 p_params
->ets_cbs
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_CBS
);
555 p_params
->max_ets_tc
= QED_MFW_GET_FIELD(p_ets
->flags
,
557 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
558 "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
559 p_params
->ets_willing
,
561 p_ets
->pri_tc_tbl
[0], p_params
->max_ets_tc
);
563 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
564 * encoded in a type u32 array of size 2.
566 bw_map
[0] = be32_to_cpu(p_ets
->tc_bw_tbl
[0]);
567 bw_map
[1] = be32_to_cpu(p_ets
->tc_bw_tbl
[1]);
568 tsa_map
[0] = be32_to_cpu(p_ets
->tc_tsa_tbl
[0]);
569 tsa_map
[1] = be32_to_cpu(p_ets
->tc_tsa_tbl
[1]);
570 pri_map
= p_ets
->pri_tc_tbl
[0];
571 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
572 p_params
->ets_tc_bw_tbl
[i
] = ((u8
*)bw_map
)[i
];
573 p_params
->ets_tc_tsa_tbl
[i
] = ((u8
*)tsa_map
)[i
];
574 p_params
->ets_pri_tc_tbl
[i
] = QED_DCBX_PRIO2TC(pri_map
, i
);
575 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
576 "elem %d bw_tbl %x tsa_tbl %x\n",
577 i
, p_params
->ets_tc_bw_tbl
[i
],
578 p_params
->ets_tc_tsa_tbl
[i
]);
583 qed_dcbx_get_common_params(struct qed_hwfn
*p_hwfn
,
584 struct dcbx_app_priority_feature
*p_app
,
585 struct dcbx_app_priority_entry
*p_tbl
,
586 struct dcbx_ets_feature
*p_ets
,
587 u32 pfc
, struct qed_dcbx_params
*p_params
, bool ieee
)
589 qed_dcbx_get_app_data(p_hwfn
, p_app
, p_tbl
, p_params
, ieee
);
590 qed_dcbx_get_ets_data(p_hwfn
, p_ets
, p_params
);
591 qed_dcbx_get_pfc_data(p_hwfn
, pfc
, p_params
);
595 qed_dcbx_get_local_params(struct qed_hwfn
*p_hwfn
,
596 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
598 struct dcbx_features
*p_feat
;
600 p_feat
= &p_hwfn
->p_dcbx_info
->local_admin
.features
;
601 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
602 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
603 p_feat
->pfc
, ¶ms
->local
.params
, false);
604 params
->local
.valid
= true;
608 qed_dcbx_get_remote_params(struct qed_hwfn
*p_hwfn
,
609 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
611 struct dcbx_features
*p_feat
;
613 p_feat
= &p_hwfn
->p_dcbx_info
->remote
.features
;
614 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
615 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
616 p_feat
->pfc
, ¶ms
->remote
.params
, false);
617 params
->remote
.valid
= true;
621 qed_dcbx_get_operational_params(struct qed_hwfn
*p_hwfn
,
622 struct qed_ptt
*p_ptt
,
623 struct qed_dcbx_get
*params
)
625 struct qed_dcbx_operational_params
*p_operational
;
626 struct qed_dcbx_results
*p_results
;
627 struct dcbx_features
*p_feat
;
632 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
634 /* If DCBx version is non zero, then negotiation
635 * was successfuly performed
637 p_operational
= ¶ms
->operational
;
638 enabled
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) !=
639 DCBX_CONFIG_VERSION_DISABLED
);
641 p_operational
->enabled
= enabled
;
642 p_operational
->valid
= false;
646 p_feat
= &p_hwfn
->p_dcbx_info
->operational
.features
;
647 p_results
= &p_hwfn
->p_dcbx_info
->results
;
649 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
650 DCBX_CONFIG_VERSION_IEEE
);
651 p_operational
->ieee
= val
;
652 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
653 DCBX_CONFIG_VERSION_CEE
);
654 p_operational
->cee
= val
;
656 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Version support: ieee %d, cee %d\n",
657 p_operational
->ieee
, p_operational
->cee
);
659 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
660 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
661 p_feat
->pfc
, ¶ms
->operational
.params
,
662 p_operational
->ieee
);
663 qed_dcbx_get_priority_info(p_hwfn
, &p_operational
->app_prio
, p_results
);
664 err
= QED_MFW_GET_FIELD(p_feat
->app
.flags
, DCBX_APP_ERROR
);
665 p_operational
->err
= err
;
666 p_operational
->enabled
= enabled
;
667 p_operational
->valid
= true;
671 qed_dcbx_get_local_lldp_params(struct qed_hwfn
*p_hwfn
,
672 struct qed_ptt
*p_ptt
,
673 struct qed_dcbx_get
*params
)
675 struct lldp_config_params_s
*p_local
;
677 p_local
= &p_hwfn
->p_dcbx_info
->lldp_local
[LLDP_NEAREST_BRIDGE
];
679 memcpy(params
->lldp_local
.local_chassis_id
, p_local
->local_chassis_id
,
680 ARRAY_SIZE(p_local
->local_chassis_id
));
681 memcpy(params
->lldp_local
.local_port_id
, p_local
->local_port_id
,
682 ARRAY_SIZE(p_local
->local_port_id
));
686 qed_dcbx_get_remote_lldp_params(struct qed_hwfn
*p_hwfn
,
687 struct qed_ptt
*p_ptt
,
688 struct qed_dcbx_get
*params
)
690 struct lldp_status_params_s
*p_remote
;
692 p_remote
= &p_hwfn
->p_dcbx_info
->lldp_remote
[LLDP_NEAREST_BRIDGE
];
694 memcpy(params
->lldp_remote
.peer_chassis_id
, p_remote
->peer_chassis_id
,
695 ARRAY_SIZE(p_remote
->peer_chassis_id
));
696 memcpy(params
->lldp_remote
.peer_port_id
, p_remote
->peer_port_id
,
697 ARRAY_SIZE(p_remote
->peer_port_id
));
701 qed_dcbx_get_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
702 struct qed_dcbx_get
*p_params
,
703 enum qed_mib_read_type type
)
706 case QED_DCBX_REMOTE_MIB
:
707 qed_dcbx_get_remote_params(p_hwfn
, p_ptt
, p_params
);
709 case QED_DCBX_LOCAL_MIB
:
710 qed_dcbx_get_local_params(p_hwfn
, p_ptt
, p_params
);
712 case QED_DCBX_OPERATIONAL_MIB
:
713 qed_dcbx_get_operational_params(p_hwfn
, p_ptt
, p_params
);
715 case QED_DCBX_REMOTE_LLDP_MIB
:
716 qed_dcbx_get_remote_lldp_params(p_hwfn
, p_ptt
, p_params
);
718 case QED_DCBX_LOCAL_LLDP_MIB
:
719 qed_dcbx_get_local_lldp_params(p_hwfn
, p_ptt
, p_params
);
722 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
731 qed_dcbx_read_local_lldp_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
733 struct qed_dcbx_mib_meta_data data
;
736 memset(&data
, 0, sizeof(data
));
737 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
739 data
.lldp_local
= p_hwfn
->p_dcbx_info
->lldp_local
;
740 data
.size
= sizeof(struct lldp_config_params_s
);
741 qed_memcpy_from(p_hwfn
, p_ptt
, data
.lldp_local
, data
.addr
, data
.size
);
747 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn
*p_hwfn
,
748 struct qed_ptt
*p_ptt
,
749 enum qed_mib_read_type type
)
751 struct qed_dcbx_mib_meta_data data
;
754 memset(&data
, 0, sizeof(data
));
755 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
757 data
.lldp_remote
= p_hwfn
->p_dcbx_info
->lldp_remote
;
758 data
.size
= sizeof(struct lldp_status_params_s
);
759 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
765 qed_dcbx_read_operational_mib(struct qed_hwfn
*p_hwfn
,
766 struct qed_ptt
*p_ptt
,
767 enum qed_mib_read_type type
)
769 struct qed_dcbx_mib_meta_data data
;
772 memset(&data
, 0, sizeof(data
));
773 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
774 offsetof(struct public_port
, operational_dcbx_mib
);
775 data
.mib
= &p_hwfn
->p_dcbx_info
->operational
;
776 data
.size
= sizeof(struct dcbx_mib
);
777 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
783 qed_dcbx_read_remote_mib(struct qed_hwfn
*p_hwfn
,
784 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
786 struct qed_dcbx_mib_meta_data data
;
789 memset(&data
, 0, sizeof(data
));
790 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
791 offsetof(struct public_port
, remote_dcbx_mib
);
792 data
.mib
= &p_hwfn
->p_dcbx_info
->remote
;
793 data
.size
= sizeof(struct dcbx_mib
);
794 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
800 qed_dcbx_read_local_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
802 struct qed_dcbx_mib_meta_data data
;
805 memset(&data
, 0, sizeof(data
));
806 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
807 offsetof(struct public_port
, local_admin_dcbx_mib
);
808 data
.local_admin
= &p_hwfn
->p_dcbx_info
->local_admin
;
809 data
.size
= sizeof(struct dcbx_local_params
);
810 qed_memcpy_from(p_hwfn
, p_ptt
, data
.local_admin
, data
.addr
, data
.size
);
815 static int qed_dcbx_read_mib(struct qed_hwfn
*p_hwfn
,
816 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
821 case QED_DCBX_OPERATIONAL_MIB
:
822 rc
= qed_dcbx_read_operational_mib(p_hwfn
, p_ptt
, type
);
824 case QED_DCBX_REMOTE_MIB
:
825 rc
= qed_dcbx_read_remote_mib(p_hwfn
, p_ptt
, type
);
827 case QED_DCBX_LOCAL_MIB
:
828 rc
= qed_dcbx_read_local_mib(p_hwfn
, p_ptt
);
830 case QED_DCBX_REMOTE_LLDP_MIB
:
831 rc
= qed_dcbx_read_remote_lldp_mib(p_hwfn
, p_ptt
, type
);
833 case QED_DCBX_LOCAL_LLDP_MIB
:
834 rc
= qed_dcbx_read_local_lldp_mib(p_hwfn
, p_ptt
);
837 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
844 * Reconfigure QM and invoke PF update ramrod command if operational MIB
845 * change is detected.
848 qed_dcbx_mib_update_event(struct qed_hwfn
*p_hwfn
,
849 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
853 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
857 if (type
== QED_DCBX_OPERATIONAL_MIB
) {
858 rc
= qed_dcbx_process_mib_info(p_hwfn
);
860 /* reconfigure tcs of QM queues according
861 * to negotiation results
863 qed_qm_reconf(p_hwfn
, p_ptt
);
865 /* update storm FW with negotiation results */
866 qed_sp_pf_update(p_hwfn
);
873 int qed_dcbx_info_alloc(struct qed_hwfn
*p_hwfn
)
877 p_hwfn
->p_dcbx_info
= kzalloc(sizeof(*p_hwfn
->p_dcbx_info
), GFP_KERNEL
);
878 if (!p_hwfn
->p_dcbx_info
)
884 void qed_dcbx_info_free(struct qed_hwfn
*p_hwfn
,
885 struct qed_dcbx_info
*p_dcbx_info
)
887 kfree(p_hwfn
->p_dcbx_info
);
890 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data
*p_data
,
891 struct qed_dcbx_results
*p_src
,
892 enum dcbx_protocol_type type
)
894 p_data
->dcb_enable_flag
= p_src
->arr
[type
].enable
;
895 p_data
->dcb_priority
= p_src
->arr
[type
].priority
;
896 p_data
->dcb_tc
= p_src
->arr
[type
].tc
;
899 /* Set pf update ramrod command params */
900 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results
*p_src
,
901 struct pf_update_ramrod_data
*p_dest
)
903 struct protocol_dcb_data
*p_dcb_data
;
904 bool update_flag
= false;
906 p_dest
->pf_id
= p_src
->pf_id
;
908 update_flag
= p_src
->arr
[DCBX_PROTOCOL_FCOE
].update
;
909 p_dest
->update_fcoe_dcb_data_flag
= update_flag
;
911 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
;
912 p_dest
->update_roce_dcb_data_flag
= update_flag
;
913 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
;
914 p_dest
->update_roce_dcb_data_flag
= update_flag
;
916 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ISCSI
].update
;
917 p_dest
->update_iscsi_dcb_data_flag
= update_flag
;
918 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ETH
].update
;
919 p_dest
->update_eth_dcb_data_flag
= update_flag
;
921 p_dcb_data
= &p_dest
->fcoe_dcb_data
;
922 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_FCOE
);
923 p_dcb_data
= &p_dest
->roce_dcb_data
;
925 if (p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
)
926 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
928 if (p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
)
929 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
930 DCBX_PROTOCOL_ROCE_V2
);
932 p_dcb_data
= &p_dest
->iscsi_dcb_data
;
933 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ISCSI
);
934 p_dcb_data
= &p_dest
->eth_dcb_data
;
935 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ETH
);
939 static int qed_dcbx_query_params(struct qed_hwfn
*p_hwfn
,
940 struct qed_dcbx_get
*p_get
,
941 enum qed_mib_read_type type
)
943 struct qed_ptt
*p_ptt
;
946 if (IS_VF(p_hwfn
->cdev
))
949 p_ptt
= qed_ptt_acquire(p_hwfn
);
953 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
957 rc
= qed_dcbx_get_params(p_hwfn
, p_ptt
, p_get
, type
);
960 qed_ptt_release(p_hwfn
, p_ptt
);
965 qed_dcbx_set_pfc_data(struct qed_hwfn
*p_hwfn
,
966 u32
*pfc
, struct qed_dcbx_params
*p_params
)
971 if (p_params
->pfc
.willing
)
972 *pfc
|= DCBX_PFC_WILLING_MASK
;
974 *pfc
&= ~DCBX_PFC_WILLING_MASK
;
976 if (p_params
->pfc
.enabled
)
977 *pfc
|= DCBX_PFC_ENABLED_MASK
;
979 *pfc
&= ~DCBX_PFC_ENABLED_MASK
;
981 *pfc
&= ~DCBX_PFC_CAPS_MASK
;
982 *pfc
|= (u32
)p_params
->pfc
.max_tc
<< DCBX_PFC_CAPS_SHIFT
;
984 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
985 if (p_params
->pfc
.prio
[i
])
988 *pfc
&= ~DCBX_PFC_PRI_EN_BITMAP_MASK
;
989 *pfc
|= (pfc_map
<< DCBX_PFC_PRI_EN_BITMAP_SHIFT
);
991 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "pfc = 0x%x\n", *pfc
);
995 qed_dcbx_set_ets_data(struct qed_hwfn
*p_hwfn
,
996 struct dcbx_ets_feature
*p_ets
,
997 struct qed_dcbx_params
*p_params
)
999 u8
*bw_map
, *tsa_map
;
1003 if (p_params
->ets_willing
)
1004 p_ets
->flags
|= DCBX_ETS_WILLING_MASK
;
1006 p_ets
->flags
&= ~DCBX_ETS_WILLING_MASK
;
1008 if (p_params
->ets_cbs
)
1009 p_ets
->flags
|= DCBX_ETS_CBS_MASK
;
1011 p_ets
->flags
&= ~DCBX_ETS_CBS_MASK
;
1013 if (p_params
->ets_enabled
)
1014 p_ets
->flags
|= DCBX_ETS_ENABLED_MASK
;
1016 p_ets
->flags
&= ~DCBX_ETS_ENABLED_MASK
;
1018 p_ets
->flags
&= ~DCBX_ETS_MAX_TCS_MASK
;
1019 p_ets
->flags
|= (u32
)p_params
->max_ets_tc
<< DCBX_ETS_MAX_TCS_SHIFT
;
1021 bw_map
= (u8
*)&p_ets
->tc_bw_tbl
[0];
1022 tsa_map
= (u8
*)&p_ets
->tc_tsa_tbl
[0];
1023 p_ets
->pri_tc_tbl
[0] = 0;
1024 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1025 bw_map
[i
] = p_params
->ets_tc_bw_tbl
[i
];
1026 tsa_map
[i
] = p_params
->ets_tc_tsa_tbl
[i
];
1027 /* Copy the priority value to the corresponding 4 bits in the
1028 * traffic class table.
1030 val
= (((u32
)p_params
->ets_pri_tc_tbl
[i
]) << ((7 - i
) * 4));
1031 p_ets
->pri_tc_tbl
[0] |= val
;
1033 for (i
= 0; i
< 2; i
++) {
1034 p_ets
->tc_bw_tbl
[i
] = cpu_to_be32(p_ets
->tc_bw_tbl
[i
]);
1035 p_ets
->tc_tsa_tbl
[i
] = cpu_to_be32(p_ets
->tc_tsa_tbl
[i
]);
1040 qed_dcbx_set_app_data(struct qed_hwfn
*p_hwfn
,
1041 struct dcbx_app_priority_feature
*p_app
,
1042 struct qed_dcbx_params
*p_params
, bool ieee
)
1047 if (p_params
->app_willing
)
1048 p_app
->flags
|= DCBX_APP_WILLING_MASK
;
1050 p_app
->flags
&= ~DCBX_APP_WILLING_MASK
;
1052 if (p_params
->app_valid
)
1053 p_app
->flags
|= DCBX_APP_ENABLED_MASK
;
1055 p_app
->flags
&= ~DCBX_APP_ENABLED_MASK
;
1057 p_app
->flags
&= ~DCBX_APP_NUM_ENTRIES_MASK
;
1058 p_app
->flags
|= (u32
)p_params
->num_app_entries
<<
1059 DCBX_APP_NUM_ENTRIES_SHIFT
;
1061 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
1062 entry
= &p_app
->app_pri_tbl
[i
].entry
;
1065 *entry
&= ~(DCBX_APP_SF_IEEE_MASK
| DCBX_APP_SF_MASK
);
1066 switch (p_params
->app_entry
[i
].sf_ieee
) {
1067 case QED_DCBX_SF_IEEE_ETHTYPE
:
1068 *entry
|= ((u32
)DCBX_APP_SF_IEEE_ETHTYPE
<<
1069 DCBX_APP_SF_IEEE_SHIFT
);
1070 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1073 case QED_DCBX_SF_IEEE_TCP_PORT
:
1074 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_PORT
<<
1075 DCBX_APP_SF_IEEE_SHIFT
);
1076 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1079 case QED_DCBX_SF_IEEE_UDP_PORT
:
1080 *entry
|= ((u32
)DCBX_APP_SF_IEEE_UDP_PORT
<<
1081 DCBX_APP_SF_IEEE_SHIFT
);
1082 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1085 case QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
1086 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_UDP_PORT
<<
1087 DCBX_APP_SF_IEEE_SHIFT
);
1088 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1093 *entry
&= ~DCBX_APP_SF_MASK
;
1094 if (p_params
->app_entry
[i
].ethtype
)
1095 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1098 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1102 *entry
&= ~DCBX_APP_PROTOCOL_ID_MASK
;
1103 *entry
|= ((u32
)p_params
->app_entry
[i
].proto_id
<<
1104 DCBX_APP_PROTOCOL_ID_SHIFT
);
1105 *entry
&= ~DCBX_APP_PRI_MAP_MASK
;
1106 *entry
|= ((u32
)(p_params
->app_entry
[i
].prio
) <<
1107 DCBX_APP_PRI_MAP_SHIFT
);
1112 qed_dcbx_set_local_params(struct qed_hwfn
*p_hwfn
,
1113 struct dcbx_local_params
*local_admin
,
1114 struct qed_dcbx_set
*params
)
1118 local_admin
->flags
= 0;
1119 memcpy(&local_admin
->features
,
1120 &p_hwfn
->p_dcbx_info
->operational
.features
,
1121 sizeof(local_admin
->features
));
1123 if (params
->enabled
) {
1124 local_admin
->config
= params
->ver_num
;
1125 ieee
= !!(params
->ver_num
& DCBX_CONFIG_VERSION_IEEE
);
1127 local_admin
->config
= DCBX_CONFIG_VERSION_DISABLED
;
1130 if (params
->override_flags
& QED_DCBX_OVERRIDE_PFC_CFG
)
1131 qed_dcbx_set_pfc_data(p_hwfn
, &local_admin
->features
.pfc
,
1132 ¶ms
->config
.params
);
1134 if (params
->override_flags
& QED_DCBX_OVERRIDE_ETS_CFG
)
1135 qed_dcbx_set_ets_data(p_hwfn
, &local_admin
->features
.ets
,
1136 ¶ms
->config
.params
);
1138 if (params
->override_flags
& QED_DCBX_OVERRIDE_APP_CFG
)
1139 qed_dcbx_set_app_data(p_hwfn
, &local_admin
->features
.app
,
1140 ¶ms
->config
.params
, ieee
);
1143 int qed_dcbx_config_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
1144 struct qed_dcbx_set
*params
, bool hw_commit
)
1146 struct dcbx_local_params local_admin
;
1147 struct qed_dcbx_mib_meta_data data
;
1148 u32 resp
= 0, param
= 0;
1152 memcpy(&p_hwfn
->p_dcbx_info
->set
, params
,
1153 sizeof(struct qed_dcbx_set
));
1157 /* clear set-parmas cache */
1158 memset(&p_hwfn
->p_dcbx_info
->set
, 0, sizeof(p_hwfn
->p_dcbx_info
->set
));
1160 memset(&local_admin
, 0, sizeof(local_admin
));
1161 qed_dcbx_set_local_params(p_hwfn
, &local_admin
, params
);
1163 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1164 offsetof(struct public_port
, local_admin_dcbx_mib
);
1165 data
.local_admin
= &local_admin
;
1166 data
.size
= sizeof(struct dcbx_local_params
);
1167 qed_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.local_admin
, data
.size
);
1169 rc
= qed_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_DCBX
,
1170 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT
, &resp
, ¶m
);
1172 DP_NOTICE(p_hwfn
, "Failed to send DCBX update request\n");
1177 int qed_dcbx_get_config_params(struct qed_hwfn
*p_hwfn
,
1178 struct qed_dcbx_set
*params
)
1180 struct qed_dcbx_get
*dcbx_info
;
1183 if (p_hwfn
->p_dcbx_info
->set
.config
.valid
) {
1184 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
,
1185 sizeof(struct qed_dcbx_set
));
1189 dcbx_info
= kzalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1193 rc
= qed_dcbx_query_params(p_hwfn
, dcbx_info
, QED_DCBX_OPERATIONAL_MIB
);
1199 p_hwfn
->p_dcbx_info
->set
.override_flags
= 0;
1200 p_hwfn
->p_dcbx_info
->set
.ver_num
= DCBX_CONFIG_VERSION_DISABLED
;
1201 if (dcbx_info
->operational
.cee
)
1202 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1203 if (dcbx_info
->operational
.ieee
)
1204 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1206 p_hwfn
->p_dcbx_info
->set
.enabled
= dcbx_info
->operational
.enabled
;
1207 memcpy(&p_hwfn
->p_dcbx_info
->set
.config
.params
,
1208 &dcbx_info
->operational
.params
,
1209 sizeof(struct qed_dcbx_admin_params
));
1210 p_hwfn
->p_dcbx_info
->set
.config
.valid
= true;
1212 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
, sizeof(struct qed_dcbx_set
));
1219 static struct qed_dcbx_get
*qed_dcbnl_get_dcbx(struct qed_hwfn
*hwfn
,
1220 enum qed_mib_read_type type
)
1222 struct qed_dcbx_get
*dcbx_info
;
1224 dcbx_info
= kzalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1228 if (qed_dcbx_query_params(hwfn
, dcbx_info
, type
)) {
1233 if ((type
== QED_DCBX_OPERATIONAL_MIB
) &&
1234 !dcbx_info
->operational
.enabled
) {
1235 DP_INFO(hwfn
, "DCBX is not enabled/operational\n");
1243 static u8
qed_dcbnl_getstate(struct qed_dev
*cdev
)
1245 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1246 struct qed_dcbx_get
*dcbx_info
;
1249 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1253 enabled
= dcbx_info
->operational
.enabled
;
1254 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", enabled
);
1260 static u8
qed_dcbnl_setstate(struct qed_dev
*cdev
, u8 state
)
1262 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1263 struct qed_dcbx_set dcbx_set
;
1264 struct qed_ptt
*ptt
;
1267 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", state
);
1269 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1270 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1274 dcbx_set
.enabled
= !!state
;
1276 ptt
= qed_ptt_acquire(hwfn
);
1280 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1282 qed_ptt_release(hwfn
, ptt
);
1287 static void qed_dcbnl_getpgtccfgtx(struct qed_dev
*cdev
, int tc
, u8
*prio_type
,
1288 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1290 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1291 struct qed_dcbx_get
*dcbx_info
;
1293 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tc = %d\n", tc
);
1294 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1295 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1296 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1300 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1304 *pgid
= dcbx_info
->operational
.params
.ets_pri_tc_tbl
[tc
];
1308 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8
*bw_pct
)
1310 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1311 struct qed_dcbx_get
*dcbx_info
;
1314 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d\n", pgid
);
1315 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1316 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1320 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1324 *bw_pct
= dcbx_info
->operational
.params
.ets_tc_bw_tbl
[pgid
];
1325 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "bw_pct = %d\n", *bw_pct
);
1329 static void qed_dcbnl_getpgtccfgrx(struct qed_dev
*cdev
, int tc
, u8
*prio
,
1330 u8
*bwg_id
, u8
*bw_pct
, u8
*up_map
)
1332 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1333 *prio
= *bwg_id
= *bw_pct
= *up_map
= 0;
1336 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev
*cdev
,
1337 int bwg_id
, u8
*bw_pct
)
1339 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1343 static void qed_dcbnl_getpfccfg(struct qed_dev
*cdev
,
1344 int priority
, u8
*setting
)
1346 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1347 struct qed_dcbx_get
*dcbx_info
;
1349 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d\n", priority
);
1350 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1351 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1355 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1359 *setting
= dcbx_info
->operational
.params
.pfc
.prio
[priority
];
1360 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "setting = %d\n", *setting
);
1364 static void qed_dcbnl_setpfccfg(struct qed_dev
*cdev
, int priority
, u8 setting
)
1366 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1367 struct qed_dcbx_set dcbx_set
;
1368 struct qed_ptt
*ptt
;
1371 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d setting = %d\n",
1373 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1374 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1378 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1379 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1383 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1384 dcbx_set
.config
.params
.pfc
.prio
[priority
] = !!setting
;
1386 ptt
= qed_ptt_acquire(hwfn
);
1390 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1392 qed_ptt_release(hwfn
, ptt
);
1395 static u8
qed_dcbnl_getcap(struct qed_dev
*cdev
, int capid
, u8
*cap
)
1397 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1398 struct qed_dcbx_get
*dcbx_info
;
1401 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "capid = %d\n", capid
);
1402 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1407 case DCB_CAP_ATTR_PG
:
1408 case DCB_CAP_ATTR_PFC
:
1409 case DCB_CAP_ATTR_UP2TC
:
1410 case DCB_CAP_ATTR_GSP
:
1413 case DCB_CAP_ATTR_PG_TCS
:
1414 case DCB_CAP_ATTR_PFC_TCS
:
1417 case DCB_CAP_ATTR_DCBX
:
1418 *cap
= (DCB_CAP_DCBX_LLD_MANAGED
| DCB_CAP_DCBX_VER_CEE
|
1419 DCB_CAP_DCBX_VER_IEEE
);
1426 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "id = %d caps = %d\n", capid
, *cap
);
1432 static int qed_dcbnl_getnumtcs(struct qed_dev
*cdev
, int tcid
, u8
*num
)
1434 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1435 struct qed_dcbx_get
*dcbx_info
;
1438 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d\n", tcid
);
1439 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1444 case DCB_NUMTCS_ATTR_PG
:
1445 *num
= dcbx_info
->operational
.params
.max_ets_tc
;
1447 case DCB_NUMTCS_ATTR_PFC
:
1448 *num
= dcbx_info
->operational
.params
.pfc
.max_tc
;
1455 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "numtcs = %d\n", *num
);
1460 static u8
qed_dcbnl_getpfcstate(struct qed_dev
*cdev
)
1462 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1463 struct qed_dcbx_get
*dcbx_info
;
1466 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1470 enabled
= dcbx_info
->operational
.params
.pfc
.enabled
;
1471 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d\n", enabled
);
1477 static u8
qed_dcbnl_getdcbx(struct qed_dev
*cdev
)
1479 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1480 struct qed_dcbx_get
*dcbx_info
;
1483 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1487 if (dcbx_info
->operational
.enabled
)
1488 mode
|= DCB_CAP_DCBX_LLD_MANAGED
;
1489 if (dcbx_info
->operational
.ieee
)
1490 mode
|= DCB_CAP_DCBX_VER_IEEE
;
1491 if (dcbx_info
->operational
.cee
)
1492 mode
|= DCB_CAP_DCBX_VER_CEE
;
1494 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "dcb mode = %d\n", mode
);
1500 static void qed_dcbnl_setpgtccfgtx(struct qed_dev
*cdev
,
1502 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1504 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1505 struct qed_dcbx_set dcbx_set
;
1506 struct qed_ptt
*ptt
;
1509 DP_VERBOSE(hwfn
, QED_MSG_DCB
,
1510 "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n",
1511 tc
, pri_type
, pgid
, bw_pct
, up_map
);
1513 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1514 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1518 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1519 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1523 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1524 dcbx_set
.config
.params
.ets_pri_tc_tbl
[tc
] = pgid
;
1526 ptt
= qed_ptt_acquire(hwfn
);
1530 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1532 qed_ptt_release(hwfn
, ptt
);
1535 static void qed_dcbnl_setpgtccfgrx(struct qed_dev
*cdev
, int prio
,
1536 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1538 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1541 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1543 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1544 struct qed_dcbx_set dcbx_set
;
1545 struct qed_ptt
*ptt
;
1548 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d bw_pct = %d\n", pgid
, bw_pct
);
1549 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1550 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1554 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1555 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1559 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1560 dcbx_set
.config
.params
.ets_tc_bw_tbl
[pgid
] = bw_pct
;
1562 ptt
= qed_ptt_acquire(hwfn
);
1566 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1568 qed_ptt_release(hwfn
, ptt
);
1571 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1573 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1576 static u8
qed_dcbnl_setall(struct qed_dev
*cdev
)
1578 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1579 struct qed_dcbx_set dcbx_set
;
1580 struct qed_ptt
*ptt
;
1583 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1584 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1588 ptt
= qed_ptt_acquire(hwfn
);
1592 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 1);
1594 qed_ptt_release(hwfn
, ptt
);
1599 static int qed_dcbnl_setnumtcs(struct qed_dev
*cdev
, int tcid
, u8 num
)
1601 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1602 struct qed_dcbx_set dcbx_set
;
1603 struct qed_ptt
*ptt
;
1606 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d num = %d\n", tcid
, num
);
1607 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1608 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1613 case DCB_NUMTCS_ATTR_PG
:
1614 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1615 dcbx_set
.config
.params
.max_ets_tc
= num
;
1617 case DCB_NUMTCS_ATTR_PFC
:
1618 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1619 dcbx_set
.config
.params
.pfc
.max_tc
= num
;
1622 DP_INFO(hwfn
, "Invalid tcid %d\n", tcid
);
1626 ptt
= qed_ptt_acquire(hwfn
);
1630 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1632 qed_ptt_release(hwfn
, ptt
);
1637 static void qed_dcbnl_setpfcstate(struct qed_dev
*cdev
, u8 state
)
1639 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1640 struct qed_dcbx_set dcbx_set
;
1641 struct qed_ptt
*ptt
;
1644 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new state = %d\n", state
);
1646 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1647 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1651 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1652 dcbx_set
.config
.params
.pfc
.enabled
= !!state
;
1654 ptt
= qed_ptt_acquire(hwfn
);
1658 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1660 qed_ptt_release(hwfn
, ptt
);
1663 static int qed_dcbnl_getapp(struct qed_dev
*cdev
, u8 idtype
, u16 idval
)
1665 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1666 struct qed_dcbx_get
*dcbx_info
;
1667 struct qed_app_entry
*entry
;
1672 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1676 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1677 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1678 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
1679 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
)) {
1685 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1686 DP_ERR(cdev
, "App entry (%d, %d) not found\n", idtype
, idval
);
1696 static int qed_dcbnl_setapp(struct qed_dev
*cdev
,
1697 u8 idtype
, u16 idval
, u8 pri_map
)
1699 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1700 struct qed_dcbx_set dcbx_set
;
1701 struct qed_app_entry
*entry
;
1702 struct qed_ptt
*ptt
;
1706 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1707 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1711 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1712 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1713 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
1714 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
))
1716 /* First empty slot */
1717 if (!entry
->proto_id
) {
1718 dcbx_set
.config
.params
.num_app_entries
++;
1723 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1724 DP_ERR(cdev
, "App table is full\n");
1728 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1729 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
1730 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= idval
;
1731 dcbx_set
.config
.params
.app_entry
[i
].prio
= pri_map
;
1733 ptt
= qed_ptt_acquire(hwfn
);
1737 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1739 qed_ptt_release(hwfn
, ptt
);
1744 static u8
qed_dcbnl_setdcbx(struct qed_dev
*cdev
, u8 mode
)
1746 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1747 struct qed_dcbx_set dcbx_set
;
1748 struct qed_ptt
*ptt
;
1751 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new mode = %x\n", mode
);
1753 if (!(mode
& DCB_CAP_DCBX_VER_IEEE
) && !(mode
& DCB_CAP_DCBX_VER_CEE
)) {
1754 DP_INFO(hwfn
, "Allowed mode is cee, ieee or both\n");
1758 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1759 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1763 dcbx_set
.ver_num
= 0;
1764 if (mode
& DCB_CAP_DCBX_VER_CEE
) {
1765 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1766 dcbx_set
.enabled
= true;
1769 if (mode
& DCB_CAP_DCBX_VER_IEEE
) {
1770 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1771 dcbx_set
.enabled
= true;
1774 ptt
= qed_ptt_acquire(hwfn
);
1778 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1780 qed_ptt_release(hwfn
, ptt
);
1785 static u8
qed_dcbnl_getfeatcfg(struct qed_dev
*cdev
, int featid
, u8
*flags
)
1787 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1788 struct qed_dcbx_get
*dcbx_info
;
1790 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "Feature id = %d\n", featid
);
1791 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1797 case DCB_FEATCFG_ATTR_PG
:
1798 if (dcbx_info
->operational
.params
.ets_enabled
)
1799 *flags
= DCB_FEATCFG_ENABLE
;
1801 *flags
= DCB_FEATCFG_ERROR
;
1803 case DCB_FEATCFG_ATTR_PFC
:
1804 if (dcbx_info
->operational
.params
.pfc
.enabled
)
1805 *flags
= DCB_FEATCFG_ENABLE
;
1807 *flags
= DCB_FEATCFG_ERROR
;
1809 case DCB_FEATCFG_ATTR_APP
:
1810 if (dcbx_info
->operational
.params
.app_valid
)
1811 *flags
= DCB_FEATCFG_ENABLE
;
1813 *flags
= DCB_FEATCFG_ERROR
;
1816 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1821 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "flags = %d\n", *flags
);
1827 static u8
qed_dcbnl_setfeatcfg(struct qed_dev
*cdev
, int featid
, u8 flags
)
1829 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1830 struct qed_dcbx_set dcbx_set
;
1831 bool enabled
, willing
;
1832 struct qed_ptt
*ptt
;
1835 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "featid = %d flags = %d\n",
1837 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1838 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1842 enabled
= !!(flags
& DCB_FEATCFG_ENABLE
);
1843 willing
= !!(flags
& DCB_FEATCFG_WILLING
);
1845 case DCB_FEATCFG_ATTR_PG
:
1846 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1847 dcbx_set
.config
.params
.ets_enabled
= enabled
;
1848 dcbx_set
.config
.params
.ets_willing
= willing
;
1850 case DCB_FEATCFG_ATTR_PFC
:
1851 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1852 dcbx_set
.config
.params
.pfc
.enabled
= enabled
;
1853 dcbx_set
.config
.params
.pfc
.willing
= willing
;
1855 case DCB_FEATCFG_ATTR_APP
:
1856 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1857 dcbx_set
.config
.params
.app_willing
= willing
;
1860 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1864 ptt
= qed_ptt_acquire(hwfn
);
1868 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1870 qed_ptt_release(hwfn
, ptt
);
1875 static int qed_dcbnl_peer_getappinfo(struct qed_dev
*cdev
,
1876 struct dcb_peer_app_info
*info
,
1879 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1880 struct qed_dcbx_get
*dcbx_info
;
1882 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1886 info
->willing
= dcbx_info
->remote
.params
.app_willing
;
1887 info
->error
= dcbx_info
->remote
.params
.app_error
;
1888 *app_count
= dcbx_info
->remote
.params
.num_app_entries
;
1894 static int qed_dcbnl_peer_getapptable(struct qed_dev
*cdev
,
1895 struct dcb_app
*table
)
1897 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1898 struct qed_dcbx_get
*dcbx_info
;
1901 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1905 for (i
= 0; i
< dcbx_info
->remote
.params
.num_app_entries
; i
++) {
1906 if (dcbx_info
->remote
.params
.app_entry
[i
].ethtype
)
1907 table
[i
].selector
= DCB_APP_IDTYPE_ETHTYPE
;
1909 table
[i
].selector
= DCB_APP_IDTYPE_PORTNUM
;
1910 table
[i
].priority
= dcbx_info
->remote
.params
.app_entry
[i
].prio
;
1912 dcbx_info
->remote
.params
.app_entry
[i
].proto_id
;
1920 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev
*cdev
, struct cee_pfc
*pfc
)
1922 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1923 struct qed_dcbx_get
*dcbx_info
;
1926 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1930 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1931 if (dcbx_info
->remote
.params
.pfc
.prio
[i
])
1932 pfc
->pfc_en
|= BIT(i
);
1934 pfc
->tcs_supported
= dcbx_info
->remote
.params
.pfc
.max_tc
;
1935 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d tcs_supported = %d\n",
1936 pfc
->pfc_en
, pfc
->tcs_supported
);
1942 static int qed_dcbnl_cee_peer_getpg(struct qed_dev
*cdev
, struct cee_pg
*pg
)
1944 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1945 struct qed_dcbx_get
*dcbx_info
;
1948 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1952 pg
->willing
= dcbx_info
->remote
.params
.ets_willing
;
1953 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1954 pg
->pg_bw
[i
] = dcbx_info
->remote
.params
.ets_tc_bw_tbl
[i
];
1955 pg
->prio_pg
[i
] = dcbx_info
->remote
.params
.ets_pri_tc_tbl
[i
];
1958 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "willing = %d", pg
->willing
);
1964 static int qed_dcbnl_get_ieee_pfc(struct qed_dev
*cdev
,
1965 struct ieee_pfc
*pfc
, bool remote
)
1967 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1968 struct qed_dcbx_params
*params
;
1969 struct qed_dcbx_get
*dcbx_info
;
1972 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1976 if (!dcbx_info
->operational
.ieee
) {
1977 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1983 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1984 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
1985 QED_DCBX_REMOTE_MIB
);
1991 params
= &dcbx_info
->remote
.params
;
1993 params
= &dcbx_info
->operational
.params
;
1996 pfc
->pfc_cap
= params
->pfc
.max_tc
;
1998 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1999 if (params
->pfc
.prio
[i
])
2000 pfc
->pfc_en
|= BIT(i
);
2007 static int qed_dcbnl_ieee_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2009 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, false);
2012 static int qed_dcbnl_ieee_setpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2014 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2015 struct qed_dcbx_get
*dcbx_info
;
2016 struct qed_dcbx_set dcbx_set
;
2017 struct qed_ptt
*ptt
;
2020 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2024 if (!dcbx_info
->operational
.ieee
) {
2025 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2032 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2033 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2037 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
2038 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
2039 dcbx_set
.config
.params
.pfc
.prio
[i
] = !!(pfc
->pfc_en
& BIT(i
));
2041 ptt
= qed_ptt_acquire(hwfn
);
2045 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2047 qed_ptt_release(hwfn
, ptt
);
2052 static int qed_dcbnl_get_ieee_ets(struct qed_dev
*cdev
,
2053 struct ieee_ets
*ets
, bool remote
)
2055 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2056 struct qed_dcbx_get
*dcbx_info
;
2057 struct qed_dcbx_params
*params
;
2060 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2064 if (!dcbx_info
->operational
.ieee
) {
2065 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2071 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
2072 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
2073 QED_DCBX_REMOTE_MIB
);
2079 params
= &dcbx_info
->remote
.params
;
2081 params
= &dcbx_info
->operational
.params
;
2084 ets
->ets_cap
= params
->max_ets_tc
;
2085 ets
->willing
= params
->ets_willing
;
2086 ets
->cbs
= params
->ets_cbs
;
2087 memcpy(ets
->tc_tx_bw
, params
->ets_tc_bw_tbl
, sizeof(ets
->tc_tx_bw
));
2088 memcpy(ets
->tc_tsa
, params
->ets_tc_tsa_tbl
, sizeof(ets
->tc_tsa
));
2089 memcpy(ets
->prio_tc
, params
->ets_pri_tc_tbl
, sizeof(ets
->prio_tc
));
2095 static int qed_dcbnl_ieee_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2097 return qed_dcbnl_get_ieee_ets(cdev
, ets
, false);
2100 static int qed_dcbnl_ieee_setets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2102 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2103 struct qed_dcbx_get
*dcbx_info
;
2104 struct qed_dcbx_set dcbx_set
;
2105 struct qed_ptt
*ptt
;
2108 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2112 if (!dcbx_info
->operational
.ieee
) {
2113 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2120 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2121 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2125 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
2126 dcbx_set
.config
.params
.max_ets_tc
= ets
->ets_cap
;
2127 dcbx_set
.config
.params
.ets_willing
= ets
->willing
;
2128 dcbx_set
.config
.params
.ets_cbs
= ets
->cbs
;
2129 memcpy(dcbx_set
.config
.params
.ets_tc_bw_tbl
, ets
->tc_tx_bw
,
2130 sizeof(ets
->tc_tx_bw
));
2131 memcpy(dcbx_set
.config
.params
.ets_tc_tsa_tbl
, ets
->tc_tsa
,
2132 sizeof(ets
->tc_tsa
));
2133 memcpy(dcbx_set
.config
.params
.ets_pri_tc_tbl
, ets
->prio_tc
,
2134 sizeof(ets
->prio_tc
));
2136 ptt
= qed_ptt_acquire(hwfn
);
2140 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2142 qed_ptt_release(hwfn
, ptt
);
2148 qed_dcbnl_ieee_peer_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2150 return qed_dcbnl_get_ieee_ets(cdev
, ets
, true);
2154 qed_dcbnl_ieee_peer_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2156 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, true);
2159 static int qed_dcbnl_ieee_getapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2161 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2162 struct qed_dcbx_get
*dcbx_info
;
2163 struct qed_app_entry
*entry
;
2168 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2172 if (!dcbx_info
->operational
.ieee
) {
2173 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2178 /* ieee defines the selector field value for ethertype to be 1 */
2179 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2180 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2181 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
2182 if ((entry
->ethtype
== ethtype
) &&
2183 (entry
->proto_id
== app
->protocol
)) {
2189 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2190 DP_ERR(cdev
, "App entry (%d, %d) not found\n", app
->selector
,
2196 app
->priority
= ffs(prio
) - 1;
2203 static int qed_dcbnl_ieee_setapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2205 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2206 struct qed_dcbx_get
*dcbx_info
;
2207 struct qed_dcbx_set dcbx_set
;
2208 struct qed_app_entry
*entry
;
2209 struct qed_ptt
*ptt
;
2213 if (app
->priority
< 0 || app
->priority
>= QED_MAX_PFC_PRIORITIES
) {
2214 DP_INFO(hwfn
, "Invalid priority %d\n", app
->priority
);
2218 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2222 if (!dcbx_info
->operational
.ieee
) {
2223 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2230 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2231 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2235 /* ieee defines the selector field value for ethertype to be 1 */
2236 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2237 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2238 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
2239 if ((entry
->ethtype
== ethtype
) &&
2240 (entry
->proto_id
== app
->protocol
))
2242 /* First empty slot */
2243 if (!entry
->proto_id
) {
2244 dcbx_set
.config
.params
.num_app_entries
++;
2249 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2250 DP_ERR(cdev
, "App table is full\n");
2254 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
2255 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
2256 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= app
->protocol
;
2257 dcbx_set
.config
.params
.app_entry
[i
].prio
= BIT(app
->priority
);
2259 ptt
= qed_ptt_acquire(hwfn
);
2263 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2265 qed_ptt_release(hwfn
, ptt
);
2270 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass
= {
2271 .getstate
= qed_dcbnl_getstate
,
2272 .setstate
= qed_dcbnl_setstate
,
2273 .getpgtccfgtx
= qed_dcbnl_getpgtccfgtx
,
2274 .getpgbwgcfgtx
= qed_dcbnl_getpgbwgcfgtx
,
2275 .getpgtccfgrx
= qed_dcbnl_getpgtccfgrx
,
2276 .getpgbwgcfgrx
= qed_dcbnl_getpgbwgcfgrx
,
2277 .getpfccfg
= qed_dcbnl_getpfccfg
,
2278 .setpfccfg
= qed_dcbnl_setpfccfg
,
2279 .getcap
= qed_dcbnl_getcap
,
2280 .getnumtcs
= qed_dcbnl_getnumtcs
,
2281 .getpfcstate
= qed_dcbnl_getpfcstate
,
2282 .getdcbx
= qed_dcbnl_getdcbx
,
2283 .setpgtccfgtx
= qed_dcbnl_setpgtccfgtx
,
2284 .setpgtccfgrx
= qed_dcbnl_setpgtccfgrx
,
2285 .setpgbwgcfgtx
= qed_dcbnl_setpgbwgcfgtx
,
2286 .setpgbwgcfgrx
= qed_dcbnl_setpgbwgcfgrx
,
2287 .setall
= qed_dcbnl_setall
,
2288 .setnumtcs
= qed_dcbnl_setnumtcs
,
2289 .setpfcstate
= qed_dcbnl_setpfcstate
,
2290 .setapp
= qed_dcbnl_setapp
,
2291 .setdcbx
= qed_dcbnl_setdcbx
,
2292 .setfeatcfg
= qed_dcbnl_setfeatcfg
,
2293 .getfeatcfg
= qed_dcbnl_getfeatcfg
,
2294 .getapp
= qed_dcbnl_getapp
,
2295 .peer_getappinfo
= qed_dcbnl_peer_getappinfo
,
2296 .peer_getapptable
= qed_dcbnl_peer_getapptable
,
2297 .cee_peer_getpfc
= qed_dcbnl_cee_peer_getpfc
,
2298 .cee_peer_getpg
= qed_dcbnl_cee_peer_getpg
,
2299 .ieee_getpfc
= qed_dcbnl_ieee_getpfc
,
2300 .ieee_setpfc
= qed_dcbnl_ieee_setpfc
,
2301 .ieee_getets
= qed_dcbnl_ieee_getets
,
2302 .ieee_setets
= qed_dcbnl_ieee_setets
,
2303 .ieee_peer_getpfc
= qed_dcbnl_ieee_peer_getpfc
,
2304 .ieee_peer_getets
= qed_dcbnl_ieee_peer_getets
,
2305 .ieee_getapp
= qed_dcbnl_ieee_getapp
,
2306 .ieee_setapp
= qed_dcbnl_ieee_setapp
,