Message ID | 20220819064811.37700-5-pkshih@realtek.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 843059d8193c1d28bed9b80c331088e775cf0151 |
Delegated to: | Kalle Valo |
Headers | show |
Series | wifi: rtw89: correct MAC and PCI settings | expand |
On Fri, Aug 19, 2022 at 02:48:10PM +0800, Ping-Ke Shih wrote: > From: Chin-Yen Lee <timlee@realtek.com> > > 8852CE controls CLKREQ, ASPM L1, L1ss via wifi registers > instead, so change them accordingly. > ... > static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) > { > + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; > int ret; > > - if (enable) > - ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_TIMER_CTRL, > - RTW89_PCIE_BIT_L1SUB); > - else > - ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_TIMER_CTRL, > - RTW89_PCIE_BIT_L1SUB); > - if (ret) > - rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", > - enable ? "set" : "unset", ret); > + if (chip_id == RTL8852A || chip_id == RTL8852B) { > + if (enable) > + ret = rtw89_pci_config_byte_set(rtwdev, > + RTW89_PCIE_TIMER_CTRL, > + RTW89_PCIE_BIT_L1SUB); > + else > + ret = rtw89_pci_config_byte_clr(rtwdev, > + RTW89_PCIE_TIMER_CTRL, > + RTW89_PCIE_BIT_L1SUB); > + if (ret) > + rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", > + enable ? "set" : "unset", ret); > + } else if (chip_id == RTL8852C) { > + ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1SS_STS_V1, > + RTW89_PCIE_BIT_ASPM_L11 | > + RTW89_PCIE_BIT_PCI_L11); > + if (ret) > + rtw89_warn(rtwdev, "failed to unset ASPM L1.1, ret=%d", ret); > + if (enable) > + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, > + B_AX_L1SUB_DISABLE); > + else > + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, > + B_AX_L1SUB_DISABLE); > + } > } We get here via this path: rtw89_pci_probe rtw89_pci_l1ss_cfg pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) rtw89_pci_l1ss_set(rtwdev, true); This looks like it might be a problem because L1SS configuration is owned by the PCI core, not by the device driver. The PCI core provides sysfs user interfaces that can enable and disable L1SS at run-time without notification to the driver (see [1]). The user may enable or disable L1SS using those sysfs interfaces, and this code in the rtw89 driver will not be called. Bjorn P.S. rtw89_pci_l1ss_set() is only called from rtw89_pci_l1ss_cfg() which always supplies "enable == true", so it looks like that parameter is not needed. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/testing/sysfs-bus-pci?id=v6.1#n410
> -----Original Message----- > From: Bjorn Helgaas <helgaas@kernel.org> > Sent: Wednesday, February 8, 2023 4:50 AM > To: Ping-Ke Shih <pkshih@realtek.com> > Cc: Kalle Valo <kvalo@kernel.org>; Leo.Li <leo.li@realtek.com>; Timlee <timlee@realtek.com>; Bernie Huang > <phhuang@realtek.com>; linux-wireless@vger.kernel.org; linux-pci@vger.kernel.org > Subject: Re: [PATCH v2 4/5] wifi: rtw89: pci: enable CLK_REQ, ASPM, L1 and L1ss for 8852c > > On Fri, Aug 19, 2022 at 02:48:10PM +0800, Ping-Ke Shih wrote: > > From: Chin-Yen Lee <timlee@realtek.com> > > > > 8852CE controls CLKREQ, ASPM L1, L1ss via wifi registers > > instead, so change them accordingly. > > > ... > > static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) > > { > > + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; > > int ret; > > > > - if (enable) > > - ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_TIMER_CTRL, > > - RTW89_PCIE_BIT_L1SUB); > > - else > > - ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_TIMER_CTRL, > > - RTW89_PCIE_BIT_L1SUB); > > - if (ret) > > - rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", > > - enable ? "set" : "unset", ret); > > + if (chip_id == RTL8852A || chip_id == RTL8852B) { > > + if (enable) > > + ret = rtw89_pci_config_byte_set(rtwdev, > > + RTW89_PCIE_TIMER_CTRL, > > + RTW89_PCIE_BIT_L1SUB); > > + else > > + ret = rtw89_pci_config_byte_clr(rtwdev, > > + RTW89_PCIE_TIMER_CTRL, > > + RTW89_PCIE_BIT_L1SUB); > > + if (ret) > > + rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", > > + enable ? "set" : "unset", ret); > > + } else if (chip_id == RTL8852C) { > > + ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1SS_STS_V1, > > + RTW89_PCIE_BIT_ASPM_L11 | > > + RTW89_PCIE_BIT_PCI_L11); > > + if (ret) > > + rtw89_warn(rtwdev, "failed to unset ASPM L1.1, ret=%d", ret); > > + if (enable) > > + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, > > + B_AX_L1SUB_DISABLE); > > + else > > + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, > > + B_AX_L1SUB_DISABLE); > > + } > > } > > We get here via this path: > > rtw89_pci_probe > rtw89_pci_l1ss_cfg > pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); > if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) > rtw89_pci_l1ss_set(rtwdev, true); > > This looks like it might be a problem because L1SS configuration is > owned by the PCI core, not by the device driver. The PCI core > provides sysfs user interfaces that can enable and disable L1SS at > run-time without notification to the driver (see [1]). > > The user may enable or disable L1SS using those sysfs interfaces, and > this code in the rtw89 driver will not be called. The chunk of code is to configure L1SS of chip specific setting along with standard PCI capability, and normally the setting and capability are consistent. An exception is that PCI capability is enabled but chip specific setting is disabled, when we want to use module parameter to disable chip specific setting experimentally to resolve interoperability problem on some platforms. We don't suggest the use case that L1SS of PCI capability is disabled but chip specific setting is enabled, because hardware could get abnormal occasionally. Also, it could also get unexpected behavior suddenly if we change L1SS dynamically. Summary: PCI capability chip specific setting comment -------------- --------------------- ------- enabled enabled ok, currently support disabled disabled ok, currently support enabled disabled experimental case via module parameter disabled enabled don't suggest With above reasons, if users meet problem or unexpected result after changing L1SS, we may tell them this hardware can't dynamically configure L1SS via sysfs interfaces. Ping-Ke
On Wed, Feb 08, 2023 at 09:15:50AM +0000, Ping-Ke Shih wrote: > > -----Original Message----- > > From: Bjorn Helgaas <helgaas@kernel.org> > > On Fri, Aug 19, 2022 at 02:48:10PM +0800, Ping-Ke Shih wrote: > > > From: Chin-Yen Lee <timlee@realtek.com> > > > > > > 8852CE controls CLKREQ, ASPM L1, L1ss via wifi registers > > > instead, so change them accordingly. > > ... > > We get here via this path: > > > > rtw89_pci_probe > > rtw89_pci_l1ss_cfg > > pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); > > if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) > > rtw89_pci_l1ss_set(rtwdev, true); > > > > This looks like it might be a problem because L1SS configuration > > is owned by the PCI core, not by the device driver. The PCI core > > provides sysfs user interfaces that can enable and disable L1SS at > > run-time without notification to the driver (see [1]). > > > > The user may enable or disable L1SS using those sysfs interfaces, > > and this code in the rtw89 driver will not be called. > > The chunk of code is to configure L1SS of chip specific setting > along with standard PCI capability, and normally the setting and > capability are consistent. An exception is that PCI capability is > enabled but chip specific setting is disabled, when we want to use > module parameter to disable chip specific setting experimentally to > resolve interoperability problem on some platforms. This is a significant usability problem. An interoperability problem means the device doesn't work correctly for some users, and there's no obvious reason *why* it doesn't work, so they don't know how to fix it. Module parameters are not a solution because users don't know when they are needed or how to use them. This leads to situations like [1,2,3], where users waste a lot of time flailing around to get the device to work, and the eventual "solution" is to replace it with something else: After replacing the Realtek card with Intel AX200 I do not have the described problem anymore. > We don't suggest the use case that L1SS of PCI capability is > disabled but chip specific setting is enabled, because hardware > could get abnormal occasionally. Also, it could also get unexpected > behavior suddenly if we change L1SS dynamically. > > Summary: > > PCI capability chip specific setting comment > -------------- --------------------- ------- > enabled enabled ok, currently support > disabled disabled ok, currently support > enabled disabled experimental case via module parameter > disabled enabled don't suggest I think the fact that you need chip-specific code here is a hardware defect in the rtw89 device. The whole point of L1SS being in the PCIe spec is so generic software can configure it without having to know chip-specific details. > With above reasons, if users meet problem or unexpected result after > changing L1SS, we may tell them this hardware can't dynamically > configure L1SS via sysfs interfaces. How can we make this better, so the device works and users never have to specify those module parameters? Would it help if we had a way to make a quirk that meant "never enable L1SS for this device"? Obviously that's not ideal because we want the power savings of L1SS, but the power saving is only worthwhile if the device always *works*. Or maybe we could have a quirk that means "the PCI core will never change the L1SS configuration for this device"? Would that help? Bjorn [1] https://github.com/lwfinger/rtw89/issues/41 [2] https://bbs.archlinux.org/viewtopic.php?id=273515 [3] https://bugs.launchpad.net/ubuntu/+source/linux-firmware/+bug/1971656
> -----Original Message----- > From: Bjorn Helgaas <helgaas@kernel.org> > Sent: Thursday, February 9, 2023 6:04 AM > To: Ping-Ke Shih <pkshih@realtek.com> > Cc: Kalle Valo <kvalo@kernel.org>; Leo.Li <leo.li@realtek.com>; Timlee <timlee@realtek.com>; Bernie Huang > <phhuang@realtek.com>; linux-wireless@vger.kernel.org; linux-pci@vger.kernel.org > Subject: Re: [PATCH v2 4/5] wifi: rtw89: pci: enable CLK_REQ, ASPM, L1 and L1ss for 8852c > > On Wed, Feb 08, 2023 at 09:15:50AM +0000, Ping-Ke Shih wrote: > > > -----Original Message----- > > > From: Bjorn Helgaas <helgaas@kernel.org> > > > On Fri, Aug 19, 2022 at 02:48:10PM +0800, Ping-Ke Shih wrote: > > > > From: Chin-Yen Lee <timlee@realtek.com> > > > > > > > > 8852CE controls CLKREQ, ASPM L1, L1ss via wifi registers > > > > instead, so change them accordingly. > > > ... > > > > We get here via this path: > > > > > > rtw89_pci_probe > > > rtw89_pci_l1ss_cfg > > > pci_read_config_dword(pdev, l1ss_cap_ptr + PCI_L1SS_CTL1, &l1ss_ctrl); > > > if (l1ss_ctrl & PCI_L1SS_CTL1_L1SS_MASK) > > > rtw89_pci_l1ss_set(rtwdev, true); > > > > > > This looks like it might be a problem because L1SS configuration > > > is owned by the PCI core, not by the device driver. The PCI core > > > provides sysfs user interfaces that can enable and disable L1SS at > > > run-time without notification to the driver (see [1]). > > > > > > The user may enable or disable L1SS using those sysfs interfaces, > > > and this code in the rtw89 driver will not be called. > > > > The chunk of code is to configure L1SS of chip specific setting > > along with standard PCI capability, and normally the setting and > > capability are consistent. An exception is that PCI capability is > > enabled but chip specific setting is disabled, when we want to use > > module parameter to disable chip specific setting experimentally to > > resolve interoperability problem on some platforms. > > This is a significant usability problem. An interoperability problem > means the device doesn't work correctly for some users, and there's no > obvious reason *why* it doesn't work, so they don't know how to fix > it. > > Module parameters are not a solution because users don't know when > they are needed or how to use them. This leads to situations like > [1,2,3], where users waste a lot of time flailing around to get the > device to work, and the eventual "solution" is to replace it with > something else: > > After replacing the Realtek card with Intel AX200 I do not have the > described problem anymore. A cause of interoperability problem could be due to PCI bridge side configured by BIOS. We have fixed this kind of problem many times before. Maybe, this device has less tolerance to handle PCI signals. The module parameter is an alternative way to help users to resolve the problem in their platforms. If people buy a computer with this device built-in, he will meet this problem in low probability because ODM will verify this ahead. If people buy this device themselves to install to their platforms, it is hard to guarantee it can work well, because cause of interoperability could be bride side as mentioned in beginning. > > > We don't suggest the use case that L1SS of PCI capability is > > disabled but chip specific setting is enabled, because hardware > > could get abnormal occasionally. Also, it could also get unexpected > > behavior suddenly if we change L1SS dynamically. > > > > Summary: > > > > PCI capability chip specific setting comment > > -------------- --------------------- ------- > > enabled enabled ok, currently support > > disabled disabled ok, currently support > > enabled disabled experimental case via module parameter > > disabled enabled don't suggest > > I think the fact that you need chip-specific code here is a hardware > defect in the rtw89 device. The whole point of L1SS being in the PCIe > spec is so generic software can configure it without having to know > chip-specific details. > > > With above reasons, if users meet problem or unexpected result after > > changing L1SS, we may tell them this hardware can't dynamically > > configure L1SS via sysfs interfaces. > > How can we make this better, so the device works and users never have > to specify those module parameters? Normally, users don't need to specify this module parameter. If it's really needed, we can add a quirk along with DMI vendor and product name to configure automatically. But, indeed we still need a user to try that module parameter can work on a certain platform. > > Would it help if we had a way to make a quirk that meant "never enable > L1SS for this device"? Obviously that's not ideal because we want the > power savings of L1SS, but the power saving is only worthwhile if the > device always *works*. > > Or maybe we could have a quirk that means "the PCI core will never > change the L1SS configuration for this device"? Would that help? > In fact, we only don't suggest to change L1SS "dynamically". Initially, enable or disable L1SS is usable, and driver will set chip-specific setting along with standard PCI configuration. So, I think it would be okay to have a quirk that "never change L1SS dynamically". But, I'm not sure if switching L1SS is a common option for average users? I mean L1SS normally is configured by developers only, so restrictions aren't always good to them, because they should know what they are doing. Ping-Ke
On Mon, Feb 13, 2023 at 01:46:51AM +0000, Ping-Ke Shih wrote: > > -----Original Message----- > > From: Bjorn Helgaas <helgaas@kernel.org> > > Sent: Thursday, February 9, 2023 6:04 AM > > To: Ping-Ke Shih <pkshih@realtek.com> > > Cc: Kalle Valo <kvalo@kernel.org>; Leo.Li <leo.li@realtek.com>; Timlee <timlee@realtek.com>; Bernie Huang > > <phhuang@realtek.com>; linux-wireless@vger.kernel.org; linux-pci@vger.kernel.org > > Subject: Re: [PATCH v2 4/5] wifi: rtw89: pci: enable CLK_REQ, ASPM, L1 and L1ss for 8852c It would be better if your email client allows you to respond without the unnecessary repetition of the From/To/Cc/Subject lines above. For example, this would be sufficient: > On Thursday, February 9, 2023 6:04 AM, Bjorn Helgaas wrote: > > On Wed, Feb 08, 2023 at 09:15:50AM +0000, Ping-Ke Shih wrote: > > > On Fri, Aug 19, 2022 at 02:48:10PM, Ping-Ke Shih wrote: Then it's shorter and easier to figure out who wrote what. > > On Wed, Feb 08, 2023 at 09:15:50AM +0000, Ping-Ke Shih wrote: > > > > -----Original Message----- > > > > From: Bjorn Helgaas <helgaas@kernel.org> > > > The chunk of code is to configure L1SS of chip specific setting > > > along with standard PCI capability, and normally the setting and > > > capability are consistent. An exception is that PCI capability is > > > enabled but chip specific setting is disabled, when we want to use > > > module parameter to disable chip specific setting experimentally to > > > resolve interoperability problem on some platforms. > > > > This is a significant usability problem. An interoperability problem > > means the device doesn't work correctly for some users, and there's no > > obvious reason *why* it doesn't work, so they don't know how to fix > > it. > > > > Module parameters are not a solution because users don't know when > > they are needed or how to use them. This leads to situations like > > [1,2,3], where users waste a lot of time flailing around to get the > > device to work, and the eventual "solution" is to replace it with > > something else: > > > > After replacing the Realtek card with Intel AX200 I do not have the > > described problem anymore. > > A cause of interoperability problem could be due to PCI bridge side > configured by BIOS. We have fixed this kind of problem many times before. > Maybe, this device has less tolerance to handle PCI signals. The module > parameter is an alternative way to help users to resolve the problem in > their platforms. If people buy a computer with this device built-in, he > will meet this problem in low probability because ODM will verify this > ahead. If people buy this device themselves to install to their platforms, > it is hard to guarantee it can work well, because cause of interoperability > could be bride side as mentioned in beginning. The BIOS or PCI core should configure both the bridge and the endpoint so they are consistent. If the driver needs to do something, e.g., via a module parameter, that means there's a BIOS or PCI core defect that should be fixed. It should be fixed in the PCI core, not in the individual driver. > > > We don't suggest the use case that L1SS of PCI capability is > > > disabled but chip specific setting is enabled, because hardware > > > could get abnormal occasionally. Also, it could also get unexpected > > > behavior suddenly if we change L1SS dynamically. > > > > > > Summary: > > > > > > PCI capability chip specific setting comment > > > -------------- --------------------- ------- > > > enabled enabled ok, currently support > > > disabled disabled ok, currently support > > > enabled disabled experimental case via module parameter > > > disabled enabled don't suggest > > > > I think the fact that you need chip-specific code here is a hardware > > defect in the rtw89 device. The whole point of L1SS being in the PCIe > > spec is so generic software can configure it without having to know > > chip-specific details. > > > > > With above reasons, if users meet problem or unexpected result after > > > changing L1SS, we may tell them this hardware can't dynamically > > > configure L1SS via sysfs interfaces. > > > > How can we make this better, so the device works and users never have > > to specify those module parameters? > > Normally, users don't need to specify this module parameter. If it's > really needed, we can add a quirk along with DMI vendor and product > name to configure automatically. But, indeed we still need a user to > try that module parameter can work on a certain platform. The fact that the parameter exists means *some* users do need it. And that is a huge problem because those users don't *know* they need it; they just see a device that doesn't work, and they don't know why. All they can do is try random combinations of parameters to see what seems to work. This just doesn't scale for users that deal with a dozen different devices in their system. We can't expect them to fiddle with module parameters for each. > > Would it help if we had a way to make a quirk that meant "never enable > > L1SS for this device"? Obviously that's not ideal because we want the > > power savings of L1SS, but the power saving is only worthwhile if the > > device always *works*. > > > > Or maybe we could have a quirk that means "the PCI core will never > > change the L1SS configuration for this device"? Would that help? > > In fact, we only don't suggest to change L1SS "dynamically". Initially, > enable or disable L1SS is usable, and driver will set chip-specific > setting along with standard PCI configuration. If your device is implemented correctly per the PCIe spec, there should be no problem with changing L1SS configuration dynamically. Of course if there are PCI core defects that mean it doesn't work, those can and should be fixed. > So, I think it would be okay to have a quirk that "never change L1SS > dynamically". But, I'm not sure if switching L1SS is a common > option for average users? I mean L1SS normally is configured by > developers only, so restrictions aren't always good to them, because > they should know what they are doing. There are sysfs options for changing L1SS configuration, and it's reasonable for users to change that based on changing workload. I expect tools like powertop to take advantage of that eventually. Bjorn
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index c09d2ffc5005f..67baf495a6986 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3291,6 +3291,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev) static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; int ret; if (rtw89_pci_disable_clkreq) @@ -3301,19 +3302,33 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) if (ret) rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, - RTW89_PCIE_BIT_CLK); - else - ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1_CTRL, - RTW89_PCIE_BIT_CLK); - if (ret) - rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d", - enable ? "set" : "unset", ret); + if (chip_id == RTL8852A) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_CLK); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_CLK); + if (ret) + rtw89_err(rtwdev, "failed to %s CLKREQ_L1, ret=%d", + enable ? "set" : "unset", ret); + } else if (chip_id == RTL8852C) { + rtw89_write32_set(rtwdev, R_AX_PCIE_LAT_CTRL, + B_AX_CLK_REQ_SEL_OPT | B_AX_CLK_REQ_SEL); + if (enable) + rtw89_write32_set(rtwdev, R_AX_L1_CLK_CTRL, + B_AX_CLK_REQ_N); + else + rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL, + B_AX_CLK_REQ_N); + } } static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; u8 value = 0; int ret; @@ -3332,12 +3347,23 @@ static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable) if (ret) rtw89_err(rtwdev, "failed to read ASPM Delay\n"); - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, - RTW89_PCIE_BIT_L1); - else - ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1_CTRL, - RTW89_PCIE_BIT_L1); + if (chip_id == RTL8852A || chip_id == RTL8852B) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_L1); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_L1_CTRL, + RTW89_PCIE_BIT_L1); + } else if (chip_id == RTL8852C) { + if (enable) + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_ASPM_CTRL_L1); + else + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_ASPM_CTRL_L1); + } if (ret) rtw89_err(rtwdev, "failed to %s ASPM L1, ret=%d", enable ? "set" : "unset", ret); @@ -3398,17 +3424,34 @@ static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev) static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable) { + enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; int ret; - if (enable) - ret = rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_TIMER_CTRL, - RTW89_PCIE_BIT_L1SUB); - else - ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_TIMER_CTRL, - RTW89_PCIE_BIT_L1SUB); - if (ret) - rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", - enable ? "set" : "unset", ret); + if (chip_id == RTL8852A || chip_id == RTL8852B) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_TIMER_CTRL, + RTW89_PCIE_BIT_L1SUB); + else + ret = rtw89_pci_config_byte_clr(rtwdev, + RTW89_PCIE_TIMER_CTRL, + RTW89_PCIE_BIT_L1SUB); + if (ret) + rtw89_err(rtwdev, "failed to %s L1SS, ret=%d", + enable ? "set" : "unset", ret); + } else if (chip_id == RTL8852C) { + ret = rtw89_pci_config_byte_clr(rtwdev, RTW89_PCIE_L1SS_STS_V1, + RTW89_PCIE_BIT_ASPM_L11 | + RTW89_PCIE_BIT_PCI_L11); + if (ret) + rtw89_warn(rtwdev, "failed to unset ASPM L1.1, ret=%d", ret); + if (enable) + rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_L1SUB_DISABLE); + else + rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1, + B_AX_L1SUB_DISABLE); + } } static void rtw89_pci_l1ss_cfg(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index e80380271cd35..63dc6d4db6022 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -62,9 +62,16 @@ #define B_AX_REQ_ENTR_L1 BIT(8) #define B_AX_L1SUB_DISABLE BIT(0) +#define R_AX_L1_CLK_CTRL 0x3010 +#define B_AX_CLK_REQ_N BIT(1) + #define R_AX_PCIE_BG_CLR 0x303C #define B_AX_BG_CLR_ASYNC_M3 BIT(4) +#define R_AX_PCIE_LAT_CTRL 0x3044 +#define B_AX_CLK_REQ_SEL_OPT BIT(1) +#define B_AX_CLK_REQ_SEL BIT(0) + #define R_AX_PCIE_IO_RCY_M1 0x3100 #define B_AX_PCIE_IO_RCY_P_M1 BIT(5) #define B_AX_PCIE_IO_RCY_WDT_P_M1 BIT(4) @@ -531,6 +538,11 @@ #define RTW89_PCIE_GEN2_SPEED 0x02 #define RTW89_PCIE_PHY_RATE 0x82 #define RTW89_PCIE_PHY_RATE_MASK GENMASK(1, 0) +#define RTW89_PCIE_L1SS_STS_V1 0x0168 +#define RTW89_PCIE_BIT_ASPM_L11 BIT(3) +#define RTW89_PCIE_BIT_ASPM_L12 BIT(2) +#define RTW89_PCIE_BIT_PCI_L11 BIT(1) +#define RTW89_PCIE_BIT_PCI_L12 BIT(0) #define RTW89_PCIE_ASPM_CTRL 0x070F #define RTW89_L1DLY_MASK GENMASK(5, 3) #define RTW89_L0DLY_MASK GENMASK(2, 0)