+++ /dev/null
-From e2333703373e8b81294da5d1c73c30154f75b082 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri, 15 Oct 2021 18:56:33 +0200
-Subject: [PATCH] ath10k: fetch (pre-)calibration data via nvmem subsystem
-
-On most embedded ath10k devices (like range extenders,
-routers, accesspoints, ...) the calibration data is
-stored in a easily accessible MTD partitions named
-"ART", "caldata", "calibration", etc...
-
-Since commit 4b361cfa8624 ("mtd: core: add OTP nvmem provider support"):
-MTD partitions and portions of them can be specified
-as potential nvmem-cells which are accessible through
-the nvmem subsystem.
-
-This feature - together with an nvmem cell definition either
-in the platform data or via device-tree allows drivers to get
-the (pre-)calibration data which is required for initializing
-the WIFI.
-
-Tested with Netgear EX6150v2 (IPQ4018)
-
-Cc: Robert Marko <robimarko@gmail.com>
-Cc: Thibaut Varene <hacks@slashdirt.org>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
----
---- a/ath10k-5.15/core.c
-+++ b/ath10k-5.15/core.c
-@@ -13,6 +13,7 @@
- #include <linux/dmi.h>
- #include <linux/ctype.h>
- #include <linux/pm_qos.h>
-+#include <linux/nvmem-consumer.h>
- #include <asm/byteorder.h>
- #include <linux/ctype.h>
-
-@@ -1005,7 +1006,8 @@ static int ath10k_core_get_board_id_from
- }
-
- if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
-- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
-+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
-+ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
- bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
- else
- bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
-@@ -2115,7 +2117,8 @@ static int ath10k_download_and_run_otp(s
-
- /* As of now pre-cal is valid for 10_4 variants */
- if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
-- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
-+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
-+ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
- bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
-
- ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
-@@ -2249,6 +2252,39 @@ struct ath10k_bss_rom_ie {
- __le32 rom_len;
- } __packed;
-
-+static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
-+{
-+ struct nvmem_cell *cell;
-+ void *buf;
-+ size_t len;
-+ int ret;
-+
-+ cell = devm_nvmem_cell_get(ar->dev, cell_name);
-+ if (IS_ERR(cell)) {
-+ ret = PTR_ERR(cell);
-+ return ret;
-+ }
-+
-+ buf = nvmem_cell_read(cell, &len);
-+ if (IS_ERR(buf))
-+ return PTR_ERR(buf);
-+
-+ if (ar->hw_params.cal_data_len != len) {
-+ kfree(buf);
-+ ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
-+ cell_name, len, ar->hw_params.cal_data_len);
-+ return -EMSGSIZE;
-+ }
-+
-+ ret = ath10k_download_board_data(ar, buf, len);
-+ kfree(buf);
-+ if (ret)
-+ ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
-+ cell_name, ret);
-+
-+ return ret;
-+}
-+
- int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
- struct ath10k_fw_file *fw_file)
- {
-@@ -2625,6 +2661,18 @@ static int ath10k_core_pre_cal_download(
- {
- int ret;
-
-+ ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
-+ if (ret == 0) {
-+ ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
-+ goto success;
-+ } else if (ret == -EPROBE_DEFER) {
-+ return ret;
-+ }
-+
-+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
-+ "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
-+ ret);
-+
- ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
- if (ret == 0) {
- ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
-@@ -2691,6 +2739,18 @@ static int ath10k_download_cal_data(stru
- "pre cal download procedure failed, try cal file: %d\n",
- ret);
-
-+ ret = ath10k_download_cal_nvmem(ar, "calibration");
-+ if (ret == 0) {
-+ ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
-+ goto done;
-+ } else if (ret == -EPROBE_DEFER) {
-+ return ret;
-+ }
-+
-+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
-+ "boot did not find a calibration nvmem-cell, try file next: %d\n",
-+ ret);
-+
- ret = ath10k_download_cal_file(ar, ar->cal_file);
- if (ret == 0) {
- ar->cal_mode = ATH10K_CAL_MODE_FILE;
---- a/ath10k-5.15/core.h
-+++ b/ath10k-5.15/core.h
-@@ -1109,8 +1109,10 @@ enum ath10k_cal_mode {
- ATH10K_CAL_MODE_FILE,
- ATH10K_CAL_MODE_OTP,
- ATH10K_CAL_MODE_DT,
-+ ATH10K_CAL_MODE_NVMEM,
- ATH10K_PRE_CAL_MODE_FILE,
- ATH10K_PRE_CAL_MODE_DT,
-+ ATH10K_PRE_CAL_MODE_NVMEM,
- ATH10K_CAL_MODE_EEPROM,
- };
-
-@@ -1130,10 +1132,14 @@ static inline const char *ath10k_cal_mod
- return "otp";
- case ATH10K_CAL_MODE_DT:
- return "dt";
-+ case ATH10K_CAL_MODE_NVMEM:
-+ return "nvmem";
- case ATH10K_PRE_CAL_MODE_FILE:
- return "pre-cal-file";
- case ATH10K_PRE_CAL_MODE_DT:
- return "pre-cal-dt";
-+ case ATH10K_PRE_CAL_MODE_NVMEM:
-+ return "pre-cal-nvmem";
- case ATH10K_CAL_MODE_EEPROM:
- return "eeprom";
- }