From 76047d6637a511f82b5646a2952d8e6f72afd6e3 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Mon, 8 Jul 2024 11:19:16 -0400 Subject: [PATCH] nss-drv: extract and display nss firmware version Added a custom function to show NSS firmware version during boot. ``` [Mon Jul 8 07:45:21 2024] qca-nss 39000000.nss: NSS FW Version: NSS.FW.12.1-022-HK.R ``` And ``` [Mon Jul 8 07:21:12 2024] qca-nss 39000000.nss: NSS FW Version: NSS.HK.11.4.0.5-5-R ``` Not sure why Qualcomm never included this ability in their drivers, since it's clearly there in every firmware. Signed-off-by: Sean Khan --- .../0022-nss-drv-display-fw-version.patch | 78 +++++++++++++++ .../0020-nss-drv-display-fw-version.patch | 94 +++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 qca-nss-drv/patches-11.4/0022-nss-drv-display-fw-version.patch create mode 100644 qca-nss-drv/patches/0020-nss-drv-display-fw-version.patch diff --git a/qca-nss-drv/patches-11.4/0022-nss-drv-display-fw-version.patch b/qca-nss-drv/patches-11.4/0022-nss-drv-display-fw-version.patch new file mode 100644 index 0000000..1b4e4f4 --- /dev/null +++ b/qca-nss-drv/patches-11.4/0022-nss-drv-display-fw-version.patch @@ -0,0 +1,78 @@ +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -43,6 +43,7 @@ + */ + #define NSS_AP0_IMAGE "qca-nss0.bin" + #define NSS_AP1_IMAGE "qca-nss1.bin" ++#define BUFFER_SIZE 8192 + + /* + * File local/Static variables/functions +@@ -50,6 +51,56 @@ + static const struct net_device_ops nss_netdev_ops; + static const struct ethtool_ops nss_ethtool_ops; + ++// Function to search for the byte sequence in the buffer ++static unsigned char *search_sequence(const unsigned char *buffer, ++ size_t buffer_size, ++ const unsigned char *sequence, ++ size_t sequence_size) ++{ ++ for (size_t i = 0; i <= buffer_size - sequence_size; i++) { ++ if (memcmp(buffer + i, sequence, sequence_size) == 0) { ++ return (unsigned char *)(buffer + i); ++ } ++ } ++ return NULL; ++} ++ ++static int nss_hal_firmware_info(struct platform_device *nss_dev, ++ const struct firmware *fw) ++{ ++ unsigned char *start_pos, *end_pos; ++ size_t i; ++ unsigned char start_sequence[] = { 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20 }; ++ unsigned char end_sequence[] = { 0x00 }; ++ char version[256]; ++ bool found = false; ++ ++ // Search for the start sequence ++ start_pos = search_sequence(fw->data, fw->size, start_sequence, sizeof(start_sequence)); ++ if (start_pos) { ++ start_pos += sizeof(start_sequence); ++ ++ end_pos = search_sequence(start_pos, fw->size - (start_pos - fw->data), end_sequence, sizeof(end_sequence)); ++ if (end_pos) { ++ // Convert the version information to a string ++ for (i = 0; start_pos + i < end_pos && i < sizeof(version) - 1; i++) { ++ version[i] = start_pos[i]; ++ } ++ version[i] = '\0'; ++ ++ dev_info(&nss_dev->dev, "NSS FW Version: %s\n", version); ++ found = true; ++ } ++ } ++ ++ if (!found) { ++ dev_err(&nss_dev->dev, "Unable to get NSS FW version\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + int nss_hal_firmware_load(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) + { + const struct firmware *nss_fw; +@@ -81,6 +132,10 @@ int nss_hal_firmware_load(struct nss_ctx + return rc; + } + ++ if (nss_ctx->id == 0) { ++ nss_hal_firmware_info(nss_dev, nss_fw); ++ } ++ + dev_info(&nss_dev->dev, "fw of size %d bytes copied to addr: %x, nss_id: %d\n", (int)nss_fw->size, npd->load_addr, nss_ctx->id); + memcpy_toio(load_mem, nss_fw->data, nss_fw->size); + release_firmware(nss_fw); diff --git a/qca-nss-drv/patches/0020-nss-drv-display-fw-version.patch b/qca-nss-drv/patches/0020-nss-drv-display-fw-version.patch new file mode 100644 index 0000000..f8a0010 --- /dev/null +++ b/qca-nss-drv/patches/0020-nss-drv-display-fw-version.patch @@ -0,0 +1,94 @@ +--- a/nss_hal/nss_hal.c ++++ b/nss_hal/nss_hal.c +@@ -30,7 +30,6 @@ + #include + + #include "nss_hal.h" +-#include "nss_arch.h" + #include "nss_core.h" + #include "nss_tx_rx_common.h" + #ifdef NSS_DATA_PLANE_GENERIC_SUPPORT +@@ -51,6 +50,7 @@ + */ + #define NSS_AP0_IMAGE "qca-nss0.bin" + #define NSS_AP1_IMAGE "qca-nss1.bin" ++#define BUFFER_SIZE 8192 + + /* + * File local/Static variables/functions +@@ -58,6 +58,56 @@ + static const struct net_device_ops nss_netdev_ops; + static const struct ethtool_ops nss_ethtool_ops; + ++// Function to search for the byte sequence in the buffer ++static unsigned char *search_sequence(const unsigned char *buffer, ++ size_t buffer_size, ++ const unsigned char *sequence, ++ size_t sequence_size) ++{ ++ for (size_t i = 0; i <= buffer_size - sequence_size; i++) { ++ if (memcmp(buffer + i, sequence, sequence_size) == 0) { ++ return (unsigned char *)(buffer + i); ++ } ++ } ++ return NULL; ++} ++ ++static int nss_hal_firmware_info(struct platform_device *nss_dev, ++ const struct firmware *fw) ++{ ++ unsigned char *start_pos, *end_pos; ++ size_t i; ++ unsigned char start_sequence[] = { 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20 }; ++ unsigned char end_sequence[] = { 0x00 }; ++ char version[256]; ++ bool found = false; ++ ++ // Search for the start sequence ++ start_pos = search_sequence(fw->data, fw->size, start_sequence, sizeof(start_sequence)); ++ if (start_pos) { ++ start_pos += sizeof(start_sequence); ++ ++ end_pos = search_sequence(start_pos, fw->size - (start_pos - fw->data), end_sequence, sizeof(end_sequence)); ++ if (end_pos) { ++ // Convert the version information to a string ++ for (i = 0; start_pos + i < end_pos && i < sizeof(version) - 1; i++) { ++ version[i] = start_pos[i]; ++ } ++ version[i] = '\0'; ++ ++ dev_info(&nss_dev->dev, "NSS fw version: %s\n", version); ++ found = true; ++ } ++ } ++ ++ if (!found) { ++ dev_err(&nss_dev->dev, "Unable to get NSS fw version\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + int nss_hal_firmware_load(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) + { + const struct firmware *nss_fw; +@@ -81,7 +131,6 @@ int nss_hal_firmware_load(struct nss_ctx + return rc; + } + +- + load_mem = ioremap(npd->load_addr, nss_fw->size); + if (!load_mem) { + nss_info_always("%px: ioremap failed: %x", nss_ctx, npd->load_addr); +@@ -89,6 +138,10 @@ int nss_hal_firmware_load(struct nss_ctx + return rc; + } + ++ if (nss_ctx->id == 0) { ++ nss_hal_firmware_info(nss_dev, nss_fw); ++ } ++ + dev_info(&nss_dev->dev, "fw of size %d bytes copied to addr: %x, nss_id: %d\n", (int)nss_fw->size, npd->load_addr, nss_ctx->id); + memcpy_toio(load_mem, nss_fw->data, nss_fw->size); + release_firmware(nss_fw);