123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- From 9c9103776669669ae724ca844f9ea1c24a3858dd Mon Sep 17 00:00:00 2001
- 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 5f997becdbaa..9a9929424513 100644
- --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
- +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
- @@ -1702,9 +1702,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
- static void 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 */
- 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);
- --
- 2.49.0
- From de88988bb0d5cbe32fabac2241c84c394d988c3d Mon Sep 17 00:00:00 2001
- 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 9a9929424513..2273e3029776 100644
- --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
- +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
- @@ -377,6 +377,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",
- @@ -418,6 +419,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);
- --
- 2.49.0
- From 4abcf78a128e215d638f9718acf11858cd5f278a Mon Sep 17 00:00:00 2001
- 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
- index 75dbe07e07e2..fd0f1aa5eaa9 100644
- --- 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 */
- @@ -440,6 +441,7 @@ static const struct usb_device_id quirks_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 },
- @@ -3870,6 +3872,19 @@ static int btusb_probe(struct usb_interface *intf,
- 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;
- --
- 2.49.0
|