Skip to content

Commit aa70ff0

Browse files
Ping-Ke ShihKalle Valo
authored andcommitted
wifi: rtw89: pci: early chips only enable 36-bit DMA on specific PCI hosts
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: 1fd4b3f ("wifi: rtw89: pci: support 36-bit PCI DMA address") Reported-by: Marcel Weißenbach <[email protected]> Closes: https://lore.kernel.org/linux-wireless/[email protected]/T/#m07c5694df1acb173a42e1a0bab7ac22bd231a2b8 Signed-off-by: Ping-Ke Shih <[email protected]> Tested-by: Marcel Weißenbach <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 52009b4 commit aa70ff0

File tree

1 file changed

+41
-7
lines changed
  • drivers/net/wireless/realtek/rtw89

1 file changed

+41
-7
lines changed

drivers/net/wireless/realtek/rtw89/pci.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
30263026
pci_disable_device(pdev);
30273027
}
30283028

3029-
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
3029+
static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
30303030
{
3031-
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
30323031
const struct rtw89_chip_info *chip = rtwdev->chip;
30333032

3034-
if (!rtwpci->enable_dac)
3035-
return;
3036-
30373033
switch (chip->chip_id) {
30383034
case RTL8852A:
30393035
case RTL8852B:
30403036
case RTL8851B:
30413037
case RTL8852BT:
3042-
break;
3038+
return true;
30433039
default:
3044-
return;
3040+
return false;
3041+
}
3042+
}
3043+
3044+
static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
3045+
{
3046+
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
3047+
struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
3048+
3049+
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
3050+
return true;
3051+
3052+
if (!bridge)
3053+
return false;
3054+
3055+
switch (bridge->vendor) {
3056+
case PCI_VENDOR_ID_INTEL:
3057+
return true;
3058+
case PCI_VENDOR_ID_ASMEDIA:
3059+
if (bridge->device == 0x2806)
3060+
return true;
3061+
break;
30453062
}
30463063

3064+
return false;
3065+
}
3066+
3067+
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
3068+
{
3069+
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
3070+
3071+
if (!rtwpci->enable_dac)
3072+
return;
3073+
3074+
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
3075+
return;
3076+
30473077
rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
30483078
}
30493079

@@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
30613091
goto err;
30623092
}
30633093

3094+
if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
3095+
goto no_dac;
3096+
30643097
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
30653098
if (!ret) {
30663099
rtwpci->enable_dac = true;
@@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
30733106
goto err_release_regions;
30743107
}
30753108
}
3109+
no_dac:
30763110

30773111
resource_len = pci_resource_len(pdev, bar_id);
30783112
rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);

0 commit comments

Comments
 (0)