Add tags to already upstreamed patches. Signed-off-by: Nick Hainke <vincent@systemli.org>
		
			
				
	
	
		
			163 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
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/drivers/net/wireless/ath/ath10k/core.c
 | 
						|
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
						|
@@ -12,6 +12,7 @@
 | 
						|
 #include <linux/dmi.h>
 | 
						|
 #include <linux/ctype.h>
 | 
						|
 #include <linux/pm_qos.h>
 | 
						|
+#include <linux/nvmem-consumer.h>
 | 
						|
 #include <asm/byteorder.h>
 | 
						|
 
 | 
						|
 #include "core.h"
 | 
						|
@@ -955,7 +956,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;
 | 
						|
@@ -1757,7 +1759,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);
 | 
						|
@@ -1884,6 +1887,39 @@ out_free:
 | 
						|
 	return ret;
 | 
						|
 }
 | 
						|
 
 | 
						|
+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)
 | 
						|
 {
 | 
						|
@@ -2118,6 +2154,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;
 | 
						|
@@ -2184,6 +2232,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/drivers/net/wireless/ath/ath10k/core.h
 | 
						|
+++ b/drivers/net/wireless/ath/ath10k/core.h
 | 
						|
@@ -877,8 +877,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,
 | 
						|
 };
 | 
						|
 
 | 
						|
@@ -898,10 +900,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";
 | 
						|
 	}
 |