Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69ce674b authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville
Browse files

ath9k: do btcoex ASPM disabling at initialization time



Disable ASPM in pci ->probe on upstream (device) and downstream
(PCIe port) component. According to e1000e driver authors this is
required. I did not find that requirement in PCIe spec, but it seems
to be logical for me.

This need to be fixed for CONFIG_PCIEASPM, that will be done later ...

Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3b9cf1be
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -603,10 +603,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)

	ath9k_hw_init_mode_regs(ah);


	if (ah->is_pciexpress)
		ath9k_hw_aspm_init(ah);
	else
	if (!ah->is_pciexpress)
		ath9k_hw_disablepcie(ah);

	if (!AR_SREV_9300_20_OR_LATER(ah))
@@ -621,6 +618,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
	if (r)
		return r;

	if (ah->is_pciexpress)
		ath9k_hw_aspm_init(ah);

	r = ath9k_hw_init_macaddr(ah);
	if (r) {
		ath_err(common, "Failed to initialize MAC address\n");
+0 −4
Original line number Diff line number Diff line
@@ -1036,10 +1036,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
void ath9k_hw_proc_mib_event(struct ath_hw *ah);
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);

#define ATH_PCIE_CAP_LINK_CTRL	0x70
#define ATH_PCIE_CAP_LINK_L0S	1
#define ATH_PCIE_CAP_LINK_L1	2

#define ATH9K_CLOCK_RATE_CCK		22
#define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
#define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
+0 −2
Original line number Diff line number Diff line
@@ -1145,8 +1145,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
					   AR_STOMP_LOW_WLAN_WGHT);
		ath9k_hw_btcoex_enable(ah);

		if (common->bus_ops->bt_coex_prep)
			common->bus_ops->bt_coex_prep(common);
		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
			ath9k_btcoex_timer_resume(sc);
	}
+25 −19
Original line number Diff line number Diff line
@@ -89,23 +89,6 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
	return true;
}

/*
 * Bluetooth coexistance requires disabling ASPM.
 */
static void ath_pci_bt_coex_prep(struct ath_common *common)
{
	struct ath_softc *sc = (struct ath_softc *) common->priv;
	struct pci_dev *pdev = to_pci_dev(sc->dev);
	u8 aspm;

	if (!pci_is_pcie(pdev))
		return;

	pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
	aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
	pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
}

static void ath_pci_extn_synch_enable(struct ath_common *common)
{
	struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -117,6 +100,7 @@ static void ath_pci_extn_synch_enable(struct ath_common *common)
	pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
}

/* Need to be called after we discover btcoex capabilities */
static void ath_pci_aspm_init(struct ath_common *common)
{
	struct ath_softc *sc = (struct ath_softc *) common->priv;
@@ -126,10 +110,33 @@ static void ath_pci_aspm_init(struct ath_common *common)
	int pos;
	u8 aspm;

	if (!pci_is_pcie(pdev))
	pos = pci_pcie_cap(pdev);
	if (!pos)
		return;

	parent = pdev->bus->self;

	if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) {
		/* Bluetooth coexistance requires disabling ASPM. */
		pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
		aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
		pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);

		/*
		 * Both upstream and downstream PCIe components should
		 * have the same ASPM settings.
		 */
		if (WARN_ON(!parent))
			return;

		pos = pci_pcie_cap(parent);
		pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm);
		aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
		pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm);

		return;
	}

	if (WARN_ON(!parent))
		return;

@@ -146,7 +153,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
	.ath_bus_type = ATH_PCI,
	.read_cachesize = ath_pci_read_cachesize,
	.eeprom_read = ath_pci_eeprom_read,
	.bt_coex_prep = ath_pci_bt_coex_prep,
	.extn_synch_en = ath_pci_extn_synch_enable,
	.aspm_init = ath_pci_aspm_init,
};