wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/668-ath12k-regdb-encoding-board-2-binary.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

435 lines
13 KiB
Diff

From 143b11a194c50b6666983c0f8d0bbd6bb64404eb Mon Sep 17 00:00:00 2001
From: Karthik M <quic_karm@quicinc.com>
Date: Tue, 9 Aug 2022 22:10:12 +0530
Subject: [PATCH] ath12k: Encoding regdb.bin in board-2.bin
Add support to encode regdb.bin in board-2.bin along with the bdf files.
Check Regdb.bin file in board-2.bin first. If its not found, check in
the firmware location of the chip.
Signed-off-by: Karthik M <quic_karm@quicinc.com>
---
drivers/net/wireless/ath/ath12k/core.c | 2 +-
drivers/net/wireless/ath/ath12k/core.h | 3 +++
drivers/net/wireless/ath/ath12k/qmi.c | 16 ++++++++++++----
3 files changed, 16 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -325,7 +325,7 @@ int ath12k_core_check_dt(struct ath12k_b
}
static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
- size_t name_len)
+ char *defaultname, size_t name_len)
{
/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
char variant[9 + ATH12K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
@@ -333,12 +333,33 @@ static int ath12k_core_create_board_name
if (ab->qmi.target.bdf_ext[0] != '\0')
scnprintf(variant, sizeof(variant), ",variant=%s",
ab->qmi.target.bdf_ext);
-
- scnprintf(name, name_len,
- "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
- ath12k_bus_str(ab->hif.bus),
- ab->qmi.target.chip_id,
- ab->qmi.target.board_id, variant);
+ switch (ab->id.bdf_search) {
+ case ATH12K_BDF_SEARCH_BUS_AND_BOARD:
+ scnprintf(name, name_len,
+ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,"
+ "subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
+ ath12k_bus_str(ab->hif.bus),
+ ab->id.vendor, ab->id.device,
+ ab->id.subsystem_vendor,
+ ab->id.subsystem_device,
+ ab->qmi.target.chip_id,
+ ab->qmi.target.board_id,
+ variant);
+ break;
+ default:
+ scnprintf(name, name_len,
+ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
+ ath12k_bus_str(ab->hif.bus),
+ ab->qmi.target.chip_id,
+ ab->qmi.target.board_id, variant);
+
+ scnprintf(defaultname, name_len,
+ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
+ ath12k_bus_str(ab->hif.bus),
+ ab->qmi.target.chip_id,
+ ATH12K_DEFAULT_ID, variant);
+ break;
+ }
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot using board name '%s'\n", name);
@@ -379,7 +400,9 @@ static int ath12k_core_parse_bd_ie_board
struct ath12k_board_data *bd,
const void *buf, size_t buf_len,
const char *boardname,
- int bd_ie_type)
+ int ie_id,
+ int name_id,
+ int data_id)
{
const struct ath12k_fw_ie *hdr;
bool name_match_found;
@@ -389,7 +412,7 @@ static int ath12k_core_parse_bd_ie_board
name_match_found = false;
- /* go through ATH12K_BD_IE_BOARD_ elements */
+ /* go through ATH12K_BD_IE_BOARD_/ATH12K_BD_IE_REGDB_ elements */
while (buf_len > sizeof(struct ath12k_fw_ie)) {
hdr = buf;
board_ie_id = le32_to_cpu(hdr->id);
@@ -400,48 +423,51 @@ static int ath12k_core_parse_bd_ie_board
buf += sizeof(*hdr);
if (buf_len < ALIGN(board_ie_len, 4)) {
- ath12k_err(ab, "invalid ATH12K_BD_IE_BOARD length: %zu < %zu\n",
- buf_len, ALIGN(board_ie_len, 4));
+ ath12k_err(ab, "invalid %s length: %zu < %zu\n",
+ ath12k_bd_ie_type_str(ie_id),
+ buf_len, ALIGN(board_ie_len, 4));
ret = -EINVAL;
goto out;
}
- switch (board_ie_id) {
- case ATH12K_BD_IE_BOARD_NAME:
+ if (board_ie_id == name_id) {
ath12k_dbg_dump(ab, ATH12K_DBG_BOOT, "board name", "",
board_ie_data, board_ie_len);
if (board_ie_len != strlen(boardname))
- break;
+ goto next;
ret = memcmp(board_ie_data, boardname, strlen(boardname));
if (ret)
- break;
+ goto next;
name_match_found = true;
ath12k_dbg(ab, ATH12K_DBG_BOOT,
- "boot found match for name '%s'",
+ "boot found match %s for name '%s'",
+ ath12k_bd_ie_type_str(ie_id),
boardname);
- break;
- case ATH12K_BD_IE_BOARD_DATA:
+ } else if (board_ie_id == data_id) {
if (!name_match_found)
/* no match found */
- break;
+ goto next;
ath12k_dbg(ab, ATH12K_DBG_BOOT,
- "boot found board data for '%s'", boardname);
+ "boot found %s for '%s'",
+ ath12k_bd_ie_type_str(ie_id),
+ boardname);
bd->data = board_ie_data;
bd->len = board_ie_len;
ret = 0;
goto out;
- default:
- ath12k_warn(ab, "unknown ATH12K_BD_IE_BOARD found: %d\n",
- board_ie_id);
- break;
+ } else {
+ ath12k_warn(ab, "unknown %s id found: %d\n",
+ ath12k_bd_ie_type_str(ie_id),
+ board_ie_id);
}
+next:
/* jump over the padding */
board_ie_len = ALIGN(board_ie_len, 4);
@@ -457,8 +483,11 @@ out:
}
static int ath12k_core_fetch_board_data_api_n(struct ath12k_base *ab,
- struct ath12k_board_data *bd,
- const char *boardname)
+ struct ath12k_board_data *bd,
+ const char *boardname,
+ int ie_id_match,
+ int name_id,
+ int data_id)
{
size_t len, magic_len;
const u8 *data;
@@ -523,15 +552,16 @@ static int ath12k_core_fetch_board_data_
goto err;
}
- switch (ie_id) {
- case ATH12K_BD_IE_BOARD:
+ if (ie_id == ie_id_match) {
ret = ath12k_core_parse_bd_ie_board(ab, bd, data,
ie_len,
boardname,
- ATH12K_BD_IE_BOARD);
+ ie_id_match,
+ name_id,
+ data_id);
if (ret == -ENOENT)
/* no match found, continue */
- break;
+ goto next;
else if (ret)
/* there was an error, bail out */
goto err;
@@ -539,6 +569,7 @@ static int ath12k_core_fetch_board_data_
goto out;
}
+next:
/* jump over the padding */
ie_len = ALIGN(ie_len, 4);
@@ -548,9 +579,10 @@ static int ath12k_core_fetch_board_data_
out:
if (!bd->data || !bd->len) {
- ath12k_err(ab,
- "failed to fetch board data for %s from %s\n",
- boardname, filepath);
+ ath12k_dbg(ab, ATH12K_DBG_BOOT,
+ "failed to fetch %s for %s from %s\n",
+ ath12k_bd_ie_type_str(ie_id_match),
+ boardname, filepath);
ret = -ENODATA;
goto err;
}
@@ -567,6 +599,7 @@ int ath12k_core_fetch_board_data_api_1(s
char *filename)
{
bd->fw = ath12k_core_firmware_request(ab, filename);
+
if (IS_ERR(bd->fw))
return PTR_ERR(bd->fw);
@@ -576,28 +609,43 @@ int ath12k_core_fetch_board_data_api_1(s
return 0;
}
-#define BOARD_NAME_SIZE 100
int ath12k_core_fetch_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd)
{
- char boardname[BOARD_NAME_SIZE];
+ char boardname[BOARD_NAME_SIZE], boarddefaultname[BOARD_NAME_SIZE];
int ret;
- ret = ath12k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
+ ret = ath12k_core_create_board_name(ab, boardname, boarddefaultname,
+ BOARD_NAME_SIZE);
if (ret) {
ath12k_err(ab, "failed to create board name: %d", ret);
return ret;
}
ab->bd_api = 2;
- ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname);
+ ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname,
+ ATH12K_BD_IE_BOARD,
+ ATH12K_BD_IE_BOARD_NAME,
+ ATH12K_BD_IE_BOARD_DATA);
+ if (!ret)
+ goto success;
+
+ ret = ath12k_core_fetch_board_data_api_n(ab, bd, boarddefaultname,
+ ATH12K_BD_IE_BOARD,
+ ATH12K_BD_IE_BOARD_NAME,
+ ATH12K_BD_IE_BOARD_DATA);
if (!ret)
goto success;
ab->bd_api = 1;
ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_DEFAULT_BOARD_FILE);
if (ret) {
- ath12k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
+ ath12k_err(ab, "failed to fetch board-2.bin from %s\n",
ab->hw_params->fw.dir);
+ } else {
+ ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_BOARD_API2_FILE);
+ if (ret)
+ ath12k_err(ab, "failed to fetch board-2.bin from %s\n",
+ ab->hw_params->fw.dir);
return ret;
}
@@ -606,6 +654,45 @@ success:
return 0;
}
+int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd)
+{
+ char regdbname[REGDB_NAME_SIZE], regdbdefaultname[REGDB_NAME_SIZE];
+ int ret;
+
+ ret = ath12k_core_create_board_name(ab, regdbname, regdbdefaultname,
+ REGDB_NAME_SIZE);
+ if (ret) {
+ ath12k_err(ab, "failed to create regdb name: %d", ret);
+ return ret;
+ }
+
+ ab->bd_api = 2;
+ ret = ath12k_core_fetch_board_data_api_n(ab, bd, regdbname,
+ ATH12K_BD_IE_REGDB,
+ ATH12K_BD_IE_REGDB_NAME,
+ ATH12K_BD_IE_REGDB_DATA);
+ if (!ret)
+ goto success;
+
+ ret = ath12k_core_fetch_board_data_api_n(ab, bd, regdbdefaultname,
+ ATH12K_BD_IE_REGDB,
+ ATH12K_BD_IE_REGDB_NAME,
+ ATH12K_BD_IE_REGDB_DATA);
+ if (!ret)
+ goto success;
+
+ ab->bd_api = 1;
+ ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_REGDB_FILE_NAME);
+ if (ret) {
+ ath12k_err(ab, "failed to fetch %s file from %s\n",
+ ATH12K_REGDB_FILE_NAME, ab->hw_params->fw.dir);
+ return ret;
+ }
+
+success:
+ ath12k_dbg(ab, ATH12K_DBG_BOOT, "using board api %d\n", ab->bd_api);
+ return 0;
+}
static void ath12k_core_stop(struct ath12k_base *ab)
{
lockdep_assert_held(&ab->ag->mutex_lock);
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -60,6 +60,11 @@ enum ath12k_supported_bw {
ATH12K_BW_320 = 4,
};
+enum ath12k_bdf_search {
+ ATH12K_BDF_SEARCH_DEFAULT,
+ ATH12K_BDF_SEARCH_BUS_AND_BOARD,
+};
+
enum wme_ac {
WME_AC_BE,
WME_AC_BK,
@@ -853,6 +858,9 @@ struct ath12k_pdev {
struct mlo_timestamp timestamp;
};
+#define BOARD_NAME_SIZE 100
+#define REGDB_NAME_SIZE 100
+
struct ath12k_board_data {
const struct firmware *fw;
const void *data;
@@ -913,6 +921,13 @@ struct ath12k_reg_freq {
u32 end_freq;
};
+struct vendor_info {
+ enum ath12k_bdf_search bdf_search;
+ u32 vendor;
+ u32 device;
+ u32 subsystem_vendor;
+ u32 subsystem_device;
+};
struct ath12k_hw {
struct ieee80211_hw *hw;
@@ -1058,6 +1073,8 @@ struct ath12k_base {
bool stats_disable;
u32 rx_hash;
+ struct vendor_info id;
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
@@ -1198,6 +1215,8 @@ int ath12k_core_fetch_board_data_api_1(s
char *filename);
int ath12k_core_fetch_bdf(struct ath12k_base *ath12k,
struct ath12k_board_data *bd);
+int ath12k_core_fetch_regdb(struct ath12k_base *ath12k,
+ struct ath12k_board_data *bd);
void ath12k_core_free_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd);
int ath12k_core_check_dt(struct ath12k_base *ath12k);
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -3441,12 +3441,12 @@ static int ath12k_qmi_load_bdf_qmi(struc
break;
case ATH12K_QMI_BDF_TYPE_REGDB:
- ret = ath12k_core_fetch_board_data_api_1(ab, &bd,
- ATH12K_REGDB_FILE_NAME);
+ ret = ath12k_core_fetch_regdb(ab, &bd);
if (ret) {
- ath12k_warn(ab, "qmi failed to load regdb bin:\n");
+ ath12k_warn(ab, "qmi failed to load regdb:\n");
goto out;
}
+ type = ATH12K_QMI_BDF_TYPE_REGDB;
break;
default:
ath12k_warn(ab, "unknown file type for load %d", type);
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -84,6 +84,8 @@
#define ATH12K_AMSS_FILE "amss.bin"
#define ATH12K_M3_FILE "m3.bin"
#define ATH12K_REGDB_FILE_NAME "regdb.bin"
+#define ATH12K_REGDB_BINARY "regdb"
+#define ATH12K_DEFAULT_ID 255
enum ath12k_hw_rate_cck {
ATH12K_HW_RATE_CCK_LP_11M = 0,
@@ -255,12 +257,32 @@ enum ath12k_bd_ie_board_type {
ATH12K_BD_IE_BOARD_DATA = 1,
};
+enum ath12k_bd_ie_regdb_type {
+ ATH12K_BD_IE_REGDB_NAME = 0,
+ ATH12K_BD_IE_REGDB_DATA = 1,
+};
+
enum ath12k_bd_ie_type {
/* contains sub IEs of enum ath12k_bd_ie_board_type */
ATH12K_BD_IE_BOARD = 0,
- ATH12K_BD_IE_BOARD_EXT = 1,
+ ATH12K_BD_IE_REGDB = 1,
+ ATH12K_BD_IE_BOARD_EXT = 2,
};
+static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type)
+{
+ switch (type) {
+ case ATH12K_BD_IE_BOARD:
+ return "board data";
+ case ATH12K_BD_IE_REGDB:
+ return "regdb data";
+ case ATH12K_BD_IE_BOARD_EXT:
+ return "board data ext";
+ }
+
+ return "unknown";
+}
+
struct ath12k_hw_regs {
u32 hal_tcl1_ring_id;
u32 hal_tcl1_ring_misc;