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_app_port(u32 app_info_bitmap
)
57 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
61 static bool qed_dcbx_default_tlv(u32 app_info_bitmap
, u16 proto_id
)
63 return !!(qed_dcbx_app_ethtype(app_info_bitmap
) &&
64 proto_id
== QED_ETH_TYPE_DEFAULT
);
67 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap
, u16 proto_id
)
69 return !!(qed_dcbx_app_port(app_info_bitmap
) &&
70 proto_id
== QED_TCP_PORT_ISCSI
);
73 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap
, u16 proto_id
)
75 return !!(qed_dcbx_app_ethtype(app_info_bitmap
) &&
76 proto_id
== QED_ETH_TYPE_FCOE
);
79 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap
, u16 proto_id
)
81 return !!(qed_dcbx_app_ethtype(app_info_bitmap
) &&
82 proto_id
== QED_ETH_TYPE_ROCE
);
85 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap
, u16 proto_id
)
87 return !!(qed_dcbx_app_port(app_info_bitmap
) &&
88 proto_id
== QED_UDP_PORT_TYPE_ROCE_V2
);
92 qed_dcbx_dp_protocol(struct qed_hwfn
*p_hwfn
, struct qed_dcbx_results
*p_data
)
94 enum dcbx_protocol_type id
;
97 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "DCBX negotiated: %d\n",
98 p_data
->dcbx_enabled
);
100 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
101 id
= qed_dcbx_app_update
[i
].id
;
103 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
104 "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
105 qed_dcbx_app_update
[i
].name
, p_data
->arr
[id
].update
,
106 p_data
->arr
[id
].enable
, p_data
->arr
[id
].priority
,
107 p_data
->arr
[id
].tc
, p_hwfn
->hw_info
.num_tc
);
112 qed_dcbx_set_params(struct qed_dcbx_results
*p_data
,
113 struct qed_hw_info
*p_info
,
118 enum dcbx_protocol_type type
,
119 enum qed_pci_personality personality
)
121 /* PF update ramrod data */
122 p_data
->arr
[type
].update
= update
;
123 p_data
->arr
[type
].enable
= enable
;
124 p_data
->arr
[type
].priority
= prio
;
125 p_data
->arr
[type
].tc
= tc
;
128 if (p_info
->personality
== personality
) {
129 if (personality
== QED_PCI_ETH
)
130 p_info
->non_offload_tc
= tc
;
132 p_info
->offload_tc
= tc
;
136 /* Update app protocol data and hw_info fields with the TLV info */
138 qed_dcbx_update_app_info(struct qed_dcbx_results
*p_data
,
139 struct qed_hwfn
*p_hwfn
,
142 u8 prio
, u8 tc
, enum dcbx_protocol_type type
)
144 struct qed_hw_info
*p_info
= &p_hwfn
->hw_info
;
145 enum qed_pci_personality personality
;
146 enum dcbx_protocol_type id
;
150 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
151 id
= qed_dcbx_app_update
[i
].id
;
156 personality
= qed_dcbx_app_update
[i
].personality
;
157 name
= qed_dcbx_app_update
[i
].name
;
159 qed_dcbx_set_params(p_data
, p_info
, enable
, update
,
160 prio
, tc
, type
, personality
);
165 qed_dcbx_get_app_protocol_type(struct qed_hwfn
*p_hwfn
,
167 u16 id
, enum dcbx_protocol_type
*type
)
169 if (qed_dcbx_fcoe_tlv(app_prio_bitmap
, id
)) {
170 *type
= DCBX_PROTOCOL_FCOE
;
171 } else if (qed_dcbx_roce_tlv(app_prio_bitmap
, id
)) {
172 *type
= DCBX_PROTOCOL_ROCE
;
173 } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap
, id
)) {
174 *type
= DCBX_PROTOCOL_ISCSI
;
175 } else if (qed_dcbx_default_tlv(app_prio_bitmap
, id
)) {
176 *type
= DCBX_PROTOCOL_ETH
;
177 } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap
, id
)) {
178 *type
= DCBX_PROTOCOL_ROCE_V2
;
180 *type
= DCBX_MAX_PROTOCOL_TYPE
;
182 "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
183 id
, app_prio_bitmap
);
190 /* Parse app TLV's to update TC information in hw_info structure for
191 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
194 qed_dcbx_process_tlv(struct qed_hwfn
*p_hwfn
,
195 struct qed_dcbx_results
*p_data
,
196 struct dcbx_app_priority_entry
*p_tbl
,
197 u32 pri_tc_tbl
, int count
, bool dcbx_enabled
)
200 enum dcbx_protocol_type type
;
206 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Num APP entries = %d\n", count
);
209 for (i
= 0; i
< count
; i
++) {
210 protocol_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
211 DCBX_APP_PROTOCOL_ID
);
212 priority_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
214 priority
= ffs(priority_map
) - 1;
216 DP_ERR(p_hwfn
, "Invalid priority\n");
220 tc
= QED_DCBX_PRIO2TC(pri_tc_tbl
, priority
);
221 if (qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
222 protocol_id
, &type
)) {
223 /* ETH always have the enable bit reset, as it gets
224 * vlan information per packet. For other protocols,
225 * should be set according to the dcbx_enabled
226 * indication, but we only got here if there was an
227 * app tlv for the protocol, so dcbx must be enabled.
229 enable
= !(type
== DCBX_PROTOCOL_ETH
);
231 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
236 /* If RoCE-V2 TLV is not detected, driver need to use RoCE app
237 * data for RoCE-v2 not the default app data.
239 if (!p_data
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
240 p_data
->arr
[DCBX_PROTOCOL_ROCE
].update
) {
241 tc
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].tc
;
242 priority
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
243 qed_dcbx_update_app_info(p_data
, p_hwfn
, true, true,
244 priority
, tc
, DCBX_PROTOCOL_ROCE_V2
);
247 /* Update ramrod protocol data and hw_info fields
248 * with default info when corresponding APP TLV's are not detected.
249 * The enabled field has a different logic for ethernet as only for
250 * ethernet dcb should disabled by default, as the information arrives
251 * from the OS (unless an explicit app tlv was present).
253 tc
= p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
;
254 priority
= p_data
->arr
[DCBX_PROTOCOL_ETH
].priority
;
255 for (type
= 0; type
< DCBX_MAX_PROTOCOL_TYPE
; type
++) {
256 if (p_data
->arr
[type
].update
)
259 enable
= !(type
== DCBX_PROTOCOL_ETH
);
260 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
267 /* Parse app TLV's to update TC information in hw_info structure for
268 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
270 static int qed_dcbx_process_mib_info(struct qed_hwfn
*p_hwfn
)
272 struct dcbx_app_priority_feature
*p_app
;
273 struct dcbx_app_priority_entry
*p_tbl
;
274 struct qed_dcbx_results data
= { 0 };
275 struct dcbx_ets_feature
*p_ets
;
276 struct qed_hw_info
*p_info
;
277 u32 pri_tc_tbl
, flags
;
282 /* If DCBx version is non zero, then negotiation was
283 * successfuly performed
285 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
286 dcbx_enabled
= !!QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
);
288 p_app
= &p_hwfn
->p_dcbx_info
->operational
.features
.app
;
289 p_tbl
= p_app
->app_pri_tbl
;
291 p_ets
= &p_hwfn
->p_dcbx_info
->operational
.features
.ets
;
292 pri_tc_tbl
= p_ets
->pri_tc_tbl
[0];
294 p_info
= &p_hwfn
->hw_info
;
295 num_entries
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_NUM_ENTRIES
);
297 rc
= qed_dcbx_process_tlv(p_hwfn
, &data
, p_tbl
, pri_tc_tbl
,
298 num_entries
, dcbx_enabled
);
302 p_info
->num_tc
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
303 data
.pf_id
= p_hwfn
->rel_pf_id
;
304 data
.dcbx_enabled
= dcbx_enabled
;
306 qed_dcbx_dp_protocol(p_hwfn
, &data
);
308 memcpy(&p_hwfn
->p_dcbx_info
->results
, &data
,
309 sizeof(struct qed_dcbx_results
));
315 qed_dcbx_copy_mib(struct qed_hwfn
*p_hwfn
,
316 struct qed_ptt
*p_ptt
,
317 struct qed_dcbx_mib_meta_data
*p_data
,
318 enum qed_mib_read_type type
)
320 u32 prefix_seq_num
, suffix_seq_num
;
324 /* The data is considered to be valid only if both sequence numbers are
328 if (type
== QED_DCBX_REMOTE_LLDP_MIB
) {
329 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_remote
,
330 p_data
->addr
, p_data
->size
);
331 prefix_seq_num
= p_data
->lldp_remote
->prefix_seq_num
;
332 suffix_seq_num
= p_data
->lldp_remote
->suffix_seq_num
;
334 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->mib
,
335 p_data
->addr
, p_data
->size
);
336 prefix_seq_num
= p_data
->mib
->prefix_seq_num
;
337 suffix_seq_num
= p_data
->mib
->suffix_seq_num
;
343 "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
344 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
345 } while ((prefix_seq_num
!= suffix_seq_num
) &&
346 (read_count
< QED_DCBX_MAX_MIB_READ_TRY
));
348 if (read_count
>= QED_DCBX_MAX_MIB_READ_TRY
) {
350 "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
351 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
360 qed_dcbx_get_priority_info(struct qed_hwfn
*p_hwfn
,
361 struct qed_dcbx_app_prio
*p_prio
,
362 struct qed_dcbx_results
*p_results
)
366 p_prio
->roce
= QED_DCBX_INVALID_PRIORITY
;
367 p_prio
->roce_v2
= QED_DCBX_INVALID_PRIORITY
;
368 p_prio
->iscsi
= QED_DCBX_INVALID_PRIORITY
;
369 p_prio
->fcoe
= QED_DCBX_INVALID_PRIORITY
;
371 if (p_results
->arr
[DCBX_PROTOCOL_ROCE
].update
&&
372 p_results
->arr
[DCBX_PROTOCOL_ROCE
].enable
)
373 p_prio
->roce
= p_results
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
375 if (p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
376 p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].enable
) {
377 val
= p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].priority
;
378 p_prio
->roce_v2
= val
;
381 if (p_results
->arr
[DCBX_PROTOCOL_ISCSI
].update
&&
382 p_results
->arr
[DCBX_PROTOCOL_ISCSI
].enable
)
383 p_prio
->iscsi
= p_results
->arr
[DCBX_PROTOCOL_ISCSI
].priority
;
385 if (p_results
->arr
[DCBX_PROTOCOL_FCOE
].update
&&
386 p_results
->arr
[DCBX_PROTOCOL_FCOE
].enable
)
387 p_prio
->fcoe
= p_results
->arr
[DCBX_PROTOCOL_FCOE
].priority
;
389 if (p_results
->arr
[DCBX_PROTOCOL_ETH
].update
&&
390 p_results
->arr
[DCBX_PROTOCOL_ETH
].enable
)
391 p_prio
->eth
= p_results
->arr
[DCBX_PROTOCOL_ETH
].priority
;
393 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
394 "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
395 p_prio
->iscsi
, p_prio
->roce
, p_prio
->roce_v2
, p_prio
->fcoe
,
400 qed_dcbx_get_app_data(struct qed_hwfn
*p_hwfn
,
401 struct dcbx_app_priority_feature
*p_app
,
402 struct dcbx_app_priority_entry
*p_tbl
,
403 struct qed_dcbx_params
*p_params
)
405 struct qed_app_entry
*entry
;
409 p_params
->app_willing
= QED_MFW_GET_FIELD(p_app
->flags
,
411 p_params
->app_valid
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ENABLED
);
412 p_params
->app_error
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ERROR
);
413 p_params
->num_app_entries
= QED_MFW_GET_FIELD(p_app
->flags
,
414 DCBX_APP_NUM_ENTRIES
);
415 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
416 entry
= &p_params
->app_entry
[i
];
417 entry
->ethtype
= !(QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
419 pri_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
420 entry
->prio
= ffs(pri_map
) - 1;
421 entry
->proto_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
422 DCBX_APP_PROTOCOL_ID
);
423 qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
428 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
429 "APP params: willing %d, valid %d error = %d\n",
430 p_params
->app_willing
, p_params
->app_valid
,
431 p_params
->app_error
);
435 qed_dcbx_get_pfc_data(struct qed_hwfn
*p_hwfn
,
436 u32 pfc
, struct qed_dcbx_params
*p_params
)
440 p_params
->pfc
.willing
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_WILLING
);
441 p_params
->pfc
.max_tc
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_CAPS
);
442 p_params
->pfc
.enabled
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_ENABLED
);
443 pfc_map
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_PRI_EN_BITMAP
);
444 p_params
->pfc
.prio
[0] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_0
);
445 p_params
->pfc
.prio
[1] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_1
);
446 p_params
->pfc
.prio
[2] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_2
);
447 p_params
->pfc
.prio
[3] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_3
);
448 p_params
->pfc
.prio
[4] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_4
);
449 p_params
->pfc
.prio
[5] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_5
);
450 p_params
->pfc
.prio
[6] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_6
);
451 p_params
->pfc
.prio
[7] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_7
);
453 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
454 "PFC params: willing %d, pfc_bitmap %d\n",
455 p_params
->pfc
.willing
, pfc_map
);
459 qed_dcbx_get_ets_data(struct qed_hwfn
*p_hwfn
,
460 struct dcbx_ets_feature
*p_ets
,
461 struct qed_dcbx_params
*p_params
)
463 u32 bw_map
[2], tsa_map
[2], pri_map
;
466 p_params
->ets_willing
= QED_MFW_GET_FIELD(p_ets
->flags
,
468 p_params
->ets_enabled
= QED_MFW_GET_FIELD(p_ets
->flags
,
470 p_params
->ets_cbs
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_CBS
);
471 p_params
->max_ets_tc
= QED_MFW_GET_FIELD(p_ets
->flags
,
473 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
474 "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
475 p_params
->ets_willing
,
477 p_ets
->pri_tc_tbl
[0], p_params
->max_ets_tc
);
479 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
480 * encoded in a type u32 array of size 2.
482 bw_map
[0] = be32_to_cpu(p_ets
->tc_bw_tbl
[0]);
483 bw_map
[1] = be32_to_cpu(p_ets
->tc_bw_tbl
[1]);
484 tsa_map
[0] = be32_to_cpu(p_ets
->tc_tsa_tbl
[0]);
485 tsa_map
[1] = be32_to_cpu(p_ets
->tc_tsa_tbl
[1]);
486 pri_map
= be32_to_cpu(p_ets
->pri_tc_tbl
[0]);
487 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
488 p_params
->ets_tc_bw_tbl
[i
] = ((u8
*)bw_map
)[i
];
489 p_params
->ets_tc_tsa_tbl
[i
] = ((u8
*)tsa_map
)[i
];
490 p_params
->ets_pri_tc_tbl
[i
] = QED_DCBX_PRIO2TC(pri_map
, i
);
491 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
492 "elem %d bw_tbl %x tsa_tbl %x\n",
493 i
, p_params
->ets_tc_bw_tbl
[i
],
494 p_params
->ets_tc_tsa_tbl
[i
]);
499 qed_dcbx_get_common_params(struct qed_hwfn
*p_hwfn
,
500 struct dcbx_app_priority_feature
*p_app
,
501 struct dcbx_app_priority_entry
*p_tbl
,
502 struct dcbx_ets_feature
*p_ets
,
503 u32 pfc
, struct qed_dcbx_params
*p_params
)
505 qed_dcbx_get_app_data(p_hwfn
, p_app
, p_tbl
, p_params
);
506 qed_dcbx_get_ets_data(p_hwfn
, p_ets
, p_params
);
507 qed_dcbx_get_pfc_data(p_hwfn
, pfc
, p_params
);
511 qed_dcbx_get_local_params(struct qed_hwfn
*p_hwfn
,
512 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
514 struct dcbx_features
*p_feat
;
516 p_feat
= &p_hwfn
->p_dcbx_info
->local_admin
.features
;
517 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
518 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
519 p_feat
->pfc
, ¶ms
->local
.params
);
520 params
->local
.valid
= true;
524 qed_dcbx_get_remote_params(struct qed_hwfn
*p_hwfn
,
525 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
527 struct dcbx_features
*p_feat
;
529 p_feat
= &p_hwfn
->p_dcbx_info
->remote
.features
;
530 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
531 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
532 p_feat
->pfc
, ¶ms
->remote
.params
);
533 params
->remote
.valid
= true;
537 qed_dcbx_get_operational_params(struct qed_hwfn
*p_hwfn
,
538 struct qed_ptt
*p_ptt
,
539 struct qed_dcbx_get
*params
)
541 struct qed_dcbx_operational_params
*p_operational
;
542 struct qed_dcbx_results
*p_results
;
543 struct dcbx_features
*p_feat
;
548 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
550 /* If DCBx version is non zero, then negotiation
551 * was successfuly performed
553 p_operational
= ¶ms
->operational
;
554 enabled
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) !=
555 DCBX_CONFIG_VERSION_DISABLED
);
557 p_operational
->enabled
= enabled
;
558 p_operational
->valid
= false;
562 p_feat
= &p_hwfn
->p_dcbx_info
->operational
.features
;
563 p_results
= &p_hwfn
->p_dcbx_info
->results
;
565 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
566 DCBX_CONFIG_VERSION_IEEE
);
567 p_operational
->ieee
= val
;
568 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
569 DCBX_CONFIG_VERSION_CEE
);
570 p_operational
->cee
= val
;
572 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Version support: ieee %d, cee %d\n",
573 p_operational
->ieee
, p_operational
->cee
);
575 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
576 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
577 p_feat
->pfc
, ¶ms
->operational
.params
);
578 qed_dcbx_get_priority_info(p_hwfn
, &p_operational
->app_prio
, p_results
);
579 err
= QED_MFW_GET_FIELD(p_feat
->app
.flags
, DCBX_APP_ERROR
);
580 p_operational
->err
= err
;
581 p_operational
->enabled
= enabled
;
582 p_operational
->valid
= true;
586 qed_dcbx_get_local_lldp_params(struct qed_hwfn
*p_hwfn
,
587 struct qed_ptt
*p_ptt
,
588 struct qed_dcbx_get
*params
)
590 struct lldp_config_params_s
*p_local
;
592 p_local
= &p_hwfn
->p_dcbx_info
->lldp_local
[LLDP_NEAREST_BRIDGE
];
594 memcpy(params
->lldp_local
.local_chassis_id
, p_local
->local_chassis_id
,
595 ARRAY_SIZE(p_local
->local_chassis_id
));
596 memcpy(params
->lldp_local
.local_port_id
, p_local
->local_port_id
,
597 ARRAY_SIZE(p_local
->local_port_id
));
601 qed_dcbx_get_remote_lldp_params(struct qed_hwfn
*p_hwfn
,
602 struct qed_ptt
*p_ptt
,
603 struct qed_dcbx_get
*params
)
605 struct lldp_status_params_s
*p_remote
;
607 p_remote
= &p_hwfn
->p_dcbx_info
->lldp_remote
[LLDP_NEAREST_BRIDGE
];
609 memcpy(params
->lldp_remote
.peer_chassis_id
, p_remote
->peer_chassis_id
,
610 ARRAY_SIZE(p_remote
->peer_chassis_id
));
611 memcpy(params
->lldp_remote
.peer_port_id
, p_remote
->peer_port_id
,
612 ARRAY_SIZE(p_remote
->peer_port_id
));
616 qed_dcbx_get_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
617 struct qed_dcbx_get
*p_params
,
618 enum qed_mib_read_type type
)
621 case QED_DCBX_REMOTE_MIB
:
622 qed_dcbx_get_remote_params(p_hwfn
, p_ptt
, p_params
);
624 case QED_DCBX_LOCAL_MIB
:
625 qed_dcbx_get_local_params(p_hwfn
, p_ptt
, p_params
);
627 case QED_DCBX_OPERATIONAL_MIB
:
628 qed_dcbx_get_operational_params(p_hwfn
, p_ptt
, p_params
);
630 case QED_DCBX_REMOTE_LLDP_MIB
:
631 qed_dcbx_get_remote_lldp_params(p_hwfn
, p_ptt
, p_params
);
633 case QED_DCBX_LOCAL_LLDP_MIB
:
634 qed_dcbx_get_local_lldp_params(p_hwfn
, p_ptt
, p_params
);
637 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
646 qed_dcbx_read_local_lldp_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
648 struct qed_dcbx_mib_meta_data data
;
651 memset(&data
, 0, sizeof(data
));
652 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
654 data
.lldp_local
= p_hwfn
->p_dcbx_info
->lldp_local
;
655 data
.size
= sizeof(struct lldp_config_params_s
);
656 qed_memcpy_from(p_hwfn
, p_ptt
, data
.lldp_local
, data
.addr
, data
.size
);
662 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn
*p_hwfn
,
663 struct qed_ptt
*p_ptt
,
664 enum qed_mib_read_type type
)
666 struct qed_dcbx_mib_meta_data data
;
669 memset(&data
, 0, sizeof(data
));
670 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
672 data
.lldp_remote
= p_hwfn
->p_dcbx_info
->lldp_remote
;
673 data
.size
= sizeof(struct lldp_status_params_s
);
674 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
680 qed_dcbx_read_operational_mib(struct qed_hwfn
*p_hwfn
,
681 struct qed_ptt
*p_ptt
,
682 enum qed_mib_read_type type
)
684 struct qed_dcbx_mib_meta_data data
;
687 memset(&data
, 0, sizeof(data
));
688 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
689 offsetof(struct public_port
, operational_dcbx_mib
);
690 data
.mib
= &p_hwfn
->p_dcbx_info
->operational
;
691 data
.size
= sizeof(struct dcbx_mib
);
692 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
698 qed_dcbx_read_remote_mib(struct qed_hwfn
*p_hwfn
,
699 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
701 struct qed_dcbx_mib_meta_data data
;
704 memset(&data
, 0, sizeof(data
));
705 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
706 offsetof(struct public_port
, remote_dcbx_mib
);
707 data
.mib
= &p_hwfn
->p_dcbx_info
->remote
;
708 data
.size
= sizeof(struct dcbx_mib
);
709 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
715 qed_dcbx_read_local_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
717 struct qed_dcbx_mib_meta_data data
;
720 memset(&data
, 0, sizeof(data
));
721 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
722 offsetof(struct public_port
, local_admin_dcbx_mib
);
723 data
.local_admin
= &p_hwfn
->p_dcbx_info
->local_admin
;
724 data
.size
= sizeof(struct dcbx_local_params
);
725 qed_memcpy_from(p_hwfn
, p_ptt
, data
.local_admin
, data
.addr
, data
.size
);
730 static int qed_dcbx_read_mib(struct qed_hwfn
*p_hwfn
,
731 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
736 case QED_DCBX_OPERATIONAL_MIB
:
737 rc
= qed_dcbx_read_operational_mib(p_hwfn
, p_ptt
, type
);
739 case QED_DCBX_REMOTE_MIB
:
740 rc
= qed_dcbx_read_remote_mib(p_hwfn
, p_ptt
, type
);
742 case QED_DCBX_LOCAL_MIB
:
743 rc
= qed_dcbx_read_local_mib(p_hwfn
, p_ptt
);
745 case QED_DCBX_REMOTE_LLDP_MIB
:
746 rc
= qed_dcbx_read_remote_lldp_mib(p_hwfn
, p_ptt
, type
);
748 case QED_DCBX_LOCAL_LLDP_MIB
:
749 rc
= qed_dcbx_read_local_lldp_mib(p_hwfn
, p_ptt
);
752 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
759 * Reconfigure QM and invoke PF update ramrod command if operational MIB
760 * change is detected.
763 qed_dcbx_mib_update_event(struct qed_hwfn
*p_hwfn
,
764 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
768 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
772 if (type
== QED_DCBX_OPERATIONAL_MIB
) {
773 rc
= qed_dcbx_process_mib_info(p_hwfn
);
775 /* reconfigure tcs of QM queues according
776 * to negotiation results
778 qed_qm_reconf(p_hwfn
, p_ptt
);
780 /* update storm FW with negotiation results */
781 qed_sp_pf_update(p_hwfn
);
788 int qed_dcbx_info_alloc(struct qed_hwfn
*p_hwfn
)
792 p_hwfn
->p_dcbx_info
= kzalloc(sizeof(*p_hwfn
->p_dcbx_info
), GFP_KERNEL
);
793 if (!p_hwfn
->p_dcbx_info
) {
795 "Failed to allocate 'struct qed_dcbx_info'\n");
802 void qed_dcbx_info_free(struct qed_hwfn
*p_hwfn
,
803 struct qed_dcbx_info
*p_dcbx_info
)
805 kfree(p_hwfn
->p_dcbx_info
);
808 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data
*p_data
,
809 struct qed_dcbx_results
*p_src
,
810 enum dcbx_protocol_type type
)
812 p_data
->dcb_enable_flag
= p_src
->arr
[type
].enable
;
813 p_data
->dcb_priority
= p_src
->arr
[type
].priority
;
814 p_data
->dcb_tc
= p_src
->arr
[type
].tc
;
817 /* Set pf update ramrod command params */
818 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results
*p_src
,
819 struct pf_update_ramrod_data
*p_dest
)
821 struct protocol_dcb_data
*p_dcb_data
;
822 bool update_flag
= false;
824 p_dest
->pf_id
= p_src
->pf_id
;
826 update_flag
= p_src
->arr
[DCBX_PROTOCOL_FCOE
].update
;
827 p_dest
->update_fcoe_dcb_data_flag
= update_flag
;
829 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
;
830 p_dest
->update_roce_dcb_data_flag
= update_flag
;
831 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
;
832 p_dest
->update_roce_dcb_data_flag
= update_flag
;
834 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ISCSI
].update
;
835 p_dest
->update_iscsi_dcb_data_flag
= update_flag
;
836 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ETH
].update
;
837 p_dest
->update_eth_dcb_data_flag
= update_flag
;
839 p_dcb_data
= &p_dest
->fcoe_dcb_data
;
840 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_FCOE
);
841 p_dcb_data
= &p_dest
->roce_dcb_data
;
843 if (p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
)
844 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
846 if (p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
)
847 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
848 DCBX_PROTOCOL_ROCE_V2
);
850 p_dcb_data
= &p_dest
->iscsi_dcb_data
;
851 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ISCSI
);
852 p_dcb_data
= &p_dest
->eth_dcb_data
;
853 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ETH
);
857 static int qed_dcbx_query_params(struct qed_hwfn
*p_hwfn
,
858 struct qed_dcbx_get
*p_get
,
859 enum qed_mib_read_type type
)
861 struct qed_ptt
*p_ptt
;
864 p_ptt
= qed_ptt_acquire(p_hwfn
);
868 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
872 rc
= qed_dcbx_get_params(p_hwfn
, p_ptt
, p_get
, type
);
875 qed_ptt_release(p_hwfn
, p_ptt
);
880 qed_dcbx_set_pfc_data(struct qed_hwfn
*p_hwfn
,
881 u32
*pfc
, struct qed_dcbx_params
*p_params
)
886 if (p_params
->pfc
.willing
)
887 *pfc
|= DCBX_PFC_WILLING_MASK
;
889 *pfc
&= ~DCBX_PFC_WILLING_MASK
;
891 if (p_params
->pfc
.enabled
)
892 *pfc
|= DCBX_PFC_ENABLED_MASK
;
894 *pfc
&= ~DCBX_PFC_ENABLED_MASK
;
896 *pfc
&= ~DCBX_PFC_CAPS_MASK
;
897 *pfc
|= (u32
)p_params
->pfc
.max_tc
<< DCBX_PFC_CAPS_SHIFT
;
899 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
900 if (p_params
->pfc
.prio
[i
])
903 *pfc
|= (pfc_map
<< DCBX_PFC_PRI_EN_BITMAP_SHIFT
);
905 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "pfc = 0x%x\n", *pfc
);
909 qed_dcbx_set_ets_data(struct qed_hwfn
*p_hwfn
,
910 struct dcbx_ets_feature
*p_ets
,
911 struct qed_dcbx_params
*p_params
)
913 u8
*bw_map
, *tsa_map
;
917 if (p_params
->ets_willing
)
918 p_ets
->flags
|= DCBX_ETS_WILLING_MASK
;
920 p_ets
->flags
&= ~DCBX_ETS_WILLING_MASK
;
922 if (p_params
->ets_cbs
)
923 p_ets
->flags
|= DCBX_ETS_CBS_MASK
;
925 p_ets
->flags
&= ~DCBX_ETS_CBS_MASK
;
927 if (p_params
->ets_enabled
)
928 p_ets
->flags
|= DCBX_ETS_ENABLED_MASK
;
930 p_ets
->flags
&= ~DCBX_ETS_ENABLED_MASK
;
932 p_ets
->flags
&= ~DCBX_ETS_MAX_TCS_MASK
;
933 p_ets
->flags
|= (u32
)p_params
->max_ets_tc
<< DCBX_ETS_MAX_TCS_SHIFT
;
935 bw_map
= (u8
*)&p_ets
->tc_bw_tbl
[0];
936 tsa_map
= (u8
*)&p_ets
->tc_tsa_tbl
[0];
937 p_ets
->pri_tc_tbl
[0] = 0;
938 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
939 bw_map
[i
] = p_params
->ets_tc_bw_tbl
[i
];
940 tsa_map
[i
] = p_params
->ets_tc_tsa_tbl
[i
];
941 /* Copy the priority value to the corresponding 4 bits in the
942 * traffic class table.
944 val
= (((u32
)p_params
->ets_pri_tc_tbl
[i
]) << ((7 - i
) * 4));
945 p_ets
->pri_tc_tbl
[0] |= val
;
947 p_ets
->pri_tc_tbl
[0] = cpu_to_be32(p_ets
->pri_tc_tbl
[0]);
948 for (i
= 0; i
< 2; i
++) {
949 p_ets
->tc_bw_tbl
[i
] = cpu_to_be32(p_ets
->tc_bw_tbl
[i
]);
950 p_ets
->tc_tsa_tbl
[i
] = cpu_to_be32(p_ets
->tc_tsa_tbl
[i
]);
955 qed_dcbx_set_app_data(struct qed_hwfn
*p_hwfn
,
956 struct dcbx_app_priority_feature
*p_app
,
957 struct qed_dcbx_params
*p_params
)
962 if (p_params
->app_willing
)
963 p_app
->flags
|= DCBX_APP_WILLING_MASK
;
965 p_app
->flags
&= ~DCBX_APP_WILLING_MASK
;
967 if (p_params
->app_valid
)
968 p_app
->flags
|= DCBX_APP_ENABLED_MASK
;
970 p_app
->flags
&= ~DCBX_APP_ENABLED_MASK
;
972 p_app
->flags
&= ~DCBX_APP_NUM_ENTRIES_MASK
;
973 p_app
->flags
|= (u32
)p_params
->num_app_entries
<<
974 DCBX_APP_NUM_ENTRIES_SHIFT
;
976 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
977 entry
= &p_app
->app_pri_tbl
[i
].entry
;
978 *entry
&= ~DCBX_APP_SF_MASK
;
979 if (p_params
->app_entry
[i
].ethtype
)
980 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
983 *entry
|= ((u32
)DCBX_APP_SF_PORT
<< DCBX_APP_SF_SHIFT
);
984 *entry
&= ~DCBX_APP_PROTOCOL_ID_MASK
;
985 *entry
|= ((u32
)p_params
->app_entry
[i
].proto_id
<<
986 DCBX_APP_PROTOCOL_ID_SHIFT
);
987 *entry
&= ~DCBX_APP_PRI_MAP_MASK
;
988 *entry
|= ((u32
)(p_params
->app_entry
[i
].prio
) <<
989 DCBX_APP_PRI_MAP_SHIFT
);
994 qed_dcbx_set_local_params(struct qed_hwfn
*p_hwfn
,
995 struct dcbx_local_params
*local_admin
,
996 struct qed_dcbx_set
*params
)
998 local_admin
->flags
= 0;
999 memcpy(&local_admin
->features
,
1000 &p_hwfn
->p_dcbx_info
->operational
.features
,
1001 sizeof(local_admin
->features
));
1003 if (params
->enabled
)
1004 local_admin
->config
= params
->ver_num
;
1006 local_admin
->config
= DCBX_CONFIG_VERSION_DISABLED
;
1008 if (params
->override_flags
& QED_DCBX_OVERRIDE_PFC_CFG
)
1009 qed_dcbx_set_pfc_data(p_hwfn
, &local_admin
->features
.pfc
,
1010 ¶ms
->config
.params
);
1012 if (params
->override_flags
& QED_DCBX_OVERRIDE_ETS_CFG
)
1013 qed_dcbx_set_ets_data(p_hwfn
, &local_admin
->features
.ets
,
1014 ¶ms
->config
.params
);
1016 if (params
->override_flags
& QED_DCBX_OVERRIDE_APP_CFG
)
1017 qed_dcbx_set_app_data(p_hwfn
, &local_admin
->features
.app
,
1018 ¶ms
->config
.params
);
1021 int qed_dcbx_config_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
1022 struct qed_dcbx_set
*params
, bool hw_commit
)
1024 struct dcbx_local_params local_admin
;
1025 struct qed_dcbx_mib_meta_data data
;
1026 u32 resp
= 0, param
= 0;
1030 memcpy(&p_hwfn
->p_dcbx_info
->set
, params
,
1031 sizeof(struct qed_dcbx_set
));
1035 /* clear set-parmas cache */
1036 memset(&p_hwfn
->p_dcbx_info
->set
, 0, sizeof(p_hwfn
->p_dcbx_info
->set
));
1038 memset(&local_admin
, 0, sizeof(local_admin
));
1039 qed_dcbx_set_local_params(p_hwfn
, &local_admin
, params
);
1041 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1042 offsetof(struct public_port
, local_admin_dcbx_mib
);
1043 data
.local_admin
= &local_admin
;
1044 data
.size
= sizeof(struct dcbx_local_params
);
1045 qed_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.local_admin
, data
.size
);
1047 rc
= qed_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_DCBX
,
1048 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT
, &resp
, ¶m
);
1050 DP_NOTICE(p_hwfn
, "Failed to send DCBX update request\n");
1055 int qed_dcbx_get_config_params(struct qed_hwfn
*p_hwfn
,
1056 struct qed_dcbx_set
*params
)
1058 struct qed_dcbx_get
*dcbx_info
;
1061 if (p_hwfn
->p_dcbx_info
->set
.config
.valid
) {
1062 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
,
1063 sizeof(struct qed_dcbx_set
));
1067 dcbx_info
= kmalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1069 DP_ERR(p_hwfn
, "Failed to allocate struct qed_dcbx_info\n");
1073 rc
= qed_dcbx_query_params(p_hwfn
, dcbx_info
, QED_DCBX_OPERATIONAL_MIB
);
1079 p_hwfn
->p_dcbx_info
->set
.override_flags
= 0;
1080 p_hwfn
->p_dcbx_info
->set
.ver_num
= DCBX_CONFIG_VERSION_DISABLED
;
1081 if (dcbx_info
->operational
.cee
)
1082 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1083 if (dcbx_info
->operational
.ieee
)
1084 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1086 p_hwfn
->p_dcbx_info
->set
.enabled
= dcbx_info
->operational
.enabled
;
1087 memcpy(&p_hwfn
->p_dcbx_info
->set
.config
.params
,
1088 &dcbx_info
->operational
.params
,
1089 sizeof(struct qed_dcbx_admin_params
));
1090 p_hwfn
->p_dcbx_info
->set
.config
.valid
= true;
1092 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
, sizeof(struct qed_dcbx_set
));
1099 static struct qed_dcbx_get
*qed_dcbnl_get_dcbx(struct qed_hwfn
*hwfn
,
1100 enum qed_mib_read_type type
)
1102 struct qed_dcbx_get
*dcbx_info
;
1104 dcbx_info
= kmalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1106 DP_ERR(hwfn
->cdev
, "Failed to allocate memory for dcbx_info\n");
1110 if (qed_dcbx_query_params(hwfn
, dcbx_info
, type
)) {
1115 if ((type
== QED_DCBX_OPERATIONAL_MIB
) &&
1116 !dcbx_info
->operational
.enabled
) {
1117 DP_INFO(hwfn
, "DCBX is not enabled/operational\n");
1125 static u8
qed_dcbnl_getstate(struct qed_dev
*cdev
)
1127 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1128 struct qed_dcbx_get
*dcbx_info
;
1131 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1135 enabled
= dcbx_info
->operational
.enabled
;
1136 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", enabled
);
1142 static u8
qed_dcbnl_setstate(struct qed_dev
*cdev
, u8 state
)
1144 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1145 struct qed_dcbx_set dcbx_set
;
1146 struct qed_ptt
*ptt
;
1149 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", state
);
1151 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1152 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1156 dcbx_set
.enabled
= !!state
;
1158 ptt
= qed_ptt_acquire(hwfn
);
1162 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1164 qed_ptt_release(hwfn
, ptt
);
1169 static void qed_dcbnl_getpgtccfgtx(struct qed_dev
*cdev
, int tc
, u8
*prio_type
,
1170 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1172 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1173 struct qed_dcbx_get
*dcbx_info
;
1175 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tc = %d\n", tc
);
1176 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1177 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1178 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1182 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1186 *pgid
= dcbx_info
->operational
.params
.ets_pri_tc_tbl
[tc
];
1190 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8
*bw_pct
)
1192 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1193 struct qed_dcbx_get
*dcbx_info
;
1196 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d\n", pgid
);
1197 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1198 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1202 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1206 *bw_pct
= dcbx_info
->operational
.params
.ets_tc_bw_tbl
[pgid
];
1207 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "bw_pct = %d\n", *bw_pct
);
1211 static void qed_dcbnl_getpgtccfgrx(struct qed_dev
*cdev
, int tc
, u8
*prio
,
1212 u8
*bwg_id
, u8
*bw_pct
, u8
*up_map
)
1214 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1215 *prio
= *bwg_id
= *bw_pct
= *up_map
= 0;
1218 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev
*cdev
,
1219 int bwg_id
, u8
*bw_pct
)
1221 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1225 static void qed_dcbnl_getpfccfg(struct qed_dev
*cdev
,
1226 int priority
, u8
*setting
)
1228 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1229 struct qed_dcbx_get
*dcbx_info
;
1231 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d\n", priority
);
1232 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1233 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1237 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1241 *setting
= dcbx_info
->operational
.params
.pfc
.prio
[priority
];
1242 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "setting = %d\n", *setting
);
1246 static void qed_dcbnl_setpfccfg(struct qed_dev
*cdev
, int priority
, u8 setting
)
1248 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1249 struct qed_dcbx_set dcbx_set
;
1250 struct qed_ptt
*ptt
;
1253 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d setting = %d\n",
1255 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1256 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1260 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1261 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1265 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1266 dcbx_set
.config
.params
.pfc
.prio
[priority
] = !!setting
;
1268 ptt
= qed_ptt_acquire(hwfn
);
1272 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1274 qed_ptt_release(hwfn
, ptt
);
1277 static u8
qed_dcbnl_getcap(struct qed_dev
*cdev
, int capid
, u8
*cap
)
1279 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1280 struct qed_dcbx_get
*dcbx_info
;
1283 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "capid = %d\n", capid
);
1284 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1289 case DCB_CAP_ATTR_PG
:
1290 case DCB_CAP_ATTR_PFC
:
1291 case DCB_CAP_ATTR_UP2TC
:
1292 case DCB_CAP_ATTR_GSP
:
1295 case DCB_CAP_ATTR_PG_TCS
:
1296 case DCB_CAP_ATTR_PFC_TCS
:
1299 case DCB_CAP_ATTR_DCBX
:
1300 *cap
= (DCB_CAP_DCBX_LLD_MANAGED
| DCB_CAP_DCBX_VER_CEE
|
1301 DCB_CAP_DCBX_VER_IEEE
);
1308 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "id = %d caps = %d\n", capid
, *cap
);
1314 static int qed_dcbnl_getnumtcs(struct qed_dev
*cdev
, int tcid
, u8
*num
)
1316 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1317 struct qed_dcbx_get
*dcbx_info
;
1320 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d\n", tcid
);
1321 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1326 case DCB_NUMTCS_ATTR_PG
:
1327 *num
= dcbx_info
->operational
.params
.max_ets_tc
;
1329 case DCB_NUMTCS_ATTR_PFC
:
1330 *num
= dcbx_info
->operational
.params
.pfc
.max_tc
;
1337 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "numtcs = %d\n", *num
);
1342 static u8
qed_dcbnl_getpfcstate(struct qed_dev
*cdev
)
1344 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1345 struct qed_dcbx_get
*dcbx_info
;
1348 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1352 enabled
= dcbx_info
->operational
.params
.pfc
.enabled
;
1353 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d\n", enabled
);
1359 static u8
qed_dcbnl_getdcbx(struct qed_dev
*cdev
)
1361 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1362 struct qed_dcbx_get
*dcbx_info
;
1365 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1369 if (dcbx_info
->operational
.enabled
)
1370 mode
|= DCB_CAP_DCBX_LLD_MANAGED
;
1371 if (dcbx_info
->operational
.ieee
)
1372 mode
|= DCB_CAP_DCBX_VER_IEEE
;
1373 if (dcbx_info
->operational
.cee
)
1374 mode
|= DCB_CAP_DCBX_VER_CEE
;
1376 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "dcb mode = %d\n", mode
);
1382 static void qed_dcbnl_setpgtccfgtx(struct qed_dev
*cdev
,
1384 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1386 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1387 struct qed_dcbx_set dcbx_set
;
1388 struct qed_ptt
*ptt
;
1391 DP_VERBOSE(hwfn
, QED_MSG_DCB
,
1392 "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n",
1393 tc
, pri_type
, pgid
, bw_pct
, up_map
);
1395 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1396 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1400 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1401 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1405 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1406 dcbx_set
.config
.params
.ets_pri_tc_tbl
[tc
] = pgid
;
1408 ptt
= qed_ptt_acquire(hwfn
);
1412 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1414 qed_ptt_release(hwfn
, ptt
);
1417 static void qed_dcbnl_setpgtccfgrx(struct qed_dev
*cdev
, int prio
,
1418 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1420 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1423 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1425 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1426 struct qed_dcbx_set dcbx_set
;
1427 struct qed_ptt
*ptt
;
1430 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d bw_pct = %d\n", pgid
, bw_pct
);
1431 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1432 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1436 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1437 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1441 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1442 dcbx_set
.config
.params
.ets_tc_bw_tbl
[pgid
] = bw_pct
;
1444 ptt
= qed_ptt_acquire(hwfn
);
1448 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1450 qed_ptt_release(hwfn
, ptt
);
1453 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1455 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1458 static u8
qed_dcbnl_setall(struct qed_dev
*cdev
)
1460 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1461 struct qed_dcbx_set dcbx_set
;
1462 struct qed_ptt
*ptt
;
1465 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1466 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1470 ptt
= qed_ptt_acquire(hwfn
);
1474 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 1);
1476 qed_ptt_release(hwfn
, ptt
);
1481 static int qed_dcbnl_setnumtcs(struct qed_dev
*cdev
, int tcid
, u8 num
)
1483 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1484 struct qed_dcbx_set dcbx_set
;
1485 struct qed_ptt
*ptt
;
1488 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d num = %d\n", tcid
, num
);
1489 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1490 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1495 case DCB_NUMTCS_ATTR_PG
:
1496 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1497 dcbx_set
.config
.params
.max_ets_tc
= num
;
1499 case DCB_NUMTCS_ATTR_PFC
:
1500 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1501 dcbx_set
.config
.params
.pfc
.max_tc
= num
;
1504 DP_INFO(hwfn
, "Invalid tcid %d\n", tcid
);
1508 ptt
= qed_ptt_acquire(hwfn
);
1512 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1514 qed_ptt_release(hwfn
, ptt
);
1519 static void qed_dcbnl_setpfcstate(struct qed_dev
*cdev
, u8 state
)
1521 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1522 struct qed_dcbx_set dcbx_set
;
1523 struct qed_ptt
*ptt
;
1526 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new state = %d\n", state
);
1528 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1529 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1533 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1534 dcbx_set
.config
.params
.pfc
.enabled
= !!state
;
1536 ptt
= qed_ptt_acquire(hwfn
);
1540 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1542 qed_ptt_release(hwfn
, ptt
);
1545 static int qed_dcbnl_getapp(struct qed_dev
*cdev
, u8 idtype
, u16 idval
)
1547 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1548 struct qed_dcbx_get
*dcbx_info
;
1549 struct qed_app_entry
*entry
;
1554 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1558 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1559 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1560 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
1561 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
)) {
1567 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1568 DP_ERR(cdev
, "App entry (%d, %d) not found\n", idtype
, idval
);
1578 static int qed_dcbnl_setapp(struct qed_dev
*cdev
,
1579 u8 idtype
, u16 idval
, u8 pri_map
)
1581 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1582 struct qed_dcbx_set dcbx_set
;
1583 struct qed_app_entry
*entry
;
1584 struct qed_ptt
*ptt
;
1588 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1589 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1593 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1594 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1595 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
1596 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
))
1598 /* First empty slot */
1599 if (!entry
->proto_id
)
1603 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1604 DP_ERR(cdev
, "App table is full\n");
1608 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1609 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
1610 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= idval
;
1611 dcbx_set
.config
.params
.app_entry
[i
].prio
= pri_map
;
1613 ptt
= qed_ptt_acquire(hwfn
);
1617 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1619 qed_ptt_release(hwfn
, ptt
);
1624 static u8
qed_dcbnl_setdcbx(struct qed_dev
*cdev
, u8 mode
)
1626 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1627 struct qed_dcbx_set dcbx_set
;
1628 struct qed_ptt
*ptt
;
1631 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new mode = %x\n", mode
);
1633 if (!(mode
& DCB_CAP_DCBX_VER_IEEE
) && !(mode
& DCB_CAP_DCBX_VER_CEE
)) {
1634 DP_INFO(hwfn
, "Allowed mode is cee, ieee or both\n");
1638 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1639 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1643 dcbx_set
.ver_num
= 0;
1644 if (mode
& DCB_CAP_DCBX_VER_CEE
) {
1645 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1646 dcbx_set
.enabled
= true;
1649 if (mode
& DCB_CAP_DCBX_VER_IEEE
) {
1650 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1651 dcbx_set
.enabled
= true;
1654 ptt
= qed_ptt_acquire(hwfn
);
1658 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1660 qed_ptt_release(hwfn
, ptt
);
1665 static u8
qed_dcbnl_getfeatcfg(struct qed_dev
*cdev
, int featid
, u8
*flags
)
1667 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1668 struct qed_dcbx_get
*dcbx_info
;
1670 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "Feature id = %d\n", featid
);
1671 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1677 case DCB_FEATCFG_ATTR_PG
:
1678 if (dcbx_info
->operational
.params
.ets_enabled
)
1679 *flags
= DCB_FEATCFG_ENABLE
;
1681 *flags
= DCB_FEATCFG_ERROR
;
1683 case DCB_FEATCFG_ATTR_PFC
:
1684 if (dcbx_info
->operational
.params
.pfc
.enabled
)
1685 *flags
= DCB_FEATCFG_ENABLE
;
1687 *flags
= DCB_FEATCFG_ERROR
;
1689 case DCB_FEATCFG_ATTR_APP
:
1690 if (dcbx_info
->operational
.params
.app_valid
)
1691 *flags
= DCB_FEATCFG_ENABLE
;
1693 *flags
= DCB_FEATCFG_ERROR
;
1696 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1701 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "flags = %d\n", *flags
);
1707 static u8
qed_dcbnl_setfeatcfg(struct qed_dev
*cdev
, int featid
, u8 flags
)
1709 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1710 struct qed_dcbx_set dcbx_set
;
1711 bool enabled
, willing
;
1712 struct qed_ptt
*ptt
;
1715 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "featid = %d flags = %d\n",
1717 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1718 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1722 enabled
= !!(flags
& DCB_FEATCFG_ENABLE
);
1723 willing
= !!(flags
& DCB_FEATCFG_WILLING
);
1725 case DCB_FEATCFG_ATTR_PG
:
1726 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1727 dcbx_set
.config
.params
.ets_enabled
= enabled
;
1728 dcbx_set
.config
.params
.ets_willing
= willing
;
1730 case DCB_FEATCFG_ATTR_PFC
:
1731 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1732 dcbx_set
.config
.params
.pfc
.enabled
= enabled
;
1733 dcbx_set
.config
.params
.pfc
.willing
= willing
;
1735 case DCB_FEATCFG_ATTR_APP
:
1736 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1737 dcbx_set
.config
.params
.app_willing
= willing
;
1740 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1744 ptt
= qed_ptt_acquire(hwfn
);
1748 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1750 qed_ptt_release(hwfn
, ptt
);
1755 static int qed_dcbnl_peer_getappinfo(struct qed_dev
*cdev
,
1756 struct dcb_peer_app_info
*info
,
1759 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1760 struct qed_dcbx_get
*dcbx_info
;
1762 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1766 info
->willing
= dcbx_info
->remote
.params
.app_willing
;
1767 info
->error
= dcbx_info
->remote
.params
.app_error
;
1768 *app_count
= dcbx_info
->remote
.params
.num_app_entries
;
1774 static int qed_dcbnl_peer_getapptable(struct qed_dev
*cdev
,
1775 struct dcb_app
*table
)
1777 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1778 struct qed_dcbx_get
*dcbx_info
;
1781 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1785 for (i
= 0; i
< dcbx_info
->remote
.params
.num_app_entries
; i
++) {
1786 if (dcbx_info
->remote
.params
.app_entry
[i
].ethtype
)
1787 table
[i
].selector
= DCB_APP_IDTYPE_ETHTYPE
;
1789 table
[i
].selector
= DCB_APP_IDTYPE_PORTNUM
;
1790 table
[i
].priority
= dcbx_info
->remote
.params
.app_entry
[i
].prio
;
1792 dcbx_info
->remote
.params
.app_entry
[i
].proto_id
;
1800 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev
*cdev
, struct cee_pfc
*pfc
)
1802 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1803 struct qed_dcbx_get
*dcbx_info
;
1806 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1810 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1811 if (dcbx_info
->remote
.params
.pfc
.prio
[i
])
1812 pfc
->pfc_en
|= BIT(i
);
1814 pfc
->tcs_supported
= dcbx_info
->remote
.params
.pfc
.max_tc
;
1815 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d tcs_supported = %d\n",
1816 pfc
->pfc_en
, pfc
->tcs_supported
);
1822 static int qed_dcbnl_cee_peer_getpg(struct qed_dev
*cdev
, struct cee_pg
*pg
)
1824 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1825 struct qed_dcbx_get
*dcbx_info
;
1828 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1832 pg
->willing
= dcbx_info
->remote
.params
.ets_willing
;
1833 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1834 pg
->pg_bw
[i
] = dcbx_info
->remote
.params
.ets_tc_bw_tbl
[i
];
1835 pg
->prio_pg
[i
] = dcbx_info
->remote
.params
.ets_pri_tc_tbl
[i
];
1838 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "willing = %d", pg
->willing
);
1844 static int qed_dcbnl_get_ieee_pfc(struct qed_dev
*cdev
,
1845 struct ieee_pfc
*pfc
, bool remote
)
1847 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1848 struct qed_dcbx_params
*params
;
1849 struct qed_dcbx_get
*dcbx_info
;
1852 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1856 if (!dcbx_info
->operational
.ieee
) {
1857 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1862 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1863 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
1864 QED_DCBX_REMOTE_MIB
);
1870 params
= &dcbx_info
->remote
.params
;
1872 params
= &dcbx_info
->operational
.params
;
1875 pfc
->pfc_cap
= params
->pfc
.max_tc
;
1877 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1878 if (params
->pfc
.prio
[i
])
1879 pfc
->pfc_en
|= BIT(i
);
1886 static int qed_dcbnl_ieee_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
1888 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, false);
1891 static int qed_dcbnl_ieee_setpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
1893 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1894 struct qed_dcbx_get
*dcbx_info
;
1895 struct qed_dcbx_set dcbx_set
;
1896 struct qed_ptt
*ptt
;
1899 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1903 if (!dcbx_info
->operational
.ieee
) {
1904 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1911 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1912 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1916 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1917 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1918 dcbx_set
.config
.params
.pfc
.prio
[i
] = !!(pfc
->pfc_en
& BIT(i
));
1920 ptt
= qed_ptt_acquire(hwfn
);
1924 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1926 qed_ptt_release(hwfn
, ptt
);
1931 static int qed_dcbnl_get_ieee_ets(struct qed_dev
*cdev
,
1932 struct ieee_ets
*ets
, bool remote
)
1934 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1935 struct qed_dcbx_get
*dcbx_info
;
1936 struct qed_dcbx_params
*params
;
1939 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1943 if (!dcbx_info
->operational
.ieee
) {
1944 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1950 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1951 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
1952 QED_DCBX_REMOTE_MIB
);
1958 params
= &dcbx_info
->remote
.params
;
1960 params
= &dcbx_info
->operational
.params
;
1963 ets
->ets_cap
= params
->max_ets_tc
;
1964 ets
->willing
= params
->ets_willing
;
1965 ets
->cbs
= params
->ets_cbs
;
1966 memcpy(ets
->tc_tx_bw
, params
->ets_tc_bw_tbl
, sizeof(ets
->tc_tx_bw
));
1967 memcpy(ets
->tc_tsa
, params
->ets_tc_tsa_tbl
, sizeof(ets
->tc_tsa
));
1968 memcpy(ets
->prio_tc
, params
->ets_pri_tc_tbl
, sizeof(ets
->prio_tc
));
1974 static int qed_dcbnl_ieee_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
1976 return qed_dcbnl_get_ieee_ets(cdev
, ets
, false);
1979 static int qed_dcbnl_ieee_setets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
1981 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1982 struct qed_dcbx_get
*dcbx_info
;
1983 struct qed_dcbx_set dcbx_set
;
1984 struct qed_ptt
*ptt
;
1987 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1991 if (!dcbx_info
->operational
.ieee
) {
1992 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
1999 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2000 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2004 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
2005 dcbx_set
.config
.params
.max_ets_tc
= ets
->ets_cap
;
2006 dcbx_set
.config
.params
.ets_willing
= ets
->willing
;
2007 dcbx_set
.config
.params
.ets_cbs
= ets
->cbs
;
2008 memcpy(dcbx_set
.config
.params
.ets_tc_bw_tbl
, ets
->tc_tx_bw
,
2009 sizeof(ets
->tc_tx_bw
));
2010 memcpy(dcbx_set
.config
.params
.ets_tc_tsa_tbl
, ets
->tc_tsa
,
2011 sizeof(ets
->tc_tsa
));
2012 memcpy(dcbx_set
.config
.params
.ets_pri_tc_tbl
, ets
->prio_tc
,
2013 sizeof(ets
->prio_tc
));
2015 ptt
= qed_ptt_acquire(hwfn
);
2019 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2021 qed_ptt_release(hwfn
, ptt
);
2026 int qed_dcbnl_ieee_peer_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2028 return qed_dcbnl_get_ieee_ets(cdev
, ets
, true);
2031 int qed_dcbnl_ieee_peer_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2033 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, true);
2036 int qed_dcbnl_ieee_getapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2038 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2039 struct qed_dcbx_get
*dcbx_info
;
2040 struct qed_app_entry
*entry
;
2045 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2049 if (!dcbx_info
->operational
.ieee
) {
2050 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2055 /* ieee defines the selector field value for ethertype to be 1 */
2056 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2057 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2058 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
2059 if ((entry
->ethtype
== ethtype
) &&
2060 (entry
->proto_id
== app
->protocol
)) {
2066 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2067 DP_ERR(cdev
, "App entry (%d, %d) not found\n", app
->selector
,
2073 app
->priority
= ffs(prio
) - 1;
2080 int qed_dcbnl_ieee_setapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2082 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2083 struct qed_dcbx_get
*dcbx_info
;
2084 struct qed_dcbx_set dcbx_set
;
2085 struct qed_app_entry
*entry
;
2086 struct qed_ptt
*ptt
;
2090 if (app
->priority
< 0 || app
->priority
>= QED_MAX_PFC_PRIORITIES
) {
2091 DP_INFO(hwfn
, "Invalid priority %d\n", app
->priority
);
2095 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2099 if (!dcbx_info
->operational
.ieee
) {
2100 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2107 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2108 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2112 /* ieee defines the selector field value for ethertype to be 1 */
2113 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2114 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2115 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
2116 if ((entry
->ethtype
== ethtype
) &&
2117 (entry
->proto_id
== app
->protocol
))
2119 /* First empty slot */
2120 if (!entry
->proto_id
)
2124 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2125 DP_ERR(cdev
, "App table is full\n");
2129 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
2130 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
2131 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= app
->protocol
;
2132 dcbx_set
.config
.params
.app_entry
[i
].prio
= BIT(app
->priority
);
2134 ptt
= qed_ptt_acquire(hwfn
);
2138 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2140 qed_ptt_release(hwfn
, ptt
);
2145 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass
= {
2146 .getstate
= qed_dcbnl_getstate
,
2147 .setstate
= qed_dcbnl_setstate
,
2148 .getpgtccfgtx
= qed_dcbnl_getpgtccfgtx
,
2149 .getpgbwgcfgtx
= qed_dcbnl_getpgbwgcfgtx
,
2150 .getpgtccfgrx
= qed_dcbnl_getpgtccfgrx
,
2151 .getpgbwgcfgrx
= qed_dcbnl_getpgbwgcfgrx
,
2152 .getpfccfg
= qed_dcbnl_getpfccfg
,
2153 .setpfccfg
= qed_dcbnl_setpfccfg
,
2154 .getcap
= qed_dcbnl_getcap
,
2155 .getnumtcs
= qed_dcbnl_getnumtcs
,
2156 .getpfcstate
= qed_dcbnl_getpfcstate
,
2157 .getdcbx
= qed_dcbnl_getdcbx
,
2158 .setpgtccfgtx
= qed_dcbnl_setpgtccfgtx
,
2159 .setpgtccfgrx
= qed_dcbnl_setpgtccfgrx
,
2160 .setpgbwgcfgtx
= qed_dcbnl_setpgbwgcfgtx
,
2161 .setpgbwgcfgrx
= qed_dcbnl_setpgbwgcfgrx
,
2162 .setall
= qed_dcbnl_setall
,
2163 .setnumtcs
= qed_dcbnl_setnumtcs
,
2164 .setpfcstate
= qed_dcbnl_setpfcstate
,
2165 .setapp
= qed_dcbnl_setapp
,
2166 .setdcbx
= qed_dcbnl_setdcbx
,
2167 .setfeatcfg
= qed_dcbnl_setfeatcfg
,
2168 .getfeatcfg
= qed_dcbnl_getfeatcfg
,
2169 .getapp
= qed_dcbnl_getapp
,
2170 .peer_getappinfo
= qed_dcbnl_peer_getappinfo
,
2171 .peer_getapptable
= qed_dcbnl_peer_getapptable
,
2172 .cee_peer_getpfc
= qed_dcbnl_cee_peer_getpfc
,
2173 .cee_peer_getpg
= qed_dcbnl_cee_peer_getpg
,
2174 .ieee_getpfc
= qed_dcbnl_ieee_getpfc
,
2175 .ieee_setpfc
= qed_dcbnl_ieee_setpfc
,
2176 .ieee_getets
= qed_dcbnl_ieee_getets
,
2177 .ieee_setets
= qed_dcbnl_ieee_setets
,
2178 .ieee_peer_getpfc
= qed_dcbnl_ieee_peer_getpfc
,
2179 .ieee_peer_getets
= qed_dcbnl_ieee_peer_getets
,
2180 .ieee_getapp
= qed_dcbnl_ieee_getapp
,
2181 .ieee_setapp
= qed_dcbnl_ieee_setapp
,