mt76: update to the latest version
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 653-0048-rtl8xxxu-Implement-rtl8188eu_power_off.patch
1 From 34e65b6f310234cf3e3629bd3d896a4f84df71f4 Mon Sep 17 00:00:00 2001
2 From: Jes Sorensen <Jes.Sorensen@redhat.com>
3 Date: Fri, 26 Aug 2016 16:09:00 -0400
4 Subject: [PATCH] rtl8xxxu: Implement rtl8188eu_power_off()
5
6 This makes the driver match the poweroff sequence of the vendor driver
7 and allows the firmware to reload correctly upon rmmod/insmod.
8 However the device still doesn't receive data upon reloading.
9
10 Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
11 ---
12  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c | 136 ++++++++++++++++++++-
13  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h  |   2 +
14  2 files changed, 137 insertions(+), 1 deletion(-)
15
16 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
17 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
18 @@ -1191,6 +1191,71 @@ exit:
19         return ret;
20  }
21  
22 +static int rtl8188eu_emu_to_disabled(struct rtl8xxxu_priv *priv)
23 +{
24 +       u8 val8;
25 +
26 +       /* 0x04[12:11] = 01 enable WL suspend */
27 +       val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 2);
28 +       val8 &= ~BIT(0);
29 +       rtl8xxxu_write8(priv, REG_APS_FSMCO + 2, val8);
30 +
31 +       val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
32 +       val8 |= BIT(7);
33 +       rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
34 +
35 +       return 0;
36 +}
37 +
38 +static int rtl8188eu_active_to_lps(struct rtl8xxxu_priv *priv)
39 +{
40 +       struct device *dev = &priv->udev->dev;
41 +       u8 val8;
42 +       u16 val16;
43 +       u32 val32;
44 +       int retry, retval;
45 +
46 +       rtl8xxxu_write8(priv, REG_TXPAUSE, 0x7f);
47 +
48 +       retry = 100;
49 +       retval = -EBUSY;
50 +       /*
51 +        * Poll 32 bit wide 0x05f8 for 0x00000000 to ensure no TX is pending.
52 +        */
53 +       do {
54 +               val32 = rtl8xxxu_read32(priv, 0x05f8);
55 +               if (!val32) {
56 +                       retval = 0;
57 +                       break;
58 +               }
59 +       } while (retry--);
60 +
61 +       if (!retry) {
62 +               dev_warn(dev, "Failed to flush TX queue\n");
63 +               retval = -EBUSY;
64 +               goto out;
65 +       }
66 +
67 +       /* Disable CCK and OFDM, clock gated */
68 +       val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
69 +       val8 &= ~SYS_FUNC_BBRSTB;
70 +       rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
71 +
72 +       udelay(2);
73 +
74 +       /* Reset MAC TRX */
75 +       val16 = rtl8xxxu_read16(priv, REG_CR);
76 +       val16 &= ~(CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | CR_SECURITY_ENABLE);
77 +       rtl8xxxu_write16(priv, REG_CR, val16);
78 +
79 +       val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST);
80 +       val8 |= DUAL_TSF_TX_OK;
81 +       rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8);
82 +
83 +out:
84 +       return retval;
85 +}
86 +
87  static int rtl8188eu_power_on(struct rtl8xxxu_priv *priv)
88  {
89         u16 val16;
90 @@ -1221,6 +1286,75 @@ exit:
91         return ret;
92  }
93  
94 +void rtl8188eu_power_off(struct rtl8xxxu_priv *priv)
95 +{
96 +       u8 val8;
97 +       u16 val16;
98 +
99 +       rtl8xxxu_flush_fifo(priv);
100 +
101 +       val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL);
102 +       val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE;
103 +       rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8);
104 +
105 +       /* Turn off RF */
106 +       rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
107 +
108 +       rtl8188eu_active_to_lps(priv);
109 +
110 +       /* Reset Firmware if running in RAM */
111 +       if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
112 +               rtl8xxxu_firmware_self_reset(priv);
113 +
114 +       /* Reset MCU */
115 +       val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
116 +       val16 &= ~SYS_FUNC_CPU_ENABLE;
117 +       rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
118 +
119 +       /* Reset MCU ready status */
120 +       rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
121 +
122 +       /* 32K_CTRL looks to be very 8188e specific */
123 +       val8 = rtl8xxxu_read8(priv, REG_32K_CTRL);
124 +       val8 &= ~BIT(0);
125 +       rtl8xxxu_write8(priv, REG_32K_CTRL, val8);
126 +
127 +       rtl8188eu_active_to_emu(priv);
128 +       rtl8188eu_emu_to_disabled(priv);
129 +
130 +       /* Reset MCU IO Wrapper */
131 +       val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
132 +       val8 &= ~BIT(3);
133 +       rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
134 +
135 +       val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
136 +       val8 |= BIT(3);
137 +       rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
138 +
139 +       /* Vendor driver refers to GPIO_IN */
140 +       val8 = rtl8xxxu_read8(priv, REG_GPIO_PIN_CTRL);
141 +       /* Vendor driver refers to GPIO_OUT */
142 +       rtl8xxxu_write8(priv, REG_GPIO_PIN_CTRL + 1, val8);
143 +       rtl8xxxu_write8(priv, REG_GPIO_PIN_CTRL + 2, 0xff);
144 +
145 +       val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL);
146 +       rtl8xxxu_write8(priv, REG_GPIO_IO_SEL + 1, val8 << 4);
147 +       val8 = rtl8xxxu_read8(priv, REG_GPIO_IO_SEL + 1);
148 +       rtl8xxxu_write8(priv, REG_GPIO_IO_SEL + 1, val8 | 0x0f);
149 +
150 +       /*
151 +        * Set LNA, TRSW, EX_PA Pin to output mode
152 +        * Referred to as REG_BB_PAD_CTRL in 8188eu vendor driver
153 +        */
154 +       rtl8xxxu_write32(priv, REG_PAD_CTRL1, 0x00080808);
155 +
156 +       rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x00);
157 +
158 +       val16 = rtl8xxxu_read16(priv, REG_APS_FSMCO);
159 +       val16 |= APS_FSMCO_ENABLE_POWERDOWN | APS_FSMCO_HW_POWERDOWN;
160 +       rtl8xxxu_write16(priv, REG_APS_FSMCO, val16);
161 +}
162 +
163  static void rtl8188e_enable_rf(struct rtl8xxxu_priv *priv)
164  {
165         rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
166 @@ -1265,7 +1399,7 @@ struct rtl8xxxu_fileops rtl8188eu_fops =
167         .parse_efuse = rtl8188eu_parse_efuse,
168         .load_firmware = rtl8188eu_load_firmware,
169         .power_on = rtl8188eu_power_on,
170 -       .power_off = rtl8xxxu_power_off,
171 +       .power_off = rtl8188eu_power_off,
172         .reset_8051 = rtl8188eu_reset_8051,
173         .llt_init = rtl8xxxu_init_llt_table,
174         .init_phy_bb = rtl8188eu_init_phy_bb,
175 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
176 +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
177 @@ -418,6 +418,8 @@
178  #define REG_MBIST_START                        0x0174
179  #define REG_MBIST_DONE                 0x0178
180  #define REG_MBIST_FAIL                 0x017c
181 +/* 8188EU */
182 +#define REG_32K_CTRL                   0x0194
183  #define REG_C2HEVT_MSG_NORMAL          0x01a0
184  /* 8192EU/8723BU/8812 */
185  #define REG_C2HEVT_CMD_ID_8723B                0x01ae