diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index d7ceb9ae59df..6e2d62a9623d 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -950,6 +950,78 @@ static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, num_macs), }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + voltage_mv_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x16, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + voltage_mv), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + time_freq_hz_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x17, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + time_freq_hz), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + otp_version_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x18, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + otp_version), + }, + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + eeprom_read_timeout_valid), + }, + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(u32), + .array_type = NO_ARRAY, + .tlv_type = 0x19, + .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, + eeprom_read_timeout), + }, { .data_type = QMI_EOTI, .array_type = NO_ARRAY, @@ -1846,8 +1918,8 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); - ret = qmi_txn_init(&ab->qmi.handle, &txn, - qmi_wlanfw_cap_resp_msg_v01_ei, &resp); + ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei, + &resp); if (ret < 0) goto out; @@ -1900,6 +1972,12 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id, sizeof(ab->qmi.target.fw_build_id)); + if (resp.eeprom_read_timeout_valid) { + ab->qmi.target.eeprom_caldata = + resp.eeprom_read_timeout; + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n"); + } + ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n", ab->qmi.target.chip_id, ab->qmi.target.chip_family, ab->qmi.target.board_id, ab->qmi.target.soc_id); @@ -1963,7 +2041,8 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, req->end = 1; } - if (ab->bus_params.fixed_bdf_addr) { + if (ab->bus_params.fixed_bdf_addr || + type == ATH11K_QMI_FILE_TYPE_EEPROM) { req->data_valid = 0; req->end = 1; req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; @@ -2010,7 +2089,8 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, goto err_iounmap; } - if (ab->bus_params.fixed_bdf_addr) { + if (ab->bus_params.fixed_bdf_addr || + type == ATH11K_QMI_FILE_TYPE_EEPROM) { remaining = 0; } else { remaining -= req->data_len; @@ -2039,6 +2119,7 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) struct ath11k_board_data bd; u32 fw_size, file_type; int ret = 0, bdf_type; + const u8 *tmp; memset(&bd, 0, sizeof(bd)); ret = ath11k_core_fetch_bdf(ab, &bd); @@ -2063,31 +2144,38 @@ static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) goto out; } - /* QCA6390 does not support cal data file, skip it */ + /* QCA6390 does not support cal data, skip it */ if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF) goto out; - file_type = ATH11K_QMI_FILE_TYPE_CALDATA; + if (ab->qmi.target.eeprom_caldata) { + file_type = ATH11K_QMI_FILE_TYPE_EEPROM; + tmp = filename; + fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; + } else { + file_type = ATH11K_QMI_FILE_TYPE_CALDATA; - /* cal--.bin */ - snprintf(filename, sizeof(filename), "cal-%s-%s.bin", - ath11k_bus_str(ab->hif.bus), dev_name(dev)); - fw_entry = ath11k_core_firmware_request(ab, filename); - if (!IS_ERR(fw_entry)) - goto success; + /* cal--.bin */ + snprintf(filename, sizeof(filename), "cal-%s-%s.bin", + ath11k_bus_str(ab->hif.bus), dev_name(dev)); + fw_entry = ath11k_core_firmware_request(ab, filename); + if (!IS_ERR(fw_entry)) + goto success; - fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); - if (IS_ERR(fw_entry)) { - ret = PTR_ERR(fw_entry); - ath11k_warn(ab, - "qmi failed to load CAL data file:%s\n", - filename); - goto out; + fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); + if (IS_ERR(fw_entry)) { + ret = PTR_ERR(fw_entry); + ath11k_warn(ab, + "qmi failed to load CAL data file:%s\n", + filename); + goto out; + } +success: + fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size); + tmp = fw_entry->data; } -success: - fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size); - ret = ath11k_qmi_load_file_target_mem(ab, fw_entry->data, fw_size, file_type); + ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type); if (ret < 0) { ath11k_warn(ab, "qmi failed to load caldata\n"); goto out_qmi_cal; @@ -2096,7 +2184,8 @@ success: ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type); out_qmi_cal: - release_firmware(fw_entry); + if (!ab->qmi.target.eeprom_caldata) + release_firmware(fw_entry); out: ath11k_core_free_bdf(ab, &bd); ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n"); diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index 30236c5d26e2..3bb0f9ef7996 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -10,7 +10,7 @@ #include #define ATH11K_HOST_VERSION_STRING "WIN" -#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000 +#define ATH11K_QMI_WLANFW_TIMEOUT_MS 10000 #define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE 64 #define ATH11K_QMI_CALDB_ADDRESS 0x4BA00000 #define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128 @@ -42,6 +42,7 @@ struct ath11k_base; enum ath11k_qmi_file_type { ATH11K_QMI_FILE_TYPE_BDF_GOLDEN, ATH11K_QMI_FILE_TYPE_CALDATA, + ATH11K_QMI_FILE_TYPE_EEPROM, ATH11K_QMI_MAX_FILE_TYPE, }; @@ -102,6 +103,7 @@ struct target_info { u32 board_id; u32 soc_id; u32 fw_version; + u32 eeprom_caldata; char fw_build_timestamp[ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1]; char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1]; char bdf_ext[ATH11K_QMI_BDF_EXT_STR_LENGTH]; @@ -133,7 +135,7 @@ struct ath11k_qmi { wait_queue_head_t cold_boot_waitq; }; -#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 189 +#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261 #define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034 #define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7 #define QMI_WLFW_HOST_CAP_RESP_V01 0x0034 @@ -283,7 +285,7 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 { }; #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 -#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 207 +#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 #define QMI_WLANFW_CAP_REQ_V01 0x0024 #define QMI_WLANFW_CAP_RESP_V01 0x0024 @@ -364,6 +366,14 @@ struct qmi_wlanfw_cap_resp_msg_v01 { char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1]; u8 num_macs_valid; u8 num_macs; + u8 voltage_mv_valid; + u32 voltage_mv; + u8 time_freq_hz_valid; + u32 time_freq_hz; + u8 otp_version_valid; + u32 otp_version; + u8 eeprom_read_timeout_valid; + u32 eeprom_read_timeout; }; struct qmi_wlanfw_cap_req_msg_v01 {