diff options
Diffstat (limited to 'package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch')
-rw-r--r-- | package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch b/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch deleted file mode 100644 index 357b006bcc..0000000000 --- a/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch +++ /dev/null @@ -1,237 +0,0 @@ -From: Thomas Hebb <tommyhebb@gmail.com> -Subject: [PATCH] ath10k: search all IEs for variant before falling back -Date: Wed, 21 Feb 2018 11:43:39 -0500 - -commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file -extension") added a feature to ath10k that allows Board Data File -(BDF) conflicts between multiple devices that use the same device IDs -but have different calibration requirements to be resolved by allowing -a "variant" string to be stored in SMBIOS [and later device tree, added -by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration- -variant")] that gets appended to the ID stored in board-2.bin. - -This original patch had a regression, however. Namely that devices with -a variant present in SMBIOS that didn't need custom BDFs could no longer -find the default BDF, which has no variant appended. The patch was -reverted and re-applied with a fix for this issue in commit 1657b8f84ed9 -("search SMBIOS for OEM board file extension"). - -But the fix to fall back to a default BDF introduced another issue: the -driver currently parses IEs in board-2.bin one by one, and for each one -it first checks to see if it matches the ID with the variant appended. -If it doesn't, it checks to see if it matches the "fallback" ID with no -variant. If a matching BDF is found at any point during this search, the -search is terminated and that BDF is used. The issue is that it's very -possible (and is currently the case for board-2.bin files present in the -ath10k-firmware repository) for the default BDF to occur in an earlier -IE than the variant-specific BDF. In this case, the current code will -happily choose the default BDF even though a better-matching BDF is -present later in the file. - -This patch fixes the issue by first searching the entire file for the ID -with variant, and searching for the fallback ID only if that search -fails. It also includes some code cleanup in the area, as -ath10k_core_fetch_board_data_api_n() no longer does its own string -mangling to remove the variant from an ID, instead leaving that job to a -new flag passed to ath10k_core_create_board_name(). - -I've tested this patch on a QCA4019 and verified that the driver behaves -correctly for 1) both fallback and variant BDFs present, 2) only fallback -BDF present, and 3) no matching BDFs present. - -Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension") -Signed-off-by: Thomas Hebb <tommyhebb@gmail.com> ---- - drivers/net/wireless/ath/ath10k/core.c | 134 ++++++++++++++++++--------------- - 1 file changed, 72 insertions(+), 62 deletions(-) - ---- a/drivers/net/wireless/ath/ath10k/core.c -+++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -1132,14 +1132,61 @@ out: - return ret; - } - -+static int ath10k_core_search_bd(struct ath10k *ar, -+ const char *boardname, -+ const u8 *data, -+ size_t len) -+{ -+ size_t ie_len; -+ struct ath10k_fw_ie *hdr; -+ int ret = -ENOENT, ie_id; -+ -+ while (len > sizeof(struct ath10k_fw_ie)) { -+ hdr = (struct ath10k_fw_ie *)data; -+ ie_id = le32_to_cpu(hdr->id); -+ ie_len = le32_to_cpu(hdr->len); -+ -+ len -= sizeof(*hdr); -+ data = hdr->data; -+ -+ if (len < ALIGN(ie_len, 4)) { -+ ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", -+ ie_id, ie_len, len); -+ return -EINVAL; -+ } -+ -+ switch (ie_id) { -+ case ATH10K_BD_IE_BOARD: -+ ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, -+ boardname); -+ if (ret == -ENOENT) -+ /* no match found, continue */ -+ break; -+ -+ /* either found or error, so stop searching */ -+ goto out; -+ } -+ -+ /* jump over the padding */ -+ ie_len = ALIGN(ie_len, 4); -+ -+ len -= ie_len; -+ data += ie_len; -+ } -+ -+out: -+ /* return result of parse_bd_ie_board() or -ENOENT */ -+ return ret; -+} -+ - static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar, - const char *boardname, -+ const char *fallback_boardname, - const char *filename) - { -- size_t len, magic_len, ie_len; -- struct ath10k_fw_ie *hdr; -+ size_t len, magic_len; - const u8 *data; -- int ret, ie_id; -+ int ret; - - ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar, - ar->hw_params.fw.dir, -@@ -1177,69 +1224,23 @@ static int ath10k_core_fetch_board_data_ - data += magic_len; - len -= magic_len; - -- while (len > sizeof(struct ath10k_fw_ie)) { -- hdr = (struct ath10k_fw_ie *)data; -- ie_id = le32_to_cpu(hdr->id); -- ie_len = le32_to_cpu(hdr->len); -- -- len -= sizeof(*hdr); -- data = hdr->data; -- -- if (len < ALIGN(ie_len, 4)) { -- ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", -- ie_id, ie_len, len); -- ret = -EINVAL; -- goto err; -- } -+ /* attempt to find boardname in the IE list */ -+ ret = ath10k_core_search_bd(ar, boardname, data, len); - -- switch (ie_id) { -- case ATH10K_BD_IE_BOARD: -- ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, -- boardname); -- if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') { -- /* try default bdf if variant was not found */ -- char *s, *v = ",variant="; -- char boardname2[100]; -- -- strlcpy(boardname2, boardname, -- sizeof(boardname2)); -- -- s = strstr(boardname2, v); -- if (s) -- *s = '\0'; /* strip ",variant=%s" */ -- -- ret = ath10k_core_parse_bd_ie_board(ar, data, -- ie_len, -- boardname2); -- } -+ /* if we didn't find it and have a fallback name, try that */ -+ if (ret == -ENOENT && fallback_boardname) -+ ret = ath10k_core_search_bd(ar, fallback_boardname, data, len); - -- if (ret == -ENOENT) -- /* no match found, continue */ -- break; -- else if (ret) -- /* there was an error, bail out */ -- goto err; -- -- /* board data found */ -- goto out; -- } -- -- /* jump over the padding */ -- ie_len = ALIGN(ie_len, 4); -- -- len -= ie_len; -- data += ie_len; -- } -- --out: -- if (!ar->normal_mode_fw.board_data || !ar->normal_mode_fw.board_len) { -+ if (ret == -ENOENT) { - ath10k_err(ar, - "failed to fetch board data for %s from %s/%s\n", - boardname, ar->hw_params.fw.dir, filename); - ret = -ENODATA; -- goto err; - } - -+ if (ret) -+ goto err; -+ - return 0; - - err: -@@ -1248,12 +1249,12 @@ err: - } - - static int ath10k_core_create_board_name(struct ath10k *ar, char *name, -- size_t name_len) -+ size_t name_len, bool with_variant) - { - /* strlen(',variant=') + strlen(ar->id.bdf_ext) */ - char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; - -- if (ar->id.bdf_ext[0] != '\0') -+ if (with_variant && ar->id.bdf_ext[0] != '\0') - scnprintf(variant, sizeof(variant), ",variant=%s", - ar->id.bdf_ext); - -@@ -1279,17 +1280,26 @@ out: - - static int ath10k_core_fetch_board_file(struct ath10k *ar) - { -- char boardname[100]; -+ char boardname[100], fallback_boardname[100]; - int ret; - -- ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname)); -+ ret = ath10k_core_create_board_name(ar, boardname, -+ sizeof(boardname), true); - if (ret) { - ath10k_err(ar, "failed to create board name: %d", ret); - return ret; - } - -+ ret = ath10k_core_create_board_name(ar, fallback_boardname, -+ sizeof(boardname), false); -+ if (ret) { -+ ath10k_err(ar, "failed to create fallback board name: %d", ret); -+ return ret; -+ } -+ - ar->bd_api = 2; - ret = ath10k_core_fetch_board_data_api_n(ar, boardname, -+ fallback_boardname, - ATH10K_BOARD_API2_FILE); - if (!ret) - goto success; |