[X/Y/Z][v2] ath10k: search SMBIOS for OEM board file extension

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[X/Y/Z][v2] ath10k: search SMBIOS for OEM board file extension

Shrirang Bagul
BugLink: https://bugs.launchpad.net/bugs/1666742

Patches for ath10k driver to read board variant from SMBIOS.

Patch for Zesty is a clean cherry-pick. Yakkety and Xenial are backports
only due to difference in context.

Example:
 If a default board data file for a specific board is identified by a string
         "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
          subsystem-device=0310"
 then the OEM specific data file, if used, could be identified by variant
 suffix:
         "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
          subsystem-device=0310,variant=DE_1AB"

If board data file name extension is set but board-2.bin does not contain board
data file for the variant, the driver will fallback to the default board data
file not to break backward compatibility.


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Xenial SRU][PATCH v2] ath10k: search SMBIOS for OEM board file extension

Shrirang Bagul
From: Waldemar Rymarkiewicz <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1666742

Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.

The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.

To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.

If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.

Example:
If a default board data file for a specific board is identified by a string
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310,variant=DE_1AB"

If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.

This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.

Signed-off-by: Waldemar Rymarkiewicz <[hidden email]>
Signed-off-by: Kalle Valo <[hidden email]>
(backported from commit 1657b8f84ed9fc1d2a100671f1d42d6286f20073)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 drivers/net/wireless/ath/ath10k/core.c | 102 ++++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/core.h |  23 ++++++++
 2 files changed, 122 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 531de256d58d..ca9c913fc066 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -18,6 +18,9 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/of.h>
+#include <linux/dmi.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
 
 #include "core.h"
 #include "mac.h"
@@ -558,6 +561,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
  return 0;
 }
 
+static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+{
+ struct ath10k *ar = data;
+ const char *bdf_ext;
+ const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
+ u8 bdf_enabled;
+ int i;
+
+ if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
+ return;
+
+ if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "wrong smbios bdf ext type length (%d).\n",
+   hdr->length);
+ return;
+ }
+
+ bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
+ if (!bdf_enabled) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
+ return;
+ }
+
+ /* Only one string exists (per spec) */
+ bdf_ext = (char *)hdr + hdr->length;
+
+ if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant magic does not match.\n");
+ return;
+ }
+
+ for (i = 0; i < strlen(bdf_ext); i++) {
+ if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant name contains non ascii chars.\n");
+ return;
+ }
+ }
+
+ /* Copy extension name without magic suffix */
+ if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
+    sizeof(ar->id.bdf_ext)) < 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
+    bdf_ext);
+ return;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
+   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
+}
+
+static int ath10k_core_check_smbios(struct ath10k *ar)
+{
+ ar->id.bdf_ext[0] = '\0';
+ dmi_walk(ath10k_core_check_bdfext, ar);
+
+ if (ar->id.bdf_ext[0] == '\0')
+ return -ENODATA;
+
+ return 0;
+}
+
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
  u32 result, address = ar->hw_params.patch_load_addr;
@@ -865,6 +934,23 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
  case ATH10K_BD_IE_BOARD:
  ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
     boardname);
+ if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') {
+ /* try default bdf if variant was not found */
+ char *s, *v = ",variant=";
+ char boardname2[100];
+
+ strlcpy(boardname2, boardname,
+ sizeof(boardname2));
+
+ s = strstr(boardname2, v);
+ if (s)
+ *s = '\0';  /* strip ",variant=%s" */
+
+ ret = ath10k_core_parse_bd_ie_board(ar, data,
+    ie_len,
+    boardname2);
+ }
+
  if (ret == -ENOENT)
  /* no match found, continue */
  break;
@@ -902,6 +988,9 @@ err:
 static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  size_t name_len)
 {
+ /* strlen(',variant=') + strlen(ar->id.bdf_ext) */
+ char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
+
  if (ar->id.bmi_ids_valid) {
  scnprintf(name, name_len,
   "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -911,12 +1000,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  goto out;
  }
 
+ if (ar->id.bdf_ext[0] != '\0')
+ scnprintf(variant, sizeof(variant), ",variant=%s",
+  ar->id.bdf_ext);
+
  scnprintf(name, name_len,
-  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
   ath10k_bus_str(ar->hif.bus),
   ar->id.vendor, ar->id.device,
-  ar->id.subsystem_vendor, ar->id.subsystem_device);
-
+  ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
 out:
  ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
 
@@ -1797,6 +1889,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
  return ret;
  }
 
+ ret = ath10k_core_check_smbios(ar);
+ if (ret)
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
+
  ret = ath10k_core_fetch_board_file(ar);
  if (ret) {
  ath10k_err(ar, "failed to fetch board file: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 858d75f49a9f..5f07a416b162 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -65,6 +65,27 @@
 #define ATH10K_KEEPALIVE_MAX_IDLE 3895
 #define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
 
+/* NAPI poll budget */
+#define ATH10K_NAPI_BUDGET      64
+#define ATH10K_NAPI_QUOTA_LIMIT 60
+
+/* SMBIOS type containing Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8
+
+/* SMBIOS type structure length (excluding strings-set) */
+#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9
+
+/* Offset pointing to Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8
+
+/* Board Data File Name Extension string length.
+ * String format: BDF_<Customer ID>_<Extension>\0
+ */
+#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20
+
+/* The magic used by QCA spec */
+#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
+
 struct ath10k;
 
 enum ath10k_bus {
@@ -701,6 +722,8 @@ struct ath10k {
  bool bmi_ids_valid;
  u8 bmi_board_id;
  u8 bmi_chip_id;
+
+ char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
  } id;
 
  int fw_api;
--
2.11.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Yakkety][PATCH v2] ath10k: search SMBIOS for OEM board file extension

Shrirang Bagul
In reply to this post by Shrirang Bagul
From: Waldemar Rymarkiewicz <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1666742

Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.

The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.

To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.

If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.

Example:
If a default board data file for a specific board is identified by a string
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310,variant=DE_1AB"

If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.

This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.

Signed-off-by: Waldemar Rymarkiewicz <[hidden email]>
Signed-off-by: Kalle Valo <[hidden email]>
(backported from commit 1657b8f84ed9fc1d2a100671f1d42d6286f20073)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 drivers/net/wireless/ath/ath10k/core.c | 101 ++++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/core.h |  23 ++++++++
 2 files changed, 121 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index e88982921aa3..1bafc2b270ab 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -18,6 +18,8 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/of.h>
+#include <linux/dmi.h>
+#include <linux/ctype.h>
 #include <asm/byteorder.h>
 
 #include "core.h"
@@ -681,6 +683,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
  return 0;
 }
 
+static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+{
+ struct ath10k *ar = data;
+ const char *bdf_ext;
+ const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
+ u8 bdf_enabled;
+ int i;
+
+ if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
+ return;
+
+ if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "wrong smbios bdf ext type length (%d).\n",
+   hdr->length);
+ return;
+ }
+
+ bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
+ if (!bdf_enabled) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
+ return;
+ }
+
+ /* Only one string exists (per spec) */
+ bdf_ext = (char *)hdr + hdr->length;
+
+ if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant magic does not match.\n");
+ return;
+ }
+
+ for (i = 0; i < strlen(bdf_ext); i++) {
+ if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant name contains non ascii chars.\n");
+ return;
+ }
+ }
+
+ /* Copy extension name without magic suffix */
+ if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
+    sizeof(ar->id.bdf_ext)) < 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
+    bdf_ext);
+ return;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
+   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
+}
+
+static int ath10k_core_check_smbios(struct ath10k *ar)
+{
+ ar->id.bdf_ext[0] = '\0';
+ dmi_walk(ath10k_core_check_bdfext, ar);
+
+ if (ar->id.bdf_ext[0] == '\0')
+ return -ENODATA;
+
+ return 0;
+}
+
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
  u32 result, address = ar->hw_params.patch_load_addr;
@@ -990,6 +1058,23 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
  case ATH10K_BD_IE_BOARD:
  ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
     boardname);
+ if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') {
+ /* try default bdf if variant was not found */
+ char *s, *v = ",variant=";
+ char boardname2[100];
+
+ strlcpy(boardname2, boardname,
+ sizeof(boardname2));
+
+ s = strstr(boardname2, v);
+ if (s)
+ *s = '\0';  /* strip ",variant=%s" */
+
+ ret = ath10k_core_parse_bd_ie_board(ar, data,
+    ie_len,
+    boardname2);
+ }
+
  if (ret == -ENOENT)
  /* no match found, continue */
  break;
@@ -1027,6 +1112,9 @@ err:
 static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  size_t name_len)
 {
+ /* strlen(',variant=') + strlen(ar->id.bdf_ext) */
+ char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
+
  if (ar->id.bmi_ids_valid) {
  scnprintf(name, name_len,
   "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -1036,12 +1124,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  goto out;
  }
 
+ if (ar->id.bdf_ext[0] != '\0')
+ scnprintf(variant, sizeof(variant), ",variant=%s",
+  ar->id.bdf_ext);
+
  scnprintf(name, name_len,
-  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
   ath10k_bus_str(ar->hif.bus),
   ar->id.vendor, ar->id.device,
-  ar->id.subsystem_vendor, ar->id.subsystem_device);
-
+  ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
 out:
  ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
 
@@ -2016,6 +2107,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
  goto err_free_firmware_files;
  }
 
+ ret = ath10k_core_check_smbios(ar);
+ if (ret)
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
+
  ret = ath10k_core_fetch_board_file(ar);
  if (ret) {
  ath10k_err(ar, "failed to fetch board file: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 76ad825a823d..b0839d14c116 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -65,6 +65,27 @@
 #define ATH10K_KEEPALIVE_MAX_IDLE 3895
 #define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
 
+/* NAPI poll budget */
+#define ATH10K_NAPI_BUDGET      64
+#define ATH10K_NAPI_QUOTA_LIMIT 60
+
+/* SMBIOS type containing Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8
+
+/* SMBIOS type structure length (excluding strings-set) */
+#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9
+
+/* Offset pointing to Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8
+
+/* Board Data File Name Extension string length.
+ * String format: BDF_<Customer ID>_<Extension>\0
+ */
+#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20
+
+/* The magic used by QCA spec */
+#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
+
 struct ath10k;
 
 enum ath10k_bus {
@@ -788,6 +809,8 @@ struct ath10k {
  bool bmi_ids_valid;
  u8 bmi_board_id;
  u8 bmi_chip_id;
+
+ char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
  } id;
 
  int fw_api;
--
2.11.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Zesty][PATCH v2] ath10k: search SMBIOS for OEM board file extension

Shrirang Bagul
In reply to this post by Shrirang Bagul
From: Waldemar Rymarkiewicz <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1666742

Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.

The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.

To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.

If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.

Example:
If a default board data file for a specific board is identified by a string
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
      "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
       subsystem-device=0310,variant=DE_1AB"

If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.

This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.

Signed-off-by: Waldemar Rymarkiewicz <[hidden email]>
Signed-off-by: Kalle Valo <[hidden email]>
(cherry picked from commit 1657b8f84ed9fc1d2a100671f1d42d6286f20073)
Signed-off-by: Shrirang Bagul <[hidden email]>
---
 drivers/net/wireless/ath/ath10k/core.c | 101 ++++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/core.h |  19 +++++++
 2 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 01f5d4db4d0e..2ff689fe6d00 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -18,6 +18,8 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/of.h>
+#include <linux/dmi.h>
+#include <linux/ctype.h>
 #include <asm/byteorder.h>
 
 #include "core.h"
@@ -704,6 +706,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
  return 0;
 }
 
+static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+{
+ struct ath10k *ar = data;
+ const char *bdf_ext;
+ const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
+ u8 bdf_enabled;
+ int i;
+
+ if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
+ return;
+
+ if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "wrong smbios bdf ext type length (%d).\n",
+   hdr->length);
+ return;
+ }
+
+ bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
+ if (!bdf_enabled) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
+ return;
+ }
+
+ /* Only one string exists (per spec) */
+ bdf_ext = (char *)hdr + hdr->length;
+
+ if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant magic does not match.\n");
+ return;
+ }
+
+ for (i = 0; i < strlen(bdf_ext); i++) {
+ if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant name contains non ascii chars.\n");
+ return;
+ }
+ }
+
+ /* Copy extension name without magic suffix */
+ if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
+    sizeof(ar->id.bdf_ext)) < 0) {
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
+    bdf_ext);
+ return;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
+   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
+   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
+}
+
+static int ath10k_core_check_smbios(struct ath10k *ar)
+{
+ ar->id.bdf_ext[0] = '\0';
+ dmi_walk(ath10k_core_check_bdfext, ar);
+
+ if (ar->id.bdf_ext[0] == '\0')
+ return -ENODATA;
+
+ return 0;
+}
+
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
  u32 result, address = ar->hw_params.patch_load_addr;
@@ -1013,6 +1081,23 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
  case ATH10K_BD_IE_BOARD:
  ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
     boardname);
+ if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') {
+ /* try default bdf if variant was not found */
+ char *s, *v = ",variant=";
+ char boardname2[100];
+
+ strlcpy(boardname2, boardname,
+ sizeof(boardname2));
+
+ s = strstr(boardname2, v);
+ if (s)
+ *s = '\0';  /* strip ",variant=%s" */
+
+ ret = ath10k_core_parse_bd_ie_board(ar, data,
+    ie_len,
+    boardname2);
+ }
+
  if (ret == -ENOENT)
  /* no match found, continue */
  break;
@@ -1050,6 +1135,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
 static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  size_t name_len)
 {
+ /* strlen(',variant=') + strlen(ar->id.bdf_ext) */
+ char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
+
  if (ar->id.bmi_ids_valid) {
  scnprintf(name, name_len,
   "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -1059,12 +1147,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
  goto out;
  }
 
+ if (ar->id.bdf_ext[0] != '\0')
+ scnprintf(variant, sizeof(variant), ",variant=%s",
+  ar->id.bdf_ext);
+
  scnprintf(name, name_len,
-  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
   ath10k_bus_str(ar->hif.bus),
   ar->id.vendor, ar->id.device,
-  ar->id.subsystem_vendor, ar->id.subsystem_device);
-
+  ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
 out:
  ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
 
@@ -2123,6 +2214,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
  goto err_free_firmware_files;
  }
 
+ ret = ath10k_core_check_smbios(ar);
+ if (ret)
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
+
  ret = ath10k_core_fetch_board_file(ar);
  if (ret) {
  ath10k_err(ar, "failed to fetch board file: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 09ff8b8a6441..77df39a5ed63 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -69,6 +69,23 @@
 #define ATH10K_NAPI_BUDGET      64
 #define ATH10K_NAPI_QUOTA_LIMIT 60
 
+/* SMBIOS type containing Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8
+
+/* SMBIOS type structure length (excluding strings-set) */
+#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9
+
+/* Offset pointing to Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8
+
+/* Board Data File Name Extension string length.
+ * String format: BDF_<Customer ID>_<Extension>\0
+ */
+#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20
+
+/* The magic used by QCA spec */
+#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
+
 struct ath10k;
 
 enum ath10k_bus {
@@ -781,6 +798,8 @@ struct ath10k {
  bool bmi_ids_valid;
  u8 bmi_board_id;
  u8 bmi_chip_id;
+
+ char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
  } id;
 
  int fw_api;
--
2.11.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ACK: [Zesty][PATCH v2] ath10k: search SMBIOS for OEM board file extension

AceLan Kao
This patch only affects the machine comes with a specific OEM string in SMBIOS,
and then using another firmware file. Without the OEM string, it still uses the
original firmware file. Should be safe for SRU.

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ACK: [Yakkety][PATCH v2] ath10k: search SMBIOS for OEM board file extension

AceLan Kao
In reply to this post by Shrirang Bagul
This patch only affects the machine comes with a specific OEM string in SMBIOS,
and then using another firmware file. Without the OEM string, it still uses the
original firmware file. Should be safe for SRU.

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ACK: [Xenial SRU][PATCH v2] ath10k: search SMBIOS for OEM board file extension

AceLan Kao
In reply to this post by Shrirang Bagul
This patch only affects the machine comes with a specific OEM string in SMBIOS,
and then using another firmware file. Without the OEM string, it still uses the
original firmware file. Should be safe for SRU.

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ACK/cmnt: [X/Y/Z][v2] ath10k: search SMBIOS for OEM board file extension

Stefan Bader-2
In reply to this post by Shrirang Bagul
On 06.07.2017 13:12, Shrirang Bagul wrote:

> BugLink: https://bugs.launchpad.net/bugs/1666742
>
> Patches for ath10k driver to read board variant from SMBIOS.
>
> Patch for Zesty is a clean cherry-pick. Yakkety and Xenial are backports
> only due to difference in context.
>
> Example:
>  If a default board data file for a specific board is identified by a string
>          "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
>           subsystem-device=0310"
>  then the OEM specific data file, if used, could be identified by variant
>  suffix:
>          "bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
>           subsystem-device=0310,variant=DE_1AB"
>
> If board data file name extension is set but board-2.bin does not contain board
> data file for the variant, the driver will fallback to the default board data
> file not to break backward compatibility.
>
>
Acked-by: Stefan Bader <[hidden email]>

Looks to be isolated to very specific HW and defaulting to unchanged behaviour.
Though would induce more confidence if the bug report would mention testing on
some HW with special variant (and if available one without).

-Stefan



--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

APPLIED: [X/Y/Z][v2] ath10k: search SMBIOS for OEM board file extension

Thadeu Lima de Souza Cascardo-3
In reply to this post by Shrirang Bagul
Applied to xenial, yakkety and zesty master-next branches.

Thanks.
Cascardo.

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Loading...