mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
wifi: rtl8xxxu: Use correct power off sequence for RTL8192CU
RTL8192CU disappears and reappears when rtl8xxxu is unloaded: usbcore: deregistering interface driver rtl8xxxu wlp3s0f3u2: deauthenticating from ... by local choice (Reason: 3=DEAUTH_LEAVING) usb 1-2: rtl8xxxu_active_to_emu: Disabling MAC timed out usb 1-2: USB disconnect, device number 7 usb 1-2: disconnecting usb 1-2: new high-speed USB device number 8 using xhci_hcd usb 1-2: New USB device found, idVendor=0bda, idProduct=8178, bcdDevice= 2.00 usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-2: Product: 802.11n WLAN Adapter usb 1-2: Manufacturer: Realtek usb 1-2: SerialNumber: 00e04c000001 This is because rtl8xxxu is using the power off sequence for RTL8723AU. Add the correct power off sequence for RTL8192CU. rtl8xxxu_power_off(), rtl8xxxu_active_to_emu(), and rtl8xxxu_emu_to_disabled() are now only used for RTL8723AU, so move them to 8723a.c and rename them to have the "rtl8723au" prefix. Tested only with RTL8192CU. Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/b9d3f137-12ce-4bd9-8ada-3b8874bc3615@gmail.com
This commit is contained in:
parent
fb5183aa65
commit
9b567039e5
|
|
@ -593,6 +593,84 @@ static int rtl8192cu_power_on(struct rtl8xxxu_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void rtl8192cu_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u32 val32;
|
||||
u16 val16;
|
||||
u8 val8;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Workaround for 8188RU LNA power leakage problem.
|
||||
*/
|
||||
if (priv->rtl_chip == RTL8188R) {
|
||||
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
|
||||
val32 |= BIT(1);
|
||||
rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
|
||||
}
|
||||
|
||||
/* _DisableRFAFEAndResetBB */
|
||||
rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
|
||||
rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, 0xff, 0);
|
||||
|
||||
rtl8xxxu_write8_set(priv, REG_APSD_CTRL, APSD_CTRL_OFF);
|
||||
rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, FPGA0_RF_PARM_CLK_GATE);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC,
|
||||
SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_BB_GLB_RSTN);
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC, SYS_FUNC_USBA | SYS_FUNC_USBD);
|
||||
|
||||
/* _ResetDigitalProcedure1 */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_DL_READY) {
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_FWIMR, 0x20);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
if (!(val16 & SYS_FUNC_CPU_ENABLE))
|
||||
break;
|
||||
|
||||
fsleep(50);
|
||||
}
|
||||
|
||||
if (i == 100) {
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC + 1,
|
||||
(SYS_FUNC_HWPDN | SYS_FUNC_ELDR) >> 8);
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
val8 = (SYS_FUNC_HWPDN | SYS_FUNC_ELDR | SYS_FUNC_CPU_ENABLE) >> 8;
|
||||
rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8);
|
||||
|
||||
/* _DisableGPIO */
|
||||
rtl8xxxu_write16(priv, REG_GPIO_PIN_CTRL + 2, 0);
|
||||
val32 = rtl8xxxu_read32(priv, REG_GPIO_PIN_CTRL) & 0xffff00ff;
|
||||
val32 |= (val32 & 0xff) << 8;
|
||||
val32 |= 0x00ff0000;
|
||||
rtl8xxxu_write32(priv, REG_GPIO_PIN_CTRL, val32);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_GPIO_MUXCFG + 3, 0);
|
||||
val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG + 2) & 0xff0f;
|
||||
val16 |= (val16 & 0xf) << 4;
|
||||
val16 |= 0x0780;
|
||||
rtl8xxxu_write16(priv, REG_GPIO_MUXCFG + 2, val16);
|
||||
|
||||
/* _DisableAnalog */
|
||||
val8 = 0x23;
|
||||
if (priv->vendor_umc && priv->chip_cut == 1)
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8);
|
||||
|
||||
val16 = APS_FSMCO_HOST | APS_FSMCO_HW_SUSPEND | APS_FSMCO_PFM_ALDN;
|
||||
rtl8xxxu_write16(priv, REG_APS_FSMCO, val16);
|
||||
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
static int rtl8192cu_led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
|
|
@ -618,7 +696,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
|
|||
.parse_efuse = rtl8192cu_parse_efuse,
|
||||
.load_firmware = rtl8192cu_load_firmware,
|
||||
.power_on = rtl8192cu_power_on,
|
||||
.power_off = rtl8xxxu_power_off,
|
||||
.power_off = rtl8192cu_power_off,
|
||||
.read_efuse = rtl8xxxu_read_efuse,
|
||||
.reset_8051 = rtl8xxxu_reset_8051,
|
||||
.llt_init = rtl8xxxu_init_llt_table,
|
||||
|
|
|
|||
|
|
@ -411,6 +411,119 @@ static int rtl8723au_power_on(struct rtl8xxxu_priv *priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl8723au_active_to_emu(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
int count, ret = 0;
|
||||
|
||||
/* Start of rtl8723AU_card_enable_flow */
|
||||
/* Act to Cardemu sequence*/
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
|
||||
|
||||
/* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */
|
||||
val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
val8 &= ~LEDCFG2_DPDT_SELECT;
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
|
||||
|
||||
/* 0x0005[1] = 1 turn off MAC by HW state machine*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(1);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
if ((val8 & BIT(1)) == 0)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 0x0000[5] = 1 analog Ips to digital, 1:isolation */
|
||||
val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
|
||||
val8 |= SYS_ISO_ANALOG_IPS;
|
||||
rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
|
||||
|
||||
/* 0x0020[0] = 0 disable LDOA12 MACRO block*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
|
||||
val8 &= ~LDOA15_ENABLE;
|
||||
rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl8723au_emu_to_disabled(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
|
||||
/* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20);
|
||||
|
||||
/* 0x04[12:11] = 01 enable WL suspend */
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 &= ~BIT(4);
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(7);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
/* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */
|
||||
val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtl8723au_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
|
||||
rtl8xxxu_flush_fifo(priv);
|
||||
|
||||
rtl8xxxu_active_to_lps(priv);
|
||||
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
|
||||
|
||||
/* Reset Firmware if running in RAM */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
|
||||
rtl8xxxu_firmware_self_reset(priv);
|
||||
|
||||
/* Reset MCU */
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
val16 &= ~SYS_FUNC_CPU_ENABLE;
|
||||
rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
|
||||
|
||||
/* Reset MCU ready status */
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8723au_active_to_emu(priv);
|
||||
rtl8723au_emu_to_disabled(priv);
|
||||
|
||||
/* Reset MCU IO Wrapper */
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 &= ~BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
/* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
#define XTAL1 GENMASK(23, 18)
|
||||
#define XTAL0 GENMASK(17, 12)
|
||||
|
||||
|
|
@ -492,7 +605,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = {
|
|||
.parse_efuse = rtl8723au_parse_efuse,
|
||||
.load_firmware = rtl8723au_load_firmware,
|
||||
.power_on = rtl8723au_power_on,
|
||||
.power_off = rtl8xxxu_power_off,
|
||||
.power_off = rtl8723au_power_off,
|
||||
.read_efuse = rtl8xxxu_read_efuse,
|
||||
.reset_8051 = rtl8xxxu_reset_8051,
|
||||
.llt_init = rtl8xxxu_init_llt_table,
|
||||
|
|
|
|||
|
|
@ -3637,54 +3637,6 @@ static void rtl8xxxu_set_ampdu_min_space(struct rtl8xxxu_priv *priv, u8 density)
|
|||
rtl8xxxu_write8(priv, REG_AMPDU_MIN_SPACE, val8);
|
||||
}
|
||||
|
||||
static int rtl8xxxu_active_to_emu(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
int count, ret = 0;
|
||||
|
||||
/* Start of rtl8723AU_card_enable_flow */
|
||||
/* Act to Cardemu sequence*/
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
|
||||
|
||||
/* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */
|
||||
val8 = rtl8xxxu_read8(priv, REG_LEDCFG2);
|
||||
val8 &= ~LEDCFG2_DPDT_SELECT;
|
||||
rtl8xxxu_write8(priv, REG_LEDCFG2, val8);
|
||||
|
||||
/* 0x0005[1] = 1 turn off MAC by HW state machine*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(1);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
if ((val8 & BIT(1)) == 0)
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n",
|
||||
__func__);
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 0x0000[5] = 1 analog Ips to digital, 1:isolation */
|
||||
val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL);
|
||||
val8 |= SYS_ISO_ANALOG_IPS;
|
||||
rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8);
|
||||
|
||||
/* 0x0020[0] = 0 disable LDOA12 MACRO block*/
|
||||
val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL);
|
||||
val8 &= ~LDOA15_ENABLE;
|
||||
rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
|
|
@ -3761,31 +3713,6 @@ void rtl8xxxu_disabled_to_emu(struct rtl8xxxu_priv *priv)
|
|||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
}
|
||||
|
||||
static int rtl8xxxu_emu_to_disabled(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
|
||||
/* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20);
|
||||
|
||||
/* 0x04[12:11] = 01 enable WL suspend */
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 &= ~BIT(4);
|
||||
val8 |= BIT(3);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
|
||||
val8 |= BIT(7);
|
||||
rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
|
||||
|
||||
/* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */
|
||||
val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
struct device *dev = &priv->udev->dev;
|
||||
|
|
@ -3863,56 +3790,6 @@ void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv)
|
|||
rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32);
|
||||
}
|
||||
|
||||
void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv)
|
||||
{
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
|
||||
/*
|
||||
* Workaround for 8188RU LNA power leakage problem.
|
||||
*/
|
||||
if (priv->rtl_chip == RTL8188R) {
|
||||
val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM);
|
||||
val32 |= BIT(1);
|
||||
rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32);
|
||||
}
|
||||
|
||||
rtl8xxxu_flush_fifo(priv);
|
||||
|
||||
rtl8xxxu_active_to_lps(priv);
|
||||
|
||||
/* Turn off RF */
|
||||
rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
|
||||
|
||||
/* Reset Firmware if running in RAM */
|
||||
if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
|
||||
rtl8xxxu_firmware_self_reset(priv);
|
||||
|
||||
/* Reset MCU */
|
||||
val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
|
||||
val16 &= ~SYS_FUNC_CPU_ENABLE;
|
||||
rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
|
||||
|
||||
/* Reset MCU ready status */
|
||||
rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
|
||||
|
||||
rtl8xxxu_active_to_emu(priv);
|
||||
rtl8xxxu_emu_to_disabled(priv);
|
||||
|
||||
/* Reset MCU IO Wrapper */
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 &= ~BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
|
||||
val8 |= BIT(0);
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
|
||||
|
||||
/* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */
|
||||
rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e);
|
||||
}
|
||||
|
||||
void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
|
||||
u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#define APS_FSMCO_SW_LPS BIT(10)
|
||||
#define APS_FSMCO_HW_SUSPEND BIT(11)
|
||||
#define APS_FSMCO_PCIE BIT(12)
|
||||
#define APS_FSMCO_HOST BIT(14)
|
||||
#define APS_FSMCO_HW_POWERDOWN BIT(15)
|
||||
#define APS_FSMCO_WLON_RESET BIT(16)
|
||||
|
||||
|
|
|
|||
|
|
@ -2078,7 +2078,6 @@ int rtl8xxxu_init_phy_regs(struct rtl8xxxu_priv *priv,
|
|||
const struct rtl8xxxu_reg32val *array);
|
||||
int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name);
|
||||
void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv);
|
||||
void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv);
|
||||
void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor);
|
||||
void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor);
|
||||
void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user