PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/net/wireless/mt5931/os/linux/gl_rst.c

https://gitlab.com/rychly/rk3026-linux-sources
C | 473 lines | 229 code | 71 blank | 173 comment | 25 complexity | 4c7046eca538d706ff0ac01767bcf873 MD5 | raw file
  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. * 11 10 2011 cp.wu
  13. * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
  14. * 1. eliminaite direct calls to printk in porting layer.
  15. * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
  16. *
  17. * 04 22 2011 cp.wu
  18. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
  19. * skip power-off handshaking when RESET indication is received.
  20. *
  21. * 04 14 2011 cp.wu
  22. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
  23. * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
  24. * 2. add dummy function for both Win32 and Linux part.
  25. *
  26. * 03 30 2011 cp.wu
  27. * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
  28. * use netlink unicast instead of broadcast
  29. *
  30. **
  31. */
  32. /*******************************************************************************
  33. * C O M P I L E R F L A G S
  34. ********************************************************************************
  35. */
  36. /*******************************************************************************
  37. * E X T E R N A L R E F E R E N C E S
  38. ********************************************************************************
  39. */
  40. #include "gl_os.h"
  41. #include "debug.h"
  42. #include "wlan_lib.h"
  43. #include "gl_wext.h"
  44. #include "precomp.h"
  45. #include <linux/poll.h>
  46. #include <net/netlink.h>
  47. #include <net/genetlink.h>
  48. #if CFG_CHIP_RESET_SUPPORT
  49. /*******************************************************************************
  50. * C O N S T A N T S
  51. ********************************************************************************
  52. */
  53. #define MAX_BIND_PROCESS (4)
  54. #define MTK_WIFI_FAMILY_NAME "MTK_WIFI"
  55. #define MTK_WIFI_RESET_START_NAME "RESET_START"
  56. #define MTK_WIFI_RESET_END_NAME "RESET_END"
  57. #define MTK_WIFI_RESET_TEST_NAME "GENETLINK_START"
  58. /*******************************************************************************
  59. * D A T A T Y P E S
  60. ********************************************************************************
  61. */
  62. enum {
  63. __MTK_WIFI_ATTR_INVALID,
  64. MTK_WIFI_ATTR_MSG,
  65. __MTK_WIFI_ATTR_MAX,
  66. };
  67. #define MTK_WIFI_ATTR_MAX (__MTK_WIFI_ATTR_MAX - 1)
  68. enum {
  69. __MTK_WIFI_COMMAND_INVALID,
  70. MTK_WIFI_COMMAND_BIND,
  71. MTK_WIFI_COMMAND_RESET,
  72. __MTK_WIFI_COMMAND_MAX,
  73. };
  74. #define MTK_WIFI_COMMAND_MAX (__MTK_WIFI_COMMAND_MAX - 1)
  75. /*******************************************************************************
  76. * P U B L I C D A T A
  77. ********************************************************************************
  78. */
  79. /*******************************************************************************
  80. * P R I V A T E D A T A
  81. ********************************************************************************
  82. */
  83. static UINT_32 mtk_wifi_seqnum = 0;
  84. static int num_bind_process = 0;
  85. static pid_t bind_pid[MAX_BIND_PROCESS];
  86. static BOOLEAN fgIsResetting = FALSE;
  87. /* attribute policy */
  88. static struct nla_policy mtk_wifi_genl_policy[MTK_WIFI_ATTR_MAX + 1] = {
  89. [MTK_WIFI_ATTR_MSG] = { .type = NLA_NUL_STRING },
  90. };
  91. /* family definition */
  92. static struct genl_family mtk_wifi_gnl_family = {
  93. .id = GENL_ID_GENERATE,
  94. .hdrsize = 0,
  95. .name = MTK_WIFI_FAMILY_NAME,
  96. .version = 1,
  97. .maxattr = MTK_WIFI_ATTR_MAX,
  98. };
  99. /* forward declaration */
  100. static int mtk_wifi_bind(
  101. struct sk_buff *skb,
  102. struct genl_info *info
  103. );
  104. static int mtk_wifi_reset(
  105. struct sk_buff *skb,
  106. struct genl_info *info
  107. );
  108. /* operation definition */
  109. static struct genl_ops mtk_wifi_gnl_ops_bind = {
  110. .cmd = MTK_WIFI_COMMAND_BIND,
  111. .flags = 0,
  112. .policy = mtk_wifi_genl_policy,
  113. .doit = mtk_wifi_bind,
  114. .dumpit = NULL,
  115. };
  116. static struct genl_ops mtk_wifi_gnl_ops_reset = {
  117. .cmd = MTK_WIFI_COMMAND_RESET,
  118. .flags = 0,
  119. .policy = mtk_wifi_genl_policy,
  120. .doit = mtk_wifi_reset,
  121. .dumpit = NULL,
  122. };
  123. /*******************************************************************************
  124. * M A C R O S
  125. ********************************************************************************
  126. */
  127. /*******************************************************************************
  128. * F U N C T I O N D E C L A R A T I O N S
  129. ********************************************************************************
  130. */
  131. extern int
  132. mtk_wcn_wmt_msgcb_reg(
  133. ENUM_WMTDRV_TYPE_T eType,
  134. PF_WMT_CB pCb);
  135. extern int
  136. mtk_wcn_wmt_msgcb_unreg(
  137. ENUM_WMTDRV_TYPE_T eType
  138. );
  139. static void *
  140. glResetCallback (
  141. ENUM_WMTDRV_TYPE_T eSrcType,
  142. ENUM_WMTDRV_TYPE_T eDstType,
  143. ENUM_WMTMSG_TYPE_T eMsgType,
  144. void * prMsgBody,
  145. unsigned int u4MsgLength
  146. );
  147. static BOOLEAN
  148. glResetSendMessage (
  149. char *aucMsg,
  150. u8 cmd
  151. );
  152. /*******************************************************************************
  153. * F U N C T I O N S
  154. ********************************************************************************
  155. */
  156. /*----------------------------------------------------------------------------*/
  157. /*!
  158. * @brief This routine is responsible for
  159. * 1. registering for reset callbacks
  160. * 2. initialize netlink socket
  161. *
  162. * @param none
  163. *
  164. * @retval none
  165. */
  166. /*----------------------------------------------------------------------------*/
  167. VOID
  168. glResetInit(
  169. VOID
  170. )
  171. {
  172. /* 1. register for reset callback */
  173. mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB)glResetCallback);
  174. /* 2.1 registration for NETLINK_GENERIC family */
  175. if(genl_register_family(&mtk_wifi_gnl_family) != 0) {
  176. DBGLOG(INIT, WARN, ("%s(): GE_NELINK family registration fail\n", __func__));
  177. }
  178. else {
  179. /* 2.2 operation registration */
  180. if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_bind) != 0) {
  181. DBGLOG(INIT, WARN, ("%s(): BIND operation registration fail\n", __func__));
  182. }
  183. if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_reset) != 0) {
  184. DBGLOG(INIT, WARN, ("%s(): RESET operation registration fail\n", __func__));
  185. }
  186. }
  187. return;
  188. }
  189. /*----------------------------------------------------------------------------*/
  190. /*!
  191. * @brief This routine is responsible for
  192. * 1. uninitialize netlink socket
  193. * 2. deregistering for reset callbacks
  194. *
  195. * @param none
  196. *
  197. * @retval none
  198. */
  199. /*----------------------------------------------------------------------------*/
  200. VOID
  201. glResetUninit(
  202. VOID
  203. )
  204. {
  205. /* 1. release NETLINK_GENERIC family */
  206. genl_unregister_family(&mtk_wifi_gnl_family);
  207. /* 2. deregister for reset callback */
  208. mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
  209. return;
  210. }
  211. /*----------------------------------------------------------------------------*/
  212. /*!
  213. * @brief This routine is invoked when there is reset messages indicated
  214. *
  215. * @param eSrcType
  216. * eDstType
  217. * eMsgType
  218. * prMsgBody
  219. * u4MsgLength
  220. *
  221. * @retval
  222. */
  223. /*----------------------------------------------------------------------------*/
  224. static void *
  225. glResetCallback (
  226. ENUM_WMTDRV_TYPE_T eSrcType,
  227. ENUM_WMTDRV_TYPE_T eDstType,
  228. ENUM_WMTMSG_TYPE_T eMsgType,
  229. void * prMsgBody,
  230. unsigned int u4MsgLength
  231. )
  232. {
  233. switch(eMsgType) {
  234. case WMTMSG_TYPE_RESET:
  235. if(u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
  236. P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
  237. switch(*prRstMsg) {
  238. case WMTRSTMSG_RESET_START:
  239. fgIsResetting = TRUE;
  240. glResetSendMessage(MTK_WIFI_RESET_START_NAME, MTK_WIFI_COMMAND_RESET);
  241. break;
  242. case WMTRSTMSG_RESET_END:
  243. glResetSendMessage(MTK_WIFI_RESET_END_NAME, MTK_WIFI_COMMAND_RESET);
  244. fgIsResetting = FALSE;
  245. break;
  246. default:
  247. break;
  248. }
  249. }
  250. break;
  251. default:
  252. break;
  253. }
  254. return NULL;
  255. }
  256. /*----------------------------------------------------------------------------*/
  257. /*!
  258. * @brief This routine send out message via netlink socket
  259. *
  260. * @param aucMsg
  261. * u4MsgLength
  262. *
  263. * @retval TRUE
  264. * FALSE
  265. */
  266. /*----------------------------------------------------------------------------*/
  267. static BOOLEAN
  268. glResetSendMessage(
  269. char * aucMsg,
  270. u8 cmd
  271. )
  272. {
  273. struct sk_buff *skb = NULL;
  274. void *msg_head = NULL;
  275. int rc = -1;
  276. int i;
  277. if(num_bind_process == 0) {
  278. /* no listening process */
  279. return FALSE;
  280. }
  281. for(i = 0 ; i < num_bind_process ; i++) {
  282. skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  283. if(skb) {
  284. msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd);
  285. if(msg_head == NULL) {
  286. nlmsg_free(skb);
  287. return FALSE;
  288. }
  289. rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg);
  290. if(rc != 0) {
  291. nlmsg_free(skb);
  292. return FALSE;
  293. }
  294. /* finalize the message */
  295. genlmsg_end(skb, msg_head);
  296. /* sending message */
  297. rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
  298. if(rc != 0) {
  299. return FALSE;
  300. }
  301. }
  302. else {
  303. return FALSE;
  304. }
  305. }
  306. return TRUE;
  307. }
  308. /*----------------------------------------------------------------------------*/
  309. /*!
  310. * @brief This routine is called to identify PID for process binding
  311. *
  312. * @param skb
  313. * info
  314. *
  315. * @retval 0
  316. * nonzero
  317. */
  318. /*----------------------------------------------------------------------------*/
  319. int mtk_wifi_bind(
  320. struct sk_buff *skb,
  321. struct genl_info *info
  322. )
  323. {
  324. struct nlattr *na;
  325. char * mydata;
  326. if (info == NULL) {
  327. goto out;
  328. }
  329. /*for each attribute there is an index in info->attrs which points to a nlattr structure
  330. *in this structure the data is given
  331. */
  332. na = info->attrs[MTK_WIFI_ATTR_MSG];
  333. if (na) {
  334. mydata = (char *)nla_data(na);
  335. /* no need to parse mydata */
  336. }
  337. /* collect PID */
  338. if(num_bind_process < MAX_BIND_PROCESS) {
  339. bind_pid[num_bind_process] = info->snd_pid;
  340. num_bind_process++;
  341. }
  342. else {
  343. DBGLOG(INIT, WARN, ("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS));
  344. }
  345. out:
  346. return 0;
  347. }
  348. /*----------------------------------------------------------------------------*/
  349. /*!
  350. * @brief This routine is called for reset, shout not happen
  351. *
  352. * @param skb
  353. * info
  354. *
  355. * @retval 0
  356. * nonzero
  357. */
  358. /*----------------------------------------------------------------------------*/
  359. int mtk_wifi_reset(
  360. struct sk_buff *skb,
  361. struct genl_info *info
  362. )
  363. {
  364. DBGLOG(INIT, WARN, ("%s(): should not be invoked\n", __func__));
  365. return 0;
  366. }
  367. /*----------------------------------------------------------------------------*/
  368. /*!
  369. * @brief This routine is called for generating reset request to WMT
  370. *
  371. * @param None
  372. *
  373. * @retval None
  374. */
  375. /*----------------------------------------------------------------------------*/
  376. VOID
  377. glSendResetRequest(
  378. VOID
  379. )
  380. {
  381. // WMT thread would trigger whole chip resetting itself
  382. return;
  383. }
  384. /*----------------------------------------------------------------------------*/
  385. /*!
  386. * @brief This routine is called for checking if MT6620 is resetting
  387. *
  388. * @param None
  389. *
  390. * @retval TRUE
  391. * FALSE
  392. */
  393. /*----------------------------------------------------------------------------*/
  394. BOOLEAN
  395. kalIsResetting(
  396. VOID
  397. )
  398. {
  399. return fgIsResetting;
  400. }
  401. #endif // CFG_CHIP_RESET_SUPPORT