18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 28c2ecf20Sopenharmony_ci/* QLogic qed NIC Driver 38c2ecf20Sopenharmony_ci * Copyright (c) 2015-2017 QLogic Corporation 48c2ecf20Sopenharmony_ci * Copyright (c) 2019-2020 Marvell International Ltd. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/types.h> 88c2ecf20Sopenharmony_ci#include <asm/byteorder.h> 98c2ecf20Sopenharmony_ci#include <linux/bitops.h> 108c2ecf20Sopenharmony_ci#include <linux/dcbnl.h> 118c2ecf20Sopenharmony_ci#include <linux/errno.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <linux/string.h> 158c2ecf20Sopenharmony_ci#include "qed.h" 168c2ecf20Sopenharmony_ci#include "qed_cxt.h" 178c2ecf20Sopenharmony_ci#include "qed_dcbx.h" 188c2ecf20Sopenharmony_ci#include "qed_hsi.h" 198c2ecf20Sopenharmony_ci#include "qed_sp.h" 208c2ecf20Sopenharmony_ci#include "qed_sriov.h" 218c2ecf20Sopenharmony_ci#include "qed_rdma.h" 228c2ecf20Sopenharmony_ci#ifdef CONFIG_DCB 238c2ecf20Sopenharmony_ci#include <linux/qed/qed_eth_if.h> 248c2ecf20Sopenharmony_ci#endif 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define QED_DCBX_MAX_MIB_READ_TRY (100) 278c2ecf20Sopenharmony_ci#define QED_ETH_TYPE_DEFAULT (0) 288c2ecf20Sopenharmony_ci#define QED_ETH_TYPE_ROCE (0x8915) 298c2ecf20Sopenharmony_ci#define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7) 308c2ecf20Sopenharmony_ci#define QED_ETH_TYPE_FCOE (0x8906) 318c2ecf20Sopenharmony_ci#define QED_TCP_PORT_ISCSI (0xCBC) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define QED_DCBX_INVALID_PRIORITY 0xFF 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* Get Traffic Class from priority traffic class table, 4 bits represent 368c2ecf20Sopenharmony_ci * the traffic class corresponding to the priority. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci#define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \ 398c2ecf20Sopenharmony_ci ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = { 428c2ecf20Sopenharmony_ci {DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_ISCSI}, 438c2ecf20Sopenharmony_ci {DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_FCOE}, 448c2ecf20Sopenharmony_ci {DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_ETH_ROCE}, 458c2ecf20Sopenharmony_ci {DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_ETH_ROCE}, 468c2ecf20Sopenharmony_ci {DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH}, 478c2ecf20Sopenharmony_ci}; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic bool qed_dcbx_app_ethtype(u32 app_info_bitmap) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 528c2ecf20Sopenharmony_ci DCBX_APP_SF_ETHTYPE); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* Old MFW */ 608c2ecf20Sopenharmony_ci if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 618c2ecf20Sopenharmony_ci return qed_dcbx_app_ethtype(app_info_bitmap); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE); 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic bool qed_dcbx_app_port(u32 app_info_bitmap) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 698c2ecf20Sopenharmony_ci DCBX_APP_SF_PORT); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic bool qed_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci /* Old MFW */ 778c2ecf20Sopenharmony_ci if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 788c2ecf20Sopenharmony_ci return qed_dcbx_app_port(app_info_bitmap); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT); 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic bool qed_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci bool ethtype; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci if (ieee) 888c2ecf20Sopenharmony_ci ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 898c2ecf20Sopenharmony_ci else 908c2ecf20Sopenharmony_ci ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return !!(ethtype && (proto_id == QED_ETH_TYPE_DEFAULT)); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci bool port; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (ieee) 1008c2ecf20Sopenharmony_ci port = qed_dcbx_ieee_app_port(app_info_bitmap, 1018c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_TCP_PORT); 1028c2ecf20Sopenharmony_ci else 1038c2ecf20Sopenharmony_ci port = qed_dcbx_app_port(app_info_bitmap); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci return !!(port && (proto_id == QED_TCP_PORT_ISCSI)); 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci bool ethtype; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if (ieee) 1138c2ecf20Sopenharmony_ci ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 1148c2ecf20Sopenharmony_ci else 1158c2ecf20Sopenharmony_ci ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci return !!(ethtype && (proto_id == QED_ETH_TYPE_FCOE)); 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic bool qed_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci bool ethtype; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (ieee) 1258c2ecf20Sopenharmony_ci ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 1268c2ecf20Sopenharmony_ci else 1278c2ecf20Sopenharmony_ci ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci return !!(ethtype && (proto_id == QED_ETH_TYPE_ROCE)); 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci bool port; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci if (ieee) 1378c2ecf20Sopenharmony_ci port = qed_dcbx_ieee_app_port(app_info_bitmap, 1388c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_UDP_PORT); 1398c2ecf20Sopenharmony_ci else 1408c2ecf20Sopenharmony_ci port = qed_dcbx_app_port(app_info_bitmap); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci return !!(port && (proto_id == QED_UDP_PORT_TYPE_ROCE_V2)); 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic void 1468c2ecf20Sopenharmony_ciqed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci enum dcbx_protocol_type id; 1498c2ecf20Sopenharmony_ci int i; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, "DCBX negotiated: %d\n", 1528c2ecf20Sopenharmony_ci p_data->dcbx_enabled); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 1558c2ecf20Sopenharmony_ci id = qed_dcbx_app_update[i].id; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 1588c2ecf20Sopenharmony_ci "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n", 1598c2ecf20Sopenharmony_ci qed_dcbx_app_update[i].name, p_data->arr[id].update, 1608c2ecf20Sopenharmony_ci p_data->arr[id].enable, p_data->arr[id].priority, 1618c2ecf20Sopenharmony_ci p_data->arr[id].tc, p_hwfn->hw_info.num_active_tc); 1628c2ecf20Sopenharmony_ci } 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic void 1668c2ecf20Sopenharmony_ciqed_dcbx_set_params(struct qed_dcbx_results *p_data, 1678c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 1688c2ecf20Sopenharmony_ci bool app_tlv, bool enable, u8 prio, u8 tc, 1698c2ecf20Sopenharmony_ci enum dcbx_protocol_type type, 1708c2ecf20Sopenharmony_ci enum qed_pci_personality personality) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci /* PF update ramrod data */ 1738c2ecf20Sopenharmony_ci p_data->arr[type].enable = enable; 1748c2ecf20Sopenharmony_ci p_data->arr[type].priority = prio; 1758c2ecf20Sopenharmony_ci p_data->arr[type].tc = tc; 1768c2ecf20Sopenharmony_ci if (enable) 1778c2ecf20Sopenharmony_ci p_data->arr[type].update = UPDATE_DCB; 1788c2ecf20Sopenharmony_ci else 1798c2ecf20Sopenharmony_ci p_data->arr[type].update = DONT_UPDATE_DCB_DSCP; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci if (test_bit(QED_MF_DONT_ADD_VLAN0_TAG, &p_hwfn->cdev->mf_bits)) 1828c2ecf20Sopenharmony_ci p_data->arr[type].dont_add_vlan0 = true; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci /* QM reconf data */ 1858c2ecf20Sopenharmony_ci if (app_tlv && p_hwfn->hw_info.personality == personality) 1868c2ecf20Sopenharmony_ci qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci /* Configure dcbx vlan priority in doorbell block for roce EDPM */ 1898c2ecf20Sopenharmony_ci if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) && 1908c2ecf20Sopenharmony_ci type == DCBX_PROTOCOL_ROCE) { 1918c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1); 1928c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_PCP_BB_K2, prio << 1); 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* Update app protocol data and hw_info fields with the TLV info */ 1978c2ecf20Sopenharmony_cistatic void 1988c2ecf20Sopenharmony_ciqed_dcbx_update_app_info(struct qed_dcbx_results *p_data, 1998c2ecf20Sopenharmony_ci struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 2008c2ecf20Sopenharmony_ci bool app_tlv, bool enable, u8 prio, u8 tc, 2018c2ecf20Sopenharmony_ci enum dcbx_protocol_type type) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci enum qed_pci_personality personality; 2048c2ecf20Sopenharmony_ci enum dcbx_protocol_type id; 2058c2ecf20Sopenharmony_ci int i; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 2088c2ecf20Sopenharmony_ci id = qed_dcbx_app_update[i].id; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci if (type != id) 2118c2ecf20Sopenharmony_ci continue; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci personality = qed_dcbx_app_update[i].personality; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable, 2168c2ecf20Sopenharmony_ci prio, tc, type, personality); 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic bool 2218c2ecf20Sopenharmony_ciqed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn, 2228c2ecf20Sopenharmony_ci u32 app_prio_bitmap, 2238c2ecf20Sopenharmony_ci u16 id, enum dcbx_protocol_type *type, bool ieee) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci if (qed_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) { 2268c2ecf20Sopenharmony_ci *type = DCBX_PROTOCOL_FCOE; 2278c2ecf20Sopenharmony_ci } else if (qed_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) { 2288c2ecf20Sopenharmony_ci *type = DCBX_PROTOCOL_ROCE; 2298c2ecf20Sopenharmony_ci } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) { 2308c2ecf20Sopenharmony_ci *type = DCBX_PROTOCOL_ISCSI; 2318c2ecf20Sopenharmony_ci } else if (qed_dcbx_default_tlv(app_prio_bitmap, id, ieee)) { 2328c2ecf20Sopenharmony_ci *type = DCBX_PROTOCOL_ETH; 2338c2ecf20Sopenharmony_ci } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) { 2348c2ecf20Sopenharmony_ci *type = DCBX_PROTOCOL_ROCE_V2; 2358c2ecf20Sopenharmony_ci } else { 2368c2ecf20Sopenharmony_ci *type = DCBX_MAX_PROTOCOL_TYPE; 2378c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 2388c2ecf20Sopenharmony_ci "No action required, App TLV entry = 0x%x\n", 2398c2ecf20Sopenharmony_ci app_prio_bitmap); 2408c2ecf20Sopenharmony_ci return false; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci return true; 2448c2ecf20Sopenharmony_ci} 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci/* Parse app TLV's to update TC information in hw_info structure for 2478c2ecf20Sopenharmony_ci * reconfiguring QM. Get protocol specific data for PF update ramrod command. 2488c2ecf20Sopenharmony_ci */ 2498c2ecf20Sopenharmony_cistatic int 2508c2ecf20Sopenharmony_ciqed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 2518c2ecf20Sopenharmony_ci struct qed_dcbx_results *p_data, 2528c2ecf20Sopenharmony_ci struct dcbx_app_priority_entry *p_tbl, 2538c2ecf20Sopenharmony_ci u32 pri_tc_tbl, int count, u8 dcbx_version) 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci enum dcbx_protocol_type type; 2568c2ecf20Sopenharmony_ci bool enable, ieee, eth_tlv; 2578c2ecf20Sopenharmony_ci u8 tc, priority_map; 2588c2ecf20Sopenharmony_ci u16 protocol_id; 2598c2ecf20Sopenharmony_ci int priority; 2608c2ecf20Sopenharmony_ci int i; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Num APP entries = %d\n", count); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE); 2658c2ecf20Sopenharmony_ci eth_tlv = false; 2668c2ecf20Sopenharmony_ci /* Parse APP TLV */ 2678c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 2688c2ecf20Sopenharmony_ci protocol_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 2698c2ecf20Sopenharmony_ci DCBX_APP_PROTOCOL_ID); 2708c2ecf20Sopenharmony_ci priority_map = QED_MFW_GET_FIELD(p_tbl[i].entry, 2718c2ecf20Sopenharmony_ci DCBX_APP_PRI_MAP); 2728c2ecf20Sopenharmony_ci priority = ffs(priority_map) - 1; 2738c2ecf20Sopenharmony_ci if (priority < 0) { 2748c2ecf20Sopenharmony_ci DP_ERR(p_hwfn, "Invalid priority\n"); 2758c2ecf20Sopenharmony_ci return -EINVAL; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci tc = QED_DCBX_PRIO2TC(pri_tc_tbl, priority); 2798c2ecf20Sopenharmony_ci if (qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 2808c2ecf20Sopenharmony_ci protocol_id, &type, ieee)) { 2818c2ecf20Sopenharmony_ci /* ETH always have the enable bit reset, as it gets 2828c2ecf20Sopenharmony_ci * vlan information per packet. For other protocols, 2838c2ecf20Sopenharmony_ci * should be set according to the dcbx_enabled 2848c2ecf20Sopenharmony_ci * indication, but we only got here if there was an 2858c2ecf20Sopenharmony_ci * app tlv for the protocol, so dcbx must be enabled. 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_ci if (type == DCBX_PROTOCOL_ETH) { 2888c2ecf20Sopenharmony_ci enable = false; 2898c2ecf20Sopenharmony_ci eth_tlv = true; 2908c2ecf20Sopenharmony_ci } else { 2918c2ecf20Sopenharmony_ci enable = true; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true, 2958c2ecf20Sopenharmony_ci enable, priority, tc, type); 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci /* If Eth TLV is not detected, use UFP TC as default TC */ 3008c2ecf20Sopenharmony_ci if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) && !eth_tlv) 3018c2ecf20Sopenharmony_ci p_data->arr[DCBX_PROTOCOL_ETH].tc = p_hwfn->ufp_info.tc; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* Update ramrod protocol data and hw_info fields 3048c2ecf20Sopenharmony_ci * with default info when corresponding APP TLV's are not detected. 3058c2ecf20Sopenharmony_ci * The enabled field has a different logic for ethernet as only for 3068c2ecf20Sopenharmony_ci * ethernet dcb should disabled by default, as the information arrives 3078c2ecf20Sopenharmony_ci * from the OS (unless an explicit app tlv was present). 3088c2ecf20Sopenharmony_ci */ 3098c2ecf20Sopenharmony_ci tc = p_data->arr[DCBX_PROTOCOL_ETH].tc; 3108c2ecf20Sopenharmony_ci priority = p_data->arr[DCBX_PROTOCOL_ETH].priority; 3118c2ecf20Sopenharmony_ci for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) { 3128c2ecf20Sopenharmony_ci if (p_data->arr[type].update) 3138c2ecf20Sopenharmony_ci continue; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; 3168c2ecf20Sopenharmony_ci qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable, 3178c2ecf20Sopenharmony_ci priority, tc, type); 3188c2ecf20Sopenharmony_ci } 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci return 0; 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci/* Parse app TLV's to update TC information in hw_info structure for 3248c2ecf20Sopenharmony_ci * reconfiguring QM. Get protocol specific data for PF update ramrod command. 3258c2ecf20Sopenharmony_ci */ 3268c2ecf20Sopenharmony_cistatic int 3278c2ecf20Sopenharmony_ciqed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci struct dcbx_app_priority_feature *p_app; 3308c2ecf20Sopenharmony_ci struct dcbx_app_priority_entry *p_tbl; 3318c2ecf20Sopenharmony_ci struct qed_dcbx_results data = { 0 }; 3328c2ecf20Sopenharmony_ci struct dcbx_ets_feature *p_ets; 3338c2ecf20Sopenharmony_ci struct qed_hw_info *p_info; 3348c2ecf20Sopenharmony_ci u32 pri_tc_tbl, flags; 3358c2ecf20Sopenharmony_ci u8 dcbx_version; 3368c2ecf20Sopenharmony_ci int num_entries; 3378c2ecf20Sopenharmony_ci int rc = 0; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci flags = p_hwfn->p_dcbx_info->operational.flags; 3408c2ecf20Sopenharmony_ci dcbx_version = QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci p_app = &p_hwfn->p_dcbx_info->operational.features.app; 3438c2ecf20Sopenharmony_ci p_tbl = p_app->app_pri_tbl; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci p_ets = &p_hwfn->p_dcbx_info->operational.features.ets; 3468c2ecf20Sopenharmony_ci pri_tc_tbl = p_ets->pri_tc_tbl[0]; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci p_info = &p_hwfn->hw_info; 3498c2ecf20Sopenharmony_ci num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci rc = qed_dcbx_process_tlv(p_hwfn, p_ptt, &data, p_tbl, pri_tc_tbl, 3528c2ecf20Sopenharmony_ci num_entries, dcbx_version); 3538c2ecf20Sopenharmony_ci if (rc) 3548c2ecf20Sopenharmony_ci return rc; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci p_info->num_active_tc = QED_MFW_GET_FIELD(p_ets->flags, 3578c2ecf20Sopenharmony_ci DCBX_ETS_MAX_TCS); 3588c2ecf20Sopenharmony_ci p_hwfn->qm_info.ooo_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_OOO_TC); 3598c2ecf20Sopenharmony_ci data.pf_id = p_hwfn->rel_pf_id; 3608c2ecf20Sopenharmony_ci data.dcbx_enabled = !!dcbx_version; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci qed_dcbx_dp_protocol(p_hwfn, &data); 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci memcpy(&p_hwfn->p_dcbx_info->results, &data, 3658c2ecf20Sopenharmony_ci sizeof(struct qed_dcbx_results)); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci return 0; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic int 3718c2ecf20Sopenharmony_ciqed_dcbx_copy_mib(struct qed_hwfn *p_hwfn, 3728c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 3738c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data *p_data, 3748c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 3758c2ecf20Sopenharmony_ci{ 3768c2ecf20Sopenharmony_ci u32 prefix_seq_num, suffix_seq_num; 3778c2ecf20Sopenharmony_ci int read_count = 0; 3788c2ecf20Sopenharmony_ci int rc = 0; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci /* The data is considered to be valid only if both sequence numbers are 3818c2ecf20Sopenharmony_ci * the same. 3828c2ecf20Sopenharmony_ci */ 3838c2ecf20Sopenharmony_ci do { 3848c2ecf20Sopenharmony_ci if (type == QED_DCBX_REMOTE_LLDP_MIB) { 3858c2ecf20Sopenharmony_ci qed_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote, 3868c2ecf20Sopenharmony_ci p_data->addr, p_data->size); 3878c2ecf20Sopenharmony_ci prefix_seq_num = p_data->lldp_remote->prefix_seq_num; 3888c2ecf20Sopenharmony_ci suffix_seq_num = p_data->lldp_remote->suffix_seq_num; 3898c2ecf20Sopenharmony_ci } else { 3908c2ecf20Sopenharmony_ci qed_memcpy_from(p_hwfn, p_ptt, p_data->mib, 3918c2ecf20Sopenharmony_ci p_data->addr, p_data->size); 3928c2ecf20Sopenharmony_ci prefix_seq_num = p_data->mib->prefix_seq_num; 3938c2ecf20Sopenharmony_ci suffix_seq_num = p_data->mib->suffix_seq_num; 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci read_count++; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, 3988c2ecf20Sopenharmony_ci QED_MSG_DCB, 3998c2ecf20Sopenharmony_ci "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 4008c2ecf20Sopenharmony_ci type, read_count, prefix_seq_num, suffix_seq_num); 4018c2ecf20Sopenharmony_ci } while ((prefix_seq_num != suffix_seq_num) && 4028c2ecf20Sopenharmony_ci (read_count < QED_DCBX_MAX_MIB_READ_TRY)); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci if (read_count >= QED_DCBX_MAX_MIB_READ_TRY) { 4058c2ecf20Sopenharmony_ci DP_ERR(p_hwfn, 4068c2ecf20Sopenharmony_ci "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 4078c2ecf20Sopenharmony_ci type, read_count, prefix_seq_num, suffix_seq_num); 4088c2ecf20Sopenharmony_ci rc = -EIO; 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci return rc; 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_cistatic void 4158c2ecf20Sopenharmony_ciqed_dcbx_get_priority_info(struct qed_hwfn *p_hwfn, 4168c2ecf20Sopenharmony_ci struct qed_dcbx_app_prio *p_prio, 4178c2ecf20Sopenharmony_ci struct qed_dcbx_results *p_results) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci u8 val; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci p_prio->roce = QED_DCBX_INVALID_PRIORITY; 4228c2ecf20Sopenharmony_ci p_prio->roce_v2 = QED_DCBX_INVALID_PRIORITY; 4238c2ecf20Sopenharmony_ci p_prio->iscsi = QED_DCBX_INVALID_PRIORITY; 4248c2ecf20Sopenharmony_ci p_prio->fcoe = QED_DCBX_INVALID_PRIORITY; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci if (p_results->arr[DCBX_PROTOCOL_ROCE].update && 4278c2ecf20Sopenharmony_ci p_results->arr[DCBX_PROTOCOL_ROCE].enable) 4288c2ecf20Sopenharmony_ci p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update && 4318c2ecf20Sopenharmony_ci p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) { 4328c2ecf20Sopenharmony_ci val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority; 4338c2ecf20Sopenharmony_ci p_prio->roce_v2 = val; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci if (p_results->arr[DCBX_PROTOCOL_ISCSI].update && 4378c2ecf20Sopenharmony_ci p_results->arr[DCBX_PROTOCOL_ISCSI].enable) 4388c2ecf20Sopenharmony_ci p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci if (p_results->arr[DCBX_PROTOCOL_FCOE].update && 4418c2ecf20Sopenharmony_ci p_results->arr[DCBX_PROTOCOL_FCOE].enable) 4428c2ecf20Sopenharmony_ci p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci if (p_results->arr[DCBX_PROTOCOL_ETH].update && 4458c2ecf20Sopenharmony_ci p_results->arr[DCBX_PROTOCOL_ETH].enable) 4468c2ecf20Sopenharmony_ci p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority; 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 4498c2ecf20Sopenharmony_ci "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n", 4508c2ecf20Sopenharmony_ci p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe, 4518c2ecf20Sopenharmony_ci p_prio->eth); 4528c2ecf20Sopenharmony_ci} 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_cistatic void 4558c2ecf20Sopenharmony_ciqed_dcbx_get_app_data(struct qed_hwfn *p_hwfn, 4568c2ecf20Sopenharmony_ci struct dcbx_app_priority_feature *p_app, 4578c2ecf20Sopenharmony_ci struct dcbx_app_priority_entry *p_tbl, 4588c2ecf20Sopenharmony_ci struct qed_dcbx_params *p_params, bool ieee) 4598c2ecf20Sopenharmony_ci{ 4608c2ecf20Sopenharmony_ci struct qed_app_entry *entry; 4618c2ecf20Sopenharmony_ci u8 pri_map; 4628c2ecf20Sopenharmony_ci int i; 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci p_params->app_willing = QED_MFW_GET_FIELD(p_app->flags, 4658c2ecf20Sopenharmony_ci DCBX_APP_WILLING); 4668c2ecf20Sopenharmony_ci p_params->app_valid = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ENABLED); 4678c2ecf20Sopenharmony_ci p_params->app_error = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR); 4688c2ecf20Sopenharmony_ci p_params->num_app_entries = QED_MFW_GET_FIELD(p_app->flags, 4698c2ecf20Sopenharmony_ci DCBX_APP_NUM_ENTRIES); 4708c2ecf20Sopenharmony_ci for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 4718c2ecf20Sopenharmony_ci entry = &p_params->app_entry[i]; 4728c2ecf20Sopenharmony_ci if (ieee) { 4738c2ecf20Sopenharmony_ci u8 sf_ieee; 4748c2ecf20Sopenharmony_ci u32 val; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci sf_ieee = QED_MFW_GET_FIELD(p_tbl[i].entry, 4778c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE); 4788c2ecf20Sopenharmony_ci switch (sf_ieee) { 4798c2ecf20Sopenharmony_ci case DCBX_APP_SF_IEEE_RESERVED: 4808c2ecf20Sopenharmony_ci /* Old MFW */ 4818c2ecf20Sopenharmony_ci val = QED_MFW_GET_FIELD(p_tbl[i].entry, 4828c2ecf20Sopenharmony_ci DCBX_APP_SF); 4838c2ecf20Sopenharmony_ci entry->sf_ieee = val ? 4848c2ecf20Sopenharmony_ci QED_DCBX_SF_IEEE_TCP_UDP_PORT : 4858c2ecf20Sopenharmony_ci QED_DCBX_SF_IEEE_ETHTYPE; 4868c2ecf20Sopenharmony_ci break; 4878c2ecf20Sopenharmony_ci case DCBX_APP_SF_IEEE_ETHTYPE: 4888c2ecf20Sopenharmony_ci entry->sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE; 4898c2ecf20Sopenharmony_ci break; 4908c2ecf20Sopenharmony_ci case DCBX_APP_SF_IEEE_TCP_PORT: 4918c2ecf20Sopenharmony_ci entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT; 4928c2ecf20Sopenharmony_ci break; 4938c2ecf20Sopenharmony_ci case DCBX_APP_SF_IEEE_UDP_PORT: 4948c2ecf20Sopenharmony_ci entry->sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT; 4958c2ecf20Sopenharmony_ci break; 4968c2ecf20Sopenharmony_ci case DCBX_APP_SF_IEEE_TCP_UDP_PORT: 4978c2ecf20Sopenharmony_ci entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT; 4988c2ecf20Sopenharmony_ci break; 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci } else { 5018c2ecf20Sopenharmony_ci entry->ethtype = !(QED_MFW_GET_FIELD(p_tbl[i].entry, 5028c2ecf20Sopenharmony_ci DCBX_APP_SF)); 5038c2ecf20Sopenharmony_ci } 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci pri_map = QED_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP); 5068c2ecf20Sopenharmony_ci entry->prio = ffs(pri_map) - 1; 5078c2ecf20Sopenharmony_ci entry->proto_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 5088c2ecf20Sopenharmony_ci DCBX_APP_PROTOCOL_ID); 5098c2ecf20Sopenharmony_ci qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 5108c2ecf20Sopenharmony_ci entry->proto_id, 5118c2ecf20Sopenharmony_ci &entry->proto_type, ieee); 5128c2ecf20Sopenharmony_ci } 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5158c2ecf20Sopenharmony_ci "APP params: willing %d, valid %d error = %d\n", 5168c2ecf20Sopenharmony_ci p_params->app_willing, p_params->app_valid, 5178c2ecf20Sopenharmony_ci p_params->app_error); 5188c2ecf20Sopenharmony_ci} 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_cistatic void 5218c2ecf20Sopenharmony_ciqed_dcbx_get_pfc_data(struct qed_hwfn *p_hwfn, 5228c2ecf20Sopenharmony_ci u32 pfc, struct qed_dcbx_params *p_params) 5238c2ecf20Sopenharmony_ci{ 5248c2ecf20Sopenharmony_ci u8 pfc_map; 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci p_params->pfc.willing = QED_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING); 5278c2ecf20Sopenharmony_ci p_params->pfc.max_tc = QED_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS); 5288c2ecf20Sopenharmony_ci p_params->pfc.enabled = QED_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED); 5298c2ecf20Sopenharmony_ci pfc_map = QED_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP); 5308c2ecf20Sopenharmony_ci p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0); 5318c2ecf20Sopenharmony_ci p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1); 5328c2ecf20Sopenharmony_ci p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2); 5338c2ecf20Sopenharmony_ci p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3); 5348c2ecf20Sopenharmony_ci p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4); 5358c2ecf20Sopenharmony_ci p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5); 5368c2ecf20Sopenharmony_ci p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6); 5378c2ecf20Sopenharmony_ci p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7); 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5408c2ecf20Sopenharmony_ci "PFC params: willing %d, pfc_bitmap %u max_tc = %u enabled = %d\n", 5418c2ecf20Sopenharmony_ci p_params->pfc.willing, pfc_map, p_params->pfc.max_tc, 5428c2ecf20Sopenharmony_ci p_params->pfc.enabled); 5438c2ecf20Sopenharmony_ci} 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_cistatic void 5468c2ecf20Sopenharmony_ciqed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn, 5478c2ecf20Sopenharmony_ci struct dcbx_ets_feature *p_ets, 5488c2ecf20Sopenharmony_ci struct qed_dcbx_params *p_params) 5498c2ecf20Sopenharmony_ci{ 5508c2ecf20Sopenharmony_ci __be32 bw_map[2], tsa_map[2]; 5518c2ecf20Sopenharmony_ci u32 pri_map; 5528c2ecf20Sopenharmony_ci int i; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci p_params->ets_willing = QED_MFW_GET_FIELD(p_ets->flags, 5558c2ecf20Sopenharmony_ci DCBX_ETS_WILLING); 5568c2ecf20Sopenharmony_ci p_params->ets_enabled = QED_MFW_GET_FIELD(p_ets->flags, 5578c2ecf20Sopenharmony_ci DCBX_ETS_ENABLED); 5588c2ecf20Sopenharmony_ci p_params->ets_cbs = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS); 5598c2ecf20Sopenharmony_ci p_params->max_ets_tc = QED_MFW_GET_FIELD(p_ets->flags, 5608c2ecf20Sopenharmony_ci DCBX_ETS_MAX_TCS); 5618c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5628c2ecf20Sopenharmony_ci "ETS params: willing %d, enabled = %d ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n", 5638c2ecf20Sopenharmony_ci p_params->ets_willing, p_params->ets_enabled, 5648c2ecf20Sopenharmony_ci p_params->ets_cbs, p_ets->pri_tc_tbl[0], 5658c2ecf20Sopenharmony_ci p_params->max_ets_tc); 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci if (p_params->ets_enabled && !p_params->max_ets_tc) { 5688c2ecf20Sopenharmony_ci p_params->max_ets_tc = QED_MAX_PFC_PRIORITIES; 5698c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5708c2ecf20Sopenharmony_ci "ETS params: max_ets_tc is forced to %d\n", 5718c2ecf20Sopenharmony_ci p_params->max_ets_tc); 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci /* 8 bit tsa and bw data corresponding to each of the 8 TC's are 5758c2ecf20Sopenharmony_ci * encoded in a type u32 array of size 2. 5768c2ecf20Sopenharmony_ci */ 5778c2ecf20Sopenharmony_ci cpu_to_be32_array(bw_map, p_ets->tc_bw_tbl, 2); 5788c2ecf20Sopenharmony_ci cpu_to_be32_array(tsa_map, p_ets->tc_tsa_tbl, 2); 5798c2ecf20Sopenharmony_ci pri_map = p_ets->pri_tc_tbl[0]; 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 5828c2ecf20Sopenharmony_ci p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i]; 5838c2ecf20Sopenharmony_ci p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i]; 5848c2ecf20Sopenharmony_ci p_params->ets_pri_tc_tbl[i] = QED_DCBX_PRIO2TC(pri_map, i); 5858c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5868c2ecf20Sopenharmony_ci "elem %d bw_tbl %x tsa_tbl %x\n", 5878c2ecf20Sopenharmony_ci i, p_params->ets_tc_bw_tbl[i], 5888c2ecf20Sopenharmony_ci p_params->ets_tc_tsa_tbl[i]); 5898c2ecf20Sopenharmony_ci } 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic void 5938c2ecf20Sopenharmony_ciqed_dcbx_get_common_params(struct qed_hwfn *p_hwfn, 5948c2ecf20Sopenharmony_ci struct dcbx_app_priority_feature *p_app, 5958c2ecf20Sopenharmony_ci struct dcbx_app_priority_entry *p_tbl, 5968c2ecf20Sopenharmony_ci struct dcbx_ets_feature *p_ets, 5978c2ecf20Sopenharmony_ci u32 pfc, struct qed_dcbx_params *p_params, bool ieee) 5988c2ecf20Sopenharmony_ci{ 5998c2ecf20Sopenharmony_ci qed_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee); 6008c2ecf20Sopenharmony_ci qed_dcbx_get_ets_data(p_hwfn, p_ets, p_params); 6018c2ecf20Sopenharmony_ci qed_dcbx_get_pfc_data(p_hwfn, pfc, p_params); 6028c2ecf20Sopenharmony_ci} 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_cistatic void 6058c2ecf20Sopenharmony_ciqed_dcbx_get_local_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *params) 6068c2ecf20Sopenharmony_ci{ 6078c2ecf20Sopenharmony_ci struct dcbx_features *p_feat; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci p_feat = &p_hwfn->p_dcbx_info->local_admin.features; 6108c2ecf20Sopenharmony_ci qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6118c2ecf20Sopenharmony_ci p_feat->app.app_pri_tbl, &p_feat->ets, 6128c2ecf20Sopenharmony_ci p_feat->pfc, ¶ms->local.params, false); 6138c2ecf20Sopenharmony_ci params->local.valid = true; 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_cistatic void 6178c2ecf20Sopenharmony_ciqed_dcbx_get_remote_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *params) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci struct dcbx_features *p_feat; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci p_feat = &p_hwfn->p_dcbx_info->remote.features; 6228c2ecf20Sopenharmony_ci qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6238c2ecf20Sopenharmony_ci p_feat->app.app_pri_tbl, &p_feat->ets, 6248c2ecf20Sopenharmony_ci p_feat->pfc, ¶ms->remote.params, false); 6258c2ecf20Sopenharmony_ci params->remote.valid = true; 6268c2ecf20Sopenharmony_ci} 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_cistatic void 6298c2ecf20Sopenharmony_ciqed_dcbx_get_operational_params(struct qed_hwfn *p_hwfn, 6308c2ecf20Sopenharmony_ci struct qed_dcbx_get *params) 6318c2ecf20Sopenharmony_ci{ 6328c2ecf20Sopenharmony_ci struct qed_dcbx_operational_params *p_operational; 6338c2ecf20Sopenharmony_ci struct qed_dcbx_results *p_results; 6348c2ecf20Sopenharmony_ci struct dcbx_features *p_feat; 6358c2ecf20Sopenharmony_ci bool enabled, err; 6368c2ecf20Sopenharmony_ci u32 flags; 6378c2ecf20Sopenharmony_ci bool val; 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci flags = p_hwfn->p_dcbx_info->operational.flags; 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci /* If DCBx version is non zero, then negotiation 6428c2ecf20Sopenharmony_ci * was successfuly performed 6438c2ecf20Sopenharmony_ci */ 6448c2ecf20Sopenharmony_ci p_operational = ¶ms->operational; 6458c2ecf20Sopenharmony_ci enabled = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) != 6468c2ecf20Sopenharmony_ci DCBX_CONFIG_VERSION_DISABLED); 6478c2ecf20Sopenharmony_ci if (!enabled) { 6488c2ecf20Sopenharmony_ci p_operational->enabled = enabled; 6498c2ecf20Sopenharmony_ci p_operational->valid = false; 6508c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Dcbx is disabled\n"); 6518c2ecf20Sopenharmony_ci return; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci p_feat = &p_hwfn->p_dcbx_info->operational.features; 6558c2ecf20Sopenharmony_ci p_results = &p_hwfn->p_dcbx_info->results; 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 6588c2ecf20Sopenharmony_ci DCBX_CONFIG_VERSION_IEEE); 6598c2ecf20Sopenharmony_ci p_operational->ieee = val; 6608c2ecf20Sopenharmony_ci val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 6618c2ecf20Sopenharmony_ci DCBX_CONFIG_VERSION_CEE); 6628c2ecf20Sopenharmony_ci p_operational->cee = val; 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_ci val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 6658c2ecf20Sopenharmony_ci DCBX_CONFIG_VERSION_STATIC); 6668c2ecf20Sopenharmony_ci p_operational->local = val; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 6698c2ecf20Sopenharmony_ci "Version support: ieee %d, cee %d, static %d\n", 6708c2ecf20Sopenharmony_ci p_operational->ieee, p_operational->cee, 6718c2ecf20Sopenharmony_ci p_operational->local); 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6748c2ecf20Sopenharmony_ci p_feat->app.app_pri_tbl, &p_feat->ets, 6758c2ecf20Sopenharmony_ci p_feat->pfc, ¶ms->operational.params, 6768c2ecf20Sopenharmony_ci p_operational->ieee); 6778c2ecf20Sopenharmony_ci qed_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio, p_results); 6788c2ecf20Sopenharmony_ci err = QED_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR); 6798c2ecf20Sopenharmony_ci p_operational->err = err; 6808c2ecf20Sopenharmony_ci p_operational->enabled = enabled; 6818c2ecf20Sopenharmony_ci p_operational->valid = true; 6828c2ecf20Sopenharmony_ci} 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_cistatic void 6858c2ecf20Sopenharmony_ciqed_dcbx_get_local_lldp_params(struct qed_hwfn *p_hwfn, 6868c2ecf20Sopenharmony_ci struct qed_dcbx_get *params) 6878c2ecf20Sopenharmony_ci{ 6888c2ecf20Sopenharmony_ci struct lldp_config_params_s *p_local; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE]; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id, 6938c2ecf20Sopenharmony_ci sizeof(p_local->local_chassis_id)); 6948c2ecf20Sopenharmony_ci memcpy(params->lldp_local.local_port_id, p_local->local_port_id, 6958c2ecf20Sopenharmony_ci sizeof(p_local->local_port_id)); 6968c2ecf20Sopenharmony_ci} 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_cistatic void 6998c2ecf20Sopenharmony_ciqed_dcbx_get_remote_lldp_params(struct qed_hwfn *p_hwfn, 7008c2ecf20Sopenharmony_ci struct qed_dcbx_get *params) 7018c2ecf20Sopenharmony_ci{ 7028c2ecf20Sopenharmony_ci struct lldp_status_params_s *p_remote; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE]; 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id, 7078c2ecf20Sopenharmony_ci sizeof(p_remote->peer_chassis_id)); 7088c2ecf20Sopenharmony_ci memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id, 7098c2ecf20Sopenharmony_ci sizeof(p_remote->peer_port_id)); 7108c2ecf20Sopenharmony_ci} 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_cistatic int 7138c2ecf20Sopenharmony_ciqed_dcbx_get_params(struct qed_hwfn *p_hwfn, struct qed_dcbx_get *p_params, 7148c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 7158c2ecf20Sopenharmony_ci{ 7168c2ecf20Sopenharmony_ci switch (type) { 7178c2ecf20Sopenharmony_ci case QED_DCBX_REMOTE_MIB: 7188c2ecf20Sopenharmony_ci qed_dcbx_get_remote_params(p_hwfn, p_params); 7198c2ecf20Sopenharmony_ci break; 7208c2ecf20Sopenharmony_ci case QED_DCBX_LOCAL_MIB: 7218c2ecf20Sopenharmony_ci qed_dcbx_get_local_params(p_hwfn, p_params); 7228c2ecf20Sopenharmony_ci break; 7238c2ecf20Sopenharmony_ci case QED_DCBX_OPERATIONAL_MIB: 7248c2ecf20Sopenharmony_ci qed_dcbx_get_operational_params(p_hwfn, p_params); 7258c2ecf20Sopenharmony_ci break; 7268c2ecf20Sopenharmony_ci case QED_DCBX_REMOTE_LLDP_MIB: 7278c2ecf20Sopenharmony_ci qed_dcbx_get_remote_lldp_params(p_hwfn, p_params); 7288c2ecf20Sopenharmony_ci break; 7298c2ecf20Sopenharmony_ci case QED_DCBX_LOCAL_LLDP_MIB: 7308c2ecf20Sopenharmony_ci qed_dcbx_get_local_lldp_params(p_hwfn, p_params); 7318c2ecf20Sopenharmony_ci break; 7328c2ecf20Sopenharmony_ci default: 7338c2ecf20Sopenharmony_ci DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 7348c2ecf20Sopenharmony_ci return -EINVAL; 7358c2ecf20Sopenharmony_ci } 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci return 0; 7388c2ecf20Sopenharmony_ci} 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_cistatic int 7418c2ecf20Sopenharmony_ciqed_dcbx_read_local_lldp_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 7428c2ecf20Sopenharmony_ci{ 7438c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 7448c2ecf20Sopenharmony_ci int rc = 0; 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci memset(&data, 0, sizeof(data)); 7478c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 7488c2ecf20Sopenharmony_ci lldp_config_params); 7498c2ecf20Sopenharmony_ci data.lldp_local = p_hwfn->p_dcbx_info->lldp_local; 7508c2ecf20Sopenharmony_ci data.size = sizeof(struct lldp_config_params_s); 7518c2ecf20Sopenharmony_ci qed_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size); 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci return rc; 7548c2ecf20Sopenharmony_ci} 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_cistatic int 7578c2ecf20Sopenharmony_ciqed_dcbx_read_remote_lldp_mib(struct qed_hwfn *p_hwfn, 7588c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 7598c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 7608c2ecf20Sopenharmony_ci{ 7618c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 7628c2ecf20Sopenharmony_ci int rc = 0; 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci memset(&data, 0, sizeof(data)); 7658c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 7668c2ecf20Sopenharmony_ci lldp_status_params); 7678c2ecf20Sopenharmony_ci data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote; 7688c2ecf20Sopenharmony_ci data.size = sizeof(struct lldp_status_params_s); 7698c2ecf20Sopenharmony_ci rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci return rc; 7728c2ecf20Sopenharmony_ci} 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_cistatic int 7758c2ecf20Sopenharmony_ciqed_dcbx_read_operational_mib(struct qed_hwfn *p_hwfn, 7768c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, 7778c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 7788c2ecf20Sopenharmony_ci{ 7798c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 7808c2ecf20Sopenharmony_ci int rc = 0; 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci memset(&data, 0, sizeof(data)); 7838c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + 7848c2ecf20Sopenharmony_ci offsetof(struct public_port, operational_dcbx_mib); 7858c2ecf20Sopenharmony_ci data.mib = &p_hwfn->p_dcbx_info->operational; 7868c2ecf20Sopenharmony_ci data.size = sizeof(struct dcbx_mib); 7878c2ecf20Sopenharmony_ci rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci return rc; 7908c2ecf20Sopenharmony_ci} 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_cistatic int 7938c2ecf20Sopenharmony_ciqed_dcbx_read_remote_mib(struct qed_hwfn *p_hwfn, 7948c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, enum qed_mib_read_type type) 7958c2ecf20Sopenharmony_ci{ 7968c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 7978c2ecf20Sopenharmony_ci int rc = 0; 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci memset(&data, 0, sizeof(data)); 8008c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + 8018c2ecf20Sopenharmony_ci offsetof(struct public_port, remote_dcbx_mib); 8028c2ecf20Sopenharmony_ci data.mib = &p_hwfn->p_dcbx_info->remote; 8038c2ecf20Sopenharmony_ci data.size = sizeof(struct dcbx_mib); 8048c2ecf20Sopenharmony_ci rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci return rc; 8078c2ecf20Sopenharmony_ci} 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_cistatic int 8108c2ecf20Sopenharmony_ciqed_dcbx_read_local_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 8118c2ecf20Sopenharmony_ci{ 8128c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 8138c2ecf20Sopenharmony_ci int rc = 0; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci memset(&data, 0, sizeof(data)); 8168c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + 8178c2ecf20Sopenharmony_ci offsetof(struct public_port, local_admin_dcbx_mib); 8188c2ecf20Sopenharmony_ci data.local_admin = &p_hwfn->p_dcbx_info->local_admin; 8198c2ecf20Sopenharmony_ci data.size = sizeof(struct dcbx_local_params); 8208c2ecf20Sopenharmony_ci qed_memcpy_from(p_hwfn, p_ptt, data.local_admin, data.addr, data.size); 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci return rc; 8238c2ecf20Sopenharmony_ci} 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_cistatic int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn, 8268c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, enum qed_mib_read_type type) 8278c2ecf20Sopenharmony_ci{ 8288c2ecf20Sopenharmony_ci int rc = -EINVAL; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci switch (type) { 8318c2ecf20Sopenharmony_ci case QED_DCBX_OPERATIONAL_MIB: 8328c2ecf20Sopenharmony_ci rc = qed_dcbx_read_operational_mib(p_hwfn, p_ptt, type); 8338c2ecf20Sopenharmony_ci break; 8348c2ecf20Sopenharmony_ci case QED_DCBX_REMOTE_MIB: 8358c2ecf20Sopenharmony_ci rc = qed_dcbx_read_remote_mib(p_hwfn, p_ptt, type); 8368c2ecf20Sopenharmony_ci break; 8378c2ecf20Sopenharmony_ci case QED_DCBX_LOCAL_MIB: 8388c2ecf20Sopenharmony_ci rc = qed_dcbx_read_local_mib(p_hwfn, p_ptt); 8398c2ecf20Sopenharmony_ci break; 8408c2ecf20Sopenharmony_ci case QED_DCBX_REMOTE_LLDP_MIB: 8418c2ecf20Sopenharmony_ci rc = qed_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type); 8428c2ecf20Sopenharmony_ci break; 8438c2ecf20Sopenharmony_ci case QED_DCBX_LOCAL_LLDP_MIB: 8448c2ecf20Sopenharmony_ci rc = qed_dcbx_read_local_lldp_mib(p_hwfn, p_ptt); 8458c2ecf20Sopenharmony_ci break; 8468c2ecf20Sopenharmony_ci default: 8478c2ecf20Sopenharmony_ci DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 8488c2ecf20Sopenharmony_ci } 8498c2ecf20Sopenharmony_ci 8508c2ecf20Sopenharmony_ci return rc; 8518c2ecf20Sopenharmony_ci} 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_cistatic void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type) 8548c2ecf20Sopenharmony_ci{ 8558c2ecf20Sopenharmony_ci struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common; 8568c2ecf20Sopenharmony_ci void *cookie = hwfn->cdev->ops_cookie; 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci if (cookie && op->dcbx_aen) 8598c2ecf20Sopenharmony_ci op->dcbx_aen(cookie, &hwfn->p_dcbx_info->get, mib_type); 8608c2ecf20Sopenharmony_ci} 8618c2ecf20Sopenharmony_ci 8628c2ecf20Sopenharmony_ci/* Read updated MIB. 8638c2ecf20Sopenharmony_ci * Reconfigure QM and invoke PF update ramrod command if operational MIB 8648c2ecf20Sopenharmony_ci * change is detected. 8658c2ecf20Sopenharmony_ci */ 8668c2ecf20Sopenharmony_ciint 8678c2ecf20Sopenharmony_ciqed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn, 8688c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt, enum qed_mib_read_type type) 8698c2ecf20Sopenharmony_ci{ 8708c2ecf20Sopenharmony_ci int rc = 0; 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 8738c2ecf20Sopenharmony_ci if (rc) 8748c2ecf20Sopenharmony_ci return rc; 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_ci if (type == QED_DCBX_OPERATIONAL_MIB) { 8778c2ecf20Sopenharmony_ci rc = qed_dcbx_process_mib_info(p_hwfn, p_ptt); 8788c2ecf20Sopenharmony_ci if (!rc) { 8798c2ecf20Sopenharmony_ci /* reconfigure tcs of QM queues according 8808c2ecf20Sopenharmony_ci * to negotiation results 8818c2ecf20Sopenharmony_ci */ 8828c2ecf20Sopenharmony_ci qed_qm_reconf(p_hwfn, p_ptt); 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci /* update storm FW with negotiation results */ 8858c2ecf20Sopenharmony_ci qed_sp_pf_update(p_hwfn); 8868c2ecf20Sopenharmony_ci 8878c2ecf20Sopenharmony_ci /* for roce PFs, we may want to enable/disable DPM 8888c2ecf20Sopenharmony_ci * when DCBx change occurs 8898c2ecf20Sopenharmony_ci */ 8908c2ecf20Sopenharmony_ci if (p_hwfn->hw_info.personality == 8918c2ecf20Sopenharmony_ci QED_PCI_ETH_ROCE) 8928c2ecf20Sopenharmony_ci qed_roce_dpm_dcbx(p_hwfn, p_ptt); 8938c2ecf20Sopenharmony_ci } 8948c2ecf20Sopenharmony_ci } 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci qed_dcbx_get_params(p_hwfn, &p_hwfn->p_dcbx_info->get, type); 8978c2ecf20Sopenharmony_ci 8988c2ecf20Sopenharmony_ci if (type == QED_DCBX_OPERATIONAL_MIB) { 8998c2ecf20Sopenharmony_ci struct qed_dcbx_results *p_data; 9008c2ecf20Sopenharmony_ci u16 val; 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci /* Configure in NIG which protocols support EDPM and should 9038c2ecf20Sopenharmony_ci * honor PFC. 9048c2ecf20Sopenharmony_ci */ 9058c2ecf20Sopenharmony_ci p_data = &p_hwfn->p_dcbx_info->results; 9068c2ecf20Sopenharmony_ci val = (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE].tc) | 9078c2ecf20Sopenharmony_ci (0x1 << p_data->arr[DCBX_PROTOCOL_ROCE_V2].tc); 9088c2ecf20Sopenharmony_ci val <<= NIG_REG_TX_EDPM_CTRL_TX_EDPM_TC_EN_SHIFT; 9098c2ecf20Sopenharmony_ci val |= NIG_REG_TX_EDPM_CTRL_TX_EDPM_EN; 9108c2ecf20Sopenharmony_ci qed_wr(p_hwfn, p_ptt, NIG_REG_TX_EDPM_CTRL, val); 9118c2ecf20Sopenharmony_ci } 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_ci qed_dcbx_aen(p_hwfn, type); 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci return rc; 9168c2ecf20Sopenharmony_ci} 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ciint qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn) 9198c2ecf20Sopenharmony_ci{ 9208c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info = kzalloc(sizeof(*p_hwfn->p_dcbx_info), GFP_KERNEL); 9218c2ecf20Sopenharmony_ci if (!p_hwfn->p_dcbx_info) 9228c2ecf20Sopenharmony_ci return -ENOMEM; 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci return 0; 9258c2ecf20Sopenharmony_ci} 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_civoid qed_dcbx_info_free(struct qed_hwfn *p_hwfn) 9288c2ecf20Sopenharmony_ci{ 9298c2ecf20Sopenharmony_ci kfree(p_hwfn->p_dcbx_info); 9308c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info = NULL; 9318c2ecf20Sopenharmony_ci} 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_cistatic void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data, 9348c2ecf20Sopenharmony_ci struct qed_dcbx_results *p_src, 9358c2ecf20Sopenharmony_ci enum dcbx_protocol_type type) 9368c2ecf20Sopenharmony_ci{ 9378c2ecf20Sopenharmony_ci p_data->dcb_enable_flag = p_src->arr[type].enable; 9388c2ecf20Sopenharmony_ci p_data->dcb_priority = p_src->arr[type].priority; 9398c2ecf20Sopenharmony_ci p_data->dcb_tc = p_src->arr[type].tc; 9408c2ecf20Sopenharmony_ci p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0; 9418c2ecf20Sopenharmony_ci} 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci/* Set pf update ramrod command params */ 9448c2ecf20Sopenharmony_civoid qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src, 9458c2ecf20Sopenharmony_ci struct pf_update_ramrod_data *p_dest) 9468c2ecf20Sopenharmony_ci{ 9478c2ecf20Sopenharmony_ci struct protocol_dcb_data *p_dcb_data; 9488c2ecf20Sopenharmony_ci u8 update_flag; 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_ci update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update; 9518c2ecf20Sopenharmony_ci p_dest->update_fcoe_dcb_data_mode = update_flag; 9528c2ecf20Sopenharmony_ci 9538c2ecf20Sopenharmony_ci update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update; 9548c2ecf20Sopenharmony_ci p_dest->update_roce_dcb_data_mode = update_flag; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update; 9578c2ecf20Sopenharmony_ci p_dest->update_rroce_dcb_data_mode = update_flag; 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update; 9608c2ecf20Sopenharmony_ci p_dest->update_iscsi_dcb_data_mode = update_flag; 9618c2ecf20Sopenharmony_ci update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update; 9628c2ecf20Sopenharmony_ci p_dest->update_eth_dcb_data_mode = update_flag; 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci p_dcb_data = &p_dest->fcoe_dcb_data; 9658c2ecf20Sopenharmony_ci qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE); 9668c2ecf20Sopenharmony_ci p_dcb_data = &p_dest->roce_dcb_data; 9678c2ecf20Sopenharmony_ci qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE); 9688c2ecf20Sopenharmony_ci p_dcb_data = &p_dest->rroce_dcb_data; 9698c2ecf20Sopenharmony_ci qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ROCE_V2); 9708c2ecf20Sopenharmony_ci p_dcb_data = &p_dest->iscsi_dcb_data; 9718c2ecf20Sopenharmony_ci qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI); 9728c2ecf20Sopenharmony_ci p_dcb_data = &p_dest->eth_dcb_data; 9738c2ecf20Sopenharmony_ci qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH); 9748c2ecf20Sopenharmony_ci} 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ciu8 qed_dcbx_get_priority_tc(struct qed_hwfn *p_hwfn, u8 pri) 9778c2ecf20Sopenharmony_ci{ 9788c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info = &p_hwfn->p_dcbx_info->get; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci if (pri >= QED_MAX_PFC_PRIORITIES) { 9818c2ecf20Sopenharmony_ci DP_ERR(p_hwfn, "Invalid priority %d\n", pri); 9828c2ecf20Sopenharmony_ci return QED_DCBX_DEFAULT_TC; 9838c2ecf20Sopenharmony_ci } 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_ci if (!dcbx_info->operational.valid) { 9868c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, 9878c2ecf20Sopenharmony_ci "Dcbx parameters not available\n"); 9888c2ecf20Sopenharmony_ci return QED_DCBX_DEFAULT_TC; 9898c2ecf20Sopenharmony_ci } 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci return dcbx_info->operational.params.ets_pri_tc_tbl[pri]; 9928c2ecf20Sopenharmony_ci} 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ci#ifdef CONFIG_DCB 9958c2ecf20Sopenharmony_cistatic int qed_dcbx_query_params(struct qed_hwfn *p_hwfn, 9968c2ecf20Sopenharmony_ci struct qed_dcbx_get *p_get, 9978c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 9988c2ecf20Sopenharmony_ci{ 9998c2ecf20Sopenharmony_ci struct qed_ptt *p_ptt; 10008c2ecf20Sopenharmony_ci int rc; 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci if (IS_VF(p_hwfn->cdev)) 10038c2ecf20Sopenharmony_ci return -EINVAL; 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci p_ptt = qed_ptt_acquire(p_hwfn); 10068c2ecf20Sopenharmony_ci if (!p_ptt) 10078c2ecf20Sopenharmony_ci return -EBUSY; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 10108c2ecf20Sopenharmony_ci if (rc) 10118c2ecf20Sopenharmony_ci goto out; 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci rc = qed_dcbx_get_params(p_hwfn, p_get, type); 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_ciout: 10168c2ecf20Sopenharmony_ci qed_ptt_release(p_hwfn, p_ptt); 10178c2ecf20Sopenharmony_ci return rc; 10188c2ecf20Sopenharmony_ci} 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_cistatic void 10218c2ecf20Sopenharmony_ciqed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn, 10228c2ecf20Sopenharmony_ci u32 *pfc, struct qed_dcbx_params *p_params) 10238c2ecf20Sopenharmony_ci{ 10248c2ecf20Sopenharmony_ci u8 pfc_map = 0; 10258c2ecf20Sopenharmony_ci int i; 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ci *pfc &= ~DCBX_PFC_ERROR_MASK; 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_ci if (p_params->pfc.willing) 10308c2ecf20Sopenharmony_ci *pfc |= DCBX_PFC_WILLING_MASK; 10318c2ecf20Sopenharmony_ci else 10328c2ecf20Sopenharmony_ci *pfc &= ~DCBX_PFC_WILLING_MASK; 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci if (p_params->pfc.enabled) 10358c2ecf20Sopenharmony_ci *pfc |= DCBX_PFC_ENABLED_MASK; 10368c2ecf20Sopenharmony_ci else 10378c2ecf20Sopenharmony_ci *pfc &= ~DCBX_PFC_ENABLED_MASK; 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci *pfc &= ~DCBX_PFC_CAPS_MASK; 10408c2ecf20Sopenharmony_ci *pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT; 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 10438c2ecf20Sopenharmony_ci if (p_params->pfc.prio[i]) 10448c2ecf20Sopenharmony_ci pfc_map |= BIT(i); 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci *pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK; 10478c2ecf20Sopenharmony_ci *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT); 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc); 10508c2ecf20Sopenharmony_ci} 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_cistatic void 10538c2ecf20Sopenharmony_ciqed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn, 10548c2ecf20Sopenharmony_ci struct dcbx_ets_feature *p_ets, 10558c2ecf20Sopenharmony_ci struct qed_dcbx_params *p_params) 10568c2ecf20Sopenharmony_ci{ 10578c2ecf20Sopenharmony_ci __be32 bw_map[2], tsa_map[2]; 10588c2ecf20Sopenharmony_ci u32 val; 10598c2ecf20Sopenharmony_ci int i; 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci if (p_params->ets_willing) 10628c2ecf20Sopenharmony_ci p_ets->flags |= DCBX_ETS_WILLING_MASK; 10638c2ecf20Sopenharmony_ci else 10648c2ecf20Sopenharmony_ci p_ets->flags &= ~DCBX_ETS_WILLING_MASK; 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci if (p_params->ets_cbs) 10678c2ecf20Sopenharmony_ci p_ets->flags |= DCBX_ETS_CBS_MASK; 10688c2ecf20Sopenharmony_ci else 10698c2ecf20Sopenharmony_ci p_ets->flags &= ~DCBX_ETS_CBS_MASK; 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci if (p_params->ets_enabled) 10728c2ecf20Sopenharmony_ci p_ets->flags |= DCBX_ETS_ENABLED_MASK; 10738c2ecf20Sopenharmony_ci else 10748c2ecf20Sopenharmony_ci p_ets->flags &= ~DCBX_ETS_ENABLED_MASK; 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ci p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK; 10778c2ecf20Sopenharmony_ci p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci p_ets->pri_tc_tbl[0] = 0; 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 10828c2ecf20Sopenharmony_ci ((u8 *)bw_map)[i] = p_params->ets_tc_bw_tbl[i]; 10838c2ecf20Sopenharmony_ci ((u8 *)tsa_map)[i] = p_params->ets_tc_tsa_tbl[i]; 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_ci /* Copy the priority value to the corresponding 4 bits in the 10868c2ecf20Sopenharmony_ci * traffic class table. 10878c2ecf20Sopenharmony_ci */ 10888c2ecf20Sopenharmony_ci val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4)); 10898c2ecf20Sopenharmony_ci p_ets->pri_tc_tbl[0] |= val; 10908c2ecf20Sopenharmony_ci } 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci be32_to_cpu_array(p_ets->tc_bw_tbl, bw_map, 2); 10938c2ecf20Sopenharmony_ci be32_to_cpu_array(p_ets->tc_tsa_tbl, tsa_map, 2); 10948c2ecf20Sopenharmony_ci} 10958c2ecf20Sopenharmony_ci 10968c2ecf20Sopenharmony_cistatic void 10978c2ecf20Sopenharmony_ciqed_dcbx_set_app_data(struct qed_hwfn *p_hwfn, 10988c2ecf20Sopenharmony_ci struct dcbx_app_priority_feature *p_app, 10998c2ecf20Sopenharmony_ci struct qed_dcbx_params *p_params, bool ieee) 11008c2ecf20Sopenharmony_ci{ 11018c2ecf20Sopenharmony_ci u32 *entry; 11028c2ecf20Sopenharmony_ci int i; 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci if (p_params->app_willing) 11058c2ecf20Sopenharmony_ci p_app->flags |= DCBX_APP_WILLING_MASK; 11068c2ecf20Sopenharmony_ci else 11078c2ecf20Sopenharmony_ci p_app->flags &= ~DCBX_APP_WILLING_MASK; 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci if (p_params->app_valid) 11108c2ecf20Sopenharmony_ci p_app->flags |= DCBX_APP_ENABLED_MASK; 11118c2ecf20Sopenharmony_ci else 11128c2ecf20Sopenharmony_ci p_app->flags &= ~DCBX_APP_ENABLED_MASK; 11138c2ecf20Sopenharmony_ci 11148c2ecf20Sopenharmony_ci p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK; 11158c2ecf20Sopenharmony_ci p_app->flags |= (u32)p_params->num_app_entries << 11168c2ecf20Sopenharmony_ci DCBX_APP_NUM_ENTRIES_SHIFT; 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 11198c2ecf20Sopenharmony_ci entry = &p_app->app_pri_tbl[i].entry; 11208c2ecf20Sopenharmony_ci *entry = 0; 11218c2ecf20Sopenharmony_ci if (ieee) { 11228c2ecf20Sopenharmony_ci *entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK); 11238c2ecf20Sopenharmony_ci switch (p_params->app_entry[i].sf_ieee) { 11248c2ecf20Sopenharmony_ci case QED_DCBX_SF_IEEE_ETHTYPE: 11258c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE << 11268c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_SHIFT); 11278c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_ETHTYPE << 11288c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11298c2ecf20Sopenharmony_ci break; 11308c2ecf20Sopenharmony_ci case QED_DCBX_SF_IEEE_TCP_PORT: 11318c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT << 11328c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_SHIFT); 11338c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_PORT << 11348c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11358c2ecf20Sopenharmony_ci break; 11368c2ecf20Sopenharmony_ci case QED_DCBX_SF_IEEE_UDP_PORT: 11378c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT << 11388c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_SHIFT); 11398c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_PORT << 11408c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11418c2ecf20Sopenharmony_ci break; 11428c2ecf20Sopenharmony_ci case QED_DCBX_SF_IEEE_TCP_UDP_PORT: 11438c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT << 11448c2ecf20Sopenharmony_ci DCBX_APP_SF_IEEE_SHIFT); 11458c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_PORT << 11468c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11478c2ecf20Sopenharmony_ci break; 11488c2ecf20Sopenharmony_ci } 11498c2ecf20Sopenharmony_ci } else { 11508c2ecf20Sopenharmony_ci *entry &= ~DCBX_APP_SF_MASK; 11518c2ecf20Sopenharmony_ci if (p_params->app_entry[i].ethtype) 11528c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_ETHTYPE << 11538c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11548c2ecf20Sopenharmony_ci else 11558c2ecf20Sopenharmony_ci *entry |= ((u32)DCBX_APP_SF_PORT << 11568c2ecf20Sopenharmony_ci DCBX_APP_SF_SHIFT); 11578c2ecf20Sopenharmony_ci } 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci *entry &= ~DCBX_APP_PROTOCOL_ID_MASK; 11608c2ecf20Sopenharmony_ci *entry |= ((u32)p_params->app_entry[i].proto_id << 11618c2ecf20Sopenharmony_ci DCBX_APP_PROTOCOL_ID_SHIFT); 11628c2ecf20Sopenharmony_ci *entry &= ~DCBX_APP_PRI_MAP_MASK; 11638c2ecf20Sopenharmony_ci *entry |= ((u32)(p_params->app_entry[i].prio) << 11648c2ecf20Sopenharmony_ci DCBX_APP_PRI_MAP_SHIFT); 11658c2ecf20Sopenharmony_ci } 11668c2ecf20Sopenharmony_ci} 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_cistatic void 11698c2ecf20Sopenharmony_ciqed_dcbx_set_local_params(struct qed_hwfn *p_hwfn, 11708c2ecf20Sopenharmony_ci struct dcbx_local_params *local_admin, 11718c2ecf20Sopenharmony_ci struct qed_dcbx_set *params) 11728c2ecf20Sopenharmony_ci{ 11738c2ecf20Sopenharmony_ci bool ieee = false; 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_ci local_admin->flags = 0; 11768c2ecf20Sopenharmony_ci memcpy(&local_admin->features, 11778c2ecf20Sopenharmony_ci &p_hwfn->p_dcbx_info->operational.features, 11788c2ecf20Sopenharmony_ci sizeof(local_admin->features)); 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci if (params->enabled) { 11818c2ecf20Sopenharmony_ci local_admin->config = params->ver_num; 11828c2ecf20Sopenharmony_ci ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE); 11838c2ecf20Sopenharmony_ci } else { 11848c2ecf20Sopenharmony_ci local_admin->config = DCBX_CONFIG_VERSION_DISABLED; 11858c2ecf20Sopenharmony_ci } 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Dcbx version = %d\n", 11888c2ecf20Sopenharmony_ci local_admin->config); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci if (params->override_flags & QED_DCBX_OVERRIDE_PFC_CFG) 11918c2ecf20Sopenharmony_ci qed_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc, 11928c2ecf20Sopenharmony_ci ¶ms->config.params); 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci if (params->override_flags & QED_DCBX_OVERRIDE_ETS_CFG) 11958c2ecf20Sopenharmony_ci qed_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets, 11968c2ecf20Sopenharmony_ci ¶ms->config.params); 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci if (params->override_flags & QED_DCBX_OVERRIDE_APP_CFG) 11998c2ecf20Sopenharmony_ci qed_dcbx_set_app_data(p_hwfn, &local_admin->features.app, 12008c2ecf20Sopenharmony_ci ¶ms->config.params, ieee); 12018c2ecf20Sopenharmony_ci} 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ciint qed_dcbx_config_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 12048c2ecf20Sopenharmony_ci struct qed_dcbx_set *params, bool hw_commit) 12058c2ecf20Sopenharmony_ci{ 12068c2ecf20Sopenharmony_ci struct dcbx_local_params local_admin; 12078c2ecf20Sopenharmony_ci struct qed_dcbx_mib_meta_data data; 12088c2ecf20Sopenharmony_ci u32 resp = 0, param = 0; 12098c2ecf20Sopenharmony_ci int rc = 0; 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci if (!hw_commit) { 12128c2ecf20Sopenharmony_ci memcpy(&p_hwfn->p_dcbx_info->set, params, 12138c2ecf20Sopenharmony_ci sizeof(struct qed_dcbx_set)); 12148c2ecf20Sopenharmony_ci return 0; 12158c2ecf20Sopenharmony_ci } 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci /* clear set-parmas cache */ 12188c2ecf20Sopenharmony_ci memset(&p_hwfn->p_dcbx_info->set, 0, sizeof(p_hwfn->p_dcbx_info->set)); 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci memset(&local_admin, 0, sizeof(local_admin)); 12218c2ecf20Sopenharmony_ci qed_dcbx_set_local_params(p_hwfn, &local_admin, params); 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci data.addr = p_hwfn->mcp_info->port_addr + 12248c2ecf20Sopenharmony_ci offsetof(struct public_port, local_admin_dcbx_mib); 12258c2ecf20Sopenharmony_ci data.local_admin = &local_admin; 12268c2ecf20Sopenharmony_ci data.size = sizeof(struct dcbx_local_params); 12278c2ecf20Sopenharmony_ci qed_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size); 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX, 12308c2ecf20Sopenharmony_ci 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, ¶m); 12318c2ecf20Sopenharmony_ci if (rc) 12328c2ecf20Sopenharmony_ci DP_NOTICE(p_hwfn, "Failed to send DCBX update request\n"); 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci return rc; 12358c2ecf20Sopenharmony_ci} 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ciint qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, 12388c2ecf20Sopenharmony_ci struct qed_dcbx_set *params) 12398c2ecf20Sopenharmony_ci{ 12408c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 12418c2ecf20Sopenharmony_ci int rc; 12428c2ecf20Sopenharmony_ci 12438c2ecf20Sopenharmony_ci if (p_hwfn->p_dcbx_info->set.config.valid) { 12448c2ecf20Sopenharmony_ci memcpy(params, &p_hwfn->p_dcbx_info->set, 12458c2ecf20Sopenharmony_ci sizeof(struct qed_dcbx_set)); 12468c2ecf20Sopenharmony_ci return 0; 12478c2ecf20Sopenharmony_ci } 12488c2ecf20Sopenharmony_ci 12498c2ecf20Sopenharmony_ci dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL); 12508c2ecf20Sopenharmony_ci if (!dcbx_info) 12518c2ecf20Sopenharmony_ci return -ENOMEM; 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB); 12548c2ecf20Sopenharmony_ci if (rc) { 12558c2ecf20Sopenharmony_ci kfree(dcbx_info); 12568c2ecf20Sopenharmony_ci return rc; 12578c2ecf20Sopenharmony_ci } 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.override_flags = 0; 12608c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED; 12618c2ecf20Sopenharmony_ci if (dcbx_info->operational.cee) 12628c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE; 12638c2ecf20Sopenharmony_ci if (dcbx_info->operational.ieee) 12648c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 12658c2ecf20Sopenharmony_ci if (dcbx_info->operational.local) 12668c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC; 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; 12698c2ecf20Sopenharmony_ci BUILD_BUG_ON(sizeof(dcbx_info->operational.params) != 12708c2ecf20Sopenharmony_ci sizeof(p_hwfn->p_dcbx_info->set.config.params)); 12718c2ecf20Sopenharmony_ci memcpy(&p_hwfn->p_dcbx_info->set.config.params, 12728c2ecf20Sopenharmony_ci &dcbx_info->operational.params, 12738c2ecf20Sopenharmony_ci sizeof(p_hwfn->p_dcbx_info->set.config.params)); 12748c2ecf20Sopenharmony_ci p_hwfn->p_dcbx_info->set.config.valid = true; 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci kfree(dcbx_info); 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci return 0; 12818c2ecf20Sopenharmony_ci} 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_cistatic struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, 12848c2ecf20Sopenharmony_ci enum qed_mib_read_type type) 12858c2ecf20Sopenharmony_ci{ 12868c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_ATOMIC); 12898c2ecf20Sopenharmony_ci if (!dcbx_info) 12908c2ecf20Sopenharmony_ci return NULL; 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci if (qed_dcbx_query_params(hwfn, dcbx_info, type)) { 12938c2ecf20Sopenharmony_ci kfree(dcbx_info); 12948c2ecf20Sopenharmony_ci return NULL; 12958c2ecf20Sopenharmony_ci } 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci if ((type == QED_DCBX_OPERATIONAL_MIB) && 12988c2ecf20Sopenharmony_ci !dcbx_info->operational.enabled) { 12998c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational\n"); 13008c2ecf20Sopenharmony_ci kfree(dcbx_info); 13018c2ecf20Sopenharmony_ci return NULL; 13028c2ecf20Sopenharmony_ci } 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci return dcbx_info; 13058c2ecf20Sopenharmony_ci} 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_getstate(struct qed_dev *cdev) 13088c2ecf20Sopenharmony_ci{ 13098c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 13108c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 13118c2ecf20Sopenharmony_ci bool enabled; 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 13148c2ecf20Sopenharmony_ci if (!dcbx_info) 13158c2ecf20Sopenharmony_ci return 0; 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci enabled = dcbx_info->operational.enabled; 13188c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", enabled); 13198c2ecf20Sopenharmony_ci kfree(dcbx_info); 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_ci return enabled; 13228c2ecf20Sopenharmony_ci} 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_setstate(struct qed_dev *cdev, u8 state) 13258c2ecf20Sopenharmony_ci{ 13268c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 13278c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 13288c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 13298c2ecf20Sopenharmony_ci int rc; 13308c2ecf20Sopenharmony_ci 13318c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", state); 13328c2ecf20Sopenharmony_ci 13338c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 13348c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 13358c2ecf20Sopenharmony_ci if (rc) 13368c2ecf20Sopenharmony_ci return 1; 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_ci dcbx_set.enabled = !!state; 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 13418c2ecf20Sopenharmony_ci if (!ptt) 13428c2ecf20Sopenharmony_ci return 1; 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ci return rc ? 1 : 0; 13498c2ecf20Sopenharmony_ci} 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_cistatic void qed_dcbnl_getpgtccfgtx(struct qed_dev *cdev, int tc, u8 *prio_type, 13528c2ecf20Sopenharmony_ci u8 *pgid, u8 *bw_pct, u8 *up_map) 13538c2ecf20Sopenharmony_ci{ 13548c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 13558c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "tc = %d\n", tc); 13588c2ecf20Sopenharmony_ci *prio_type = *pgid = *bw_pct = *up_map = 0; 13598c2ecf20Sopenharmony_ci if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 13608c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid tc %d\n", tc); 13618c2ecf20Sopenharmony_ci return; 13628c2ecf20Sopenharmony_ci } 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 13658c2ecf20Sopenharmony_ci if (!dcbx_info) 13668c2ecf20Sopenharmony_ci return; 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci *pgid = dcbx_info->operational.params.ets_pri_tc_tbl[tc]; 13698c2ecf20Sopenharmony_ci kfree(dcbx_info); 13708c2ecf20Sopenharmony_ci} 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_cistatic void qed_dcbnl_getpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 *bw_pct) 13738c2ecf20Sopenharmony_ci{ 13748c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 13758c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci *bw_pct = 0; 13788c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d\n", pgid); 13798c2ecf20Sopenharmony_ci if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 13808c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 13818c2ecf20Sopenharmony_ci return; 13828c2ecf20Sopenharmony_ci } 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 13858c2ecf20Sopenharmony_ci if (!dcbx_info) 13868c2ecf20Sopenharmony_ci return; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci *bw_pct = dcbx_info->operational.params.ets_tc_bw_tbl[pgid]; 13898c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "bw_pct = %d\n", *bw_pct); 13908c2ecf20Sopenharmony_ci kfree(dcbx_info); 13918c2ecf20Sopenharmony_ci} 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_cistatic void qed_dcbnl_getpgtccfgrx(struct qed_dev *cdev, int tc, u8 *prio, 13948c2ecf20Sopenharmony_ci u8 *bwg_id, u8 *bw_pct, u8 *up_map) 13958c2ecf20Sopenharmony_ci{ 13968c2ecf20Sopenharmony_ci DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 13978c2ecf20Sopenharmony_ci *prio = *bwg_id = *bw_pct = *up_map = 0; 13988c2ecf20Sopenharmony_ci} 13998c2ecf20Sopenharmony_ci 14008c2ecf20Sopenharmony_cistatic void qed_dcbnl_getpgbwgcfgrx(struct qed_dev *cdev, 14018c2ecf20Sopenharmony_ci int bwg_id, u8 *bw_pct) 14028c2ecf20Sopenharmony_ci{ 14038c2ecf20Sopenharmony_ci DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 14048c2ecf20Sopenharmony_ci *bw_pct = 0; 14058c2ecf20Sopenharmony_ci} 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_cistatic void qed_dcbnl_getpfccfg(struct qed_dev *cdev, 14088c2ecf20Sopenharmony_ci int priority, u8 *setting) 14098c2ecf20Sopenharmony_ci{ 14108c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 14118c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d\n", priority); 14148c2ecf20Sopenharmony_ci if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 14158c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid priority %d\n", priority); 14168c2ecf20Sopenharmony_ci return; 14178c2ecf20Sopenharmony_ci } 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 14208c2ecf20Sopenharmony_ci if (!dcbx_info) 14218c2ecf20Sopenharmony_ci return; 14228c2ecf20Sopenharmony_ci 14238c2ecf20Sopenharmony_ci *setting = dcbx_info->operational.params.pfc.prio[priority]; 14248c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "setting = %d\n", *setting); 14258c2ecf20Sopenharmony_ci kfree(dcbx_info); 14268c2ecf20Sopenharmony_ci} 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpfccfg(struct qed_dev *cdev, int priority, u8 setting) 14298c2ecf20Sopenharmony_ci{ 14308c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 14318c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 14328c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 14338c2ecf20Sopenharmony_ci int rc; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d setting = %d\n", 14368c2ecf20Sopenharmony_ci priority, setting); 14378c2ecf20Sopenharmony_ci if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 14388c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid priority %d\n", priority); 14398c2ecf20Sopenharmony_ci return; 14408c2ecf20Sopenharmony_ci } 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 14438c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 14448c2ecf20Sopenharmony_ci if (rc) 14458c2ecf20Sopenharmony_ci return; 14468c2ecf20Sopenharmony_ci 14478c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 14488c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.prio[priority] = !!setting; 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 14518c2ecf20Sopenharmony_ci if (!ptt) 14528c2ecf20Sopenharmony_ci return; 14538c2ecf20Sopenharmony_ci 14548c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 14578c2ecf20Sopenharmony_ci} 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap) 14608c2ecf20Sopenharmony_ci{ 14618c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 14628c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 14638c2ecf20Sopenharmony_ci int rc = 0; 14648c2ecf20Sopenharmony_ci 14658c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "capid = %d\n", capid); 14668c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 14678c2ecf20Sopenharmony_ci if (!dcbx_info) 14688c2ecf20Sopenharmony_ci return 1; 14698c2ecf20Sopenharmony_ci 14708c2ecf20Sopenharmony_ci switch (capid) { 14718c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PG: 14728c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PFC: 14738c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_UP2TC: 14748c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_GSP: 14758c2ecf20Sopenharmony_ci *cap = true; 14768c2ecf20Sopenharmony_ci break; 14778c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PG_TCS: 14788c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_PFC_TCS: 14798c2ecf20Sopenharmony_ci *cap = 0x80; 14808c2ecf20Sopenharmony_ci break; 14818c2ecf20Sopenharmony_ci case DCB_CAP_ATTR_DCBX: 14828c2ecf20Sopenharmony_ci *cap = (DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_VER_IEEE | 14838c2ecf20Sopenharmony_ci DCB_CAP_DCBX_STATIC); 14848c2ecf20Sopenharmony_ci break; 14858c2ecf20Sopenharmony_ci default: 14868c2ecf20Sopenharmony_ci *cap = false; 14878c2ecf20Sopenharmony_ci rc = 1; 14888c2ecf20Sopenharmony_ci } 14898c2ecf20Sopenharmony_ci 14908c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "id = %d caps = %d\n", capid, *cap); 14918c2ecf20Sopenharmony_ci kfree(dcbx_info); 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci return rc; 14948c2ecf20Sopenharmony_ci} 14958c2ecf20Sopenharmony_ci 14968c2ecf20Sopenharmony_cistatic int qed_dcbnl_getnumtcs(struct qed_dev *cdev, int tcid, u8 *num) 14978c2ecf20Sopenharmony_ci{ 14988c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 14998c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 15008c2ecf20Sopenharmony_ci int rc = 0; 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d\n", tcid); 15038c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 15048c2ecf20Sopenharmony_ci if (!dcbx_info) 15058c2ecf20Sopenharmony_ci return -EINVAL; 15068c2ecf20Sopenharmony_ci 15078c2ecf20Sopenharmony_ci switch (tcid) { 15088c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PG: 15098c2ecf20Sopenharmony_ci *num = dcbx_info->operational.params.max_ets_tc; 15108c2ecf20Sopenharmony_ci break; 15118c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PFC: 15128c2ecf20Sopenharmony_ci *num = dcbx_info->operational.params.pfc.max_tc; 15138c2ecf20Sopenharmony_ci break; 15148c2ecf20Sopenharmony_ci default: 15158c2ecf20Sopenharmony_ci rc = -EINVAL; 15168c2ecf20Sopenharmony_ci } 15178c2ecf20Sopenharmony_ci 15188c2ecf20Sopenharmony_ci kfree(dcbx_info); 15198c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "numtcs = %d\n", *num); 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci return rc; 15228c2ecf20Sopenharmony_ci} 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_getpfcstate(struct qed_dev *cdev) 15258c2ecf20Sopenharmony_ci{ 15268c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 15278c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 15288c2ecf20Sopenharmony_ci bool enabled; 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 15318c2ecf20Sopenharmony_ci if (!dcbx_info) 15328c2ecf20Sopenharmony_ci return 0; 15338c2ecf20Sopenharmony_ci 15348c2ecf20Sopenharmony_ci enabled = dcbx_info->operational.params.pfc.enabled; 15358c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d\n", enabled); 15368c2ecf20Sopenharmony_ci kfree(dcbx_info); 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_ci return enabled; 15398c2ecf20Sopenharmony_ci} 15408c2ecf20Sopenharmony_ci 15418c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_getdcbx(struct qed_dev *cdev) 15428c2ecf20Sopenharmony_ci{ 15438c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 15448c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 15458c2ecf20Sopenharmony_ci u8 mode = 0; 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 15488c2ecf20Sopenharmony_ci if (!dcbx_info) 15498c2ecf20Sopenharmony_ci return 0; 15508c2ecf20Sopenharmony_ci 15518c2ecf20Sopenharmony_ci if (dcbx_info->operational.ieee) 15528c2ecf20Sopenharmony_ci mode |= DCB_CAP_DCBX_VER_IEEE; 15538c2ecf20Sopenharmony_ci if (dcbx_info->operational.cee) 15548c2ecf20Sopenharmony_ci mode |= DCB_CAP_DCBX_VER_CEE; 15558c2ecf20Sopenharmony_ci if (dcbx_info->operational.local) 15568c2ecf20Sopenharmony_ci mode |= DCB_CAP_DCBX_STATIC; 15578c2ecf20Sopenharmony_ci 15588c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode); 15598c2ecf20Sopenharmony_ci kfree(dcbx_info); 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci return mode; 15628c2ecf20Sopenharmony_ci} 15638c2ecf20Sopenharmony_ci 15648c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpgtccfgtx(struct qed_dev *cdev, 15658c2ecf20Sopenharmony_ci int tc, 15668c2ecf20Sopenharmony_ci u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 15678c2ecf20Sopenharmony_ci{ 15688c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 15698c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 15708c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 15718c2ecf20Sopenharmony_ci int rc; 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, 15748c2ecf20Sopenharmony_ci "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n", 15758c2ecf20Sopenharmony_ci tc, pri_type, pgid, bw_pct, up_map); 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_ci if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 15788c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid tc %d\n", tc); 15798c2ecf20Sopenharmony_ci return; 15808c2ecf20Sopenharmony_ci } 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 15838c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 15848c2ecf20Sopenharmony_ci if (rc) 15858c2ecf20Sopenharmony_ci return; 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 15888c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_pri_tc_tbl[tc] = pgid; 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 15918c2ecf20Sopenharmony_ci if (!ptt) 15928c2ecf20Sopenharmony_ci return; 15938c2ecf20Sopenharmony_ci 15948c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 15978c2ecf20Sopenharmony_ci} 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpgtccfgrx(struct qed_dev *cdev, int prio, 16008c2ecf20Sopenharmony_ci u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 16018c2ecf20Sopenharmony_ci{ 16028c2ecf20Sopenharmony_ci DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 16038c2ecf20Sopenharmony_ci} 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 bw_pct) 16068c2ecf20Sopenharmony_ci{ 16078c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 16088c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 16098c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 16108c2ecf20Sopenharmony_ci int rc; 16118c2ecf20Sopenharmony_ci 16128c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d bw_pct = %d\n", pgid, bw_pct); 16138c2ecf20Sopenharmony_ci if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 16148c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 16158c2ecf20Sopenharmony_ci return; 16168c2ecf20Sopenharmony_ci } 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 16198c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 16208c2ecf20Sopenharmony_ci if (rc) 16218c2ecf20Sopenharmony_ci return; 16228c2ecf20Sopenharmony_ci 16238c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 16248c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_tc_bw_tbl[pgid] = bw_pct; 16258c2ecf20Sopenharmony_ci 16268c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 16278c2ecf20Sopenharmony_ci if (!ptt) 16288c2ecf20Sopenharmony_ci return; 16298c2ecf20Sopenharmony_ci 16308c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 16318c2ecf20Sopenharmony_ci 16328c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 16338c2ecf20Sopenharmony_ci} 16348c2ecf20Sopenharmony_ci 16358c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpgbwgcfgrx(struct qed_dev *cdev, int pgid, u8 bw_pct) 16368c2ecf20Sopenharmony_ci{ 16378c2ecf20Sopenharmony_ci DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 16388c2ecf20Sopenharmony_ci} 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_setall(struct qed_dev *cdev) 16418c2ecf20Sopenharmony_ci{ 16428c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 16438c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 16448c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 16458c2ecf20Sopenharmony_ci int rc; 16468c2ecf20Sopenharmony_ci 16478c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 16488c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 16498c2ecf20Sopenharmony_ci if (rc) 16508c2ecf20Sopenharmony_ci return 1; 16518c2ecf20Sopenharmony_ci 16528c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 16538c2ecf20Sopenharmony_ci if (!ptt) 16548c2ecf20Sopenharmony_ci return 1; 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 1); 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 16598c2ecf20Sopenharmony_ci 16608c2ecf20Sopenharmony_ci return rc; 16618c2ecf20Sopenharmony_ci} 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_cistatic int qed_dcbnl_setnumtcs(struct qed_dev *cdev, int tcid, u8 num) 16648c2ecf20Sopenharmony_ci{ 16658c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 16668c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 16678c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 16688c2ecf20Sopenharmony_ci int rc; 16698c2ecf20Sopenharmony_ci 16708c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d num = %d\n", tcid, num); 16718c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 16728c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 16738c2ecf20Sopenharmony_ci if (rc) 16748c2ecf20Sopenharmony_ci return 1; 16758c2ecf20Sopenharmony_ci 16768c2ecf20Sopenharmony_ci switch (tcid) { 16778c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PG: 16788c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 16798c2ecf20Sopenharmony_ci dcbx_set.config.params.max_ets_tc = num; 16808c2ecf20Sopenharmony_ci break; 16818c2ecf20Sopenharmony_ci case DCB_NUMTCS_ATTR_PFC: 16828c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 16838c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.max_tc = num; 16848c2ecf20Sopenharmony_ci break; 16858c2ecf20Sopenharmony_ci default: 16868c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid tcid %d\n", tcid); 16878c2ecf20Sopenharmony_ci return -EINVAL; 16888c2ecf20Sopenharmony_ci } 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 16918c2ecf20Sopenharmony_ci if (!ptt) 16928c2ecf20Sopenharmony_ci return -EINVAL; 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 16958c2ecf20Sopenharmony_ci 16968c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_ci return 0; 16998c2ecf20Sopenharmony_ci} 17008c2ecf20Sopenharmony_ci 17018c2ecf20Sopenharmony_cistatic void qed_dcbnl_setpfcstate(struct qed_dev *cdev, u8 state) 17028c2ecf20Sopenharmony_ci{ 17038c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 17048c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 17058c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 17068c2ecf20Sopenharmony_ci int rc; 17078c2ecf20Sopenharmony_ci 17088c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "new state = %d\n", state); 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 17118c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 17128c2ecf20Sopenharmony_ci if (rc) 17138c2ecf20Sopenharmony_ci return; 17148c2ecf20Sopenharmony_ci 17158c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 17168c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.enabled = !!state; 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 17198c2ecf20Sopenharmony_ci if (!ptt) 17208c2ecf20Sopenharmony_ci return; 17218c2ecf20Sopenharmony_ci 17228c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 17258c2ecf20Sopenharmony_ci} 17268c2ecf20Sopenharmony_ci 17278c2ecf20Sopenharmony_cistatic int qed_dcbnl_getapp(struct qed_dev *cdev, u8 idtype, u16 idval) 17288c2ecf20Sopenharmony_ci{ 17298c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 17308c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 17318c2ecf20Sopenharmony_ci struct qed_app_entry *entry; 17328c2ecf20Sopenharmony_ci bool ethtype; 17338c2ecf20Sopenharmony_ci u8 prio = 0; 17348c2ecf20Sopenharmony_ci int i; 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 17378c2ecf20Sopenharmony_ci if (!dcbx_info) 17388c2ecf20Sopenharmony_ci return -EINVAL; 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 17418c2ecf20Sopenharmony_ci for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 17428c2ecf20Sopenharmony_ci entry = &dcbx_info->operational.params.app_entry[i]; 17438c2ecf20Sopenharmony_ci if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) { 17448c2ecf20Sopenharmony_ci prio = entry->prio; 17458c2ecf20Sopenharmony_ci break; 17468c2ecf20Sopenharmony_ci } 17478c2ecf20Sopenharmony_ci } 17488c2ecf20Sopenharmony_ci 17498c2ecf20Sopenharmony_ci if (i == QED_DCBX_MAX_APP_PROTOCOL) { 17508c2ecf20Sopenharmony_ci DP_ERR(cdev, "App entry (%d, %d) not found\n", idtype, idval); 17518c2ecf20Sopenharmony_ci kfree(dcbx_info); 17528c2ecf20Sopenharmony_ci return -EINVAL; 17538c2ecf20Sopenharmony_ci } 17548c2ecf20Sopenharmony_ci 17558c2ecf20Sopenharmony_ci kfree(dcbx_info); 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_ci return prio; 17588c2ecf20Sopenharmony_ci} 17598c2ecf20Sopenharmony_ci 17608c2ecf20Sopenharmony_cistatic int qed_dcbnl_setapp(struct qed_dev *cdev, 17618c2ecf20Sopenharmony_ci u8 idtype, u16 idval, u8 pri_map) 17628c2ecf20Sopenharmony_ci{ 17638c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 17648c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 17658c2ecf20Sopenharmony_ci struct qed_app_entry *entry; 17668c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 17678c2ecf20Sopenharmony_ci bool ethtype; 17688c2ecf20Sopenharmony_ci int rc, i; 17698c2ecf20Sopenharmony_ci 17708c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 17718c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 17728c2ecf20Sopenharmony_ci if (rc) 17738c2ecf20Sopenharmony_ci return -EINVAL; 17748c2ecf20Sopenharmony_ci 17758c2ecf20Sopenharmony_ci ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 17768c2ecf20Sopenharmony_ci for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 17778c2ecf20Sopenharmony_ci entry = &dcbx_set.config.params.app_entry[i]; 17788c2ecf20Sopenharmony_ci if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) 17798c2ecf20Sopenharmony_ci break; 17808c2ecf20Sopenharmony_ci /* First empty slot */ 17818c2ecf20Sopenharmony_ci if (!entry->proto_id) { 17828c2ecf20Sopenharmony_ci dcbx_set.config.params.num_app_entries++; 17838c2ecf20Sopenharmony_ci break; 17848c2ecf20Sopenharmony_ci } 17858c2ecf20Sopenharmony_ci } 17868c2ecf20Sopenharmony_ci 17878c2ecf20Sopenharmony_ci if (i == QED_DCBX_MAX_APP_PROTOCOL) { 17888c2ecf20Sopenharmony_ci DP_ERR(cdev, "App table is full\n"); 17898c2ecf20Sopenharmony_ci return -EBUSY; 17908c2ecf20Sopenharmony_ci } 17918c2ecf20Sopenharmony_ci 17928c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 17938c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].ethtype = ethtype; 17948c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].proto_id = idval; 17958c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].prio = pri_map; 17968c2ecf20Sopenharmony_ci 17978c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 17988c2ecf20Sopenharmony_ci if (!ptt) 17998c2ecf20Sopenharmony_ci return -EBUSY; 18008c2ecf20Sopenharmony_ci 18018c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 18028c2ecf20Sopenharmony_ci 18038c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 18048c2ecf20Sopenharmony_ci 18058c2ecf20Sopenharmony_ci return rc; 18068c2ecf20Sopenharmony_ci} 18078c2ecf20Sopenharmony_ci 18088c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_setdcbx(struct qed_dev *cdev, u8 mode) 18098c2ecf20Sopenharmony_ci{ 18108c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 18118c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 18128c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 18138c2ecf20Sopenharmony_ci int rc; 18148c2ecf20Sopenharmony_ci 18158c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "new mode = %x\n", mode); 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci if (!(mode & DCB_CAP_DCBX_VER_IEEE) && 18188c2ecf20Sopenharmony_ci !(mode & DCB_CAP_DCBX_VER_CEE) && !(mode & DCB_CAP_DCBX_STATIC)) { 18198c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Allowed modes are cee, ieee or static\n"); 18208c2ecf20Sopenharmony_ci return 1; 18218c2ecf20Sopenharmony_ci } 18228c2ecf20Sopenharmony_ci 18238c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 18248c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 18258c2ecf20Sopenharmony_ci if (rc) 18268c2ecf20Sopenharmony_ci return 1; 18278c2ecf20Sopenharmony_ci 18288c2ecf20Sopenharmony_ci dcbx_set.ver_num = 0; 18298c2ecf20Sopenharmony_ci if (mode & DCB_CAP_DCBX_VER_CEE) { 18308c2ecf20Sopenharmony_ci dcbx_set.ver_num |= DCBX_CONFIG_VERSION_CEE; 18318c2ecf20Sopenharmony_ci dcbx_set.enabled = true; 18328c2ecf20Sopenharmony_ci } 18338c2ecf20Sopenharmony_ci 18348c2ecf20Sopenharmony_ci if (mode & DCB_CAP_DCBX_VER_IEEE) { 18358c2ecf20Sopenharmony_ci dcbx_set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 18368c2ecf20Sopenharmony_ci dcbx_set.enabled = true; 18378c2ecf20Sopenharmony_ci } 18388c2ecf20Sopenharmony_ci 18398c2ecf20Sopenharmony_ci if (mode & DCB_CAP_DCBX_STATIC) { 18408c2ecf20Sopenharmony_ci dcbx_set.ver_num |= DCBX_CONFIG_VERSION_STATIC; 18418c2ecf20Sopenharmony_ci dcbx_set.enabled = true; 18428c2ecf20Sopenharmony_ci } 18438c2ecf20Sopenharmony_ci 18448c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 18458c2ecf20Sopenharmony_ci if (!ptt) 18468c2ecf20Sopenharmony_ci return 1; 18478c2ecf20Sopenharmony_ci 18488c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 18498c2ecf20Sopenharmony_ci 18508c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 18518c2ecf20Sopenharmony_ci 18528c2ecf20Sopenharmony_ci return rc; 18538c2ecf20Sopenharmony_ci} 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_getfeatcfg(struct qed_dev *cdev, int featid, u8 *flags) 18568c2ecf20Sopenharmony_ci{ 18578c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 18588c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 18598c2ecf20Sopenharmony_ci 18608c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "Feature id = %d\n", featid); 18618c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 18628c2ecf20Sopenharmony_ci if (!dcbx_info) 18638c2ecf20Sopenharmony_ci return 1; 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci *flags = 0; 18668c2ecf20Sopenharmony_ci switch (featid) { 18678c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_PG: 18688c2ecf20Sopenharmony_ci if (dcbx_info->operational.params.ets_enabled) 18698c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ENABLE; 18708c2ecf20Sopenharmony_ci else 18718c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ERROR; 18728c2ecf20Sopenharmony_ci break; 18738c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_PFC: 18748c2ecf20Sopenharmony_ci if (dcbx_info->operational.params.pfc.enabled) 18758c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ENABLE; 18768c2ecf20Sopenharmony_ci else 18778c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ERROR; 18788c2ecf20Sopenharmony_ci break; 18798c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_APP: 18808c2ecf20Sopenharmony_ci if (dcbx_info->operational.params.app_valid) 18818c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ENABLE; 18828c2ecf20Sopenharmony_ci else 18838c2ecf20Sopenharmony_ci *flags = DCB_FEATCFG_ERROR; 18848c2ecf20Sopenharmony_ci break; 18858c2ecf20Sopenharmony_ci default: 18868c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 18878c2ecf20Sopenharmony_ci kfree(dcbx_info); 18888c2ecf20Sopenharmony_ci return 1; 18898c2ecf20Sopenharmony_ci } 18908c2ecf20Sopenharmony_ci 18918c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "flags = %d\n", *flags); 18928c2ecf20Sopenharmony_ci kfree(dcbx_info); 18938c2ecf20Sopenharmony_ci 18948c2ecf20Sopenharmony_ci return 0; 18958c2ecf20Sopenharmony_ci} 18968c2ecf20Sopenharmony_ci 18978c2ecf20Sopenharmony_cistatic u8 qed_dcbnl_setfeatcfg(struct qed_dev *cdev, int featid, u8 flags) 18988c2ecf20Sopenharmony_ci{ 18998c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 19008c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 19018c2ecf20Sopenharmony_ci bool enabled, willing; 19028c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 19038c2ecf20Sopenharmony_ci int rc; 19048c2ecf20Sopenharmony_ci 19058c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "featid = %d flags = %d\n", 19068c2ecf20Sopenharmony_ci featid, flags); 19078c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 19088c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 19098c2ecf20Sopenharmony_ci if (rc) 19108c2ecf20Sopenharmony_ci return 1; 19118c2ecf20Sopenharmony_ci 19128c2ecf20Sopenharmony_ci enabled = !!(flags & DCB_FEATCFG_ENABLE); 19138c2ecf20Sopenharmony_ci willing = !!(flags & DCB_FEATCFG_WILLING); 19148c2ecf20Sopenharmony_ci switch (featid) { 19158c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_PG: 19168c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 19178c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_enabled = enabled; 19188c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_willing = willing; 19198c2ecf20Sopenharmony_ci break; 19208c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_PFC: 19218c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 19228c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.enabled = enabled; 19238c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.willing = willing; 19248c2ecf20Sopenharmony_ci break; 19258c2ecf20Sopenharmony_ci case DCB_FEATCFG_ATTR_APP: 19268c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 19278c2ecf20Sopenharmony_ci dcbx_set.config.params.app_willing = willing; 19288c2ecf20Sopenharmony_ci break; 19298c2ecf20Sopenharmony_ci default: 19308c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 19318c2ecf20Sopenharmony_ci return 1; 19328c2ecf20Sopenharmony_ci } 19338c2ecf20Sopenharmony_ci 19348c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 19358c2ecf20Sopenharmony_ci if (!ptt) 19368c2ecf20Sopenharmony_ci return 1; 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 19418c2ecf20Sopenharmony_ci 19428c2ecf20Sopenharmony_ci return 0; 19438c2ecf20Sopenharmony_ci} 19448c2ecf20Sopenharmony_ci 19458c2ecf20Sopenharmony_cistatic int qed_dcbnl_peer_getappinfo(struct qed_dev *cdev, 19468c2ecf20Sopenharmony_ci struct dcb_peer_app_info *info, 19478c2ecf20Sopenharmony_ci u16 *app_count) 19488c2ecf20Sopenharmony_ci{ 19498c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 19508c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 19518c2ecf20Sopenharmony_ci 19528c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 19538c2ecf20Sopenharmony_ci if (!dcbx_info) 19548c2ecf20Sopenharmony_ci return -EINVAL; 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_ci info->willing = dcbx_info->remote.params.app_willing; 19578c2ecf20Sopenharmony_ci info->error = dcbx_info->remote.params.app_error; 19588c2ecf20Sopenharmony_ci *app_count = dcbx_info->remote.params.num_app_entries; 19598c2ecf20Sopenharmony_ci kfree(dcbx_info); 19608c2ecf20Sopenharmony_ci 19618c2ecf20Sopenharmony_ci return 0; 19628c2ecf20Sopenharmony_ci} 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_cistatic int qed_dcbnl_peer_getapptable(struct qed_dev *cdev, 19658c2ecf20Sopenharmony_ci struct dcb_app *table) 19668c2ecf20Sopenharmony_ci{ 19678c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 19688c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 19698c2ecf20Sopenharmony_ci int i; 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 19728c2ecf20Sopenharmony_ci if (!dcbx_info) 19738c2ecf20Sopenharmony_ci return -EINVAL; 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_ci for (i = 0; i < dcbx_info->remote.params.num_app_entries; i++) { 19768c2ecf20Sopenharmony_ci if (dcbx_info->remote.params.app_entry[i].ethtype) 19778c2ecf20Sopenharmony_ci table[i].selector = DCB_APP_IDTYPE_ETHTYPE; 19788c2ecf20Sopenharmony_ci else 19798c2ecf20Sopenharmony_ci table[i].selector = DCB_APP_IDTYPE_PORTNUM; 19808c2ecf20Sopenharmony_ci table[i].priority = dcbx_info->remote.params.app_entry[i].prio; 19818c2ecf20Sopenharmony_ci table[i].protocol = 19828c2ecf20Sopenharmony_ci dcbx_info->remote.params.app_entry[i].proto_id; 19838c2ecf20Sopenharmony_ci } 19848c2ecf20Sopenharmony_ci 19858c2ecf20Sopenharmony_ci kfree(dcbx_info); 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_ci return 0; 19888c2ecf20Sopenharmony_ci} 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_cistatic int qed_dcbnl_cee_peer_getpfc(struct qed_dev *cdev, struct cee_pfc *pfc) 19918c2ecf20Sopenharmony_ci{ 19928c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 19938c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 19948c2ecf20Sopenharmony_ci int i; 19958c2ecf20Sopenharmony_ci 19968c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 19978c2ecf20Sopenharmony_ci if (!dcbx_info) 19988c2ecf20Sopenharmony_ci return -EINVAL; 19998c2ecf20Sopenharmony_ci 20008c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 20018c2ecf20Sopenharmony_ci if (dcbx_info->remote.params.pfc.prio[i]) 20028c2ecf20Sopenharmony_ci pfc->pfc_en |= BIT(i); 20038c2ecf20Sopenharmony_ci 20048c2ecf20Sopenharmony_ci pfc->tcs_supported = dcbx_info->remote.params.pfc.max_tc; 20058c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d tcs_supported = %d\n", 20068c2ecf20Sopenharmony_ci pfc->pfc_en, pfc->tcs_supported); 20078c2ecf20Sopenharmony_ci kfree(dcbx_info); 20088c2ecf20Sopenharmony_ci 20098c2ecf20Sopenharmony_ci return 0; 20108c2ecf20Sopenharmony_ci} 20118c2ecf20Sopenharmony_ci 20128c2ecf20Sopenharmony_cistatic int qed_dcbnl_cee_peer_getpg(struct qed_dev *cdev, struct cee_pg *pg) 20138c2ecf20Sopenharmony_ci{ 20148c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 20158c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 20168c2ecf20Sopenharmony_ci int i; 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 20198c2ecf20Sopenharmony_ci if (!dcbx_info) 20208c2ecf20Sopenharmony_ci return -EINVAL; 20218c2ecf20Sopenharmony_ci 20228c2ecf20Sopenharmony_ci pg->willing = dcbx_info->remote.params.ets_willing; 20238c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 20248c2ecf20Sopenharmony_ci pg->pg_bw[i] = dcbx_info->remote.params.ets_tc_bw_tbl[i]; 20258c2ecf20Sopenharmony_ci pg->prio_pg[i] = dcbx_info->remote.params.ets_pri_tc_tbl[i]; 20268c2ecf20Sopenharmony_ci } 20278c2ecf20Sopenharmony_ci 20288c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "willing = %d", pg->willing); 20298c2ecf20Sopenharmony_ci kfree(dcbx_info); 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_ci return 0; 20328c2ecf20Sopenharmony_ci} 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_cistatic int qed_dcbnl_get_ieee_pfc(struct qed_dev *cdev, 20358c2ecf20Sopenharmony_ci struct ieee_pfc *pfc, bool remote) 20368c2ecf20Sopenharmony_ci{ 20378c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 20388c2ecf20Sopenharmony_ci struct qed_dcbx_params *params; 20398c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 20408c2ecf20Sopenharmony_ci int rc, i; 20418c2ecf20Sopenharmony_ci 20428c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 20438c2ecf20Sopenharmony_ci if (!dcbx_info) 20448c2ecf20Sopenharmony_ci return -EINVAL; 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 20478c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 20488c2ecf20Sopenharmony_ci kfree(dcbx_info); 20498c2ecf20Sopenharmony_ci return -EINVAL; 20508c2ecf20Sopenharmony_ci } 20518c2ecf20Sopenharmony_ci 20528c2ecf20Sopenharmony_ci if (remote) { 20538c2ecf20Sopenharmony_ci memset(dcbx_info, 0, sizeof(*dcbx_info)); 20548c2ecf20Sopenharmony_ci rc = qed_dcbx_query_params(hwfn, dcbx_info, 20558c2ecf20Sopenharmony_ci QED_DCBX_REMOTE_MIB); 20568c2ecf20Sopenharmony_ci if (rc) { 20578c2ecf20Sopenharmony_ci kfree(dcbx_info); 20588c2ecf20Sopenharmony_ci return -EINVAL; 20598c2ecf20Sopenharmony_ci } 20608c2ecf20Sopenharmony_ci 20618c2ecf20Sopenharmony_ci params = &dcbx_info->remote.params; 20628c2ecf20Sopenharmony_ci } else { 20638c2ecf20Sopenharmony_ci params = &dcbx_info->operational.params; 20648c2ecf20Sopenharmony_ci } 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci pfc->pfc_cap = params->pfc.max_tc; 20678c2ecf20Sopenharmony_ci pfc->pfc_en = 0; 20688c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 20698c2ecf20Sopenharmony_ci if (params->pfc.prio[i]) 20708c2ecf20Sopenharmony_ci pfc->pfc_en |= BIT(i); 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci kfree(dcbx_info); 20738c2ecf20Sopenharmony_ci 20748c2ecf20Sopenharmony_ci return 0; 20758c2ecf20Sopenharmony_ci} 20768c2ecf20Sopenharmony_ci 20778c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 20788c2ecf20Sopenharmony_ci{ 20798c2ecf20Sopenharmony_ci return qed_dcbnl_get_ieee_pfc(cdev, pfc, false); 20808c2ecf20Sopenharmony_ci} 20818c2ecf20Sopenharmony_ci 20828c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_setpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 20838c2ecf20Sopenharmony_ci{ 20848c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 20858c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 20868c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 20878c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 20888c2ecf20Sopenharmony_ci int rc, i; 20898c2ecf20Sopenharmony_ci 20908c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 20918c2ecf20Sopenharmony_ci if (!dcbx_info) 20928c2ecf20Sopenharmony_ci return -EINVAL; 20938c2ecf20Sopenharmony_ci 20948c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 20958c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 20968c2ecf20Sopenharmony_ci kfree(dcbx_info); 20978c2ecf20Sopenharmony_ci return -EINVAL; 20988c2ecf20Sopenharmony_ci } 20998c2ecf20Sopenharmony_ci 21008c2ecf20Sopenharmony_ci kfree(dcbx_info); 21018c2ecf20Sopenharmony_ci 21028c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 21038c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 21048c2ecf20Sopenharmony_ci if (rc) 21058c2ecf20Sopenharmony_ci return -EINVAL; 21068c2ecf20Sopenharmony_ci 21078c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 21088c2ecf20Sopenharmony_ci for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 21098c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.prio[i] = !!(pfc->pfc_en & BIT(i)); 21108c2ecf20Sopenharmony_ci 21118c2ecf20Sopenharmony_ci dcbx_set.config.params.pfc.max_tc = pfc->pfc_cap; 21128c2ecf20Sopenharmony_ci 21138c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 21148c2ecf20Sopenharmony_ci if (!ptt) 21158c2ecf20Sopenharmony_ci return -EINVAL; 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 21188c2ecf20Sopenharmony_ci 21198c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 21208c2ecf20Sopenharmony_ci 21218c2ecf20Sopenharmony_ci return rc; 21228c2ecf20Sopenharmony_ci} 21238c2ecf20Sopenharmony_ci 21248c2ecf20Sopenharmony_cistatic int qed_dcbnl_get_ieee_ets(struct qed_dev *cdev, 21258c2ecf20Sopenharmony_ci struct ieee_ets *ets, bool remote) 21268c2ecf20Sopenharmony_ci{ 21278c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 21288c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 21298c2ecf20Sopenharmony_ci struct qed_dcbx_params *params; 21308c2ecf20Sopenharmony_ci int rc; 21318c2ecf20Sopenharmony_ci 21328c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 21338c2ecf20Sopenharmony_ci if (!dcbx_info) 21348c2ecf20Sopenharmony_ci return -EINVAL; 21358c2ecf20Sopenharmony_ci 21368c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 21378c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 21388c2ecf20Sopenharmony_ci kfree(dcbx_info); 21398c2ecf20Sopenharmony_ci return -EINVAL; 21408c2ecf20Sopenharmony_ci } 21418c2ecf20Sopenharmony_ci 21428c2ecf20Sopenharmony_ci if (remote) { 21438c2ecf20Sopenharmony_ci memset(dcbx_info, 0, sizeof(*dcbx_info)); 21448c2ecf20Sopenharmony_ci rc = qed_dcbx_query_params(hwfn, dcbx_info, 21458c2ecf20Sopenharmony_ci QED_DCBX_REMOTE_MIB); 21468c2ecf20Sopenharmony_ci if (rc) { 21478c2ecf20Sopenharmony_ci kfree(dcbx_info); 21488c2ecf20Sopenharmony_ci return -EINVAL; 21498c2ecf20Sopenharmony_ci } 21508c2ecf20Sopenharmony_ci 21518c2ecf20Sopenharmony_ci params = &dcbx_info->remote.params; 21528c2ecf20Sopenharmony_ci } else { 21538c2ecf20Sopenharmony_ci params = &dcbx_info->operational.params; 21548c2ecf20Sopenharmony_ci } 21558c2ecf20Sopenharmony_ci 21568c2ecf20Sopenharmony_ci ets->ets_cap = params->max_ets_tc; 21578c2ecf20Sopenharmony_ci ets->willing = params->ets_willing; 21588c2ecf20Sopenharmony_ci ets->cbs = params->ets_cbs; 21598c2ecf20Sopenharmony_ci memcpy(ets->tc_tx_bw, params->ets_tc_bw_tbl, sizeof(ets->tc_tx_bw)); 21608c2ecf20Sopenharmony_ci memcpy(ets->tc_tsa, params->ets_tc_tsa_tbl, sizeof(ets->tc_tsa)); 21618c2ecf20Sopenharmony_ci memcpy(ets->prio_tc, params->ets_pri_tc_tbl, sizeof(ets->prio_tc)); 21628c2ecf20Sopenharmony_ci kfree(dcbx_info); 21638c2ecf20Sopenharmony_ci 21648c2ecf20Sopenharmony_ci return 0; 21658c2ecf20Sopenharmony_ci} 21668c2ecf20Sopenharmony_ci 21678c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_getets(struct qed_dev *cdev, struct ieee_ets *ets) 21688c2ecf20Sopenharmony_ci{ 21698c2ecf20Sopenharmony_ci return qed_dcbnl_get_ieee_ets(cdev, ets, false); 21708c2ecf20Sopenharmony_ci} 21718c2ecf20Sopenharmony_ci 21728c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_setets(struct qed_dev *cdev, struct ieee_ets *ets) 21738c2ecf20Sopenharmony_ci{ 21748c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 21758c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 21768c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 21778c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 21788c2ecf20Sopenharmony_ci int rc; 21798c2ecf20Sopenharmony_ci 21808c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 21818c2ecf20Sopenharmony_ci if (!dcbx_info) 21828c2ecf20Sopenharmony_ci return -EINVAL; 21838c2ecf20Sopenharmony_ci 21848c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 21858c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 21868c2ecf20Sopenharmony_ci kfree(dcbx_info); 21878c2ecf20Sopenharmony_ci return -EINVAL; 21888c2ecf20Sopenharmony_ci } 21898c2ecf20Sopenharmony_ci 21908c2ecf20Sopenharmony_ci kfree(dcbx_info); 21918c2ecf20Sopenharmony_ci 21928c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 21938c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 21948c2ecf20Sopenharmony_ci if (rc) 21958c2ecf20Sopenharmony_ci return -EINVAL; 21968c2ecf20Sopenharmony_ci 21978c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 21988c2ecf20Sopenharmony_ci dcbx_set.config.params.max_ets_tc = ets->ets_cap; 21998c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_willing = ets->willing; 22008c2ecf20Sopenharmony_ci dcbx_set.config.params.ets_cbs = ets->cbs; 22018c2ecf20Sopenharmony_ci memcpy(dcbx_set.config.params.ets_tc_bw_tbl, ets->tc_tx_bw, 22028c2ecf20Sopenharmony_ci sizeof(ets->tc_tx_bw)); 22038c2ecf20Sopenharmony_ci memcpy(dcbx_set.config.params.ets_tc_tsa_tbl, ets->tc_tsa, 22048c2ecf20Sopenharmony_ci sizeof(ets->tc_tsa)); 22058c2ecf20Sopenharmony_ci memcpy(dcbx_set.config.params.ets_pri_tc_tbl, ets->prio_tc, 22068c2ecf20Sopenharmony_ci sizeof(ets->prio_tc)); 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 22098c2ecf20Sopenharmony_ci if (!ptt) 22108c2ecf20Sopenharmony_ci return -EINVAL; 22118c2ecf20Sopenharmony_ci 22128c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 22138c2ecf20Sopenharmony_ci 22148c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 22158c2ecf20Sopenharmony_ci 22168c2ecf20Sopenharmony_ci return rc; 22178c2ecf20Sopenharmony_ci} 22188c2ecf20Sopenharmony_ci 22198c2ecf20Sopenharmony_cistatic int 22208c2ecf20Sopenharmony_ciqed_dcbnl_ieee_peer_getets(struct qed_dev *cdev, struct ieee_ets *ets) 22218c2ecf20Sopenharmony_ci{ 22228c2ecf20Sopenharmony_ci return qed_dcbnl_get_ieee_ets(cdev, ets, true); 22238c2ecf20Sopenharmony_ci} 22248c2ecf20Sopenharmony_ci 22258c2ecf20Sopenharmony_cistatic int 22268c2ecf20Sopenharmony_ciqed_dcbnl_ieee_peer_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 22278c2ecf20Sopenharmony_ci{ 22288c2ecf20Sopenharmony_ci return qed_dcbnl_get_ieee_pfc(cdev, pfc, true); 22298c2ecf20Sopenharmony_ci} 22308c2ecf20Sopenharmony_ci 22318c2ecf20Sopenharmony_cistatic int qed_get_sf_ieee_value(u8 selector, u8 *sf_ieee) 22328c2ecf20Sopenharmony_ci{ 22338c2ecf20Sopenharmony_ci switch (selector) { 22348c2ecf20Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_ETHERTYPE: 22358c2ecf20Sopenharmony_ci *sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE; 22368c2ecf20Sopenharmony_ci break; 22378c2ecf20Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_STREAM: 22388c2ecf20Sopenharmony_ci *sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT; 22398c2ecf20Sopenharmony_ci break; 22408c2ecf20Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_DGRAM: 22418c2ecf20Sopenharmony_ci *sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT; 22428c2ecf20Sopenharmony_ci break; 22438c2ecf20Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_ANY: 22448c2ecf20Sopenharmony_ci *sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT; 22458c2ecf20Sopenharmony_ci break; 22468c2ecf20Sopenharmony_ci default: 22478c2ecf20Sopenharmony_ci return -EINVAL; 22488c2ecf20Sopenharmony_ci } 22498c2ecf20Sopenharmony_ci 22508c2ecf20Sopenharmony_ci return 0; 22518c2ecf20Sopenharmony_ci} 22528c2ecf20Sopenharmony_ci 22538c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_getapp(struct qed_dev *cdev, struct dcb_app *app) 22548c2ecf20Sopenharmony_ci{ 22558c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 22568c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 22578c2ecf20Sopenharmony_ci struct qed_app_entry *entry; 22588c2ecf20Sopenharmony_ci u8 prio = 0; 22598c2ecf20Sopenharmony_ci u8 sf_ieee; 22608c2ecf20Sopenharmony_ci int i; 22618c2ecf20Sopenharmony_ci 22628c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "selector = %d protocol = %d\n", 22638c2ecf20Sopenharmony_ci app->selector, app->protocol); 22648c2ecf20Sopenharmony_ci 22658c2ecf20Sopenharmony_ci if (qed_get_sf_ieee_value(app->selector, &sf_ieee)) { 22668c2ecf20Sopenharmony_ci DP_INFO(cdev, "Invalid selector field value %d\n", 22678c2ecf20Sopenharmony_ci app->selector); 22688c2ecf20Sopenharmony_ci return -EINVAL; 22698c2ecf20Sopenharmony_ci } 22708c2ecf20Sopenharmony_ci 22718c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 22728c2ecf20Sopenharmony_ci if (!dcbx_info) 22738c2ecf20Sopenharmony_ci return -EINVAL; 22748c2ecf20Sopenharmony_ci 22758c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 22768c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 22778c2ecf20Sopenharmony_ci kfree(dcbx_info); 22788c2ecf20Sopenharmony_ci return -EINVAL; 22798c2ecf20Sopenharmony_ci } 22808c2ecf20Sopenharmony_ci 22818c2ecf20Sopenharmony_ci for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 22828c2ecf20Sopenharmony_ci entry = &dcbx_info->operational.params.app_entry[i]; 22838c2ecf20Sopenharmony_ci if ((entry->sf_ieee == sf_ieee) && 22848c2ecf20Sopenharmony_ci (entry->proto_id == app->protocol)) { 22858c2ecf20Sopenharmony_ci prio = entry->prio; 22868c2ecf20Sopenharmony_ci break; 22878c2ecf20Sopenharmony_ci } 22888c2ecf20Sopenharmony_ci } 22898c2ecf20Sopenharmony_ci 22908c2ecf20Sopenharmony_ci if (i == QED_DCBX_MAX_APP_PROTOCOL) { 22918c2ecf20Sopenharmony_ci DP_ERR(cdev, "App entry (%d, %d) not found\n", app->selector, 22928c2ecf20Sopenharmony_ci app->protocol); 22938c2ecf20Sopenharmony_ci kfree(dcbx_info); 22948c2ecf20Sopenharmony_ci return -EINVAL; 22958c2ecf20Sopenharmony_ci } 22968c2ecf20Sopenharmony_ci 22978c2ecf20Sopenharmony_ci app->priority = ffs(prio) - 1; 22988c2ecf20Sopenharmony_ci 22998c2ecf20Sopenharmony_ci kfree(dcbx_info); 23008c2ecf20Sopenharmony_ci 23018c2ecf20Sopenharmony_ci return 0; 23028c2ecf20Sopenharmony_ci} 23038c2ecf20Sopenharmony_ci 23048c2ecf20Sopenharmony_cistatic int qed_dcbnl_ieee_setapp(struct qed_dev *cdev, struct dcb_app *app) 23058c2ecf20Sopenharmony_ci{ 23068c2ecf20Sopenharmony_ci struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 23078c2ecf20Sopenharmony_ci struct qed_dcbx_get *dcbx_info; 23088c2ecf20Sopenharmony_ci struct qed_dcbx_set dcbx_set; 23098c2ecf20Sopenharmony_ci struct qed_app_entry *entry; 23108c2ecf20Sopenharmony_ci struct qed_ptt *ptt; 23118c2ecf20Sopenharmony_ci u8 sf_ieee; 23128c2ecf20Sopenharmony_ci int rc, i; 23138c2ecf20Sopenharmony_ci 23148c2ecf20Sopenharmony_ci DP_VERBOSE(hwfn, QED_MSG_DCB, "selector = %d protocol = %d pri = %d\n", 23158c2ecf20Sopenharmony_ci app->selector, app->protocol, app->priority); 23168c2ecf20Sopenharmony_ci if (app->priority >= QED_MAX_PFC_PRIORITIES) { 23178c2ecf20Sopenharmony_ci DP_INFO(hwfn, "Invalid priority %d\n", app->priority); 23188c2ecf20Sopenharmony_ci return -EINVAL; 23198c2ecf20Sopenharmony_ci } 23208c2ecf20Sopenharmony_ci 23218c2ecf20Sopenharmony_ci if (qed_get_sf_ieee_value(app->selector, &sf_ieee)) { 23228c2ecf20Sopenharmony_ci DP_INFO(cdev, "Invalid selector field value %d\n", 23238c2ecf20Sopenharmony_ci app->selector); 23248c2ecf20Sopenharmony_ci return -EINVAL; 23258c2ecf20Sopenharmony_ci } 23268c2ecf20Sopenharmony_ci 23278c2ecf20Sopenharmony_ci dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 23288c2ecf20Sopenharmony_ci if (!dcbx_info) 23298c2ecf20Sopenharmony_ci return -EINVAL; 23308c2ecf20Sopenharmony_ci 23318c2ecf20Sopenharmony_ci if (!dcbx_info->operational.ieee) { 23328c2ecf20Sopenharmony_ci DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 23338c2ecf20Sopenharmony_ci kfree(dcbx_info); 23348c2ecf20Sopenharmony_ci return -EINVAL; 23358c2ecf20Sopenharmony_ci } 23368c2ecf20Sopenharmony_ci 23378c2ecf20Sopenharmony_ci kfree(dcbx_info); 23388c2ecf20Sopenharmony_ci 23398c2ecf20Sopenharmony_ci memset(&dcbx_set, 0, sizeof(dcbx_set)); 23408c2ecf20Sopenharmony_ci rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 23418c2ecf20Sopenharmony_ci if (rc) 23428c2ecf20Sopenharmony_ci return -EINVAL; 23438c2ecf20Sopenharmony_ci 23448c2ecf20Sopenharmony_ci for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 23458c2ecf20Sopenharmony_ci entry = &dcbx_set.config.params.app_entry[i]; 23468c2ecf20Sopenharmony_ci if ((entry->sf_ieee == sf_ieee) && 23478c2ecf20Sopenharmony_ci (entry->proto_id == app->protocol)) 23488c2ecf20Sopenharmony_ci break; 23498c2ecf20Sopenharmony_ci /* First empty slot */ 23508c2ecf20Sopenharmony_ci if (!entry->proto_id) { 23518c2ecf20Sopenharmony_ci dcbx_set.config.params.num_app_entries++; 23528c2ecf20Sopenharmony_ci break; 23538c2ecf20Sopenharmony_ci } 23548c2ecf20Sopenharmony_ci } 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_ci if (i == QED_DCBX_MAX_APP_PROTOCOL) { 23578c2ecf20Sopenharmony_ci DP_ERR(cdev, "App table is full\n"); 23588c2ecf20Sopenharmony_ci return -EBUSY; 23598c2ecf20Sopenharmony_ci } 23608c2ecf20Sopenharmony_ci 23618c2ecf20Sopenharmony_ci dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 23628c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].sf_ieee = sf_ieee; 23638c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].proto_id = app->protocol; 23648c2ecf20Sopenharmony_ci dcbx_set.config.params.app_entry[i].prio = BIT(app->priority); 23658c2ecf20Sopenharmony_ci 23668c2ecf20Sopenharmony_ci ptt = qed_ptt_acquire(hwfn); 23678c2ecf20Sopenharmony_ci if (!ptt) 23688c2ecf20Sopenharmony_ci return -EBUSY; 23698c2ecf20Sopenharmony_ci 23708c2ecf20Sopenharmony_ci rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 23718c2ecf20Sopenharmony_ci 23728c2ecf20Sopenharmony_ci qed_ptt_release(hwfn, ptt); 23738c2ecf20Sopenharmony_ci 23748c2ecf20Sopenharmony_ci return rc; 23758c2ecf20Sopenharmony_ci} 23768c2ecf20Sopenharmony_ci 23778c2ecf20Sopenharmony_ciconst struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass = { 23788c2ecf20Sopenharmony_ci .getstate = qed_dcbnl_getstate, 23798c2ecf20Sopenharmony_ci .setstate = qed_dcbnl_setstate, 23808c2ecf20Sopenharmony_ci .getpgtccfgtx = qed_dcbnl_getpgtccfgtx, 23818c2ecf20Sopenharmony_ci .getpgbwgcfgtx = qed_dcbnl_getpgbwgcfgtx, 23828c2ecf20Sopenharmony_ci .getpgtccfgrx = qed_dcbnl_getpgtccfgrx, 23838c2ecf20Sopenharmony_ci .getpgbwgcfgrx = qed_dcbnl_getpgbwgcfgrx, 23848c2ecf20Sopenharmony_ci .getpfccfg = qed_dcbnl_getpfccfg, 23858c2ecf20Sopenharmony_ci .setpfccfg = qed_dcbnl_setpfccfg, 23868c2ecf20Sopenharmony_ci .getcap = qed_dcbnl_getcap, 23878c2ecf20Sopenharmony_ci .getnumtcs = qed_dcbnl_getnumtcs, 23888c2ecf20Sopenharmony_ci .getpfcstate = qed_dcbnl_getpfcstate, 23898c2ecf20Sopenharmony_ci .getdcbx = qed_dcbnl_getdcbx, 23908c2ecf20Sopenharmony_ci .setpgtccfgtx = qed_dcbnl_setpgtccfgtx, 23918c2ecf20Sopenharmony_ci .setpgtccfgrx = qed_dcbnl_setpgtccfgrx, 23928c2ecf20Sopenharmony_ci .setpgbwgcfgtx = qed_dcbnl_setpgbwgcfgtx, 23938c2ecf20Sopenharmony_ci .setpgbwgcfgrx = qed_dcbnl_setpgbwgcfgrx, 23948c2ecf20Sopenharmony_ci .setall = qed_dcbnl_setall, 23958c2ecf20Sopenharmony_ci .setnumtcs = qed_dcbnl_setnumtcs, 23968c2ecf20Sopenharmony_ci .setpfcstate = qed_dcbnl_setpfcstate, 23978c2ecf20Sopenharmony_ci .setapp = qed_dcbnl_setapp, 23988c2ecf20Sopenharmony_ci .setdcbx = qed_dcbnl_setdcbx, 23998c2ecf20Sopenharmony_ci .setfeatcfg = qed_dcbnl_setfeatcfg, 24008c2ecf20Sopenharmony_ci .getfeatcfg = qed_dcbnl_getfeatcfg, 24018c2ecf20Sopenharmony_ci .getapp = qed_dcbnl_getapp, 24028c2ecf20Sopenharmony_ci .peer_getappinfo = qed_dcbnl_peer_getappinfo, 24038c2ecf20Sopenharmony_ci .peer_getapptable = qed_dcbnl_peer_getapptable, 24048c2ecf20Sopenharmony_ci .cee_peer_getpfc = qed_dcbnl_cee_peer_getpfc, 24058c2ecf20Sopenharmony_ci .cee_peer_getpg = qed_dcbnl_cee_peer_getpg, 24068c2ecf20Sopenharmony_ci .ieee_getpfc = qed_dcbnl_ieee_getpfc, 24078c2ecf20Sopenharmony_ci .ieee_setpfc = qed_dcbnl_ieee_setpfc, 24088c2ecf20Sopenharmony_ci .ieee_getets = qed_dcbnl_ieee_getets, 24098c2ecf20Sopenharmony_ci .ieee_setets = qed_dcbnl_ieee_setets, 24108c2ecf20Sopenharmony_ci .ieee_peer_getpfc = qed_dcbnl_ieee_peer_getpfc, 24118c2ecf20Sopenharmony_ci .ieee_peer_getets = qed_dcbnl_ieee_peer_getets, 24128c2ecf20Sopenharmony_ci .ieee_getapp = qed_dcbnl_ieee_getapp, 24138c2ecf20Sopenharmony_ci .ieee_setapp = qed_dcbnl_ieee_setapp, 24148c2ecf20Sopenharmony_ci}; 24158c2ecf20Sopenharmony_ci 24168c2ecf20Sopenharmony_ci#endif 2417