support different wifi bt chip auto compatible
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931 / 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(
76     struct early_suspend        *prDesc,
77     early_suspend_callback      wlanSuspend,
78     late_resume_callback        wlanResume);
79
80 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
81 #endif
82
83 /*******************************************************************************
84 *                              F U N C T I O N S
85 ********************************************************************************
86 */
87
88
89 /*----------------------------------------------------------------------------*/
90 /*!
91 * \brief    check interface name parameter is valid or not
92 *             if invalid, set ifname to P2P_MODE_INF_NAME
93 *
94 *
95 * \retval
96 */
97 /*----------------------------------------------------------------------------*/
98 VOID
99 p2pCheckInterfaceName(
100     VOID
101     )
102 {
103
104     if(mode) {
105         mode = RUNNING_AP_MODE;
106         ifname = AP_MODE_INF_NAME;
107     }
108 #if 0
109     UINT_32 ifLen = 0;
110
111     if(ifname) {
112         ifLen = strlen(ifname);
113
114         if(ifLen > MAX_INF_NAME_LEN) {
115             ifname[MAX_INF_NAME_LEN] = '\0';
116         }
117         else if( ifLen < MIN_INF_NAME_LEN  ) {
118             ifname = P2P_MODE_INF_NAME;
119         }
120     } else {
121         ifname = P2P_MODE_INF_NAME;
122     }
123 #endif
124 }
125
126
127 extern UINT_8 g_aucBufIpAddr[32];
128
129 static void wlanP2PEarlySuspend(void)
130 {
131     struct net_device *prDev = NULL;
132     P_GLUE_INFO_T prGlueInfo = NULL;
133     UINT_8  ip[4] = { 0 };
134     UINT_32 u4NumIPv4 = 0;
135 #ifdef  CONFIG_IPV6
136     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
137     UINT_32 u4NumIPv6 = 0;
138 #endif
139     UINT_32 i;
140         P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
141
142     printk(KERN_INFO "*********p2pEarlySuspend************\n");
143
144     if(!wlanExportGlueInfo(&prGlueInfo)) {
145         printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
146         return;
147     }
148
149     ASSERT(prGlueInfo);
150     // <1> Sanity check and acquire the net_device
151     prDev = prGlueInfo->prP2PInfo->prDevHandler;
152     ASSERT(prDev);
153
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");
159         return;
160     }
161
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]);
166
167    // todo: traverse between list to find whole sets of IPv4 addresses
168     if (!((ip[0] == 0) &&
169          (ip[1] == 0) &&
170          (ip[2] == 0) &&
171          (ip[3] == 0))) {
172         u4NumIPv4++;
173     }
174
175 #ifdef  CONFIG_IPV6
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");
181         return;
182     }
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]
190             );
191     // todo: traverse between list to find whole sets of IPv6 addresses
192
193     if (!((ip6[0] == 0) &&
194          (ip6[1] == 0) &&
195          (ip6[2] == 0) &&
196          (ip6[3] == 0) &&
197          (ip6[4] == 0) &&
198          (ip6[5] == 0))) {
199     }
200
201 #endif
202     // <7> set up the ARP filter
203     {
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;
210
211         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
212
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;;
218 #if 0
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);
222 #else
223             prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
224             kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
225
226 //            prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));    // TODO: frog. The pointer is not right.
227
228             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
229             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
230
231             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
232 #endif
233         }
234 #ifdef  CONFIG_IPV6
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));
240
241             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
242             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
243
244             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
245        }
246 #endif
247         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
248
249         rStatus = kalIoctl(prGlueInfo,
250                 wlanoidSetP2pSetNetworkAddress,
251                 (PVOID)prParamNetAddrList,
252                 u4Len,
253                 FALSE,
254                 FALSE,
255                 TRUE,
256                 TRUE,
257                 &u4SetInfoLen);
258
259         if (rStatus != WLAN_STATUS_SUCCESS) {
260             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
261         }
262     }
263 }
264
265
266 static void wlanP2PLateResume(void)
267 {
268     struct net_device *prDev = NULL;
269     P_GLUE_INFO_T prGlueInfo = NULL;
270     UINT_8  ip[4] = { 0 };
271 #ifdef  CONFIG_IPV6
272     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
273 #endif
274
275     printk(KERN_INFO "*********wlanP2PLateResume************\n");
276     if(!wlanExportGlueInfo(&prGlueInfo)) {
277         printk(KERN_INFO "*********p2pLateResume ignored************\n");
278         return;
279     }
280
281     ASSERT(prGlueInfo);
282     // <1> Sanity check and acquire the net_device
283     prDev = prGlueInfo->prP2PInfo->prDevHandler;
284     ASSERT(prDev);
285
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");
291         return;
292     }
293
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]);
298
299 #ifdef  CONFIG_IPV6
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");
305         return;
306     }
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]
314             );
315 #endif
316     // <7> clear the ARP filter
317     {
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;
323
324         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
325
326         prParamNetAddrList->u4AddressCount = 0;
327         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
328
329         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
330         rStatus = kalIoctl(prGlueInfo,
331                 wlanoidSetP2pSetNetworkAddress,
332                 (PVOID)prParamNetAddrList,
333                 u4Len,
334                 FALSE,
335                 FALSE,
336                 TRUE,
337                 TRUE,
338                 &u4SetInfoLen);
339
340         if (rStatus != WLAN_STATUS_SUCCESS) {
341             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
342         }
343     }
344 }
345
346 #if defined(CONFIG_HAS_EARLYSUSPEND)
347 static struct early_suspend mt6620_p2p_early_suspend_desc = {
348     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
349 };
350
351 static void p2p_early_suspend(struct early_suspend *h)
352 {
353     printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
354     wlanP2PEarlySuspend();
355 }
356
357 static void p2p_late_resume(struct early_suspend *h)
358 {
359     printk(KERN_INFO "*********wlanP2P_late_resume************\n");
360     wlanP2PLateResume();
361 }
362 #endif
363
364 /*----------------------------------------------------------------------------*/
365 /*!
366 * \brief
367 *       run p2p init procedure, include register pointer to wlan
368 *                                                     glue register p2p
369 *                                                     set p2p registered flag
370 * \retval 1     Success
371 */
372 /*----------------------------------------------------------------------------*/
373 BOOLEAN
374 p2pLaunch(
375     P_GLUE_INFO_T prGlueInfo
376     )
377 {
378
379     printk("p2p Launch\n");
380
381     if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
382         printk("p2p already registered\n");
383         return FALSE;
384     }
385     else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
386         prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
387
388         printk("Launch success, fgIsP2PRegistered TRUE.\n");
389
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);
393 #endif
394
395         return TRUE;
396     }
397     else {
398         printk("Launch Fail\n");
399     }
400
401     return FALSE;
402 }
403
404
405 VOID
406 p2pSetMode (
407     IN BOOLEAN fgIsAPMOde
408     ) 
409 {
410     if (fgIsAPMOde) {
411         mode = RUNNING_AP_MODE;
412         ifname = AP_MODE_INF_NAME;
413     }
414     else {
415         mode = RUNNING_P2P_MODE;
416         ifname = P2P_MODE_INF_NAME;
417     }
418
419     return;
420 } /* p2pSetMode */
421
422
423 /*----------------------------------------------------------------------------*/
424 /*!
425 * \brief
426 *       run p2p exit procedure, include unregister pointer to wlan
427 *                                                     glue unregister p2p
428 *                                                     set p2p registered flag
429
430 * \retval 1     Success
431 */
432 /*----------------------------------------------------------------------------*/
433 BOOLEAN
434 p2pRemove(
435     P_GLUE_INFO_T prGlueInfo
436     )
437 {
438     if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
439         printk("p2p is not Registered.\n");
440         return FALSE;
441     }
442     else {
443
444 #if defined(CONFIG_HAS_EARLYSUSPEND)
445         glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
446 #endif
447         /*Check p2p fsm is stop or not. If not then stop now*/
448         if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
449             p2pStopImmediate(prGlueInfo);
450         }
451         prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
452         glUnregisterP2P(prGlueInfo);
453         /*p2p is removed successfully*/
454         return TRUE;
455     }
456     return FALSE;
457 }
458
459 #if 0
460 /*----------------------------------------------------------------------------*/
461 /*!
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.
465 *
466 * \retval 0     Success
467 */
468 /*----------------------------------------------------------------------------*/
469 static int initP2P(void)
470 {
471     P_GLUE_INFO_T prGlueInfo;
472
473     /*check interface name validation*/
474     p2pCheckInterfaceName();
475
476     printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
477
478     /*register p2p init & exit function to wlan sub module handler*/
479     wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
480
481     /*if wlan is not start yet, do nothing
482         * p2pLaunch will be called by txthread while wlan start
483         */
484     /*if wlan is not started yet, return FALSE*/
485     if(wlanExportGlueInfo(&prGlueInfo)) {
486         wlanSubModInit(prGlueInfo);
487         return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
488     }
489
490     return 0;
491 } /* end of initP2P() */
492
493
494 /*----------------------------------------------------------------------------*/
495 /*!
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.
499 *
500 * \return (none)
501 */
502 /*----------------------------------------------------------------------------*/
503 //1 Module Leave Point
504 static VOID __exit exitP2P(void)
505 {
506     P_GLUE_INFO_T prGlueInfo;
507
508     printk( KERN_INFO DRV_NAME "ExitP2P\n");
509
510     /*if wlan is not started yet, return FALSE*/
511     if(wlanExportGlueInfo(&prGlueInfo)) {
512         wlanSubModExit(prGlueInfo);
513     }
514     /*UNregister p2p init & exit function to wlan sub module handler*/
515     wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
516 } /* end of exitP2P() */
517 #endif
518