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 * sync. whole-chip resetting mechanism to V2.0 branch.
71 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
72 * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
73 * 2. add dummy function for both Win32 and Linux part.
76 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
77 * use netlink unicast instead of broadcast
82 /*******************************************************************************
83 * C O M P I L E R F L A G S
84 ********************************************************************************
87 /*******************************************************************************
88 * E X T E R N A L R E F E R E N C E S
89 ********************************************************************************
96 #include <linux/poll.h>
97 #include <net/netlink.h>
98 #include <net/genetlink.h>
100 #if CFG_CHIP_RESET_SUPPORT
102 /*******************************************************************************
104 ********************************************************************************
106 #define MAX_BIND_PROCESS (4)
108 #define MTK_WIFI_FAMILY_NAME "MTK_WIFI"
109 #define MTK_WIFI_RESET_START_NAME "RESET_START"
110 #define MTK_WIFI_RESET_END_NAME "RESET_END"
111 #define MTK_WIFI_RESET_TEST_NAME "GENETLINK_START"
114 /*******************************************************************************
116 ********************************************************************************
119 __MTK_WIFI_ATTR_INVALID,
123 #define MTK_WIFI_ATTR_MAX (__MTK_WIFI_ATTR_MAX - 1)
127 __MTK_WIFI_COMMAND_INVALID,
128 MTK_WIFI_COMMAND_BIND,
129 MTK_WIFI_COMMAND_RESET,
130 __MTK_WIFI_COMMAND_MAX,
132 #define MTK_WIFI_COMMAND_MAX (__MTK_WIFI_COMMAND_MAX - 1)
134 /*******************************************************************************
135 * P U B L I C D A T A
136 ********************************************************************************
139 /*******************************************************************************
140 * P R I V A T E D A T A
141 ********************************************************************************
143 static UINT_32 mtk_wifi_seqnum = 0;
144 static int num_bind_process = 0;
145 static pid_t bind_pid[MAX_BIND_PROCESS];
146 static BOOLEAN fgIsResetting = FALSE;
148 /* attribute policy */
149 static struct nla_policy mtk_wifi_genl_policy[MTK_WIFI_ATTR_MAX + 1] = {
150 [MTK_WIFI_ATTR_MSG] = { .type = NLA_NUL_STRING },
153 /* family definition */
154 static struct genl_family mtk_wifi_gnl_family = {
155 .id = GENL_ID_GENERATE,
157 .name = MTK_WIFI_FAMILY_NAME,
159 .maxattr = MTK_WIFI_ATTR_MAX,
162 /* forward declaration */
163 static int mtk_wifi_bind(
165 struct genl_info *info
168 static int mtk_wifi_reset(
170 struct genl_info *info
173 /* operation definition */
174 static struct genl_ops mtk_wifi_gnl_ops_bind = {
175 .cmd = MTK_WIFI_COMMAND_BIND,
177 .policy = mtk_wifi_genl_policy,
178 .doit = mtk_wifi_bind,
182 static struct genl_ops mtk_wifi_gnl_ops_reset = {
183 .cmd = MTK_WIFI_COMMAND_RESET,
185 .policy = mtk_wifi_genl_policy,
186 .doit = mtk_wifi_reset,
191 /*******************************************************************************
193 ********************************************************************************
196 /*******************************************************************************
197 * F U N C T I O N D E C L A R A T I O N S
198 ********************************************************************************
201 mtk_wcn_wmt_msgcb_reg(
202 ENUM_WMTDRV_TYPE_T eType,
206 mtk_wcn_wmt_msgcb_unreg(
207 ENUM_WMTDRV_TYPE_T eType
212 ENUM_WMTDRV_TYPE_T eSrcType,
213 ENUM_WMTDRV_TYPE_T eDstType,
214 ENUM_WMTMSG_TYPE_T eMsgType,
216 unsigned int u4MsgLength
226 /*******************************************************************************
228 ********************************************************************************
230 /*----------------------------------------------------------------------------*/
232 * @brief This routine is responsible for
233 * 1. registering for reset callbacks
234 * 2. initialize netlink socket
240 /*----------------------------------------------------------------------------*/
246 /* 1. register for reset callback */
247 mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB)glResetCallback);
249 /* 2.1 registration for NETLINK_GENERIC family */
250 if(genl_register_family(&mtk_wifi_gnl_family) != 0) {
251 DBGLOG(INIT, WARN, ("%s(): GE_NELINK family registration fail\n", __func__));
254 /* 2.2 operation registration */
255 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_bind) != 0) {
256 DBGLOG(INIT, WARN, ("%s(): BIND operation registration fail\n", __func__));
259 if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_reset) != 0) {
260 DBGLOG(INIT, WARN, ("%s(): RESET operation registration fail\n", __func__));
268 /*----------------------------------------------------------------------------*/
270 * @brief This routine is responsible for
271 * 1. uninitialize netlink socket
272 * 2. deregistering for reset callbacks
278 /*----------------------------------------------------------------------------*/
284 /* 1. release NETLINK_GENERIC family */
285 genl_unregister_family(&mtk_wifi_gnl_family);
287 /* 2. deregister for reset callback */
288 mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI);
294 /*----------------------------------------------------------------------------*/
296 * @brief This routine is invoked when there is reset messages indicated
306 /*----------------------------------------------------------------------------*/
309 ENUM_WMTDRV_TYPE_T eSrcType,
310 ENUM_WMTDRV_TYPE_T eDstType,
311 ENUM_WMTMSG_TYPE_T eMsgType,
313 unsigned int u4MsgLength
317 case WMTMSG_TYPE_RESET:
318 if(u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
319 P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody;
322 case WMTRSTMSG_RESET_START:
323 fgIsResetting = TRUE;
324 glResetSendMessage(MTK_WIFI_RESET_START_NAME, MTK_WIFI_COMMAND_RESET);
327 case WMTRSTMSG_RESET_END:
328 glResetSendMessage(MTK_WIFI_RESET_END_NAME, MTK_WIFI_COMMAND_RESET);
329 fgIsResetting = FALSE;
347 /*----------------------------------------------------------------------------*/
349 * @brief This routine send out message via netlink socket
357 /*----------------------------------------------------------------------------*/
364 struct sk_buff *skb = NULL;
365 void *msg_head = NULL;
369 if(num_bind_process == 0) {
370 /* no listening process */
374 for(i = 0 ; i < num_bind_process ; i++) {
375 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
378 msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd);
380 if(msg_head == NULL) {
385 rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg);
391 /* finalize the message */
392 genlmsg_end(skb, msg_head);
394 /* sending message */
395 rc = genlmsg_unicast(&init_net, skb, bind_pid[i]);
409 /*----------------------------------------------------------------------------*/
411 * @brief This routine is called to identify PID for process binding
419 /*----------------------------------------------------------------------------*/
422 struct genl_info *info
432 /*for each attribute there is an index in info->attrs which points to a nlattr structure
433 *in this structure the data is given
436 na = info->attrs[MTK_WIFI_ATTR_MSG];
438 mydata = (char *)nla_data(na);
440 /* no need to parse mydata */
444 if(num_bind_process < MAX_BIND_PROCESS) {
445 bind_pid[num_bind_process] = info->snd_pid;
449 DBGLOG(INIT, WARN, ("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS));
457 /*----------------------------------------------------------------------------*/
459 * @brief This routine is called for reset, shout not happen
467 /*----------------------------------------------------------------------------*/
470 struct genl_info *info
473 DBGLOG(INIT, WARN, ("%s(): should not be invoked\n", __func__));
479 /*----------------------------------------------------------------------------*/
481 * @brief This routine is called for generating reset request to WMT
487 /*----------------------------------------------------------------------------*/
493 // WMT thread would trigger whole chip resetting itself
498 /*----------------------------------------------------------------------------*/
500 * @brief This routine is called for checking if MT6620 is resetting
507 /*----------------------------------------------------------------------------*/
513 return fgIsResetting;
517 #endif // CFG_CHIP_RESET_SUPPORT