aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/realtek/rtw88/mac.c
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2020-04-22 11:46:02 +0800
committerKalle Valo <kvalo@codeaurora.org>2020-04-23 07:47:21 +0300
commit4e223a5f5342fab01ccebf87714401f559dcc791 (patch)
tree4e23b9b12db028fcfcac0c3f78c5c27b6000305a /drivers/net/wireless/realtek/rtw88/mac.c
parentrtw88: no need to send additional information to legacy firmware (diff)
downloadlinux-4e223a5f5342fab01ccebf87714401f559dcc791.tar.xz
linux-4e223a5f5342fab01ccebf87714401f559dcc791.zip
rtw88: 8723d: Add mac power-on/-off function
The mac power-on flow consists of three steps: 1. pre_sys_cfg (Before switching power state) 2. power_switch (Switching power state) 3. init_sys_cfg (Settings after swtiching power state) When switching power state, driver will load and parse the power sequence tables. For 8723D devices, the logics for parsing are most same except for the polling function. 8723D devices need to toggle BIT_PFM_WOWL twice. The settings after power state is switched for 8723D devices are quite different with other devices, extract a legacy function for them. For power-off flow, 8723D devices have the same logic with existing chips. But warning printed if we run power-off sequence in power-off state: rtw_pci 0000:03:00.0: failed to poll offset=0x5f8 mask=0xff value=0x0 The scenario is user do 'ifconfig up' that will run power-on sequence to bring up and then run power-off sequence to enter idle (IEEE80211_CONF_IDLE). Then, user do 'ifconfig down' that will run power-off sequence again, and the warning is shown. Original code check power-on state to avoid to run power-on sequence twice, and this commit extends to check both power-on and power-off states. Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20200422034607.28747-4-yhchuang@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/mac.c')
-rw-r--r--drivers/net/wireless/realtek/rtw88/mac.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c
index 6092604abfb9..21b5c7173f0f 100644
--- a/drivers/net/wireless/realtek/rtw88/mac.c
+++ b/drivers/net/wireless/realtek/rtw88/mac.c
@@ -61,6 +61,14 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
rtw_write8(rtwdev, REG_RSV_CTRL, 0);
+ if (rtw_chip_wcpu_11n(rtwdev)) {
+ if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO)
+ rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL);
+ else
+ rtw_write8(rtwdev, REG_LDO_SWR_CTRL, SPS_SEL);
+ return 0;
+ }
+
switch (rtw_hci_type(rtwdev)) {
case RTW_HCI_TYPE_PCIE:
rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
@@ -123,10 +131,19 @@ static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
flag == 0) {
value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
- value |= BIT(3);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
+ value &= ~BIT_PFM_WOWL;
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+ }
+ value |= BIT_PFM_WOWL;
rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
- value &= ~BIT(3);
+ value &= ~BIT_PFM_WOWL;
rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
+ value |= BIT_PFM_WOWL;
+ rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+ }
+
cnt = RTW_PWR_POLLING_CNT;
flag = 1;
} else {
@@ -228,12 +245,14 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
u8 rpwm;
bool cur_pwr;
- rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
+ if (rtw_chip_wcpu_11ac(rtwdev)) {
+ rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
- /* Check FW still exist or not */
- if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) {
- rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE;
- rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm);
+ /* Check FW still exist or not */
+ if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) {
+ rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE;
+ rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm);
+ }
}
if (rtw_read8(rtwdev, REG_CR) == 0xea)
@@ -244,7 +263,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
else
cur_pwr = true;
- if (pwr_on && cur_pwr)
+ if (pwr_on == cur_pwr)
return -EALREADY;
pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq;
@@ -254,7 +273,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
return 0;
}
-static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
+static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
{
u8 sys_func_en = rtwdev->chip->sys_func_en;
u8 value8;
@@ -279,6 +298,29 @@ static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
return 0;
}
+static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev)
+{
+ rtw_write8(rtwdev, REG_CR, 0xff);
+ mdelay(2);
+ rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0x7f);
+ mdelay(2);
+
+ rtw_write8_set(rtwdev, REG_SYS_CLKR, BIT_WAKEPAD_EN);
+ rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC);
+
+ rtw_write16(rtwdev, REG_CR, 0x2ff);
+
+ return 0;
+}
+
+static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
+{
+ if (rtw_chip_wcpu_11n(rtwdev))
+ return __rtw_mac_init_system_cfg_legacy(rtwdev);
+
+ return __rtw_mac_init_system_cfg(rtwdev);
+}
+
int rtw_mac_power_on(struct rtw_dev *rtwdev)
{
int ret = 0;