Skip to content

Commit b5fbb78

Browse files
committed
mwifiex: Add quirk resetting the PCI bridge on Surface Pro 5 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 certain systems like the Microsoft Surface Pro 5 from entering deep powersaving states (platform C-State 10), because the exit latency of that state would be higher than what the card can tolerate. Now the card works just the same (including the firmware crashes) when that hardcoded LTR value is reported, so it's kind of useless and only prevents us from saving power. It appears that the power management core of the PCH resets its stored LTR values when doing a function level reset of the PCI bridge device. ALso the card firmware won't report a new LTR unless it's restarted, so resetting the bridge device seems to be a good solution for resetting the LTR value to 0 and thus allowing deep powersaving states.
1 parent e8470c7 commit b5fbb78

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

drivers/net/wireless/marvell/mwifiex/pcie.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,9 +1600,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
16001600
static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
16011601
{
16021602
struct pcie_service_card *card = adapter->card;
1603+
struct pci_dev *pdev = card->dev;
1604+
struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
16031605
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
16041606
int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
16051607

1608+
/* Trigger a function level reset of the PCI bridge device, this makes
1609+
* the firmware of PCIe 88W8897 cards stop reporting a fixed LTR value
1610+
* that prevents the system from entering package C10 and S0ix powersaving
1611+
* states.
1612+
* We need to do it here because it must happen after firmware
1613+
* initialization and this function is called after that is done.
1614+
*/
1615+
if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
1616+
pci_reset_function(parent_pdev);
1617+
16061618
/* Write the RX ring read pointer in to reg->rx_rdptr */
16071619
if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
16081620
tx_wrap)) {

drivers/net/wireless/marvell/mwifiex/pcie_quirks.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
4343
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
4444
},
4545
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
46-
QUIRK_NO_BRIDGE_D3),
46+
QUIRK_NO_BRIDGE_D3 |
47+
QUIRK_DO_FLR_ON_BRIDGE),
4748
},
4849
{
4950
.ident = "Surface Pro 5 (LTE)",
@@ -53,7 +54,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
5354
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
5455
},
5556
.driver_data = (void *)(QUIRK_FW_RST_D3COLD |
56-
QUIRK_NO_BRIDGE_D3),
57+
QUIRK_NO_BRIDGE_D3 |
58+
QUIRK_DO_FLR_ON_BRIDGE),
5759
},
5860
{
5961
.ident = "Surface Pro 6",
@@ -147,6 +149,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
147149
if (card->quirks & QUIRK_NO_BRIDGE_D3)
148150
dev_info(&pdev->dev,
149151
"quirk no_brigde_d3 enabled\n");
152+
if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
153+
dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n");
150154
}
151155

152156
static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)

drivers/net/wireless/marvell/mwifiex/pcie_quirks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
#define QUIRK_FW_RST_WSID_S3 BIT(1)
1414
#define QUIRK_NO_BRIDGE_D3 BIT(2)
15+
#define QUIRK_DO_FLR_ON_BRIDGE BIT(4)
1516

1617
void mwifiex_initialize_quirks(struct pcie_service_card *card);
1718
int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);

0 commit comments

Comments
 (0)