From: Wen Gong <[email protected]>
Currently ath11k only support string type with bus, chip id and board id
such as "bus=ahb,qmi-chip-id=1,qmi-board-id=4" for ahb bus chip and
"bus=pci,qmi-chip-id=0,qmi-board-id=255" for PCIe bus chip in
board-2.bin. For WCN6855, it is not enough to distinguish all different
chips.
This is to add a new string type which include bus, chip id, board id,
vendor, device, subsystem-vendor and subsystem-device for WCN6855.
ath11k will first load board-2.bin and search in it for the board data
with the above parameters, if matched one board data, then download it
to firmware, if not matched any one, then ath11k will download the file
board.bin to firmware.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Signed-off-by: Wen Gong <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
---
drivers/net/wireless/ath/ath11k/core.c | 27 ++++++++++++++++++++------
drivers/net/wireless/ath/ath11k/core.h | 13 +++++++++++++
drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++++++
drivers/net/wireless/ath/ath11k/qmi.h | 3 +++
4 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 8f09ae827170..a8c6f7cf33d5 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -406,11 +406,26 @@ static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
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",
- ath11k_bus_str(ab->hif.bus),
- ab->qmi.target.chip_id,
- ab->qmi.target.board_id, variant);
+ switch (ab->id.bdf_search) {
+ case ATH11K_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",
+ ath11k_bus_str(ab->hif.bus),
+ ab->id.vendor, ab->id.device,
+ ab->id.subsystem_vendor,
+ ab->id.subsystem_device,
+ FIELD_GET(ATH11K_CHIP_ID_MASK, ab->qmi.target.chip_id),
+ ab->qmi.target.board_id & 0xFF,
+ variant);
+ break;
+ default:
+ scnprintf(name, name_len,
+ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
+ ath11k_bus_str(ab->hif.bus),
+ ab->qmi.target.chip_id,
+ ab->qmi.target.board_id, variant);
+ break;
+ }
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
@@ -647,7 +662,7 @@ static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
return 0;
}
-#define BOARD_NAME_SIZE 100
+#define BOARD_NAME_SIZE 200
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
{
char boardname[BOARD_NAME_SIZE];
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
index d58ca38d78c7..eda90776cee1 100644
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -47,6 +47,11 @@ enum ath11k_supported_bw {
ATH11K_BW_160 = 3,
};
+enum ath11k_bdf_search {
+ ATH11K_BDF_SEARCH_DEFAULT,
+ ATH11K_BDF_SEARCH_BUS_AND_BOARD,
+};
+
enum wme_ac {
WME_AC_BE,
WME_AC_BK,
@@ -761,6 +766,14 @@ struct ath11k_base {
struct completion htc_suspend;
struct ath11k_num_vdevs_peers num_vdevs_peers;
+ struct {
+ enum ath11k_bdf_search bdf_search;
+ u32 vendor;
+ u32 device;
+ u32 subsystem_vendor;
+ u32 subsystem_device;
+ } id;
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index c6540d562c42..40f7e70693c0 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -1290,6 +1290,15 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
goto err_free_core;
}
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",
+ pdev->vendor, pdev->device,
+ pdev->subsystem_vendor, pdev->subsystem_device);
+
+ ab->id.vendor = pdev->vendor;
+ ab->id.device = pdev->device;
+ ab->id.subsystem_vendor = pdev->subsystem_vendor;
+ ab->id.subsystem_device = pdev->subsystem_device;
+
switch (pci_dev->device) {
case QCA6390_DEVICE_ID:
ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
@@ -1312,6 +1321,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ab->hw_rev = ATH11K_HW_QCN9074_HW10;
break;
case WCN6855_DEVICE_ID:
+ ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD;
ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
&soc_hw_version_minor);
switch (soc_hw_version_major) {
diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
index 3bb0f9ef7996..a7c01b51d9a6 100644
--- a/drivers/net/wireless/ath/ath11k/qmi.h
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
@@ -97,6 +97,9 @@ struct target_mem_chunk {
u32 *vaddr;
};
+/* used to get the chip id in struct target_info */
+#define ATH11K_CHIP_ID_MASK 0x10
+
struct target_info {
u32 chip_id;
u32 chip_family;
--
2.25.1
Jouni Malinen <[email protected]> writes:
> From: Wen Gong <[email protected]>
>
> Currently ath11k only support string type with bus, chip id and board id
> such as "bus=ahb,qmi-chip-id=1,qmi-board-id=4" for ahb bus chip and
> "bus=pci,qmi-chip-id=0,qmi-board-id=255" for PCIe bus chip in
> board-2.bin. For WCN6855, it is not enough to distinguish all different
> chips.
>
> This is to add a new string type which include bus, chip id, board id,
> vendor, device, subsystem-vendor and subsystem-device for WCN6855.
>
> ath11k will first load board-2.bin and search in it for the board data
> with the above parameters, if matched one board data, then download it
> to firmware, if not matched any one, then ath11k will download the file
> board.bin to firmware.
>
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
>
> Signed-off-by: Wen Gong <[email protected]>
> Signed-off-by: Jouni Malinen <[email protected]>
> ---
> drivers/net/wireless/ath/ath11k/core.c | 27 ++++++++++++++++++++------
> drivers/net/wireless/ath/ath11k/core.h | 13 +++++++++++++
> drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++++++
> drivers/net/wireless/ath/ath11k/qmi.h | 3 +++
> 4 files changed, 47 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
> index 8f09ae827170..a8c6f7cf33d5 100644
> --- a/drivers/net/wireless/ath/ath11k/core.c
> +++ b/drivers/net/wireless/ath/ath11k/core.c
> @@ -406,11 +406,26 @@ static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
> 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",
> - ath11k_bus_str(ab->hif.bus),
> - ab->qmi.target.chip_id,
> - ab->qmi.target.board_id, variant);
> + switch (ab->id.bdf_search) {
> + case ATH11K_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",
> + ath11k_bus_str(ab->hif.bus),
> + ab->id.vendor, ab->id.device,
> + ab->id.subsystem_vendor,
> + ab->id.subsystem_device,
> + FIELD_GET(ATH11K_CHIP_ID_MASK, ab->qmi.target.chip_id),
> + ab->qmi.target.board_id & 0xFF,
Why are chip_id and board_id masked? Why cannot we use values directly
provided by the firmware?
And if we need to mask those, it's better to do them in qmi.c where they
are stored:
if (resp.chip_info_valid) {
ab->qmi.target.chip_id = resp.chip_info.chip_id;
ab->qmi.target.chip_family = resp.chip_info.chip_family;
}
if (resp.board_info_valid)
ab->qmi.target.board_id = resp.board_info.board_id;
else
ab->qmi.target.board_id = 0xFF;
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
On 2021-11-08 21:15, Kalle Valo wrote:
> Jouni Malinen <[email protected]> writes:
...
>> + switch (ab->id.bdf_search) {
>> + case ATH11K_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",
>> + ath11k_bus_str(ab->hif.bus),
>> + ab->id.vendor, ab->id.device,
>> + ab->id.subsystem_vendor,
>> + ab->id.subsystem_device,
>> + FIELD_GET(ATH11K_CHIP_ID_MASK, ab->qmi.target.chip_id),
>> + ab->qmi.target.board_id & 0xFF,
>
> Why are chip_id and board_id masked? Why cannot we use values directly
> provided by the firmware?
>
below is the log for WCN6855 2.0, its chip_id is 0x2 and board_id is
0x106, but actually we need to
find the board data with chip-id=0 and board-id=6, so we add mask here.
[ 3000.176621] ath11k_pci 0000:05:00.0: chip_id 0x2 chip_family 0xb
board_id 0x106 soc_id 0x400c0200
[ 3000.182361] ath11k_pci 0000:05:00.0: boot using board name
'bus=pci,vendor=17cb,device=1103,subsystem-vendor=17cb,subsystem-device=3374,qmi-chip-id=0,qmi-board-id=6'
> And if we need to mask those, it's better to do them in qmi.c where
> they
> are stored:
>
Currenly logic of default: in ath11k_core_create_board_name() which is
introduced in 1st commit
also use the chip_id and board_id, if mask them in qmi.c may effect the
logic of ath11k_core_create_board_name().
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/drivers/net/wireless/ath/ath11k?h=ath-next&id=d5c65159f2895379e11ca13f62feabe93278985d
ath11k: driver for Qualcomm IEEE 802.11ax devices
+static int ath11k_core_create_board_name(struct ath11k_base *ab, char
*name,
+ size_t name_len)
+{
+ /* Note: bus is fixed to ahb. When other bus type supported,
+ * make it to dynamic.
+ */
+ scnprintf(name, name_len,
+ "bus=ahb,qmi-chip-id=%d,qmi-board-id=%d",
+ ab->qmi.target.chip_id,
+ ab->qmi.target.board_id);
+
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
+
+ return 0;
+}
another thing is that, other bits of chip_id/board_id maybe also need
used by other place/feature, so we still need to
store the total original value of chip_id/board_id instead of mask it
only for board data file.
Then user can easily get their own mask from chip_id/board_id.
> if (resp.chip_info_valid) {
> ab->qmi.target.chip_id = resp.chip_info.chip_id;
> ab->qmi.target.chip_family = resp.chip_info.chip_family;
> }
>
> if (resp.board_info_valid)
> ab->qmi.target.board_id = resp.board_info.board_id;
> else
> ab->qmi.target.board_id = 0xFF;