mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-19 12:58:20 +07:00
ath10k: restore QCA9880-AR1A (v1) detection
This patch restores the old behavior that read
the chip_id on the QCA988x before resetting the
chip. This needs to be done in this order since
the unsupported QCA988x AR1A chips fall off the
bus when resetted. Otherwise the next MMIO Op
after the reset causes a BUS ERROR and panic.
Cc: stable@vger.kernel.org
Fixes: 1a7fecb766
("ath10k: reset chip before reading chip_id in probe")
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
cc6df017e5
commit
f8914a1462
@ -3486,7 +3486,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
struct ath10k_pci *ar_pci;
|
||||
enum ath10k_hw_rev hw_rev;
|
||||
struct ath10k_bus_params bus_params = {};
|
||||
bool pci_ps;
|
||||
bool pci_ps, is_qca988x = false;
|
||||
int (*pci_soft_reset)(struct ath10k *ar);
|
||||
int (*pci_hard_reset)(struct ath10k *ar);
|
||||
u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
|
||||
@ -3496,6 +3496,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
case QCA988X_2_0_DEVICE_ID:
|
||||
hw_rev = ATH10K_HW_QCA988X;
|
||||
pci_ps = false;
|
||||
is_qca988x = true;
|
||||
pci_soft_reset = ath10k_pci_warm_reset;
|
||||
pci_hard_reset = ath10k_pci_qca988x_chip_reset;
|
||||
targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
|
||||
@ -3615,25 +3616,34 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
goto err_deinit_irq;
|
||||
}
|
||||
|
||||
bus_params.dev_type = ATH10K_DEV_TYPE_LL;
|
||||
bus_params.link_can_suspend = true;
|
||||
/* Read CHIP_ID before reset to catch QCA9880-AR1A v1 devices that
|
||||
* fall off the bus during chip_reset. These chips have the same pci
|
||||
* device id as the QCA9880 BR4A or 2R4E. So that's why the check.
|
||||
*/
|
||||
if (is_qca988x) {
|
||||
bus_params.chip_id =
|
||||
ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
|
||||
if (bus_params.chip_id != 0xffffffff) {
|
||||
if (!ath10k_pci_chip_is_supported(pdev->device,
|
||||
bus_params.chip_id))
|
||||
goto err_unsupported;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ath10k_pci_chip_reset(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to reset chip: %d\n", ret);
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
bus_params.dev_type = ATH10K_DEV_TYPE_LL;
|
||||
bus_params.link_can_suspend = true;
|
||||
bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
|
||||
if (bus_params.chip_id == 0xffffffff) {
|
||||
ath10k_err(ar, "failed to get chip id\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
if (bus_params.chip_id == 0xffffffff)
|
||||
goto err_unsupported;
|
||||
|
||||
if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) {
|
||||
ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
|
||||
pdev->device, bus_params.chip_id);
|
||||
if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id))
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
ret = ath10k_core_register(ar, &bus_params);
|
||||
if (ret) {
|
||||
@ -3643,6 +3653,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
return 0;
|
||||
|
||||
err_unsupported:
|
||||
ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
|
||||
pdev->device, bus_params.chip_id);
|
||||
|
||||
err_free_irq:
|
||||
ath10k_pci_free_irq(ar);
|
||||
ath10k_pci_rx_retry_sync(ar);
|
||||
|
Loading…
Reference in New Issue
Block a user