Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 1a7fecb766c8 ("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>

authored by

Christian Lamparter and committed by
Kalle Valo
f8914a14 cc6df017

+25 -11
+25 -11
drivers/net/wireless/ath/ath10k/pci.c
··· 3486 3486 struct ath10k_pci *ar_pci; 3487 3487 enum ath10k_hw_rev hw_rev; 3488 3488 struct ath10k_bus_params bus_params = {}; 3489 - bool pci_ps; 3489 + bool pci_ps, is_qca988x = false; 3490 3490 int (*pci_soft_reset)(struct ath10k *ar); 3491 3491 int (*pci_hard_reset)(struct ath10k *ar); 3492 3492 u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); ··· 3496 3496 case QCA988X_2_0_DEVICE_ID: 3497 3497 hw_rev = ATH10K_HW_QCA988X; 3498 3498 pci_ps = false; 3499 + is_qca988x = true; 3499 3500 pci_soft_reset = ath10k_pci_warm_reset; 3500 3501 pci_hard_reset = ath10k_pci_qca988x_chip_reset; 3501 3502 targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr; ··· 3616 3615 goto err_deinit_irq; 3617 3616 } 3618 3617 3618 + bus_params.dev_type = ATH10K_DEV_TYPE_LL; 3619 + bus_params.link_can_suspend = true; 3620 + /* Read CHIP_ID before reset to catch QCA9880-AR1A v1 devices that 3621 + * fall off the bus during chip_reset. These chips have the same pci 3622 + * device id as the QCA9880 BR4A or 2R4E. So that's why the check. 3623 + */ 3624 + if (is_qca988x) { 3625 + bus_params.chip_id = 3626 + ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); 3627 + if (bus_params.chip_id != 0xffffffff) { 3628 + if (!ath10k_pci_chip_is_supported(pdev->device, 3629 + bus_params.chip_id)) 3630 + goto err_unsupported; 3631 + } 3632 + } 3633 + 3619 3634 ret = ath10k_pci_chip_reset(ar); 3620 3635 if (ret) { 3621 3636 ath10k_err(ar, "failed to reset chip: %d\n", ret); 3622 3637 goto err_free_irq; 3623 3638 } 3624 3639 3625 - bus_params.dev_type = ATH10K_DEV_TYPE_LL; 3626 - bus_params.link_can_suspend = true; 3627 3640 bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); 3628 - if (bus_params.chip_id == 0xffffffff) { 3629 - ath10k_err(ar, "failed to get chip id\n"); 3630 - goto err_free_irq; 3631 - } 3641 + if (bus_params.chip_id == 0xffffffff) 3642 + goto err_unsupported; 3632 3643 3633 - if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) { 3634 - ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", 3635 - pdev->device, bus_params.chip_id); 3644 + if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) 3636 3645 goto err_free_irq; 3637 - } 3638 3646 3639 3647 ret = ath10k_core_register(ar, &bus_params); 3640 3648 if (ret) { ··· 3652 3642 } 3653 3643 3654 3644 return 0; 3645 + 3646 + err_unsupported: 3647 + ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", 3648 + pdev->device, bus_params.chip_id); 3655 3649 3656 3650 err_free_irq: 3657 3651 ath10k_pci_free_irq(ar);