1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2016 - 2018 Cavium Inc.
9 #include "ecore_sp_commands.h"
10 #include "ecore_dcbx.h"
11 #include "ecore_cxt.h"
12 #include "ecore_gtt_reg_addr.h"
13 #include "ecore_iro.h"
14 #include "ecore_iov_api.h"
16 #define ECORE_DCBX_MAX_MIB_READ_TRY (100)
17 #define ECORE_ETH_TYPE_DEFAULT (0)
19 #define ECORE_DCBX_INVALID_PRIORITY 0xFF
21 /* Get Traffic Class from priority traffic class table, 4 bits represent
22 * the traffic class corresponding to the priority.
24 #define ECORE_DCBX_PRIO2TC(prio_tc_tbl, prio) \
25 ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
27 static bool ecore_dcbx_app_ethtype(u32 app_info_bitmap
)
29 return !!(GET_MFW_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
33 static bool ecore_dcbx_ieee_app_ethtype(u32 app_info_bitmap
)
35 u8 mfw_val
= GET_MFW_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
38 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
39 return ecore_dcbx_app_ethtype(app_info_bitmap
);
41 return !!(mfw_val
== DCBX_APP_SF_IEEE_ETHTYPE
);
44 static bool ecore_dcbx_app_port(u32 app_info_bitmap
)
46 return !!(GET_MFW_FIELD(app_info_bitmap
, DCBX_APP_SF
) ==
50 static bool ecore_dcbx_ieee_app_port(u32 app_info_bitmap
, u8 type
)
52 u8 mfw_val
= GET_MFW_FIELD(app_info_bitmap
, DCBX_APP_SF_IEEE
);
55 if (mfw_val
== DCBX_APP_SF_IEEE_RESERVED
)
56 return ecore_dcbx_app_port(app_info_bitmap
);
58 return !!(mfw_val
== type
|| mfw_val
== DCBX_APP_SF_IEEE_TCP_UDP_PORT
);
61 static bool ecore_dcbx_default_tlv(u32 app_info_bitmap
, u16 proto_id
, bool ieee
)
66 ethtype
= ecore_dcbx_ieee_app_ethtype(app_info_bitmap
);
68 ethtype
= ecore_dcbx_app_ethtype(app_info_bitmap
);
70 return !!(ethtype
&& (proto_id
== ECORE_ETH_TYPE_DEFAULT
));
73 static bool ecore_dcbx_iwarp_tlv(struct ecore_hwfn
*p_hwfn
, u32 app_info_bitmap
,
74 u16 proto_id
, bool ieee
)
78 if (!p_hwfn
->p_dcbx_info
->iwarp_port
)
82 port
= ecore_dcbx_ieee_app_port(app_info_bitmap
,
83 DCBX_APP_SF_IEEE_TCP_PORT
);
85 port
= ecore_dcbx_app_port(app_info_bitmap
);
87 return !!(port
&& (proto_id
== p_hwfn
->p_dcbx_info
->iwarp_port
));
91 ecore_dcbx_dp_protocol(struct ecore_hwfn
*p_hwfn
,
92 struct ecore_dcbx_results
*p_data
)
94 enum dcbx_protocol_type id
;
97 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "DCBX negotiated: %d\n",
98 p_data
->dcbx_enabled
);
100 for (i
= 0; i
< OSAL_ARRAY_SIZE(ecore_dcbx_app_update
); i
++) {
101 id
= ecore_dcbx_app_update
[i
].id
;
103 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
104 "%s info: update %d, enable %d, prio %d, tc %d,"
105 " num_active_tc %d dscp_enable = %d dscp_val = %d\n",
106 ecore_dcbx_app_update
[i
].name
,
107 p_data
->arr
[id
].update
,
108 p_data
->arr
[id
].enable
, p_data
->arr
[id
].priority
,
109 p_data
->arr
[id
].tc
, p_hwfn
->hw_info
.num_active_tc
,
110 p_data
->arr
[id
].dscp_enable
,
111 p_data
->arr
[id
].dscp_val
);
115 u8
ecore_dcbx_get_dscp_value(struct ecore_hwfn
*p_hwfn
, u8 pri
)
117 struct ecore_dcbx_dscp_params
*dscp
= &p_hwfn
->p_dcbx_info
->get
.dscp
;
121 return ECORE_DCBX_DSCP_DISABLED
;
123 for (i
= 0; i
< ECORE_DCBX_DSCP_SIZE
; i
++)
124 if (pri
== dscp
->dscp_pri_map
[i
])
127 return ECORE_DCBX_DSCP_DISABLED
;
131 ecore_dcbx_set_params(struct ecore_dcbx_results
*p_data
,
132 struct ecore_hwfn
*p_hwfn
,
133 bool enable
, u8 prio
, u8 tc
,
134 enum dcbx_protocol_type type
,
135 enum ecore_pci_personality personality
)
137 /* PF update ramrod data */
138 p_data
->arr
[type
].enable
= enable
;
139 p_data
->arr
[type
].priority
= prio
;
140 p_data
->arr
[type
].tc
= tc
;
141 p_data
->arr
[type
].dscp_val
= ecore_dcbx_get_dscp_value(p_hwfn
, prio
);
142 if (p_data
->arr
[type
].dscp_val
== ECORE_DCBX_DSCP_DISABLED
) {
143 p_data
->arr
[type
].dscp_enable
= false;
144 p_data
->arr
[type
].dscp_val
= 0;
146 p_data
->arr
[type
].dscp_enable
= true;
148 p_data
->arr
[type
].update
= UPDATE_DCB_DSCP
;
150 /* Do not add valn tag 0 when DCB is enabled and port is in UFP mode */
151 if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC
, &p_hwfn
->p_dev
->mf_bits
))
152 p_data
->arr
[type
].dont_add_vlan0
= true;
155 if (p_hwfn
->hw_info
.personality
== personality
)
156 p_hwfn
->hw_info
.offload_tc
= tc
;
159 /* Update app protocol data and hw_info fields with the TLV info */
161 ecore_dcbx_update_app_info(struct ecore_dcbx_results
*p_data
,
162 struct ecore_hwfn
*p_hwfn
,
163 bool enable
, u8 prio
, u8 tc
,
164 enum dcbx_protocol_type type
)
166 enum ecore_pci_personality personality
;
167 enum dcbx_protocol_type id
;
170 for (i
= 0; i
< OSAL_ARRAY_SIZE(ecore_dcbx_app_update
); i
++) {
171 id
= ecore_dcbx_app_update
[i
].id
;
176 personality
= ecore_dcbx_app_update
[i
].personality
;
178 ecore_dcbx_set_params(p_data
, p_hwfn
, enable
,
179 prio
, tc
, type
, personality
);
183 static enum _ecore_status_t
184 ecore_dcbx_get_app_priority(u8 pri_bitmap
, u8
*priority
)
186 u32 pri_mask
, pri
= ECORE_MAX_PFC_PRIORITIES
;
187 u32 index
= ECORE_MAX_PFC_PRIORITIES
- 1;
188 enum _ecore_status_t rc
= ECORE_SUCCESS
;
190 /* Bitmap 1 corresponds to priority 0, return priority 0 */
191 if (pri_bitmap
== 1) {
196 /* Choose the highest priority */
197 while ((pri
== ECORE_MAX_PFC_PRIORITIES
) && index
) {
198 pri_mask
= 1 << index
;
199 if (pri_bitmap
& pri_mask
)
204 if (pri
< ECORE_MAX_PFC_PRIORITIES
)
213 ecore_dcbx_get_app_protocol_type(struct ecore_hwfn
*p_hwfn
,
214 u32 app_prio_bitmap
, u16 id
,
215 enum dcbx_protocol_type
*type
, bool ieee
)
217 if (ecore_dcbx_default_tlv(app_prio_bitmap
, id
, ieee
)) {
218 *type
= DCBX_PROTOCOL_ETH
;
220 *type
= DCBX_MAX_PROTOCOL_TYPE
;
221 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
222 "No action required, App TLV entry = 0x%x\n",
230 /* Parse app TLV's to update TC information in hw_info structure for
231 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
233 static enum _ecore_status_t
234 ecore_dcbx_process_tlv(struct ecore_hwfn
*p_hwfn
,
235 struct ecore_dcbx_results
*p_data
,
236 struct dcbx_app_priority_entry
*p_tbl
, u32 pri_tc_tbl
,
237 int count
, u8 dcbx_version
)
239 enum dcbx_protocol_type type
;
240 bool enable
, ieee
, eth_tlv
;
244 enum _ecore_status_t rc
= ECORE_SUCCESS
;
247 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
248 "Num APP entries = %d pri_tc_tbl = 0x%x dcbx_version = %u\n",
249 count
, pri_tc_tbl
, dcbx_version
);
251 ieee
= (dcbx_version
== DCBX_CONFIG_VERSION_IEEE
);
254 for (i
= 0; i
< count
; i
++) {
255 protocol_id
= GET_MFW_FIELD(p_tbl
[i
].entry
,
256 DCBX_APP_PROTOCOL_ID
);
257 priority_map
= GET_MFW_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
258 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "Id = 0x%x pri_map = %u\n",
259 protocol_id
, priority_map
);
260 rc
= ecore_dcbx_get_app_priority(priority_map
, &priority
);
261 if (rc
== ECORE_INVAL
) {
262 DP_ERR(p_hwfn
, "Invalid priority\n");
266 tc
= ECORE_DCBX_PRIO2TC(pri_tc_tbl
, priority
);
267 if (ecore_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
270 /* ETH always have the enable bit reset, as it gets
271 * vlan information per packet. For other protocols,
272 * should be set according to the dcbx_enabled
273 * indication, but we only got here if there was an
274 * app tlv for the protocol, so dcbx must be enabled.
276 if (type
== DCBX_PROTOCOL_ETH
) {
283 ecore_dcbx_update_app_info(p_data
, p_hwfn
, enable
,
288 /* If Eth TLV is not detected, use UFP TC as default TC */
289 if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC
,
290 &p_hwfn
->p_dev
->mf_bits
) && !eth_tlv
)
291 p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
= p_hwfn
->ufp_info
.tc
;
293 /* Update ramrod protocol data and hw_info fields
294 * with default info when corresponding APP TLV's are not detected.
295 * The enabled field has a different logic for ethernet as only for
296 * ethernet dcb should disabled by default, as the information arrives
297 * from the OS (unless an explicit app tlv was present).
299 tc
= p_data
->arr
[DCBX_PROTOCOL_ETH
].tc
;
300 priority
= p_data
->arr
[DCBX_PROTOCOL_ETH
].priority
;
301 for (type
= 0; type
< DCBX_MAX_PROTOCOL_TYPE
; type
++) {
302 if (p_data
->arr
[type
].update
)
305 enable
= (type
== DCBX_PROTOCOL_ETH
) ? false : !!dcbx_version
;
306 ecore_dcbx_update_app_info(p_data
, p_hwfn
, enable
,
310 return ECORE_SUCCESS
;
313 /* Parse app TLV's to update TC information in hw_info structure for
314 * reconfiguring QM. Get protocol specific data for PF update ramrod command.
316 static enum _ecore_status_t
317 ecore_dcbx_process_mib_info(struct ecore_hwfn
*p_hwfn
)
319 struct dcbx_app_priority_feature
*p_app
;
320 struct dcbx_app_priority_entry
*p_tbl
;
321 struct ecore_dcbx_results data
= { 0 };
322 struct dcbx_ets_feature
*p_ets
;
323 struct ecore_hw_info
*p_info
;
324 u32 pri_tc_tbl
, flags
;
327 enum _ecore_status_t rc
= ECORE_SUCCESS
;
329 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
330 dcbx_version
= GET_MFW_FIELD(flags
, DCBX_CONFIG_VERSION
);
332 p_app
= &p_hwfn
->p_dcbx_info
->operational
.features
.app
;
333 p_tbl
= p_app
->app_pri_tbl
;
335 p_ets
= &p_hwfn
->p_dcbx_info
->operational
.features
.ets
;
336 pri_tc_tbl
= p_ets
->pri_tc_tbl
[0];
338 p_info
= &p_hwfn
->hw_info
;
339 num_entries
= GET_MFW_FIELD(p_app
->flags
, DCBX_APP_NUM_ENTRIES
);
341 rc
= ecore_dcbx_process_tlv(p_hwfn
, &data
, p_tbl
, pri_tc_tbl
,
342 num_entries
, dcbx_version
);
343 if (rc
!= ECORE_SUCCESS
)
346 p_info
->num_active_tc
= GET_MFW_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
347 p_hwfn
->qm_info
.ooo_tc
= GET_MFW_FIELD(p_ets
->flags
, DCBX_OOO_TC
);
348 data
.pf_id
= p_hwfn
->rel_pf_id
;
349 data
.dcbx_enabled
= !!dcbx_version
;
351 ecore_dcbx_dp_protocol(p_hwfn
, &data
);
353 OSAL_MEMCPY(&p_hwfn
->p_dcbx_info
->results
, &data
,
354 sizeof(struct ecore_dcbx_results
));
356 return ECORE_SUCCESS
;
359 static enum _ecore_status_t
360 ecore_dcbx_copy_mib(struct ecore_hwfn
*p_hwfn
,
361 struct ecore_ptt
*p_ptt
,
362 struct ecore_dcbx_mib_meta_data
*p_data
,
363 enum ecore_mib_read_type type
)
365 u32 prefix_seq_num
, suffix_seq_num
;
367 enum _ecore_status_t rc
= ECORE_SUCCESS
;
369 /* The data is considered to be valid only if both sequence numbers are
373 if (type
== ECORE_DCBX_REMOTE_LLDP_MIB
) {
374 ecore_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_remote
,
375 p_data
->addr
, p_data
->size
);
376 prefix_seq_num
= p_data
->lldp_remote
->prefix_seq_num
;
377 suffix_seq_num
= p_data
->lldp_remote
->suffix_seq_num
;
378 } else if (type
== ECORE_DCBX_LLDP_TLVS
) {
379 ecore_memcpy_from(p_hwfn
, p_ptt
, p_data
->lldp_tlvs
,
380 p_data
->addr
, p_data
->size
);
381 prefix_seq_num
= p_data
->lldp_tlvs
->prefix_seq_num
;
382 suffix_seq_num
= p_data
->lldp_tlvs
->suffix_seq_num
;
385 ecore_memcpy_from(p_hwfn
, p_ptt
, p_data
->mib
,
386 p_data
->addr
, p_data
->size
);
387 prefix_seq_num
= p_data
->mib
->prefix_seq_num
;
388 suffix_seq_num
= p_data
->mib
->suffix_seq_num
;
392 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
393 "mib type = %d, try count = %d prefix seq num ="
394 " %d suffix seq num = %d\n",
395 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
396 } while ((prefix_seq_num
!= suffix_seq_num
) &&
397 (read_count
< ECORE_DCBX_MAX_MIB_READ_TRY
));
399 if (read_count
>= ECORE_DCBX_MAX_MIB_READ_TRY
) {
401 "MIB read err, mib type = %d, try count ="
402 " %d prefix seq num = %d suffix seq num = %d\n",
403 type
, read_count
, prefix_seq_num
, suffix_seq_num
);
411 ecore_dcbx_get_priority_info(struct ecore_hwfn
*p_hwfn
,
412 struct ecore_dcbx_app_prio
*p_prio
,
413 struct ecore_dcbx_results
*p_results
)
417 if (p_results
->arr
[DCBX_PROTOCOL_ETH
].update
&&
418 p_results
->arr
[DCBX_PROTOCOL_ETH
].enable
)
419 p_prio
->eth
= p_results
->arr
[DCBX_PROTOCOL_ETH
].priority
;
421 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
422 "Priorities: eth %d\n",
427 ecore_dcbx_get_app_data(struct ecore_hwfn
*p_hwfn
,
428 struct dcbx_app_priority_feature
*p_app
,
429 struct dcbx_app_priority_entry
*p_tbl
,
430 struct ecore_dcbx_params
*p_params
, bool ieee
)
432 struct ecore_app_entry
*entry
;
436 p_params
->app_willing
= GET_MFW_FIELD(p_app
->flags
, DCBX_APP_WILLING
);
437 p_params
->app_valid
= GET_MFW_FIELD(p_app
->flags
, DCBX_APP_ENABLED
);
438 p_params
->app_error
= GET_MFW_FIELD(p_app
->flags
, DCBX_APP_ERROR
);
439 p_params
->num_app_entries
= GET_MFW_FIELD(p_app
->flags
,
440 DCBX_APP_NUM_ENTRIES
);
441 for (i
= 0; i
< p_params
->num_app_entries
; i
++) {
442 entry
= &p_params
->app_entry
[i
];
447 sf_ieee
= GET_MFW_FIELD(p_tbl
[i
].entry
,
450 case DCBX_APP_SF_IEEE_RESERVED
:
452 val
= GET_MFW_FIELD(p_tbl
[i
].entry
,
454 entry
->sf_ieee
= val
?
455 ECORE_DCBX_SF_IEEE_TCP_UDP_PORT
:
456 ECORE_DCBX_SF_IEEE_ETHTYPE
;
458 case DCBX_APP_SF_IEEE_ETHTYPE
:
459 entry
->sf_ieee
= ECORE_DCBX_SF_IEEE_ETHTYPE
;
461 case DCBX_APP_SF_IEEE_TCP_PORT
:
462 entry
->sf_ieee
= ECORE_DCBX_SF_IEEE_TCP_PORT
;
464 case DCBX_APP_SF_IEEE_UDP_PORT
:
465 entry
->sf_ieee
= ECORE_DCBX_SF_IEEE_UDP_PORT
;
467 case DCBX_APP_SF_IEEE_TCP_UDP_PORT
:
469 ECORE_DCBX_SF_IEEE_TCP_UDP_PORT
;
473 entry
->ethtype
= !(GET_MFW_FIELD(p_tbl
[i
].entry
,
477 pri_map
= GET_MFW_FIELD(p_tbl
[i
].entry
, DCBX_APP_PRI_MAP
);
478 ecore_dcbx_get_app_priority(pri_map
, &entry
->prio
);
479 entry
->proto_id
= GET_MFW_FIELD(p_tbl
[i
].entry
,
480 DCBX_APP_PROTOCOL_ID
);
481 ecore_dcbx_get_app_protocol_type(p_hwfn
, p_tbl
[i
].entry
,
483 &entry
->proto_type
, ieee
);
486 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
487 "APP params: willing %d, valid %d error = %d\n",
488 p_params
->app_willing
, p_params
->app_valid
,
489 p_params
->app_error
);
493 ecore_dcbx_get_pfc_data(struct ecore_hwfn
*p_hwfn
,
494 u32 pfc
, struct ecore_dcbx_params
*p_params
)
498 p_params
->pfc
.willing
= GET_MFW_FIELD(pfc
, DCBX_PFC_WILLING
);
499 p_params
->pfc
.max_tc
= GET_MFW_FIELD(pfc
, DCBX_PFC_CAPS
);
500 p_params
->pfc
.enabled
= GET_MFW_FIELD(pfc
, DCBX_PFC_ENABLED
);
501 pfc_map
= GET_MFW_FIELD(pfc
, DCBX_PFC_PRI_EN_BITMAP
);
502 p_params
->pfc
.prio
[0] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_0
);
503 p_params
->pfc
.prio
[1] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_1
);
504 p_params
->pfc
.prio
[2] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_2
);
505 p_params
->pfc
.prio
[3] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_3
);
506 p_params
->pfc
.prio
[4] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_4
);
507 p_params
->pfc
.prio
[5] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_5
);
508 p_params
->pfc
.prio
[6] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_6
);
509 p_params
->pfc
.prio
[7] = !!(pfc_map
& DCBX_PFC_PRI_EN_BITMAP_PRI_7
);
511 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
512 "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n",
513 p_params
->pfc
.willing
, pfc_map
, p_params
->pfc
.max_tc
,
514 p_params
->pfc
.enabled
);
518 ecore_dcbx_get_ets_data(struct ecore_hwfn
*p_hwfn
,
519 struct dcbx_ets_feature
*p_ets
,
520 struct ecore_dcbx_params
*p_params
)
522 u32 bw_map
[2], tsa_map
[2], pri_map
;
525 p_params
->ets_willing
= GET_MFW_FIELD(p_ets
->flags
, DCBX_ETS_WILLING
);
526 p_params
->ets_enabled
= GET_MFW_FIELD(p_ets
->flags
, DCBX_ETS_ENABLED
);
527 p_params
->ets_cbs
= GET_MFW_FIELD(p_ets
->flags
, DCBX_ETS_CBS
);
528 p_params
->max_ets_tc
= GET_MFW_FIELD(p_ets
->flags
, DCBX_ETS_MAX_TCS
);
529 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
530 "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
531 p_params
->ets_willing
, p_params
->ets_enabled
,
532 p_params
->ets_cbs
, p_ets
->pri_tc_tbl
[0],
533 p_params
->max_ets_tc
);
535 /* 8 bit tsa and bw data corresponding to each of the 8 TC's are
536 * encoded in a type u32 array of size 2.
538 bw_map
[0] = OSAL_BE32_TO_CPU(p_ets
->tc_bw_tbl
[0]);
539 bw_map
[1] = OSAL_BE32_TO_CPU(p_ets
->tc_bw_tbl
[1]);
540 tsa_map
[0] = OSAL_BE32_TO_CPU(p_ets
->tc_tsa_tbl
[0]);
541 tsa_map
[1] = OSAL_BE32_TO_CPU(p_ets
->tc_tsa_tbl
[1]);
542 pri_map
= p_ets
->pri_tc_tbl
[0];
543 for (i
= 0; i
< ECORE_MAX_PFC_PRIORITIES
; i
++) {
544 p_params
->ets_tc_bw_tbl
[i
] = ((u8
*)bw_map
)[i
];
545 p_params
->ets_tc_tsa_tbl
[i
] = ((u8
*)tsa_map
)[i
];
546 p_params
->ets_pri_tc_tbl
[i
] = ECORE_DCBX_PRIO2TC(pri_map
, i
);
547 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
548 "elem %d bw_tbl %x tsa_tbl %x\n",
549 i
, p_params
->ets_tc_bw_tbl
[i
],
550 p_params
->ets_tc_tsa_tbl
[i
]);
555 ecore_dcbx_get_common_params(struct ecore_hwfn
*p_hwfn
,
556 struct dcbx_app_priority_feature
*p_app
,
557 struct dcbx_app_priority_entry
*p_tbl
,
558 struct dcbx_ets_feature
*p_ets
,
559 u32 pfc
, struct ecore_dcbx_params
*p_params
,
562 ecore_dcbx_get_app_data(p_hwfn
, p_app
, p_tbl
, p_params
, ieee
);
563 ecore_dcbx_get_ets_data(p_hwfn
, p_ets
, p_params
);
564 ecore_dcbx_get_pfc_data(p_hwfn
, pfc
, p_params
);
568 ecore_dcbx_get_local_params(struct ecore_hwfn
*p_hwfn
,
569 struct ecore_dcbx_get
*params
)
571 struct dcbx_features
*p_feat
;
573 p_feat
= &p_hwfn
->p_dcbx_info
->local_admin
.features
;
574 ecore_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
575 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
576 p_feat
->pfc
, ¶ms
->local
.params
, false);
577 params
->local
.valid
= true;
581 ecore_dcbx_get_remote_params(struct ecore_hwfn
*p_hwfn
,
582 struct ecore_dcbx_get
*params
)
584 struct dcbx_features
*p_feat
;
586 p_feat
= &p_hwfn
->p_dcbx_info
->remote
.features
;
587 ecore_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
588 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
589 p_feat
->pfc
, ¶ms
->remote
.params
,
591 params
->remote
.valid
= true;
594 static void ecore_dcbx_get_dscp_params(struct ecore_hwfn
*p_hwfn
,
595 struct ecore_dcbx_get
*params
)
597 struct ecore_dcbx_dscp_params
*p_dscp
;
598 struct dcb_dscp_map
*p_dscp_map
;
602 p_dscp
= ¶ms
->dscp
;
603 p_dscp_map
= &p_hwfn
->p_dcbx_info
->dscp_map
;
604 p_dscp
->enabled
= GET_MFW_FIELD(p_dscp_map
->flags
, DCB_DSCP_ENABLE
);
606 /* MFW encodes 64 dscp entries into 8 element array of u32 entries,
607 * where each entry holds the 4bit priority map for 8 dscp entries.
609 for (i
= 0, entry
= 0; i
< ECORE_DCBX_DSCP_SIZE
/ 8; i
++) {
610 pri_map
= OSAL_BE32_TO_CPU(p_dscp_map
->dscp_pri_map
[i
]);
611 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "elem %d pri_map 0x%x\n",
613 for (j
= 0; j
< ECORE_DCBX_DSCP_SIZE
/ 8; j
++, entry
++)
614 p_dscp
->dscp_pri_map
[entry
] = (u32
)(pri_map
>>
620 ecore_dcbx_get_operational_params(struct ecore_hwfn
*p_hwfn
,
621 struct ecore_dcbx_get
*params
)
623 struct ecore_dcbx_operational_params
*p_operational
;
624 struct ecore_dcbx_results
*p_results
;
625 struct dcbx_features
*p_feat
;
630 flags
= p_hwfn
->p_dcbx_info
->operational
.flags
;
632 /* If DCBx version is non zero, then negotiation
633 * was successfuly performed
635 p_operational
= ¶ms
->operational
;
636 enabled
= !!(GET_MFW_FIELD(flags
, DCBX_CONFIG_VERSION
) !=
637 DCBX_CONFIG_VERSION_DISABLED
);
639 p_operational
->enabled
= enabled
;
640 p_operational
->valid
= false;
641 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "Dcbx is disabled\n");
645 p_feat
= &p_hwfn
->p_dcbx_info
->operational
.features
;
646 p_results
= &p_hwfn
->p_dcbx_info
->results
;
648 val
= !!(GET_MFW_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
649 DCBX_CONFIG_VERSION_IEEE
);
650 p_operational
->ieee
= val
;
652 val
= !!(GET_MFW_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
653 DCBX_CONFIG_VERSION_CEE
);
654 p_operational
->cee
= val
;
656 val
= !!(GET_MFW_FIELD(flags
, DCBX_CONFIG_VERSION
) ==
657 DCBX_CONFIG_VERSION_STATIC
);
658 p_operational
->local
= val
;
660 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
661 "Version support: ieee %d, cee %d, static %d\n",
662 p_operational
->ieee
, p_operational
->cee
,
663 p_operational
->local
);
665 ecore_dcbx_get_common_params(p_hwfn
, &p_feat
->app
,
666 p_feat
->app
.app_pri_tbl
, &p_feat
->ets
,
667 p_feat
->pfc
, ¶ms
->operational
.params
,
668 p_operational
->ieee
);
669 ecore_dcbx_get_priority_info(p_hwfn
, &p_operational
->app_prio
,
671 err
= GET_MFW_FIELD(p_feat
->app
.flags
, DCBX_APP_ERROR
);
672 p_operational
->err
= err
;
673 p_operational
->enabled
= enabled
;
674 p_operational
->valid
= true;
677 static void ecore_dcbx_get_local_lldp_params(struct ecore_hwfn
*p_hwfn
,
678 struct ecore_dcbx_get
*params
)
680 struct lldp_config_params_s
*p_local
;
682 p_local
= &p_hwfn
->p_dcbx_info
->lldp_local
[LLDP_NEAREST_BRIDGE
];
684 OSAL_MEMCPY(params
->lldp_local
.local_chassis_id
,
685 p_local
->local_chassis_id
,
686 sizeof(params
->lldp_local
.local_chassis_id
));
687 OSAL_MEMCPY(params
->lldp_local
.local_port_id
, p_local
->local_port_id
,
688 sizeof(params
->lldp_local
.local_port_id
));
691 static void ecore_dcbx_get_remote_lldp_params(struct ecore_hwfn
*p_hwfn
,
692 struct ecore_dcbx_get
*params
)
694 struct lldp_status_params_s
*p_remote
;
696 p_remote
= &p_hwfn
->p_dcbx_info
->lldp_remote
[LLDP_NEAREST_BRIDGE
];
698 OSAL_MEMCPY(params
->lldp_remote
.peer_chassis_id
,
699 p_remote
->peer_chassis_id
,
700 sizeof(params
->lldp_remote
.peer_chassis_id
));
701 OSAL_MEMCPY(params
->lldp_remote
.peer_port_id
, p_remote
->peer_port_id
,
702 sizeof(params
->lldp_remote
.peer_port_id
));
705 static enum _ecore_status_t
706 ecore_dcbx_get_params(struct ecore_hwfn
*p_hwfn
,
707 struct ecore_dcbx_get
*p_params
,
708 enum ecore_mib_read_type type
)
711 case ECORE_DCBX_REMOTE_MIB
:
712 ecore_dcbx_get_remote_params(p_hwfn
, p_params
);
714 case ECORE_DCBX_LOCAL_MIB
:
715 ecore_dcbx_get_local_params(p_hwfn
, p_params
);
717 case ECORE_DCBX_OPERATIONAL_MIB
:
718 ecore_dcbx_get_operational_params(p_hwfn
, p_params
);
720 case ECORE_DCBX_REMOTE_LLDP_MIB
:
721 ecore_dcbx_get_remote_lldp_params(p_hwfn
, p_params
);
723 case ECORE_DCBX_LOCAL_LLDP_MIB
:
724 ecore_dcbx_get_local_lldp_params(p_hwfn
, p_params
);
727 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
731 return ECORE_SUCCESS
;
734 static enum _ecore_status_t
735 ecore_dcbx_read_local_lldp_mib(struct ecore_hwfn
*p_hwfn
,
736 struct ecore_ptt
*p_ptt
)
738 struct ecore_dcbx_mib_meta_data data
;
739 enum _ecore_status_t rc
= ECORE_SUCCESS
;
741 OSAL_MEM_ZERO(&data
, sizeof(data
));
742 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
744 data
.lldp_local
= p_hwfn
->p_dcbx_info
->lldp_local
;
745 data
.size
= sizeof(struct lldp_config_params_s
);
746 ecore_memcpy_from(p_hwfn
, p_ptt
, data
.lldp_local
, data
.addr
, data
.size
);
751 static enum _ecore_status_t
752 ecore_dcbx_read_remote_lldp_mib(struct ecore_hwfn
*p_hwfn
,
753 struct ecore_ptt
*p_ptt
,
754 enum ecore_mib_read_type type
)
756 struct ecore_dcbx_mib_meta_data data
;
757 enum _ecore_status_t rc
= ECORE_SUCCESS
;
759 OSAL_MEM_ZERO(&data
, sizeof(data
));
760 data
.addr
= p_hwfn
->mcp_info
->port_addr
+ offsetof(struct public_port
,
762 data
.lldp_remote
= p_hwfn
->p_dcbx_info
->lldp_remote
;
763 data
.size
= sizeof(struct lldp_status_params_s
);
764 rc
= ecore_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
769 static enum _ecore_status_t
770 ecore_dcbx_read_operational_mib(struct ecore_hwfn
*p_hwfn
,
771 struct ecore_ptt
*p_ptt
,
772 enum ecore_mib_read_type type
)
774 struct ecore_dcbx_mib_meta_data data
;
775 enum _ecore_status_t rc
= ECORE_SUCCESS
;
777 OSAL_MEM_ZERO(&data
, sizeof(data
));
778 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
779 offsetof(struct public_port
, operational_dcbx_mib
);
780 data
.mib
= &p_hwfn
->p_dcbx_info
->operational
;
781 data
.size
= sizeof(struct dcbx_mib
);
782 rc
= ecore_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
787 static enum _ecore_status_t
788 ecore_dcbx_read_remote_mib(struct ecore_hwfn
*p_hwfn
,
789 struct ecore_ptt
*p_ptt
,
790 enum ecore_mib_read_type type
)
792 struct ecore_dcbx_mib_meta_data data
;
793 enum _ecore_status_t rc
= ECORE_SUCCESS
;
795 OSAL_MEM_ZERO(&data
, sizeof(data
));
796 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
797 offsetof(struct public_port
, remote_dcbx_mib
);
798 data
.mib
= &p_hwfn
->p_dcbx_info
->remote
;
799 data
.size
= sizeof(struct dcbx_mib
);
800 rc
= ecore_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
, type
);
805 static enum _ecore_status_t
806 ecore_dcbx_read_local_mib(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
)
808 struct ecore_dcbx_mib_meta_data data
;
809 enum _ecore_status_t rc
= ECORE_SUCCESS
;
811 OSAL_MEM_ZERO(&data
, sizeof(data
));
812 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
813 offsetof(struct public_port
, local_admin_dcbx_mib
);
814 data
.local_admin
= &p_hwfn
->p_dcbx_info
->local_admin
;
815 data
.size
= sizeof(struct dcbx_local_params
);
816 ecore_memcpy_from(p_hwfn
, p_ptt
, data
.local_admin
,
817 data
.addr
, data
.size
);
823 ecore_dcbx_read_dscp_mib(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
)
825 struct ecore_dcbx_mib_meta_data data
;
827 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
828 offsetof(struct public_port
, dcb_dscp_map
);
829 data
.dscp_map
= &p_hwfn
->p_dcbx_info
->dscp_map
;
830 data
.size
= sizeof(struct dcb_dscp_map
);
831 ecore_memcpy_from(p_hwfn
, p_ptt
, data
.dscp_map
, data
.addr
, data
.size
);
834 static enum _ecore_status_t
ecore_dcbx_read_mib(struct ecore_hwfn
*p_hwfn
,
835 struct ecore_ptt
*p_ptt
,
836 enum ecore_mib_read_type type
)
838 enum _ecore_status_t rc
= ECORE_INVAL
;
841 case ECORE_DCBX_OPERATIONAL_MIB
:
842 ecore_dcbx_read_dscp_mib(p_hwfn
, p_ptt
);
843 rc
= ecore_dcbx_read_operational_mib(p_hwfn
, p_ptt
, type
);
845 case ECORE_DCBX_REMOTE_MIB
:
846 rc
= ecore_dcbx_read_remote_mib(p_hwfn
, p_ptt
, type
);
848 case ECORE_DCBX_LOCAL_MIB
:
849 rc
= ecore_dcbx_read_local_mib(p_hwfn
, p_ptt
);
851 case ECORE_DCBX_REMOTE_LLDP_MIB
:
852 rc
= ecore_dcbx_read_remote_lldp_mib(p_hwfn
, p_ptt
, type
);
854 case ECORE_DCBX_LOCAL_LLDP_MIB
:
855 rc
= ecore_dcbx_read_local_lldp_mib(p_hwfn
, p_ptt
);
858 DP_ERR(p_hwfn
, "MIB read err, unknown mib type %d\n", type
);
861 return ECORE_SUCCESS
;
866 * Reconfigure QM and invoke PF update ramrod command if operational MIB
867 * change is detected.
870 ecore_dcbx_mib_update_event(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
871 enum ecore_mib_read_type type
)
873 enum _ecore_status_t rc
= ECORE_SUCCESS
;
875 rc
= ecore_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
879 if (type
== ECORE_DCBX_OPERATIONAL_MIB
) {
880 ecore_dcbx_get_dscp_params(p_hwfn
, &p_hwfn
->p_dcbx_info
->get
);
882 rc
= ecore_dcbx_process_mib_info(p_hwfn
);
884 /* reconfigure tcs of QM queues according
885 * to negotiation results
887 ecore_qm_reconf(p_hwfn
, p_ptt
);
889 /* update storm FW with negotiation results */
890 ecore_sp_pf_update_dcbx(p_hwfn
);
894 ecore_dcbx_get_params(p_hwfn
, &p_hwfn
->p_dcbx_info
->get
, type
);
896 /* Update the DSCP to TC mapping bit if required */
897 if ((type
== ECORE_DCBX_OPERATIONAL_MIB
) &&
898 p_hwfn
->p_dcbx_info
->dscp_nig_update
) {
899 u8 val
= !!p_hwfn
->p_dcbx_info
->get
.dscp
.enabled
;
901 ecore_wr(p_hwfn
, p_ptt
, NIG_REG_DSCP_TO_TC_MAP_ENABLE
, val
);
902 p_hwfn
->p_dcbx_info
->dscp_nig_update
= false;
905 OSAL_DCBX_AEN(p_hwfn
, type
);
910 enum _ecore_status_t
ecore_dcbx_info_alloc(struct ecore_hwfn
*p_hwfn
)
912 p_hwfn
->p_dcbx_info
= OSAL_ZALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
913 sizeof(*p_hwfn
->p_dcbx_info
));
914 if (!p_hwfn
->p_dcbx_info
) {
915 DP_NOTICE(p_hwfn
, false,
916 "Failed to allocate `struct ecore_dcbx_info'");
920 p_hwfn
->p_dcbx_info
->iwarp_port
=
921 p_hwfn
->pf_params
.rdma_pf_params
.iwarp_port
;
923 return ECORE_SUCCESS
;
926 void ecore_dcbx_info_free(struct ecore_hwfn
*p_hwfn
)
928 OSAL_FREE(p_hwfn
->p_dev
, p_hwfn
->p_dcbx_info
);
931 static void ecore_dcbx_update_protocol_data(struct protocol_dcb_data
*p_data
,
932 struct ecore_dcbx_results
*p_src
,
933 enum dcbx_protocol_type type
)
935 p_data
->dcb_enable_flag
= p_src
->arr
[type
].enable
;
936 p_data
->dcb_priority
= p_src
->arr
[type
].priority
;
937 p_data
->dcb_tc
= p_src
->arr
[type
].tc
;
938 p_data
->dscp_enable_flag
= p_src
->arr
[type
].dscp_enable
;
939 p_data
->dscp_val
= p_src
->arr
[type
].dscp_val
;
940 p_data
->dcb_dont_add_vlan0
= p_src
->arr
[type
].dont_add_vlan0
;
943 /* Set pf update ramrod command params */
944 void ecore_dcbx_set_pf_update_params(struct ecore_dcbx_results
*p_src
,
945 struct pf_update_ramrod_data
*p_dest
)
947 struct protocol_dcb_data
*p_dcb_data
;
950 update_flag
= p_src
->arr
[DCBX_PROTOCOL_ETH
].update
;
951 p_dest
->update_eth_dcb_data_mode
= update_flag
;
952 update_flag
= p_src
->arr
[DCBX_PROTOCOL_IWARP
].update
;
953 p_dest
->update_iwarp_dcb_data_mode
= update_flag
;
955 p_dcb_data
= &p_dest
->eth_dcb_data
;
956 ecore_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_ETH
);
957 p_dcb_data
= &p_dest
->iwarp_dcb_data
;
958 ecore_dcbx_update_protocol_data(p_dcb_data
, p_src
, DCBX_PROTOCOL_IWARP
);
961 enum _ecore_status_t
ecore_dcbx_query_params(struct ecore_hwfn
*p_hwfn
,
962 struct ecore_dcbx_get
*p_get
,
963 enum ecore_mib_read_type type
)
965 struct ecore_ptt
*p_ptt
;
966 enum _ecore_status_t rc
;
968 if (IS_VF(p_hwfn
->p_dev
))
971 p_ptt
= ecore_ptt_acquire(p_hwfn
);
973 return ECORE_TIMEOUT
;
975 rc
= ecore_dcbx_read_mib(p_hwfn
, p_ptt
, type
);
976 if (rc
!= ECORE_SUCCESS
)
979 ecore_dcbx_get_dscp_params(p_hwfn
, p_get
);
981 rc
= ecore_dcbx_get_params(p_hwfn
, p_get
, type
);
984 ecore_ptt_release(p_hwfn
, p_ptt
);
989 ecore_dcbx_set_pfc_data(struct ecore_hwfn
*p_hwfn
,
990 u32
*pfc
, struct ecore_dcbx_params
*p_params
)
995 if (p_params
->pfc
.willing
)
996 *pfc
|= DCBX_PFC_WILLING_MASK
;
998 *pfc
&= ~DCBX_PFC_WILLING_MASK
;
1000 if (p_params
->pfc
.enabled
)
1001 *pfc
|= DCBX_PFC_ENABLED_MASK
;
1003 *pfc
&= ~DCBX_PFC_ENABLED_MASK
;
1005 *pfc
&= ~DCBX_PFC_CAPS_MASK
;
1006 *pfc
|= (u32
)p_params
->pfc
.max_tc
<< DCBX_PFC_CAPS_OFFSET
;
1008 for (i
= 0; i
< ECORE_MAX_PFC_PRIORITIES
; i
++)
1009 if (p_params
->pfc
.prio
[i
])
1010 pfc_map
|= (1 << i
);
1011 *pfc
&= ~DCBX_PFC_PRI_EN_BITMAP_MASK
;
1012 *pfc
|= (pfc_map
<< DCBX_PFC_PRI_EN_BITMAP_OFFSET
);
1014 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "pfc = 0x%x\n", *pfc
);
1018 ecore_dcbx_set_ets_data(struct ecore_hwfn
*p_hwfn
,
1019 struct dcbx_ets_feature
*p_ets
,
1020 struct ecore_dcbx_params
*p_params
)
1022 u8
*bw_map
, *tsa_map
;
1026 if (p_params
->ets_willing
)
1027 p_ets
->flags
|= DCBX_ETS_WILLING_MASK
;
1029 p_ets
->flags
&= ~DCBX_ETS_WILLING_MASK
;
1031 if (p_params
->ets_cbs
)
1032 p_ets
->flags
|= DCBX_ETS_CBS_MASK
;
1034 p_ets
->flags
&= ~DCBX_ETS_CBS_MASK
;
1036 if (p_params
->ets_enabled
)
1037 p_ets
->flags
|= DCBX_ETS_ENABLED_MASK
;
1039 p_ets
->flags
&= ~DCBX_ETS_ENABLED_MASK
;
1041 p_ets
->flags
&= ~DCBX_ETS_MAX_TCS_MASK
;
1042 p_ets
->flags
|= (u32
)p_params
->max_ets_tc
<< DCBX_ETS_MAX_TCS_OFFSET
;
1044 bw_map
= (u8
*)&p_ets
->tc_bw_tbl
[0];
1045 tsa_map
= (u8
*)&p_ets
->tc_tsa_tbl
[0];
1046 p_ets
->pri_tc_tbl
[0] = 0;
1047 for (i
= 0; i
< ECORE_MAX_PFC_PRIORITIES
; i
++) {
1048 bw_map
[i
] = p_params
->ets_tc_bw_tbl
[i
];
1049 tsa_map
[i
] = p_params
->ets_tc_tsa_tbl
[i
];
1050 /* Copy the priority value to the corresponding 4 bits in the
1051 * traffic class table.
1053 val
= (((u32
)p_params
->ets_pri_tc_tbl
[i
]) << ((7 - i
) * 4));
1054 p_ets
->pri_tc_tbl
[0] |= val
;
1056 for (i
= 0; i
< 2; i
++) {
1057 p_ets
->tc_bw_tbl
[i
] = OSAL_CPU_TO_BE32(p_ets
->tc_bw_tbl
[i
]);
1058 p_ets
->tc_tsa_tbl
[i
] = OSAL_CPU_TO_BE32(p_ets
->tc_tsa_tbl
[i
]);
1061 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
1062 "flags = 0x%x pri_tc = 0x%x tc_bwl[] = {0x%x, 0x%x} tc_tsa = {0x%x, 0x%x}\n",
1063 p_ets
->flags
, p_ets
->pri_tc_tbl
[0], p_ets
->tc_bw_tbl
[0],
1064 p_ets
->tc_bw_tbl
[1], p_ets
->tc_tsa_tbl
[0],
1065 p_ets
->tc_tsa_tbl
[1]);
1069 ecore_dcbx_set_app_data(struct ecore_hwfn
*p_hwfn
,
1070 struct dcbx_app_priority_feature
*p_app
,
1071 struct ecore_dcbx_params
*p_params
, bool ieee
)
1076 if (p_params
->app_willing
)
1077 p_app
->flags
|= DCBX_APP_WILLING_MASK
;
1079 p_app
->flags
&= ~DCBX_APP_WILLING_MASK
;
1081 if (p_params
->app_valid
)
1082 p_app
->flags
|= DCBX_APP_ENABLED_MASK
;
1084 p_app
->flags
&= ~DCBX_APP_ENABLED_MASK
;
1086 p_app
->flags
&= ~DCBX_APP_NUM_ENTRIES_MASK
;
1087 p_app
->flags
|= (u32
)p_params
->num_app_entries
<<
1088 DCBX_APP_NUM_ENTRIES_OFFSET
;
1090 for (i
= 0; i
< p_params
->num_app_entries
; i
++) {
1091 entry
= &p_app
->app_pri_tbl
[i
].entry
;
1094 *entry
&= ~(DCBX_APP_SF_IEEE_MASK
| DCBX_APP_SF_MASK
);
1095 switch (p_params
->app_entry
[i
].sf_ieee
) {
1096 case ECORE_DCBX_SF_IEEE_ETHTYPE
:
1097 *entry
|= ((u32
)DCBX_APP_SF_IEEE_ETHTYPE
<<
1098 DCBX_APP_SF_IEEE_OFFSET
);
1099 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1100 DCBX_APP_SF_OFFSET
);
1102 case ECORE_DCBX_SF_IEEE_TCP_PORT
:
1103 *entry
|= ((u32
)DCBX_APP_SF_IEEE_TCP_PORT
<<
1104 DCBX_APP_SF_IEEE_OFFSET
);
1105 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1106 DCBX_APP_SF_OFFSET
);
1108 case ECORE_DCBX_SF_IEEE_UDP_PORT
:
1109 *entry
|= ((u32
)DCBX_APP_SF_IEEE_UDP_PORT
<<
1110 DCBX_APP_SF_IEEE_OFFSET
);
1111 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1112 DCBX_APP_SF_OFFSET
);
1114 case ECORE_DCBX_SF_IEEE_TCP_UDP_PORT
:
1115 *entry
|= (u32
)DCBX_APP_SF_IEEE_TCP_UDP_PORT
<<
1116 DCBX_APP_SF_IEEE_OFFSET
;
1117 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1118 DCBX_APP_SF_OFFSET
);
1122 *entry
&= ~DCBX_APP_SF_MASK
;
1123 if (p_params
->app_entry
[i
].ethtype
)
1124 *entry
|= ((u32
)DCBX_APP_SF_ETHTYPE
<<
1125 DCBX_APP_SF_OFFSET
);
1127 *entry
|= ((u32
)DCBX_APP_SF_PORT
<<
1128 DCBX_APP_SF_OFFSET
);
1130 *entry
&= ~DCBX_APP_PROTOCOL_ID_MASK
;
1131 *entry
|= ((u32
)p_params
->app_entry
[i
].proto_id
<<
1132 DCBX_APP_PROTOCOL_ID_OFFSET
);
1133 *entry
&= ~DCBX_APP_PRI_MAP_MASK
;
1134 *entry
|= ((u32
)(p_params
->app_entry
[i
].prio
) <<
1135 DCBX_APP_PRI_MAP_OFFSET
);
1138 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "flags = 0x%x\n", p_app
->flags
);
1142 ecore_dcbx_set_local_params(struct ecore_hwfn
*p_hwfn
,
1143 struct dcbx_local_params
*local_admin
,
1144 struct ecore_dcbx_set
*params
)
1148 local_admin
->flags
= 0;
1149 OSAL_MEMCPY(&local_admin
->features
,
1150 &p_hwfn
->p_dcbx_info
->operational
.features
,
1151 sizeof(local_admin
->features
));
1153 if (params
->enabled
) {
1154 local_admin
->config
= params
->ver_num
;
1155 ieee
= !!(params
->ver_num
& DCBX_CONFIG_VERSION_IEEE
);
1157 local_admin
->config
= DCBX_CONFIG_VERSION_DISABLED
;
1160 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "Dcbx version = %d\n",
1161 local_admin
->config
);
1163 if (params
->override_flags
& ECORE_DCBX_OVERRIDE_PFC_CFG
)
1164 ecore_dcbx_set_pfc_data(p_hwfn
, &local_admin
->features
.pfc
,
1165 ¶ms
->config
.params
);
1167 if (params
->override_flags
& ECORE_DCBX_OVERRIDE_ETS_CFG
)
1168 ecore_dcbx_set_ets_data(p_hwfn
, &local_admin
->features
.ets
,
1169 ¶ms
->config
.params
);
1171 if (params
->override_flags
& ECORE_DCBX_OVERRIDE_APP_CFG
)
1172 ecore_dcbx_set_app_data(p_hwfn
, &local_admin
->features
.app
,
1173 ¶ms
->config
.params
, ieee
);
1176 static enum _ecore_status_t
1177 ecore_dcbx_set_dscp_params(struct ecore_hwfn
*p_hwfn
,
1178 struct dcb_dscp_map
*p_dscp_map
,
1179 struct ecore_dcbx_set
*p_params
)
1184 OSAL_MEMCPY(p_dscp_map
, &p_hwfn
->p_dcbx_info
->dscp_map
,
1185 sizeof(*p_dscp_map
));
1187 p_dscp_map
->flags
&= ~DCB_DSCP_ENABLE_MASK
;
1188 if (p_params
->dscp
.enabled
)
1189 p_dscp_map
->flags
|= DCB_DSCP_ENABLE_MASK
;
1191 for (i
= 0, entry
= 0; i
< 8; i
++) {
1193 for (j
= 0; j
< 8; j
++, entry
++)
1194 val
|= (((u32
)p_params
->dscp
.dscp_pri_map
[entry
]) <<
1197 p_dscp_map
->dscp_pri_map
[i
] = OSAL_CPU_TO_BE32(val
);
1200 p_hwfn
->p_dcbx_info
->dscp_nig_update
= true;
1202 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
, "flags = 0x%x\n", p_dscp_map
->flags
);
1203 DP_VERBOSE(p_hwfn
, ECORE_MSG_DCB
,
1204 "pri_map[] = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1205 p_dscp_map
->dscp_pri_map
[0], p_dscp_map
->dscp_pri_map
[1],
1206 p_dscp_map
->dscp_pri_map
[2], p_dscp_map
->dscp_pri_map
[3],
1207 p_dscp_map
->dscp_pri_map
[4], p_dscp_map
->dscp_pri_map
[5],
1208 p_dscp_map
->dscp_pri_map
[6], p_dscp_map
->dscp_pri_map
[7]);
1210 return ECORE_SUCCESS
;
1213 enum _ecore_status_t
ecore_dcbx_config_params(struct ecore_hwfn
*p_hwfn
,
1214 struct ecore_ptt
*p_ptt
,
1215 struct ecore_dcbx_set
*params
,
1218 struct dcbx_local_params local_admin
;
1219 struct ecore_dcbx_mib_meta_data data
;
1220 struct dcb_dscp_map dscp_map
;
1221 u32 resp
= 0, param
= 0;
1222 enum _ecore_status_t rc
= ECORE_SUCCESS
;
1224 OSAL_MEMCPY(&p_hwfn
->p_dcbx_info
->set
, params
,
1225 sizeof(p_hwfn
->p_dcbx_info
->set
));
1227 return ECORE_SUCCESS
;
1229 OSAL_MEMSET(&local_admin
, 0, sizeof(local_admin
));
1230 ecore_dcbx_set_local_params(p_hwfn
, &local_admin
, params
);
1232 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1233 offsetof(struct public_port
, local_admin_dcbx_mib
);
1234 data
.local_admin
= &local_admin
;
1235 data
.size
= sizeof(struct dcbx_local_params
);
1236 ecore_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.local_admin
, data
.size
);
1238 if (params
->override_flags
& ECORE_DCBX_OVERRIDE_DSCP_CFG
) {
1239 OSAL_MEMSET(&dscp_map
, 0, sizeof(dscp_map
));
1240 ecore_dcbx_set_dscp_params(p_hwfn
, &dscp_map
, params
);
1242 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1243 offsetof(struct public_port
, dcb_dscp_map
);
1244 data
.dscp_map
= &dscp_map
;
1245 data
.size
= sizeof(struct dcb_dscp_map
);
1246 ecore_memcpy_to(p_hwfn
, p_ptt
, data
.addr
, data
.dscp_map
,
1250 rc
= ecore_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_DCBX
,
1251 1 << DRV_MB_PARAM_LLDP_SEND_OFFSET
, &resp
, ¶m
);
1252 if (rc
!= ECORE_SUCCESS
)
1253 DP_NOTICE(p_hwfn
, false,
1254 "Failed to send DCBX update request\n");
1259 enum _ecore_status_t
ecore_dcbx_get_config_params(struct ecore_hwfn
*p_hwfn
,
1260 struct ecore_dcbx_set
*params
)
1262 struct ecore_dcbx_get
*dcbx_info
;
1265 if (p_hwfn
->p_dcbx_info
->set
.config
.valid
) {
1266 OSAL_MEMCPY(params
, &p_hwfn
->p_dcbx_info
->set
,
1267 sizeof(struct ecore_dcbx_set
));
1268 return ECORE_SUCCESS
;
1271 dcbx_info
= OSAL_ALLOC(p_hwfn
->p_dev
, GFP_KERNEL
,
1272 sizeof(*dcbx_info
));
1276 OSAL_MEMSET(dcbx_info
, 0, sizeof(*dcbx_info
));
1277 rc
= ecore_dcbx_query_params(p_hwfn
, dcbx_info
,
1278 ECORE_DCBX_OPERATIONAL_MIB
);
1280 OSAL_FREE(p_hwfn
->p_dev
, dcbx_info
);
1283 p_hwfn
->p_dcbx_info
->set
.override_flags
= 0;
1285 p_hwfn
->p_dcbx_info
->set
.ver_num
= DCBX_CONFIG_VERSION_DISABLED
;
1286 if (dcbx_info
->operational
.cee
)
1287 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_CEE
;
1288 if (dcbx_info
->operational
.ieee
)
1289 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_IEEE
;
1290 if (dcbx_info
->operational
.local
)
1291 p_hwfn
->p_dcbx_info
->set
.ver_num
|= DCBX_CONFIG_VERSION_STATIC
;
1293 p_hwfn
->p_dcbx_info
->set
.enabled
= dcbx_info
->operational
.enabled
;
1294 OSAL_MEMCPY(&p_hwfn
->p_dcbx_info
->set
.dscp
,
1295 &p_hwfn
->p_dcbx_info
->get
.dscp
,
1296 sizeof(struct ecore_dcbx_dscp_params
));
1297 OSAL_MEMCPY(&p_hwfn
->p_dcbx_info
->set
.config
.params
,
1298 &dcbx_info
->operational
.params
,
1299 sizeof(p_hwfn
->p_dcbx_info
->set
.config
.params
));
1300 p_hwfn
->p_dcbx_info
->set
.config
.valid
= true;
1302 OSAL_MEMCPY(params
, &p_hwfn
->p_dcbx_info
->set
,
1303 sizeof(struct ecore_dcbx_set
));
1305 OSAL_FREE(p_hwfn
->p_dev
, dcbx_info
);
1307 return ECORE_SUCCESS
;
1310 enum _ecore_status_t
ecore_lldp_register_tlv(struct ecore_hwfn
*p_hwfn
,
1311 struct ecore_ptt
*p_ptt
,
1312 enum ecore_lldp_agent agent
,
1315 u32 mb_param
= 0, mcp_resp
= 0, mcp_param
= 0, val
= 0;
1316 enum _ecore_status_t rc
= ECORE_SUCCESS
;
1319 case ECORE_LLDP_NEAREST_BRIDGE
:
1320 val
= LLDP_NEAREST_BRIDGE
;
1322 case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE
:
1323 val
= LLDP_NEAREST_NON_TPMR_BRIDGE
;
1325 case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE
:
1326 val
= LLDP_NEAREST_CUSTOMER_BRIDGE
;
1329 DP_ERR(p_hwfn
, "Invalid agent type %d\n", agent
);
1333 SET_MFW_FIELD(mb_param
, DRV_MB_PARAM_LLDP_AGENT
, val
);
1334 SET_MFW_FIELD(mb_param
, DRV_MB_PARAM_LLDP_TLV_RX_TYPE
, tlv_type
);
1336 rc
= ecore_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_REGISTER_LLDP_TLVS_RX
,
1337 mb_param
, &mcp_resp
, &mcp_param
);
1338 if (rc
!= ECORE_SUCCESS
)
1339 DP_NOTICE(p_hwfn
, false, "Failed to register TLV\n");
1344 enum _ecore_status_t
1345 ecore_lldp_mib_update_event(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
)
1347 struct ecore_dcbx_mib_meta_data data
;
1348 enum _ecore_status_t rc
= ECORE_SUCCESS
;
1349 struct lldp_received_tlvs_s tlvs
;
1352 for (i
= 0; i
< LLDP_MAX_LLDP_AGENTS
; i
++) {
1353 OSAL_MEM_ZERO(&data
, sizeof(data
));
1354 data
.addr
= p_hwfn
->mcp_info
->port_addr
+
1355 offsetof(struct public_port
, lldp_received_tlvs
[i
]);
1356 data
.lldp_tlvs
= &tlvs
;
1357 data
.size
= sizeof(tlvs
);
1358 rc
= ecore_dcbx_copy_mib(p_hwfn
, p_ptt
, &data
,
1359 ECORE_DCBX_LLDP_TLVS
);
1360 if (rc
!= ECORE_SUCCESS
) {
1361 DP_NOTICE(p_hwfn
, false, "Failed to read lldp TLVs\n");
1368 for (i
= 0; i
< MAX_TLV_BUFFER
; i
++)
1369 tlvs
.tlvs_buffer
[i
] =
1370 OSAL_CPU_TO_BE32(tlvs
.tlvs_buffer
[i
]);
1372 OSAL_LLDP_RX_TLVS(p_hwfn
, tlvs
.tlvs_buffer
, tlvs
.length
);
1378 enum _ecore_status_t
1379 ecore_lldp_get_params(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1380 struct ecore_lldp_config_params
*p_params
)
1382 struct lldp_config_params_s lldp_params
;
1386 switch (p_params
->agent
) {
1387 case ECORE_LLDP_NEAREST_BRIDGE
:
1388 val
= LLDP_NEAREST_BRIDGE
;
1390 case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE
:
1391 val
= LLDP_NEAREST_NON_TPMR_BRIDGE
;
1393 case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE
:
1394 val
= LLDP_NEAREST_CUSTOMER_BRIDGE
;
1397 DP_ERR(p_hwfn
, "Invalid agent type %d\n", p_params
->agent
);
1401 addr
= p_hwfn
->mcp_info
->port_addr
+
1402 offsetof(struct public_port
, lldp_config_params
[val
]);
1404 ecore_memcpy_from(p_hwfn
, p_ptt
, &lldp_params
, addr
,
1405 sizeof(lldp_params
));
1407 p_params
->tx_interval
= GET_MFW_FIELD(lldp_params
.config
,
1408 LLDP_CONFIG_TX_INTERVAL
);
1409 p_params
->tx_hold
= GET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_HOLD
);
1410 p_params
->tx_credit
= GET_MFW_FIELD(lldp_params
.config
,
1411 LLDP_CONFIG_MAX_CREDIT
);
1412 p_params
->rx_enable
= GET_MFW_FIELD(lldp_params
.config
,
1413 LLDP_CONFIG_ENABLE_RX
);
1414 p_params
->tx_enable
= GET_MFW_FIELD(lldp_params
.config
,
1415 LLDP_CONFIG_ENABLE_TX
);
1417 OSAL_MEMCPY(p_params
->chassis_id_tlv
, lldp_params
.local_chassis_id
,
1418 sizeof(p_params
->chassis_id_tlv
));
1419 for (i
= 0; i
< ECORE_LLDP_CHASSIS_ID_STAT_LEN
; i
++)
1420 p_params
->chassis_id_tlv
[i
] =
1421 OSAL_BE32_TO_CPU(p_params
->chassis_id_tlv
[i
]);
1423 OSAL_MEMCPY(p_params
->port_id_tlv
, lldp_params
.local_port_id
,
1424 sizeof(p_params
->port_id_tlv
));
1425 for (i
= 0; i
< ECORE_LLDP_PORT_ID_STAT_LEN
; i
++)
1426 p_params
->port_id_tlv
[i
] =
1427 OSAL_BE32_TO_CPU(p_params
->port_id_tlv
[i
]);
1429 return ECORE_SUCCESS
;
1432 enum _ecore_status_t
1433 ecore_lldp_set_params(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1434 struct ecore_lldp_config_params
*p_params
)
1436 u32 mb_param
= 0, mcp_resp
= 0, mcp_param
= 0;
1437 struct lldp_config_params_s lldp_params
;
1438 enum _ecore_status_t rc
= ECORE_SUCCESS
;
1442 switch (p_params
->agent
) {
1443 case ECORE_LLDP_NEAREST_BRIDGE
:
1444 val
= LLDP_NEAREST_BRIDGE
;
1446 case ECORE_LLDP_NEAREST_NON_TPMR_BRIDGE
:
1447 val
= LLDP_NEAREST_NON_TPMR_BRIDGE
;
1449 case ECORE_LLDP_NEAREST_CUSTOMER_BRIDGE
:
1450 val
= LLDP_NEAREST_CUSTOMER_BRIDGE
;
1453 DP_ERR(p_hwfn
, "Invalid agent type %d\n", p_params
->agent
);
1457 SET_MFW_FIELD(mb_param
, DRV_MB_PARAM_LLDP_AGENT
, val
);
1458 addr
= p_hwfn
->mcp_info
->port_addr
+
1459 offsetof(struct public_port
, lldp_config_params
[val
]);
1461 OSAL_MEMSET(&lldp_params
, 0, sizeof(lldp_params
));
1462 SET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_TX_INTERVAL
,
1463 p_params
->tx_interval
);
1464 SET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_HOLD
, p_params
->tx_hold
);
1465 SET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_MAX_CREDIT
,
1466 p_params
->tx_credit
);
1467 SET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_ENABLE_RX
,
1468 !!p_params
->rx_enable
);
1469 SET_MFW_FIELD(lldp_params
.config
, LLDP_CONFIG_ENABLE_TX
,
1470 !!p_params
->tx_enable
);
1472 for (i
= 0; i
< ECORE_LLDP_CHASSIS_ID_STAT_LEN
; i
++)
1473 p_params
->chassis_id_tlv
[i
] =
1474 OSAL_CPU_TO_BE32(p_params
->chassis_id_tlv
[i
]);
1475 OSAL_MEMCPY(lldp_params
.local_chassis_id
, p_params
->chassis_id_tlv
,
1476 sizeof(lldp_params
.local_chassis_id
));
1478 for (i
= 0; i
< ECORE_LLDP_PORT_ID_STAT_LEN
; i
++)
1479 p_params
->port_id_tlv
[i
] =
1480 OSAL_CPU_TO_BE32(p_params
->port_id_tlv
[i
]);
1481 OSAL_MEMCPY(lldp_params
.local_port_id
, p_params
->port_id_tlv
,
1482 sizeof(lldp_params
.local_port_id
));
1484 ecore_memcpy_to(p_hwfn
, p_ptt
, addr
, &lldp_params
, sizeof(lldp_params
));
1486 rc
= ecore_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_LLDP
,
1487 mb_param
, &mcp_resp
, &mcp_param
);
1488 if (rc
!= ECORE_SUCCESS
)
1489 DP_NOTICE(p_hwfn
, false, "SET_LLDP failed, error = %d\n", rc
);
1494 enum _ecore_status_t
1495 ecore_lldp_set_system_tlvs(struct ecore_hwfn
*p_hwfn
, struct ecore_ptt
*p_ptt
,
1496 struct ecore_lldp_sys_tlvs
*p_params
)
1498 u32 mb_param
= 0, mcp_resp
= 0, mcp_param
= 0;
1499 enum _ecore_status_t rc
= ECORE_SUCCESS
;
1500 struct lldp_system_tlvs_buffer_s lld_tlv_buf
;
1505 p_val
= (u32
*)p_params
->buf
;
1506 for (i
= 0; i
< ECORE_LLDP_SYS_TLV_SIZE
/ 4; i
++)
1507 p_val
[i
] = OSAL_CPU_TO_BE32(p_val
[i
]);
1509 OSAL_MEMSET(&lld_tlv_buf
, 0, sizeof(lld_tlv_buf
));
1510 SET_MFW_FIELD(lld_tlv_buf
.flags
, LLDP_SYSTEM_TLV_VALID
, 1);
1511 SET_MFW_FIELD(lld_tlv_buf
.flags
, LLDP_SYSTEM_TLV_MANDATORY
,
1512 !!p_params
->discard_mandatory_tlv
);
1513 SET_MFW_FIELD(lld_tlv_buf
.flags
, LLDP_SYSTEM_TLV_LENGTH
,
1514 p_params
->buf_size
);
1515 len
= ECORE_LLDP_SYS_TLV_SIZE
/ 2;
1516 OSAL_MEMCPY(lld_tlv_buf
.data
, p_params
->buf
, len
);
1518 addr
= p_hwfn
->mcp_info
->port_addr
+
1519 offsetof(struct public_port
, system_lldp_tlvs_buf
);
1520 ecore_memcpy_to(p_hwfn
, p_ptt
, addr
, &lld_tlv_buf
, sizeof(lld_tlv_buf
));
1522 if (p_params
->buf_size
> len
) {
1523 addr
= p_hwfn
->mcp_info
->port_addr
+
1524 offsetof(struct public_port
, system_lldp_tlvs_buf2
);
1525 ecore_memcpy_to(p_hwfn
, p_ptt
, addr
, &p_params
->buf
[len
],
1526 ECORE_LLDP_SYS_TLV_SIZE
/ 2);
1529 rc
= ecore_mcp_cmd(p_hwfn
, p_ptt
, DRV_MSG_CODE_SET_LLDP
,
1530 mb_param
, &mcp_resp
, &mcp_param
);
1531 if (rc
!= ECORE_SUCCESS
)
1532 DP_NOTICE(p_hwfn
, false, "SET_LLDP failed, error = %d\n", rc
);