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
14 /*******************************************************************************
15 * C O M P I L E R F L A G S
16 ********************************************************************************
19 /*******************************************************************************
20 * E X T E R N A L R E F E R E N C E S
21 ********************************************************************************
27 /*******************************************************************************
29 ********************************************************************************
32 #define P2P_MODE_INF_NAME "p2p%d";
33 #define AP_MODE_INF_NAME "wlan%d";
35 //#define MAX_INF_NAME_LEN 15
36 //#define MIN_INF_NAME_LEN 1
38 #define RUNNING_P2P_MODE 0
39 #define RUNNING_AP_MODE 1
41 /*******************************************************************************
43 ********************************************************************************
46 /*******************************************************************************
48 ********************************************************************************
53 /*******************************************************************************
54 * P R I V A T E D A T A
55 ********************************************************************************
58 /* Get interface name and running mode from module insertion parameter
59 * Usage: insmod p2p.ko mode=1
60 * default: interface name is p2p%d
63 static PUCHAR ifname = P2P_MODE_INF_NAME;
64 static UINT_16 mode = RUNNING_P2P_MODE;
66 /*******************************************************************************
68 ********************************************************************************
71 /*******************************************************************************
72 * F U N C T I O N D E C L A R A T I O N S
73 ********************************************************************************
75 #if defined(CONFIG_HAS_EARLYSUSPEND)
76 extern int glRegisterEarlySuspend(
77 struct early_suspend *prDesc,
78 early_suspend_callback wlanSuspend,
79 late_resume_callback wlanResume);
81 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
84 /*******************************************************************************
86 ********************************************************************************
90 /*----------------------------------------------------------------------------*/
92 * \brief check interface name parameter is valid or not
93 * if invalid, set ifname to P2P_MODE_INF_NAME
98 /*----------------------------------------------------------------------------*/
100 p2pCheckInterfaceName(
106 mode = RUNNING_AP_MODE;
107 ifname = AP_MODE_INF_NAME;
113 ifLen = strlen(ifname);
115 if(ifLen > MAX_INF_NAME_LEN) {
116 ifname[MAX_INF_NAME_LEN] = '\0';
118 else if( ifLen < MIN_INF_NAME_LEN ) {
119 ifname = P2P_MODE_INF_NAME;
122 ifname = P2P_MODE_INF_NAME;
128 extern UINT_8 g_aucBufIpAddr[32];
131 static void wlanP2PEarlySuspend(void)
133 struct in_device *in_dev;
134 struct net_device *prDev = NULL;
135 P_GLUE_INFO_T prGlueInfo = NULL;
136 UINT_8 ip[4] = { 0 };
137 UINT_32 u4NumIPv4 = 0;
138 #if defined(CONFIG_IPV6) && defined(ENABLE_IPV6_WLAN)
139 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
141 UINT_32 u4NumIPv6 = 0;
143 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
145 printk(KERN_INFO "*********p2pEarlySuspend************\n");
147 if(!wlanExportGlueInfo(&prGlueInfo)) {
148 printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
153 // <1> Sanity check and acquire the net_device
154 prDev = prGlueInfo->prP2PInfo->prDevHandler;
157 // <3> get the IPv4 address
158 in_dev = in_dev_get(prDev);
163 if(!in_dev->ifa_list ||!in_dev->ifa_list->ifa_local) {
166 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
169 // <4> copy the IPv4 address
170 kalMemCopy(ip, &(in_dev->ifa_list->ifa_local), sizeof(ip));
174 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
175 ip[0],ip[1],ip[2],ip[3]);
177 // todo: traverse between list to find whole sets of IPv4 addresses
178 if (!((ip[0] == 0) &&
185 #if defined(CONFIG_IPV6) && defined( ENABLE_IPV6_WLAN)
186 // <5> get the IPv6 address
187 if(!prDev || !(prDev->ip6_ptr)||\
188 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
189 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
190 printk(KERN_INFO "ipv6 is not avaliable.\n");
193 // <6> copy the IPv6 address
194 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
195 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
196 ip6[0],ip6[1],ip6[2],ip6[3],
197 ip6[4],ip6[5],ip6[6],ip6[7],
198 ip6[8],ip6[9],ip6[10],ip6[11],
199 ip6[12],ip6[13],ip6[14],ip6[15]
201 // todo: traverse between list to find whole sets of IPv6 addresses
203 if (!((ip6[0] == 0) &&
213 // <7> set up the ARP filter
215 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
216 UINT_32 u4SetInfoLen = 0;
217 // UINT_8 aucBuf[32] = {0};
218 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
219 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
220 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
222 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
224 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
225 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
226 for (i = 0; i < u4NumIPv4; i++) {
227 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
228 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
230 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
231 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
232 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
234 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
235 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
237 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); // TODO: frog. The pointer is not right.
239 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
240 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
242 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
245 #if defined(CONFIG_IPV6) && defined(ENABLE_IPV6_WLAN)
246 for (i = 0; i < u4NumIPv6; i++) {
247 prParamNetAddr->u2AddressLength = 6;;
248 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
249 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
250 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
252 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
253 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
255 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
258 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
260 rStatus = kalIoctl(prGlueInfo,
261 wlanoidSetP2pSetNetworkAddress,
262 (PVOID)prParamNetAddrList,
270 if (rStatus != WLAN_STATUS_SUCCESS) {
271 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
277 static void wlanP2PLateResume(void)
279 struct in_device *in_dev;
280 struct net_device *prDev = NULL;
281 P_GLUE_INFO_T prGlueInfo = NULL;
282 UINT_8 ip[4] = { 0 };
283 #if defined(CONFIG_IPV6) && defined(ENABLE_IPV6_WLAN)
284 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
287 printk(KERN_INFO "*********wlanP2PLateResume************\n");
288 if(!wlanExportGlueInfo(&prGlueInfo)) {
289 printk(KERN_INFO "*********p2pLateResume ignored************\n");
294 // <1> Sanity check and acquire the net_device
295 prDev = prGlueInfo->prP2PInfo->prDevHandler;
298 // <3> get the IPv4 address
299 in_dev = in_dev_get(prDev);
304 if(!in_dev->ifa_list ||!in_dev->ifa_list->ifa_local) {
307 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
310 // <4> copy the IPv4 address
311 kalMemCopy(ip, &(in_dev->ifa_list->ifa_local), sizeof(ip));
315 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
316 ip[0],ip[1],ip[2],ip[3]);
318 #if defined(CONFIG_IPV6) && defined(ENABLE_IPV6_WLAN)
319 // <5> get the IPv6 address
320 if(!prDev || !(prDev->ip6_ptr)||\
321 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
322 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
323 printk(KERN_INFO "ipv6 is not avaliable.\n");
326 // <6> copy the IPv6 address
327 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
328 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
329 ip6[0],ip6[1],ip6[2],ip6[3],
330 ip6[4],ip6[5],ip6[6],ip6[7],
331 ip6[8],ip6[9],ip6[10],ip6[11],
332 ip6[12],ip6[13],ip6[14],ip6[15]
335 // <7> clear the ARP filter
337 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
338 UINT_32 u4SetInfoLen = 0;
339 // UINT_8 aucBuf[32] = {0};
340 UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
341 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
343 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
345 prParamNetAddrList->u4AddressCount = 0;
346 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
348 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
349 rStatus = kalIoctl(prGlueInfo,
350 wlanoidSetP2pSetNetworkAddress,
351 (PVOID)prParamNetAddrList,
359 if (rStatus != WLAN_STATUS_SUCCESS) {
360 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
365 #if defined(CONFIG_HAS_EARLYSUSPEND)
366 static struct early_suspend mt6620_p2p_early_suspend_desc = {
367 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
370 static void p2p_early_suspend(struct early_suspend *h)
372 printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
373 wlanP2PEarlySuspend();
376 static void p2p_late_resume(struct early_suspend *h)
378 printk(KERN_INFO "*********wlanP2P_late_resume************\n");
383 /*----------------------------------------------------------------------------*/
386 * run p2p init procedure, include register pointer to wlan
388 * set p2p registered flag
391 /*----------------------------------------------------------------------------*/
394 P_GLUE_INFO_T prGlueInfo
398 printk("p2p Launch\n");
400 if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
401 printk("p2p already registered\n");
404 else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
405 prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
407 printk("Launch success, fgIsP2PRegistered TRUE.\n");
409 #if defined(CONFIG_HAS_EARLYSUSPEND)
410 /* Here, we register the early suspend and resume callback */
411 glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc, p2p_early_suspend, p2p_late_resume);
417 printk("Launch Fail\n");
426 IN BOOLEAN fgIsAPMOde
430 mode = RUNNING_AP_MODE;
431 ifname = AP_MODE_INF_NAME;
434 mode = RUNNING_P2P_MODE;
435 ifname = P2P_MODE_INF_NAME;
442 /*----------------------------------------------------------------------------*/
445 * run p2p exit procedure, include unregister pointer to wlan
446 * glue unregister p2p
447 * set p2p registered flag
451 /*----------------------------------------------------------------------------*/
454 P_GLUE_INFO_T prGlueInfo
457 if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
458 printk("p2p is not Registered.\n");
463 #if defined(CONFIG_HAS_EARLYSUSPEND)
464 glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
466 /*Check p2p fsm is stop or not. If not then stop now*/
467 if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
468 p2pStopImmediate(prGlueInfo);
470 prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
471 glUnregisterP2P(prGlueInfo);
472 /*p2p is removed successfully*/
479 /*----------------------------------------------------------------------------*/
481 * \brief Driver entry point when the driver is configured as a Linux Module, and
482 * is called once at module load time, by the user-level modutils
483 * application: insmod or modprobe.
487 /*----------------------------------------------------------------------------*/
488 static int initP2P(void)
490 P_GLUE_INFO_T prGlueInfo;
492 /*check interface name validation*/
493 p2pCheckInterfaceName();
495 printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
497 /*register p2p init & exit function to wlan sub module handler*/
498 wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
500 /*if wlan is not start yet, do nothing
501 * p2pLaunch will be called by txthread while wlan start
503 /*if wlan is not started yet, return FALSE*/
504 if(wlanExportGlueInfo(&prGlueInfo)) {
505 wlanSubModInit(prGlueInfo);
506 return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
510 } /* end of initP2P() */
513 /*----------------------------------------------------------------------------*/
515 * \brief Driver exit point when the driver as a Linux Module is removed. Called
516 * at module unload time, by the user level modutils application: rmmod.
517 * This is our last chance to clean up after ourselves.
521 /*----------------------------------------------------------------------------*/
522 //1 Module Leave Point
523 static VOID __exit exitP2P(void)
525 P_GLUE_INFO_T prGlueInfo;
527 printk( KERN_INFO DRV_NAME "ExitP2P\n");
529 /*if wlan is not started yet, return FALSE*/
530 if(wlanExportGlueInfo(&prGlueInfo)) {
531 wlanSubModExit(prGlueInfo);
533 /*UNregister p2p init & exit function to wlan sub module handler*/
534 wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
535 } /* end of exitP2P() */