diff --git a/cnss2/main.h b/cnss2/main.h index a68be98148..bd37abb29d 100644 --- a/cnss2/main.h +++ b/cnss2/main.h @@ -567,6 +567,7 @@ struct cnss_plat_data { struct mutex dev_lock; /* mutex for register access through debugfs */ struct mutex driver_ops_lock; /* mutex for external driver ops */ struct cnss_wlan_driver *driver_ops; + u32 supported_link_speed; u32 device_freq_hz; u32 diag_reg_read_addr; u32 diag_reg_read_mem_type; diff --git a/cnss2/pci.c b/cnss2/pci.c index 44fbf6e9fd..6bf5bd65bc 100644 --- a/cnss2/pci.c +++ b/cnss2/pci.c @@ -1311,6 +1311,42 @@ static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save) return 0; } +static int cnss_update_supported_link_info(struct cnss_pci_data *pci_priv) +{ + int ret = 0; + struct pci_dev *root_port; + struct device_node *root_of_node; + struct cnss_plat_data *plat_priv; + + if (!pci_priv) + return -EINVAL; + + if (pci_priv->device_id != KIWI_DEVICE_ID) + return ret; + + plat_priv = pci_priv->plat_priv; + root_port = pcie_find_root_port(pci_priv->pci_dev); + + if (!root_port) { + cnss_pr_err("PCIe root port is null\n"); + return -EINVAL; + } + + root_of_node = root_port->dev.of_node; + if (root_of_node && root_of_node->parent) { + ret = of_property_read_u32(root_of_node->parent, + "qcom,target-link-speed", + &plat_priv->supported_link_speed); + if (!ret) + cnss_pr_dbg("Supported PCIe Link Speed: %d\n", + plat_priv->supported_link_speed); + else + plat_priv->supported_link_speed = 0; + } + + return ret; +} + static int cnss_pci_get_link_status(struct cnss_pci_data *pci_priv) { u16 link_status; @@ -7144,6 +7180,8 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, /* update drv support flag */ cnss_pci_update_drv_supported(pci_priv); + cnss_update_supported_link_info(pci_priv); + ret = cnss_reg_pci_event(pci_priv); if (ret) { cnss_pr_err("Failed to register PCI event, err = %d\n", ret); diff --git a/cnss2/qmi.c b/cnss2/qmi.c index 745b6c7d67..714361d403 100644 --- a/cnss2/qmi.c +++ b/cnss2/qmi.c @@ -327,6 +327,14 @@ static int cnss_wlfw_host_cap_send_sync(struct cnss_plat_data *plat_priv) req->nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT; } + if (plat_priv->supported_link_speed) { + req->pcie_link_info_valid = 1; + req->pcie_link_info.pci_link_speed = + plat_priv->supported_link_speed; + cnss_pr_dbg("Supported link speed in Host Cap %d\n", + plat_priv->supported_link_speed); + } + if (cnss_bus_is_smmu_s1_enabled(plat_priv) && !cnss_bus_get_iova(plat_priv, &iova_start, &iova_size) && !cnss_bus_get_iova_ipa(plat_priv, &iova_ipa_start, diff --git a/cnss_utils/wlan_firmware_service_v01.c b/cnss_utils/wlan_firmware_service_v01.c index d0fe1533ec..312dc4aee0 100644 --- a/cnss_utils/wlan_firmware_service_v01.c +++ b/cnss_utils/wlan_firmware_service_v01.c @@ -804,6 +804,34 @@ static struct qmi_elem_info wlfw_share_mem_info_s_v01_ei[] = { }, }; +static struct qmi_elem_info wlfw_host_pcie_link_info_s_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct + wlfw_host_pcie_link_info_s_v01, + pci_link_speed), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = offsetof(struct + wlfw_host_pcie_link_info_s_v01, + pci_link_width), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; + struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = { { .data_type = QMI_OPT_FLAG, @@ -1205,6 +1233,26 @@ struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[] = { wlfw_ind_register_req_msg_v01, m3_dump_upload_segments_req_enable), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x24, + .offset = offsetof(struct + wlfw_ind_register_req_msg_v01, + fw_ssr_enable_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x24, + .offset = offsetof(struct + wlfw_ind_register_req_msg_v01, + fw_ssr_enable), + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -4062,6 +4110,27 @@ struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = { mlo_chip_v2_info), .ei_array = wlfw_host_mlo_chip_v2_info_s_v01_ei, }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x30, + .offset = offsetof(struct + wlfw_host_cap_req_msg_v01, + pcie_link_info_valid), + }, + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct wlfw_host_pcie_link_info_s_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x30, + .offset = offsetof(struct + wlfw_host_cap_req_msg_v01, + pcie_link_info), + .ei_array = wlfw_host_pcie_link_info_s_v01_ei, + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -6569,6 +6638,54 @@ struct qmi_elem_info wlfw_tme_lite_info_resp_msg_v01_ei[] = { }; EXPORT_SYMBOL(wlfw_tme_lite_info_resp_msg_v01_ei); +struct qmi_elem_info wlfw_fw_ssr_ind_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; +EXPORT_SYMBOL(wlfw_fw_ssr_ind_msg_v01_ei); + +struct qmi_elem_info wlfw_bmps_ctrl_req_msg_v01_ei[] = { + { + .data_type = QMI_SIGNED_4_BYTE_ENUM, + .elem_len = 1, + .elem_size = sizeof(enum wlfw_bmps_state_enum_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct + wlfw_bmps_ctrl_req_msg_v01, + bmps_state), + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; +EXPORT_SYMBOL(wlfw_bmps_ctrl_req_msg_v01_ei); + +struct qmi_elem_info wlfw_bmps_ctrl_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct + wlfw_bmps_ctrl_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + .tlv_type = QMI_COMMON_TLV_TYPE, + }, +}; +EXPORT_SYMBOL(wlfw_bmps_ctrl_resp_msg_v01_ei); + /** * wlfw_is_valid_dt_node_found - Check if valid device tree node present * diff --git a/cnss_utils/wlan_firmware_service_v01.h b/cnss_utils/wlan_firmware_service_v01.h index b1b113478d..241127cfb6 100644 --- a/cnss_utils/wlan_firmware_service_v01.h +++ b/cnss_utils/wlan_firmware_service_v01.h @@ -37,6 +37,7 @@ #define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027 #define QMI_WLFW_IND_REGISTER_RESP_V01 0x0020 #define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029 +#define QMI_WLFW_BMPS_CTRL_RESP_V01 0x005D #define QMI_WLFW_AUX_UC_INFO_RESP_V01 0x005A #define QMI_WLFW_M3_INFO_REQ_V01 0x003C #define QMI_WLFW_PCIE_GEN_SWITCH_REQ_V01 0x0053 @@ -75,10 +76,12 @@ #define QMI_WLFW_QDSS_TRACE_REQ_MEM_IND_V01 0x003F #define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028 #define QMI_WLFW_ATHDIAG_WRITE_RESP_V01 0x0031 +#define QMI_WLFW_FW_SSR_IND_V01 0x005C #define QMI_WLFW_PHY_CAP_RESP_V01 0x0057 #define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_V01 0x0044 #define QMI_WLFW_SOC_WAKE_RESP_V01 0x004F #define QMI_WLFW_GET_INFO_RESP_V01 0x004A +#define QMI_WLFW_BMPS_CTRL_REQ_V01 0x005D #define QMI_WLFW_PCIE_GEN_SWITCH_RESP_V01 0x0053 #define QMI_WLFW_INI_REQ_V01 0x002F #define QMI_WLFW_M3_DUMP_UPLOAD_SEGMENTS_REQ_IND_V01 0x0054 @@ -354,6 +357,13 @@ enum wlfw_tme_lite_file_type_v01 { WLFW_TME_LITE_FILE_TYPE_MAX_VAL_V01 = INT_MAX, }; +enum wlfw_bmps_state_enum_v01 { + WLFW_BMPS_STATE_ENUM_MIN_VAL_V01 = INT_MIN, + QMI_WLFW_BMPS_ENABLE_V01 = 0, + QMI_WLFW_BMPS_DISABLE_V01 = 1, + WLFW_BMPS_STATE_ENUM_MAX_VAL_V01 = INT_MAX, +}; + #define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00) #define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01) #define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02) @@ -506,6 +516,11 @@ struct wlfw_share_mem_info_s_v01 { u64 size; }; +struct wlfw_host_pcie_link_info_s_v01 { + u32 pci_link_speed; + u32 pci_link_width; +}; + struct wlfw_ind_register_req_msg_v01 { u8 fw_ready_enable_valid; u8 fw_ready_enable; @@ -547,8 +562,10 @@ struct wlfw_ind_register_req_msg_v01 { u8 qdss_mem_ready_enable; u8 m3_dump_upload_segments_req_enable_valid; u8 m3_dump_upload_segments_req_enable; + u8 fw_ssr_enable_valid; + u8 fw_ssr_enable; }; -#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 86 +#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 90 extern struct qmi_elem_info wlfw_ind_register_req_msg_v01_ei[]; struct wlfw_ind_register_resp_msg_v01 { @@ -976,8 +993,10 @@ struct wlfw_host_cap_req_msg_v01 { u8 fw_ini_cfg_support; u8 mlo_chip_v2_info_valid; struct wlfw_host_mlo_chip_v2_info_s_v01 mlo_chip_v2_info[QMI_WLFW_MAX_NUM_MLO_V2_CHIPS_V01]; + u8 pcie_link_info_valid; + struct wlfw_host_pcie_link_info_s_v01 pcie_link_info; }; -#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 570 +#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 581 extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 { @@ -1499,4 +1518,22 @@ struct wlfw_tme_lite_info_resp_msg_v01 { #define WLFW_TME_LITE_INFO_RESP_MSG_V01_MAX_MSG_LEN 7 extern struct qmi_elem_info wlfw_tme_lite_info_resp_msg_v01_ei[]; +struct wlfw_fw_ssr_ind_msg_v01 { + char placeholder; +}; +#define WLFW_FW_SSR_IND_MSG_V01_MAX_MSG_LEN 0 +extern struct qmi_elem_info wlfw_fw_ssr_ind_msg_v01_ei[]; + +struct wlfw_bmps_ctrl_req_msg_v01 { + enum wlfw_bmps_state_enum_v01 bmps_state; +}; +#define WLFW_BMPS_CTRL_REQ_MSG_V01_MAX_MSG_LEN 7 +extern struct qmi_elem_info wlfw_bmps_ctrl_req_msg_v01_ei[]; + +struct wlfw_bmps_ctrl_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; +#define WLFW_BMPS_CTRL_RESP_MSG_V01_MAX_MSG_LEN 7 +extern struct qmi_elem_info wlfw_bmps_ctrl_resp_msg_v01_ei[]; + #endif