148 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// NXP Wireless LAN device driver: PCIE and platform specific quirks3 4#include <linux/dmi.h>5 6#include "pcie_quirks.h"7 8/* quirk table based on DMI matching */9static const struct dmi_system_id mwifiex_quirk_table[] = {10 {11 .ident = "Surface Pro 4",12 .matches = {13 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),14 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),15 },16 .driver_data = (void *)QUIRK_FW_RST_D3COLD,17 },18 {19 .ident = "Surface Pro 5",20 .matches = {21 /* match for SKU here due to generic product name "Surface Pro" */22 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),23 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),24 },25 .driver_data = (void *)QUIRK_FW_RST_D3COLD,26 },27 {28 .ident = "Surface Pro 5 (LTE)",29 .matches = {30 /* match for SKU here due to generic product name "Surface Pro" */31 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),32 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),33 },34 .driver_data = (void *)QUIRK_FW_RST_D3COLD,35 },36 {37 .ident = "Surface Pro 6",38 .matches = {39 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),40 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),41 },42 .driver_data = (void *)QUIRK_FW_RST_D3COLD,43 },44 {45 .ident = "Surface Book 1",46 .matches = {47 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),48 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),49 },50 .driver_data = (void *)QUIRK_FW_RST_D3COLD,51 },52 {53 .ident = "Surface Book 2",54 .matches = {55 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),56 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),57 },58 .driver_data = (void *)QUIRK_FW_RST_D3COLD,59 },60 {61 .ident = "Surface Laptop 1",62 .matches = {63 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),64 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),65 },66 .driver_data = (void *)QUIRK_FW_RST_D3COLD,67 },68 {69 .ident = "Surface Laptop 2",70 .matches = {71 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),72 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),73 },74 .driver_data = (void *)QUIRK_FW_RST_D3COLD,75 },76 {}77};78 79void mwifiex_initialize_quirks(struct pcie_service_card *card)80{81 struct pci_dev *pdev = card->dev;82 const struct dmi_system_id *dmi_id;83 84 dmi_id = dmi_first_match(mwifiex_quirk_table);85 if (dmi_id)86 card->quirks = (uintptr_t)dmi_id->driver_data;87 88 if (!card->quirks)89 dev_info(&pdev->dev, "no quirks enabled\n");90 if (card->quirks & QUIRK_FW_RST_D3COLD)91 dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");92}93 94static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)95{96 dev_info(&pdev->dev, "putting into D3cold...\n");97 98 pci_save_state(pdev);99 if (pci_is_enabled(pdev))100 pci_disable_device(pdev);101 pci_set_power_state(pdev, PCI_D3cold);102}103 104static int mwifiex_pcie_set_power_d0(struct pci_dev *pdev)105{106 int ret;107 108 dev_info(&pdev->dev, "putting into D0...\n");109 110 pci_set_power_state(pdev, PCI_D0);111 ret = pci_enable_device(pdev);112 if (ret) {113 dev_err(&pdev->dev, "pci_enable_device failed\n");114 return ret;115 }116 pci_restore_state(pdev);117 118 return 0;119}120 121int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev)122{123 struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);124 int ret;125 126 /* Power-cycle (put into D3cold then D0) */127 dev_info(&pdev->dev, "Using reset_d3cold quirk to perform FW reset\n");128 129 /* We need to perform power-cycle also for bridge of wifi because130 * on some devices (e.g. Surface Book 1), the OS for some reasons131 * can't know the real power state of the bridge.132 * When tried to power-cycle only wifi, the reset failed with the133 * following dmesg log:134 * "Cannot transition to power state D0 for parent in D3hot".135 */136 mwifiex_pcie_set_power_d3cold(pdev);137 mwifiex_pcie_set_power_d3cold(parent_pdev);138 139 ret = mwifiex_pcie_set_power_d0(parent_pdev);140 if (ret)141 return ret;142 ret = mwifiex_pcie_set_power_d0(pdev);143 if (ret)144 return ret;145 146 return 0;147}148