Last active
August 11, 2024 16:39
-
-
Save qosmio/bd0941c6e0f6ddd2da411fd6ff4d24d2 to your computer and use it in GitHub Desktop.
999-904-allow-power-increase-set-vht160.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/drivers/net/wireless/ath/ath11k/core.c | |
+++ b/drivers/net/wireless/ath/ath11k/core.c | |
@@ -24,6 +24,10 @@ module_param_named(nss_offload, nss_offl | |
MODULE_PARM_DESC(nss_offload, "Enable NSS Offload support"); | |
#endif | |
+static int poweroffset=0; | |
+module_param_named(poweroffset, poweroffset, uint, 0644); | |
+MODULE_PARM_DESC(poweroffset, "power offset for power table. negative values are permitted. units in 0.25db"); | |
+ | |
unsigned int ath11k_debug_mask; | |
EXPORT_SYMBOL(ath11k_debug_mask); | |
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644); | |
@@ -1415,6 +1419,479 @@ int ath11k_core_fetch_board_data_api_1(s | |
return 0; | |
} | |
+static void calcrawchecksum(void *caldata, int offset, int size) | |
+{ | |
+ int i; | |
+ u16 *cdata = (u16 *)caldata; | |
+ u16 *ptr_eeprom = (u16 *)caldata; | |
+ u16 crc = 0; | |
+ cdata[offset] = 0; | |
+ for (i = 0; i < size; i += 2) { | |
+ crc ^= le16_to_cpu(*ptr_eeprom); | |
+ ptr_eeprom++; | |
+ } | |
+ crc = ~crc; | |
+ cdata[offset] = cpu_to_le16(crc); | |
+} | |
+ | |
+static void calcchecksum(void *caldata, int size) | |
+{ | |
+ calcrawchecksum(caldata, 5, size); | |
+} | |
+ | |
+static void removeregdomain(struct ath11k_base *ab, const void *data, int type) | |
+{ | |
+ u16 *s = (u16 *)data; | |
+ if (s[52 / 2]) | |
+ ath11k_info(ab, "remove regdomain0 0x%02x\n", s[52 / 2]); | |
+ s[52 / 2] = 0; | |
+ if (type == 0) { | |
+ if (s[1104 / 2]) | |
+ ath11k_info(ab, "remove regdomain1 0x%02x\n", s[1104 / 2]); | |
+ s[1104 / 2] = 0; | |
+ } else { | |
+ if (s[1112 / 2]) | |
+ ath11k_info(ab, "remove regdomain1 0x%02x\n", s[1112 / 2]); | |
+ s[1112 / 2] = 0; | |
+ if (s[1280 / 2]) | |
+ ath11k_info(ab, "remove regdomain2 0x%02x\n", s[1280 / 2]); | |
+ s[1280 / 2] = 0; | |
+ if (s[1448 / 2]) | |
+ ath11k_info(ab, "remove regdomain3 0x%02x\n", s[1448 / 2]); | |
+ s[1448 / 2] = 0; | |
+ } | |
+} | |
+enum { | |
+ WHAL_OPFLAGS_11A = 0x00000001, | |
+ WHAL_OPFLAGS_11G = 0x00000002, | |
+ WHAL_OPFLAGS_5G_HT40 = 0x00000004, | |
+ WHAL_OPFLAGS_2G_HT40 = 0x00000008, | |
+ WHAL_OPFLAGS_5G_HT20 = 0x00000010, | |
+ WHAL_OPFLAGS_2G_HT20 = 0x00000020, | |
+ WHAL_OPFLAGS_5G_VHT20 = 0x00000040, | |
+ WHAL_OPFLAGS_2G_VHT20 = 0x00000080, | |
+ WHAL_OPFLAGS_5G_VHT40 = 0x00000100, | |
+ WHAL_OPFLAGS_2G_VHT40 = 0x00000200, | |
+ WHAL_OPFLAGS_5G_VHT80 = 0x00000400, | |
+ WHAL_OPFLAGS_5G_VHT80P80 = 0x00000800, | |
+ WHAL_OPFLAGS_5G_VHT160 = 0x00001000 | |
+}; | |
+ | |
+struct regdb_entry_8074 { | |
+ u16 country_code; | |
+ u16 reg_dmn_pair_id; | |
+ u8 alpha[3]; | |
+ u8 alpha2_11d[3]; | |
+ u8 max_bw_2g; | |
+ u8 max_bw_5g; | |
+ u8 phymode_bitmap; | |
+ u8 pad; | |
+}; | |
+ | |
+struct regdb_entry_9074 { | |
+ u16 country_code; | |
+ u16 reg_dmn_pair_id; | |
+ u8 super_dmn_6g_id; | |
+ u8 alpha[3]; | |
+ u8 alpha2_11d[3]; | |
+ u8 max_bw_2g; | |
+ u8 max_bw_5g; | |
+ u8 max_bw_6g; | |
+ u8 phymode_bitmap; | |
+ u8 flags; | |
+}; | |
+ | |
+struct regdb_8074 { | |
+ u16 nvid; | |
+ u16 nvlen; | |
+ u32 nvflag; | |
+ struct regdb_entry_8074 entry[0]; | |
+}; | |
+struct regdb_9074 { | |
+ u16 nvid; | |
+ u16 nvlen; | |
+ u32 nvflag; | |
+ struct regdb_entry_9074 entry[0]; | |
+}; | |
+ | |
+void patchrawregdb(struct ath11k_base *ab, const void *bd) | |
+{ | |
+ struct regdb_entry_8074 *regdb1 = (struct regdb_entry_8074 *)bd; | |
+ struct regdb_entry_9074 *regdb2 = (struct regdb_entry_9074 *)bd; | |
+ | |
+ /* | |
+ * we detect here which format is used. since some chipsets like 9074 do make use of both formats | |
+ * so easiest way is to check for the reg domain code which is always identical as first entry | |
+ */ | |
+ if (regdb1[0].alpha[0] == 65 && regdb1[0].alpha[1] == 70) { | |
+ int i; | |
+ ath11k_info(ab, "patch reg db in ipq8074 format\n"); | |
+ for (i = 0; i < 220; i++) { | |
+ if (regdb1[i].max_bw_5g == 80) { | |
+ ath11k_info(ab, "patch entry %d\n", i); | |
+ regdb1[i].max_bw_5g = 160; | |
+ } | |
+ } | |
+ } else if (regdb2[0].alpha[0] == 65 && regdb2[0].alpha[1] == 70) { | |
+ int i; | |
+ ath11k_info(ab, "patch reg db in qcn9074 format\n"); | |
+ for (i = 0; i < 220; i++) { | |
+ if (regdb2[i].max_bw_5g == 80) { | |
+ ath11k_info(ab, "patch entry %d\n", i); | |
+ regdb2[i].max_bw_5g = 160; | |
+ } | |
+ } | |
+ } else { | |
+ ath11k_info(ab, "something wrong. did not find a regdb\n"); | |
+ } | |
+} | |
+ | |
+void patchregdb(struct ath11k_base *ab, void *bd) | |
+{ | |
+ int id; | |
+ u8 *data = (u8 *)bd; | |
+ // int i; | |
+ struct regdb_8074 *regdb1; | |
+ struct regdb_9074 *regdb2; | |
+ switch (ab->hw_rev) { | |
+ case ATH11K_HW_IPQ8074: | |
+ id = 20; | |
+ break; | |
+ case ATH11K_HW_IPQ6018_HW10: | |
+ id = 20; | |
+ break; | |
+ case ATH11K_HW_QCN9074_HW10: | |
+ id = 19; | |
+ break; | |
+ case ATH11K_HW_IPQ5018_HW10: | |
+ id = 20; | |
+ break; | |
+ default: | |
+ return; | |
+ } | |
+ regdb1 = (struct regdb_8074 *)data; | |
+ regdb2 = (struct regdb_9074 *)data; | |
+ while (regdb1->nvid <= id) { | |
+ if (regdb1->nvid == id) { | |
+ patchrawregdb(ab, regdb1->entry); | |
+ break; | |
+ } | |
+ data += regdb1->nvlen + 4; | |
+ regdb1 = (struct regdb_8074 *)data; | |
+ regdb2 = (struct regdb_9074 *)data; | |
+ } | |
+} | |
+ | |
+struct targetpower { | |
+ u16 nvid; | |
+ u16 nvlen; | |
+ u32 nvflag; | |
+ s8 power[0]; | |
+}; | |
+ | |
+static void showdbm(struct ath11k_base *ab, const char *lead, int val) | |
+{ | |
+ ath11k_info(ab, "%s %d.%d dbm\n", lead, val / 4, (((val % 4) * 10) % 4) ? ((val % 4) * 100) / 4 : ((val % 4) * 10) / 4); | |
+} | |
+ | |
+/* units in 0.25 db */ | |
+static void patchpower(struct ath11k_base *ab, const void *bd, int poweroffset) | |
+{ | |
+ int id; | |
+ u8 *data = (u8 *)bd; | |
+ int i; | |
+ /* int nvlen; */ | |
+ struct targetpower *power; | |
+ switch (ab->hw_rev) { | |
+ case ATH11K_HW_IPQ8074: | |
+ id = 12; | |
+ break; | |
+ case ATH11K_HW_IPQ6018_HW10: | |
+ id = 12; | |
+ break; | |
+ case ATH11K_HW_QCN9074_HW10: | |
+ id = 11; | |
+ break; | |
+ case ATH11K_HW_IPQ5018_HW10: | |
+ id = 11; | |
+ break; | |
+ default: | |
+ return; | |
+ } | |
+ power = (struct targetpower *)data; | |
+ while (power->nvid <= id) { | |
+ if (power->nvid == id) { | |
+ int max = -255; | |
+ for (i = 0; i < (power->nvlen - 4); i++) { | |
+ if ((power->power[i]) > max) | |
+ max = power->power[i]; | |
+ } | |
+ showdbm(ab, "maximum calibrated power", max); | |
+ if (max + poweroffset > 126) { | |
+ poweroffset = 126 - max; | |
+ showdbm(ab, "limit poweroffset to", poweroffset); | |
+ } | |
+ for (i = 0; i < (power->nvlen - 4); i++) { | |
+ int newpower = power->power[i] + poweroffset; | |
+ if (power->power[i] && newpower >= -40 && newpower <= 126) | |
+ power->power[i] = newpower; | |
+ } | |
+ if (poweroffset) { | |
+ max = -255; | |
+ for (i = 0; i < (power->nvlen - 4); i++) { | |
+ if ((power->power[i]) > max) | |
+ max = power->power[i]; | |
+ } | |
+ showdbm(ab, "new maximum calibrated power is", | |
+ max); | |
+ } | |
+ break; | |
+ } | |
+ data += power->nvlen + 4; | |
+ power = (struct targetpower *)data; | |
+ } | |
+} | |
+ | |
+#if 0 | |
+struct gainperchanperchain { | |
+ u8 gain[4]; | |
+}; | |
+struct perchain2g { | |
+ u8 gainfreq[3]; | |
+ u8 pad; | |
+ struct gainperchanperchain gain[3]; | |
+}; | |
+struct perchain5g { | |
+ u8 gainfreq[8]; | |
+ struct gainperchanperchain gain[8]; | |
+}; | |
+struct antennagain_8074 { | |
+ u16 nvid; | |
+ u16 nvlen; | |
+ u32 nvflag; | |
+ struct perchain5g gain5g[3]; | |
+ struct perchain2g gain2g; | |
+ u8 featureenable; | |
+}; | |
+ | |
+/* units in 0.25 db */ | |
+static void patchantennagain(struct ath11k_base *ab, const void *bd) | |
+{ | |
+ int id; | |
+ u8 *data = (u8 *)bd; | |
+ int i; | |
+ struct targetpower *power; | |
+ switch (ab->hw_rev) { | |
+ case ATH11K_HW_IPQ8074: | |
+ id = 22; | |
+ break; | |
+ case ATH11K_HW_IPQ6018_HW10: | |
+ id = 22; | |
+ break; | |
+ case ATH11K_HW_QCN9074_HW10: | |
+ id = 20; | |
+ break; | |
+ case ATH11K_HW_IPQ5018_HW10: | |
+ id = 21; | |
+ break; | |
+ default: | |
+ return; | |
+ } | |
+ power = (struct targetpower *)data; | |
+ while (power->nvid <= id) { | |
+ if (power->nvid == id) { | |
+ int max = 0; | |
+ for (i = 0; i < (power->nvlen - 4); i++) { | |
+ if ((power->power[i]) > max) | |
+ max = power->power[i]; | |
+ } | |
+ showdbm(ab, "antenna gain", max); | |
+ break; | |
+ } | |
+ data += power->nvlen + 4; | |
+ power = (struct targetpower *)data; | |
+ } | |
+} | |
+#endif | |
+ | |
+static void patchradiolimits(struct ath11k_base *ab, const void *bd) | |
+{ | |
+ u8 *data = (u8 *)bd; | |
+ if (ab->hw_rev != ATH11K_HW_IPQ8074) | |
+ return; | |
+ switch (data[557]) { | |
+ case 0: | |
+ ath11k_info(ab, "RF_MODE: PHYA Only\n"); | |
+ break; | |
+ case 1: | |
+ ath11k_info(ab, "RF_MODE: DBS PHYA=5G, PHYB=2.4G\n"); | |
+ break; | |
+ case 2: | |
+ ath11k_info(ab, "RF_MODE: SBS PHYA0=5G, PHYA1=5G\n"); | |
+ break; | |
+ case 3: | |
+ ath11k_info(ab, "RF_MODE: PHYB Only\n"); | |
+ break; | |
+ case 4: | |
+ ath11k_info(ab, "RF_MODE: DBS_SBS PHYA0=5G (lower freq), PHYA1=5G (upper freq), PHYB=2.4G\n"); | |
+ // ath11k_info(ab, "patch to mode 5\n"); | |
+ // data[557] = 5; | |
+ break; | |
+ case 5: | |
+ ath11k_info(ab, "RF_MODE: DBS OR SBS PHYA0=5G, PHYA1=5G, PHYB=2.4G\n"); | |
+ break; | |
+ } | |
+} | |
+ | |
+struct boardflags { | |
+ u32 opflags; | |
+ u32 featureenable; | |
+ u32 miscconfig; | |
+ u32 reserved; | |
+ u16 txmask2g; | |
+ u16 rxmask2g; | |
+ u16 txmask5g; | |
+ u16 rxmask5g; | |
+}; | |
+ | |
+/* | |
+//offset 603 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.enable7115Chan 1 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.afc_local_rsvd 0 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.Deployment_Enable 1 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.Deployment_Type 1 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.Power_mode_mask 7 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.reserved[0] 0 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.reserved[1] 0 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.reserved[2] 0 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.reserved[3] 0 | |
+u8 COMMON_BDF_HEADER.baseBdfHeader.feature6GDeploymentConfig.reserved[4] 0 | |
+*/ | |
+ | |
+struct feature6g { | |
+ u8 enable7115Chan; // 1 | |
+ u8 afc_local_rsvd; // 0 | |
+ u8 Deployment_Enable; // 1 | |
+ u8 Deployment_Type; // 1 | |
+ u8 Power_mode_mask; // 7 | |
+}; | |
+ | |
+void patchvht160(struct ath11k_base *ab, const void *data, int phynum, int type) | |
+{ | |
+ u8 *s = (u8 *)data; | |
+ u32 *tmp; | |
+ u8 *regdb = (u8 *)data; | |
+ struct boardflags *f; | |
+ /* struct feature6g *f6g = (struct feature6g *)®db[603]; */ | |
+ if (!data) | |
+ return; | |
+ | |
+ tmp = (u32 *)&s[68]; | |
+ *tmp &= ~(1 << 13); | |
+ switch (phynum) { | |
+ case 0: | |
+ f = (struct boardflags *)&s[1040]; | |
+ if ((f->opflags & WHAL_OPFLAGS_5G_VHT80) && !(f->opflags & WHAL_OPFLAGS_5G_VHT160)) { | |
+ ath11k_info(ab, "patch board1 flags %X to %X\n", f->opflags, | |
+ f->opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160); | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT80P80; | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT160; | |
+ } | |
+ /* if (type) {OA | |
+ f->miscconfig |= 0x400; // 6ghz | |
+ f6g->enable7115Chan=1; | |
+ f6g->Deployment_Enable=1; | |
+ f6g->Deployment_Type=1; | |
+ f6g->Power_mode_mask=7; | |
+ }*/ | |
+ break; | |
+ case 1: | |
+ f = (struct boardflags *)&s[1208]; | |
+ if ((f->opflags & WHAL_OPFLAGS_5G_VHT80) && !(f->opflags & WHAL_OPFLAGS_5G_VHT160)) { | |
+ ath11k_info(ab, "patch board2 flags %X to %X\n", f->opflags, | |
+ f->opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160); | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT80P80; | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT160; | |
+ } | |
+ break; | |
+ case 2: | |
+ f = (struct boardflags *)&s[1376]; | |
+ if ((f->opflags & WHAL_OPFLAGS_5G_VHT80) && !(f->opflags & WHAL_OPFLAGS_5G_VHT160)) { | |
+ ath11k_info(ab, "patch board3 flags %X to %X\n", f->opflags, | |
+ f->opflags | WHAL_OPFLAGS_5G_VHT80P80 | WHAL_OPFLAGS_5G_VHT160); | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT80P80; | |
+ f->opflags |= WHAL_OPFLAGS_5G_VHT160; | |
+ } | |
+ break; | |
+ } | |
+ /* patch max bw 5g to 160 */ | |
+ patchregdb(ab, regdb); | |
+} | |
+ | |
+void show_bdf_version(const char *name, struct ath11k_base *ab, const void *bd) | |
+{ | |
+ u8 *data = (u8 *)bd; | |
+ u32 offset; | |
+ u8 patch[3]; | |
+ u32 size = 0x10000; | |
+ if (!bd) | |
+ return; | |
+ switch (ab->hw_rev) { | |
+ case ATH11K_HW_IPQ8074: | |
+ patch[0] = 7; | |
+ patch[1] = 2; | |
+ patch[2] = 3; | |
+ offset = 559; | |
+ size = 0x20000; | |
+ removeregdomain(ab, bd, 1); | |
+ patchvht160(ab, bd, 0, 0); | |
+ patchvht160(ab, bd, 1, 0); | |
+ patchvht160(ab, bd, 2, 0); | |
+ break; | |
+ case ATH11K_HW_IPQ6018_HW10: | |
+ patch[0] = 1; | |
+ patch[1] = 4; | |
+ patch[2] = 3; | |
+ offset = 495; | |
+ size = 0x10000; | |
+ removeregdomain(ab, bd, 0); | |
+ break; | |
+ case ATH11K_HW_QCN9074_HW10: | |
+ patch[0] = 4; | |
+ patch[1] = 2; | |
+ patch[2] = 0; | |
+ offset = 555; | |
+ size = 0x20000; | |
+ removeregdomain(ab, bd, 0); | |
+ patchvht160(ab, bd, 0, 1); | |
+ break; | |
+ case ATH11K_HW_IPQ5018_HW10: | |
+ patch[0] = 3; | |
+ patch[1] = 4; | |
+ patch[2] = 0; | |
+ offset = 0x1eb; | |
+ size = 0x20000; | |
+ removeregdomain(ab, bd, 0); | |
+ break; | |
+ default: | |
+ return; | |
+ } | |
+ | |
+ if (data) { | |
+ // if (data[offset] != patch[0]) { | |
+ // ath11k_info(ab, "warning. incompatible bdf template revision v%d.%d.%d, boardrev %d (major version must be %d)\n", data[offset], data[offset+1], data[offset+2], data[59], patch[0]); | |
+ // } else | |
+ { | |
+ ath11k_info(ab, "%s template revision v%d.%d.%d, boardrev %d, patch to v%d.%d.%d\n", name, data[offset], | |
+ data[offset + 1], data[offset + 2], data[59], patch[0], patch[1], patch[2]); | |
+ memcpy(&data[offset], patch, 3); | |
+ patchpower(ab, data, poweroffset); | |
+ patchradiolimits(ab, data); | |
+ calcchecksum(data, size); | |
+ } | |
+ } | |
+} | |
+ | |
#define BOARD_NAME_SIZE 200 | |
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) | |
{ | |
@@ -1441,8 +1918,10 @@ int ath11k_core_fetch_bdf(struct ath11k_ | |
ATH11K_BD_IE_BOARD, | |
ATH11K_BD_IE_BOARD_NAME, | |
ATH11K_BD_IE_BOARD_DATA); | |
- if (!ret) | |
+ if (!ret) { | |
+ show_bdf_version("bdf", ab, bd->data); | |
goto exit; | |
+ } | |
fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL); | |
if (!fallback_boardname) { | |
@@ -1461,8 +1940,10 @@ int ath11k_core_fetch_bdf(struct ath11k_ | |
ATH11K_BD_IE_BOARD, | |
ATH11K_BD_IE_BOARD_NAME, | |
ATH11K_BD_IE_BOARD_DATA); | |
- if (!ret) | |
+ if (!ret) { | |
+ show_bdf_version("bdf", ab, bd->data); | |
goto exit; | |
+ } | |
chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL); | |
if (!chip_id_boardname) { | |
@@ -1482,8 +1963,10 @@ int ath11k_core_fetch_bdf(struct ath11k_ | |
ATH11K_BD_IE_BOARD_NAME, | |
ATH11K_BD_IE_BOARD_DATA); | |
- if (!ret) | |
+ if (!ret) { | |
+ show_bdf_version("bdf", ab, bd->data); | |
goto exit; | |
+ } | |
bd_api = 1; | |
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); | |
@@ -1501,6 +1984,8 @@ int ath11k_core_fetch_bdf(struct ath11k_ | |
ath11k_err(ab, "failed to fetch board.bin from %s\n", | |
ab->hw_params.fw.dir); | |
+ } else { | |
+ show_bdf_version("bdf", ab, bd->data); | |
} | |
exit: | |
@@ -1530,8 +2015,11 @@ int ath11k_core_fetch_regdb(struct ath11 | |
ATH11K_BD_IE_REGDB, | |
ATH11K_BD_IE_REGDB_NAME, | |
ATH11K_BD_IE_REGDB_DATA); | |
- if (!ret) | |
+ if (!ret) { | |
+ patchrawregdb(ab, (u8 *)bd->data + 2); | |
+ calcrawchecksum((u8 *)bd->data, 0, bd->len); | |
goto exit; | |
+ } | |
ret = ath11k_core_create_bus_type_board_name(ab, default_boardname, | |
BOARD_NAME_SIZE); | |
@@ -1545,14 +2033,20 @@ int ath11k_core_fetch_regdb(struct ath11 | |
ATH11K_BD_IE_REGDB, | |
ATH11K_BD_IE_REGDB_NAME, | |
ATH11K_BD_IE_REGDB_DATA); | |
- if (!ret) | |
+ if (!ret) { | |
+ patchrawregdb(ab, (u8 *)bd->data + 2); | |
+ calcrawchecksum((u8 *)bd->data, 0, bd->len); | |
goto exit; | |
+ } | |
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); | |
if (ret) | |
ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", | |
ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); | |
- | |
+ else { | |
+ patchrawregdb(ab, (u8 *)bd->data + 2); | |
+ calcrawchecksum((u8 *)bd->data, 0, bd->len); | |
+ } | |
exit: | |
if (!ret) | |
ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment