static int ath10k_init_download_firmware(struct ath10k *ar, enum ath10k_firmware_mode mode) { int ret; ret = ath10k_download_board_data(ar); if (ret) { ath10k_err(ar, "failed to download board data: %d\n", ret); return ret; } ret = ath10k_download_and_run_otp(ar); if (ret) { ath10k_err(ar, "failed to run otp: %d\n", ret); return ret; } ret = ath10k_download_fw(ar, mode); if (ret) { ath10k_err(ar, "failed to download firmware: %d\n", ret); return ret; } return ret; }
static int ath10k_download_cal_dt(struct ath10k *ar) { struct device_node *node; int data_len; void *data; int ret; node = ar->dev->of_node; if (!node) /* Device Tree is optional, don't print any warnings if * there's no node for ath10k. */ return -ENOENT; if (!of_get_property(node, "qcom,ath10k-calibration-data", &data_len)) { /* The calibration data node is optional */ return -ENOENT; } if (data_len != QCA988X_CAL_DATA_LEN) { ath10k_warn(ar, "invalid calibration data length in DT: %d\n", data_len); ret = -EMSGSIZE; goto out; } data = kmalloc(data_len, GFP_KERNEL); if (!data) { ret = -ENOMEM; goto out; } ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data", data, data_len); if (ret) { ath10k_warn(ar, "failed to read calibration data from DT: %d\n", ret); goto out_free; } ret = ath10k_download_board_data(ar, data, data_len); if (ret) { ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n", ret); goto out_free; } ret = 0; out_free: kfree(data); out: return ret; }
static int ath10k_download_and_run_otp(struct ath10k *ar) { u32 result, address = ar->hw_params.patch_load_addr; u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param; int ret; ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len); if (ret) { ath10k_err(ar, "failed to download board data: %d\n", ret); return ret; } /* OTP is optional */ if (!ar->otp_data || !ar->otp_len) { ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", ar->otp_data, ar->otp_len); return 0; } ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", address, ar->otp_len); ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); if (ret) { ath10k_err(ar, "could not write otp (%d)\n", ret); return ret; } ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result); if (ret) { ath10k_err(ar, "could not execute otp (%d)\n", ret); return ret; } ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT, ar->fw_features)) && result != 0) { ath10k_err(ar, "otp calibration failed: %d", result); return -EINVAL; } return 0; }
static int ath10k_init_download_firmware(struct ath10k *ar) { int ret; ret = ath10k_download_board_data(ar); if (ret) return ret; ret = ath10k_download_and_run_otp(ar); if (ret) return ret; ret = ath10k_download_fw(ar); if (ret) return ret; return ret; }
static int ath10k_download_cal_file(struct ath10k *ar) { int ret; if (!ar->cal_file) return -ENOENT; if (IS_ERR(ar->cal_file)) return PTR_ERR(ar->cal_file); ret = ath10k_download_board_data(ar, ar->cal_file->data, ar->cal_file->size); if (ret) { ath10k_err(ar, "failed to download cal_file data: %d\n", ret); return ret; } ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n"); return 0; }