139651abdSSudarsana Reddy Kalluru /* QLogic qed NIC Driver 239651abdSSudarsana Reddy Kalluru * Copyright (c) 2015 QLogic Corporation 339651abdSSudarsana Reddy Kalluru * 439651abdSSudarsana Reddy Kalluru * This software is available under the terms of the GNU General Public License 539651abdSSudarsana Reddy Kalluru * (GPL) Version 2, available from the file COPYING in the main directory of 639651abdSSudarsana Reddy Kalluru * this source tree. 739651abdSSudarsana Reddy Kalluru */ 839651abdSSudarsana Reddy Kalluru 939651abdSSudarsana Reddy Kalluru #include <linux/types.h> 1039651abdSSudarsana Reddy Kalluru #include <asm/byteorder.h> 1139651abdSSudarsana Reddy Kalluru #include <linux/bitops.h> 12a1d8d8a5SSudarsana Reddy Kalluru #include <linux/dcbnl.h> 1339651abdSSudarsana Reddy Kalluru #include <linux/errno.h> 1439651abdSSudarsana Reddy Kalluru #include <linux/kernel.h> 1539651abdSSudarsana Reddy Kalluru #include <linux/slab.h> 1639651abdSSudarsana Reddy Kalluru #include <linux/string.h> 1739651abdSSudarsana Reddy Kalluru #include "qed.h" 1839651abdSSudarsana Reddy Kalluru #include "qed_cxt.h" 1939651abdSSudarsana Reddy Kalluru #include "qed_dcbx.h" 2039651abdSSudarsana Reddy Kalluru #include "qed_hsi.h" 2139651abdSSudarsana Reddy Kalluru #include "qed_sp.h" 225fe118c9SSudarsana Reddy Kalluru #include "qed_sriov.h" 23a1d8d8a5SSudarsana Reddy Kalluru #ifdef CONFIG_DCB 24a1d8d8a5SSudarsana Reddy Kalluru #include <linux/qed/qed_eth_if.h> 25a1d8d8a5SSudarsana Reddy Kalluru #endif 2639651abdSSudarsana Reddy Kalluru 2739651abdSSudarsana Reddy Kalluru #define QED_DCBX_MAX_MIB_READ_TRY (100) 2839651abdSSudarsana Reddy Kalluru #define QED_ETH_TYPE_DEFAULT (0) 2939651abdSSudarsana Reddy Kalluru #define QED_ETH_TYPE_ROCE (0x8915) 3039651abdSSudarsana Reddy Kalluru #define QED_UDP_PORT_TYPE_ROCE_V2 (0x12B7) 3139651abdSSudarsana Reddy Kalluru #define QED_ETH_TYPE_FCOE (0x8906) 3239651abdSSudarsana Reddy Kalluru #define QED_TCP_PORT_ISCSI (0xCBC) 3339651abdSSudarsana Reddy Kalluru 3439651abdSSudarsana Reddy Kalluru #define QED_DCBX_INVALID_PRIORITY 0xFF 3539651abdSSudarsana Reddy Kalluru 3639651abdSSudarsana Reddy Kalluru /* Get Traffic Class from priority traffic class table, 4 bits represent 3739651abdSSudarsana Reddy Kalluru * the traffic class corresponding to the priority. 3839651abdSSudarsana Reddy Kalluru */ 3939651abdSSudarsana Reddy Kalluru #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \ 4039651abdSSudarsana Reddy Kalluru ((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7) 4139651abdSSudarsana Reddy Kalluru 4239651abdSSudarsana Reddy Kalluru static const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = { 4339651abdSSudarsana Reddy Kalluru {DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_DEFAULT}, 4439651abdSSudarsana Reddy Kalluru {DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_DEFAULT}, 4539651abdSSudarsana Reddy Kalluru {DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_DEFAULT}, 4639651abdSSudarsana Reddy Kalluru {DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_DEFAULT}, 4739651abdSSudarsana Reddy Kalluru {DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH} 4839651abdSSudarsana Reddy Kalluru }; 4939651abdSSudarsana Reddy Kalluru 5039651abdSSudarsana Reddy Kalluru static bool qed_dcbx_app_ethtype(u32 app_info_bitmap) 5139651abdSSudarsana Reddy Kalluru { 5239651abdSSudarsana Reddy Kalluru return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 5339651abdSSudarsana Reddy Kalluru DCBX_APP_SF_ETHTYPE); 5439651abdSSudarsana Reddy Kalluru } 5539651abdSSudarsana Reddy Kalluru 56fb9ea8a9SSudarsana Reddy Kalluru static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap) 57fb9ea8a9SSudarsana Reddy Kalluru { 58fb9ea8a9SSudarsana Reddy Kalluru u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 59fb9ea8a9SSudarsana Reddy Kalluru 60fb9ea8a9SSudarsana Reddy Kalluru /* Old MFW */ 61fb9ea8a9SSudarsana Reddy Kalluru if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 62fb9ea8a9SSudarsana Reddy Kalluru return qed_dcbx_app_ethtype(app_info_bitmap); 63fb9ea8a9SSudarsana Reddy Kalluru 64fb9ea8a9SSudarsana Reddy Kalluru return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE); 65fb9ea8a9SSudarsana Reddy Kalluru } 66fb9ea8a9SSudarsana Reddy Kalluru 6739651abdSSudarsana Reddy Kalluru static bool qed_dcbx_app_port(u32 app_info_bitmap) 6839651abdSSudarsana Reddy Kalluru { 6939651abdSSudarsana Reddy Kalluru return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) == 7039651abdSSudarsana Reddy Kalluru DCBX_APP_SF_PORT); 7139651abdSSudarsana Reddy Kalluru } 7239651abdSSudarsana Reddy Kalluru 7359bcb797SSudarsana Reddy Kalluru static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type) 7459bcb797SSudarsana Reddy Kalluru { 7559bcb797SSudarsana Reddy Kalluru u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE); 7659bcb797SSudarsana Reddy Kalluru 7759bcb797SSudarsana Reddy Kalluru /* Old MFW */ 7859bcb797SSudarsana Reddy Kalluru if (mfw_val == DCBX_APP_SF_IEEE_RESERVED) 7959bcb797SSudarsana Reddy Kalluru return qed_dcbx_app_port(app_info_bitmap); 8059bcb797SSudarsana Reddy Kalluru 8159bcb797SSudarsana Reddy Kalluru return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT); 8259bcb797SSudarsana Reddy Kalluru } 8359bcb797SSudarsana Reddy Kalluru 84fb9ea8a9SSudarsana Reddy Kalluru static bool qed_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 8539651abdSSudarsana Reddy Kalluru { 86fb9ea8a9SSudarsana Reddy Kalluru bool ethtype; 87fb9ea8a9SSudarsana Reddy Kalluru 88fb9ea8a9SSudarsana Reddy Kalluru if (ieee) 89fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 90fb9ea8a9SSudarsana Reddy Kalluru else 91fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 92fb9ea8a9SSudarsana Reddy Kalluru 93fb9ea8a9SSudarsana Reddy Kalluru return !!(ethtype && (proto_id == QED_ETH_TYPE_DEFAULT)); 9439651abdSSudarsana Reddy Kalluru } 9539651abdSSudarsana Reddy Kalluru 9659bcb797SSudarsana Reddy Kalluru static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 9739651abdSSudarsana Reddy Kalluru { 9859bcb797SSudarsana Reddy Kalluru bool port; 9959bcb797SSudarsana Reddy Kalluru 10059bcb797SSudarsana Reddy Kalluru if (ieee) 10159bcb797SSudarsana Reddy Kalluru port = qed_dcbx_ieee_app_port(app_info_bitmap, 10259bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_TCP_PORT); 10359bcb797SSudarsana Reddy Kalluru else 10459bcb797SSudarsana Reddy Kalluru port = qed_dcbx_app_port(app_info_bitmap); 10559bcb797SSudarsana Reddy Kalluru 10659bcb797SSudarsana Reddy Kalluru return !!(port && (proto_id == QED_TCP_PORT_ISCSI)); 10739651abdSSudarsana Reddy Kalluru } 10839651abdSSudarsana Reddy Kalluru 109fb9ea8a9SSudarsana Reddy Kalluru static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 11039651abdSSudarsana Reddy Kalluru { 111fb9ea8a9SSudarsana Reddy Kalluru bool ethtype; 112fb9ea8a9SSudarsana Reddy Kalluru 113fb9ea8a9SSudarsana Reddy Kalluru if (ieee) 114fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 115fb9ea8a9SSudarsana Reddy Kalluru else 116fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 117fb9ea8a9SSudarsana Reddy Kalluru 118fb9ea8a9SSudarsana Reddy Kalluru return !!(ethtype && (proto_id == QED_ETH_TYPE_FCOE)); 11939651abdSSudarsana Reddy Kalluru } 12039651abdSSudarsana Reddy Kalluru 121fb9ea8a9SSudarsana Reddy Kalluru static bool qed_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 12239651abdSSudarsana Reddy Kalluru { 123fb9ea8a9SSudarsana Reddy Kalluru bool ethtype; 124fb9ea8a9SSudarsana Reddy Kalluru 125fb9ea8a9SSudarsana Reddy Kalluru if (ieee) 126fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap); 127fb9ea8a9SSudarsana Reddy Kalluru else 128fb9ea8a9SSudarsana Reddy Kalluru ethtype = qed_dcbx_app_ethtype(app_info_bitmap); 129fb9ea8a9SSudarsana Reddy Kalluru 130fb9ea8a9SSudarsana Reddy Kalluru return !!(ethtype && (proto_id == QED_ETH_TYPE_ROCE)); 13139651abdSSudarsana Reddy Kalluru } 13239651abdSSudarsana Reddy Kalluru 13359bcb797SSudarsana Reddy Kalluru static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee) 13439651abdSSudarsana Reddy Kalluru { 13559bcb797SSudarsana Reddy Kalluru bool port; 13659bcb797SSudarsana Reddy Kalluru 13759bcb797SSudarsana Reddy Kalluru if (ieee) 13859bcb797SSudarsana Reddy Kalluru port = qed_dcbx_ieee_app_port(app_info_bitmap, 13959bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_UDP_PORT); 14059bcb797SSudarsana Reddy Kalluru else 14159bcb797SSudarsana Reddy Kalluru port = qed_dcbx_app_port(app_info_bitmap); 14259bcb797SSudarsana Reddy Kalluru 14359bcb797SSudarsana Reddy Kalluru return !!(port && (proto_id == QED_UDP_PORT_TYPE_ROCE_V2)); 14439651abdSSudarsana Reddy Kalluru } 14539651abdSSudarsana Reddy Kalluru 14639651abdSSudarsana Reddy Kalluru static void 14739651abdSSudarsana Reddy Kalluru qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data) 14839651abdSSudarsana Reddy Kalluru { 14939651abdSSudarsana Reddy Kalluru enum dcbx_protocol_type id; 15039651abdSSudarsana Reddy Kalluru int i; 15139651abdSSudarsana Reddy Kalluru 15239651abdSSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, "DCBX negotiated: %d\n", 15339651abdSSudarsana Reddy Kalluru p_data->dcbx_enabled); 15439651abdSSudarsana Reddy Kalluru 15539651abdSSudarsana Reddy Kalluru for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 15639651abdSSudarsana Reddy Kalluru id = qed_dcbx_app_update[i].id; 15739651abdSSudarsana Reddy Kalluru 15839651abdSSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 15939651abdSSudarsana Reddy Kalluru "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n", 16039651abdSSudarsana Reddy Kalluru qed_dcbx_app_update[i].name, p_data->arr[id].update, 16139651abdSSudarsana Reddy Kalluru p_data->arr[id].enable, p_data->arr[id].priority, 16239651abdSSudarsana Reddy Kalluru p_data->arr[id].tc, p_hwfn->hw_info.num_tc); 16339651abdSSudarsana Reddy Kalluru } 16439651abdSSudarsana Reddy Kalluru } 16539651abdSSudarsana Reddy Kalluru 16639651abdSSudarsana Reddy Kalluru static void 16739651abdSSudarsana Reddy Kalluru qed_dcbx_set_params(struct qed_dcbx_results *p_data, 16839651abdSSudarsana Reddy Kalluru struct qed_hw_info *p_info, 16939651abdSSudarsana Reddy Kalluru bool enable, 17039651abdSSudarsana Reddy Kalluru bool update, 17139651abdSSudarsana Reddy Kalluru u8 prio, 17239651abdSSudarsana Reddy Kalluru u8 tc, 17339651abdSSudarsana Reddy Kalluru enum dcbx_protocol_type type, 17439651abdSSudarsana Reddy Kalluru enum qed_pci_personality personality) 17539651abdSSudarsana Reddy Kalluru { 17639651abdSSudarsana Reddy Kalluru /* PF update ramrod data */ 17739651abdSSudarsana Reddy Kalluru p_data->arr[type].update = update; 17839651abdSSudarsana Reddy Kalluru p_data->arr[type].enable = enable; 17939651abdSSudarsana Reddy Kalluru p_data->arr[type].priority = prio; 18039651abdSSudarsana Reddy Kalluru p_data->arr[type].tc = tc; 18139651abdSSudarsana Reddy Kalluru 18239651abdSSudarsana Reddy Kalluru /* QM reconf data */ 18339651abdSSudarsana Reddy Kalluru if (p_info->personality == personality) { 18439651abdSSudarsana Reddy Kalluru if (personality == QED_PCI_ETH) 18539651abdSSudarsana Reddy Kalluru p_info->non_offload_tc = tc; 18639651abdSSudarsana Reddy Kalluru else 18739651abdSSudarsana Reddy Kalluru p_info->offload_tc = tc; 18839651abdSSudarsana Reddy Kalluru } 18939651abdSSudarsana Reddy Kalluru } 19039651abdSSudarsana Reddy Kalluru 19139651abdSSudarsana Reddy Kalluru /* Update app protocol data and hw_info fields with the TLV info */ 19239651abdSSudarsana Reddy Kalluru static void 19339651abdSSudarsana Reddy Kalluru qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, 19439651abdSSudarsana Reddy Kalluru struct qed_hwfn *p_hwfn, 19539651abdSSudarsana Reddy Kalluru bool enable, 19639651abdSSudarsana Reddy Kalluru bool update, 19739651abdSSudarsana Reddy Kalluru u8 prio, u8 tc, enum dcbx_protocol_type type) 19839651abdSSudarsana Reddy Kalluru { 19939651abdSSudarsana Reddy Kalluru struct qed_hw_info *p_info = &p_hwfn->hw_info; 20039651abdSSudarsana Reddy Kalluru enum qed_pci_personality personality; 20139651abdSSudarsana Reddy Kalluru enum dcbx_protocol_type id; 20239651abdSSudarsana Reddy Kalluru char *name; 20339651abdSSudarsana Reddy Kalluru int i; 20439651abdSSudarsana Reddy Kalluru 20539651abdSSudarsana Reddy Kalluru for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) { 20639651abdSSudarsana Reddy Kalluru id = qed_dcbx_app_update[i].id; 20739651abdSSudarsana Reddy Kalluru 20839651abdSSudarsana Reddy Kalluru if (type != id) 20939651abdSSudarsana Reddy Kalluru continue; 21039651abdSSudarsana Reddy Kalluru 21139651abdSSudarsana Reddy Kalluru personality = qed_dcbx_app_update[i].personality; 21239651abdSSudarsana Reddy Kalluru name = qed_dcbx_app_update[i].name; 21339651abdSSudarsana Reddy Kalluru 21439651abdSSudarsana Reddy Kalluru qed_dcbx_set_params(p_data, p_info, enable, update, 21539651abdSSudarsana Reddy Kalluru prio, tc, type, personality); 21639651abdSSudarsana Reddy Kalluru } 21739651abdSSudarsana Reddy Kalluru } 21839651abdSSudarsana Reddy Kalluru 21939651abdSSudarsana Reddy Kalluru static bool 22039651abdSSudarsana Reddy Kalluru qed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn, 22139651abdSSudarsana Reddy Kalluru u32 app_prio_bitmap, 222fb9ea8a9SSudarsana Reddy Kalluru u16 id, enum dcbx_protocol_type *type, bool ieee) 22339651abdSSudarsana Reddy Kalluru { 224fb9ea8a9SSudarsana Reddy Kalluru if (qed_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) { 22539651abdSSudarsana Reddy Kalluru *type = DCBX_PROTOCOL_FCOE; 226fb9ea8a9SSudarsana Reddy Kalluru } else if (qed_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) { 22739651abdSSudarsana Reddy Kalluru *type = DCBX_PROTOCOL_ROCE; 22859bcb797SSudarsana Reddy Kalluru } else if (qed_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) { 22939651abdSSudarsana Reddy Kalluru *type = DCBX_PROTOCOL_ISCSI; 230fb9ea8a9SSudarsana Reddy Kalluru } else if (qed_dcbx_default_tlv(app_prio_bitmap, id, ieee)) { 23139651abdSSudarsana Reddy Kalluru *type = DCBX_PROTOCOL_ETH; 23259bcb797SSudarsana Reddy Kalluru } else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) { 23339651abdSSudarsana Reddy Kalluru *type = DCBX_PROTOCOL_ROCE_V2; 23439651abdSSudarsana Reddy Kalluru } else { 23539651abdSSudarsana Reddy Kalluru *type = DCBX_MAX_PROTOCOL_TYPE; 23639651abdSSudarsana Reddy Kalluru DP_ERR(p_hwfn, 23739651abdSSudarsana Reddy Kalluru "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n", 23839651abdSSudarsana Reddy Kalluru id, app_prio_bitmap); 23939651abdSSudarsana Reddy Kalluru return false; 24039651abdSSudarsana Reddy Kalluru } 24139651abdSSudarsana Reddy Kalluru 24239651abdSSudarsana Reddy Kalluru return true; 24339651abdSSudarsana Reddy Kalluru } 24439651abdSSudarsana Reddy Kalluru 24539651abdSSudarsana Reddy Kalluru /* Parse app TLV's to update TC information in hw_info structure for 24639651abdSSudarsana Reddy Kalluru * reconfiguring QM. Get protocol specific data for PF update ramrod command. 24739651abdSSudarsana Reddy Kalluru */ 24839651abdSSudarsana Reddy Kalluru static int 24939651abdSSudarsana Reddy Kalluru qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, 25039651abdSSudarsana Reddy Kalluru struct qed_dcbx_results *p_data, 25139651abdSSudarsana Reddy Kalluru struct dcbx_app_priority_entry *p_tbl, 252fb9ea8a9SSudarsana Reddy Kalluru u32 pri_tc_tbl, int count, u8 dcbx_version) 25339651abdSSudarsana Reddy Kalluru { 25454b9430fSDan Carpenter u8 tc, priority_map; 25539651abdSSudarsana Reddy Kalluru enum dcbx_protocol_type type; 256fb9ea8a9SSudarsana Reddy Kalluru bool enable, ieee; 25739651abdSSudarsana Reddy Kalluru u16 protocol_id; 25854b9430fSDan Carpenter int priority; 25939651abdSSudarsana Reddy Kalluru int i; 26039651abdSSudarsana Reddy Kalluru 26139651abdSSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Num APP entries = %d\n", count); 26239651abdSSudarsana Reddy Kalluru 263fb9ea8a9SSudarsana Reddy Kalluru ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE); 26439651abdSSudarsana Reddy Kalluru /* Parse APP TLV */ 26539651abdSSudarsana Reddy Kalluru for (i = 0; i < count; i++) { 26639651abdSSudarsana Reddy Kalluru protocol_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 26739651abdSSudarsana Reddy Kalluru DCBX_APP_PROTOCOL_ID); 26839651abdSSudarsana Reddy Kalluru priority_map = QED_MFW_GET_FIELD(p_tbl[i].entry, 26939651abdSSudarsana Reddy Kalluru DCBX_APP_PRI_MAP); 27039651abdSSudarsana Reddy Kalluru priority = ffs(priority_map) - 1; 27139651abdSSudarsana Reddy Kalluru if (priority < 0) { 27239651abdSSudarsana Reddy Kalluru DP_ERR(p_hwfn, "Invalid priority\n"); 27339651abdSSudarsana Reddy Kalluru return -EINVAL; 27439651abdSSudarsana Reddy Kalluru } 27539651abdSSudarsana Reddy Kalluru 27639651abdSSudarsana Reddy Kalluru tc = QED_DCBX_PRIO2TC(pri_tc_tbl, priority); 27739651abdSSudarsana Reddy Kalluru if (qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 278fb9ea8a9SSudarsana Reddy Kalluru protocol_id, &type, ieee)) { 27939651abdSSudarsana Reddy Kalluru /* ETH always have the enable bit reset, as it gets 28039651abdSSudarsana Reddy Kalluru * vlan information per packet. For other protocols, 28139651abdSSudarsana Reddy Kalluru * should be set according to the dcbx_enabled 28239651abdSSudarsana Reddy Kalluru * indication, but we only got here if there was an 28339651abdSSudarsana Reddy Kalluru * app tlv for the protocol, so dcbx must be enabled. 28439651abdSSudarsana Reddy Kalluru */ 285ec7c7f5cSSudarsana Reddy Kalluru enable = !(type == DCBX_PROTOCOL_ETH); 28639651abdSSudarsana Reddy Kalluru 28739651abdSSudarsana Reddy Kalluru qed_dcbx_update_app_info(p_data, p_hwfn, enable, true, 28839651abdSSudarsana Reddy Kalluru priority, tc, type); 28939651abdSSudarsana Reddy Kalluru } 29039651abdSSudarsana Reddy Kalluru } 29139651abdSSudarsana Reddy Kalluru 29239651abdSSudarsana Reddy Kalluru /* If RoCE-V2 TLV is not detected, driver need to use RoCE app 29339651abdSSudarsana Reddy Kalluru * data for RoCE-v2 not the default app data. 29439651abdSSudarsana Reddy Kalluru */ 29539651abdSSudarsana Reddy Kalluru if (!p_data->arr[DCBX_PROTOCOL_ROCE_V2].update && 29639651abdSSudarsana Reddy Kalluru p_data->arr[DCBX_PROTOCOL_ROCE].update) { 29739651abdSSudarsana Reddy Kalluru tc = p_data->arr[DCBX_PROTOCOL_ROCE].tc; 29839651abdSSudarsana Reddy Kalluru priority = p_data->arr[DCBX_PROTOCOL_ROCE].priority; 29939651abdSSudarsana Reddy Kalluru qed_dcbx_update_app_info(p_data, p_hwfn, true, true, 30039651abdSSudarsana Reddy Kalluru priority, tc, DCBX_PROTOCOL_ROCE_V2); 30139651abdSSudarsana Reddy Kalluru } 30239651abdSSudarsana Reddy Kalluru 30339651abdSSudarsana Reddy Kalluru /* Update ramrod protocol data and hw_info fields 30439651abdSSudarsana Reddy Kalluru * with default info when corresponding APP TLV's are not detected. 30539651abdSSudarsana Reddy Kalluru * The enabled field has a different logic for ethernet as only for 30639651abdSSudarsana Reddy Kalluru * ethernet dcb should disabled by default, as the information arrives 30739651abdSSudarsana Reddy Kalluru * from the OS (unless an explicit app tlv was present). 30839651abdSSudarsana Reddy Kalluru */ 30939651abdSSudarsana Reddy Kalluru tc = p_data->arr[DCBX_PROTOCOL_ETH].tc; 31039651abdSSudarsana Reddy Kalluru priority = p_data->arr[DCBX_PROTOCOL_ETH].priority; 31139651abdSSudarsana Reddy Kalluru for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) { 31239651abdSSudarsana Reddy Kalluru if (p_data->arr[type].update) 31339651abdSSudarsana Reddy Kalluru continue; 31439651abdSSudarsana Reddy Kalluru 3156ad8c632SSudarsana Reddy Kalluru enable = !(type == DCBX_PROTOCOL_ETH); 31639651abdSSudarsana Reddy Kalluru qed_dcbx_update_app_info(p_data, p_hwfn, enable, true, 31739651abdSSudarsana Reddy Kalluru priority, tc, type); 31839651abdSSudarsana Reddy Kalluru } 31939651abdSSudarsana Reddy Kalluru 32039651abdSSudarsana Reddy Kalluru return 0; 32139651abdSSudarsana Reddy Kalluru } 32239651abdSSudarsana Reddy Kalluru 32339651abdSSudarsana Reddy Kalluru /* Parse app TLV's to update TC information in hw_info structure for 32439651abdSSudarsana Reddy Kalluru * reconfiguring QM. Get protocol specific data for PF update ramrod command. 32539651abdSSudarsana Reddy Kalluru */ 32639651abdSSudarsana Reddy Kalluru static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn) 32739651abdSSudarsana Reddy Kalluru { 32839651abdSSudarsana Reddy Kalluru struct dcbx_app_priority_feature *p_app; 32939651abdSSudarsana Reddy Kalluru struct dcbx_app_priority_entry *p_tbl; 33039651abdSSudarsana Reddy Kalluru struct qed_dcbx_results data = { 0 }; 33139651abdSSudarsana Reddy Kalluru struct dcbx_ets_feature *p_ets; 33239651abdSSudarsana Reddy Kalluru struct qed_hw_info *p_info; 33339651abdSSudarsana Reddy Kalluru u32 pri_tc_tbl, flags; 334fb9ea8a9SSudarsana Reddy Kalluru u8 dcbx_version; 33539651abdSSudarsana Reddy Kalluru int num_entries; 33639651abdSSudarsana Reddy Kalluru int rc = 0; 33739651abdSSudarsana Reddy Kalluru 33839651abdSSudarsana Reddy Kalluru flags = p_hwfn->p_dcbx_info->operational.flags; 339fb9ea8a9SSudarsana Reddy Kalluru dcbx_version = QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION); 34039651abdSSudarsana Reddy Kalluru 34139651abdSSudarsana Reddy Kalluru p_app = &p_hwfn->p_dcbx_info->operational.features.app; 34239651abdSSudarsana Reddy Kalluru p_tbl = p_app->app_pri_tbl; 34339651abdSSudarsana Reddy Kalluru 34439651abdSSudarsana Reddy Kalluru p_ets = &p_hwfn->p_dcbx_info->operational.features.ets; 34539651abdSSudarsana Reddy Kalluru pri_tc_tbl = p_ets->pri_tc_tbl[0]; 34639651abdSSudarsana Reddy Kalluru 34739651abdSSudarsana Reddy Kalluru p_info = &p_hwfn->hw_info; 34839651abdSSudarsana Reddy Kalluru num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES); 34939651abdSSudarsana Reddy Kalluru 35039651abdSSudarsana Reddy Kalluru rc = qed_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl, 351fb9ea8a9SSudarsana Reddy Kalluru num_entries, dcbx_version); 35239651abdSSudarsana Reddy Kalluru if (rc) 35339651abdSSudarsana Reddy Kalluru return rc; 35439651abdSSudarsana Reddy Kalluru 35539651abdSSudarsana Reddy Kalluru p_info->num_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS); 35639651abdSSudarsana Reddy Kalluru data.pf_id = p_hwfn->rel_pf_id; 357fb9ea8a9SSudarsana Reddy Kalluru data.dcbx_enabled = !!dcbx_version; 35839651abdSSudarsana Reddy Kalluru 35939651abdSSudarsana Reddy Kalluru qed_dcbx_dp_protocol(p_hwfn, &data); 36039651abdSSudarsana Reddy Kalluru 36139651abdSSudarsana Reddy Kalluru memcpy(&p_hwfn->p_dcbx_info->results, &data, 36239651abdSSudarsana Reddy Kalluru sizeof(struct qed_dcbx_results)); 36339651abdSSudarsana Reddy Kalluru 36439651abdSSudarsana Reddy Kalluru return 0; 36539651abdSSudarsana Reddy Kalluru } 36639651abdSSudarsana Reddy Kalluru 36739651abdSSudarsana Reddy Kalluru static int 36839651abdSSudarsana Reddy Kalluru qed_dcbx_copy_mib(struct qed_hwfn *p_hwfn, 36939651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 37039651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data *p_data, 37139651abdSSudarsana Reddy Kalluru enum qed_mib_read_type type) 37239651abdSSudarsana Reddy Kalluru { 37339651abdSSudarsana Reddy Kalluru u32 prefix_seq_num, suffix_seq_num; 37439651abdSSudarsana Reddy Kalluru int read_count = 0; 37539651abdSSudarsana Reddy Kalluru int rc = 0; 37639651abdSSudarsana Reddy Kalluru 37739651abdSSudarsana Reddy Kalluru /* The data is considered to be valid only if both sequence numbers are 37839651abdSSudarsana Reddy Kalluru * the same. 37939651abdSSudarsana Reddy Kalluru */ 38039651abdSSudarsana Reddy Kalluru do { 38139651abdSSudarsana Reddy Kalluru if (type == QED_DCBX_REMOTE_LLDP_MIB) { 38239651abdSSudarsana Reddy Kalluru qed_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote, 38339651abdSSudarsana Reddy Kalluru p_data->addr, p_data->size); 38439651abdSSudarsana Reddy Kalluru prefix_seq_num = p_data->lldp_remote->prefix_seq_num; 38539651abdSSudarsana Reddy Kalluru suffix_seq_num = p_data->lldp_remote->suffix_seq_num; 38639651abdSSudarsana Reddy Kalluru } else { 38739651abdSSudarsana Reddy Kalluru qed_memcpy_from(p_hwfn, p_ptt, p_data->mib, 38839651abdSSudarsana Reddy Kalluru p_data->addr, p_data->size); 38939651abdSSudarsana Reddy Kalluru prefix_seq_num = p_data->mib->prefix_seq_num; 39039651abdSSudarsana Reddy Kalluru suffix_seq_num = p_data->mib->suffix_seq_num; 39139651abdSSudarsana Reddy Kalluru } 39239651abdSSudarsana Reddy Kalluru read_count++; 39339651abdSSudarsana Reddy Kalluru 39439651abdSSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, 39539651abdSSudarsana Reddy Kalluru QED_MSG_DCB, 39639651abdSSudarsana Reddy Kalluru "mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 39739651abdSSudarsana Reddy Kalluru type, read_count, prefix_seq_num, suffix_seq_num); 39839651abdSSudarsana Reddy Kalluru } while ((prefix_seq_num != suffix_seq_num) && 39939651abdSSudarsana Reddy Kalluru (read_count < QED_DCBX_MAX_MIB_READ_TRY)); 40039651abdSSudarsana Reddy Kalluru 40139651abdSSudarsana Reddy Kalluru if (read_count >= QED_DCBX_MAX_MIB_READ_TRY) { 40239651abdSSudarsana Reddy Kalluru DP_ERR(p_hwfn, 40339651abdSSudarsana Reddy Kalluru "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n", 40439651abdSSudarsana Reddy Kalluru type, read_count, prefix_seq_num, suffix_seq_num); 40539651abdSSudarsana Reddy Kalluru rc = -EIO; 40639651abdSSudarsana Reddy Kalluru } 40739651abdSSudarsana Reddy Kalluru 40839651abdSSudarsana Reddy Kalluru return rc; 40939651abdSSudarsana Reddy Kalluru } 41039651abdSSudarsana Reddy Kalluru 4116ad8c632SSudarsana Reddy Kalluru #ifdef CONFIG_DCB 4126ad8c632SSudarsana Reddy Kalluru static void 4136ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_priority_info(struct qed_hwfn *p_hwfn, 4146ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_app_prio *p_prio, 4156ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_results *p_results) 4166ad8c632SSudarsana Reddy Kalluru { 4176ad8c632SSudarsana Reddy Kalluru u8 val; 4186ad8c632SSudarsana Reddy Kalluru 4196ad8c632SSudarsana Reddy Kalluru p_prio->roce = QED_DCBX_INVALID_PRIORITY; 4206ad8c632SSudarsana Reddy Kalluru p_prio->roce_v2 = QED_DCBX_INVALID_PRIORITY; 4216ad8c632SSudarsana Reddy Kalluru p_prio->iscsi = QED_DCBX_INVALID_PRIORITY; 4226ad8c632SSudarsana Reddy Kalluru p_prio->fcoe = QED_DCBX_INVALID_PRIORITY; 4236ad8c632SSudarsana Reddy Kalluru 4246ad8c632SSudarsana Reddy Kalluru if (p_results->arr[DCBX_PROTOCOL_ROCE].update && 4256ad8c632SSudarsana Reddy Kalluru p_results->arr[DCBX_PROTOCOL_ROCE].enable) 4266ad8c632SSudarsana Reddy Kalluru p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority; 4276ad8c632SSudarsana Reddy Kalluru 4286ad8c632SSudarsana Reddy Kalluru if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update && 4296ad8c632SSudarsana Reddy Kalluru p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) { 4306ad8c632SSudarsana Reddy Kalluru val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority; 4316ad8c632SSudarsana Reddy Kalluru p_prio->roce_v2 = val; 4326ad8c632SSudarsana Reddy Kalluru } 4336ad8c632SSudarsana Reddy Kalluru 4346ad8c632SSudarsana Reddy Kalluru if (p_results->arr[DCBX_PROTOCOL_ISCSI].update && 4356ad8c632SSudarsana Reddy Kalluru p_results->arr[DCBX_PROTOCOL_ISCSI].enable) 4366ad8c632SSudarsana Reddy Kalluru p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority; 4376ad8c632SSudarsana Reddy Kalluru 4386ad8c632SSudarsana Reddy Kalluru if (p_results->arr[DCBX_PROTOCOL_FCOE].update && 4396ad8c632SSudarsana Reddy Kalluru p_results->arr[DCBX_PROTOCOL_FCOE].enable) 4406ad8c632SSudarsana Reddy Kalluru p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority; 4416ad8c632SSudarsana Reddy Kalluru 4426ad8c632SSudarsana Reddy Kalluru if (p_results->arr[DCBX_PROTOCOL_ETH].update && 4436ad8c632SSudarsana Reddy Kalluru p_results->arr[DCBX_PROTOCOL_ETH].enable) 4446ad8c632SSudarsana Reddy Kalluru p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority; 4456ad8c632SSudarsana Reddy Kalluru 4466ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 4476ad8c632SSudarsana Reddy Kalluru "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n", 4486ad8c632SSudarsana Reddy Kalluru p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe, 4496ad8c632SSudarsana Reddy Kalluru p_prio->eth); 4506ad8c632SSudarsana Reddy Kalluru } 4516ad8c632SSudarsana Reddy Kalluru 4526ad8c632SSudarsana Reddy Kalluru static void 4536ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_app_data(struct qed_hwfn *p_hwfn, 4546ad8c632SSudarsana Reddy Kalluru struct dcbx_app_priority_feature *p_app, 4556ad8c632SSudarsana Reddy Kalluru struct dcbx_app_priority_entry *p_tbl, 456fb9ea8a9SSudarsana Reddy Kalluru struct qed_dcbx_params *p_params, bool ieee) 4576ad8c632SSudarsana Reddy Kalluru { 4586ad8c632SSudarsana Reddy Kalluru struct qed_app_entry *entry; 4596ad8c632SSudarsana Reddy Kalluru u8 pri_map; 4606ad8c632SSudarsana Reddy Kalluru int i; 4616ad8c632SSudarsana Reddy Kalluru 4626ad8c632SSudarsana Reddy Kalluru p_params->app_willing = QED_MFW_GET_FIELD(p_app->flags, 4636ad8c632SSudarsana Reddy Kalluru DCBX_APP_WILLING); 4646ad8c632SSudarsana Reddy Kalluru p_params->app_valid = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ENABLED); 4656ad8c632SSudarsana Reddy Kalluru p_params->app_error = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR); 4666ad8c632SSudarsana Reddy Kalluru p_params->num_app_entries = QED_MFW_GET_FIELD(p_app->flags, 4676ad8c632SSudarsana Reddy Kalluru DCBX_APP_NUM_ENTRIES); 4686ad8c632SSudarsana Reddy Kalluru for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 4696ad8c632SSudarsana Reddy Kalluru entry = &p_params->app_entry[i]; 47059bcb797SSudarsana Reddy Kalluru if (ieee) { 47159bcb797SSudarsana Reddy Kalluru u8 sf_ieee; 47259bcb797SSudarsana Reddy Kalluru u32 val; 47359bcb797SSudarsana Reddy Kalluru 47459bcb797SSudarsana Reddy Kalluru sf_ieee = QED_MFW_GET_FIELD(p_tbl[i].entry, 47559bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE); 47659bcb797SSudarsana Reddy Kalluru switch (sf_ieee) { 47759bcb797SSudarsana Reddy Kalluru case DCBX_APP_SF_IEEE_RESERVED: 47859bcb797SSudarsana Reddy Kalluru /* Old MFW */ 47959bcb797SSudarsana Reddy Kalluru val = QED_MFW_GET_FIELD(p_tbl[i].entry, 48059bcb797SSudarsana Reddy Kalluru DCBX_APP_SF); 48159bcb797SSudarsana Reddy Kalluru entry->sf_ieee = val ? 48259bcb797SSudarsana Reddy Kalluru QED_DCBX_SF_IEEE_TCP_UDP_PORT : 48359bcb797SSudarsana Reddy Kalluru QED_DCBX_SF_IEEE_ETHTYPE; 48459bcb797SSudarsana Reddy Kalluru break; 48559bcb797SSudarsana Reddy Kalluru case DCBX_APP_SF_IEEE_ETHTYPE: 48659bcb797SSudarsana Reddy Kalluru entry->sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE; 48759bcb797SSudarsana Reddy Kalluru break; 48859bcb797SSudarsana Reddy Kalluru case DCBX_APP_SF_IEEE_TCP_PORT: 48959bcb797SSudarsana Reddy Kalluru entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT; 49059bcb797SSudarsana Reddy Kalluru break; 49159bcb797SSudarsana Reddy Kalluru case DCBX_APP_SF_IEEE_UDP_PORT: 49259bcb797SSudarsana Reddy Kalluru entry->sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT; 49359bcb797SSudarsana Reddy Kalluru break; 49459bcb797SSudarsana Reddy Kalluru case DCBX_APP_SF_IEEE_TCP_UDP_PORT: 49559bcb797SSudarsana Reddy Kalluru entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT; 49659bcb797SSudarsana Reddy Kalluru break; 49759bcb797SSudarsana Reddy Kalluru } 49859bcb797SSudarsana Reddy Kalluru } else { 4996ad8c632SSudarsana Reddy Kalluru entry->ethtype = !(QED_MFW_GET_FIELD(p_tbl[i].entry, 5006ad8c632SSudarsana Reddy Kalluru DCBX_APP_SF)); 50159bcb797SSudarsana Reddy Kalluru } 50259bcb797SSudarsana Reddy Kalluru 5036ad8c632SSudarsana Reddy Kalluru pri_map = QED_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP); 5046ad8c632SSudarsana Reddy Kalluru entry->prio = ffs(pri_map) - 1; 5056ad8c632SSudarsana Reddy Kalluru entry->proto_id = QED_MFW_GET_FIELD(p_tbl[i].entry, 5066ad8c632SSudarsana Reddy Kalluru DCBX_APP_PROTOCOL_ID); 5076ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry, 5086ad8c632SSudarsana Reddy Kalluru entry->proto_id, 509fb9ea8a9SSudarsana Reddy Kalluru &entry->proto_type, ieee); 5106ad8c632SSudarsana Reddy Kalluru } 5116ad8c632SSudarsana Reddy Kalluru 5126ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5136ad8c632SSudarsana Reddy Kalluru "APP params: willing %d, valid %d error = %d\n", 5146ad8c632SSudarsana Reddy Kalluru p_params->app_willing, p_params->app_valid, 5156ad8c632SSudarsana Reddy Kalluru p_params->app_error); 5166ad8c632SSudarsana Reddy Kalluru } 5176ad8c632SSudarsana Reddy Kalluru 5186ad8c632SSudarsana Reddy Kalluru static void 5196ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_pfc_data(struct qed_hwfn *p_hwfn, 5206ad8c632SSudarsana Reddy Kalluru u32 pfc, struct qed_dcbx_params *p_params) 5216ad8c632SSudarsana Reddy Kalluru { 5226ad8c632SSudarsana Reddy Kalluru u8 pfc_map; 5236ad8c632SSudarsana Reddy Kalluru 5246ad8c632SSudarsana Reddy Kalluru p_params->pfc.willing = QED_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING); 5256ad8c632SSudarsana Reddy Kalluru p_params->pfc.max_tc = QED_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS); 5266ad8c632SSudarsana Reddy Kalluru p_params->pfc.enabled = QED_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED); 5276ad8c632SSudarsana Reddy Kalluru pfc_map = QED_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP); 5286ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0); 5296ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1); 5306ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2); 5316ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3); 5326ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4); 5336ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5); 5346ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6); 5356ad8c632SSudarsana Reddy Kalluru p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7); 5366ad8c632SSudarsana Reddy Kalluru 5376ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5386ad8c632SSudarsana Reddy Kalluru "PFC params: willing %d, pfc_bitmap %d\n", 5396ad8c632SSudarsana Reddy Kalluru p_params->pfc.willing, pfc_map); 5406ad8c632SSudarsana Reddy Kalluru } 5416ad8c632SSudarsana Reddy Kalluru 5426ad8c632SSudarsana Reddy Kalluru static void 5436ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn, 5446ad8c632SSudarsana Reddy Kalluru struct dcbx_ets_feature *p_ets, 5456ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_params *p_params) 5466ad8c632SSudarsana Reddy Kalluru { 5476ad8c632SSudarsana Reddy Kalluru u32 bw_map[2], tsa_map[2], pri_map; 5486ad8c632SSudarsana Reddy Kalluru int i; 5496ad8c632SSudarsana Reddy Kalluru 5506ad8c632SSudarsana Reddy Kalluru p_params->ets_willing = QED_MFW_GET_FIELD(p_ets->flags, 5516ad8c632SSudarsana Reddy Kalluru DCBX_ETS_WILLING); 5526ad8c632SSudarsana Reddy Kalluru p_params->ets_enabled = QED_MFW_GET_FIELD(p_ets->flags, 5536ad8c632SSudarsana Reddy Kalluru DCBX_ETS_ENABLED); 5546ad8c632SSudarsana Reddy Kalluru p_params->ets_cbs = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS); 5556ad8c632SSudarsana Reddy Kalluru p_params->max_ets_tc = QED_MFW_GET_FIELD(p_ets->flags, 5566ad8c632SSudarsana Reddy Kalluru DCBX_ETS_MAX_TCS); 5576ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5586ad8c632SSudarsana Reddy Kalluru "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n", 5596ad8c632SSudarsana Reddy Kalluru p_params->ets_willing, 5606ad8c632SSudarsana Reddy Kalluru p_params->ets_cbs, 5616ad8c632SSudarsana Reddy Kalluru p_ets->pri_tc_tbl[0], p_params->max_ets_tc); 5626ad8c632SSudarsana Reddy Kalluru 5636ad8c632SSudarsana Reddy Kalluru /* 8 bit tsa and bw data corresponding to each of the 8 TC's are 5646ad8c632SSudarsana Reddy Kalluru * encoded in a type u32 array of size 2. 5656ad8c632SSudarsana Reddy Kalluru */ 5666ad8c632SSudarsana Reddy Kalluru bw_map[0] = be32_to_cpu(p_ets->tc_bw_tbl[0]); 5676ad8c632SSudarsana Reddy Kalluru bw_map[1] = be32_to_cpu(p_ets->tc_bw_tbl[1]); 5686ad8c632SSudarsana Reddy Kalluru tsa_map[0] = be32_to_cpu(p_ets->tc_tsa_tbl[0]); 5696ad8c632SSudarsana Reddy Kalluru tsa_map[1] = be32_to_cpu(p_ets->tc_tsa_tbl[1]); 570c0c45a6bSSudarsana Reddy Kalluru pri_map = p_ets->pri_tc_tbl[0]; 5716ad8c632SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 5726ad8c632SSudarsana Reddy Kalluru p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i]; 5736ad8c632SSudarsana Reddy Kalluru p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i]; 5746ad8c632SSudarsana Reddy Kalluru p_params->ets_pri_tc_tbl[i] = QED_DCBX_PRIO2TC(pri_map, i); 5756ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, 5766ad8c632SSudarsana Reddy Kalluru "elem %d bw_tbl %x tsa_tbl %x\n", 5776ad8c632SSudarsana Reddy Kalluru i, p_params->ets_tc_bw_tbl[i], 5786ad8c632SSudarsana Reddy Kalluru p_params->ets_tc_tsa_tbl[i]); 5796ad8c632SSudarsana Reddy Kalluru } 5806ad8c632SSudarsana Reddy Kalluru } 5816ad8c632SSudarsana Reddy Kalluru 5826ad8c632SSudarsana Reddy Kalluru static void 5836ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_common_params(struct qed_hwfn *p_hwfn, 5846ad8c632SSudarsana Reddy Kalluru struct dcbx_app_priority_feature *p_app, 5856ad8c632SSudarsana Reddy Kalluru struct dcbx_app_priority_entry *p_tbl, 5866ad8c632SSudarsana Reddy Kalluru struct dcbx_ets_feature *p_ets, 587fb9ea8a9SSudarsana Reddy Kalluru u32 pfc, struct qed_dcbx_params *p_params, bool ieee) 5886ad8c632SSudarsana Reddy Kalluru { 589fb9ea8a9SSudarsana Reddy Kalluru qed_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee); 5906ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_ets_data(p_hwfn, p_ets, p_params); 5916ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_pfc_data(p_hwfn, pfc, p_params); 5926ad8c632SSudarsana Reddy Kalluru } 5936ad8c632SSudarsana Reddy Kalluru 5946ad8c632SSudarsana Reddy Kalluru static void 5956ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_local_params(struct qed_hwfn *p_hwfn, 5966ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt, struct qed_dcbx_get *params) 5976ad8c632SSudarsana Reddy Kalluru { 5986ad8c632SSudarsana Reddy Kalluru struct dcbx_features *p_feat; 5996ad8c632SSudarsana Reddy Kalluru 6006ad8c632SSudarsana Reddy Kalluru p_feat = &p_hwfn->p_dcbx_info->local_admin.features; 6016ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6026ad8c632SSudarsana Reddy Kalluru p_feat->app.app_pri_tbl, &p_feat->ets, 603fb9ea8a9SSudarsana Reddy Kalluru p_feat->pfc, ¶ms->local.params, false); 6046ad8c632SSudarsana Reddy Kalluru params->local.valid = true; 6056ad8c632SSudarsana Reddy Kalluru } 6066ad8c632SSudarsana Reddy Kalluru 6076ad8c632SSudarsana Reddy Kalluru static void 6086ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_remote_params(struct qed_hwfn *p_hwfn, 6096ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt, struct qed_dcbx_get *params) 6106ad8c632SSudarsana Reddy Kalluru { 6116ad8c632SSudarsana Reddy Kalluru struct dcbx_features *p_feat; 6126ad8c632SSudarsana Reddy Kalluru 6136ad8c632SSudarsana Reddy Kalluru p_feat = &p_hwfn->p_dcbx_info->remote.features; 6146ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6156ad8c632SSudarsana Reddy Kalluru p_feat->app.app_pri_tbl, &p_feat->ets, 616fb9ea8a9SSudarsana Reddy Kalluru p_feat->pfc, ¶ms->remote.params, false); 6176ad8c632SSudarsana Reddy Kalluru params->remote.valid = true; 6186ad8c632SSudarsana Reddy Kalluru } 6196ad8c632SSudarsana Reddy Kalluru 6206ad8c632SSudarsana Reddy Kalluru static void 6216ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_operational_params(struct qed_hwfn *p_hwfn, 6226ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 6236ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *params) 6246ad8c632SSudarsana Reddy Kalluru { 6256ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_operational_params *p_operational; 6266ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_results *p_results; 6276ad8c632SSudarsana Reddy Kalluru struct dcbx_features *p_feat; 6286ad8c632SSudarsana Reddy Kalluru bool enabled, err; 6296ad8c632SSudarsana Reddy Kalluru u32 flags; 6306ad8c632SSudarsana Reddy Kalluru bool val; 6316ad8c632SSudarsana Reddy Kalluru 6326ad8c632SSudarsana Reddy Kalluru flags = p_hwfn->p_dcbx_info->operational.flags; 6336ad8c632SSudarsana Reddy Kalluru 6346ad8c632SSudarsana Reddy Kalluru /* If DCBx version is non zero, then negotiation 6356ad8c632SSudarsana Reddy Kalluru * was successfuly performed 6366ad8c632SSudarsana Reddy Kalluru */ 6376ad8c632SSudarsana Reddy Kalluru p_operational = ¶ms->operational; 6386ad8c632SSudarsana Reddy Kalluru enabled = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) != 6396ad8c632SSudarsana Reddy Kalluru DCBX_CONFIG_VERSION_DISABLED); 6406ad8c632SSudarsana Reddy Kalluru if (!enabled) { 6416ad8c632SSudarsana Reddy Kalluru p_operational->enabled = enabled; 6426ad8c632SSudarsana Reddy Kalluru p_operational->valid = false; 6436ad8c632SSudarsana Reddy Kalluru return; 6446ad8c632SSudarsana Reddy Kalluru } 6456ad8c632SSudarsana Reddy Kalluru 6466ad8c632SSudarsana Reddy Kalluru p_feat = &p_hwfn->p_dcbx_info->operational.features; 6476ad8c632SSudarsana Reddy Kalluru p_results = &p_hwfn->p_dcbx_info->results; 6486ad8c632SSudarsana Reddy Kalluru 6496ad8c632SSudarsana Reddy Kalluru val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 6506ad8c632SSudarsana Reddy Kalluru DCBX_CONFIG_VERSION_IEEE); 6516ad8c632SSudarsana Reddy Kalluru p_operational->ieee = val; 6526ad8c632SSudarsana Reddy Kalluru val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) == 6536ad8c632SSudarsana Reddy Kalluru DCBX_CONFIG_VERSION_CEE); 6546ad8c632SSudarsana Reddy Kalluru p_operational->cee = val; 6556ad8c632SSudarsana Reddy Kalluru 6566ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Version support: ieee %d, cee %d\n", 6576ad8c632SSudarsana Reddy Kalluru p_operational->ieee, p_operational->cee); 6586ad8c632SSudarsana Reddy Kalluru 6596ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_common_params(p_hwfn, &p_feat->app, 6606ad8c632SSudarsana Reddy Kalluru p_feat->app.app_pri_tbl, &p_feat->ets, 661fb9ea8a9SSudarsana Reddy Kalluru p_feat->pfc, ¶ms->operational.params, 662fb9ea8a9SSudarsana Reddy Kalluru p_operational->ieee); 6636ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio, p_results); 6646ad8c632SSudarsana Reddy Kalluru err = QED_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR); 6656ad8c632SSudarsana Reddy Kalluru p_operational->err = err; 6666ad8c632SSudarsana Reddy Kalluru p_operational->enabled = enabled; 6676ad8c632SSudarsana Reddy Kalluru p_operational->valid = true; 6686ad8c632SSudarsana Reddy Kalluru } 6696ad8c632SSudarsana Reddy Kalluru 6706ad8c632SSudarsana Reddy Kalluru static void 6716ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_local_lldp_params(struct qed_hwfn *p_hwfn, 6726ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 6736ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *params) 6746ad8c632SSudarsana Reddy Kalluru { 6756ad8c632SSudarsana Reddy Kalluru struct lldp_config_params_s *p_local; 6766ad8c632SSudarsana Reddy Kalluru 6776ad8c632SSudarsana Reddy Kalluru p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE]; 6786ad8c632SSudarsana Reddy Kalluru 6796ad8c632SSudarsana Reddy Kalluru memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id, 6806ad8c632SSudarsana Reddy Kalluru ARRAY_SIZE(p_local->local_chassis_id)); 6816ad8c632SSudarsana Reddy Kalluru memcpy(params->lldp_local.local_port_id, p_local->local_port_id, 6826ad8c632SSudarsana Reddy Kalluru ARRAY_SIZE(p_local->local_port_id)); 6836ad8c632SSudarsana Reddy Kalluru } 6846ad8c632SSudarsana Reddy Kalluru 6856ad8c632SSudarsana Reddy Kalluru static void 6866ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_remote_lldp_params(struct qed_hwfn *p_hwfn, 6876ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 6886ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *params) 6896ad8c632SSudarsana Reddy Kalluru { 6906ad8c632SSudarsana Reddy Kalluru struct lldp_status_params_s *p_remote; 6916ad8c632SSudarsana Reddy Kalluru 6926ad8c632SSudarsana Reddy Kalluru p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE]; 6936ad8c632SSudarsana Reddy Kalluru 6946ad8c632SSudarsana Reddy Kalluru memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id, 6956ad8c632SSudarsana Reddy Kalluru ARRAY_SIZE(p_remote->peer_chassis_id)); 6966ad8c632SSudarsana Reddy Kalluru memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id, 6976ad8c632SSudarsana Reddy Kalluru ARRAY_SIZE(p_remote->peer_port_id)); 6986ad8c632SSudarsana Reddy Kalluru } 6996ad8c632SSudarsana Reddy Kalluru 7006ad8c632SSudarsana Reddy Kalluru static int 7016ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 7026ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *p_params, 7036ad8c632SSudarsana Reddy Kalluru enum qed_mib_read_type type) 7046ad8c632SSudarsana Reddy Kalluru { 7056ad8c632SSudarsana Reddy Kalluru switch (type) { 7066ad8c632SSudarsana Reddy Kalluru case QED_DCBX_REMOTE_MIB: 7076ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_remote_params(p_hwfn, p_ptt, p_params); 7086ad8c632SSudarsana Reddy Kalluru break; 7096ad8c632SSudarsana Reddy Kalluru case QED_DCBX_LOCAL_MIB: 7106ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_local_params(p_hwfn, p_ptt, p_params); 7116ad8c632SSudarsana Reddy Kalluru break; 7126ad8c632SSudarsana Reddy Kalluru case QED_DCBX_OPERATIONAL_MIB: 7136ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_operational_params(p_hwfn, p_ptt, p_params); 7146ad8c632SSudarsana Reddy Kalluru break; 7156ad8c632SSudarsana Reddy Kalluru case QED_DCBX_REMOTE_LLDP_MIB: 7166ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params); 7176ad8c632SSudarsana Reddy Kalluru break; 7186ad8c632SSudarsana Reddy Kalluru case QED_DCBX_LOCAL_LLDP_MIB: 7196ad8c632SSudarsana Reddy Kalluru qed_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params); 7206ad8c632SSudarsana Reddy Kalluru break; 7216ad8c632SSudarsana Reddy Kalluru default: 7226ad8c632SSudarsana Reddy Kalluru DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 7236ad8c632SSudarsana Reddy Kalluru return -EINVAL; 7246ad8c632SSudarsana Reddy Kalluru } 7256ad8c632SSudarsana Reddy Kalluru 7266ad8c632SSudarsana Reddy Kalluru return 0; 7276ad8c632SSudarsana Reddy Kalluru } 7286ad8c632SSudarsana Reddy Kalluru #endif 7296ad8c632SSudarsana Reddy Kalluru 73039651abdSSudarsana Reddy Kalluru static int 73139651abdSSudarsana Reddy Kalluru qed_dcbx_read_local_lldp_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 73239651abdSSudarsana Reddy Kalluru { 73339651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 73439651abdSSudarsana Reddy Kalluru int rc = 0; 73539651abdSSudarsana Reddy Kalluru 73639651abdSSudarsana Reddy Kalluru memset(&data, 0, sizeof(data)); 73739651abdSSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 73839651abdSSudarsana Reddy Kalluru lldp_config_params); 73939651abdSSudarsana Reddy Kalluru data.lldp_local = p_hwfn->p_dcbx_info->lldp_local; 74039651abdSSudarsana Reddy Kalluru data.size = sizeof(struct lldp_config_params_s); 74139651abdSSudarsana Reddy Kalluru qed_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size); 74239651abdSSudarsana Reddy Kalluru 74339651abdSSudarsana Reddy Kalluru return rc; 74439651abdSSudarsana Reddy Kalluru } 74539651abdSSudarsana Reddy Kalluru 74639651abdSSudarsana Reddy Kalluru static int 74739651abdSSudarsana Reddy Kalluru qed_dcbx_read_remote_lldp_mib(struct qed_hwfn *p_hwfn, 74839651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 74939651abdSSudarsana Reddy Kalluru enum qed_mib_read_type type) 75039651abdSSudarsana Reddy Kalluru { 75139651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 75239651abdSSudarsana Reddy Kalluru int rc = 0; 75339651abdSSudarsana Reddy Kalluru 75439651abdSSudarsana Reddy Kalluru memset(&data, 0, sizeof(data)); 75539651abdSSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port, 75639651abdSSudarsana Reddy Kalluru lldp_status_params); 75739651abdSSudarsana Reddy Kalluru data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote; 75839651abdSSudarsana Reddy Kalluru data.size = sizeof(struct lldp_status_params_s); 75939651abdSSudarsana Reddy Kalluru rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 76039651abdSSudarsana Reddy Kalluru 76139651abdSSudarsana Reddy Kalluru return rc; 76239651abdSSudarsana Reddy Kalluru } 76339651abdSSudarsana Reddy Kalluru 76439651abdSSudarsana Reddy Kalluru static int 76539651abdSSudarsana Reddy Kalluru qed_dcbx_read_operational_mib(struct qed_hwfn *p_hwfn, 76639651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, 76739651abdSSudarsana Reddy Kalluru enum qed_mib_read_type type) 76839651abdSSudarsana Reddy Kalluru { 76939651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 77039651abdSSudarsana Reddy Kalluru int rc = 0; 77139651abdSSudarsana Reddy Kalluru 77239651abdSSudarsana Reddy Kalluru memset(&data, 0, sizeof(data)); 77339651abdSSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + 77439651abdSSudarsana Reddy Kalluru offsetof(struct public_port, operational_dcbx_mib); 77539651abdSSudarsana Reddy Kalluru data.mib = &p_hwfn->p_dcbx_info->operational; 77639651abdSSudarsana Reddy Kalluru data.size = sizeof(struct dcbx_mib); 77739651abdSSudarsana Reddy Kalluru rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 77839651abdSSudarsana Reddy Kalluru 77939651abdSSudarsana Reddy Kalluru return rc; 78039651abdSSudarsana Reddy Kalluru } 78139651abdSSudarsana Reddy Kalluru 78239651abdSSudarsana Reddy Kalluru static int 78339651abdSSudarsana Reddy Kalluru qed_dcbx_read_remote_mib(struct qed_hwfn *p_hwfn, 78439651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, enum qed_mib_read_type type) 78539651abdSSudarsana Reddy Kalluru { 78639651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 78739651abdSSudarsana Reddy Kalluru int rc = 0; 78839651abdSSudarsana Reddy Kalluru 78939651abdSSudarsana Reddy Kalluru memset(&data, 0, sizeof(data)); 79039651abdSSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + 79139651abdSSudarsana Reddy Kalluru offsetof(struct public_port, remote_dcbx_mib); 79239651abdSSudarsana Reddy Kalluru data.mib = &p_hwfn->p_dcbx_info->remote; 79339651abdSSudarsana Reddy Kalluru data.size = sizeof(struct dcbx_mib); 79439651abdSSudarsana Reddy Kalluru rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type); 79539651abdSSudarsana Reddy Kalluru 79639651abdSSudarsana Reddy Kalluru return rc; 79739651abdSSudarsana Reddy Kalluru } 79839651abdSSudarsana Reddy Kalluru 79939651abdSSudarsana Reddy Kalluru static int 80039651abdSSudarsana Reddy Kalluru qed_dcbx_read_local_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 80139651abdSSudarsana Reddy Kalluru { 80239651abdSSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 80339651abdSSudarsana Reddy Kalluru int rc = 0; 80439651abdSSudarsana Reddy Kalluru 80539651abdSSudarsana Reddy Kalluru memset(&data, 0, sizeof(data)); 80639651abdSSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + 80739651abdSSudarsana Reddy Kalluru offsetof(struct public_port, local_admin_dcbx_mib); 80839651abdSSudarsana Reddy Kalluru data.local_admin = &p_hwfn->p_dcbx_info->local_admin; 80939651abdSSudarsana Reddy Kalluru data.size = sizeof(struct dcbx_local_params); 81039651abdSSudarsana Reddy Kalluru qed_memcpy_from(p_hwfn, p_ptt, data.local_admin, data.addr, data.size); 81139651abdSSudarsana Reddy Kalluru 81239651abdSSudarsana Reddy Kalluru return rc; 81339651abdSSudarsana Reddy Kalluru } 81439651abdSSudarsana Reddy Kalluru 81539651abdSSudarsana Reddy Kalluru static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn, 81639651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, enum qed_mib_read_type type) 81739651abdSSudarsana Reddy Kalluru { 81839651abdSSudarsana Reddy Kalluru int rc = -EINVAL; 81939651abdSSudarsana Reddy Kalluru 82039651abdSSudarsana Reddy Kalluru switch (type) { 82139651abdSSudarsana Reddy Kalluru case QED_DCBX_OPERATIONAL_MIB: 82239651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_operational_mib(p_hwfn, p_ptt, type); 82339651abdSSudarsana Reddy Kalluru break; 82439651abdSSudarsana Reddy Kalluru case QED_DCBX_REMOTE_MIB: 82539651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_remote_mib(p_hwfn, p_ptt, type); 82639651abdSSudarsana Reddy Kalluru break; 82739651abdSSudarsana Reddy Kalluru case QED_DCBX_LOCAL_MIB: 82839651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_local_mib(p_hwfn, p_ptt); 82939651abdSSudarsana Reddy Kalluru break; 83039651abdSSudarsana Reddy Kalluru case QED_DCBX_REMOTE_LLDP_MIB: 83139651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type); 83239651abdSSudarsana Reddy Kalluru break; 83339651abdSSudarsana Reddy Kalluru case QED_DCBX_LOCAL_LLDP_MIB: 83439651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_local_lldp_mib(p_hwfn, p_ptt); 83539651abdSSudarsana Reddy Kalluru break; 83639651abdSSudarsana Reddy Kalluru default: 83739651abdSSudarsana Reddy Kalluru DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type); 83839651abdSSudarsana Reddy Kalluru } 83939651abdSSudarsana Reddy Kalluru 84039651abdSSudarsana Reddy Kalluru return rc; 84139651abdSSudarsana Reddy Kalluru } 84239651abdSSudarsana Reddy Kalluru 84339651abdSSudarsana Reddy Kalluru /* Read updated MIB. 84439651abdSSudarsana Reddy Kalluru * Reconfigure QM and invoke PF update ramrod command if operational MIB 84539651abdSSudarsana Reddy Kalluru * change is detected. 84639651abdSSudarsana Reddy Kalluru */ 84739651abdSSudarsana Reddy Kalluru int 84839651abdSSudarsana Reddy Kalluru qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn, 84939651abdSSudarsana Reddy Kalluru struct qed_ptt *p_ptt, enum qed_mib_read_type type) 85039651abdSSudarsana Reddy Kalluru { 85139651abdSSudarsana Reddy Kalluru int rc = 0; 85239651abdSSudarsana Reddy Kalluru 85339651abdSSudarsana Reddy Kalluru rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 85439651abdSSudarsana Reddy Kalluru if (rc) 85539651abdSSudarsana Reddy Kalluru return rc; 85639651abdSSudarsana Reddy Kalluru 85739651abdSSudarsana Reddy Kalluru if (type == QED_DCBX_OPERATIONAL_MIB) { 85839651abdSSudarsana Reddy Kalluru rc = qed_dcbx_process_mib_info(p_hwfn); 85939651abdSSudarsana Reddy Kalluru if (!rc) { 86039651abdSSudarsana Reddy Kalluru /* reconfigure tcs of QM queues according 86139651abdSSudarsana Reddy Kalluru * to negotiation results 86239651abdSSudarsana Reddy Kalluru */ 86339651abdSSudarsana Reddy Kalluru qed_qm_reconf(p_hwfn, p_ptt); 86439651abdSSudarsana Reddy Kalluru 86539651abdSSudarsana Reddy Kalluru /* update storm FW with negotiation results */ 86639651abdSSudarsana Reddy Kalluru qed_sp_pf_update(p_hwfn); 86739651abdSSudarsana Reddy Kalluru } 86839651abdSSudarsana Reddy Kalluru } 86939651abdSSudarsana Reddy Kalluru 87039651abdSSudarsana Reddy Kalluru return rc; 87139651abdSSudarsana Reddy Kalluru } 87239651abdSSudarsana Reddy Kalluru 87339651abdSSudarsana Reddy Kalluru int qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn) 87439651abdSSudarsana Reddy Kalluru { 87539651abdSSudarsana Reddy Kalluru int rc = 0; 87639651abdSSudarsana Reddy Kalluru 87739651abdSSudarsana Reddy Kalluru p_hwfn->p_dcbx_info = kzalloc(sizeof(*p_hwfn->p_dcbx_info), GFP_KERNEL); 87839651abdSSudarsana Reddy Kalluru if (!p_hwfn->p_dcbx_info) { 87939651abdSSudarsana Reddy Kalluru DP_NOTICE(p_hwfn, 88039651abdSSudarsana Reddy Kalluru "Failed to allocate 'struct qed_dcbx_info'\n"); 88139651abdSSudarsana Reddy Kalluru rc = -ENOMEM; 88239651abdSSudarsana Reddy Kalluru } 88339651abdSSudarsana Reddy Kalluru 88439651abdSSudarsana Reddy Kalluru return rc; 88539651abdSSudarsana Reddy Kalluru } 88639651abdSSudarsana Reddy Kalluru 88739651abdSSudarsana Reddy Kalluru void qed_dcbx_info_free(struct qed_hwfn *p_hwfn, 88839651abdSSudarsana Reddy Kalluru struct qed_dcbx_info *p_dcbx_info) 88939651abdSSudarsana Reddy Kalluru { 89039651abdSSudarsana Reddy Kalluru kfree(p_hwfn->p_dcbx_info); 89139651abdSSudarsana Reddy Kalluru } 89239651abdSSudarsana Reddy Kalluru 89339651abdSSudarsana Reddy Kalluru static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data, 89439651abdSSudarsana Reddy Kalluru struct qed_dcbx_results *p_src, 89539651abdSSudarsana Reddy Kalluru enum dcbx_protocol_type type) 89639651abdSSudarsana Reddy Kalluru { 89739651abdSSudarsana Reddy Kalluru p_data->dcb_enable_flag = p_src->arr[type].enable; 89839651abdSSudarsana Reddy Kalluru p_data->dcb_priority = p_src->arr[type].priority; 89939651abdSSudarsana Reddy Kalluru p_data->dcb_tc = p_src->arr[type].tc; 90039651abdSSudarsana Reddy Kalluru } 90139651abdSSudarsana Reddy Kalluru 90239651abdSSudarsana Reddy Kalluru /* Set pf update ramrod command params */ 90339651abdSSudarsana Reddy Kalluru void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src, 90439651abdSSudarsana Reddy Kalluru struct pf_update_ramrod_data *p_dest) 90539651abdSSudarsana Reddy Kalluru { 90639651abdSSudarsana Reddy Kalluru struct protocol_dcb_data *p_dcb_data; 90739651abdSSudarsana Reddy Kalluru bool update_flag = false; 90839651abdSSudarsana Reddy Kalluru 90939651abdSSudarsana Reddy Kalluru p_dest->pf_id = p_src->pf_id; 91039651abdSSudarsana Reddy Kalluru 91139651abdSSudarsana Reddy Kalluru update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update; 91239651abdSSudarsana Reddy Kalluru p_dest->update_fcoe_dcb_data_flag = update_flag; 91339651abdSSudarsana Reddy Kalluru 91439651abdSSudarsana Reddy Kalluru update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update; 91539651abdSSudarsana Reddy Kalluru p_dest->update_roce_dcb_data_flag = update_flag; 91639651abdSSudarsana Reddy Kalluru update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update; 91739651abdSSudarsana Reddy Kalluru p_dest->update_roce_dcb_data_flag = update_flag; 91839651abdSSudarsana Reddy Kalluru 91939651abdSSudarsana Reddy Kalluru update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update; 92039651abdSSudarsana Reddy Kalluru p_dest->update_iscsi_dcb_data_flag = update_flag; 92139651abdSSudarsana Reddy Kalluru update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update; 92239651abdSSudarsana Reddy Kalluru p_dest->update_eth_dcb_data_flag = update_flag; 92339651abdSSudarsana Reddy Kalluru 92439651abdSSudarsana Reddy Kalluru p_dcb_data = &p_dest->fcoe_dcb_data; 92539651abdSSudarsana Reddy Kalluru qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE); 92639651abdSSudarsana Reddy Kalluru p_dcb_data = &p_dest->roce_dcb_data; 92739651abdSSudarsana Reddy Kalluru 92839651abdSSudarsana Reddy Kalluru if (p_src->arr[DCBX_PROTOCOL_ROCE].update) 92939651abdSSudarsana Reddy Kalluru qed_dcbx_update_protocol_data(p_dcb_data, p_src, 93039651abdSSudarsana Reddy Kalluru DCBX_PROTOCOL_ROCE); 93139651abdSSudarsana Reddy Kalluru if (p_src->arr[DCBX_PROTOCOL_ROCE_V2].update) 93239651abdSSudarsana Reddy Kalluru qed_dcbx_update_protocol_data(p_dcb_data, p_src, 93339651abdSSudarsana Reddy Kalluru DCBX_PROTOCOL_ROCE_V2); 93439651abdSSudarsana Reddy Kalluru 93539651abdSSudarsana Reddy Kalluru p_dcb_data = &p_dest->iscsi_dcb_data; 93639651abdSSudarsana Reddy Kalluru qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI); 93739651abdSSudarsana Reddy Kalluru p_dcb_data = &p_dest->eth_dcb_data; 93839651abdSSudarsana Reddy Kalluru qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH); 93939651abdSSudarsana Reddy Kalluru } 9406ad8c632SSudarsana Reddy Kalluru 9416ad8c632SSudarsana Reddy Kalluru #ifdef CONFIG_DCB 9426ad8c632SSudarsana Reddy Kalluru static int qed_dcbx_query_params(struct qed_hwfn *p_hwfn, 9436ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *p_get, 9446ad8c632SSudarsana Reddy Kalluru enum qed_mib_read_type type) 9456ad8c632SSudarsana Reddy Kalluru { 9466ad8c632SSudarsana Reddy Kalluru struct qed_ptt *p_ptt; 9476ad8c632SSudarsana Reddy Kalluru int rc; 9486ad8c632SSudarsana Reddy Kalluru 9495fe118c9SSudarsana Reddy Kalluru if (IS_VF(p_hwfn->cdev)) 9505fe118c9SSudarsana Reddy Kalluru return -EINVAL; 9515fe118c9SSudarsana Reddy Kalluru 9526ad8c632SSudarsana Reddy Kalluru p_ptt = qed_ptt_acquire(p_hwfn); 9536ad8c632SSudarsana Reddy Kalluru if (!p_ptt) 9546ad8c632SSudarsana Reddy Kalluru return -EBUSY; 9556ad8c632SSudarsana Reddy Kalluru 9566ad8c632SSudarsana Reddy Kalluru rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type); 9576ad8c632SSudarsana Reddy Kalluru if (rc) 9586ad8c632SSudarsana Reddy Kalluru goto out; 9596ad8c632SSudarsana Reddy Kalluru 9606ad8c632SSudarsana Reddy Kalluru rc = qed_dcbx_get_params(p_hwfn, p_ptt, p_get, type); 9616ad8c632SSudarsana Reddy Kalluru 9626ad8c632SSudarsana Reddy Kalluru out: 9636ad8c632SSudarsana Reddy Kalluru qed_ptt_release(p_hwfn, p_ptt); 9646ad8c632SSudarsana Reddy Kalluru return rc; 9656ad8c632SSudarsana Reddy Kalluru } 9666ad8c632SSudarsana Reddy Kalluru 9676ad8c632SSudarsana Reddy Kalluru static void 9686ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn, 9696ad8c632SSudarsana Reddy Kalluru u32 *pfc, struct qed_dcbx_params *p_params) 9706ad8c632SSudarsana Reddy Kalluru { 9716ad8c632SSudarsana Reddy Kalluru u8 pfc_map = 0; 9726ad8c632SSudarsana Reddy Kalluru int i; 9736ad8c632SSudarsana Reddy Kalluru 9746ad8c632SSudarsana Reddy Kalluru if (p_params->pfc.willing) 9756ad8c632SSudarsana Reddy Kalluru *pfc |= DCBX_PFC_WILLING_MASK; 9766ad8c632SSudarsana Reddy Kalluru else 9776ad8c632SSudarsana Reddy Kalluru *pfc &= ~DCBX_PFC_WILLING_MASK; 9786ad8c632SSudarsana Reddy Kalluru 9796ad8c632SSudarsana Reddy Kalluru if (p_params->pfc.enabled) 9806ad8c632SSudarsana Reddy Kalluru *pfc |= DCBX_PFC_ENABLED_MASK; 9816ad8c632SSudarsana Reddy Kalluru else 9826ad8c632SSudarsana Reddy Kalluru *pfc &= ~DCBX_PFC_ENABLED_MASK; 9836ad8c632SSudarsana Reddy Kalluru 9846ad8c632SSudarsana Reddy Kalluru *pfc &= ~DCBX_PFC_CAPS_MASK; 9856ad8c632SSudarsana Reddy Kalluru *pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT; 9866ad8c632SSudarsana Reddy Kalluru 9876ad8c632SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 9886ad8c632SSudarsana Reddy Kalluru if (p_params->pfc.prio[i]) 9896ad8c632SSudarsana Reddy Kalluru pfc_map |= BIT(i); 9906ad8c632SSudarsana Reddy Kalluru 9916ad8c632SSudarsana Reddy Kalluru *pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT); 9926ad8c632SSudarsana Reddy Kalluru 9936ad8c632SSudarsana Reddy Kalluru DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc); 9946ad8c632SSudarsana Reddy Kalluru } 9956ad8c632SSudarsana Reddy Kalluru 9966ad8c632SSudarsana Reddy Kalluru static void 9976ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn, 9986ad8c632SSudarsana Reddy Kalluru struct dcbx_ets_feature *p_ets, 9996ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_params *p_params) 10006ad8c632SSudarsana Reddy Kalluru { 10016ad8c632SSudarsana Reddy Kalluru u8 *bw_map, *tsa_map; 10026ad8c632SSudarsana Reddy Kalluru u32 val; 10036ad8c632SSudarsana Reddy Kalluru int i; 10046ad8c632SSudarsana Reddy Kalluru 10056ad8c632SSudarsana Reddy Kalluru if (p_params->ets_willing) 10066ad8c632SSudarsana Reddy Kalluru p_ets->flags |= DCBX_ETS_WILLING_MASK; 10076ad8c632SSudarsana Reddy Kalluru else 10086ad8c632SSudarsana Reddy Kalluru p_ets->flags &= ~DCBX_ETS_WILLING_MASK; 10096ad8c632SSudarsana Reddy Kalluru 10106ad8c632SSudarsana Reddy Kalluru if (p_params->ets_cbs) 10116ad8c632SSudarsana Reddy Kalluru p_ets->flags |= DCBX_ETS_CBS_MASK; 10126ad8c632SSudarsana Reddy Kalluru else 10136ad8c632SSudarsana Reddy Kalluru p_ets->flags &= ~DCBX_ETS_CBS_MASK; 10146ad8c632SSudarsana Reddy Kalluru 10156ad8c632SSudarsana Reddy Kalluru if (p_params->ets_enabled) 10166ad8c632SSudarsana Reddy Kalluru p_ets->flags |= DCBX_ETS_ENABLED_MASK; 10176ad8c632SSudarsana Reddy Kalluru else 10186ad8c632SSudarsana Reddy Kalluru p_ets->flags &= ~DCBX_ETS_ENABLED_MASK; 10196ad8c632SSudarsana Reddy Kalluru 10206ad8c632SSudarsana Reddy Kalluru p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK; 10216ad8c632SSudarsana Reddy Kalluru p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT; 10226ad8c632SSudarsana Reddy Kalluru 10236ad8c632SSudarsana Reddy Kalluru bw_map = (u8 *)&p_ets->tc_bw_tbl[0]; 10246ad8c632SSudarsana Reddy Kalluru tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0]; 10256ad8c632SSudarsana Reddy Kalluru p_ets->pri_tc_tbl[0] = 0; 10266ad8c632SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 10276ad8c632SSudarsana Reddy Kalluru bw_map[i] = p_params->ets_tc_bw_tbl[i]; 10286ad8c632SSudarsana Reddy Kalluru tsa_map[i] = p_params->ets_tc_tsa_tbl[i]; 10296ad8c632SSudarsana Reddy Kalluru /* Copy the priority value to the corresponding 4 bits in the 10306ad8c632SSudarsana Reddy Kalluru * traffic class table. 10316ad8c632SSudarsana Reddy Kalluru */ 10326ad8c632SSudarsana Reddy Kalluru val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4)); 10336ad8c632SSudarsana Reddy Kalluru p_ets->pri_tc_tbl[0] |= val; 10346ad8c632SSudarsana Reddy Kalluru } 10356ad8c632SSudarsana Reddy Kalluru for (i = 0; i < 2; i++) { 10366ad8c632SSudarsana Reddy Kalluru p_ets->tc_bw_tbl[i] = cpu_to_be32(p_ets->tc_bw_tbl[i]); 10376ad8c632SSudarsana Reddy Kalluru p_ets->tc_tsa_tbl[i] = cpu_to_be32(p_ets->tc_tsa_tbl[i]); 10386ad8c632SSudarsana Reddy Kalluru } 10396ad8c632SSudarsana Reddy Kalluru } 10406ad8c632SSudarsana Reddy Kalluru 10416ad8c632SSudarsana Reddy Kalluru static void 10426ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_app_data(struct qed_hwfn *p_hwfn, 10436ad8c632SSudarsana Reddy Kalluru struct dcbx_app_priority_feature *p_app, 104459bcb797SSudarsana Reddy Kalluru struct qed_dcbx_params *p_params, bool ieee) 10456ad8c632SSudarsana Reddy Kalluru { 10466ad8c632SSudarsana Reddy Kalluru u32 *entry; 10476ad8c632SSudarsana Reddy Kalluru int i; 10486ad8c632SSudarsana Reddy Kalluru 10496ad8c632SSudarsana Reddy Kalluru if (p_params->app_willing) 10506ad8c632SSudarsana Reddy Kalluru p_app->flags |= DCBX_APP_WILLING_MASK; 10516ad8c632SSudarsana Reddy Kalluru else 10526ad8c632SSudarsana Reddy Kalluru p_app->flags &= ~DCBX_APP_WILLING_MASK; 10536ad8c632SSudarsana Reddy Kalluru 10546ad8c632SSudarsana Reddy Kalluru if (p_params->app_valid) 10556ad8c632SSudarsana Reddy Kalluru p_app->flags |= DCBX_APP_ENABLED_MASK; 10566ad8c632SSudarsana Reddy Kalluru else 10576ad8c632SSudarsana Reddy Kalluru p_app->flags &= ~DCBX_APP_ENABLED_MASK; 10586ad8c632SSudarsana Reddy Kalluru 10596ad8c632SSudarsana Reddy Kalluru p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK; 10606ad8c632SSudarsana Reddy Kalluru p_app->flags |= (u32)p_params->num_app_entries << 10616ad8c632SSudarsana Reddy Kalluru DCBX_APP_NUM_ENTRIES_SHIFT; 10626ad8c632SSudarsana Reddy Kalluru 10636ad8c632SSudarsana Reddy Kalluru for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { 10646ad8c632SSudarsana Reddy Kalluru entry = &p_app->app_pri_tbl[i].entry; 106559bcb797SSudarsana Reddy Kalluru if (ieee) { 106659bcb797SSudarsana Reddy Kalluru *entry &= ~DCBX_APP_SF_IEEE_MASK; 106759bcb797SSudarsana Reddy Kalluru switch (p_params->app_entry[i].sf_ieee) { 106859bcb797SSudarsana Reddy Kalluru case QED_DCBX_SF_IEEE_ETHTYPE: 106959bcb797SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE << 107059bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_SHIFT); 107159bcb797SSudarsana Reddy Kalluru break; 107259bcb797SSudarsana Reddy Kalluru case QED_DCBX_SF_IEEE_TCP_PORT: 107359bcb797SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT << 107459bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_SHIFT); 107559bcb797SSudarsana Reddy Kalluru break; 107659bcb797SSudarsana Reddy Kalluru case QED_DCBX_SF_IEEE_UDP_PORT: 107759bcb797SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT << 107859bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_SHIFT); 107959bcb797SSudarsana Reddy Kalluru break; 108059bcb797SSudarsana Reddy Kalluru case QED_DCBX_SF_IEEE_TCP_UDP_PORT: 108159bcb797SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT << 108259bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_IEEE_SHIFT); 108359bcb797SSudarsana Reddy Kalluru break; 108459bcb797SSudarsana Reddy Kalluru } 108559bcb797SSudarsana Reddy Kalluru } else { 10866ad8c632SSudarsana Reddy Kalluru *entry &= ~DCBX_APP_SF_MASK; 10876ad8c632SSudarsana Reddy Kalluru if (p_params->app_entry[i].ethtype) 10886ad8c632SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_ETHTYPE << 10896ad8c632SSudarsana Reddy Kalluru DCBX_APP_SF_SHIFT); 10906ad8c632SSudarsana Reddy Kalluru else 109159bcb797SSudarsana Reddy Kalluru *entry |= ((u32)DCBX_APP_SF_PORT << 109259bcb797SSudarsana Reddy Kalluru DCBX_APP_SF_SHIFT); 109359bcb797SSudarsana Reddy Kalluru } 109459bcb797SSudarsana Reddy Kalluru 10956ad8c632SSudarsana Reddy Kalluru *entry &= ~DCBX_APP_PROTOCOL_ID_MASK; 10966ad8c632SSudarsana Reddy Kalluru *entry |= ((u32)p_params->app_entry[i].proto_id << 10976ad8c632SSudarsana Reddy Kalluru DCBX_APP_PROTOCOL_ID_SHIFT); 10986ad8c632SSudarsana Reddy Kalluru *entry &= ~DCBX_APP_PRI_MAP_MASK; 10996ad8c632SSudarsana Reddy Kalluru *entry |= ((u32)(p_params->app_entry[i].prio) << 11006ad8c632SSudarsana Reddy Kalluru DCBX_APP_PRI_MAP_SHIFT); 11016ad8c632SSudarsana Reddy Kalluru } 11026ad8c632SSudarsana Reddy Kalluru } 11036ad8c632SSudarsana Reddy Kalluru 11046ad8c632SSudarsana Reddy Kalluru static void 11056ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_local_params(struct qed_hwfn *p_hwfn, 11066ad8c632SSudarsana Reddy Kalluru struct dcbx_local_params *local_admin, 11076ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_set *params) 11086ad8c632SSudarsana Reddy Kalluru { 110959bcb797SSudarsana Reddy Kalluru bool ieee = false; 111059bcb797SSudarsana Reddy Kalluru 11116ad8c632SSudarsana Reddy Kalluru local_admin->flags = 0; 11126ad8c632SSudarsana Reddy Kalluru memcpy(&local_admin->features, 11136ad8c632SSudarsana Reddy Kalluru &p_hwfn->p_dcbx_info->operational.features, 11146ad8c632SSudarsana Reddy Kalluru sizeof(local_admin->features)); 11156ad8c632SSudarsana Reddy Kalluru 111659bcb797SSudarsana Reddy Kalluru if (params->enabled) { 11176ad8c632SSudarsana Reddy Kalluru local_admin->config = params->ver_num; 111859bcb797SSudarsana Reddy Kalluru ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE); 111959bcb797SSudarsana Reddy Kalluru } else { 11206ad8c632SSudarsana Reddy Kalluru local_admin->config = DCBX_CONFIG_VERSION_DISABLED; 112159bcb797SSudarsana Reddy Kalluru } 11226ad8c632SSudarsana Reddy Kalluru 11236ad8c632SSudarsana Reddy Kalluru if (params->override_flags & QED_DCBX_OVERRIDE_PFC_CFG) 11246ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc, 11256ad8c632SSudarsana Reddy Kalluru ¶ms->config.params); 11266ad8c632SSudarsana Reddy Kalluru 11276ad8c632SSudarsana Reddy Kalluru if (params->override_flags & QED_DCBX_OVERRIDE_ETS_CFG) 11286ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets, 11296ad8c632SSudarsana Reddy Kalluru ¶ms->config.params); 11306ad8c632SSudarsana Reddy Kalluru 11316ad8c632SSudarsana Reddy Kalluru if (params->override_flags & QED_DCBX_OVERRIDE_APP_CFG) 11326ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_app_data(p_hwfn, &local_admin->features.app, 113359bcb797SSudarsana Reddy Kalluru ¶ms->config.params, ieee); 11346ad8c632SSudarsana Reddy Kalluru } 11356ad8c632SSudarsana Reddy Kalluru 11366ad8c632SSudarsana Reddy Kalluru int qed_dcbx_config_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 11376ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_set *params, bool hw_commit) 11386ad8c632SSudarsana Reddy Kalluru { 11396ad8c632SSudarsana Reddy Kalluru struct dcbx_local_params local_admin; 11406ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_mib_meta_data data; 11416ad8c632SSudarsana Reddy Kalluru u32 resp = 0, param = 0; 11426ad8c632SSudarsana Reddy Kalluru int rc = 0; 11436ad8c632SSudarsana Reddy Kalluru 11446ad8c632SSudarsana Reddy Kalluru if (!hw_commit) { 11456ad8c632SSudarsana Reddy Kalluru memcpy(&p_hwfn->p_dcbx_info->set, params, 11466ad8c632SSudarsana Reddy Kalluru sizeof(struct qed_dcbx_set)); 11476ad8c632SSudarsana Reddy Kalluru return 0; 11486ad8c632SSudarsana Reddy Kalluru } 11496ad8c632SSudarsana Reddy Kalluru 11506ad8c632SSudarsana Reddy Kalluru /* clear set-parmas cache */ 11516ad8c632SSudarsana Reddy Kalluru memset(&p_hwfn->p_dcbx_info->set, 0, sizeof(p_hwfn->p_dcbx_info->set)); 11526ad8c632SSudarsana Reddy Kalluru 11536ad8c632SSudarsana Reddy Kalluru memset(&local_admin, 0, sizeof(local_admin)); 11546ad8c632SSudarsana Reddy Kalluru qed_dcbx_set_local_params(p_hwfn, &local_admin, params); 11556ad8c632SSudarsana Reddy Kalluru 11566ad8c632SSudarsana Reddy Kalluru data.addr = p_hwfn->mcp_info->port_addr + 11576ad8c632SSudarsana Reddy Kalluru offsetof(struct public_port, local_admin_dcbx_mib); 11586ad8c632SSudarsana Reddy Kalluru data.local_admin = &local_admin; 11596ad8c632SSudarsana Reddy Kalluru data.size = sizeof(struct dcbx_local_params); 11606ad8c632SSudarsana Reddy Kalluru qed_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size); 11616ad8c632SSudarsana Reddy Kalluru 11626ad8c632SSudarsana Reddy Kalluru rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX, 11636ad8c632SSudarsana Reddy Kalluru 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, ¶m); 11646ad8c632SSudarsana Reddy Kalluru if (rc) 11656ad8c632SSudarsana Reddy Kalluru DP_NOTICE(p_hwfn, "Failed to send DCBX update request\n"); 11666ad8c632SSudarsana Reddy Kalluru 11676ad8c632SSudarsana Reddy Kalluru return rc; 11686ad8c632SSudarsana Reddy Kalluru } 11696ad8c632SSudarsana Reddy Kalluru 11706ad8c632SSudarsana Reddy Kalluru int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, 11716ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_set *params) 11726ad8c632SSudarsana Reddy Kalluru { 11736ad8c632SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 11746ad8c632SSudarsana Reddy Kalluru int rc; 11756ad8c632SSudarsana Reddy Kalluru 11766ad8c632SSudarsana Reddy Kalluru if (p_hwfn->p_dcbx_info->set.config.valid) { 11776ad8c632SSudarsana Reddy Kalluru memcpy(params, &p_hwfn->p_dcbx_info->set, 11786ad8c632SSudarsana Reddy Kalluru sizeof(struct qed_dcbx_set)); 11796ad8c632SSudarsana Reddy Kalluru return 0; 11806ad8c632SSudarsana Reddy Kalluru } 11816ad8c632SSudarsana Reddy Kalluru 11826ad8c632SSudarsana Reddy Kalluru dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_KERNEL); 11836ad8c632SSudarsana Reddy Kalluru if (!dcbx_info) { 11846ad8c632SSudarsana Reddy Kalluru DP_ERR(p_hwfn, "Failed to allocate struct qed_dcbx_info\n"); 11856ad8c632SSudarsana Reddy Kalluru return -ENOMEM; 11866ad8c632SSudarsana Reddy Kalluru } 11876ad8c632SSudarsana Reddy Kalluru 11886ad8c632SSudarsana Reddy Kalluru rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB); 11896ad8c632SSudarsana Reddy Kalluru if (rc) { 11906ad8c632SSudarsana Reddy Kalluru kfree(dcbx_info); 11916ad8c632SSudarsana Reddy Kalluru return rc; 11926ad8c632SSudarsana Reddy Kalluru } 11936ad8c632SSudarsana Reddy Kalluru 11946ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.override_flags = 0; 11956ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED; 11966ad8c632SSudarsana Reddy Kalluru if (dcbx_info->operational.cee) 11976ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE; 11986ad8c632SSudarsana Reddy Kalluru if (dcbx_info->operational.ieee) 11996ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 12006ad8c632SSudarsana Reddy Kalluru 12016ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; 12026ad8c632SSudarsana Reddy Kalluru memcpy(&p_hwfn->p_dcbx_info->set.config.params, 12036ad8c632SSudarsana Reddy Kalluru &dcbx_info->operational.params, 12046ad8c632SSudarsana Reddy Kalluru sizeof(struct qed_dcbx_admin_params)); 12056ad8c632SSudarsana Reddy Kalluru p_hwfn->p_dcbx_info->set.config.valid = true; 12066ad8c632SSudarsana Reddy Kalluru 12076ad8c632SSudarsana Reddy Kalluru memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); 12086ad8c632SSudarsana Reddy Kalluru 12096ad8c632SSudarsana Reddy Kalluru kfree(dcbx_info); 12106ad8c632SSudarsana Reddy Kalluru 12116ad8c632SSudarsana Reddy Kalluru return 0; 12126ad8c632SSudarsana Reddy Kalluru } 1213a1d8d8a5SSudarsana Reddy Kalluru 1214a1d8d8a5SSudarsana Reddy Kalluru static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, 1215a1d8d8a5SSudarsana Reddy Kalluru enum qed_mib_read_type type) 1216a1d8d8a5SSudarsana Reddy Kalluru { 1217a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1218a1d8d8a5SSudarsana Reddy Kalluru 1219a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = kmalloc(sizeof(*dcbx_info), GFP_KERNEL); 1220a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) { 1221a1d8d8a5SSudarsana Reddy Kalluru DP_ERR(hwfn->cdev, "Failed to allocate memory for dcbx_info\n"); 1222a1d8d8a5SSudarsana Reddy Kalluru return NULL; 1223a1d8d8a5SSudarsana Reddy Kalluru } 1224a1d8d8a5SSudarsana Reddy Kalluru 1225a1d8d8a5SSudarsana Reddy Kalluru if (qed_dcbx_query_params(hwfn, dcbx_info, type)) { 1226a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1227a1d8d8a5SSudarsana Reddy Kalluru return NULL; 1228a1d8d8a5SSudarsana Reddy Kalluru } 1229a1d8d8a5SSudarsana Reddy Kalluru 1230a1d8d8a5SSudarsana Reddy Kalluru if ((type == QED_DCBX_OPERATIONAL_MIB) && 1231a1d8d8a5SSudarsana Reddy Kalluru !dcbx_info->operational.enabled) { 1232a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational\n"); 1233a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1234a1d8d8a5SSudarsana Reddy Kalluru return NULL; 1235a1d8d8a5SSudarsana Reddy Kalluru } 1236a1d8d8a5SSudarsana Reddy Kalluru 1237a1d8d8a5SSudarsana Reddy Kalluru return dcbx_info; 1238a1d8d8a5SSudarsana Reddy Kalluru } 1239a1d8d8a5SSudarsana Reddy Kalluru 1240a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_getstate(struct qed_dev *cdev) 1241a1d8d8a5SSudarsana Reddy Kalluru { 1242a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1243a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1244a1d8d8a5SSudarsana Reddy Kalluru bool enabled; 1245a1d8d8a5SSudarsana Reddy Kalluru 1246a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1247a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1248a1d8d8a5SSudarsana Reddy Kalluru return 0; 1249a1d8d8a5SSudarsana Reddy Kalluru 1250a1d8d8a5SSudarsana Reddy Kalluru enabled = dcbx_info->operational.enabled; 1251a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", enabled); 1252a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1253a1d8d8a5SSudarsana Reddy Kalluru 1254a1d8d8a5SSudarsana Reddy Kalluru return enabled; 1255a1d8d8a5SSudarsana Reddy Kalluru } 1256a1d8d8a5SSudarsana Reddy Kalluru 1257a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_setstate(struct qed_dev *cdev, u8 state) 1258a1d8d8a5SSudarsana Reddy Kalluru { 1259a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1260a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1261a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1262a1d8d8a5SSudarsana Reddy Kalluru int rc; 1263a1d8d8a5SSudarsana Reddy Kalluru 1264a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", state); 1265a1d8d8a5SSudarsana Reddy Kalluru 1266a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1267a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1268a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1269a1d8d8a5SSudarsana Reddy Kalluru return 1; 1270a1d8d8a5SSudarsana Reddy Kalluru 1271a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.enabled = !!state; 1272a1d8d8a5SSudarsana Reddy Kalluru 1273a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1274a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1275a1d8d8a5SSudarsana Reddy Kalluru return 1; 1276a1d8d8a5SSudarsana Reddy Kalluru 1277a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1278a1d8d8a5SSudarsana Reddy Kalluru 1279a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1280a1d8d8a5SSudarsana Reddy Kalluru 1281a1d8d8a5SSudarsana Reddy Kalluru return rc ? 1 : 0; 1282a1d8d8a5SSudarsana Reddy Kalluru } 1283a1d8d8a5SSudarsana Reddy Kalluru 1284a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_getpgtccfgtx(struct qed_dev *cdev, int tc, u8 *prio_type, 1285a1d8d8a5SSudarsana Reddy Kalluru u8 *pgid, u8 *bw_pct, u8 *up_map) 1286a1d8d8a5SSudarsana Reddy Kalluru { 1287a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1288a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1289a1d8d8a5SSudarsana Reddy Kalluru 1290a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "tc = %d\n", tc); 1291a1d8d8a5SSudarsana Reddy Kalluru *prio_type = *pgid = *bw_pct = *up_map = 0; 1292a1d8d8a5SSudarsana Reddy Kalluru if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 1293a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid tc %d\n", tc); 1294a1d8d8a5SSudarsana Reddy Kalluru return; 1295a1d8d8a5SSudarsana Reddy Kalluru } 1296a1d8d8a5SSudarsana Reddy Kalluru 1297a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1298a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1299a1d8d8a5SSudarsana Reddy Kalluru return; 1300a1d8d8a5SSudarsana Reddy Kalluru 1301a1d8d8a5SSudarsana Reddy Kalluru *pgid = dcbx_info->operational.params.ets_pri_tc_tbl[tc]; 1302a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1303a1d8d8a5SSudarsana Reddy Kalluru } 1304a1d8d8a5SSudarsana Reddy Kalluru 1305a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 *bw_pct) 1306a1d8d8a5SSudarsana Reddy Kalluru { 1307a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1308a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1309a1d8d8a5SSudarsana Reddy Kalluru 1310a1d8d8a5SSudarsana Reddy Kalluru *bw_pct = 0; 1311a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d\n", pgid); 1312a1d8d8a5SSudarsana Reddy Kalluru if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 1313a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 1314a1d8d8a5SSudarsana Reddy Kalluru return; 1315a1d8d8a5SSudarsana Reddy Kalluru } 1316a1d8d8a5SSudarsana Reddy Kalluru 1317a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1318a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1319a1d8d8a5SSudarsana Reddy Kalluru return; 1320a1d8d8a5SSudarsana Reddy Kalluru 1321a1d8d8a5SSudarsana Reddy Kalluru *bw_pct = dcbx_info->operational.params.ets_tc_bw_tbl[pgid]; 1322a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "bw_pct = %d\n", *bw_pct); 1323a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1324a1d8d8a5SSudarsana Reddy Kalluru } 1325a1d8d8a5SSudarsana Reddy Kalluru 1326a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_getpgtccfgrx(struct qed_dev *cdev, int tc, u8 *prio, 1327a1d8d8a5SSudarsana Reddy Kalluru u8 *bwg_id, u8 *bw_pct, u8 *up_map) 1328a1d8d8a5SSudarsana Reddy Kalluru { 1329a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1330a1d8d8a5SSudarsana Reddy Kalluru *prio = *bwg_id = *bw_pct = *up_map = 0; 1331a1d8d8a5SSudarsana Reddy Kalluru } 1332a1d8d8a5SSudarsana Reddy Kalluru 1333a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev *cdev, 1334a1d8d8a5SSudarsana Reddy Kalluru int bwg_id, u8 *bw_pct) 1335a1d8d8a5SSudarsana Reddy Kalluru { 1336a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1337a1d8d8a5SSudarsana Reddy Kalluru *bw_pct = 0; 1338a1d8d8a5SSudarsana Reddy Kalluru } 1339a1d8d8a5SSudarsana Reddy Kalluru 1340a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_getpfccfg(struct qed_dev *cdev, 1341a1d8d8a5SSudarsana Reddy Kalluru int priority, u8 *setting) 1342a1d8d8a5SSudarsana Reddy Kalluru { 1343a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1344a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1345a1d8d8a5SSudarsana Reddy Kalluru 1346a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d\n", priority); 1347a1d8d8a5SSudarsana Reddy Kalluru if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 1348a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid priority %d\n", priority); 1349a1d8d8a5SSudarsana Reddy Kalluru return; 1350a1d8d8a5SSudarsana Reddy Kalluru } 1351a1d8d8a5SSudarsana Reddy Kalluru 1352a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1353a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1354a1d8d8a5SSudarsana Reddy Kalluru return; 1355a1d8d8a5SSudarsana Reddy Kalluru 1356a1d8d8a5SSudarsana Reddy Kalluru *setting = dcbx_info->operational.params.pfc.prio[priority]; 1357a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "setting = %d\n", *setting); 1358a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1359a1d8d8a5SSudarsana Reddy Kalluru } 1360a1d8d8a5SSudarsana Reddy Kalluru 1361a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpfccfg(struct qed_dev *cdev, int priority, u8 setting) 1362a1d8d8a5SSudarsana Reddy Kalluru { 1363a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1364a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1365a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1366a1d8d8a5SSudarsana Reddy Kalluru int rc; 1367a1d8d8a5SSudarsana Reddy Kalluru 1368a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d setting = %d\n", 1369a1d8d8a5SSudarsana Reddy Kalluru priority, setting); 1370a1d8d8a5SSudarsana Reddy Kalluru if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) { 1371a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid priority %d\n", priority); 1372a1d8d8a5SSudarsana Reddy Kalluru return; 1373a1d8d8a5SSudarsana Reddy Kalluru } 1374a1d8d8a5SSudarsana Reddy Kalluru 1375a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1376a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1377a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1378a1d8d8a5SSudarsana Reddy Kalluru return; 1379a1d8d8a5SSudarsana Reddy Kalluru 1380a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1381a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.prio[priority] = !!setting; 1382a1d8d8a5SSudarsana Reddy Kalluru 1383a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1384a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1385a1d8d8a5SSudarsana Reddy Kalluru return; 1386a1d8d8a5SSudarsana Reddy Kalluru 1387a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1388a1d8d8a5SSudarsana Reddy Kalluru 1389a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1390a1d8d8a5SSudarsana Reddy Kalluru } 1391a1d8d8a5SSudarsana Reddy Kalluru 1392a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap) 1393a1d8d8a5SSudarsana Reddy Kalluru { 1394a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1395a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1396a1d8d8a5SSudarsana Reddy Kalluru int rc = 0; 1397a1d8d8a5SSudarsana Reddy Kalluru 1398a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "capid = %d\n", capid); 1399a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1400a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1401a1d8d8a5SSudarsana Reddy Kalluru return 1; 1402a1d8d8a5SSudarsana Reddy Kalluru 1403a1d8d8a5SSudarsana Reddy Kalluru switch (capid) { 1404a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_PG: 1405a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_PFC: 1406a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_UP2TC: 1407a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_GSP: 1408a1d8d8a5SSudarsana Reddy Kalluru *cap = true; 1409a1d8d8a5SSudarsana Reddy Kalluru break; 1410a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_PG_TCS: 1411a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_PFC_TCS: 1412a1d8d8a5SSudarsana Reddy Kalluru *cap = 0x80; 1413a1d8d8a5SSudarsana Reddy Kalluru break; 1414a1d8d8a5SSudarsana Reddy Kalluru case DCB_CAP_ATTR_DCBX: 1415a1d8d8a5SSudarsana Reddy Kalluru *cap = (DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE | 1416a1d8d8a5SSudarsana Reddy Kalluru DCB_CAP_DCBX_VER_IEEE); 1417a1d8d8a5SSudarsana Reddy Kalluru break; 1418a1d8d8a5SSudarsana Reddy Kalluru default: 1419a1d8d8a5SSudarsana Reddy Kalluru *cap = false; 1420a1d8d8a5SSudarsana Reddy Kalluru rc = 1; 1421a1d8d8a5SSudarsana Reddy Kalluru } 1422a1d8d8a5SSudarsana Reddy Kalluru 1423a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "id = %d caps = %d\n", capid, *cap); 1424a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1425a1d8d8a5SSudarsana Reddy Kalluru 1426a1d8d8a5SSudarsana Reddy Kalluru return rc; 1427a1d8d8a5SSudarsana Reddy Kalluru } 1428a1d8d8a5SSudarsana Reddy Kalluru 1429a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_getnumtcs(struct qed_dev *cdev, int tcid, u8 *num) 1430a1d8d8a5SSudarsana Reddy Kalluru { 1431a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1432a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1433a1d8d8a5SSudarsana Reddy Kalluru int rc = 0; 1434a1d8d8a5SSudarsana Reddy Kalluru 1435a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d\n", tcid); 1436a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1437a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1438a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1439a1d8d8a5SSudarsana Reddy Kalluru 1440a1d8d8a5SSudarsana Reddy Kalluru switch (tcid) { 1441a1d8d8a5SSudarsana Reddy Kalluru case DCB_NUMTCS_ATTR_PG: 1442a1d8d8a5SSudarsana Reddy Kalluru *num = dcbx_info->operational.params.max_ets_tc; 1443a1d8d8a5SSudarsana Reddy Kalluru break; 1444a1d8d8a5SSudarsana Reddy Kalluru case DCB_NUMTCS_ATTR_PFC: 1445a1d8d8a5SSudarsana Reddy Kalluru *num = dcbx_info->operational.params.pfc.max_tc; 1446a1d8d8a5SSudarsana Reddy Kalluru break; 1447a1d8d8a5SSudarsana Reddy Kalluru default: 1448a1d8d8a5SSudarsana Reddy Kalluru rc = -EINVAL; 1449a1d8d8a5SSudarsana Reddy Kalluru } 1450a1d8d8a5SSudarsana Reddy Kalluru 1451a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1452a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "numtcs = %d\n", *num); 1453a1d8d8a5SSudarsana Reddy Kalluru 1454a1d8d8a5SSudarsana Reddy Kalluru return rc; 1455a1d8d8a5SSudarsana Reddy Kalluru } 1456a1d8d8a5SSudarsana Reddy Kalluru 1457a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_getpfcstate(struct qed_dev *cdev) 1458a1d8d8a5SSudarsana Reddy Kalluru { 1459a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1460a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1461a1d8d8a5SSudarsana Reddy Kalluru bool enabled; 1462a1d8d8a5SSudarsana Reddy Kalluru 1463a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1464a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1465a1d8d8a5SSudarsana Reddy Kalluru return 0; 1466a1d8d8a5SSudarsana Reddy Kalluru 1467a1d8d8a5SSudarsana Reddy Kalluru enabled = dcbx_info->operational.params.pfc.enabled; 1468a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d\n", enabled); 1469a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1470a1d8d8a5SSudarsana Reddy Kalluru 1471a1d8d8a5SSudarsana Reddy Kalluru return enabled; 1472a1d8d8a5SSudarsana Reddy Kalluru } 1473a1d8d8a5SSudarsana Reddy Kalluru 1474a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev) 1475a1d8d8a5SSudarsana Reddy Kalluru { 1476a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1477a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1478a1d8d8a5SSudarsana Reddy Kalluru u8 mode = 0; 1479a1d8d8a5SSudarsana Reddy Kalluru 1480a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1481a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1482a1d8d8a5SSudarsana Reddy Kalluru return 0; 1483a1d8d8a5SSudarsana Reddy Kalluru 1484a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.enabled) 1485a1d8d8a5SSudarsana Reddy Kalluru mode |= DCB_CAP_DCBX_LLD_MANAGED; 1486a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.ieee) 1487a1d8d8a5SSudarsana Reddy Kalluru mode |= DCB_CAP_DCBX_VER_IEEE; 1488a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.cee) 1489a1d8d8a5SSudarsana Reddy Kalluru mode |= DCB_CAP_DCBX_VER_CEE; 1490a1d8d8a5SSudarsana Reddy Kalluru 1491a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode); 1492a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1493a1d8d8a5SSudarsana Reddy Kalluru 1494a1d8d8a5SSudarsana Reddy Kalluru return mode; 1495a1d8d8a5SSudarsana Reddy Kalluru } 1496a1d8d8a5SSudarsana Reddy Kalluru 1497a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpgtccfgtx(struct qed_dev *cdev, 1498a1d8d8a5SSudarsana Reddy Kalluru int tc, 1499a1d8d8a5SSudarsana Reddy Kalluru u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 1500a1d8d8a5SSudarsana Reddy Kalluru { 1501a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1502a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1503a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1504a1d8d8a5SSudarsana Reddy Kalluru int rc; 1505a1d8d8a5SSudarsana Reddy Kalluru 1506a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, 1507a1d8d8a5SSudarsana Reddy Kalluru "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n", 1508a1d8d8a5SSudarsana Reddy Kalluru tc, pri_type, pgid, bw_pct, up_map); 1509a1d8d8a5SSudarsana Reddy Kalluru 1510a1d8d8a5SSudarsana Reddy Kalluru if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) { 1511a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid tc %d\n", tc); 1512a1d8d8a5SSudarsana Reddy Kalluru return; 1513a1d8d8a5SSudarsana Reddy Kalluru } 1514a1d8d8a5SSudarsana Reddy Kalluru 1515a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1516a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1517a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1518a1d8d8a5SSudarsana Reddy Kalluru return; 1519a1d8d8a5SSudarsana Reddy Kalluru 1520a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1521a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_pri_tc_tbl[tc] = pgid; 1522a1d8d8a5SSudarsana Reddy Kalluru 1523a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1524a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1525a1d8d8a5SSudarsana Reddy Kalluru return; 1526a1d8d8a5SSudarsana Reddy Kalluru 1527a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1528a1d8d8a5SSudarsana Reddy Kalluru 1529a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1530a1d8d8a5SSudarsana Reddy Kalluru } 1531a1d8d8a5SSudarsana Reddy Kalluru 1532a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpgtccfgrx(struct qed_dev *cdev, int prio, 1533a1d8d8a5SSudarsana Reddy Kalluru u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map) 1534a1d8d8a5SSudarsana Reddy Kalluru { 1535a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1536a1d8d8a5SSudarsana Reddy Kalluru } 1537a1d8d8a5SSudarsana Reddy Kalluru 1538a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 bw_pct) 1539a1d8d8a5SSudarsana Reddy Kalluru { 1540a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1541a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1542a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1543a1d8d8a5SSudarsana Reddy Kalluru int rc; 1544a1d8d8a5SSudarsana Reddy Kalluru 1545a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d bw_pct = %d\n", pgid, bw_pct); 1546a1d8d8a5SSudarsana Reddy Kalluru if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) { 1547a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid pgid %d\n", pgid); 1548a1d8d8a5SSudarsana Reddy Kalluru return; 1549a1d8d8a5SSudarsana Reddy Kalluru } 1550a1d8d8a5SSudarsana Reddy Kalluru 1551a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1552a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1553a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1554a1d8d8a5SSudarsana Reddy Kalluru return; 1555a1d8d8a5SSudarsana Reddy Kalluru 1556a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1557a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_tc_bw_tbl[pgid] = bw_pct; 1558a1d8d8a5SSudarsana Reddy Kalluru 1559a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1560a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1561a1d8d8a5SSudarsana Reddy Kalluru return; 1562a1d8d8a5SSudarsana Reddy Kalluru 1563a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1564a1d8d8a5SSudarsana Reddy Kalluru 1565a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1566a1d8d8a5SSudarsana Reddy Kalluru } 1567a1d8d8a5SSudarsana Reddy Kalluru 1568a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev *cdev, int pgid, u8 bw_pct) 1569a1d8d8a5SSudarsana Reddy Kalluru { 1570a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n"); 1571a1d8d8a5SSudarsana Reddy Kalluru } 1572a1d8d8a5SSudarsana Reddy Kalluru 1573a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_setall(struct qed_dev *cdev) 1574a1d8d8a5SSudarsana Reddy Kalluru { 1575a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1576a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1577a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1578a1d8d8a5SSudarsana Reddy Kalluru int rc; 1579a1d8d8a5SSudarsana Reddy Kalluru 1580a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1581a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1582a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1583a1d8d8a5SSudarsana Reddy Kalluru return 1; 1584a1d8d8a5SSudarsana Reddy Kalluru 1585a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1586a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1587a1d8d8a5SSudarsana Reddy Kalluru return 1; 1588a1d8d8a5SSudarsana Reddy Kalluru 1589a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 1); 1590a1d8d8a5SSudarsana Reddy Kalluru 1591a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1592a1d8d8a5SSudarsana Reddy Kalluru 1593a1d8d8a5SSudarsana Reddy Kalluru return rc; 1594a1d8d8a5SSudarsana Reddy Kalluru } 1595a1d8d8a5SSudarsana Reddy Kalluru 1596a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_setnumtcs(struct qed_dev *cdev, int tcid, u8 num) 1597a1d8d8a5SSudarsana Reddy Kalluru { 1598a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1599a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1600a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1601a1d8d8a5SSudarsana Reddy Kalluru int rc; 1602a1d8d8a5SSudarsana Reddy Kalluru 1603a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d num = %d\n", tcid, num); 1604a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1605a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1606a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1607a1d8d8a5SSudarsana Reddy Kalluru return 1; 1608a1d8d8a5SSudarsana Reddy Kalluru 1609a1d8d8a5SSudarsana Reddy Kalluru switch (tcid) { 1610a1d8d8a5SSudarsana Reddy Kalluru case DCB_NUMTCS_ATTR_PG: 1611a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1612a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.max_ets_tc = num; 1613a1d8d8a5SSudarsana Reddy Kalluru break; 1614a1d8d8a5SSudarsana Reddy Kalluru case DCB_NUMTCS_ATTR_PFC: 1615a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1616a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.max_tc = num; 1617a1d8d8a5SSudarsana Reddy Kalluru break; 1618a1d8d8a5SSudarsana Reddy Kalluru default: 1619a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid tcid %d\n", tcid); 1620a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1621a1d8d8a5SSudarsana Reddy Kalluru } 1622a1d8d8a5SSudarsana Reddy Kalluru 1623a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1624a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1625a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1626a1d8d8a5SSudarsana Reddy Kalluru 1627a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1628a1d8d8a5SSudarsana Reddy Kalluru 1629a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1630a1d8d8a5SSudarsana Reddy Kalluru 1631a1d8d8a5SSudarsana Reddy Kalluru return 0; 1632a1d8d8a5SSudarsana Reddy Kalluru } 1633a1d8d8a5SSudarsana Reddy Kalluru 1634a1d8d8a5SSudarsana Reddy Kalluru static void qed_dcbnl_setpfcstate(struct qed_dev *cdev, u8 state) 1635a1d8d8a5SSudarsana Reddy Kalluru { 1636a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1637a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1638a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1639a1d8d8a5SSudarsana Reddy Kalluru int rc; 1640a1d8d8a5SSudarsana Reddy Kalluru 1641a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "new state = %d\n", state); 1642a1d8d8a5SSudarsana Reddy Kalluru 1643a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1644a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1645a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1646a1d8d8a5SSudarsana Reddy Kalluru return; 1647a1d8d8a5SSudarsana Reddy Kalluru 1648a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1649a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.enabled = !!state; 1650a1d8d8a5SSudarsana Reddy Kalluru 1651a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1652a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1653a1d8d8a5SSudarsana Reddy Kalluru return; 1654a1d8d8a5SSudarsana Reddy Kalluru 1655a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1656a1d8d8a5SSudarsana Reddy Kalluru 1657a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1658a1d8d8a5SSudarsana Reddy Kalluru } 1659a1d8d8a5SSudarsana Reddy Kalluru 1660a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_getapp(struct qed_dev *cdev, u8 idtype, u16 idval) 1661a1d8d8a5SSudarsana Reddy Kalluru { 1662a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1663a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1664a1d8d8a5SSudarsana Reddy Kalluru struct qed_app_entry *entry; 1665a1d8d8a5SSudarsana Reddy Kalluru bool ethtype; 1666a1d8d8a5SSudarsana Reddy Kalluru u8 prio = 0; 1667a1d8d8a5SSudarsana Reddy Kalluru int i; 1668a1d8d8a5SSudarsana Reddy Kalluru 1669a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1670a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1671a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1672a1d8d8a5SSudarsana Reddy Kalluru 1673a1d8d8a5SSudarsana Reddy Kalluru ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 1674a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 1675a1d8d8a5SSudarsana Reddy Kalluru entry = &dcbx_info->operational.params.app_entry[i]; 1676a1d8d8a5SSudarsana Reddy Kalluru if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) { 1677a1d8d8a5SSudarsana Reddy Kalluru prio = entry->prio; 1678a1d8d8a5SSudarsana Reddy Kalluru break; 1679a1d8d8a5SSudarsana Reddy Kalluru } 1680a1d8d8a5SSudarsana Reddy Kalluru } 1681a1d8d8a5SSudarsana Reddy Kalluru 1682a1d8d8a5SSudarsana Reddy Kalluru if (i == QED_DCBX_MAX_APP_PROTOCOL) { 1683a1d8d8a5SSudarsana Reddy Kalluru DP_ERR(cdev, "App entry (%d, %d) not found\n", idtype, idval); 1684a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1685a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1686a1d8d8a5SSudarsana Reddy Kalluru } 1687a1d8d8a5SSudarsana Reddy Kalluru 1688a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1689a1d8d8a5SSudarsana Reddy Kalluru 1690a1d8d8a5SSudarsana Reddy Kalluru return prio; 1691a1d8d8a5SSudarsana Reddy Kalluru } 1692a1d8d8a5SSudarsana Reddy Kalluru 1693a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_setapp(struct qed_dev *cdev, 1694a1d8d8a5SSudarsana Reddy Kalluru u8 idtype, u16 idval, u8 pri_map) 1695a1d8d8a5SSudarsana Reddy Kalluru { 1696a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1697a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1698a1d8d8a5SSudarsana Reddy Kalluru struct qed_app_entry *entry; 1699a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1700a1d8d8a5SSudarsana Reddy Kalluru bool ethtype; 1701a1d8d8a5SSudarsana Reddy Kalluru int rc, i; 1702a1d8d8a5SSudarsana Reddy Kalluru 1703a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1704a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1705a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1706a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1707a1d8d8a5SSudarsana Reddy Kalluru 1708a1d8d8a5SSudarsana Reddy Kalluru ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE); 1709a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 1710a1d8d8a5SSudarsana Reddy Kalluru entry = &dcbx_set.config.params.app_entry[i]; 1711a1d8d8a5SSudarsana Reddy Kalluru if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) 1712a1d8d8a5SSudarsana Reddy Kalluru break; 1713a1d8d8a5SSudarsana Reddy Kalluru /* First empty slot */ 17141d7406ceSSudarsana Reddy Kalluru if (!entry->proto_id) { 17151d7406ceSSudarsana Reddy Kalluru dcbx_set.config.params.num_app_entries++; 1716a1d8d8a5SSudarsana Reddy Kalluru break; 1717a1d8d8a5SSudarsana Reddy Kalluru } 17181d7406ceSSudarsana Reddy Kalluru } 1719a1d8d8a5SSudarsana Reddy Kalluru 1720a1d8d8a5SSudarsana Reddy Kalluru if (i == QED_DCBX_MAX_APP_PROTOCOL) { 1721a1d8d8a5SSudarsana Reddy Kalluru DP_ERR(cdev, "App table is full\n"); 1722a1d8d8a5SSudarsana Reddy Kalluru return -EBUSY; 1723a1d8d8a5SSudarsana Reddy Kalluru } 1724a1d8d8a5SSudarsana Reddy Kalluru 1725a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 1726a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].ethtype = ethtype; 1727a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].proto_id = idval; 1728a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].prio = pri_map; 1729a1d8d8a5SSudarsana Reddy Kalluru 1730a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1731a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1732a1d8d8a5SSudarsana Reddy Kalluru return -EBUSY; 1733a1d8d8a5SSudarsana Reddy Kalluru 1734a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1735a1d8d8a5SSudarsana Reddy Kalluru 1736a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1737a1d8d8a5SSudarsana Reddy Kalluru 1738a1d8d8a5SSudarsana Reddy Kalluru return rc; 1739a1d8d8a5SSudarsana Reddy Kalluru } 1740a1d8d8a5SSudarsana Reddy Kalluru 1741a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_setdcbx(struct qed_dev *cdev, u8 mode) 1742a1d8d8a5SSudarsana Reddy Kalluru { 1743a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1744a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1745a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1746a1d8d8a5SSudarsana Reddy Kalluru int rc; 1747a1d8d8a5SSudarsana Reddy Kalluru 1748a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "new mode = %x\n", mode); 1749a1d8d8a5SSudarsana Reddy Kalluru 1750a1d8d8a5SSudarsana Reddy Kalluru if (!(mode & DCB_CAP_DCBX_VER_IEEE) && !(mode & DCB_CAP_DCBX_VER_CEE)) { 1751a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Allowed mode is cee, ieee or both\n"); 1752a1d8d8a5SSudarsana Reddy Kalluru return 1; 1753a1d8d8a5SSudarsana Reddy Kalluru } 1754a1d8d8a5SSudarsana Reddy Kalluru 1755a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1756a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1757a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1758a1d8d8a5SSudarsana Reddy Kalluru return 1; 1759a1d8d8a5SSudarsana Reddy Kalluru 1760a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.ver_num = 0; 1761a1d8d8a5SSudarsana Reddy Kalluru if (mode & DCB_CAP_DCBX_VER_CEE) { 1762a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.ver_num |= DCBX_CONFIG_VERSION_CEE; 1763a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.enabled = true; 1764a1d8d8a5SSudarsana Reddy Kalluru } 1765a1d8d8a5SSudarsana Reddy Kalluru 1766a1d8d8a5SSudarsana Reddy Kalluru if (mode & DCB_CAP_DCBX_VER_IEEE) { 1767a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.ver_num |= DCBX_CONFIG_VERSION_IEEE; 1768a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.enabled = true; 1769a1d8d8a5SSudarsana Reddy Kalluru } 1770a1d8d8a5SSudarsana Reddy Kalluru 1771a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1772a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1773a1d8d8a5SSudarsana Reddy Kalluru return 1; 1774a1d8d8a5SSudarsana Reddy Kalluru 1775a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1776a1d8d8a5SSudarsana Reddy Kalluru 1777a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1778a1d8d8a5SSudarsana Reddy Kalluru 1779a1d8d8a5SSudarsana Reddy Kalluru return 0; 1780a1d8d8a5SSudarsana Reddy Kalluru } 1781a1d8d8a5SSudarsana Reddy Kalluru 1782a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_getfeatcfg(struct qed_dev *cdev, int featid, u8 *flags) 1783a1d8d8a5SSudarsana Reddy Kalluru { 1784a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1785a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1786a1d8d8a5SSudarsana Reddy Kalluru 1787a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "Feature id = %d\n", featid); 1788a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1789a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1790a1d8d8a5SSudarsana Reddy Kalluru return 1; 1791a1d8d8a5SSudarsana Reddy Kalluru 1792a1d8d8a5SSudarsana Reddy Kalluru *flags = 0; 1793a1d8d8a5SSudarsana Reddy Kalluru switch (featid) { 1794a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_PG: 1795a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.params.ets_enabled) 1796a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ENABLE; 1797a1d8d8a5SSudarsana Reddy Kalluru else 1798a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ERROR; 1799a1d8d8a5SSudarsana Reddy Kalluru break; 1800a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_PFC: 1801a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.params.pfc.enabled) 1802a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ENABLE; 1803a1d8d8a5SSudarsana Reddy Kalluru else 1804a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ERROR; 1805a1d8d8a5SSudarsana Reddy Kalluru break; 1806a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_APP: 1807a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->operational.params.app_valid) 1808a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ENABLE; 1809a1d8d8a5SSudarsana Reddy Kalluru else 1810a1d8d8a5SSudarsana Reddy Kalluru *flags = DCB_FEATCFG_ERROR; 1811a1d8d8a5SSudarsana Reddy Kalluru break; 1812a1d8d8a5SSudarsana Reddy Kalluru default: 1813a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 1814a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1815a1d8d8a5SSudarsana Reddy Kalluru return 1; 1816a1d8d8a5SSudarsana Reddy Kalluru } 1817a1d8d8a5SSudarsana Reddy Kalluru 1818a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "flags = %d\n", *flags); 1819a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1820a1d8d8a5SSudarsana Reddy Kalluru 1821a1d8d8a5SSudarsana Reddy Kalluru return 0; 1822a1d8d8a5SSudarsana Reddy Kalluru } 1823a1d8d8a5SSudarsana Reddy Kalluru 1824a1d8d8a5SSudarsana Reddy Kalluru static u8 qed_dcbnl_setfeatcfg(struct qed_dev *cdev, int featid, u8 flags) 1825a1d8d8a5SSudarsana Reddy Kalluru { 1826a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1827a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 1828a1d8d8a5SSudarsana Reddy Kalluru bool enabled, willing; 1829a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 1830a1d8d8a5SSudarsana Reddy Kalluru int rc; 1831a1d8d8a5SSudarsana Reddy Kalluru 1832a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "featid = %d flags = %d\n", 1833a1d8d8a5SSudarsana Reddy Kalluru featid, flags); 1834a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 1835a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 1836a1d8d8a5SSudarsana Reddy Kalluru if (rc) 1837a1d8d8a5SSudarsana Reddy Kalluru return 1; 1838a1d8d8a5SSudarsana Reddy Kalluru 1839a1d8d8a5SSudarsana Reddy Kalluru enabled = !!(flags & DCB_FEATCFG_ENABLE); 1840a1d8d8a5SSudarsana Reddy Kalluru willing = !!(flags & DCB_FEATCFG_WILLING); 1841a1d8d8a5SSudarsana Reddy Kalluru switch (featid) { 1842a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_PG: 1843a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 1844a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_enabled = enabled; 1845a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_willing = willing; 1846a1d8d8a5SSudarsana Reddy Kalluru break; 1847a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_PFC: 1848a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 1849a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.enabled = enabled; 1850a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.willing = willing; 1851a1d8d8a5SSudarsana Reddy Kalluru break; 1852a1d8d8a5SSudarsana Reddy Kalluru case DCB_FEATCFG_ATTR_APP: 1853a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 1854a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_willing = willing; 1855a1d8d8a5SSudarsana Reddy Kalluru break; 1856a1d8d8a5SSudarsana Reddy Kalluru default: 1857a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid feature-ID %d\n", featid); 1858a1d8d8a5SSudarsana Reddy Kalluru return 1; 1859a1d8d8a5SSudarsana Reddy Kalluru } 1860a1d8d8a5SSudarsana Reddy Kalluru 1861a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 1862a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 1863a1d8d8a5SSudarsana Reddy Kalluru return 1; 1864a1d8d8a5SSudarsana Reddy Kalluru 1865a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 1866a1d8d8a5SSudarsana Reddy Kalluru 1867a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 1868a1d8d8a5SSudarsana Reddy Kalluru 1869a1d8d8a5SSudarsana Reddy Kalluru return 0; 1870a1d8d8a5SSudarsana Reddy Kalluru } 1871a1d8d8a5SSudarsana Reddy Kalluru 1872a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_peer_getappinfo(struct qed_dev *cdev, 1873a1d8d8a5SSudarsana Reddy Kalluru struct dcb_peer_app_info *info, 1874a1d8d8a5SSudarsana Reddy Kalluru u16 *app_count) 1875a1d8d8a5SSudarsana Reddy Kalluru { 1876a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1877a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1878a1d8d8a5SSudarsana Reddy Kalluru 1879a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1880a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1881a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1882a1d8d8a5SSudarsana Reddy Kalluru 1883a1d8d8a5SSudarsana Reddy Kalluru info->willing = dcbx_info->remote.params.app_willing; 1884a1d8d8a5SSudarsana Reddy Kalluru info->error = dcbx_info->remote.params.app_error; 1885a1d8d8a5SSudarsana Reddy Kalluru *app_count = dcbx_info->remote.params.num_app_entries; 1886a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1887a1d8d8a5SSudarsana Reddy Kalluru 1888a1d8d8a5SSudarsana Reddy Kalluru return 0; 1889a1d8d8a5SSudarsana Reddy Kalluru } 1890a1d8d8a5SSudarsana Reddy Kalluru 1891a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_peer_getapptable(struct qed_dev *cdev, 1892a1d8d8a5SSudarsana Reddy Kalluru struct dcb_app *table) 1893a1d8d8a5SSudarsana Reddy Kalluru { 1894a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1895a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1896a1d8d8a5SSudarsana Reddy Kalluru int i; 1897a1d8d8a5SSudarsana Reddy Kalluru 1898a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1899a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1900a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1901a1d8d8a5SSudarsana Reddy Kalluru 1902a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < dcbx_info->remote.params.num_app_entries; i++) { 1903a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->remote.params.app_entry[i].ethtype) 1904a1d8d8a5SSudarsana Reddy Kalluru table[i].selector = DCB_APP_IDTYPE_ETHTYPE; 1905a1d8d8a5SSudarsana Reddy Kalluru else 1906a1d8d8a5SSudarsana Reddy Kalluru table[i].selector = DCB_APP_IDTYPE_PORTNUM; 1907a1d8d8a5SSudarsana Reddy Kalluru table[i].priority = dcbx_info->remote.params.app_entry[i].prio; 1908a1d8d8a5SSudarsana Reddy Kalluru table[i].protocol = 1909a1d8d8a5SSudarsana Reddy Kalluru dcbx_info->remote.params.app_entry[i].proto_id; 1910a1d8d8a5SSudarsana Reddy Kalluru } 1911a1d8d8a5SSudarsana Reddy Kalluru 1912a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1913a1d8d8a5SSudarsana Reddy Kalluru 1914a1d8d8a5SSudarsana Reddy Kalluru return 0; 1915a1d8d8a5SSudarsana Reddy Kalluru } 1916a1d8d8a5SSudarsana Reddy Kalluru 1917a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_cee_peer_getpfc(struct qed_dev *cdev, struct cee_pfc *pfc) 1918a1d8d8a5SSudarsana Reddy Kalluru { 1919a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1920a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1921a1d8d8a5SSudarsana Reddy Kalluru int i; 1922a1d8d8a5SSudarsana Reddy Kalluru 1923a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1924a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1925a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1926a1d8d8a5SSudarsana Reddy Kalluru 1927a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 1928a1d8d8a5SSudarsana Reddy Kalluru if (dcbx_info->remote.params.pfc.prio[i]) 1929a1d8d8a5SSudarsana Reddy Kalluru pfc->pfc_en |= BIT(i); 1930a1d8d8a5SSudarsana Reddy Kalluru 1931a1d8d8a5SSudarsana Reddy Kalluru pfc->tcs_supported = dcbx_info->remote.params.pfc.max_tc; 1932a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d tcs_supported = %d\n", 1933a1d8d8a5SSudarsana Reddy Kalluru pfc->pfc_en, pfc->tcs_supported); 1934a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1935a1d8d8a5SSudarsana Reddy Kalluru 1936a1d8d8a5SSudarsana Reddy Kalluru return 0; 1937a1d8d8a5SSudarsana Reddy Kalluru } 1938a1d8d8a5SSudarsana Reddy Kalluru 1939a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_cee_peer_getpg(struct qed_dev *cdev, struct cee_pg *pg) 1940a1d8d8a5SSudarsana Reddy Kalluru { 1941a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1942a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1943a1d8d8a5SSudarsana Reddy Kalluru int i; 1944a1d8d8a5SSudarsana Reddy Kalluru 1945a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB); 1946a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1947a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1948a1d8d8a5SSudarsana Reddy Kalluru 1949a1d8d8a5SSudarsana Reddy Kalluru pg->willing = dcbx_info->remote.params.ets_willing; 1950a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) { 1951a1d8d8a5SSudarsana Reddy Kalluru pg->pg_bw[i] = dcbx_info->remote.params.ets_tc_bw_tbl[i]; 1952a1d8d8a5SSudarsana Reddy Kalluru pg->prio_pg[i] = dcbx_info->remote.params.ets_pri_tc_tbl[i]; 1953a1d8d8a5SSudarsana Reddy Kalluru } 1954a1d8d8a5SSudarsana Reddy Kalluru 1955a1d8d8a5SSudarsana Reddy Kalluru DP_VERBOSE(hwfn, QED_MSG_DCB, "willing = %d", pg->willing); 1956a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1957a1d8d8a5SSudarsana Reddy Kalluru 1958a1d8d8a5SSudarsana Reddy Kalluru return 0; 1959a1d8d8a5SSudarsana Reddy Kalluru } 1960a1d8d8a5SSudarsana Reddy Kalluru 1961a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_get_ieee_pfc(struct qed_dev *cdev, 1962a1d8d8a5SSudarsana Reddy Kalluru struct ieee_pfc *pfc, bool remote) 1963a1d8d8a5SSudarsana Reddy Kalluru { 1964a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 1965a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_params *params; 1966a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 1967a1d8d8a5SSudarsana Reddy Kalluru int rc, i; 1968a1d8d8a5SSudarsana Reddy Kalluru 1969a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 1970a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 1971a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1972a1d8d8a5SSudarsana Reddy Kalluru 1973a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 1974a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 1975a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1976a1d8d8a5SSudarsana Reddy Kalluru } 1977a1d8d8a5SSudarsana Reddy Kalluru 1978a1d8d8a5SSudarsana Reddy Kalluru if (remote) { 1979a1d8d8a5SSudarsana Reddy Kalluru memset(dcbx_info, 0, sizeof(*dcbx_info)); 1980a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_query_params(hwfn, dcbx_info, 1981a1d8d8a5SSudarsana Reddy Kalluru QED_DCBX_REMOTE_MIB); 1982a1d8d8a5SSudarsana Reddy Kalluru if (rc) { 1983a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1984a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 1985a1d8d8a5SSudarsana Reddy Kalluru } 1986a1d8d8a5SSudarsana Reddy Kalluru 1987a1d8d8a5SSudarsana Reddy Kalluru params = &dcbx_info->remote.params; 1988a1d8d8a5SSudarsana Reddy Kalluru } else { 1989a1d8d8a5SSudarsana Reddy Kalluru params = &dcbx_info->operational.params; 1990a1d8d8a5SSudarsana Reddy Kalluru } 1991a1d8d8a5SSudarsana Reddy Kalluru 1992a1d8d8a5SSudarsana Reddy Kalluru pfc->pfc_cap = params->pfc.max_tc; 1993a1d8d8a5SSudarsana Reddy Kalluru pfc->pfc_en = 0; 1994a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 1995a1d8d8a5SSudarsana Reddy Kalluru if (params->pfc.prio[i]) 1996a1d8d8a5SSudarsana Reddy Kalluru pfc->pfc_en |= BIT(i); 1997a1d8d8a5SSudarsana Reddy Kalluru 1998a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 1999a1d8d8a5SSudarsana Reddy Kalluru 2000a1d8d8a5SSudarsana Reddy Kalluru return 0; 2001a1d8d8a5SSudarsana Reddy Kalluru } 2002a1d8d8a5SSudarsana Reddy Kalluru 2003a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_ieee_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2004a1d8d8a5SSudarsana Reddy Kalluru { 2005a1d8d8a5SSudarsana Reddy Kalluru return qed_dcbnl_get_ieee_pfc(cdev, pfc, false); 2006a1d8d8a5SSudarsana Reddy Kalluru } 2007a1d8d8a5SSudarsana Reddy Kalluru 2008a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_ieee_setpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2009a1d8d8a5SSudarsana Reddy Kalluru { 2010a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2011a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 2012a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 2013a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 2014a1d8d8a5SSudarsana Reddy Kalluru int rc, i; 2015a1d8d8a5SSudarsana Reddy Kalluru 2016a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2017a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 2018a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2019a1d8d8a5SSudarsana Reddy Kalluru 2020a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 2021a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2022a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2023a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2024a1d8d8a5SSudarsana Reddy Kalluru } 2025a1d8d8a5SSudarsana Reddy Kalluru 2026a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2027a1d8d8a5SSudarsana Reddy Kalluru 2028a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 2029a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2030a1d8d8a5SSudarsana Reddy Kalluru if (rc) 2031a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2032a1d8d8a5SSudarsana Reddy Kalluru 2033a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG; 2034a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) 2035a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.pfc.prio[i] = !!(pfc->pfc_en & BIT(i)); 2036a1d8d8a5SSudarsana Reddy Kalluru 2037a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 2038a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 2039a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2040a1d8d8a5SSudarsana Reddy Kalluru 2041a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2042a1d8d8a5SSudarsana Reddy Kalluru 2043a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 2044a1d8d8a5SSudarsana Reddy Kalluru 2045a1d8d8a5SSudarsana Reddy Kalluru return rc; 2046a1d8d8a5SSudarsana Reddy Kalluru } 2047a1d8d8a5SSudarsana Reddy Kalluru 2048a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_get_ieee_ets(struct qed_dev *cdev, 2049a1d8d8a5SSudarsana Reddy Kalluru struct ieee_ets *ets, bool remote) 2050a1d8d8a5SSudarsana Reddy Kalluru { 2051a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2052a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 2053a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_params *params; 2054a1d8d8a5SSudarsana Reddy Kalluru int rc; 2055a1d8d8a5SSudarsana Reddy Kalluru 2056a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2057a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 2058a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2059a1d8d8a5SSudarsana Reddy Kalluru 2060a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 2061a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2062a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2063a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2064a1d8d8a5SSudarsana Reddy Kalluru } 2065a1d8d8a5SSudarsana Reddy Kalluru 2066a1d8d8a5SSudarsana Reddy Kalluru if (remote) { 2067a1d8d8a5SSudarsana Reddy Kalluru memset(dcbx_info, 0, sizeof(*dcbx_info)); 2068a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_query_params(hwfn, dcbx_info, 2069a1d8d8a5SSudarsana Reddy Kalluru QED_DCBX_REMOTE_MIB); 2070a1d8d8a5SSudarsana Reddy Kalluru if (rc) { 2071a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2072a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2073a1d8d8a5SSudarsana Reddy Kalluru } 2074a1d8d8a5SSudarsana Reddy Kalluru 2075a1d8d8a5SSudarsana Reddy Kalluru params = &dcbx_info->remote.params; 2076a1d8d8a5SSudarsana Reddy Kalluru } else { 2077a1d8d8a5SSudarsana Reddy Kalluru params = &dcbx_info->operational.params; 2078a1d8d8a5SSudarsana Reddy Kalluru } 2079a1d8d8a5SSudarsana Reddy Kalluru 2080a1d8d8a5SSudarsana Reddy Kalluru ets->ets_cap = params->max_ets_tc; 2081a1d8d8a5SSudarsana Reddy Kalluru ets->willing = params->ets_willing; 2082a1d8d8a5SSudarsana Reddy Kalluru ets->cbs = params->ets_cbs; 2083a1d8d8a5SSudarsana Reddy Kalluru memcpy(ets->tc_tx_bw, params->ets_tc_bw_tbl, sizeof(ets->tc_tx_bw)); 2084a1d8d8a5SSudarsana Reddy Kalluru memcpy(ets->tc_tsa, params->ets_tc_tsa_tbl, sizeof(ets->tc_tsa)); 2085a1d8d8a5SSudarsana Reddy Kalluru memcpy(ets->prio_tc, params->ets_pri_tc_tbl, sizeof(ets->prio_tc)); 2086a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2087a1d8d8a5SSudarsana Reddy Kalluru 2088a1d8d8a5SSudarsana Reddy Kalluru return 0; 2089a1d8d8a5SSudarsana Reddy Kalluru } 2090a1d8d8a5SSudarsana Reddy Kalluru 2091a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_ieee_getets(struct qed_dev *cdev, struct ieee_ets *ets) 2092a1d8d8a5SSudarsana Reddy Kalluru { 2093a1d8d8a5SSudarsana Reddy Kalluru return qed_dcbnl_get_ieee_ets(cdev, ets, false); 2094a1d8d8a5SSudarsana Reddy Kalluru } 2095a1d8d8a5SSudarsana Reddy Kalluru 2096a1d8d8a5SSudarsana Reddy Kalluru static int qed_dcbnl_ieee_setets(struct qed_dev *cdev, struct ieee_ets *ets) 2097a1d8d8a5SSudarsana Reddy Kalluru { 2098a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2099a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 2100a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 2101a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 2102a1d8d8a5SSudarsana Reddy Kalluru int rc; 2103a1d8d8a5SSudarsana Reddy Kalluru 2104a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2105a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 2106a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2107a1d8d8a5SSudarsana Reddy Kalluru 2108a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 2109a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2110a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2111a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2112a1d8d8a5SSudarsana Reddy Kalluru } 2113a1d8d8a5SSudarsana Reddy Kalluru 2114a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2115a1d8d8a5SSudarsana Reddy Kalluru 2116a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 2117a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2118a1d8d8a5SSudarsana Reddy Kalluru if (rc) 2119a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2120a1d8d8a5SSudarsana Reddy Kalluru 2121a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG; 2122a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.max_ets_tc = ets->ets_cap; 2123a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_willing = ets->willing; 2124a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.ets_cbs = ets->cbs; 2125a1d8d8a5SSudarsana Reddy Kalluru memcpy(dcbx_set.config.params.ets_tc_bw_tbl, ets->tc_tx_bw, 2126a1d8d8a5SSudarsana Reddy Kalluru sizeof(ets->tc_tx_bw)); 2127a1d8d8a5SSudarsana Reddy Kalluru memcpy(dcbx_set.config.params.ets_tc_tsa_tbl, ets->tc_tsa, 2128a1d8d8a5SSudarsana Reddy Kalluru sizeof(ets->tc_tsa)); 2129a1d8d8a5SSudarsana Reddy Kalluru memcpy(dcbx_set.config.params.ets_pri_tc_tbl, ets->prio_tc, 2130a1d8d8a5SSudarsana Reddy Kalluru sizeof(ets->prio_tc)); 2131a1d8d8a5SSudarsana Reddy Kalluru 2132a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 2133a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 2134a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2135a1d8d8a5SSudarsana Reddy Kalluru 2136a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2137a1d8d8a5SSudarsana Reddy Kalluru 2138a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 2139a1d8d8a5SSudarsana Reddy Kalluru 2140a1d8d8a5SSudarsana Reddy Kalluru return rc; 2141a1d8d8a5SSudarsana Reddy Kalluru } 2142a1d8d8a5SSudarsana Reddy Kalluru 2143a1d8d8a5SSudarsana Reddy Kalluru int qed_dcbnl_ieee_peer_getets(struct qed_dev *cdev, struct ieee_ets *ets) 2144a1d8d8a5SSudarsana Reddy Kalluru { 2145a1d8d8a5SSudarsana Reddy Kalluru return qed_dcbnl_get_ieee_ets(cdev, ets, true); 2146a1d8d8a5SSudarsana Reddy Kalluru } 2147a1d8d8a5SSudarsana Reddy Kalluru 2148a1d8d8a5SSudarsana Reddy Kalluru int qed_dcbnl_ieee_peer_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc) 2149a1d8d8a5SSudarsana Reddy Kalluru { 2150a1d8d8a5SSudarsana Reddy Kalluru return qed_dcbnl_get_ieee_pfc(cdev, pfc, true); 2151a1d8d8a5SSudarsana Reddy Kalluru } 2152a1d8d8a5SSudarsana Reddy Kalluru 2153a1d8d8a5SSudarsana Reddy Kalluru int qed_dcbnl_ieee_getapp(struct qed_dev *cdev, struct dcb_app *app) 2154a1d8d8a5SSudarsana Reddy Kalluru { 2155a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2156a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 2157a1d8d8a5SSudarsana Reddy Kalluru struct qed_app_entry *entry; 2158a1d8d8a5SSudarsana Reddy Kalluru bool ethtype; 2159a1d8d8a5SSudarsana Reddy Kalluru u8 prio = 0; 2160a1d8d8a5SSudarsana Reddy Kalluru int i; 2161a1d8d8a5SSudarsana Reddy Kalluru 2162a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2163a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 2164a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2165a1d8d8a5SSudarsana Reddy Kalluru 2166a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 2167a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2168a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2169a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2170a1d8d8a5SSudarsana Reddy Kalluru } 2171a1d8d8a5SSudarsana Reddy Kalluru 2172a1d8d8a5SSudarsana Reddy Kalluru /* ieee defines the selector field value for ethertype to be 1 */ 2173a1d8d8a5SSudarsana Reddy Kalluru ethtype = !!((app->selector - 1) == DCB_APP_IDTYPE_ETHTYPE); 2174a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 2175a1d8d8a5SSudarsana Reddy Kalluru entry = &dcbx_info->operational.params.app_entry[i]; 2176a1d8d8a5SSudarsana Reddy Kalluru if ((entry->ethtype == ethtype) && 2177a1d8d8a5SSudarsana Reddy Kalluru (entry->proto_id == app->protocol)) { 2178a1d8d8a5SSudarsana Reddy Kalluru prio = entry->prio; 2179a1d8d8a5SSudarsana Reddy Kalluru break; 2180a1d8d8a5SSudarsana Reddy Kalluru } 2181a1d8d8a5SSudarsana Reddy Kalluru } 2182a1d8d8a5SSudarsana Reddy Kalluru 2183a1d8d8a5SSudarsana Reddy Kalluru if (i == QED_DCBX_MAX_APP_PROTOCOL) { 2184a1d8d8a5SSudarsana Reddy Kalluru DP_ERR(cdev, "App entry (%d, %d) not found\n", app->selector, 2185a1d8d8a5SSudarsana Reddy Kalluru app->protocol); 2186a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2187a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2188a1d8d8a5SSudarsana Reddy Kalluru } 2189a1d8d8a5SSudarsana Reddy Kalluru 2190a1d8d8a5SSudarsana Reddy Kalluru app->priority = ffs(prio) - 1; 2191a1d8d8a5SSudarsana Reddy Kalluru 2192a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2193a1d8d8a5SSudarsana Reddy Kalluru 2194a1d8d8a5SSudarsana Reddy Kalluru return 0; 2195a1d8d8a5SSudarsana Reddy Kalluru } 2196a1d8d8a5SSudarsana Reddy Kalluru 2197a1d8d8a5SSudarsana Reddy Kalluru int qed_dcbnl_ieee_setapp(struct qed_dev *cdev, struct dcb_app *app) 2198a1d8d8a5SSudarsana Reddy Kalluru { 2199a1d8d8a5SSudarsana Reddy Kalluru struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 2200a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_get *dcbx_info; 2201a1d8d8a5SSudarsana Reddy Kalluru struct qed_dcbx_set dcbx_set; 2202a1d8d8a5SSudarsana Reddy Kalluru struct qed_app_entry *entry; 2203a1d8d8a5SSudarsana Reddy Kalluru struct qed_ptt *ptt; 2204a1d8d8a5SSudarsana Reddy Kalluru bool ethtype; 2205a1d8d8a5SSudarsana Reddy Kalluru int rc, i; 2206a1d8d8a5SSudarsana Reddy Kalluru 2207a1d8d8a5SSudarsana Reddy Kalluru if (app->priority < 0 || app->priority >= QED_MAX_PFC_PRIORITIES) { 2208a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "Invalid priority %d\n", app->priority); 2209a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2210a1d8d8a5SSudarsana Reddy Kalluru } 2211a1d8d8a5SSudarsana Reddy Kalluru 2212a1d8d8a5SSudarsana Reddy Kalluru dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB); 2213a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info) 2214a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2215a1d8d8a5SSudarsana Reddy Kalluru 2216a1d8d8a5SSudarsana Reddy Kalluru if (!dcbx_info->operational.ieee) { 2217a1d8d8a5SSudarsana Reddy Kalluru DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n"); 2218a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2219a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2220a1d8d8a5SSudarsana Reddy Kalluru } 2221a1d8d8a5SSudarsana Reddy Kalluru 2222a1d8d8a5SSudarsana Reddy Kalluru kfree(dcbx_info); 2223a1d8d8a5SSudarsana Reddy Kalluru 2224a1d8d8a5SSudarsana Reddy Kalluru memset(&dcbx_set, 0, sizeof(dcbx_set)); 2225a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_get_config_params(hwfn, &dcbx_set); 2226a1d8d8a5SSudarsana Reddy Kalluru if (rc) 2227a1d8d8a5SSudarsana Reddy Kalluru return -EINVAL; 2228a1d8d8a5SSudarsana Reddy Kalluru 2229a1d8d8a5SSudarsana Reddy Kalluru /* ieee defines the selector field value for ethertype to be 1 */ 2230a1d8d8a5SSudarsana Reddy Kalluru ethtype = !!((app->selector - 1) == DCB_APP_IDTYPE_ETHTYPE); 2231a1d8d8a5SSudarsana Reddy Kalluru for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) { 2232a1d8d8a5SSudarsana Reddy Kalluru entry = &dcbx_set.config.params.app_entry[i]; 2233a1d8d8a5SSudarsana Reddy Kalluru if ((entry->ethtype == ethtype) && 2234a1d8d8a5SSudarsana Reddy Kalluru (entry->proto_id == app->protocol)) 2235a1d8d8a5SSudarsana Reddy Kalluru break; 2236a1d8d8a5SSudarsana Reddy Kalluru /* First empty slot */ 22371d7406ceSSudarsana Reddy Kalluru if (!entry->proto_id) { 22381d7406ceSSudarsana Reddy Kalluru dcbx_set.config.params.num_app_entries++; 2239a1d8d8a5SSudarsana Reddy Kalluru break; 2240a1d8d8a5SSudarsana Reddy Kalluru } 22411d7406ceSSudarsana Reddy Kalluru } 2242a1d8d8a5SSudarsana Reddy Kalluru 2243a1d8d8a5SSudarsana Reddy Kalluru if (i == QED_DCBX_MAX_APP_PROTOCOL) { 2244a1d8d8a5SSudarsana Reddy Kalluru DP_ERR(cdev, "App table is full\n"); 2245a1d8d8a5SSudarsana Reddy Kalluru return -EBUSY; 2246a1d8d8a5SSudarsana Reddy Kalluru } 2247a1d8d8a5SSudarsana Reddy Kalluru 2248a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG; 2249a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].ethtype = ethtype; 2250a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].proto_id = app->protocol; 2251a1d8d8a5SSudarsana Reddy Kalluru dcbx_set.config.params.app_entry[i].prio = BIT(app->priority); 2252a1d8d8a5SSudarsana Reddy Kalluru 2253a1d8d8a5SSudarsana Reddy Kalluru ptt = qed_ptt_acquire(hwfn); 2254a1d8d8a5SSudarsana Reddy Kalluru if (!ptt) 2255a1d8d8a5SSudarsana Reddy Kalluru return -EBUSY; 2256a1d8d8a5SSudarsana Reddy Kalluru 2257a1d8d8a5SSudarsana Reddy Kalluru rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0); 2258a1d8d8a5SSudarsana Reddy Kalluru 2259a1d8d8a5SSudarsana Reddy Kalluru qed_ptt_release(hwfn, ptt); 2260a1d8d8a5SSudarsana Reddy Kalluru 2261a1d8d8a5SSudarsana Reddy Kalluru return rc; 2262a1d8d8a5SSudarsana Reddy Kalluru } 2263a1d8d8a5SSudarsana Reddy Kalluru 2264a1d8d8a5SSudarsana Reddy Kalluru const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass = { 2265a1d8d8a5SSudarsana Reddy Kalluru .getstate = qed_dcbnl_getstate, 2266a1d8d8a5SSudarsana Reddy Kalluru .setstate = qed_dcbnl_setstate, 2267a1d8d8a5SSudarsana Reddy Kalluru .getpgtccfgtx = qed_dcbnl_getpgtccfgtx, 2268a1d8d8a5SSudarsana Reddy Kalluru .getpgbwgcfgtx = qed_dcbnl_getpgbwgcfgtx, 2269a1d8d8a5SSudarsana Reddy Kalluru .getpgtccfgrx = qed_dcbnl_getpgtccfgrx, 2270a1d8d8a5SSudarsana Reddy Kalluru .getpgbwgcfgrx = qed_dcbnl_getpgbwgcfgrx, 2271a1d8d8a5SSudarsana Reddy Kalluru .getpfccfg = qed_dcbnl_getpfccfg, 2272a1d8d8a5SSudarsana Reddy Kalluru .setpfccfg = qed_dcbnl_setpfccfg, 2273a1d8d8a5SSudarsana Reddy Kalluru .getcap = qed_dcbnl_getcap, 2274a1d8d8a5SSudarsana Reddy Kalluru .getnumtcs = qed_dcbnl_getnumtcs, 2275a1d8d8a5SSudarsana Reddy Kalluru .getpfcstate = qed_dcbnl_getpfcstate, 2276a1d8d8a5SSudarsana Reddy Kalluru .getdcbx = qed_dcbnl_getdcbx, 2277a1d8d8a5SSudarsana Reddy Kalluru .setpgtccfgtx = qed_dcbnl_setpgtccfgtx, 2278a1d8d8a5SSudarsana Reddy Kalluru .setpgtccfgrx = qed_dcbnl_setpgtccfgrx, 2279a1d8d8a5SSudarsana Reddy Kalluru .setpgbwgcfgtx = qed_dcbnl_setpgbwgcfgtx, 2280a1d8d8a5SSudarsana Reddy Kalluru .setpgbwgcfgrx = qed_dcbnl_setpgbwgcfgrx, 2281a1d8d8a5SSudarsana Reddy Kalluru .setall = qed_dcbnl_setall, 2282a1d8d8a5SSudarsana Reddy Kalluru .setnumtcs = qed_dcbnl_setnumtcs, 2283a1d8d8a5SSudarsana Reddy Kalluru .setpfcstate = qed_dcbnl_setpfcstate, 2284a1d8d8a5SSudarsana Reddy Kalluru .setapp = qed_dcbnl_setapp, 2285a1d8d8a5SSudarsana Reddy Kalluru .setdcbx = qed_dcbnl_setdcbx, 2286a1d8d8a5SSudarsana Reddy Kalluru .setfeatcfg = qed_dcbnl_setfeatcfg, 2287a1d8d8a5SSudarsana Reddy Kalluru .getfeatcfg = qed_dcbnl_getfeatcfg, 2288a1d8d8a5SSudarsana Reddy Kalluru .getapp = qed_dcbnl_getapp, 2289a1d8d8a5SSudarsana Reddy Kalluru .peer_getappinfo = qed_dcbnl_peer_getappinfo, 2290a1d8d8a5SSudarsana Reddy Kalluru .peer_getapptable = qed_dcbnl_peer_getapptable, 2291a1d8d8a5SSudarsana Reddy Kalluru .cee_peer_getpfc = qed_dcbnl_cee_peer_getpfc, 2292a1d8d8a5SSudarsana Reddy Kalluru .cee_peer_getpg = qed_dcbnl_cee_peer_getpg, 2293a1d8d8a5SSudarsana Reddy Kalluru .ieee_getpfc = qed_dcbnl_ieee_getpfc, 2294a1d8d8a5SSudarsana Reddy Kalluru .ieee_setpfc = qed_dcbnl_ieee_setpfc, 2295a1d8d8a5SSudarsana Reddy Kalluru .ieee_getets = qed_dcbnl_ieee_getets, 2296a1d8d8a5SSudarsana Reddy Kalluru .ieee_setets = qed_dcbnl_ieee_setets, 2297a1d8d8a5SSudarsana Reddy Kalluru .ieee_peer_getpfc = qed_dcbnl_ieee_peer_getpfc, 2298a1d8d8a5SSudarsana Reddy Kalluru .ieee_peer_getets = qed_dcbnl_ieee_peer_getets, 2299a1d8d8a5SSudarsana Reddy Kalluru .ieee_getapp = qed_dcbnl_ieee_getapp, 2300a1d8d8a5SSudarsana Reddy Kalluru .ieee_setapp = qed_dcbnl_ieee_setapp, 2301a1d8d8a5SSudarsana Reddy Kalluru }; 2302a1d8d8a5SSudarsana Reddy Kalluru 23036ad8c632SSudarsana Reddy Kalluru #endif 2304