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(struct early_suspend
*prDesc
,
76 early_suspend_callback wlanSuspend
,
77 late_resume_callback wlanResume
);
79 extern int glUnregisterEarlySuspend(struct early_suspend
*prDesc
);
82 /*******************************************************************************
84 ********************************************************************************
88 /*----------------------------------------------------------------------------*/
90 * \brief check interface name parameter is valid or not
91 * if invalid, set ifname to P2P_MODE_INF_NAME
96 /*----------------------------------------------------------------------------*/
97 VOID
p2pCheckInterfaceName(VOID
)
101 mode
= RUNNING_AP_MODE
;
102 ifname
= AP_MODE_INF_NAME
;
108 ifLen
= strlen(ifname
);
110 if (ifLen
> MAX_INF_NAME_LEN
) {
111 ifname
[MAX_INF_NAME_LEN
] = '\0';
112 } else if (ifLen
< MIN_INF_NAME_LEN
) {
113 ifname
= P2P_MODE_INF_NAME
;
116 ifname
= P2P_MODE_INF_NAME
;
122 extern UINT_8 g_aucBufIpAddr
[32];
124 static void wlanP2PEarlySuspend(void)
126 struct net_device
*prDev
= NULL
;
127 P_GLUE_INFO_T prGlueInfo
= NULL
;
128 UINT_8 ip
[4] = { 0 };
129 UINT_32 u4NumIPv4
= 0;
131 UINT_8 ip6
[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
132 UINT_32 u4NumIPv6
= 0;
135 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr
;
137 printk(KERN_INFO
"*********p2pEarlySuspend************\n");
139 if (!wlanExportGlueInfo(&prGlueInfo
)) {
140 printk(KERN_INFO
"*********p2pEarlySuspend ignored************\n");
145 /* <1> Sanity check and acquire the net_device */
146 prDev
= prGlueInfo
->prP2PInfo
->prDevHandler
;
149 /* <3> get the IPv4 address */
150 if (!prDev
|| !(prDev
->ip_ptr
) ||
151 !((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
||
152 !(&(((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
->ifa_local
))) {
153 printk(KERN_INFO
"ip is not avaliable.\n");
156 /* <4> copy the IPv4 address */
157 kalMemCopy(ip
, &(((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
->ifa_local
), sizeof(ip
));
158 printk(KERN_INFO
"ip is %d.%d.%d.%d\n", ip
[0], ip
[1], ip
[2], ip
[3]);
160 /* todo: traverse between list to find whole sets of IPv4 addresses */
161 if (!((ip
[0] == 0) && (ip
[1] == 0) && (ip
[2] == 0) && (ip
[3] == 0))) {
165 /* <5> get the IPv6 address */
166 if (!prDev
|| !(prDev
->ip6_ptr
) ||
167 !((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
||
168 !(&(((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
->ifa_local
))) {
169 printk(KERN_INFO
"ipv6 is not avaliable.\n");
172 /* <6> copy the IPv6 address */
173 kalMemCopy(ip6
, &(((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
->ifa_local
),
175 printk(KERN_INFO
"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ip6
[0],
176 ip6
[1], ip6
[2], ip6
[3], ip6
[4], ip6
[5], ip6
[6], ip6
[7], ip6
[8], ip6
[9], ip6
[10],
177 ip6
[11], ip6
[12], ip6
[13], ip6
[14], ip6
[15]
179 /* todo: traverse between list to find whole sets of IPv6 addresses */
181 if (!((ip6
[0] == 0) &&
182 (ip6
[1] == 0) && (ip6
[2] == 0) && (ip6
[3] == 0) && (ip6
[4] == 0) && (ip6
[5] == 0))) {
185 /* <7> set up the ARP filter */
187 WLAN_STATUS rStatus
= WLAN_STATUS_FAILURE
;
188 UINT_32 u4SetInfoLen
= 0;
189 /* UINT_8 aucBuf[32] = {0}; */
190 UINT_32 u4Len
= OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST
, arAddress
);
191 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList
= (P_PARAM_NETWORK_ADDRESS_LIST
) g_aucBufIpAddr
; /* aucBuf; */
192 P_PARAM_NETWORK_ADDRESS prParamNetAddr
= prParamNetAddrList
->arAddress
;
194 kalMemZero(g_aucBufIpAddr
, sizeof(g_aucBufIpAddr
));
196 prParamNetAddrList
->u4AddressCount
= u4NumIPv4
+ u4NumIPv6
;
197 prParamNetAddrList
->u2AddressType
= PARAM_PROTOCOL_ID_TCP_IP
;
198 for (i
= 0; i
< u4NumIPv4
; i
++) {
199 prParamNetAddr
->u2AddressLength
= sizeof(PARAM_NETWORK_ADDRESS_IP
); /* 4;; */
200 prParamNetAddr
->u2AddressType
= PARAM_PROTOCOL_ID_TCP_IP
;
202 kalMemCopy(prParamNetAddr
->aucAddress
, ip
, sizeof(ip
));
204 (P_PARAM_NETWORK_ADDRESS
) ((UINT_32
) prParamNetAddr
+ sizeof(ip
));
205 u4Len
+= OFFSET_OF(PARAM_NETWORK_ADDRESS
, aucAddress
) + sizeof(ip
);
207 prParamIpAddr
= (P_PARAM_NETWORK_ADDRESS_IP
) prParamNetAddr
->aucAddress
;
208 kalMemCopy(&prParamIpAddr
->in_addr
, ip
, sizeof(ip
));
210 /* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); // TODO: frog. The pointer is not right. */
212 prParamNetAddr
= (P_PARAM_NETWORK_ADDRESS
) ((UINT_32
) prParamNetAddr
+
213 (UINT_32
) (prParamNetAddr
->
216 (PARAM_NETWORK_ADDRESS
,
220 OFFSET_OF(PARAM_NETWORK_ADDRESS
,
221 aucAddress
) + sizeof(PARAM_NETWORK_ADDRESS_IP
);
225 for (i
= 0; i
< u4NumIPv6
; i
++) {
226 prParamNetAddr
->u2AddressLength
= 6;
227 prParamNetAddr
->u2AddressType
= PARAM_PROTOCOL_ID_TCP_IP
;
228 kalMemCopy(prParamNetAddr
->aucAddress
, ip6
, sizeof(ip6
));
229 /* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */
231 prParamNetAddr
= (P_PARAM_NETWORK_ADDRESS
) ((UINT_32
) prParamNetAddr
+
232 (UINT_32
) (prParamNetAddr
->
235 (PARAM_NETWORK_ADDRESS
,
238 u4Len
+= OFFSET_OF(PARAM_NETWORK_ADDRESS
, aucAddress
) + sizeof(ip6
);
241 ASSERT(u4Len
<= sizeof(g_aucBufIpAddr
/*aucBuf */));
243 rStatus
= kalIoctl(prGlueInfo
,
244 wlanoidSetP2pSetNetworkAddress
,
245 (PVOID
) prParamNetAddrList
,
246 u4Len
, FALSE
, FALSE
, TRUE
, TRUE
, &u4SetInfoLen
);
248 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
249 printk(KERN_INFO DRV_NAME
"set HW pattern filter fail 0x%lx\n", rStatus
);
255 static void wlanP2PLateResume(void)
257 struct net_device
*prDev
= NULL
;
258 P_GLUE_INFO_T prGlueInfo
= NULL
;
259 UINT_8 ip
[4] = { 0 };
261 UINT_8 ip6
[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
264 printk(KERN_INFO
"*********wlanP2PLateResume************\n");
265 if (!wlanExportGlueInfo(&prGlueInfo
)) {
266 printk(KERN_INFO
"*********p2pLateResume ignored************\n");
271 /* <1> Sanity check and acquire the net_device */
272 prDev
= prGlueInfo
->prP2PInfo
->prDevHandler
;
275 /* <3> get the IPv4 address */
276 if (!prDev
|| !(prDev
->ip_ptr
) ||
277 !((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
||
278 !(&(((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
->ifa_local
))) {
279 printk(KERN_INFO
"ip is not avaliable.\n");
282 /* <4> copy the IPv4 address */
283 kalMemCopy(ip
, &(((struct in_device
*)(prDev
->ip_ptr
))->ifa_list
->ifa_local
), sizeof(ip
));
284 printk(KERN_INFO
"ip is %d.%d.%d.%d\n", ip
[0], ip
[1], ip
[2], ip
[3]);
287 /* <5> get the IPv6 address */
288 if (!prDev
|| !(prDev
->ip6_ptr
) ||
289 !((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
||
290 !(&(((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
->ifa_local
))) {
291 printk(KERN_INFO
"ipv6 is not avaliable.\n");
294 /* <6> copy the IPv6 address */
295 kalMemCopy(ip6
, &(((struct in_device
*)(prDev
->ip6_ptr
))->ifa_list
->ifa_local
),
297 printk(KERN_INFO
"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", ip6
[0],
298 ip6
[1], ip6
[2], ip6
[3], ip6
[4], ip6
[5], ip6
[6], ip6
[7], ip6
[8], ip6
[9], ip6
[10],
299 ip6
[11], ip6
[12], ip6
[13], ip6
[14], ip6
[15]
302 /* <7> clear the ARP filter */
304 WLAN_STATUS rStatus
= WLAN_STATUS_FAILURE
;
305 UINT_32 u4SetInfoLen
= 0;
306 /* UINT_8 aucBuf[32] = {0}; */
307 UINT_32 u4Len
= sizeof(PARAM_NETWORK_ADDRESS_LIST
);
308 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList
= (P_PARAM_NETWORK_ADDRESS_LIST
) g_aucBufIpAddr
; /* aucBuf; */
310 kalMemZero(g_aucBufIpAddr
, sizeof(g_aucBufIpAddr
));
312 prParamNetAddrList
->u4AddressCount
= 0;
313 prParamNetAddrList
->u2AddressType
= PARAM_PROTOCOL_ID_TCP_IP
;
315 ASSERT(u4Len
<= sizeof(g_aucBufIpAddr
/*aucBuf */));
316 rStatus
= kalIoctl(prGlueInfo
,
317 wlanoidSetP2pSetNetworkAddress
,
318 (PVOID
) prParamNetAddrList
,
319 u4Len
, FALSE
, FALSE
, TRUE
, TRUE
, &u4SetInfoLen
);
321 if (rStatus
!= WLAN_STATUS_SUCCESS
) {
322 printk(KERN_INFO DRV_NAME
"set HW pattern filter fail 0x%lx\n", rStatus
);
327 #if defined(CONFIG_HAS_EARLYSUSPEND)
328 static struct early_suspend mt6620_p2p_early_suspend_desc
= {
329 .level
= EARLY_SUSPEND_LEVEL_BLANK_SCREEN
,
332 static void p2p_early_suspend(struct early_suspend
*h
)
334 printk(KERN_INFO
"*********wlanP2P_early_suspend************\n");
335 wlanP2PEarlySuspend();
338 static void p2p_late_resume(struct early_suspend
*h
)
340 printk(KERN_INFO
"*********wlanP2P_late_resume************\n");
345 /*----------------------------------------------------------------------------*/
348 * run p2p init procedure, include register pointer to wlan
350 * set p2p registered flag
353 /*----------------------------------------------------------------------------*/
354 BOOLEAN
p2pLaunch(P_GLUE_INFO_T prGlueInfo
)
357 printk("p2p Launch\n");
359 if (prGlueInfo
->prAdapter
->fgIsP2PRegistered
== TRUE
) {
360 printk("p2p already registered\n");
362 } else if (glRegisterP2P(prGlueInfo
, ifname
, (BOOLEAN
) mode
)) {
363 prGlueInfo
->prAdapter
->fgIsP2PRegistered
= TRUE
;
365 printk("Launch success, fgIsP2PRegistered TRUE.\n");
367 #if defined(CONFIG_HAS_EARLYSUSPEND)
368 /* Here, we register the early suspend and resume callback */
369 glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc
, p2p_early_suspend
,
375 printk("Launch Fail\n");
382 VOID
p2pSetMode(IN BOOLEAN fgIsAPMOde
)
385 mode
= RUNNING_AP_MODE
;
386 ifname
= AP_MODE_INF_NAME
;
388 mode
= RUNNING_P2P_MODE
;
389 ifname
= P2P_MODE_INF_NAME
;
396 /*----------------------------------------------------------------------------*/
399 * run p2p exit procedure, include unregister pointer to wlan
400 * glue unregister p2p
401 * set p2p registered flag
405 /*----------------------------------------------------------------------------*/
406 BOOLEAN
p2pRemove(P_GLUE_INFO_T prGlueInfo
)
408 if (prGlueInfo
->prAdapter
->fgIsP2PRegistered
== FALSE
) {
409 printk("p2p is not Registered.\n");
413 #if defined(CONFIG_HAS_EARLYSUSPEND)
414 glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc
);
416 /*Check p2p fsm is stop or not. If not then stop now */
417 if (IS_P2P_ACTIVE(prGlueInfo
->prAdapter
)) {
418 p2pStopImmediate(prGlueInfo
);
420 prGlueInfo
->prAdapter
->fgIsP2PRegistered
= FALSE
;
421 glUnregisterP2P(prGlueInfo
);
422 /*p2p is removed successfully */
429 /*----------------------------------------------------------------------------*/
431 * \brief Driver entry point when the driver is configured as a Linux Module, and
432 * is called once at module load time, by the user-level modutils
433 * application: insmod or modprobe.
437 /*----------------------------------------------------------------------------*/
438 static int initP2P(void)
440 P_GLUE_INFO_T prGlueInfo
;
442 /*check interface name validation */
443 p2pCheckInterfaceName();
445 printk(KERN_INFO DRV_NAME
"InitP2P, Ifname: %s, Mode: %s\n", ifname
, mode
? "AP" : "P2P");
447 /*register p2p init & exit function to wlan sub module handler */
448 wlanSubModRegisterInitExit(p2pLaunch
, p2pRemove
, P2P_MODULE
);
450 /*if wlan is not start yet, do nothing
451 * p2pLaunch will be called by txthread while wlan start
453 /*if wlan is not started yet, return FALSE */
454 if (wlanExportGlueInfo(&prGlueInfo
)) {
455 wlanSubModInit(prGlueInfo
);
456 return (prGlueInfo
->prAdapter
->fgIsP2PRegistered
? 0 : -EIO
);
460 } /* end of initP2P() */
463 /*----------------------------------------------------------------------------*/
465 * \brief Driver exit point when the driver as a Linux Module is removed. Called
466 * at module unload time, by the user level modutils application: rmmod.
467 * This is our last chance to clean up after ourselves.
471 /*----------------------------------------------------------------------------*/
472 /* 1 Module Leave Point */
473 static VOID __exit
exitP2P(void)
475 P_GLUE_INFO_T prGlueInfo
;
477 printk(KERN_INFO DRV_NAME
"ExitP2P\n");
479 /*if wlan is not started yet, return FALSE */
480 if (wlanExportGlueInfo(&prGlueInfo
)) {
481 wlanSubModExit(prGlueInfo
);
483 /*UNregister p2p init & exit function to wlan sub module handler */
484 wlanSubModRegisterInitExit(NULL
, NULL
, P2P_MODULE
);
485 } /* end of exitP2P() */