@@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
pci_disable_device(pdev);
}
-static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
+static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
{
- struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
const struct rtw89_chip_info *chip = rtwdev->chip;
- if (!rtwpci->enable_dac)
- return;
-
switch (chip->chip_id) {
case RTL8852A:
case RTL8852B:
case RTL8851B:
case RTL8852BT:
- break;
+ return true;
default:
- return;
+ return false;
+ }
+}
+
+static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
+
+ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+ return true;
+
+ if (!bridge)
+ return false;
+
+ switch (bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ return true;
+ case PCI_VENDOR_ID_ASMEDIA:
+ if (bridge->device == 0x2806)
+ return true;
+ break;
}
+ return false;
+}
+
+static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+
+ if (!rtwpci->enable_dac)
+ return;
+
+ if (!rtw89_pci_chip_is_manual_dac(rtwdev))
+ return;
+
rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
}
@@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
goto err;
}
+ if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
+ goto no_dac;
+
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
if (!ret) {
rtwpci->enable_dac = true;
@@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
goto err_release_regions;
}
}
+no_dac:
resource_len = pci_resource_len(pdev, bar_id);
rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
The early chips including RTL8852A, RTL8851B, RTL8852B and RTL8852BT have interoperability problems of 36-bit DMA with some PCI hosts. Rollback to 32-bit DMA by default, and only enable 36-bit DMA for tested platforms. Since all Intel platforms we have can work correctly, add the vendor ID to white list. Otherwise, list vendor/device ID of bridge we have tested. Fixes: 1fd4b3fe52ef ("wifi: rtw89: pci: support 36-bit PCI DMA address") Reported-by: Marcel Weißenbach <mweissenbach@ignaz.org> Closes: https://lore.kernel.org/linux-wireless/20240918073237.Horde.VLueh0_KaiDw-9asEEcdM84@ignaz.org/T/#m07c5694df1acb173a42e1a0bab7ac22bd231a2b8 Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> --- drivers/net/wireless/realtek/rtw89/pci.c | 48 ++++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-)