gl_rst.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. ** Id: @(#) gl_rst.c@@
  3. */
  4. /*! \file gl_rst.c
  5. \brief Main routines for supporintg MT6620 whole-chip reset mechanism
  6. This file contains the support routines of Linux driver for MediaTek Inc. 802.11
  7. Wireless LAN Adapters.
  8. */
  9. /*
  10. ** Log: gl_rst.c
  11. **
  12. ** 09 17 2012 cm.chang
  13. ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
  14. ** Duplicate source from MT6620 v2.3 driver branch
  15. ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
  16. *
  17. * 11 10 2011 cp.wu
  18. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  19. * 1. eliminaite direct calls to printk in porting layer.
  20. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  21. *
  22. * 04 22 2011 cp.wu
  23. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
  24. * RESET_START and RESET_END events
  25. * skip power-off handshaking when RESET indication is received.
  26. *
  27. * 04 14 2011 cp.wu
  28. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
  29. * RESET_START and RESET_END events
  30. * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
  31. * 2. add dummy function for both Win32 and Linux part.
  32. *
  33. * 03 30 2011 cp.wu
  34. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for
  35. * RESET_START and RESET_END events
  36. * use netlink unicast instead of broadcast
  37. *
  38. **
  39. */
  40. /*******************************************************************************
  41. * C O M P I L E R F L A G S
  42. ********************************************************************************
  43. */
  44. /*******************************************************************************
  45. * E X T E R N A L R E F E R E N C E S
  46. ********************************************************************************
  47. */
  48. #include <linux/kernel.h>
  49. #include <linux/workqueue.h>
  50. #include "precomp.h"
  51. #include "gl_rst.h"
  52. #if CFG_CHIP_RESET_SUPPORT
  53. /*******************************************************************************
  54. * C O N S T A N T S
  55. ********************************************************************************
  56. */
  57. /*******************************************************************************
  58. * P U B L I C D A T A
  59. ********************************************************************************
  60. */
  61. BOOLEAN fgIsResetting = FALSE;
  62. /*******************************************************************************
  63. * P R I V A T E D A T A
  64. ********************************************************************************
  65. */
  66. static RESET_STRUCT_T wifi_rst;
  67. static void mtk_wifi_reset(struct work_struct *work);
  68. /*******************************************************************************
  69. * F U N C T I O N D E C L A R A T I O N S
  70. ********************************************************************************
  71. */
  72. static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType,
  73. ENUM_WMTDRV_TYPE_T eDstType,
  74. ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength);
  75. /*******************************************************************************
  76. * F U N C T I O N S
  77. ********************************************************************************
  78. */
  79. /*----------------------------------------------------------------------------*/
  80. /*!
  81. * @brief This routine is responsible for
  82. * 1. register wifi reset callback
  83. * 2. initialize wifi reset work
  84. *
  85. * @param none
  86. *
  87. * @retval none
  88. */
  89. /*----------------------------------------------------------------------------*/
  90. VOID glResetInit(VOID)
  91. {
  92. /* 1. Register reset callback */
  93. mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback);
  94. /* 2. Initialize reset work */
  95. INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset);
  96. }
  97. /*----------------------------------------------------------------------------*/
  98. /*!
  99. * @brief This routine is responsible for
  100. * 1. deregister wifi reset callback
  101. *
  102. * @param none
  103. *
  104. * @retval none
  105. */
  106. /*----------------------------------------------------------------------------*/
  107. VOID glResetUninit(VOID)
  108. {
  109. /* 1. Deregister reset callback */
  110. mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
  111. }
  112. /*----------------------------------------------------------------------------*/
  113. /*!
  114. * @brief This routine is invoked when there is reset messages indicated
  115. *
  116. * @param eSrcType
  117. * eDstType
  118. * eMsgType
  119. * prMsgBody
  120. * u4MsgLength
  121. *
  122. * @retval
  123. */
  124. /*----------------------------------------------------------------------------*/
  125. static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType,
  126. ENUM_WMTDRV_TYPE_T eDstType,
  127. ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength)
  128. {
  129. switch (eMsgType) {
  130. case WMTMSG_TYPE_RESET:
  131. if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
  132. P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
  133. switch (*prRstMsg) {
  134. case WMTRSTMSG_RESET_START:
  135. DBGLOG(INIT, WARN, "Whole chip reset start!\n");
  136. fgIsResetting = TRUE;
  137. wifi_reset_start();
  138. break;
  139. case WMTRSTMSG_RESET_END:
  140. DBGLOG(INIT, WARN, "Whole chip reset end!\n");
  141. fgIsResetting = FALSE;
  142. wifi_rst.rst_data = RESET_SUCCESS;
  143. schedule_work(&(wifi_rst.rst_work));
  144. break;
  145. case WMTRSTMSG_RESET_END_FAIL:
  146. DBGLOG(INIT, WARN, "Whole chip reset fail!\n");
  147. fgIsResetting = FALSE;
  148. wifi_rst.rst_data = RESET_FAIL;
  149. schedule_work(&(wifi_rst.rst_work));
  150. break;
  151. default:
  152. break;
  153. }
  154. }
  155. break;
  156. default:
  157. break;
  158. }
  159. return NULL;
  160. }
  161. /*----------------------------------------------------------------------------*/
  162. /*!
  163. * @brief This routine is called for wifi reset
  164. *
  165. * @param skb
  166. * info
  167. *
  168. * @retval 0
  169. * nonzero
  170. */
  171. /*----------------------------------------------------------------------------*/
  172. static void mtk_wifi_reset(struct work_struct *work)
  173. {
  174. RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work);
  175. wifi_reset_end(rst->rst_data);
  176. }
  177. /*----------------------------------------------------------------------------*/
  178. /*!
  179. * @brief This routine is called for generating reset request to WMT
  180. *
  181. * @param None
  182. *
  183. * @retval None
  184. */
  185. /*----------------------------------------------------------------------------*/
  186. VOID glSendResetRequest(VOID)
  187. {
  188. /* WMT thread would trigger whole chip reset itself */
  189. }
  190. /*----------------------------------------------------------------------------*/
  191. /*!
  192. * @brief This routine is called for checking if connectivity chip is resetting
  193. *
  194. * @param None
  195. *
  196. * @retval TRUE
  197. * FALSE
  198. */
  199. /*----------------------------------------------------------------------------*/
  200. BOOLEAN kalIsResetting(VOID)
  201. {
  202. return fgIsResetting;
  203. }
  204. BOOLEAN glResetTrigger(P_ADAPTER_T prAdapter)
  205. {
  206. BOOLEAN fgResult = TRUE;
  207. #if CFG_WMT_RESET_API_SUPPORT
  208. if (kalIsResetting()) {
  209. DBGLOG(INIT, ERROR,
  210. "Skip triggering whole-chip reset during resetting! Chip[%04X E%u]\n",
  211. MTK_CHIP_REV,
  212. wlanGetEcoVersion(prAdapter));
  213. DBGLOG(INIT, ERROR,
  214. "FW Ver DEC[%u.%u] HEX[%x.%x], Driver Ver[%u.%u]\n",
  215. (prAdapter->rVerInfo.u2FwOwnVersion >> 8),
  216. (prAdapter->rVerInfo.u2FwOwnVersion & BITS(0, 7)),
  217. (prAdapter->rVerInfo.u2FwOwnVersion >> 8),
  218. (prAdapter->rVerInfo.u2FwOwnVersion & BITS(0, 7)),
  219. (prAdapter->rVerInfo.u2FwPeerVersion >> 8),
  220. (prAdapter->rVerInfo.u2FwPeerVersion & BITS(0, 7)));
  221. fgResult = TRUE;
  222. } else {
  223. DBGLOG(INIT, ERROR,
  224. "Trigger whole-chip reset! Chip[%04X E%u] FW Ver DEC[%u.%u] HEX[%x.%x], Driver Ver[%u.%u]\n",
  225. MTK_CHIP_REV,
  226. wlanGetEcoVersion(prAdapter),
  227. (prAdapter->rVerInfo.u2FwOwnVersion >> 8),
  228. (prAdapter->rVerInfo.u2FwOwnVersion & BITS(0, 7)),
  229. (prAdapter->rVerInfo.u2FwOwnVersion >> 8),
  230. (prAdapter->rVerInfo.u2FwOwnVersion & BITS(0, 7)),
  231. (prAdapter->rVerInfo.u2FwPeerVersion >> 8),
  232. (prAdapter->rVerInfo.u2FwPeerVersion & BITS(0, 7)));
  233. fgResult = mtk_wcn_wmt_do_reset(WMTDRV_TYPE_WIFI);
  234. }
  235. #endif
  236. return fgResult;
  237. }
  238. #endif /* CFG_CHIP_RESET_SUPPORT */