[PATCH 7/8] ath10k-ct: Support qcom,ath10k-calibration-data-base64
Robert Marko
robimarko at gmail.com
Wed Jan 4 05:31:53 PST 2023
On Tue, 3 Jan 2023 at 00:30, Brian Norris <computersforpeace at gmail.com> 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.
This should be sent upstream, otherwise its gonna be left downstream forever.
Regards,
Robert
>
> 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
More information about the openwrt-devel
mailing list