summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixelBot AutoMerger <android-nexus-securitybot@system.gserviceaccount.com>2022-12-11 18:50:50 -0800
committerSecurityBot <android-nexus-securitybot@system.gserviceaccount.com>2022-12-11 18:50:50 -0800
commitf1327bb9063fab7bf1c5e4d7272c14c96d9b598d (patch)
tree238c311fb737c68c886f8c0019c66803593a69dc
parent0bd17973b7a3a14f4ef06bb87ac0e531b4c5c236 (diff)
parentca2b8032c65cf7d53907332aa332b9ed03050827 (diff)
downloadcnss2-f1327bb9063fab7bf1c5e4d7272c14c96d9b598d.tar.gz
Merge android13-gs-pixel-5.10-tm-qpr2 into android13-gs-pixel-5.10-tm-qpr3
SBMerger: 478053055 Change-Id: I7b34cf88829ea0fb67d405b846a2a87d98070770 Signed-off-by: SecurityBot <android-nexus-securitybot@system.gserviceaccount.com>
-rw-r--r--cnss2/main.c4
-rw-r--r--cnss2/pci_platform.h3
-rw-r--r--cnss2/pci_platform_google.c169
-rw-r--r--cnss2/qmi.c15
4 files changed, 191 insertions, 0 deletions
diff --git a/cnss2/main.c b/cnss2/main.c
index 4ce0cf1..7505be5 100644
--- a/cnss2/main.c
+++ b/cnss2/main.c
@@ -25,6 +25,9 @@
#include "debug.h"
#include "genl.h"
#include "reg.h"
+#if IS_ENABLED(CONFIG_WCN_GOOGLE)
+#include "pci_platform.h"
+#endif
#define CNSS_DUMP_FORMAT_VER 0x11
#define CNSS_DUMP_FORMAT_VER_V2 0x22
@@ -3640,6 +3643,7 @@ static int cnss_probe(struct platform_device *plat_dev)
cnss_aop_mbox_init(plat_priv);
cnss_init_control_params(plat_priv);
#if IS_ENABLED(CONFIG_WCN_GOOGLE)
+ cnss_wlan_init_hardware_info();
plat_priv->recovery_enabled = true;
#endif //CONFIG_WCN_GOOGLE
diff --git a/cnss2/pci_platform.h b/cnss2/pci_platform.h
index 74ed99b..37ed20b 100644
--- a/cnss2/pci_platform.h
+++ b/cnss2/pci_platform.h
@@ -194,6 +194,9 @@ int _cnss_pci_get_reg_dump(struct cnss_pci_data *pci_priv,
#if IS_ENABLED(CONFIG_WCN_GOOGLE)
int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv);
+int cnss_wlan_init_hardware_info(void);
+int cnss_request_multiple_bdf_files(const struct firmware **fw,
+ const char *name, struct device *device);
#else
#if IS_ENABLED(CONFIG_ARCH_QCOM)
int cnss_pci_of_reserved_mem_device_init(struct cnss_pci_data *pci_priv);
diff --git a/cnss2/pci_platform_google.c b/cnss2/pci_platform_google.c
index 9154915..5da58b8 100644
--- a/cnss2/pci_platform_google.c
+++ b/cnss2/pci_platform_google.c
@@ -10,6 +10,57 @@
#include "debug.h"
#include "bus.h"
+#define PLT_PATH "/chosen/plat"
+#define CDB_PATH "/chosen/config"
+#define HW_SKU "sku"
+#define HW_STAGE "stage"
+#define HW_MAJOR "major"
+#define HW_MINOR "minor"
+#define MAX_HW_INFO_LEN 10u
+#define MAX_HW_EXT_LEN (MAX_HW_INFO_LEN * 2)
+#define MAX_FILE_COUNT 4u
+#define MAX_HW_STAGE 6u
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (u32)(sizeof(a) / sizeof(a[0]))
+#endif
+
+enum {
+ REV_SKU = 0,
+ REV_ONLY = 1,
+ SKU_ONLY = 2,
+ NO_EXT_NAME = 3
+};
+
+typedef struct {
+ char hw_id[MAX_HW_INFO_LEN];
+ char sku[MAX_HW_INFO_LEN];
+} sku_info_t;
+
+char hw_stage_name[MAX_HW_STAGE][MAX_HW_INFO_LEN] = {
+ "DEV",
+ "PROTO",
+ "EVT",
+ "DVT",
+ "PVT",
+ "MP",
+};
+
+sku_info_t sku_table[] = {
+ { {"G0DZQ"}, {"MMW"} },
+ { {"GWKK3"}, {"NA"} },
+ { {"G82U8"}, {"JPN"} },
+ { {"GHL1X"}, {"ROW"} }
+};
+
+typedef struct platform_hw_info {
+ unsigned long avail_bmap;
+ char ext_name[MAX_FILE_COUNT][MAX_HW_EXT_LEN];
+} platform_hw_info_t;
+
+platform_hw_info_t platform_hw_info;
+char val_revision[MAX_HW_INFO_LEN] = "NULL";
+char val_sku[MAX_HW_INFO_LEN] = "NULL";
+
extern int exynos_pcie_pm_resume(int ch_num);
extern void exynos_pcie_pm_suspend(int ch_num);
extern void exynos_pcie_set_perst(int ch_num, bool on);
@@ -316,3 +367,121 @@ void crash_info_handler(u8 *info)
strncpy(crash_info, info, string_len);
crash_info[string_len] = '\0';
}
+
+static void
+cnss_set_platform_ext_name(char *hw_rev, char* val_sku)
+{
+ memset(&platform_hw_info, 0, sizeof(platform_hw_info_t));
+
+ if (strncmp(hw_rev, "NULL", MAX_HW_INFO_LEN) != 0) {
+ if (strncmp(val_sku, "NULL", MAX_HW_INFO_LEN) != 0) {
+ snprintf(platform_hw_info.ext_name[REV_SKU], MAX_HW_EXT_LEN, "_%s_%s",
+ hw_rev, val_sku);
+ set_bit(REV_SKU, &platform_hw_info.avail_bmap);
+ }
+ snprintf(platform_hw_info.ext_name[REV_ONLY], MAX_HW_EXT_LEN, "_%s", hw_rev);
+ set_bit(REV_ONLY, &platform_hw_info.avail_bmap);
+ }
+
+ if (strncmp(val_sku, "NULL", MAX_HW_INFO_LEN) != 0) {
+ snprintf(platform_hw_info.ext_name[SKU_ONLY], MAX_HW_EXT_LEN, "_%s", val_sku);
+ set_bit(SKU_ONLY, &platform_hw_info.avail_bmap);
+ }
+
+ memset(platform_hw_info.ext_name[NO_EXT_NAME], 0, MAX_HW_EXT_LEN);
+ set_bit(NO_EXT_NAME, &platform_hw_info.avail_bmap);
+
+ return;
+}
+
+int cnss_wlan_init_hardware_info(void)
+{
+ struct device_node *node = NULL;
+ const char *hw_sku = NULL;
+ int hw_stage = -1;
+ int hw_major = -1;
+ int hw_minor = -1;
+ int i;
+
+ node = of_find_node_by_path(PLT_PATH);
+ if (!node) {
+ cnss_pr_err("Node not created under %s\n", PLT_PATH);
+ goto exit;
+ } else {
+
+ if (of_property_read_u32(node, HW_STAGE, &hw_stage)) {
+ cnss_pr_err("%s: Failed to get hw stage\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (of_property_read_u32(node, HW_MAJOR, &hw_major)) {
+ cnss_pr_err("%s: Failed to get hw major\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (of_property_read_u32(node, HW_MINOR, &hw_minor)) {
+ cnss_pr_err("%s: Failed to get hw minor\n", __FUNCTION__);
+ goto exit;
+ }
+
+ if (hw_stage > 0 && hw_stage <= MAX_HW_STAGE) {
+ snprintf(val_revision, MAX_HW_INFO_LEN, "%s%d.%d",
+ hw_stage_name[hw_stage-1], hw_major, hw_minor);
+
+ } else {
+ snprintf(val_revision, MAX_HW_INFO_LEN, "NULL");
+ }
+ }
+
+ node = of_find_node_by_path(CDB_PATH);
+ if (!node) {
+ cnss_pr_err("Node not created under %s\n", CDB_PATH);
+ goto exit;
+ } else {
+ if (of_property_read_string(node, HW_SKU, &hw_sku)) {
+ cnss_pr_err("%s: Failed to get hw sku\n", __FUNCTION__);
+ goto exit;
+ }
+
+ for (i = 0; i < ARRAYSIZE(sku_table); i ++) {
+ if (strcmp(hw_sku, sku_table[i].hw_id) == 0) {
+ strcpy(val_sku, sku_table[i].sku);
+ break;
+ }
+ }
+ }
+
+ cnss_pr_info("%s: val_revision is %s, hw_sku is %s, val_sku is %s\n",
+ __FUNCTION__, val_revision, hw_sku, val_sku);
+
+exit:
+ cnss_set_platform_ext_name(val_revision, val_sku);
+ return 0;
+}
+
+int cnss_request_multiple_bdf_files(const struct firmware **fw,
+ const char *name, struct device *device)
+{
+ int i, ret;
+ char tmp_name[MAX_FIRMWARE_NAME_LEN];
+
+ for (i = 0; i <= NO_EXT_NAME; i++) {
+ if (!test_bit(i, &platform_hw_info.avail_bmap)) {
+ continue;
+ }
+ memset(tmp_name, 0, MAX_FIRMWARE_NAME_LEN);
+ snprintf(tmp_name, MAX_FIRMWARE_NAME_LEN, "%s%s", name,
+ platform_hw_info.ext_name[i]);
+ ret = firmware_request_nowarn(fw, tmp_name, device);
+
+ if (ret) {
+ cnss_pr_info("Failed to load BDF: %s, ret: %d\n", tmp_name, ret);
+ continue;
+ } else {
+ cnss_pr_info("Load BDF successfully: %s, size: %u\n",
+ tmp_name, (*fw)->size);
+ break;
+ }
+ }
+ return ret;
+}
diff --git a/cnss2/qmi.c b/cnss2/qmi.c
index d37d11f..1b9f388 100644
--- a/cnss2/qmi.c
+++ b/cnss2/qmi.c
@@ -16,6 +16,9 @@
#include "main.h"
#include "qmi.h"
#include "genl.h"
+#if IS_ENABLED(CONFIG_WCN_GOOGLE)
+#include "pci_platform.h"
+#endif
#define WLFW_SERVICE_INS_ID_V01 1
#define WLFW_CLIENT_ID 0x4b4e454c
@@ -820,6 +823,15 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
if (bdf_type == CNSS_BDF_REGDB)
ret = cnss_request_firmware_direct(plat_priv, &fw_entry,
filename);
+#if IS_ENABLED(CONFIG_WCN_GOOGLE)
+ else if (bdf_type == CNSS_BDF_ELF) {
+ ret = cnss_request_multiple_bdf_files(&fw_entry, filename,
+ &plat_priv->plat_dev->dev);
+ if (ret) {
+ goto err_req_fw;
+ }
+ }
+#endif
else
ret = firmware_request_nowarn(&fw_entry, filename,
&plat_priv->plat_dev->dev);
@@ -832,6 +844,9 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
temp = fw_entry->data;
remaining = fw_entry->size;
+#if IS_ENABLED(CONFIG_WCN_GOOGLE)
+ if (bdf_type != CNSS_BDF_ELF)
+#endif
cnss_pr_dbg("Downloading BDF: %s, size: %u\n", filename, remaining);
while (remaining) {