import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / os / linux / gl_p2p_init.c
1 /*
2 ** $Id: @(#) gl_p2p_init.c@@
3 */
4
5 /*! \file gl_p2p_init.c
6 \brief init and exit routines of Linux driver interface for Wi-Fi Direct
7
8 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
9 Wireless LAN Adapters.
10 */
11
12
13
14 /*******************************************************************************
15 * C O M P I L E R F L A G S
16 ********************************************************************************
17 */
18
19 /*******************************************************************************
20 * E X T E R N A L R E F E R E N C E S
21 ********************************************************************************
22 */
23
24 #include "precomp.h"
25
26
27 /*******************************************************************************
28 * C O N S T A N T S
29 ********************************************************************************
30 */
31
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 */
36
37 #define RUNNING_P2P_MODE 0
38 #define RUNNING_AP_MODE 1
39
40 /*******************************************************************************
41 * D A T A T Y P E S
42 ********************************************************************************
43 */
44
45 /*******************************************************************************
46 * P U B L I C D A T A
47 ********************************************************************************
48 */
49
50
51
52 /*******************************************************************************
53 * P R I V A T E D A T A
54 ********************************************************************************
55 */
56
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
60 * running mode is P2P
61 */
62 static PUCHAR ifname = P2P_MODE_INF_NAME;
63 static UINT_16 mode = RUNNING_P2P_MODE;
64
65 /*******************************************************************************
66 * M A C R O S
67 ********************************************************************************
68 */
69
70 /*******************************************************************************
71 * F U N C T I O N D E C L A R A T I O N S
72 ********************************************************************************
73 */
74 #if defined(CONFIG_HAS_EARLYSUSPEND)
75 extern int glRegisterEarlySuspend(struct early_suspend *prDesc,
76 early_suspend_callback wlanSuspend,
77 late_resume_callback wlanResume);
78
79 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
80 #endif
81
82 /*******************************************************************************
83 * F U N C T I O N S
84 ********************************************************************************
85 */
86
87
88 /*----------------------------------------------------------------------------*/
89 /*!
90 * \brief check interface name parameter is valid or not
91 * if invalid, set ifname to P2P_MODE_INF_NAME
92 *
93 *
94 * \retval
95 */
96 /*----------------------------------------------------------------------------*/
97 VOID p2pCheckInterfaceName(VOID)
98 {
99
100 if (mode) {
101 mode = RUNNING_AP_MODE;
102 ifname = AP_MODE_INF_NAME;
103 }
104 #if 0
105 UINT_32 ifLen = 0;
106
107 if (ifname) {
108 ifLen = strlen(ifname);
109
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;
114 }
115 } else {
116 ifname = P2P_MODE_INF_NAME;
117 }
118 #endif
119 }
120
121
122 extern UINT_8 g_aucBufIpAddr[32];
123
124 static void wlanP2PEarlySuspend(void)
125 {
126 struct net_device *prDev = NULL;
127 P_GLUE_INFO_T prGlueInfo = NULL;
128 UINT_8 ip[4] = { 0 };
129 UINT_32 u4NumIPv4 = 0;
130 #ifdef CONFIG_IPV6
131 UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
132 UINT_32 u4NumIPv6 = 0;
133 #endif
134 UINT_32 i;
135 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
136
137 printk(KERN_INFO "*********p2pEarlySuspend************\n");
138
139 if (!wlanExportGlueInfo(&prGlueInfo)) {
140 printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
141 return;
142 }
143
144 ASSERT(prGlueInfo);
145 /* <1> Sanity check and acquire the net_device */
146 prDev = prGlueInfo->prP2PInfo->prDevHandler;
147 ASSERT(prDev);
148
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");
154 return;
155 }
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]);
159
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))) {
162 u4NumIPv4++;
163 }
164 #ifdef CONFIG_IPV6
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");
170 return;
171 }
172 /* <6> copy the IPv6 address */
173 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local),
174 sizeof(ip6));
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]
178 );
179 /* todo: traverse between list to find whole sets of IPv6 addresses */
180
181 if (!((ip6[0] == 0) &&
182 (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) {
183 }
184 #endif
185 /* <7> set up the ARP filter */
186 {
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;
193
194 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
195
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;
201 #if 0
202 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
203 prParamNetAddr =
204 (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip));
205 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
206 #else
207 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
208 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
209
210 /* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); // TODO: frog. The pointer is not right. */
211
212 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
213 (UINT_32) (prParamNetAddr->
214 u2AddressLength +
215 OFFSET_OF
216 (PARAM_NETWORK_ADDRESS,
217 aucAddress)));
218
219 u4Len +=
220 OFFSET_OF(PARAM_NETWORK_ADDRESS,
221 aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
222 #endif
223 }
224 #ifdef CONFIG_IPV6
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)); */
230
231 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
232 (UINT_32) (prParamNetAddr->
233 u2AddressLength +
234 OFFSET_OF
235 (PARAM_NETWORK_ADDRESS,
236 aucAddress)));
237
238 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
239 }
240 #endif
241 ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
242
243 rStatus = kalIoctl(prGlueInfo,
244 wlanoidSetP2pSetNetworkAddress,
245 (PVOID) prParamNetAddrList,
246 u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
247
248 if (rStatus != WLAN_STATUS_SUCCESS) {
249 printk(KERN_INFO DRV_NAME "set HW pattern filter fail 0x%lx\n", rStatus);
250 }
251 }
252 }
253
254
255 static void wlanP2PLateResume(void)
256 {
257 struct net_device *prDev = NULL;
258 P_GLUE_INFO_T prGlueInfo = NULL;
259 UINT_8 ip[4] = { 0 };
260 #ifdef CONFIG_IPV6
261 UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
262 #endif
263
264 printk(KERN_INFO "*********wlanP2PLateResume************\n");
265 if (!wlanExportGlueInfo(&prGlueInfo)) {
266 printk(KERN_INFO "*********p2pLateResume ignored************\n");
267 return;
268 }
269
270 ASSERT(prGlueInfo);
271 /* <1> Sanity check and acquire the net_device */
272 prDev = prGlueInfo->prP2PInfo->prDevHandler;
273 ASSERT(prDev);
274
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");
280 return;
281 }
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]);
285
286 #ifdef CONFIG_IPV6
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");
292 return;
293 }
294 /* <6> copy the IPv6 address */
295 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local),
296 sizeof(ip6));
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]
300 );
301 #endif
302 /* <7> clear the ARP filter */
303 {
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; */
309
310 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
311
312 prParamNetAddrList->u4AddressCount = 0;
313 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
314
315 ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */));
316 rStatus = kalIoctl(prGlueInfo,
317 wlanoidSetP2pSetNetworkAddress,
318 (PVOID) prParamNetAddrList,
319 u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen);
320
321 if (rStatus != WLAN_STATUS_SUCCESS) {
322 printk(KERN_INFO DRV_NAME "set HW pattern filter fail 0x%lx\n", rStatus);
323 }
324 }
325 }
326
327 #if defined(CONFIG_HAS_EARLYSUSPEND)
328 static struct early_suspend mt6620_p2p_early_suspend_desc = {
329 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
330 };
331
332 static void p2p_early_suspend(struct early_suspend *h)
333 {
334 printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
335 wlanP2PEarlySuspend();
336 }
337
338 static void p2p_late_resume(struct early_suspend *h)
339 {
340 printk(KERN_INFO "*********wlanP2P_late_resume************\n");
341 wlanP2PLateResume();
342 }
343 #endif
344
345 /*----------------------------------------------------------------------------*/
346 /*!
347 * \brief
348 * run p2p init procedure, include register pointer to wlan
349 * glue register p2p
350 * set p2p registered flag
351 * \retval 1 Success
352 */
353 /*----------------------------------------------------------------------------*/
354 BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo)
355 {
356
357 printk("p2p Launch\n");
358
359 if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
360 printk("p2p already registered\n");
361 return FALSE;
362 } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) {
363 prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
364
365 printk("Launch success, fgIsP2PRegistered TRUE.\n");
366
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,
370 p2p_late_resume);
371 #endif
372
373 return TRUE;
374 } else {
375 printk("Launch Fail\n");
376 }
377
378 return FALSE;
379 }
380
381
382 VOID p2pSetMode(IN BOOLEAN fgIsAPMOde)
383 {
384 if (fgIsAPMOde) {
385 mode = RUNNING_AP_MODE;
386 ifname = AP_MODE_INF_NAME;
387 } else {
388 mode = RUNNING_P2P_MODE;
389 ifname = P2P_MODE_INF_NAME;
390 }
391
392 return;
393 } /* p2pSetMode */
394
395
396 /*----------------------------------------------------------------------------*/
397 /*!
398 * \brief
399 * run p2p exit procedure, include unregister pointer to wlan
400 * glue unregister p2p
401 * set p2p registered flag
402
403 * \retval 1 Success
404 */
405 /*----------------------------------------------------------------------------*/
406 BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo)
407 {
408 if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
409 printk("p2p is not Registered.\n");
410 return FALSE;
411 } else {
412
413 #if defined(CONFIG_HAS_EARLYSUSPEND)
414 glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
415 #endif
416 /*Check p2p fsm is stop or not. If not then stop now */
417 if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
418 p2pStopImmediate(prGlueInfo);
419 }
420 prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
421 glUnregisterP2P(prGlueInfo);
422 /*p2p is removed successfully */
423 return TRUE;
424 }
425 return FALSE;
426 }
427
428 #if 0
429 /*----------------------------------------------------------------------------*/
430 /*!
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.
434 *
435 * \retval 0 Success
436 */
437 /*----------------------------------------------------------------------------*/
438 static int initP2P(void)
439 {
440 P_GLUE_INFO_T prGlueInfo;
441
442 /*check interface name validation */
443 p2pCheckInterfaceName();
444
445 printk(KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P");
446
447 /*register p2p init & exit function to wlan sub module handler */
448 wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
449
450 /*if wlan is not start yet, do nothing
451 * p2pLaunch will be called by txthread while wlan start
452 */
453 /*if wlan is not started yet, return FALSE */
454 if (wlanExportGlueInfo(&prGlueInfo)) {
455 wlanSubModInit(prGlueInfo);
456 return (prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO);
457 }
458
459 return 0;
460 } /* end of initP2P() */
461
462
463 /*----------------------------------------------------------------------------*/
464 /*!
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.
468 *
469 * \return (none)
470 */
471 /*----------------------------------------------------------------------------*/
472 /* 1 Module Leave Point */
473 static VOID __exit exitP2P(void)
474 {
475 P_GLUE_INFO_T prGlueInfo;
476
477 printk(KERN_INFO DRV_NAME "ExitP2P\n");
478
479 /*if wlan is not started yet, return FALSE */
480 if (wlanExportGlueInfo(&prGlueInfo)) {
481 wlanSubModExit(prGlueInfo);
482 }
483 /*UNregister p2p init & exit function to wlan sub module handler */
484 wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
485 } /* end of exitP2P() */
486 #endif