wifi: rtw89: pci: use DBI function for 8852AE/8852BE/8851BE
commit 9496d62f3877bc0f97b415bc04af98d092878026 upstream. Sometimes driver can't use kernel API pci_read/write_config_byte to access the PCI config space of above address 0x100 due to the negotiated PCI setting. 8852AE/8852BE/8851BE provide another way called DBI function, which belongs to WiFi mac and could access all PCI config space for this case. Link: https://lore.kernel.org/linux-wireless/79fe81b7db7148b9a7da2353c16d70fb@realtek.com/T/#t Signed-off-by: Chin-Yen Lee <timlee@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://msgid.link/20240103012346.6822-1-pkshih@realtek.com Signed-off-by: Zenm Chen <zenmchen@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
eeacfbab98
commit
66bde385a1
@@ -1822,22 +1822,87 @@ static int rtw89_write16_mdio_clr(struct rtw89_dev *rtwdev, u8 addr, u16 mask, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_dbi_write8(struct rtw89_dev *rtwdev, u16 addr, u8 data)
|
||||
{
|
||||
u16 addr_2lsb = addr & B_AX_DBI_2LSB;
|
||||
u16 write_addr;
|
||||
u8 flag;
|
||||
int ret;
|
||||
|
||||
write_addr = addr & B_AX_DBI_ADDR_MSK;
|
||||
write_addr |= u16_encode_bits(BIT(addr_2lsb), B_AX_DBI_WREN_MSK);
|
||||
rtw89_write8(rtwdev, R_AX_DBI_WDATA + addr_2lsb, data);
|
||||
rtw89_write16(rtwdev, R_AX_DBI_FLAG, write_addr);
|
||||
rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_WFLAG >> 16);
|
||||
|
||||
ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10,
|
||||
10 * RTW89_PCI_WR_RETRY_CNT, false,
|
||||
rtwdev, R_AX_DBI_FLAG + 2);
|
||||
if (ret)
|
||||
rtw89_err(rtwdev, "failed to write DBI register, addr=0x%X\n",
|
||||
addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_dbi_read8(struct rtw89_dev *rtwdev, u16 addr, u8 *value)
|
||||
{
|
||||
u16 read_addr = addr & B_AX_DBI_ADDR_MSK;
|
||||
u8 flag;
|
||||
int ret;
|
||||
|
||||
rtw89_write16(rtwdev, R_AX_DBI_FLAG, read_addr);
|
||||
rtw89_write8(rtwdev, R_AX_DBI_FLAG + 2, B_AX_DBI_RFLAG >> 16);
|
||||
|
||||
ret = read_poll_timeout_atomic(rtw89_read8, flag, !flag, 10,
|
||||
10 * RTW89_PCI_WR_RETRY_CNT, false,
|
||||
rtwdev, R_AX_DBI_FLAG + 2);
|
||||
if (ret) {
|
||||
rtw89_err(rtwdev, "failed to read DBI register, addr=0x%X\n",
|
||||
addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
read_addr = R_AX_DBI_RDATA + (addr & 3);
|
||||
*value = rtw89_read8(rtwdev, read_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtw89_pci_write_config_byte(struct rtw89_dev *rtwdev, u16 addr,
|
||||
u8 data)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
|
||||
struct pci_dev *pdev = rtwpci->pdev;
|
||||
int ret;
|
||||
|
||||
return pci_write_config_byte(pdev, addr, data);
|
||||
ret = pci_write_config_byte(pdev, addr, data);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
|
||||
ret = rtw89_dbi_write8(rtwdev, addr, data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_pci_read_config_byte(struct rtw89_dev *rtwdev, u16 addr,
|
||||
u8 *value)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
|
||||
struct pci_dev *pdev = rtwpci->pdev;
|
||||
int ret;
|
||||
|
||||
return pci_read_config_byte(pdev, addr, value);
|
||||
ret = pci_read_config_byte(pdev, addr, value);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B)
|
||||
ret = rtw89_dbi_read8(rtwdev, addr, value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtw89_pci_config_byte_set(struct rtw89_dev *rtwdev, u16 addr,
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#define B_AX_DBI_WFLAG BIT(16)
|
||||
#define B_AX_DBI_WREN_MSK GENMASK(15, 12)
|
||||
#define B_AX_DBI_ADDR_MSK GENMASK(11, 2)
|
||||
#define B_AX_DBI_2LSB GENMASK(1, 0)
|
||||
#define R_AX_DBI_WDATA 0x1094
|
||||
#define R_AX_DBI_RDATA 0x1098
|
||||
|
||||
|
Reference in New Issue
Block a user