[PATCH 7/8] ath10k-ct: Support qcom,ath10k-calibration-data-base64

Christian Marangi ansuelsmth at gmail.com
Wed Jan 4 04:58:01 PST 2023


On Mon, Jan 02, 2023 at 03:25:33PM -0800, Brian Norris wrote:
> See the patch notes about the stock firmware for TP-Link Onhub and
> https://chromium-review.googlesource.com/243115.
> 
> As noted there, the production firmware for Google OnHub devices only
> provide the *-base64 Device Tree property, and so either the kernel or
> some user space mechanism needs to know how to parse/convert this
> property.
> 
> I haven't submitted this patch upstream. However, it applies relatively
> cleanly to the tree even after almost 8 years, so it doesn't seem too
> hard to maintain.

It's an additional patch to refresh. Also this is only for ct but should
also be put for the normal ath10k driver.

Aside from this, I notice this is actually NOT used in the 2 device you
are proposing. I'm totally missing something or this is not needed at
all?

Also on top of that the besto solution for these special case is to
parse the base64 data in userspace a produce a calibration bin to pass
with sysfs. A patch and some code to decode base64 seems overkill to me.

> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> ---
> 
>  .../970-ath10k-calibration-base64.patch       | 249 ++++++++++++++++++
>  1 file changed, 249 insertions(+)
>  create mode 100644 package/kernel/ath10k-ct/patches/970-ath10k-calibration-base64.patch
> 
> diff --git a/package/kernel/ath10k-ct/patches/970-ath10k-calibration-base64.patch b/package/kernel/ath10k-ct/patches/970-ath10k-calibration-base64.patch
> new file mode 100644
> index 000000000000..739bdee9ccf4
> --- /dev/null
> +++ b/package/kernel/ath10k-ct/patches/970-ath10k-calibration-base64.patch
> @@ -0,0 +1,249 @@
> +Adapted from:
> +https://chromium-review.googlesource.com/307062
> +
> +This "hack" remained in the production kernel, and so the production firmware
> +for Google OnHub still only knows how to patch the *-base64 Device Tree
> +property.
> +
> +CHROMIUM: HACK: ath10k: read calibration data in base64 format from DT
> +
> + Chrome OS firmware doesn't support binary format in VPD currently.
> + As a workaround, the firmware stores the calibration data in base64
> + format in the same node with the different name:
> +
> +   qcom,ath10k-calibration-data-base64 = [ 01 02 03 ... ];
> +
> +   Since the original property "qcom,ath10k-calibration-data" is always
> +   looked for first, it should have an invalid size (e.g. 1).
> +
> +   BUG=chrome-os-partner:35262
> +   TEST=build/boot on storm suceeded. Setup Storm board as AP using
> +   hostapd and
> +   connected to the board using another device. Device was able to
> +   connect to
> +   the internet and load multiple websites.
> +
> +   Change-Id: I95675a803fad3b94977ecd0977bd9980779ad7e9
> +   Signed-off-by: Toshi Kikuchi <toshik at chromium.org>
> +   Reviewed-on: https://chromium-review.googlesource.com/243115
> +   Reviewed-by: Grant Grundler <grundler at chromium.org>
> +
> +Change-Id: I17874f0ed03e28d279b08fe70aca70af57c90bda
> +Signed-off-by: Anilkumar Kolli <akolli at codeaurora.org>
> +Reviewed-on: https://chromium-review.googlesource.com/307062
> +Commit-Ready: Grant Grundler <grundler at chromium.org>
> +Tested-by: Grant Grundler <grundler at chromium.org>
> +Reviewed-by: Srinivasa duvvuri <sduvvuri at chromium.org>
> +Reviewed-by: Grant Grundler <grundler at chromium.org>
> +--- a/ath10k-5.15/Makefile
> ++++ b/ath10k-5.15/Makefile
> +@@ -4,6 +4,7 @@ ath10k_core-y += mac.o \
> + 		 debug.o \
> + 		 core.o \
> + 		 coredump.o \
> ++		 decode64.o \
> + 		 htc.o \
> + 		 htt.o \
> + 		 htt_rx.o \
> +--- a/ath10k-5.15/core.c
> ++++ b/ath10k-5.15/core.c
> +@@ -18,6 +18,7 @@
> + #include <linux/ctype.h>
> + 
> + #include "core.h"
> ++#include "decode64.h"
> + #include "mac.h"
> + #include "htc.h"
> + #include "hif.h"
> +@@ -2167,6 +2168,73 @@ static int ath10k_download_cal_file(stru
> + 	return 0;
> + }
> + 
> ++static int ath10k_download_cal_dt_base64(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-base64",
> ++			     &data_len)) {
> ++		/* The calibration data node is optional */
> ++		return -ENOENT;
> ++	}
> ++
> ++	data = kmalloc(data_len, GFP_KERNEL);
> ++	if (!data) {
> ++		ret = -ENOMEM;
> ++		goto out;
> ++	}
> ++
> ++	ret = of_property_read_u8_array(node,
> ++					"qcom,ath10k-calibration-data-base64",
> ++					data, data_len);
> ++	if (ret) {
> ++		ath10k_warn(ar,
> ++		    "failed to read calibration data (base64) from DT: %d\n",
> ++			    ret);
> ++		goto out_free;
> ++	}
> ++
> ++	data_len = strip_nl(data, data + data_len, data);
> ++	data_len = decode64(data, data + data_len, data);
> ++	if (data_len < 0) {
> ++		ath10k_warn(ar,
> ++			    "base64 decoder found invalid input\n");
> ++		ret = -EINVAL;
> ++		goto out_free;
> ++	}
> ++
> ++	if (data_len != ar->hw_params.cal_data_len) {
> ++		ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
> ++			    data_len);
> ++		ret = -EMSGSIZE;
> ++		goto out_free;
> ++	}
> ++
> ++	ret = ath10k_download_board_data(ar, data, data_len);
> ++	if (ret) {
> ++		ath10k_warn(ar, "failed to download base64 calibration data from Device Tree: %d\n",
> ++			    ret);
> ++		goto out_free;
> ++	}
> ++
> ++	ret = 0;
> ++out_free:
> ++	kfree(data);
> ++
> ++out:
> ++	return ret;
> ++}
> ++
> + static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)
> + {
> + 	struct device_node *node;
> +@@ -2787,6 +2855,12 @@ static int ath10k_download_cal_data(stru
> + 		   "boot did not find target EEPROM entry, try OTP next: %d\n",
> + 		   ret);
> + 
> ++	ret = ath10k_download_cal_dt_base64(ar);
> ++	if (ret == 0) {
> ++		ar->cal_mode = ATH10K_CAL_MODE_DT;
> ++		goto done;
> ++	}
> ++
> + 	ret = ath10k_download_and_run_otp(ar);
> + 	if (ret) {
> + 		ath10k_err(ar, "failed to run otp: %d (download-cal-data)\n", ret);
> +--- /dev/null
> ++++ b/ath10k-5.15/decode64.c
> +@@ -0,0 +1,89 @@
> ++/*
> ++ * Copyright (c) 2013 The Linux Foundation. All rights reserved.
> ++ * Copyright (c) 2014, The Chromium OS Authors
> ++ *
> ++ * This program is free software; you can redistribute it and/or
> ++ * modify it under the terms of the GNU General Public License as
> ++ * published by the Free Software Foundation; either version 2 of
> ++ * the License, or (at your option) any later version.
> ++ *
> ++ * This program is distributed in the hope that it will be useful,
> ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> ++ * GNU General Public License for more details.
> ++ *
> ++ * You should have received a copy of the GNU General Public License
> ++ * along with this program; if not, write to the Free Software
> ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> ++ * MA 02111-1307 USA
> ++ */
> ++
> ++#include "decode64.h"
> ++
> ++static char revkey[128] = {
> ++	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
> ++	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
> ++	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
> ++	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
> ++	-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
> ++	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
> ++	-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
> ++	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
> ++};
> ++
> ++int
> ++decode64(unsigned char *src, unsigned char *src_end, unsigned char *dst)
> ++{
> ++	unsigned char *dst_end = dst;
> ++
> ++	while (&src[3] < src_end) {
> ++		int x;
> ++		int t[4];
> ++		int i;
> ++
> ++		if (src[0] == '=' || src[1] == '=' ||
> ++		    (src[2] == '=' && src[3] != '=')) {
> ++			return -1;
> ++		}
> ++
> ++		for (i = 0; i < 4; i++) {
> ++			if (src[i] == '=') {
> ++				t[i] = 0;
> ++			} else {
> ++				if (src[i] >= 128 ||
> ++				    ((t[i] = revkey[src[i]]) < 0)) {
> ++					return -1;
> ++				}
> ++			}
> ++		}
> ++
> ++		x = (t[0] << 18) + (t[1] << 12) + (t[2] << 6) + t[3];
> ++
> ++		*dst_end++ = (x >> 16) & 0xff;
> ++		if (src[2] != '=')
> ++			*dst_end++ = (x >> 8) & 0xff;
> ++		if (src[3] != '=')
> ++			*dst_end++ = x & 0xff;
> ++
> ++		src += 4;
> ++	}
> ++
> ++	if (src != src_end)
> ++		return -1;
> ++
> ++	return dst_end - dst;
> ++}
> ++
> ++int
> ++strip_nl(unsigned char *src, unsigned char *src_end, unsigned char *dst)
> ++{
> ++	unsigned char *dst_end = dst;
> ++
> ++	while (src < src_end) {
> ++		if (*src != '\n')
> ++			*dst_end++ = *src;
> ++		src++;
> ++	}
> ++
> ++	return dst_end - dst;
> ++}
> +--- /dev/null
> ++++ b/ath10k-5.15/decode64.h
> +@@ -0,0 +1,10 @@
> ++#ifndef _DECODE64_H_
> ++#define _DECODE64_H_
> ++
> ++int decode64(unsigned char *src, unsigned char *src_end,
> ++	     unsigned char *dst);
> ++
> ++int strip_nl(unsigned char *src, unsigned char *src_end,
> ++	     unsigned char *dst);
> ++
> ++#endif /* _DECODE64_H_ */
> -- 
> 2.39.0
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

-- 
	Ansuel



More information about the openwrt-devel mailing list