1 /* QLogic qed NIC Driver
2 * Copyright (c) 2015-2017 QLogic Corporation
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and /or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <linux/types.h>
34 #include <asm/byteorder.h>
35 #include <linux/bitops.h>
36 #include <linux/dcbnl.h>
37 #include <linux/errno.h>
38 #include <linux/kernel.h>
39 #include <linux/slab.h>
40 #include <linux/string.h>
46 #include "qed_sriov.h"
48 #include <linux/qed/qed_eth_if.h>
51 #define QED_DCBX_MAX_MIB_READ_TRY (100)
52 #define QED_ETH_TYPE_DEFAULT (0)
53 #define QED_ETH_TYPE_ROCE (0x8915)
54 #define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7)
55 #define QED_ETH_TYPE_FCOE (0x8906)
56 #define QED_TCP_PORT_ISCSI (0xCBC)
58 #define QED_DCBX_INVALID_PRIORITY 0xFF
60 /* Get Traffic Class from priority traffic class table, 4 bits represent
61 * the traffic class corresponding to the priority.
63 #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \
64 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
66 static const struct qed_dcbx_app_metadata qed_dcbx_app_update
[] = {
67 {DCBX_PROTOCOL_ISCSI
, "ISCSI", QED_PCI_ISCSI
},
68 {DCBX_PROTOCOL_FCOE
, "FCOE", QED_PCI_FCOE
},
69 {DCBX_PROTOCOL_ROCE
, "ROCE", QED_PCI_ETH_ROCE
},
70 {DCBX_PROTOCOL_ROCE_V2
, "ROCE_V2", QED_PCI_ETH_ROCE
},
71 {DCBX_PROTOCOL_ETH
, "ETH", QED_PCI_ETH
},
74 static bool qed_dcbx_app_ethtype(u32 app_info_bitmap
)
76 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
80 static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap
)
82 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
85 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
86 return qed_dcbx_app_ethtype(app_info_bitmap
);
88 return !!(mfw_val
== DCBX_APP_SF_IEEE_ETHTYPE
);
91 static bool qed_dcbx_app_port(u32 app_info_bitmap
)
93 return !!(QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
97 static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap
, u8 type
)
99 u8 mfw_val
= QED_MFW_GET_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
102 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
103 return qed_dcbx_app_port(app_info_bitmap
);
105 return !!(mfw_val
== type
|| mfw_val
== DCBX_APP_SF_IEEE_TCP_UDP_PORT
);
108 static bool qed_dcbx_default_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
113 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
115 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
117 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_DEFAULT
));
120 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
125 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
126 DCBX_APP_SF_IEEE_TCP_PORT
);
128 port
= qed_dcbx_app_port(app_info_bitmap
);
130 return !!(port
&& (proto_id
== QED_TCP_PORT_ISCSI
));
133 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
138 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
140 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
142 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_FCOE
));
145 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
150 ethtype
= qed_dcbx_ieee_app_ethtype(app_info_bitmap
);
152 ethtype
= qed_dcbx_app_ethtype(app_info_bitmap
);
154 return !!(ethtype
&& (proto_id
== QED_ETH_TYPE_ROCE
));
157 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
162 port
= qed_dcbx_ieee_app_port(app_info_bitmap
,
163 DCBX_APP_SF_IEEE_UDP_PORT
);
165 port
= qed_dcbx_app_port(app_info_bitmap
);
167 return !!(port
&& (proto_id
== QED_UDP_PORT_TYPE_ROCE_V2
));
171 qed_dcbx_dp_protocol(struct qed_hwfn
*p_hwfn
, struct qed_dcbx_results
*p_data
)
173 enum dcbx_protocol_type id
;
176 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "DCBX negotiated: %d\n",
177 p_data
->dcbx_enabled
);
179 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
180 id
= qed_dcbx_app_update
[i
].id
;
182 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
183 "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
184 qed_dcbx_app_update
[i
].name
, p_data
->arr
[id
].update
,
185 p_data
->arr
[id
].enable
, p_data
->arr
[id
].priority
,
186 p_data
->arr
[id
].tc
, p_hwfn
->hw_info
.num_tc
);
191 qed_dcbx_set_params(struct qed_dcbx_results
*p_data
,
192 struct qed_hw_info
*p_info
,
197 enum dcbx_protocol_type type
,
198 enum qed_pci_personality personality
)
200 /* PF update ramrod data */
201 p_data
->arr
[type
].update
= update
;
202 p_data
->arr
[type
].enable
= enable
;
203 p_data
->arr
[type
].priority
= prio
;
204 p_data
->arr
[type
].tc
= tc
;
207 if (p_info
->personality
== personality
) {
208 if (personality
== QED_PCI_ETH
)
209 p_info
->non_offload_tc
= tc
;
211 p_info
->offload_tc
= tc
;
215 /* Update app protocol data and hw_info fields with the TLV info */
217 qed_dcbx_update_app_info(struct qed_dcbx_results
*p_data
,
218 struct qed_hwfn
*p_hwfn
,
221 u8 prio
, u8 tc
, enum dcbx_protocol_type type
)
223 struct qed_hw_info
*p_info
= &p_hwfn
->hw_info
;
224 enum qed_pci_personality personality
;
225 enum dcbx_protocol_type id
;
229 for (i
= 0; i
< ARRAY_SIZE(qed_dcbx_app_update
); i
++) {
230 id
= qed_dcbx_app_update
[i
].id
;
235 personality
= qed_dcbx_app_update
[i
].personality
;
236 name
= qed_dcbx_app_update
[i
].name
;
238 qed_dcbx_set_params(p_data
, p_info
, enable
, update
,
239 prio
, tc
, type
, personality
);
244 qed_dcbx_get_app_protocol_type(struct qed_hwfn
*p_hwfn
,
246 u16 id
, enum dcbx_protocol_type
*type
, bool ieee
)
248 if (qed_dcbx_fcoe_tlv(app_prio_bitmap
, id
, ieee
)) {
249 *type
= DCBX_PROTOCOL_FCOE
;
250 } else if (qed_dcbx_roce_tlv(app_prio_bitmap
, id
, ieee
)) {
251 *type
= DCBX_PROTOCOL_ROCE
;
252 } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap
, id
, ieee
)) {
253 *type
= DCBX_PROTOCOL_ISCSI
;
254 } else if (qed_dcbx_default_tlv(app_prio_bitmap
, id
, ieee
)) {
255 *type
= DCBX_PROTOCOL_ETH
;
256 } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap
, id
, ieee
)) {
257 *type
= DCBX_PROTOCOL_ROCE_V2
;
259 *type
= DCBX_MAX_PROTOCOL_TYPE
;
261 "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
262 id
, app_prio_bitmap
);
269 /* Parse app TLV's to update TC information in hw_info structure for
270 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
273 qed_dcbx_process_tlv(struct qed_hwfn
*p_hwfn
,
274 struct qed_dcbx_results
*p_data
,
275 struct dcbx_app_priority_entry
*p_tbl
,
276 u32 pri_tc_tbl
, int count
, u8 dcbx_version
)
279 enum dcbx_protocol_type type
;
285 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Num APP entries = %d\n", count
);
287 ieee
= (dcbx_version
== DCBX_CONFIG_VERSION_IEEE
);
289 for (i
= 0; i
< count
; i
++) {
290 protocol_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
291 DCBX_APP_PROTOCOL_ID
);
292 priority_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
294 priority
= ffs(priority_map
) - 1;
296 DP_ERR(p_hwfn
, "Invalid priority\n");
300 tc
= QED_DCBX_PRIO2TC(pri_tc_tbl
, priority
);
301 if (qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
302 protocol_id
, &type
, ieee
)) {
303 /* ETH always have the enable bit reset, as it gets
304 * vlan information per packet. For other protocols,
305 * should be set according to the dcbx_enabled
306 * indication, but we only got here if there was an
307 * app tlv for the protocol, so dcbx must be enabled.
309 enable
= !(type
== DCBX_PROTOCOL_ETH
);
311 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
316 /* If RoCE-V2 TLV is not detected, driver need to use RoCE app
317 * data for RoCE-v2 not the default app data.
319 if (!p_data
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
320 p_data
->arr
[DCBX_PROTOCOL_ROCE
].update
) {
321 tc
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].tc
;
322 priority
= p_data
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
323 qed_dcbx_update_app_info(p_data
, p_hwfn
, true, true,
324 priority
, tc
, DCBX_PROTOCOL_ROCE_V2
);
327 /* Update ramrod protocol data and hw_info fields
328 * with default info when corresponding APP TLV's are not detected.
329 * The enabled field has a different logic for ethernet as only for
330 * ethernet dcb should disabled by default, as the information arrives
331 * from the OS (unless an explicit app tlv was present).
333 tc
= p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
;
334 priority
= p_data
->arr
[DCBX_PROTOCOL_ETH
].priority
;
335 for (type
= 0; type
< DCBX_MAX_PROTOCOL_TYPE
; type
++) {
336 if (p_data
->arr
[type
].update
)
339 enable
= !(type
== DCBX_PROTOCOL_ETH
);
340 qed_dcbx_update_app_info(p_data
, p_hwfn
, enable
, true,
347 /* Parse app TLV's to update TC information in hw_info structure for
348 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
350 static int qed_dcbx_process_mib_info(struct qed_hwfn
*p_hwfn
)
352 struct dcbx_app_priority_feature
*p_app
;
353 struct dcbx_app_priority_entry
*p_tbl
;
354 struct qed_dcbx_results data
= { 0 };
355 struct dcbx_ets_feature
*p_ets
;
356 struct qed_hw_info
*p_info
;
357 u32 pri_tc_tbl
, flags
;
362 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
363 dcbx_version
= QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
);
365 p_app
= &p_hwfn
->p_dcbx_info
->operational
.features
.app
;
366 p_tbl
= p_app
->app_pri_tbl
;
368 p_ets
= &p_hwfn
->p_dcbx_info
->operational
.features
.ets
;
369 pri_tc_tbl
= p_ets
->pri_tc_tbl
[0];
371 p_info
= &p_hwfn
->hw_info
;
372 num_entries
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_NUM_ENTRIES
);
374 rc
= qed_dcbx_process_tlv(p_hwfn
, &data
, p_tbl
, pri_tc_tbl
,
375 num_entries
, dcbx_version
);
379 p_info
->num_tc
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
380 data
.pf_id
= p_hwfn
->rel_pf_id
;
381 data
.dcbx_enabled
= !!dcbx_version
;
383 qed_dcbx_dp_protocol(p_hwfn
, &data
);
385 memcpy(&p_hwfn
->p_dcbx_info
->results
, &data
,
386 sizeof(struct qed_dcbx_results
));
392 qed_dcbx_copy_mib(struct qed_hwfn
*p_hwfn
,
393 struct qed_ptt
*p_ptt
,
394 struct qed_dcbx_mib_meta_data
*p_data
,
395 enum qed_mib_read_type type
)
397 u32 prefix_seq_num
, suffix_seq_num
;
401 /* The data is considered to be valid only if both sequence numbers are
405 if (type
== QED_DCBX_REMOTE_LLDP_MIB
) {
406 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_remote
,
407 p_data
->addr
, p_data
->size
);
408 prefix_seq_num
= p_data
->lldp_remote
->prefix_seq_num
;
409 suffix_seq_num
= p_data
->lldp_remote
->suffix_seq_num
;
411 qed_memcpy_from(p_hwfn
, p_ptt
, p_data
->mib
,
412 p_data
->addr
, p_data
->size
);
413 prefix_seq_num
= p_data
->mib
->prefix_seq_num
;
414 suffix_seq_num
= p_data
->mib
->suffix_seq_num
;
420 "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
421 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
422 } while ((prefix_seq_num
!= suffix_seq_num
) &&
423 (read_count
< QED_DCBX_MAX_MIB_READ_TRY
));
425 if (read_count
>= QED_DCBX_MAX_MIB_READ_TRY
) {
427 "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
428 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
436 qed_dcbx_get_priority_info(struct qed_hwfn
*p_hwfn
,
437 struct qed_dcbx_app_prio
*p_prio
,
438 struct qed_dcbx_results
*p_results
)
442 p_prio
->roce
= QED_DCBX_INVALID_PRIORITY
;
443 p_prio
->roce_v2
= QED_DCBX_INVALID_PRIORITY
;
444 p_prio
->iscsi
= QED_DCBX_INVALID_PRIORITY
;
445 p_prio
->fcoe
= QED_DCBX_INVALID_PRIORITY
;
447 if (p_results
->arr
[DCBX_PROTOCOL_ROCE
].update
&&
448 p_results
->arr
[DCBX_PROTOCOL_ROCE
].enable
)
449 p_prio
->roce
= p_results
->arr
[DCBX_PROTOCOL_ROCE
].priority
;
451 if (p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
&&
452 p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].enable
) {
453 val
= p_results
->arr
[DCBX_PROTOCOL_ROCE_V2
].priority
;
454 p_prio
->roce_v2
= val
;
457 if (p_results
->arr
[DCBX_PROTOCOL_ISCSI
].update
&&
458 p_results
->arr
[DCBX_PROTOCOL_ISCSI
].enable
)
459 p_prio
->iscsi
= p_results
->arr
[DCBX_PROTOCOL_ISCSI
].priority
;
461 if (p_results
->arr
[DCBX_PROTOCOL_FCOE
].update
&&
462 p_results
->arr
[DCBX_PROTOCOL_FCOE
].enable
)
463 p_prio
->fcoe
= p_results
->arr
[DCBX_PROTOCOL_FCOE
].priority
;
465 if (p_results
->arr
[DCBX_PROTOCOL_ETH
].update
&&
466 p_results
->arr
[DCBX_PROTOCOL_ETH
].enable
)
467 p_prio
->eth
= p_results
->arr
[DCBX_PROTOCOL_ETH
].priority
;
469 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
470 "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
471 p_prio
->iscsi
, p_prio
->roce
, p_prio
->roce_v2
, p_prio
->fcoe
,
476 qed_dcbx_get_app_data(struct qed_hwfn
*p_hwfn
,
477 struct dcbx_app_priority_feature
*p_app
,
478 struct dcbx_app_priority_entry
*p_tbl
,
479 struct qed_dcbx_params
*p_params
, bool ieee
)
481 struct qed_app_entry
*entry
;
485 p_params
->app_willing
= QED_MFW_GET_FIELD(p_app
->flags
,
487 p_params
->app_valid
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ENABLED
);
488 p_params
->app_error
= QED_MFW_GET_FIELD(p_app
->flags
, DCBX_APP_ERROR
);
489 p_params
->num_app_entries
= QED_MFW_GET_FIELD(p_app
->flags
,
490 DCBX_APP_NUM_ENTRIES
);
491 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
492 entry
= &p_params
->app_entry
[i
];
497 sf_ieee
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
500 case DCBX_APP_SF_IEEE_RESERVED
:
502 val
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
504 entry
->sf_ieee
= val
?
505 QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
506 QED_DCBX_SF_IEEE_ETHTYPE
;
508 case DCBX_APP_SF_IEEE_ETHTYPE
:
509 entry
->sf_ieee
= QED_DCBX_SF_IEEE_ETHTYPE
;
511 case DCBX_APP_SF_IEEE_TCP_PORT
:
512 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_PORT
;
514 case DCBX_APP_SF_IEEE_UDP_PORT
:
515 entry
->sf_ieee
= QED_DCBX_SF_IEEE_UDP_PORT
;
517 case DCBX_APP_SF_IEEE_TCP_UDP_PORT
:
518 entry
->sf_ieee
= QED_DCBX_SF_IEEE_TCP_UDP_PORT
;
522 entry
->ethtype
= !(QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
526 pri_map
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
527 entry
->prio
= ffs(pri_map
) - 1;
528 entry
->proto_id
= QED_MFW_GET_FIELD(p_tbl
[i
].entry
,
529 DCBX_APP_PROTOCOL_ID
);
530 qed_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
532 &entry
->proto_type
, ieee
);
535 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
536 "APP params: willing %d, valid %d error = %d\n",
537 p_params
->app_willing
, p_params
->app_valid
,
538 p_params
->app_error
);
542 qed_dcbx_get_pfc_data(struct qed_hwfn
*p_hwfn
,
543 u32 pfc
, struct qed_dcbx_params
*p_params
)
547 p_params
->pfc
.willing
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_WILLING
);
548 p_params
->pfc
.max_tc
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_CAPS
);
549 p_params
->pfc
.enabled
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_ENABLED
);
550 pfc_map
= QED_MFW_GET_FIELD(pfc
, DCBX_PFC_PRI_EN_BITMAP
);
551 p_params
->pfc
.prio
[0] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_0
);
552 p_params
->pfc
.prio
[1] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_1
);
553 p_params
->pfc
.prio
[2] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_2
);
554 p_params
->pfc
.prio
[3] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_3
);
555 p_params
->pfc
.prio
[4] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_4
);
556 p_params
->pfc
.prio
[5] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_5
);
557 p_params
->pfc
.prio
[6] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_6
);
558 p_params
->pfc
.prio
[7] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_7
);
560 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
561 "PFC params: willing %d, pfc_bitmap %d\n",
562 p_params
->pfc
.willing
, pfc_map
);
566 qed_dcbx_get_ets_data(struct qed_hwfn
*p_hwfn
,
567 struct dcbx_ets_feature
*p_ets
,
568 struct qed_dcbx_params
*p_params
)
570 u32 bw_map
[2], tsa_map
[2], pri_map
;
573 p_params
->ets_willing
= QED_MFW_GET_FIELD(p_ets
->flags
,
575 p_params
->ets_enabled
= QED_MFW_GET_FIELD(p_ets
->flags
,
577 p_params
->ets_cbs
= QED_MFW_GET_FIELD(p_ets
->flags
, DCBX_ETS_CBS
);
578 p_params
->max_ets_tc
= QED_MFW_GET_FIELD(p_ets
->flags
,
580 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
581 "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
582 p_params
->ets_willing
,
584 p_ets
->pri_tc_tbl
[0], p_params
->max_ets_tc
);
586 if (p_params
->ets_enabled
&& !p_params
->max_ets_tc
) {
587 p_params
->max_ets_tc
= QED_MAX_PFC_PRIORITIES
;
588 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
589 "ETS params: max_ets_tc is forced to %d\n",
590 p_params
->max_ets_tc
);
593 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
594 * encoded in a type u32 array of size 2.
596 bw_map
[0] = be32_to_cpu(p_ets
->tc_bw_tbl
[0]);
597 bw_map
[1] = be32_to_cpu(p_ets
->tc_bw_tbl
[1]);
598 tsa_map
[0] = be32_to_cpu(p_ets
->tc_tsa_tbl
[0]);
599 tsa_map
[1] = be32_to_cpu(p_ets
->tc_tsa_tbl
[1]);
600 pri_map
= p_ets
->pri_tc_tbl
[0];
601 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
602 p_params
->ets_tc_bw_tbl
[i
] = ((u8
*)bw_map
)[i
];
603 p_params
->ets_tc_tsa_tbl
[i
] = ((u8
*)tsa_map
)[i
];
604 p_params
->ets_pri_tc_tbl
[i
] = QED_DCBX_PRIO2TC(pri_map
, i
);
605 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
,
606 "elem %d bw_tbl %x tsa_tbl %x\n",
607 i
, p_params
->ets_tc_bw_tbl
[i
],
608 p_params
->ets_tc_tsa_tbl
[i
]);
613 qed_dcbx_get_common_params(struct qed_hwfn
*p_hwfn
,
614 struct dcbx_app_priority_feature
*p_app
,
615 struct dcbx_app_priority_entry
*p_tbl
,
616 struct dcbx_ets_feature
*p_ets
,
617 u32 pfc
, struct qed_dcbx_params
*p_params
, bool ieee
)
619 qed_dcbx_get_app_data(p_hwfn
, p_app
, p_tbl
, p_params
, ieee
);
620 qed_dcbx_get_ets_data(p_hwfn
, p_ets
, p_params
);
621 qed_dcbx_get_pfc_data(p_hwfn
, pfc
, p_params
);
625 qed_dcbx_get_local_params(struct qed_hwfn
*p_hwfn
,
626 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
628 struct dcbx_features
*p_feat
;
630 p_feat
= &p_hwfn
->p_dcbx_info
->local_admin
.features
;
631 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
632 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
633 p_feat
->pfc
, ¶ms
->local
.params
, false);
634 params
->local
.valid
= true;
638 qed_dcbx_get_remote_params(struct qed_hwfn
*p_hwfn
,
639 struct qed_ptt
*p_ptt
, struct qed_dcbx_get
*params
)
641 struct dcbx_features
*p_feat
;
643 p_feat
= &p_hwfn
->p_dcbx_info
->remote
.features
;
644 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
645 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
646 p_feat
->pfc
, ¶ms
->remote
.params
, false);
647 params
->remote
.valid
= true;
651 qed_dcbx_get_operational_params(struct qed_hwfn
*p_hwfn
,
652 struct qed_ptt
*p_ptt
,
653 struct qed_dcbx_get
*params
)
655 struct qed_dcbx_operational_params
*p_operational
;
656 struct qed_dcbx_results
*p_results
;
657 struct dcbx_features
*p_feat
;
662 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
664 /* If DCBx version is non zero, then negotiation
665 * was successfuly performed
667 p_operational
= ¶ms
->operational
;
668 enabled
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) !=
669 DCBX_CONFIG_VERSION_DISABLED
);
671 p_operational
->enabled
= enabled
;
672 p_operational
->valid
= false;
676 p_feat
= &p_hwfn
->p_dcbx_info
->operational
.features
;
677 p_results
= &p_hwfn
->p_dcbx_info
->results
;
679 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
680 DCBX_CONFIG_VERSION_IEEE
);
681 p_operational
->ieee
= val
;
682 val
= !!(QED_MFW_GET_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
683 DCBX_CONFIG_VERSION_CEE
);
684 p_operational
->cee
= val
;
686 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "Version support: ieee %d, cee %d\n",
687 p_operational
->ieee
, p_operational
->cee
);
689 qed_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
690 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
691 p_feat
->pfc
, ¶ms
->operational
.params
,
692 p_operational
->ieee
);
693 qed_dcbx_get_priority_info(p_hwfn
, &p_operational
->app_prio
, p_results
);
694 err
= QED_MFW_GET_FIELD(p_feat
->app
.flags
, DCBX_APP_ERROR
);
695 p_operational
->err
= err
;
696 p_operational
->enabled
= enabled
;
697 p_operational
->valid
= true;
701 qed_dcbx_get_local_lldp_params(struct qed_hwfn
*p_hwfn
,
702 struct qed_ptt
*p_ptt
,
703 struct qed_dcbx_get
*params
)
705 struct lldp_config_params_s
*p_local
;
707 p_local
= &p_hwfn
->p_dcbx_info
->lldp_local
[LLDP_NEAREST_BRIDGE
];
709 memcpy(params
->lldp_local
.local_chassis_id
, p_local
->local_chassis_id
,
710 ARRAY_SIZE(p_local
->local_chassis_id
));
711 memcpy(params
->lldp_local
.local_port_id
, p_local
->local_port_id
,
712 ARRAY_SIZE(p_local
->local_port_id
));
716 qed_dcbx_get_remote_lldp_params(struct qed_hwfn
*p_hwfn
,
717 struct qed_ptt
*p_ptt
,
718 struct qed_dcbx_get
*params
)
720 struct lldp_status_params_s
*p_remote
;
722 p_remote
= &p_hwfn
->p_dcbx_info
->lldp_remote
[LLDP_NEAREST_BRIDGE
];
724 memcpy(params
->lldp_remote
.peer_chassis_id
, p_remote
->peer_chassis_id
,
725 ARRAY_SIZE(p_remote
->peer_chassis_id
));
726 memcpy(params
->lldp_remote
.peer_port_id
, p_remote
->peer_port_id
,
727 ARRAY_SIZE(p_remote
->peer_port_id
));
731 qed_dcbx_get_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
732 struct qed_dcbx_get
*p_params
,
733 enum qed_mib_read_type type
)
736 case QED_DCBX_REMOTE_MIB
:
737 qed_dcbx_get_remote_params(p_hwfn
, p_ptt
, p_params
);
739 case QED_DCBX_LOCAL_MIB
:
740 qed_dcbx_get_local_params(p_hwfn
, p_ptt
, p_params
);
742 case QED_DCBX_OPERATIONAL_MIB
:
743 qed_dcbx_get_operational_params(p_hwfn
, p_ptt
, p_params
);
745 case QED_DCBX_REMOTE_LLDP_MIB
:
746 qed_dcbx_get_remote_lldp_params(p_hwfn
, p_ptt
, p_params
);
748 case QED_DCBX_LOCAL_LLDP_MIB
:
749 qed_dcbx_get_local_lldp_params(p_hwfn
, p_ptt
, p_params
);
752 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
760 qed_dcbx_read_local_lldp_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
762 struct qed_dcbx_mib_meta_data data
;
765 memset(&data
, 0, sizeof(data
));
766 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
768 data
.lldp_local
= p_hwfn
->p_dcbx_info
->lldp_local
;
769 data
.size
= sizeof(struct lldp_config_params_s
);
770 qed_memcpy_from(p_hwfn
, p_ptt
, data
.lldp_local
, data
.addr
, data
.size
);
776 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn
*p_hwfn
,
777 struct qed_ptt
*p_ptt
,
778 enum qed_mib_read_type type
)
780 struct qed_dcbx_mib_meta_data data
;
783 memset(&data
, 0, sizeof(data
));
784 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
786 data
.lldp_remote
= p_hwfn
->p_dcbx_info
->lldp_remote
;
787 data
.size
= sizeof(struct lldp_status_params_s
);
788 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
794 qed_dcbx_read_operational_mib(struct qed_hwfn
*p_hwfn
,
795 struct qed_ptt
*p_ptt
,
796 enum qed_mib_read_type type
)
798 struct qed_dcbx_mib_meta_data data
;
801 memset(&data
, 0, sizeof(data
));
802 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
803 offsetof(struct public_port
, operational_dcbx_mib
);
804 data
.mib
= &p_hwfn
->p_dcbx_info
->operational
;
805 data
.size
= sizeof(struct dcbx_mib
);
806 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
812 qed_dcbx_read_remote_mib(struct qed_hwfn
*p_hwfn
,
813 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
815 struct qed_dcbx_mib_meta_data data
;
818 memset(&data
, 0, sizeof(data
));
819 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
820 offsetof(struct public_port
, remote_dcbx_mib
);
821 data
.mib
= &p_hwfn
->p_dcbx_info
->remote
;
822 data
.size
= sizeof(struct dcbx_mib
);
823 rc
= qed_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
829 qed_dcbx_read_local_mib(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
)
831 struct qed_dcbx_mib_meta_data data
;
834 memset(&data
, 0, sizeof(data
));
835 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
836 offsetof(struct public_port
, local_admin_dcbx_mib
);
837 data
.local_admin
= &p_hwfn
->p_dcbx_info
->local_admin
;
838 data
.size
= sizeof(struct dcbx_local_params
);
839 qed_memcpy_from(p_hwfn
, p_ptt
, data
.local_admin
, data
.addr
, data
.size
);
844 static int qed_dcbx_read_mib(struct qed_hwfn
*p_hwfn
,
845 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
850 case QED_DCBX_OPERATIONAL_MIB
:
851 rc
= qed_dcbx_read_operational_mib(p_hwfn
, p_ptt
, type
);
853 case QED_DCBX_REMOTE_MIB
:
854 rc
= qed_dcbx_read_remote_mib(p_hwfn
, p_ptt
, type
);
856 case QED_DCBX_LOCAL_MIB
:
857 rc
= qed_dcbx_read_local_mib(p_hwfn
, p_ptt
);
859 case QED_DCBX_REMOTE_LLDP_MIB
:
860 rc
= qed_dcbx_read_remote_lldp_mib(p_hwfn
, p_ptt
, type
);
862 case QED_DCBX_LOCAL_LLDP_MIB
:
863 rc
= qed_dcbx_read_local_lldp_mib(p_hwfn
, p_ptt
);
866 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
872 void qed_dcbx_aen(struct qed_hwfn
*hwfn
, u32 mib_type
)
874 struct qed_common_cb_ops
*op
= hwfn
->cdev
->protocol_ops
.common
;
875 void *cookie
= hwfn
->cdev
->ops_cookie
;
877 if (cookie
&& op
->dcbx_aen
)
878 op
->dcbx_aen(cookie
, &hwfn
->p_dcbx_info
->get
, mib_type
);
882 * Reconfigure QM and invoke PF update ramrod command if operational MIB
883 * change is detected.
886 qed_dcbx_mib_update_event(struct qed_hwfn
*p_hwfn
,
887 struct qed_ptt
*p_ptt
, enum qed_mib_read_type type
)
891 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
895 if (type
== QED_DCBX_OPERATIONAL_MIB
) {
896 rc
= qed_dcbx_process_mib_info(p_hwfn
);
898 /* reconfigure tcs of QM queues according
899 * to negotiation results
901 qed_qm_reconf(p_hwfn
, p_ptt
);
903 /* update storm FW with negotiation results */
904 qed_sp_pf_update(p_hwfn
);
907 qed_dcbx_get_params(p_hwfn
, p_ptt
, &p_hwfn
->p_dcbx_info
->get
, type
);
908 qed_dcbx_aen(p_hwfn
, type
);
913 int qed_dcbx_info_alloc(struct qed_hwfn
*p_hwfn
)
917 p_hwfn
->p_dcbx_info
= kzalloc(sizeof(*p_hwfn
->p_dcbx_info
), GFP_KERNEL
);
918 if (!p_hwfn
->p_dcbx_info
)
924 void qed_dcbx_info_free(struct qed_hwfn
*p_hwfn
,
925 struct qed_dcbx_info
*p_dcbx_info
)
927 kfree(p_hwfn
->p_dcbx_info
);
930 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data
*p_data
,
931 struct qed_dcbx_results
*p_src
,
932 enum dcbx_protocol_type type
)
934 p_data
->dcb_enable_flag
= p_src
->arr
[type
].enable
;
935 p_data
->dcb_priority
= p_src
->arr
[type
].priority
;
936 p_data
->dcb_tc
= p_src
->arr
[type
].tc
;
939 /* Set pf update ramrod command params */
940 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results
*p_src
,
941 struct pf_update_ramrod_data
*p_dest
)
943 struct protocol_dcb_data
*p_dcb_data
;
944 bool update_flag
= false;
946 p_dest
->pf_id
= p_src
->pf_id
;
948 update_flag
= p_src
->arr
[DCBX_PROTOCOL_FCOE
].update
;
949 p_dest
->update_fcoe_dcb_data_flag
= update_flag
;
951 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
;
952 p_dest
->update_roce_dcb_data_flag
= update_flag
;
953 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
;
954 p_dest
->update_roce_dcb_data_flag
= update_flag
;
956 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ISCSI
].update
;
957 p_dest
->update_iscsi_dcb_data_flag
= update_flag
;
958 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ETH
].update
;
959 p_dest
->update_eth_dcb_data_flag
= update_flag
;
961 p_dcb_data
= &p_dest
->fcoe_dcb_data
;
962 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_FCOE
);
963 p_dcb_data
= &p_dest
->roce_dcb_data
;
965 if (p_src
->arr
[DCBX_PROTOCOL_ROCE
].update
)
966 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
968 if (p_src
->arr
[DCBX_PROTOCOL_ROCE_V2
].update
)
969 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
,
970 DCBX_PROTOCOL_ROCE_V2
);
972 p_dcb_data
= &p_dest
->iscsi_dcb_data
;
973 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ISCSI
);
974 p_dcb_data
= &p_dest
->eth_dcb_data
;
975 qed_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ETH
);
979 static int qed_dcbx_query_params(struct qed_hwfn
*p_hwfn
,
980 struct qed_dcbx_get
*p_get
,
981 enum qed_mib_read_type type
)
983 struct qed_ptt
*p_ptt
;
986 if (IS_VF(p_hwfn
->cdev
))
989 p_ptt
= qed_ptt_acquire(p_hwfn
);
993 rc
= qed_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
997 rc
= qed_dcbx_get_params(p_hwfn
, p_ptt
, p_get
, type
);
1000 qed_ptt_release(p_hwfn
, p_ptt
);
1005 qed_dcbx_set_pfc_data(struct qed_hwfn
*p_hwfn
,
1006 u32
*pfc
, struct qed_dcbx_params
*p_params
)
1011 *pfc
&= ~DCBX_PFC_ERROR_MASK
;
1013 if (p_params
->pfc
.willing
)
1014 *pfc
|= DCBX_PFC_WILLING_MASK
;
1016 *pfc
&= ~DCBX_PFC_WILLING_MASK
;
1018 if (p_params
->pfc
.enabled
)
1019 *pfc
|= DCBX_PFC_ENABLED_MASK
;
1021 *pfc
&= ~DCBX_PFC_ENABLED_MASK
;
1023 *pfc
&= ~DCBX_PFC_CAPS_MASK
;
1024 *pfc
|= (u32
)p_params
->pfc
.max_tc
<< DCBX_PFC_CAPS_SHIFT
;
1026 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1027 if (p_params
->pfc
.prio
[i
])
1030 *pfc
&= ~DCBX_PFC_PRI_EN_BITMAP_MASK
;
1031 *pfc
|= (pfc_map
<< DCBX_PFC_PRI_EN_BITMAP_SHIFT
);
1033 DP_VERBOSE(p_hwfn
, QED_MSG_DCB
, "pfc = 0x%x\n", *pfc
);
1037 qed_dcbx_set_ets_data(struct qed_hwfn
*p_hwfn
,
1038 struct dcbx_ets_feature
*p_ets
,
1039 struct qed_dcbx_params
*p_params
)
1041 u8
*bw_map
, *tsa_map
;
1045 if (p_params
->ets_willing
)
1046 p_ets
->flags
|= DCBX_ETS_WILLING_MASK
;
1048 p_ets
->flags
&= ~DCBX_ETS_WILLING_MASK
;
1050 if (p_params
->ets_cbs
)
1051 p_ets
->flags
|= DCBX_ETS_CBS_MASK
;
1053 p_ets
->flags
&= ~DCBX_ETS_CBS_MASK
;
1055 if (p_params
->ets_enabled
)
1056 p_ets
->flags
|= DCBX_ETS_ENABLED_MASK
;
1058 p_ets
->flags
&= ~DCBX_ETS_ENABLED_MASK
;
1060 p_ets
->flags
&= ~DCBX_ETS_MAX_TCS_MASK
;
1061 p_ets
->flags
|= (u32
)p_params
->max_ets_tc
<< DCBX_ETS_MAX_TCS_SHIFT
;
1063 bw_map
= (u8
*)&p_ets
->tc_bw_tbl
[0];
1064 tsa_map
= (u8
*)&p_ets
->tc_tsa_tbl
[0];
1065 p_ets
->pri_tc_tbl
[0] = 0;
1066 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1067 bw_map
[i
] = p_params
->ets_tc_bw_tbl
[i
];
1068 tsa_map
[i
] = p_params
->ets_tc_tsa_tbl
[i
];
1069 /* Copy the priority value to the corresponding 4 bits in the
1070 * traffic class table.
1072 val
= (((u32
)p_params
->ets_pri_tc_tbl
[i
]) << ((7 - i
) * 4));
1073 p_ets
->pri_tc_tbl
[0] |= val
;
1075 for (i
= 0; i
< 2; i
++) {
1076 p_ets
->tc_bw_tbl
[i
] = cpu_to_be32(p_ets
->tc_bw_tbl
[i
]);
1077 p_ets
->tc_tsa_tbl
[i
] = cpu_to_be32(p_ets
->tc_tsa_tbl
[i
]);
1082 qed_dcbx_set_app_data(struct qed_hwfn
*p_hwfn
,
1083 struct dcbx_app_priority_feature
*p_app
,
1084 struct qed_dcbx_params
*p_params
, bool ieee
)
1089 if (p_params
->app_willing
)
1090 p_app
->flags
|= DCBX_APP_WILLING_MASK
;
1092 p_app
->flags
&= ~DCBX_APP_WILLING_MASK
;
1094 if (p_params
->app_valid
)
1095 p_app
->flags
|= DCBX_APP_ENABLED_MASK
;
1097 p_app
->flags
&= ~DCBX_APP_ENABLED_MASK
;
1099 p_app
->flags
&= ~DCBX_APP_NUM_ENTRIES_MASK
;
1100 p_app
->flags
|= (u32
)p_params
->num_app_entries
<<
1101 DCBX_APP_NUM_ENTRIES_SHIFT
;
1103 for (i
= 0; i
< DCBX_MAX_APP_PROTOCOL
; i
++) {
1104 entry
= &p_app
->app_pri_tbl
[i
].entry
;
1107 *entry
&= ~(DCBX_APP_SF_IEEE_MASK
| DCBX_APP_SF_MASK
);
1108 switch (p_params
->app_entry
[i
].sf_ieee
) {
1109 case QED_DCBX_SF_IEEE_ETHTYPE
:
1110 *entry
|= ((u32
)DCBX_APP_SF_IEEE_ETHTYPE
<<
1111 DCBX_APP_SF_IEEE_SHIFT
);
1112 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1115 case QED_DCBX_SF_IEEE_TCP_PORT
:
1116 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_PORT
<<
1117 DCBX_APP_SF_IEEE_SHIFT
);
1118 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1121 case QED_DCBX_SF_IEEE_UDP_PORT
:
1122 *entry
|= ((u32
)DCBX_APP_SF_IEEE_UDP_PORT
<<
1123 DCBX_APP_SF_IEEE_SHIFT
);
1124 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1127 case QED_DCBX_SF_IEEE_TCP_UDP_PORT
:
1128 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_UDP_PORT
<<
1129 DCBX_APP_SF_IEEE_SHIFT
);
1130 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1135 *entry
&= ~DCBX_APP_SF_MASK
;
1136 if (p_params
->app_entry
[i
].ethtype
)
1137 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1140 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1144 *entry
&= ~DCBX_APP_PROTOCOL_ID_MASK
;
1145 *entry
|= ((u32
)p_params
->app_entry
[i
].proto_id
<<
1146 DCBX_APP_PROTOCOL_ID_SHIFT
);
1147 *entry
&= ~DCBX_APP_PRI_MAP_MASK
;
1148 *entry
|= ((u32
)(p_params
->app_entry
[i
].prio
) <<
1149 DCBX_APP_PRI_MAP_SHIFT
);
1154 qed_dcbx_set_local_params(struct qed_hwfn
*p_hwfn
,
1155 struct dcbx_local_params
*local_admin
,
1156 struct qed_dcbx_set
*params
)
1160 local_admin
->flags
= 0;
1161 memcpy(&local_admin
->features
,
1162 &p_hwfn
->p_dcbx_info
->operational
.features
,
1163 sizeof(local_admin
->features
));
1165 if (params
->enabled
) {
1166 local_admin
->config
= params
->ver_num
;
1167 ieee
= !!(params
->ver_num
& DCBX_CONFIG_VERSION_IEEE
);
1169 local_admin
->config
= DCBX_CONFIG_VERSION_DISABLED
;
1172 if (params
->override_flags
& QED_DCBX_OVERRIDE_PFC_CFG
)
1173 qed_dcbx_set_pfc_data(p_hwfn
, &local_admin
->features
.pfc
,
1174 ¶ms
->config
.params
);
1176 if (params
->override_flags
& QED_DCBX_OVERRIDE_ETS_CFG
)
1177 qed_dcbx_set_ets_data(p_hwfn
, &local_admin
->features
.ets
,
1178 ¶ms
->config
.params
);
1180 if (params
->override_flags
& QED_DCBX_OVERRIDE_APP_CFG
)
1181 qed_dcbx_set_app_data(p_hwfn
, &local_admin
->features
.app
,
1182 ¶ms
->config
.params
, ieee
);
1185 int qed_dcbx_config_params(struct qed_hwfn
*p_hwfn
, struct qed_ptt
*p_ptt
,
1186 struct qed_dcbx_set
*params
, bool hw_commit
)
1188 struct dcbx_local_params local_admin
;
1189 struct qed_dcbx_mib_meta_data data
;
1190 u32 resp
= 0, param
= 0;
1194 memcpy(&p_hwfn
->p_dcbx_info
->set
, params
,
1195 sizeof(struct qed_dcbx_set
));
1199 /* clear set-parmas cache */
1200 memset(&p_hwfn
->p_dcbx_info
->set
, 0, sizeof(p_hwfn
->p_dcbx_info
->set
));
1202 memset(&local_admin
, 0, sizeof(local_admin
));
1203 qed_dcbx_set_local_params(p_hwfn
, &local_admin
, params
);
1205 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1206 offsetof(struct public_port
, local_admin_dcbx_mib
);
1207 data
.local_admin
= &local_admin
;
1208 data
.size
= sizeof(struct dcbx_local_params
);
1209 qed_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.local_admin
, data
.size
);
1211 rc
= qed_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_DCBX
,
1212 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT
, &resp
, ¶m
);
1214 DP_NOTICE(p_hwfn
, "Failed to send DCBX update request\n");
1219 int qed_dcbx_get_config_params(struct qed_hwfn
*p_hwfn
,
1220 struct qed_dcbx_set
*params
)
1222 struct qed_dcbx_get
*dcbx_info
;
1225 if (p_hwfn
->p_dcbx_info
->set
.config
.valid
) {
1226 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
,
1227 sizeof(struct qed_dcbx_set
));
1231 dcbx_info
= kzalloc(sizeof(*dcbx_info
), GFP_KERNEL
);
1235 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1236 rc
= qed_dcbx_query_params(p_hwfn
, dcbx_info
, QED_DCBX_OPERATIONAL_MIB
);
1242 p_hwfn
->p_dcbx_info
->set
.override_flags
= 0;
1243 p_hwfn
->p_dcbx_info
->set
.ver_num
= DCBX_CONFIG_VERSION_DISABLED
;
1244 if (dcbx_info
->operational
.cee
)
1245 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1246 if (dcbx_info
->operational
.ieee
)
1247 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1249 p_hwfn
->p_dcbx_info
->set
.enabled
= dcbx_info
->operational
.enabled
;
1250 memcpy(&p_hwfn
->p_dcbx_info
->set
.config
.params
,
1251 &dcbx_info
->operational
.params
,
1252 sizeof(struct qed_dcbx_admin_params
));
1253 p_hwfn
->p_dcbx_info
->set
.config
.valid
= true;
1255 memcpy(params
, &p_hwfn
->p_dcbx_info
->set
, sizeof(struct qed_dcbx_set
));
1262 static struct qed_dcbx_get
*qed_dcbnl_get_dcbx(struct qed_hwfn
*hwfn
,
1263 enum qed_mib_read_type type
)
1265 struct qed_dcbx_get
*dcbx_info
;
1267 dcbx_info
= kmalloc(sizeof(*dcbx_info
), GFP_ATOMIC
);
1271 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
1272 if (qed_dcbx_query_params(hwfn
, dcbx_info
, type
)) {
1277 if ((type
== QED_DCBX_OPERATIONAL_MIB
) &&
1278 !dcbx_info
->operational
.enabled
) {
1279 DP_INFO(hwfn
, "DCBX is not enabled/operational\n");
1287 static u8
qed_dcbnl_getstate(struct qed_dev
*cdev
)
1289 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1290 struct qed_dcbx_get
*dcbx_info
;
1293 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1297 enabled
= dcbx_info
->operational
.enabled
;
1298 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", enabled
);
1304 static u8
qed_dcbnl_setstate(struct qed_dev
*cdev
, u8 state
)
1306 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1307 struct qed_dcbx_set dcbx_set
;
1308 struct qed_ptt
*ptt
;
1311 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "DCB state = %d\n", state
);
1313 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1314 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1318 dcbx_set
.enabled
= !!state
;
1320 ptt
= qed_ptt_acquire(hwfn
);
1324 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1326 qed_ptt_release(hwfn
, ptt
);
1331 static void qed_dcbnl_getpgtccfgtx(struct qed_dev
*cdev
, int tc
, u8
*prio_type
,
1332 u8
*pgid
, u8
*bw_pct
, u8
*up_map
)
1334 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1335 struct qed_dcbx_get
*dcbx_info
;
1337 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tc = %d\n", tc
);
1338 *prio_type
= *pgid
= *bw_pct
= *up_map
= 0;
1339 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1340 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1344 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1348 *pgid
= dcbx_info
->operational
.params
.ets_pri_tc_tbl
[tc
];
1352 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8
*bw_pct
)
1354 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1355 struct qed_dcbx_get
*dcbx_info
;
1358 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d\n", pgid
);
1359 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1360 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1364 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1368 *bw_pct
= dcbx_info
->operational
.params
.ets_tc_bw_tbl
[pgid
];
1369 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "bw_pct = %d\n", *bw_pct
);
1373 static void qed_dcbnl_getpgtccfgrx(struct qed_dev
*cdev
, int tc
, u8
*prio
,
1374 u8
*bwg_id
, u8
*bw_pct
, u8
*up_map
)
1376 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1377 *prio
= *bwg_id
= *bw_pct
= *up_map
= 0;
1380 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev
*cdev
,
1381 int bwg_id
, u8
*bw_pct
)
1383 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1387 static void qed_dcbnl_getpfccfg(struct qed_dev
*cdev
,
1388 int priority
, u8
*setting
)
1390 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1391 struct qed_dcbx_get
*dcbx_info
;
1393 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d\n", priority
);
1394 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1395 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1399 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1403 *setting
= dcbx_info
->operational
.params
.pfc
.prio
[priority
];
1404 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "setting = %d\n", *setting
);
1408 static void qed_dcbnl_setpfccfg(struct qed_dev
*cdev
, int priority
, u8 setting
)
1410 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1411 struct qed_dcbx_set dcbx_set
;
1412 struct qed_ptt
*ptt
;
1415 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "priority = %d setting = %d\n",
1417 if (priority
< 0 || priority
>= QED_MAX_PFC_PRIORITIES
) {
1418 DP_INFO(hwfn
, "Invalid priority %d\n", priority
);
1422 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1423 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1427 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1428 dcbx_set
.config
.params
.pfc
.prio
[priority
] = !!setting
;
1430 ptt
= qed_ptt_acquire(hwfn
);
1434 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1436 qed_ptt_release(hwfn
, ptt
);
1439 static u8
qed_dcbnl_getcap(struct qed_dev
*cdev
, int capid
, u8
*cap
)
1441 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1442 struct qed_dcbx_get
*dcbx_info
;
1445 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "capid = %d\n", capid
);
1446 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1451 case DCB_CAP_ATTR_PG
:
1452 case DCB_CAP_ATTR_PFC
:
1453 case DCB_CAP_ATTR_UP2TC
:
1454 case DCB_CAP_ATTR_GSP
:
1457 case DCB_CAP_ATTR_PG_TCS
:
1458 case DCB_CAP_ATTR_PFC_TCS
:
1461 case DCB_CAP_ATTR_DCBX
:
1462 *cap
= (DCB_CAP_DCBX_LLD_MANAGED
| DCB_CAP_DCBX_VER_CEE
|
1463 DCB_CAP_DCBX_VER_IEEE
);
1470 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "id = %d caps = %d\n", capid
, *cap
);
1476 static int qed_dcbnl_getnumtcs(struct qed_dev
*cdev
, int tcid
, u8
*num
)
1478 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1479 struct qed_dcbx_get
*dcbx_info
;
1482 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d\n", tcid
);
1483 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1488 case DCB_NUMTCS_ATTR_PG
:
1489 *num
= dcbx_info
->operational
.params
.max_ets_tc
;
1491 case DCB_NUMTCS_ATTR_PFC
:
1492 *num
= dcbx_info
->operational
.params
.pfc
.max_tc
;
1499 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "numtcs = %d\n", *num
);
1504 static u8
qed_dcbnl_getpfcstate(struct qed_dev
*cdev
)
1506 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1507 struct qed_dcbx_get
*dcbx_info
;
1510 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1514 enabled
= dcbx_info
->operational
.params
.pfc
.enabled
;
1515 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d\n", enabled
);
1521 static u8
qed_dcbnl_getdcbx(struct qed_dev
*cdev
)
1523 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1524 struct qed_dcbx_get
*dcbx_info
;
1527 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1531 if (dcbx_info
->operational
.enabled
)
1532 mode
|= DCB_CAP_DCBX_LLD_MANAGED
;
1533 if (dcbx_info
->operational
.ieee
)
1534 mode
|= DCB_CAP_DCBX_VER_IEEE
;
1535 if (dcbx_info
->operational
.cee
)
1536 mode
|= DCB_CAP_DCBX_VER_CEE
;
1538 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "dcb mode = %d\n", mode
);
1544 static void qed_dcbnl_setpgtccfgtx(struct qed_dev
*cdev
,
1546 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1548 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1549 struct qed_dcbx_set dcbx_set
;
1550 struct qed_ptt
*ptt
;
1553 DP_VERBOSE(hwfn
, QED_MSG_DCB
,
1554 "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n",
1555 tc
, pri_type
, pgid
, bw_pct
, up_map
);
1557 if (tc
< 0 || tc
>= QED_MAX_PFC_PRIORITIES
) {
1558 DP_INFO(hwfn
, "Invalid tc %d\n", tc
);
1562 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1563 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1567 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1568 dcbx_set
.config
.params
.ets_pri_tc_tbl
[tc
] = pgid
;
1570 ptt
= qed_ptt_acquire(hwfn
);
1574 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1576 qed_ptt_release(hwfn
, ptt
);
1579 static void qed_dcbnl_setpgtccfgrx(struct qed_dev
*cdev
, int prio
,
1580 u8 pri_type
, u8 pgid
, u8 bw_pct
, u8 up_map
)
1582 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1585 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1587 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1588 struct qed_dcbx_set dcbx_set
;
1589 struct qed_ptt
*ptt
;
1592 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pgid = %d bw_pct = %d\n", pgid
, bw_pct
);
1593 if (pgid
< 0 || pgid
>= QED_MAX_PFC_PRIORITIES
) {
1594 DP_INFO(hwfn
, "Invalid pgid %d\n", pgid
);
1598 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1599 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1603 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1604 dcbx_set
.config
.params
.ets_tc_bw_tbl
[pgid
] = bw_pct
;
1606 ptt
= qed_ptt_acquire(hwfn
);
1610 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1612 qed_ptt_release(hwfn
, ptt
);
1615 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev
*cdev
, int pgid
, u8 bw_pct
)
1617 DP_INFO(QED_LEADING_HWFN(cdev
), "Rx ETS is not supported\n");
1620 static u8
qed_dcbnl_setall(struct qed_dev
*cdev
)
1622 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1623 struct qed_dcbx_set dcbx_set
;
1624 struct qed_ptt
*ptt
;
1627 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1628 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1632 ptt
= qed_ptt_acquire(hwfn
);
1636 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 1);
1638 qed_ptt_release(hwfn
, ptt
);
1643 static int qed_dcbnl_setnumtcs(struct qed_dev
*cdev
, int tcid
, u8 num
)
1645 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1646 struct qed_dcbx_set dcbx_set
;
1647 struct qed_ptt
*ptt
;
1650 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "tcid = %d num = %d\n", tcid
, num
);
1651 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1652 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1657 case DCB_NUMTCS_ATTR_PG
:
1658 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1659 dcbx_set
.config
.params
.max_ets_tc
= num
;
1661 case DCB_NUMTCS_ATTR_PFC
:
1662 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1663 dcbx_set
.config
.params
.pfc
.max_tc
= num
;
1666 DP_INFO(hwfn
, "Invalid tcid %d\n", tcid
);
1670 ptt
= qed_ptt_acquire(hwfn
);
1674 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1676 qed_ptt_release(hwfn
, ptt
);
1681 static void qed_dcbnl_setpfcstate(struct qed_dev
*cdev
, u8 state
)
1683 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1684 struct qed_dcbx_set dcbx_set
;
1685 struct qed_ptt
*ptt
;
1688 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new state = %d\n", state
);
1690 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1691 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1695 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1696 dcbx_set
.config
.params
.pfc
.enabled
= !!state
;
1698 ptt
= qed_ptt_acquire(hwfn
);
1702 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1704 qed_ptt_release(hwfn
, ptt
);
1707 static int qed_dcbnl_getapp(struct qed_dev
*cdev
, u8 idtype
, u16 idval
)
1709 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1710 struct qed_dcbx_get
*dcbx_info
;
1711 struct qed_app_entry
*entry
;
1716 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1720 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1721 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1722 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
1723 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
)) {
1729 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1730 DP_ERR(cdev
, "App entry (%d, %d) not found\n", idtype
, idval
);
1740 static int qed_dcbnl_setapp(struct qed_dev
*cdev
,
1741 u8 idtype
, u16 idval
, u8 pri_map
)
1743 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1744 struct qed_dcbx_set dcbx_set
;
1745 struct qed_app_entry
*entry
;
1746 struct qed_ptt
*ptt
;
1750 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1751 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1755 ethtype
= !!(idtype
== DCB_APP_IDTYPE_ETHTYPE
);
1756 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
1757 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
1758 if ((entry
->ethtype
== ethtype
) && (entry
->proto_id
== idval
))
1760 /* First empty slot */
1761 if (!entry
->proto_id
) {
1762 dcbx_set
.config
.params
.num_app_entries
++;
1767 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
1768 DP_ERR(cdev
, "App table is full\n");
1772 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1773 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
1774 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= idval
;
1775 dcbx_set
.config
.params
.app_entry
[i
].prio
= pri_map
;
1777 ptt
= qed_ptt_acquire(hwfn
);
1781 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1783 qed_ptt_release(hwfn
, ptt
);
1788 static u8
qed_dcbnl_setdcbx(struct qed_dev
*cdev
, u8 mode
)
1790 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1791 struct qed_dcbx_set dcbx_set
;
1792 struct qed_ptt
*ptt
;
1795 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "new mode = %x\n", mode
);
1797 if (!(mode
& DCB_CAP_DCBX_VER_IEEE
) && !(mode
& DCB_CAP_DCBX_VER_CEE
)) {
1798 DP_INFO(hwfn
, "Allowed mode is cee, ieee or both\n");
1802 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1803 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1807 dcbx_set
.ver_num
= 0;
1808 if (mode
& DCB_CAP_DCBX_VER_CEE
) {
1809 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1810 dcbx_set
.enabled
= true;
1813 if (mode
& DCB_CAP_DCBX_VER_IEEE
) {
1814 dcbx_set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1815 dcbx_set
.enabled
= true;
1818 ptt
= qed_ptt_acquire(hwfn
);
1822 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1824 qed_ptt_release(hwfn
, ptt
);
1829 static u8
qed_dcbnl_getfeatcfg(struct qed_dev
*cdev
, int featid
, u8
*flags
)
1831 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1832 struct qed_dcbx_get
*dcbx_info
;
1834 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "Feature id = %d\n", featid
);
1835 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
1841 case DCB_FEATCFG_ATTR_PG
:
1842 if (dcbx_info
->operational
.params
.ets_enabled
)
1843 *flags
= DCB_FEATCFG_ENABLE
;
1845 *flags
= DCB_FEATCFG_ERROR
;
1847 case DCB_FEATCFG_ATTR_PFC
:
1848 if (dcbx_info
->operational
.params
.pfc
.enabled
)
1849 *flags
= DCB_FEATCFG_ENABLE
;
1851 *flags
= DCB_FEATCFG_ERROR
;
1853 case DCB_FEATCFG_ATTR_APP
:
1854 if (dcbx_info
->operational
.params
.app_valid
)
1855 *flags
= DCB_FEATCFG_ENABLE
;
1857 *flags
= DCB_FEATCFG_ERROR
;
1860 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1865 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "flags = %d\n", *flags
);
1871 static u8
qed_dcbnl_setfeatcfg(struct qed_dev
*cdev
, int featid
, u8 flags
)
1873 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1874 struct qed_dcbx_set dcbx_set
;
1875 bool enabled
, willing
;
1876 struct qed_ptt
*ptt
;
1879 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "featid = %d flags = %d\n",
1881 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
1882 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
1886 enabled
= !!(flags
& DCB_FEATCFG_ENABLE
);
1887 willing
= !!(flags
& DCB_FEATCFG_WILLING
);
1889 case DCB_FEATCFG_ATTR_PG
:
1890 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
1891 dcbx_set
.config
.params
.ets_enabled
= enabled
;
1892 dcbx_set
.config
.params
.ets_willing
= willing
;
1894 case DCB_FEATCFG_ATTR_PFC
:
1895 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
1896 dcbx_set
.config
.params
.pfc
.enabled
= enabled
;
1897 dcbx_set
.config
.params
.pfc
.willing
= willing
;
1899 case DCB_FEATCFG_ATTR_APP
:
1900 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
1901 dcbx_set
.config
.params
.app_willing
= willing
;
1904 DP_INFO(hwfn
, "Invalid feature-ID %d\n", featid
);
1908 ptt
= qed_ptt_acquire(hwfn
);
1912 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
1914 qed_ptt_release(hwfn
, ptt
);
1919 static int qed_dcbnl_peer_getappinfo(struct qed_dev
*cdev
,
1920 struct dcb_peer_app_info
*info
,
1923 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1924 struct qed_dcbx_get
*dcbx_info
;
1926 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1930 info
->willing
= dcbx_info
->remote
.params
.app_willing
;
1931 info
->error
= dcbx_info
->remote
.params
.app_error
;
1932 *app_count
= dcbx_info
->remote
.params
.num_app_entries
;
1938 static int qed_dcbnl_peer_getapptable(struct qed_dev
*cdev
,
1939 struct dcb_app
*table
)
1941 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1942 struct qed_dcbx_get
*dcbx_info
;
1945 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1949 for (i
= 0; i
< dcbx_info
->remote
.params
.num_app_entries
; i
++) {
1950 if (dcbx_info
->remote
.params
.app_entry
[i
].ethtype
)
1951 table
[i
].selector
= DCB_APP_IDTYPE_ETHTYPE
;
1953 table
[i
].selector
= DCB_APP_IDTYPE_PORTNUM
;
1954 table
[i
].priority
= dcbx_info
->remote
.params
.app_entry
[i
].prio
;
1956 dcbx_info
->remote
.params
.app_entry
[i
].proto_id
;
1964 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev
*cdev
, struct cee_pfc
*pfc
)
1966 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1967 struct qed_dcbx_get
*dcbx_info
;
1970 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1974 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
1975 if (dcbx_info
->remote
.params
.pfc
.prio
[i
])
1976 pfc
->pfc_en
|= BIT(i
);
1978 pfc
->tcs_supported
= dcbx_info
->remote
.params
.pfc
.max_tc
;
1979 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "pfc state = %d tcs_supported = %d\n",
1980 pfc
->pfc_en
, pfc
->tcs_supported
);
1986 static int qed_dcbnl_cee_peer_getpg(struct qed_dev
*cdev
, struct cee_pg
*pg
)
1988 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
1989 struct qed_dcbx_get
*dcbx_info
;
1992 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_REMOTE_MIB
);
1996 pg
->willing
= dcbx_info
->remote
.params
.ets_willing
;
1997 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++) {
1998 pg
->pg_bw
[i
] = dcbx_info
->remote
.params
.ets_tc_bw_tbl
[i
];
1999 pg
->prio_pg
[i
] = dcbx_info
->remote
.params
.ets_pri_tc_tbl
[i
];
2002 DP_VERBOSE(hwfn
, QED_MSG_DCB
, "willing = %d", pg
->willing
);
2008 static int qed_dcbnl_get_ieee_pfc(struct qed_dev
*cdev
,
2009 struct ieee_pfc
*pfc
, bool remote
)
2011 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2012 struct qed_dcbx_params
*params
;
2013 struct qed_dcbx_get
*dcbx_info
;
2016 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2020 if (!dcbx_info
->operational
.ieee
) {
2021 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2027 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
2028 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
2029 QED_DCBX_REMOTE_MIB
);
2035 params
= &dcbx_info
->remote
.params
;
2037 params
= &dcbx_info
->operational
.params
;
2040 pfc
->pfc_cap
= params
->pfc
.max_tc
;
2042 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
2043 if (params
->pfc
.prio
[i
])
2044 pfc
->pfc_en
|= BIT(i
);
2051 static int qed_dcbnl_ieee_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2053 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, false);
2056 static int qed_dcbnl_ieee_setpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2058 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2059 struct qed_dcbx_get
*dcbx_info
;
2060 struct qed_dcbx_set dcbx_set
;
2061 struct qed_ptt
*ptt
;
2064 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2068 if (!dcbx_info
->operational
.ieee
) {
2069 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2076 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2077 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2081 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_PFC_CFG
;
2082 for (i
= 0; i
< QED_MAX_PFC_PRIORITIES
; i
++)
2083 dcbx_set
.config
.params
.pfc
.prio
[i
] = !!(pfc
->pfc_en
& BIT(i
));
2085 dcbx_set
.config
.params
.pfc
.max_tc
= pfc
->pfc_cap
;
2087 ptt
= qed_ptt_acquire(hwfn
);
2091 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2093 qed_ptt_release(hwfn
, ptt
);
2098 static int qed_dcbnl_get_ieee_ets(struct qed_dev
*cdev
,
2099 struct ieee_ets
*ets
, bool remote
)
2101 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2102 struct qed_dcbx_get
*dcbx_info
;
2103 struct qed_dcbx_params
*params
;
2106 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2110 if (!dcbx_info
->operational
.ieee
) {
2111 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2117 memset(dcbx_info
, 0, sizeof(*dcbx_info
));
2118 rc
= qed_dcbx_query_params(hwfn
, dcbx_info
,
2119 QED_DCBX_REMOTE_MIB
);
2125 params
= &dcbx_info
->remote
.params
;
2127 params
= &dcbx_info
->operational
.params
;
2130 ets
->ets_cap
= params
->max_ets_tc
;
2131 ets
->willing
= params
->ets_willing
;
2132 ets
->cbs
= params
->ets_cbs
;
2133 memcpy(ets
->tc_tx_bw
, params
->ets_tc_bw_tbl
, sizeof(ets
->tc_tx_bw
));
2134 memcpy(ets
->tc_tsa
, params
->ets_tc_tsa_tbl
, sizeof(ets
->tc_tsa
));
2135 memcpy(ets
->prio_tc
, params
->ets_pri_tc_tbl
, sizeof(ets
->prio_tc
));
2141 static int qed_dcbnl_ieee_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2143 return qed_dcbnl_get_ieee_ets(cdev
, ets
, false);
2146 static int qed_dcbnl_ieee_setets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2148 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2149 struct qed_dcbx_get
*dcbx_info
;
2150 struct qed_dcbx_set dcbx_set
;
2151 struct qed_ptt
*ptt
;
2154 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2158 if (!dcbx_info
->operational
.ieee
) {
2159 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2166 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2167 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2171 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_ETS_CFG
;
2172 dcbx_set
.config
.params
.max_ets_tc
= ets
->ets_cap
;
2173 dcbx_set
.config
.params
.ets_willing
= ets
->willing
;
2174 dcbx_set
.config
.params
.ets_cbs
= ets
->cbs
;
2175 memcpy(dcbx_set
.config
.params
.ets_tc_bw_tbl
, ets
->tc_tx_bw
,
2176 sizeof(ets
->tc_tx_bw
));
2177 memcpy(dcbx_set
.config
.params
.ets_tc_tsa_tbl
, ets
->tc_tsa
,
2178 sizeof(ets
->tc_tsa
));
2179 memcpy(dcbx_set
.config
.params
.ets_pri_tc_tbl
, ets
->prio_tc
,
2180 sizeof(ets
->prio_tc
));
2182 ptt
= qed_ptt_acquire(hwfn
);
2186 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2188 qed_ptt_release(hwfn
, ptt
);
2194 qed_dcbnl_ieee_peer_getets(struct qed_dev
*cdev
, struct ieee_ets
*ets
)
2196 return qed_dcbnl_get_ieee_ets(cdev
, ets
, true);
2200 qed_dcbnl_ieee_peer_getpfc(struct qed_dev
*cdev
, struct ieee_pfc
*pfc
)
2202 return qed_dcbnl_get_ieee_pfc(cdev
, pfc
, true);
2205 static int qed_dcbnl_ieee_getapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2207 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2208 struct qed_dcbx_get
*dcbx_info
;
2209 struct qed_app_entry
*entry
;
2214 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2218 if (!dcbx_info
->operational
.ieee
) {
2219 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2224 /* ieee defines the selector field value for ethertype to be 1 */
2225 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2226 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2227 entry
= &dcbx_info
->operational
.params
.app_entry
[i
];
2228 if ((entry
->ethtype
== ethtype
) &&
2229 (entry
->proto_id
== app
->protocol
)) {
2235 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2236 DP_ERR(cdev
, "App entry (%d, %d) not found\n", app
->selector
,
2242 app
->priority
= ffs(prio
) - 1;
2249 static int qed_dcbnl_ieee_setapp(struct qed_dev
*cdev
, struct dcb_app
*app
)
2251 struct qed_hwfn
*hwfn
= QED_LEADING_HWFN(cdev
);
2252 struct qed_dcbx_get
*dcbx_info
;
2253 struct qed_dcbx_set dcbx_set
;
2254 struct qed_app_entry
*entry
;
2255 struct qed_ptt
*ptt
;
2259 if (app
->priority
< 0 || app
->priority
>= QED_MAX_PFC_PRIORITIES
) {
2260 DP_INFO(hwfn
, "Invalid priority %d\n", app
->priority
);
2264 dcbx_info
= qed_dcbnl_get_dcbx(hwfn
, QED_DCBX_OPERATIONAL_MIB
);
2268 if (!dcbx_info
->operational
.ieee
) {
2269 DP_INFO(hwfn
, "DCBX is not enabled/operational in IEEE mode\n");
2276 memset(&dcbx_set
, 0, sizeof(dcbx_set
));
2277 rc
= qed_dcbx_get_config_params(hwfn
, &dcbx_set
);
2281 /* ieee defines the selector field value for ethertype to be 1 */
2282 ethtype
= !!((app
->selector
- 1) == DCB_APP_IDTYPE_ETHTYPE
);
2283 for (i
= 0; i
< QED_DCBX_MAX_APP_PROTOCOL
; i
++) {
2284 entry
= &dcbx_set
.config
.params
.app_entry
[i
];
2285 if ((entry
->ethtype
== ethtype
) &&
2286 (entry
->proto_id
== app
->protocol
))
2288 /* First empty slot */
2289 if (!entry
->proto_id
) {
2290 dcbx_set
.config
.params
.num_app_entries
++;
2295 if (i
== QED_DCBX_MAX_APP_PROTOCOL
) {
2296 DP_ERR(cdev
, "App table is full\n");
2300 dcbx_set
.override_flags
|= QED_DCBX_OVERRIDE_APP_CFG
;
2301 dcbx_set
.config
.params
.app_entry
[i
].ethtype
= ethtype
;
2302 dcbx_set
.config
.params
.app_entry
[i
].proto_id
= app
->protocol
;
2303 dcbx_set
.config
.params
.app_entry
[i
].prio
= BIT(app
->priority
);
2305 ptt
= qed_ptt_acquire(hwfn
);
2309 rc
= qed_dcbx_config_params(hwfn
, ptt
, &dcbx_set
, 0);
2311 qed_ptt_release(hwfn
, ptt
);
2316 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass
= {
2317 .getstate
= qed_dcbnl_getstate
,
2318 .setstate
= qed_dcbnl_setstate
,
2319 .getpgtccfgtx
= qed_dcbnl_getpgtccfgtx
,
2320 .getpgbwgcfgtx
= qed_dcbnl_getpgbwgcfgtx
,
2321 .getpgtccfgrx
= qed_dcbnl_getpgtccfgrx
,
2322 .getpgbwgcfgrx
= qed_dcbnl_getpgbwgcfgrx
,
2323 .getpfccfg
= qed_dcbnl_getpfccfg
,
2324 .setpfccfg
= qed_dcbnl_setpfccfg
,
2325 .getcap
= qed_dcbnl_getcap
,
2326 .getnumtcs
= qed_dcbnl_getnumtcs
,
2327 .getpfcstate
= qed_dcbnl_getpfcstate
,
2328 .getdcbx
= qed_dcbnl_getdcbx
,
2329 .setpgtccfgtx
= qed_dcbnl_setpgtccfgtx
,
2330 .setpgtccfgrx
= qed_dcbnl_setpgtccfgrx
,
2331 .setpgbwgcfgtx
= qed_dcbnl_setpgbwgcfgtx
,
2332 .setpgbwgcfgrx
= qed_dcbnl_setpgbwgcfgrx
,
2333 .setall
= qed_dcbnl_setall
,
2334 .setnumtcs
= qed_dcbnl_setnumtcs
,
2335 .setpfcstate
= qed_dcbnl_setpfcstate
,
2336 .setapp
= qed_dcbnl_setapp
,
2337 .setdcbx
= qed_dcbnl_setdcbx
,
2338 .setfeatcfg
= qed_dcbnl_setfeatcfg
,
2339 .getfeatcfg
= qed_dcbnl_getfeatcfg
,
2340 .getapp
= qed_dcbnl_getapp
,
2341 .peer_getappinfo
= qed_dcbnl_peer_getappinfo
,
2342 .peer_getapptable
= qed_dcbnl_peer_getapptable
,
2343 .cee_peer_getpfc
= qed_dcbnl_cee_peer_getpfc
,
2344 .cee_peer_getpg
= qed_dcbnl_cee_peer_getpg
,
2345 .ieee_getpfc
= qed_dcbnl_ieee_getpfc
,
2346 .ieee_setpfc
= qed_dcbnl_ieee_setpfc
,
2347 .ieee_getets
= qed_dcbnl_ieee_getets
,
2348 .ieee_setets
= qed_dcbnl_ieee_setets
,
2349 .ieee_peer_getpfc
= qed_dcbnl_ieee_peer_getpfc
,
2350 .ieee_peer_getets
= qed_dcbnl_ieee_peer_getets
,
2351 .ieee_getapp
= qed_dcbnl_ieee_getapp
,
2352 .ieee_setapp
= qed_dcbnl_ieee_setapp
,