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 "ap%d";
34 //#define MAX_INF_NAME_LEN 15
35 //#define MIN_INF_NAME_LEN 1
37 #define RUNNING_P2P_MODE 0
38 #define RUNNING_AP_MODE 1
40 /*******************************************************************************
42 ********************************************************************************
45 /*******************************************************************************
47 ********************************************************************************
52 /*******************************************************************************
53 * P R I V A T E D A T A
54 ********************************************************************************
57 /* Get interface name and running mode from module insertion parameter
58 * Usage: insmod p2p.ko mode=1
59 * default: interface name is p2p%d
62 static PUCHAR ifname = P2P_MODE_INF_NAME;
63 static UINT_16 mode = RUNNING_P2P_MODE;
65 /*******************************************************************************
67 ********************************************************************************
70 /*******************************************************************************
71 * F U N C T I O N D E C L A R A T I O N S
72 ********************************************************************************
74 #if defined(CONFIG_HAS_EARLYSUSPEND)
75 extern int glRegisterEarlySuspend(
76 struct early_suspend *prDesc,
77 early_suspend_callback wlanSuspend,
78 late_resume_callback wlanResume);
80 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
83 /*******************************************************************************
85 ********************************************************************************
89 /*----------------------------------------------------------------------------*/
91 * \brief check interface name parameter is valid or not
92 * if invalid, set ifname to P2P_MODE_INF_NAME
97 /*----------------------------------------------------------------------------*/
99 p2pCheckInterfaceName(
105 mode = RUNNING_AP_MODE;
106 ifname = AP_MODE_INF_NAME;
112 ifLen = strlen(ifname);
114 if(ifLen > MAX_INF_NAME_LEN) {
115 ifname[MAX_INF_NAME_LEN] = '\0';
117 else if( ifLen < MIN_INF_NAME_LEN ) {
118 ifname = P2P_MODE_INF_NAME;
121 ifname = P2P_MODE_INF_NAME;
127 extern UINT_8 g_aucBufIpAddr[32];
129 static void wlanP2PEarlySuspend(void)
131 struct net_device *prDev = NULL;
132 P_GLUE_INFO_T prGlueInfo = NULL;
133 UINT_8 ip[4] = { 0 };
134 UINT_32 u4NumIPv4 = 0;
136 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
137 UINT_32 u4NumIPv6 = 0;
140 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
142 printk(KERN_INFO "*********p2pEarlySuspend************\n");
144 if(!wlanExportGlueInfo(&prGlueInfo)) {
145 printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
150 // <1> Sanity check and acquire the net_device
151 prDev = prGlueInfo->prP2PInfo->prDevHandler;
154 // <3> get the IPv4 address
155 if(!prDev || !(prDev->ip_ptr)||\
156 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
157 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
158 printk(KERN_INFO "ip is not avaliable.\n");
162 // <4> copy the IPv4 address
163 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
164 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
165 ip[0],ip[1],ip[2],ip[3]);
167 // todo: traverse between list to find whole sets of IPv4 addresses
168 if (!((ip[0] == 0) &&
176 // <5> get the IPv6 address
177 if(!prDev || !(prDev->ip6_ptr)||\
178 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
179 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
180 printk(KERN_INFO "ipv6 is not avaliable.\n");
183 // <6> copy the IPv6 address
184 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
185 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
186 ip6[0],ip6[1],ip6[2],ip6[3],
187 ip6[4],ip6[5],ip6[6],ip6[7],
188 ip6[8],ip6[9],ip6[10],ip6[11],
189 ip6[12],ip6[13],ip6[14],ip6[15]
191 // todo: traverse between list to find whole sets of IPv6 addresses
193 if (!((ip6[0] == 0) &&
202 // <7> set up the ARP filter
204 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
205 UINT_32 u4SetInfoLen = 0;
206 // UINT_8 aucBuf[32] = {0};
207 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
208 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
209 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
211 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
213 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
214 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
215 for (i = 0; i < u4NumIPv4; i++) {
216 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
217 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
219 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
220 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
221 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
223 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
224 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
226 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); // TODO: frog. The pointer is not right.
228 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
229 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
231 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
235 for (i = 0; i < u4NumIPv6; i++) {
236 prParamNetAddr->u2AddressLength = 6;;
237 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
238 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
239 // prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
241 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
242 (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
244 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
247 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
249 rStatus = kalIoctl(prGlueInfo,
250 wlanoidSetP2pSetNetworkAddress,
251 (PVOID)prParamNetAddrList,
259 if (rStatus != WLAN_STATUS_SUCCESS) {
260 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
266 static void wlanP2PLateResume(void)
268 struct net_device *prDev = NULL;
269 P_GLUE_INFO_T prGlueInfo = NULL;
270 UINT_8 ip[4] = { 0 };
272 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
275 printk(KERN_INFO "*********wlanP2PLateResume************\n");
276 if(!wlanExportGlueInfo(&prGlueInfo)) {
277 printk(KERN_INFO "*********p2pLateResume ignored************\n");
282 // <1> Sanity check and acquire the net_device
283 prDev = prGlueInfo->prP2PInfo->prDevHandler;
286 // <3> get the IPv4 address
287 if(!prDev || !(prDev->ip_ptr)||\
288 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
289 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
290 printk(KERN_INFO "ip is not avaliable.\n");
294 // <4> copy the IPv4 address
295 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
296 printk(KERN_INFO"ip is %d.%d.%d.%d\n",
297 ip[0],ip[1],ip[2],ip[3]);
300 // <5> get the IPv6 address
301 if(!prDev || !(prDev->ip6_ptr)||\
302 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
303 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
304 printk(KERN_INFO "ipv6 is not avaliable.\n");
307 // <6> copy the IPv6 address
308 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
309 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
310 ip6[0],ip6[1],ip6[2],ip6[3],
311 ip6[4],ip6[5],ip6[6],ip6[7],
312 ip6[8],ip6[9],ip6[10],ip6[11],
313 ip6[12],ip6[13],ip6[14],ip6[15]
316 // <7> clear the ARP filter
318 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
319 UINT_32 u4SetInfoLen = 0;
320 // UINT_8 aucBuf[32] = {0};
321 UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
322 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
324 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
326 prParamNetAddrList->u4AddressCount = 0;
327 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
329 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
330 rStatus = kalIoctl(prGlueInfo,
331 wlanoidSetP2pSetNetworkAddress,
332 (PVOID)prParamNetAddrList,
340 if (rStatus != WLAN_STATUS_SUCCESS) {
341 printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
346 #if defined(CONFIG_HAS_EARLYSUSPEND)
347 static struct early_suspend mt6620_p2p_early_suspend_desc = {
348 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
351 static void p2p_early_suspend(struct early_suspend *h)
353 printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
354 wlanP2PEarlySuspend();
357 static void p2p_late_resume(struct early_suspend *h)
359 printk(KERN_INFO "*********wlanP2P_late_resume************\n");
364 /*----------------------------------------------------------------------------*/
367 * run p2p init procedure, include register pointer to wlan
369 * set p2p registered flag
372 /*----------------------------------------------------------------------------*/
375 P_GLUE_INFO_T prGlueInfo
379 printk("p2p Launch\n");
381 if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
382 printk("p2p already registered\n");
385 else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
386 prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
388 printk("Launch success, fgIsP2PRegistered TRUE.\n");
390 #if defined(CONFIG_HAS_EARLYSUSPEND)
391 /* Here, we register the early suspend and resume callback */
392 glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc, p2p_early_suspend, p2p_late_resume);
398 printk("Launch Fail\n");
407 IN BOOLEAN fgIsAPMOde
411 mode = RUNNING_AP_MODE;
412 ifname = AP_MODE_INF_NAME;
415 mode = RUNNING_P2P_MODE;
416 ifname = P2P_MODE_INF_NAME;
423 /*----------------------------------------------------------------------------*/
426 * run p2p exit procedure, include unregister pointer to wlan
427 * glue unregister p2p
428 * set p2p registered flag
432 /*----------------------------------------------------------------------------*/
435 P_GLUE_INFO_T prGlueInfo
438 if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
439 printk("p2p is not Registered.\n");
444 #if defined(CONFIG_HAS_EARLYSUSPEND)
445 glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
447 /*Check p2p fsm is stop or not. If not then stop now*/
448 if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
449 p2pStopImmediate(prGlueInfo);
451 prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
452 glUnregisterP2P(prGlueInfo);
453 /*p2p is removed successfully*/
460 /*----------------------------------------------------------------------------*/
462 * \brief Driver entry point when the driver is configured as a Linux Module, and
463 * is called once at module load time, by the user-level modutils
464 * application: insmod or modprobe.
468 /*----------------------------------------------------------------------------*/
469 static int initP2P(void)
471 P_GLUE_INFO_T prGlueInfo;
473 /*check interface name validation*/
474 p2pCheckInterfaceName();
476 printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
478 /*register p2p init & exit function to wlan sub module handler*/
479 wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
481 /*if wlan is not start yet, do nothing
482 * p2pLaunch will be called by txthread while wlan start
484 /*if wlan is not started yet, return FALSE*/
485 if(wlanExportGlueInfo(&prGlueInfo)) {
486 wlanSubModInit(prGlueInfo);
487 return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
491 } /* end of initP2P() */
494 /*----------------------------------------------------------------------------*/
496 * \brief Driver exit point when the driver as a Linux Module is removed. Called
497 * at module unload time, by the user level modutils application: rmmod.
498 * This is our last chance to clean up after ourselves.
502 /*----------------------------------------------------------------------------*/
503 //1 Module Leave Point
504 static VOID __exit exitP2P(void)
506 P_GLUE_INFO_T prGlueInfo;
508 printk( KERN_INFO DRV_NAME "ExitP2P\n");
510 /*if wlan is not started yet, return FALSE*/
511 if(wlanExportGlueInfo(&prGlueInfo)) {
512 wlanSubModExit(prGlueInfo);
514 /*UNregister p2p init & exit function to wlan sub module handler*/
515 wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
516 } /* end of exitP2P() */