Code swap is a mechanism to use host memory to store
some fw binary code segment. Ath10k host driver allocates
and loads the code swap binary into the host memory and
configures the target with the host allocated memory
information at the address taken from code swap binary.
This patch adds code swap support for firmware binary.
Code swap binary for firmware bin is available in
ATH10K_FW_IE_FW_CODE_SWAP_IMAGE.
Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
drivers/net/wireless/ath/ath10k/Makefile | 3 +-
drivers/net/wireless/ath/ath10k/core.c | 24
drivers/net/wireless/ath/ath10k/core.h | 7 ++
drivers/net/wireless/ath/ath10k/hw.h | 3 +
drivers/net/wireless/ath/ath10k/swap.c | 208 +++
drivers/net/wireless/ath/ath10k/swap.h | 72 +++
6 files changed, 316 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/ath/ath10k/swap.c
create mode 100644 drivers/net/wireless/ath/ath10k/swap.h
diff --git a/drivers/net/wireless/ath/ath10k/Makefile
b/drivers/net/wireless/ath/ath10k/Makefile
index 9729e69..c04fb00 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -11,7 +11,8 @@ ath10k_core-y += mac.o \
wmi-tlv.o \
bmi.o \
hw.o \
-p2p.o
+p2p.o \
+swap.o
ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/ath10k/core.c
b/drivers/net/wireless/ath/ath10k/core.c
index f239e96..c5f5d16 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -470,6 +470,13 @@ static int ath10k_download_fw(struct ath10k *ar, enum
ath10k_firmware_mode mode)
data = ar-firmware_data;
data_len = ar-firmware_len;
mode_name = normal;
+ ret = ath10k_swap_code_seg_configure(ar,
+ ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
+ if (ret) {
+ ath10k_err(ar, failed to configure fw code swap: %d\n,
+ ret);
+ return ret;
+ }
break;
case ATH10K_FIRMWARE_MODE_UTF:
data = ar-testmode.utf-data;
@@ -509,6 +516,8 @@ static void ath10k_core_free_firmware_files(struct ath10k
*ar)
if (!IS_ERR(ar-cal_file))
release_firmware(ar-cal_file);
+ ath10k_swap_code_seg_release(ar);
+
ar-board = NULL;
ar-board_data = NULL;
ar-board_len = 0;
@@ -522,6 +531,7 @@ static void ath10k_core_free_firmware_files(struct ath10k
*ar)
ar-firmware_len = 0;
ar-cal_file = NULL;
+
}
static int ath10k_fetch_cal_file(struct ath10k *ar)
@@ -795,6 +805,13 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k
*ar, const char *name)
ath10k_dbg(ar, ATH10K_DBG_BOOT, found fw ie htt op
version %d\n,
ar-htt.op_version);
break;
+ case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+ found fw code swap image ie (%zd B)\n,
+ ie_len);
+ ar-swap.firmware_codeswap_data = data;
+ ar-swap.firmware_codeswap_len = ie_len;
+ break;
default:
ath10k_warn(ar, Unknown FW IE: %u\n,
le32_to_cpu(hdr-id));
@@ -1388,6 +1405,13 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
+ ret = ath10k_swap_code_seg_init(ar);
+ if (ret) {
+ ath10k_err(ar, failed to initialize code swap segment: %d\n,
+ ret);
+ goto err_free_firmware_files;
+ }
+
mutex_lock(ar-conf_mutex);
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
diff --git a/drivers/net/wireless/ath/ath10k/core.h
b/drivers/net/wireless/ath/ath10k/core.h
index 993cd36..b9145f5 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -36,6 +36,7 @@
#include spectral.h
#include thermal.h
#include wow.h
+#include swap.h
#define MS(_v, _f) (((_v) _f##_MASK) _f##_LSB)
#define SM(_v, _f) (((_v) _f##_LSB) _f##_MASK)
@@ -603,6 +604,12 @@ struct ath10k {
const struct firmware *cal_file;
+ struct {
+ const void *firmware_codeswap_data;
+ size_t firmware_codeswap_len;
+ struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
+ } swap;
+
char spec_board_id[100];
bool spec_board_loaded;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h