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. Signed-off-by: Brian Norris <computersforpe...@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 <tos...@chromium.org> + Reviewed-on: https://chromium-review.googlesource.com/243115 + Reviewed-by: Grant Grundler <grund...@chromium.org> + +Change-Id: I17874f0ed03e28d279b08fe70aca70af57c90bda +Signed-off-by: Anilkumar Kolli <ako...@codeaurora.org> +Reviewed-on: https://chromium-review.googlesource.com/307062 +Commit-Ready: Grant Grundler <grund...@chromium.org> +Tested-by: Grant Grundler <grund...@chromium.org> +Reviewed-by: Srinivasa duvvuri <sduvv...@chromium.org> +Reviewed-by: Grant Grundler <grund...@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@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel