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
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
19 ********************************************************************************
22 /*******************************************************************************
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
51 ********************************************************************************
58 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
59 * 1. eliminaite direct calls to printk in porting layer.
60 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
63 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
64 * skip power-off handshaking when RESET indication is received.
67 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
68 * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
69 * 2. add dummy function for both Win32 and Linux part.
72 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
73 * use netlink unicast instead of broadcast
78 /*******************************************************************************
79 * C O M P I L E R F L A G S
80 ********************************************************************************
83 /*******************************************************************************
84 * E X T E R N A L R E F E R E N C E S
85 ********************************************************************************
92 #include <linux/poll.h>
93 #include <net/netlink.h>
94 #include <net/genetlink.h>
96 #if CFG_CHIP_RESET_SUPPORT
98 /*******************************************************************************
100 ********************************************************************************
102 #define MAX_BIND_PROCESS (4)
104 #define MTK_WIFI_FAMILY_NAME "MTK_WIFI"
105 #define MTK_WIFI_RESET_START_NAME "RESET_START"
106 #define MTK_WIFI_RESET_END_NAME "RESET_END"
107 #define MTK_WIFI_RESET_TEST_NAME "GENETLINK_START"
110 /*******************************************************************************
112 ********************************************************************************
115 __MTK_WIFI_ATTR_INVALID,
119 #define MTK_WIFI_ATTR_MAX (__MTK_WIFI_ATTR_MAX - 1)
123 __MTK_WIFI_COMMAND_INVALID,
124 MTK_WIFI_COMMAND_BIND,
125 MTK_WIFI_COMMAND_RESET,
126 __MTK_WIFI_COMMAND_MAX,
128 #define MTK_WIFI_COMMAND_MAX (__MTK_WIFI_COMMAND_MAX - 1)
130 /*******************************************************************************
131 * P U B L I C D A T A
132 ********************************************************************************
134 BOOLEAN fgIsResetting = FALSE;
136 /*******************************************************************************
137 * P R I V A T E D A T A
138 ********************************************************************************
140 static UINT_32 mtk_wifi_seqnum = 0;
141 static int num_bind_process = 0;
142 static pid_t bind_pid[MAX_BIND_PROCESS];
145 /* attribute policy */
146 static struct nla_policy mtk_wifi_genl_policy[MTK_WIFI_ATTR_MAX + 1] = {
147 [MTK_WIFI_ATTR_MSG] = { .type = NLA_NUL_STRING },
150 /* family definition */
151 static struct genl_family mtk_wifi_gnl_family = {
152 .id = GENL_ID_GENERATE,
154 .name = MTK_WIFI_FAMILY_NAME,
156 .maxattr = MTK_WIFI_ATTR_MAX,
159 /* forward declaration */
160 static int mtk_wifi_bind(
162 struct genl_info *info
165 static int mtk_wifi_reset(
167 struct genl_info *info
170 /* operation definition */
171 static struct genl_ops mtk_wifi_gnl_ops_bind = {
172 .cmd = MTK_WIFI_COMMAND_BIND,
174 .policy = mtk_wifi_genl_policy,
175 .doit = mtk_wifi_bind,
179 static struct genl_ops mtk_wifi_gnl_ops_reset = {
180 .cmd = MTK_WIFI_COMMAND_RESET,
182 .policy = mtk_wifi_genl_policy,
183 .doit = mtk_wifi_reset,
188 /*******************************************************************************
190 ********************************************************************************
193 /*******************************************************************************
194 * F U N C T I O N D E C L A R A T I O N S
195 ********************************************************************************
198 mtk_wcn_wmt_msgcb_reg(
199 ENUM_WMTDRV_TYPE_T eType,
203 mtk_wcn_wmt_msgcb_unreg(
204 ENUM_WMTDRV_TYPE_T eType
209 ENUM_WMTDRV_TYPE_T eSrcType,
210 ENUM_WMTDRV_TYPE_T eDstType,
211 ENUM_WMTMSG_TYPE_T eMsgType,
213 unsigned int u4MsgLength
223 /*******************************************************************************
225 ********************************************************************************
227 /*----------------------------------------------------------------------------*/
229 * @brief This routine is responsible for
230 * 1. registering for reset callbacks
231 * 2. initialize netlink socket
237 /*----------------------------------------------------------------------------*/
243 /* 1. register for reset callback */
244 mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB)glResetCallback);
246 /* 2.1 registration for NETLINK_GENERIC family */
247 if(genl_register_family(&mtk_wifi_gnl_family) != 0) {
248 DBGLOG(INIT, WARN, ("%s(): GE_NELINK family registration fail\n", __func__));
251 /* 2.2 operation registration */
252 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_bind) != 0) {
253 DBGLOG(INIT, WARN, ("%s(): BIND operation registration fail\n", __func__));
256 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_reset) != 0) {
257 DBGLOG(INIT, WARN, ("%s(): RESET operation registration fail\n", __func__));
265 /*----------------------------------------------------------------------------*/
267 * @brief This routine is responsible for
268 * 1. uninitialize netlink socket
269 * 2. deregistering for reset callbacks
275 /*----------------------------------------------------------------------------*/
281 /* 1. release NETLINK_GENERIC family */
282 genl_unregister_family(&mtk_wifi_gnl_family);
284 /* 2. deregister for reset callback */
285 mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
291 /*----------------------------------------------------------------------------*/
293 * @brief This routine is invoked when there is reset messages indicated
303 /*----------------------------------------------------------------------------*/
306 ENUM_WMTDRV_TYPE_T eSrcType,
307 ENUM_WMTDRV_TYPE_T eDstType,
308 ENUM_WMTMSG_TYPE_T eMsgType,
310 unsigned int u4MsgLength
314 case WMTMSG_TYPE_RESET:
315 if(u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
316 P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
319 case WMTRSTMSG_RESET_START:
320 fgIsResetting = TRUE;
321 glResetSendMessage(MTK_WIFI_RESET_START_NAME, MTK_WIFI_COMMAND_RESET);
324 case WMTRSTMSG_RESET_END:
325 glResetSendMessage(MTK_WIFI_RESET_END_NAME, MTK_WIFI_COMMAND_RESET);
326 fgIsResetting = FALSE;
344 /*----------------------------------------------------------------------------*/
346 * @brief This routine send out message via netlink socket
354 /*----------------------------------------------------------------------------*/
361 struct sk_buff *skb = NULL;
362 void *msg_head = NULL;
366 if(num_bind_process == 0) {
367 /* no listening process */
371 for(i = 0 ; i < num_bind_process ; i++) {
372 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
375 msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd);
377 if(msg_head == NULL) {
382 rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg);
388 /* finalize the message */
389 genlmsg_end(skb, msg_head);
391 /* sending message */
392 rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
406 /*----------------------------------------------------------------------------*/
408 * @brief This routine is called to identify PID for process binding
416 /*----------------------------------------------------------------------------*/
419 struct genl_info *info
429 /*for each attribute there is an index in info->attrs which points to a nlattr structure
430 *in this structure the data is given
433 na = info->attrs[MTK_WIFI_ATTR_MSG];
435 mydata = (char *)nla_data(na);
437 /* no need to parse mydata */
441 if(num_bind_process < MAX_BIND_PROCESS) {
442 bind_pid[num_bind_process] = info->snd_pid;
446 DBGLOG(INIT, WARN, ("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS));
454 /*----------------------------------------------------------------------------*/
456 * @brief This routine is called for reset, shout not happen
464 /*----------------------------------------------------------------------------*/
467 struct genl_info *info
470 DBGLOG(INIT, WARN, ("%s(): should not be invoked\n", __func__));
476 /*----------------------------------------------------------------------------*/
478 * @brief This routine is called for generating reset request to WMT
484 /*----------------------------------------------------------------------------*/
490 // WMT thread would trigger whole chip resetting itself
495 /*----------------------------------------------------------------------------*/
497 * @brief This routine is called for checking if MT6620 is resetting
504 /*----------------------------------------------------------------------------*/
510 return fgIsResetting;
514 #endif // CFG_CHIP_RESET_SUPPORT