653-0048-rtl8xxxu-Implement-rtl8188eu_power_off.patch 5.2 KB

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