2 ** $Id: @(#) gl_p2p_init.c@@
5 /*! \file gl_p2p_init.c
6 \brief init and exit routines of Linux driver interface for Wi-Fi Direct
8 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
12 /*******************************************************************************
13 * Copyright (c) 2011 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 ********************************************************************************
54 /*******************************************************************************
55 * C O M P I L E R F L A G S
56 ********************************************************************************
59 /*******************************************************************************
60 * E X T E R N A L R E F E R E N C E S
61 ********************************************************************************
67 /*******************************************************************************
69 ********************************************************************************
72 #define P2P_MODE_INF_NAME "p2p%d";
73 #define AP_MODE_INF_NAME "wlan%d";
75 //#define MAX_INF_NAME_LEN 15
76 //#define MIN_INF_NAME_LEN 1
78 #define RUNNING_P2P_MODE 0
79 #define RUNNING_AP_MODE 1
81 /*******************************************************************************
83 ********************************************************************************
86 /*******************************************************************************
88 ********************************************************************************
93 /*******************************************************************************
94 * P R I V A T E D A T A
95 ********************************************************************************
98 /* Get interface name and running mode from module insertion parameter
99 * Usage: insmod p2p.ko mode=1
100 * default: interface name is p2p%d
101 * running mode is P2P
103 static PUCHAR ifname = P2P_MODE_INF_NAME;
104 static UINT_16 mode = RUNNING_P2P_MODE;
106 /*******************************************************************************
108 ********************************************************************************
111 /*******************************************************************************
112 * F U N C T I O N D E C L A R A T I O N S
113 ********************************************************************************
115 #if defined(CONFIG_HAS_EARLYSUSPEND)
116 extern int glRegisterEarlySuspend(
117 struct early_suspend *prDesc,
118 early_suspend_callback wlanSuspend,
119 late_resume_callback wlanResume);
121 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
124 /*******************************************************************************
126 ********************************************************************************
130 /*----------------------------------------------------------------------------*/
132 * \brief check interface name parameter is valid or not
133 * if invalid, set ifname to P2P_MODE_INF_NAME
138 /*----------------------------------------------------------------------------*/
140 p2pCheckInterfaceName(
146 mode = RUNNING_AP_MODE;
147 ifname = AP_MODE_INF_NAME;
153 ifLen = strlen(ifname);
155 if(ifLen > MAX_INF_NAME_LEN) {
156 ifname[MAX_INF_NAME_LEN] = '\0';
158 else if( ifLen < MIN_INF_NAME_LEN ) {
159 ifname = P2P_MODE_INF_NAME;
162 ifname = P2P_MODE_INF_NAME;
168 extern UINT_8 g_aucBufIpAddr[32];
170 static void wlanP2PEarlySuspend(void)
172 struct net_device *prDev = NULL;
173 P_GLUE_INFO_T prGlueInfo = NULL;
174 UINT_8 ip[4] = { 0 };
175 UINT_32 u4NumIPv4 = 0;
177 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
178 UINT_32 u4NumIPv6 = 0;
181 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
183 printk(KERN_INFO "*********p2pEarlySuspend************\n");
185 if(!wlanExportGlueInfo(&prGlueInfo)) {
186 printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
191 // <1> Sanity check and acquire the net_device
192 prDev = prGlueInfo->prP2PInfo->prDevHandler;
195 // <3> get the IPv4 address
196 if(!prDev || !(prDev->ip_ptr)||\
197 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
198 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
199 printk(KERN_INFO "ip is not avaliable.\n");
203 // <4> copy the IPv4 address
204 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
205 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
206 ip[0],ip[1],ip[2],ip[3]);
208 // todo: traverse between list to find whole sets of IPv4 addresses
209 if (!((ip[0] == 0) &&
217 // <5> get the IPv6 address
218 if(!prDev || !(prDev->ip6_ptr)||\
219 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
220 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
221 printk(KERN_INFO "ipv6 is not avaliable.\n");
224 // <6> copy the IPv6 address
225 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
226 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
227 ip6[0],ip6[1],ip6[2],ip6[3],
228 ip6[4],ip6[5],ip6[6],ip6[7],
229 ip6[8],ip6[9],ip6[10],ip6[11],
230 ip6[12],ip6[13],ip6[14],ip6[15]
232 // todo: traverse between list to find whole sets of IPv6 addresses
234 if (!((ip6[0] == 0) &&
243 // <7> set up the ARP filter
245 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
246 UINT_32 u4SetInfoLen = 0;
247 // UINT_8 aucBuf[32] = {0};
248 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
249 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
250 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
252 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
254 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
255 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
256 for (i = 0; i < u4NumIPv4; i++) {
257 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
258 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
260 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
261 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
262 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
264 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
265 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
267 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); // TODO: frog. The pointer is not right.
269 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
270 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
272 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
276 for (i = 0; i < u4NumIPv6; i++) {
277 prParamNetAddr->u2AddressLength = 6;;
278 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
279 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
280 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
282 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
283 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
285 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
288 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
290 rStatus = kalIoctl(prGlueInfo,
291 wlanoidSetP2pSetNetworkAddress,
292 (PVOID)prParamNetAddrList,
300 if (rStatus != WLAN_STATUS_SUCCESS) {
301 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
307 static void wlanP2PLateResume(void)
309 struct net_device *prDev = NULL;
310 P_GLUE_INFO_T prGlueInfo = NULL;
311 UINT_8 ip[4] = { 0 };
313 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
316 printk(KERN_INFO "*********wlanP2PLateResume************\n");
317 if(!wlanExportGlueInfo(&prGlueInfo)) {
318 printk(KERN_INFO "*********p2pLateResume ignored************\n");
323 // <1> Sanity check and acquire the net_device
324 prDev = prGlueInfo->prP2PInfo->prDevHandler;
327 // <3> get the IPv4 address
328 if(!prDev || !(prDev->ip_ptr)||\
329 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
330 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
331 printk(KERN_INFO "ip is not avaliable.\n");
335 // <4> copy the IPv4 address
336 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
337 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
338 ip[0],ip[1],ip[2],ip[3]);
341 // <5> get the IPv6 address
342 if(!prDev || !(prDev->ip6_ptr)||\
343 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
344 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
345 printk(KERN_INFO "ipv6 is not avaliable.\n");
348 // <6> copy the IPv6 address
349 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
350 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
351 ip6[0],ip6[1],ip6[2],ip6[3],
352 ip6[4],ip6[5],ip6[6],ip6[7],
353 ip6[8],ip6[9],ip6[10],ip6[11],
354 ip6[12],ip6[13],ip6[14],ip6[15]
357 // <7> clear the ARP filter
359 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
360 UINT_32 u4SetInfoLen = 0;
361 // UINT_8 aucBuf[32] = {0};
362 UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
363 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
365 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
367 prParamNetAddrList->u4AddressCount = 0;
368 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
370 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
371 rStatus = kalIoctl(prGlueInfo,
372 wlanoidSetP2pSetNetworkAddress,
373 (PVOID)prParamNetAddrList,
381 if (rStatus != WLAN_STATUS_SUCCESS) {
382 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
387 #if defined(CONFIG_HAS_EARLYSUSPEND)
388 static struct early_suspend mt6620_p2p_early_suspend_desc = {
389 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
392 static void p2p_early_suspend(struct early_suspend *h)
394 printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
395 wlanP2PEarlySuspend();
398 static void p2p_late_resume(struct early_suspend *h)
400 printk(KERN_INFO "*********wlanP2P_late_resume************\n");
405 /*----------------------------------------------------------------------------*/
408 * run p2p init procedure, include register pointer to wlan
410 * set p2p registered flag
413 /*----------------------------------------------------------------------------*/
416 P_GLUE_INFO_T prGlueInfo
420 printk("p2p Launch\n");
422 if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
423 printk("p2p already registered\n");
426 else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
427 prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
429 printk("Launch success, fgIsP2PRegistered TRUE.\n");
431 #if defined(CONFIG_HAS_EARLYSUSPEND)
432 /* Here, we register the early suspend and resume callback */
433 glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc, p2p_early_suspend, p2p_late_resume);
439 printk("Launch Fail\n");
448 IN BOOLEAN fgIsAPMOde
452 mode = RUNNING_AP_MODE;
453 ifname = AP_MODE_INF_NAME;
456 mode = RUNNING_P2P_MODE;
457 ifname = P2P_MODE_INF_NAME;
464 /*----------------------------------------------------------------------------*/
467 * run p2p exit procedure, include unregister pointer to wlan
468 * glue unregister p2p
469 * set p2p registered flag
473 /*----------------------------------------------------------------------------*/
476 P_GLUE_INFO_T prGlueInfo
479 if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
480 printk("p2p is not Registered.\n");
485 #if defined(CONFIG_HAS_EARLYSUSPEND)
486 glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
488 /*Check p2p fsm is stop or not. If not then stop now*/
489 if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
490 p2pStopImmediate(prGlueInfo);
492 prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
493 glUnregisterP2P(prGlueInfo);
494 /*p2p is removed successfully*/
501 /*----------------------------------------------------------------------------*/
503 * \brief Driver entry point when the driver is configured as a Linux Module, and
504 * is called once at module load time, by the user-level modutils
505 * application: insmod or modprobe.
509 /*----------------------------------------------------------------------------*/
510 static int initP2P(void)
512 P_GLUE_INFO_T prGlueInfo;
514 /*check interface name validation*/
515 p2pCheckInterfaceName();
517 printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
519 /*register p2p init & exit function to wlan sub module handler*/
520 wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
522 /*if wlan is not start yet, do nothing
523 * p2pLaunch will be called by txthread while wlan start
525 /*if wlan is not started yet, return FALSE*/
526 if(wlanExportGlueInfo(&prGlueInfo)) {
527 wlanSubModInit(prGlueInfo);
528 return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
532 } /* end of initP2P() */
535 /*----------------------------------------------------------------------------*/
537 * \brief Driver exit point when the driver as a Linux Module is removed. Called
538 * at module unload time, by the user level modutils application: rmmod.
539 * This is our last chance to clean up after ourselves.
543 /*----------------------------------------------------------------------------*/
544 //1 Module Leave Point
545 static VOID __exit exitP2P(void)
547 P_GLUE_INFO_T prGlueInfo;
549 printk( KERN_INFO DRV_NAME "ExitP2P\n");
551 /*if wlan is not started yet, return FALSE*/
552 if(wlanExportGlueInfo(&prGlueInfo)) {
553 wlanSubModExit(prGlueInfo);
555 /*UNregister p2p init & exit function to wlan sub module handler*/
556 wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
557 } /* end of exitP2P() */