2 ** $Id: @(#) gl_rst.c@@
6 \brief Main routines for supporintg MT6620 whole-chip reset mechanism
8 This file contains the support routines of Linux driver for MediaTek Inc. 802.11
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.
23 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
24 * skip power-off handshaking when RESET indication is received.
27 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
28 * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
29 * 2. add dummy function for both Win32 and Linux part.
32 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
33 * use netlink unicast instead of broadcast
38 /*******************************************************************************
39 * C O M P I L E R F L A G S
40 ********************************************************************************
43 /*******************************************************************************
44 * E X T E R N A L R E F E R E N C E S
45 ********************************************************************************
52 #include <linux/poll.h>
53 #include <net/netlink.h>
54 #include <net/genetlink.h>
56 #if CFG_CHIP_RESET_SUPPORT
58 /*******************************************************************************
60 ********************************************************************************
62 #define MAX_BIND_PROCESS (4)
64 #define MTK_WIFI_FAMILY_NAME "MTK_WIFI"
65 #define MTK_WIFI_RESET_START_NAME "RESET_START"
66 #define MTK_WIFI_RESET_END_NAME "RESET_END"
67 #define MTK_WIFI_RESET_TEST_NAME "GENETLINK_START"
70 /*******************************************************************************
72 ********************************************************************************
75 __MTK_WIFI_ATTR_INVALID,
79 #define MTK_WIFI_ATTR_MAX (__MTK_WIFI_ATTR_MAX - 1)
83 __MTK_WIFI_COMMAND_INVALID,
84 MTK_WIFI_COMMAND_BIND,
85 MTK_WIFI_COMMAND_RESET,
86 __MTK_WIFI_COMMAND_MAX,
88 #define MTK_WIFI_COMMAND_MAX (__MTK_WIFI_COMMAND_MAX - 1)
90 /*******************************************************************************
92 ********************************************************************************
93 */BOOLEAN fgIsResetting = FALSE;
95 /*******************************************************************************
96 * P R I V A T E D A T A
97 ********************************************************************************
99 static UINT_32 mtk_wifi_seqnum = 0;
100 static int num_bind_process = 0;
101 static pid_t bind_pid[MAX_BIND_PROCESS];
104 /* attribute policy */
105 static struct nla_policy mtk_wifi_genl_policy[MTK_WIFI_ATTR_MAX + 1] = {
106 [MTK_WIFI_ATTR_MSG] = { .type = NLA_NUL_STRING },
109 /* family definition */
110 static struct genl_family mtk_wifi_gnl_family = {
111 .id = GENL_ID_GENERATE,
113 .name = MTK_WIFI_FAMILY_NAME,
115 .maxattr = MTK_WIFI_ATTR_MAX,
118 /* forward declaration */
119 static int mtk_wifi_bind(
121 struct genl_info *info
124 static int mtk_wifi_reset(
126 struct genl_info *info
129 /* operation definition */
130 static struct genl_ops mtk_wifi_gnl_ops_bind = {
131 .cmd = MTK_WIFI_COMMAND_BIND,
133 .policy = mtk_wifi_genl_policy,
134 .doit = mtk_wifi_bind,
138 static struct genl_ops mtk_wifi_gnl_ops_reset = {
139 .cmd = MTK_WIFI_COMMAND_RESET,
141 .policy = mtk_wifi_genl_policy,
142 .doit = mtk_wifi_reset,
147 /*******************************************************************************
149 ********************************************************************************
152 /*******************************************************************************
153 * F U N C T I O N D E C L A R A T I O N S
154 ********************************************************************************
157 mtk_wcn_wmt_msgcb_reg(
158 ENUM_WMTDRV_TYPE_T eType,
162 mtk_wcn_wmt_msgcb_unreg(
163 ENUM_WMTDRV_TYPE_T eType
168 ENUM_WMTDRV_TYPE_T eSrcType,
169 ENUM_WMTDRV_TYPE_T eDstType,
170 ENUM_WMTMSG_TYPE_T eMsgType,
172 unsigned int u4MsgLength
182 /*******************************************************************************
184 ********************************************************************************
186 /*----------------------------------------------------------------------------*/
188 * @brief This routine is responsible for
189 * 1. registering for reset callbacks
190 * 2. initialize netlink socket
196 /*----------------------------------------------------------------------------*/
202 /* 1. register for reset callback */
203 mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB)glResetCallback);
205 /* 2.1 registration for NETLINK_GENERIC family */
206 if(genl_register_family(&mtk_wifi_gnl_family) != 0) {
207 DBGLOG(INIT, WARN, ("%s(): GE_NELINK family registration fail\n", __func__));
210 /* 2.2 operation registration */
211 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_bind) != 0) {
212 DBGLOG(INIT, WARN, ("%s(): BIND operation registration fail\n", __func__));
215 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_reset) != 0) {
216 DBGLOG(INIT, WARN, ("%s(): RESET operation registration fail\n", __func__));
224 /*----------------------------------------------------------------------------*/
226 * @brief This routine is responsible for
227 * 1. uninitialize netlink socket
228 * 2. deregistering for reset callbacks
234 /*----------------------------------------------------------------------------*/
240 /* 1. release NETLINK_GENERIC family */
241 genl_unregister_family(&mtk_wifi_gnl_family);
243 /* 2. deregister for reset callback */
244 mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
250 /*----------------------------------------------------------------------------*/
252 * @brief This routine is invoked when there is reset messages indicated
262 /*----------------------------------------------------------------------------*/
265 ENUM_WMTDRV_TYPE_T eSrcType,
266 ENUM_WMTDRV_TYPE_T eDstType,
267 ENUM_WMTMSG_TYPE_T eMsgType,
269 unsigned int u4MsgLength
273 case WMTMSG_TYPE_RESET:
274 if(u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
275 P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
278 case WMTRSTMSG_RESET_START:
279 fgIsResetting = TRUE;
280 glResetSendMessage(MTK_WIFI_RESET_START_NAME, MTK_WIFI_COMMAND_RESET);
283 case WMTRSTMSG_RESET_END:
284 glResetSendMessage(MTK_WIFI_RESET_END_NAME, MTK_WIFI_COMMAND_RESET);
285 fgIsResetting = FALSE;
303 /*----------------------------------------------------------------------------*/
305 * @brief This routine send out message via netlink socket
313 /*----------------------------------------------------------------------------*/
320 struct sk_buff *skb = NULL;
321 void *msg_head = NULL;
325 if(num_bind_process == 0) {
326 /* no listening process */
330 for(i = 0 ; i < num_bind_process ; i++) {
331 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
334 msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd);
336 if(msg_head == NULL) {
341 rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg);
347 /* finalize the message */
348 genlmsg_end(skb, msg_head);
350 /* sending message */
351 rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
365 /*----------------------------------------------------------------------------*/
367 * @brief This routine is called to identify PID for process binding
375 /*----------------------------------------------------------------------------*/
378 struct genl_info *info
388 /*for each attribute there is an index in info->attrs which points to a nlattr structure
389 *in this structure the data is given
392 na = info->attrs[MTK_WIFI_ATTR_MSG];
394 mydata = (char *)nla_data(na);
396 /* no need to parse mydata */
400 if(num_bind_process < MAX_BIND_PROCESS) {
401 bind_pid[num_bind_process] = info->snd_pid;
405 DBGLOG(INIT, WARN, ("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS));
413 /*----------------------------------------------------------------------------*/
415 * @brief This routine is called for reset, shout not happen
423 /*----------------------------------------------------------------------------*/
426 struct genl_info *info
429 DBGLOG(INIT, WARN, ("%s(): should not be invoked\n", __func__));
435 /*----------------------------------------------------------------------------*/
437 * @brief This routine is called for generating reset request to WMT
443 /*----------------------------------------------------------------------------*/
449 // WMT thread would trigger whole chip resetting itself
454 /*----------------------------------------------------------------------------*/
456 * @brief This routine is called for checking if MT6620 is resetting
463 /*----------------------------------------------------------------------------*/
469 return fgIsResetting;
473 #endif // CFG_CHIP_RESET_SUPPORT