2023-08-25 20:34:31 +00:00
|
|
|
From de173a6233f192422784aba823835c18fcd8b485 Mon Sep 17 00:00:00 2001
|
2023-07-07 22:33:51 +00:00
|
|
|
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
|
|
|
|
Date: Tue, 3 Nov 2020 13:28:04 +0100
|
|
|
|
Subject: [PATCH] mwifiex: Add quirk resetting the PCI bridge on MS Surface
|
|
|
|
devices
|
|
|
|
|
|
|
|
The most recent firmware of the 88W8897 card reports a hardcoded LTR
|
|
|
|
value to the system during initialization, probably as an (unsuccessful)
|
|
|
|
attempt of the developers to fix firmware crashes. This LTR value
|
|
|
|
prevents most of the Microsoft Surface devices from entering deep
|
|
|
|
powersaving states (either platform C-State 10 or S0ix state), because
|
|
|
|
the exit latency of that state would be higher than what the card can
|
|
|
|
tolerate.
|
|
|
|
|
|
|
|
Turns out the card works just the same (including the firmware crashes)
|
|
|
|
no matter if that hardcoded LTR value is reported or not, so it's kind
|
|
|
|
of useless and only prevents us from saving power.
|
|
|
|
|
|
|
|
To get rid of those hardcoded LTR reports, it's possible to reset the
|
|
|
|
PCI bridge device after initializing the cards firmware. I'm not exactly
|
|
|
|
sure why that works, maybe the power management subsystem of the PCH
|
|
|
|
resets its stored LTR values when doing a function level reset of the
|
|
|
|
bridge device. Doing the reset once after starting the wifi firmware
|
|
|
|
works very well, probably because the firmware only reports that LTR
|
|
|
|
value a single time during firmware startup.
|
|
|
|
|
|
|
|
Patchset: mwifiex
|
|
|
|
---
|
|
|
|
drivers/net/wireless/marvell/mwifiex/pcie.c | 12 +++++++++
|
|
|
|
.../wireless/marvell/mwifiex/pcie_quirks.c | 26 +++++++++++++------
|
|
|
|
.../wireless/marvell/mwifiex/pcie_quirks.h | 1 +
|
|
|
|
3 files changed, 31 insertions(+), 8 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
index 9a698a16a8f3..14687342bc81 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
@@ -1762,9 +1762,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
|
|
|
static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
|
|
|
|
{
|
|
|
|
struct pcie_service_card *card = adapter->card;
|
|
|
|
+ struct pci_dev *pdev = card->dev;
|
|
|
|
+ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
|
|
|
|
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
|
|
|
|
int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
|
|
|
|
|
|
|
|
+ /* Trigger a function level reset of the PCI bridge device, this makes
|
|
|
|
+ * the firmware of PCIe 88W8897 cards stop reporting a fixed LTR value
|
|
|
|
+ * that prevents the system from entering package C10 and S0ix powersaving
|
|
|
|
+ * states.
|
|
|
|
+ * We need to do it here because it must happen after firmware
|
|
|
|
+ * initialization and this function is called after that is done.
|
|
|
|
+ */
|
|
|
|
+ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
|
|
|
|
+ pci_reset_function(parent_pdev);
|
|
|
|
+
|
|
|
|
/* Write the RX ring read pointer in to reg->rx_rdptr */
|
|
|
|
if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
|
|
|
|
tx_wrap)) {
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
index dd6d21f1dbfd..f46b06f8d643 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
@@ -13,7 +13,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 5",
|
|
|
|
@@ -22,7 +23,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 5 (LTE)",
|
|
|
|
@@ -31,7 +33,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 6",
|
|
|
|
@@ -39,7 +42,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Book 1",
|
|
|
|
@@ -47,7 +51,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Book 2",
|
|
|
|
@@ -55,7 +60,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Laptop 1",
|
|
|
|
@@ -63,7 +69,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Laptop 2",
|
|
|
|
@@ -71,7 +78,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
|
|
|
|
},
|
|
|
|
- .driver_data = (void *)QUIRK_FW_RST_D3COLD,
|
|
|
|
+ .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
@@ -89,6 +97,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
|
|
|
|
dev_info(&pdev->dev, "no quirks enabled\n");
|
|
|
|
if (card->quirks & QUIRK_FW_RST_D3COLD)
|
|
|
|
dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
|
|
|
|
+ if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
|
|
|
|
+ dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
index d6ff964aec5b..5d30ae39d65e 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
#include "pcie.h"
|
|
|
|
|
|
|
|
#define QUIRK_FW_RST_D3COLD BIT(0)
|
|
|
|
+#define QUIRK_DO_FLR_ON_BRIDGE BIT(1)
|
|
|
|
|
|
|
|
void mwifiex_initialize_quirks(struct pcie_service_card *card);
|
|
|
|
int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
|
|
|
|
--
|
2023-08-25 20:34:31 +00:00
|
|
|
2.42.0
|
2023-07-07 22:33:51 +00:00
|
|
|
|
2023-08-25 20:34:31 +00:00
|
|
|
From 24046b6b9cb6ba34dc079bd690d9362581c8ec90 Mon Sep 17 00:00:00 2001
|
2023-07-07 22:33:51 +00:00
|
|
|
From: Tsuchiya Yuto <kitakar@gmail.com>
|
|
|
|
Date: Sun, 4 Oct 2020 00:11:49 +0900
|
|
|
|
Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+
|
|
|
|
|
|
|
|
Currently, mwifiex fw will crash after suspend on recent kernel series.
|
|
|
|
On Windows, it seems that the root port of wifi will never enter D3 state
|
|
|
|
(stay on D0 state). And on Linux, disabling the D3 state for the
|
|
|
|
bridge fixes fw crashing after suspend.
|
|
|
|
|
|
|
|
This commit disables the D3 state of root port on driver initialization
|
|
|
|
and fixes fw crashing after suspend.
|
|
|
|
|
|
|
|
Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
|
|
|
|
Patchset: mwifiex
|
|
|
|
---
|
|
|
|
drivers/net/wireless/marvell/mwifiex/pcie.c | 7 +++++
|
|
|
|
.../wireless/marvell/mwifiex/pcie_quirks.c | 27 +++++++++++++------
|
|
|
|
.../wireless/marvell/mwifiex/pcie_quirks.h | 1 +
|
|
|
|
3 files changed, 27 insertions(+), 8 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
index 14687342bc81..5e1a341f63df 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
|
|
|
|
@@ -368,6 +368,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
|
|
|
|
const struct pci_device_id *ent)
|
|
|
|
{
|
|
|
|
struct pcie_service_card *card;
|
|
|
|
+ struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
|
|
|
|
@@ -409,6 +410,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /* disable bridge_d3 for Surface gen4+ devices to fix fw crashing
|
|
|
|
+ * after suspend
|
|
|
|
+ */
|
|
|
|
+ if (card->quirks & QUIRK_NO_BRIDGE_D3)
|
|
|
|
+ parent_pdev->bridge_d3 = false;
|
|
|
|
+
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
index f46b06f8d643..99b024ecbade 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
|
|
|
|
@@ -14,7 +14,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 5",
|
|
|
|
@@ -24,7 +25,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 5 (LTE)",
|
|
|
|
@@ -34,7 +36,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Pro 6",
|
|
|
|
@@ -43,7 +46,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Book 1",
|
|
|
|
@@ -52,7 +56,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Book 2",
|
|
|
|
@@ -61,7 +66,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Laptop 1",
|
|
|
|
@@ -70,7 +76,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.ident = "Surface Laptop 2",
|
|
|
|
@@ -79,7 +86,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
|
|
|
|
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
|
|
|
|
},
|
|
|
|
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
|
|
|
|
- QUIRK_DO_FLR_ON_BRIDGE),
|
|
|
|
+ QUIRK_DO_FLR_ON_BRIDGE |
|
|
|
|
+ QUIRK_NO_BRIDGE_D3),
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
@@ -99,6 +107,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
|
|
|
|
dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
|
|
|
|
if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
|
|
|
|
dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n");
|
|
|
|
+ if (card->quirks & QUIRK_NO_BRIDGE_D3)
|
|
|
|
+ dev_info(&pdev->dev,
|
|
|
|
+ "quirk no_brigde_d3 enabled\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
|
|
|
|
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
index 5d30ae39d65e..c14eb56eb911 100644
|
|
|
|
--- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
+++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
|
|
|
|
@@ -5,6 +5,7 @@
|
|
|
|
|
|
|
|
#define QUIRK_FW_RST_D3COLD BIT(0)
|
|
|
|
#define QUIRK_DO_FLR_ON_BRIDGE BIT(1)
|
|
|
|
+#define QUIRK_NO_BRIDGE_D3 BIT(2)
|
|
|
|
|
|
|
|
void mwifiex_initialize_quirks(struct pcie_service_card *card);
|
|
|
|
int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
|
|
|
|
--
|
2023-08-25 20:34:31 +00:00
|
|
|
2.42.0
|
2023-07-07 22:33:51 +00:00
|
|
|
|
2023-08-25 20:34:31 +00:00
|
|
|
From f9d0cf76c6cf6015c066d70b0961bcf1ad5461b5 Mon Sep 17 00:00:00 2001
|
2023-07-07 22:33:51 +00:00
|
|
|
From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
|
|
|
|
Date: Thu, 25 Mar 2021 11:33:02 +0100
|
|
|
|
Subject: [PATCH] Bluetooth: btusb: Lower passive lescan interval on Marvell
|
|
|
|
88W8897
|
|
|
|
|
|
|
|
The Marvell 88W8897 combined wifi and bluetooth card (pcie+usb version)
|
|
|
|
is used in a lot of Microsoft Surface devices, and all those devices
|
|
|
|
suffer from very low 2.4GHz wifi connection speeds while bluetooth is
|
|
|
|
enabled. The reason for that is that the default passive scanning
|
|
|
|
interval for Bluetooth Low Energy devices is quite high in Linux
|
|
|
|
(interval of 60 msec and scan window of 30 msec, see hci_core.c), and
|
|
|
|
the Marvell chip is known for its bad bt+wifi coexisting performance.
|
|
|
|
|
|
|
|
So decrease that passive scan interval and make the scan window shorter
|
|
|
|
on this particular device to allow for spending more time transmitting
|
|
|
|
wifi signals: The new scan interval is 250 msec (0x190 * 0.625 msec) and
|
|
|
|
the new scan window is 6.25 msec (0xa * 0,625 msec).
|
|
|
|
|
|
|
|
This change has a very large impact on the 2.4GHz wifi speeds and gets
|
|
|
|
it up to performance comparable with the Windows driver, which seems to
|
|
|
|
apply a similar quirk.
|
|
|
|
|
|
|
|
The interval and window length were tested and found to work very well
|
|
|
|
with a lot of Bluetooth Low Energy devices, including the Surface Pen, a
|
|
|
|
Bluetooth Speaker and two modern Bluetooth headphones. All devices were
|
|
|
|
discovered immediately after turning them on. Even lower values were
|
|
|
|
also tested, but they introduced longer delays until devices get
|
|
|
|
discovered.
|
|
|
|
|
|
|
|
Patchset: mwifiex
|
|
|
|
---
|
|
|
|
drivers/bluetooth/btusb.c | 15 +++++++++++++++
|
|
|
|
1 file changed, 15 insertions(+)
|
|
|
|
|
|
|
|
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
2023-08-25 20:34:31 +00:00
|
|
|
index 025e803ba55c..cf3d0c36a160 100644
|
2023-07-07 22:33:51 +00:00
|
|
|
--- a/drivers/bluetooth/btusb.c
|
|
|
|
+++ b/drivers/bluetooth/btusb.c
|
|
|
|
@@ -65,6 +65,7 @@ static struct usb_driver btusb_driver;
|
|
|
|
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
|
|
|
|
#define BTUSB_INTEL_NO_WBS_SUPPORT BIT(26)
|
|
|
|
#define BTUSB_ACTIONS_SEMI BIT(27)
|
|
|
|
+#define BTUSB_LOWER_LESCAN_INTERVAL BIT(28)
|
|
|
|
|
|
|
|
static const struct usb_device_id btusb_table[] = {
|
|
|
|
/* Generic Bluetooth USB device */
|
|
|
|
@@ -468,6 +469,7 @@ static const struct usb_device_id blacklist_table[] = {
|
|
|
|
{ USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
|
|
|
|
{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
|
|
|
|
{ USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
|
|
|
|
+ { USB_DEVICE(0x1286, 0x204c), .driver_info = BTUSB_LOWER_LESCAN_INTERVAL },
|
|
|
|
|
|
|
|
/* Intel Bluetooth devices */
|
|
|
|
{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED },
|
2023-08-25 20:34:31 +00:00
|
|
|
@@ -4300,6 +4302,19 @@ static int btusb_probe(struct usb_interface *intf,
|
2023-07-07 22:33:51 +00:00
|
|
|
if (id->driver_info & BTUSB_MARVELL)
|
|
|
|
hdev->set_bdaddr = btusb_set_bdaddr_marvell;
|
|
|
|
|
|
|
|
+ /* The Marvell 88W8897 combined wifi and bluetooth card is known for
|
|
|
|
+ * very bad bt+wifi coexisting performance.
|
|
|
|
+ *
|
|
|
|
+ * Decrease the passive BT Low Energy scan interval a bit
|
|
|
|
+ * (0x0190 * 0.625 msec = 250 msec) and make the scan window shorter
|
|
|
|
+ * (0x000a * 0,625 msec = 6.25 msec). This allows for significantly
|
|
|
|
+ * higher wifi throughput while passively scanning for BT LE devices.
|
|
|
|
+ */
|
|
|
|
+ if (id->driver_info & BTUSB_LOWER_LESCAN_INTERVAL) {
|
|
|
|
+ hdev->le_scan_interval = 0x0190;
|
|
|
|
+ hdev->le_scan_window = 0x000a;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) &&
|
|
|
|
(id->driver_info & BTUSB_MEDIATEK)) {
|
|
|
|
hdev->setup = btusb_mtk_setup;
|
|
|
|
--
|
2023-08-25 20:34:31 +00:00
|
|
|
2.42.0
|
2023-07-07 22:33:51 +00:00
|
|
|
|