add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / combo_mt66xx / mt6620 / 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 "wlan%d";   
34
35 //#define MAX_INF_NAME_LEN 15
36 //#define MIN_INF_NAME_LEN 1
37
38 #define RUNNING_P2P_MODE 0
39 #define RUNNING_AP_MODE 1
40
41 /*******************************************************************************
42 *                             D A T A   T Y P E S
43 ********************************************************************************
44 */
45
46 /*******************************************************************************
47 *                            P U B L I C   D A T A
48 ********************************************************************************
49 */
50
51
52
53 /*******************************************************************************
54 *                           P R I V A T E   D A T A
55 ********************************************************************************
56 */
57
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
61 *                   running mode is P2P
62 */
63 static PUCHAR ifname = P2P_MODE_INF_NAME;
64 static UINT_16 mode = RUNNING_P2P_MODE;
65
66 /*******************************************************************************
67 *                                 M A C R O S
68 ********************************************************************************
69 */
70
71 /*******************************************************************************
72 *                   F U N C T I O N   D E C L A R A T I O N S
73 ********************************************************************************
74 */
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);
80
81 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
82 #endif
83
84 /*******************************************************************************
85 *                              F U N C T I O N S
86 ********************************************************************************
87 */
88
89
90 /*----------------------------------------------------------------------------*/
91 /*!
92 * \brief    check interface name parameter is valid or not
93 *             if invalid, set ifname to P2P_MODE_INF_NAME
94 *
95 *
96 * \retval
97 */
98 /*----------------------------------------------------------------------------*/
99 VOID
100 p2pCheckInterfaceName(
101     VOID
102     )
103 {
104
105     if(mode) {
106         mode = RUNNING_AP_MODE;
107         ifname = AP_MODE_INF_NAME;
108     }
109 #if 0
110     UINT_32 ifLen = 0;
111
112     if(ifname) {
113         ifLen = strlen(ifname);
114
115         if(ifLen > MAX_INF_NAME_LEN) {
116             ifname[MAX_INF_NAME_LEN] = '\0';
117         }
118         else if( ifLen < MIN_INF_NAME_LEN  ) {
119             ifname = P2P_MODE_INF_NAME;
120         }
121     } else {
122         ifname = P2P_MODE_INF_NAME;
123     }
124 #endif
125 }
126
127
128 extern UINT_8 g_aucBufIpAddr[32];
129
130
131 static void wlanP2PEarlySuspend(void)
132 {
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
140 #endif
141     UINT_32 u4NumIPv6 = 0;
142     UINT_32 i;
143         P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
144
145     printk(KERN_INFO "*********p2pEarlySuspend************\n");
146
147     if(!wlanExportGlueInfo(&prGlueInfo)) {
148         printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
149         return;
150     }
151
152     ASSERT(prGlueInfo);
153     // <1> Sanity check and acquire the net_device
154     prDev = prGlueInfo->prP2PInfo->prDevHandler;
155     ASSERT(prDev);
156
157     // <3> get the IPv4 address
158             in_dev = in_dev_get(prDev);
159             if (!in_dev)
160                return;
161             
162             rtnl_lock();
163             if(!in_dev->ifa_list ||!in_dev->ifa_list->ifa_local) {
164                    rtnl_unlock();
165                    in_dev_put(in_dev);
166                    DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
167         return;
168     }
169             // <4> copy the IPv4 address
170             kalMemCopy(ip, &(in_dev->ifa_list->ifa_local), sizeof(ip));
171             rtnl_unlock();
172             in_dev_put(in_dev);
173              
174     printk(KERN_INFO"ip is %d.%d.%d.%d\n",
175             ip[0],ip[1],ip[2],ip[3]);
176
177    // todo: traverse between list to find whole sets of IPv4 addresses
178     if (!((ip[0] == 0) &&
179          (ip[1] == 0) &&
180          (ip[2] == 0) &&
181          (ip[3] == 0))) {
182         u4NumIPv4++;
183     }
184
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");
191         return;
192     }
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]
200             );
201     // todo: traverse between list to find whole sets of IPv6 addresses
202
203     if (!((ip6[0] == 0) &&
204          (ip6[1] == 0) &&
205          (ip6[2] == 0) &&
206          (ip6[3] == 0) &&
207          (ip6[4] == 0) &&
208          (ip6[5] == 0))) {
209          u4NumIPv6++;
210     }
211
212 #endif
213     // <7> set up the ARP filter
214     {
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;
221
222         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
223
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;;
229 #if 0
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);
233 #else
234             prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
235             kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
236
237 //            prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));    // TODO: frog. The pointer is not right.
238
239             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
240             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
241
242             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
243 #endif
244         }
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));
251
252             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
253             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
254
255             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
256        }
257 #endif
258         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
259
260         rStatus = kalIoctl(prGlueInfo,
261                 wlanoidSetP2pSetNetworkAddress,
262                 (PVOID)prParamNetAddrList,
263                 u4Len,
264                 FALSE,
265                 FALSE,
266                 TRUE,
267                 TRUE,
268                 &u4SetInfoLen);
269
270         if (rStatus != WLAN_STATUS_SUCCESS) {
271             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
272         }
273     }
274 }
275
276
277 static void wlanP2PLateResume(void)
278 {
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
285 #endif
286
287     printk(KERN_INFO "*********wlanP2PLateResume************\n");
288     if(!wlanExportGlueInfo(&prGlueInfo)) {
289         printk(KERN_INFO "*********p2pLateResume ignored************\n");
290         return;
291     }
292
293     ASSERT(prGlueInfo);
294     // <1> Sanity check and acquire the net_device
295     prDev = prGlueInfo->prP2PInfo->prDevHandler;
296     ASSERT(prDev);
297
298    // <3> get the IPv4 address
299       in_dev = in_dev_get(prDev);
300       if (!in_dev)
301          return;
302       
303       rtnl_lock();
304       if(!in_dev->ifa_list ||!in_dev->ifa_list->ifa_local) {
305              rtnl_unlock();
306              in_dev_put(in_dev);
307              DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
308         return;
309     }
310     // <4> copy the IPv4 address
311       kalMemCopy(ip, &(in_dev->ifa_list->ifa_local), sizeof(ip));
312       rtnl_unlock();
313       in_dev_put(in_dev);           
314      
315     printk(KERN_INFO"ip is %d.%d.%d.%d\n",
316             ip[0],ip[1],ip[2],ip[3]);
317
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");
324         return;
325     }
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]
333             );
334 #endif
335     // <7> clear the ARP filter
336     {
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;
342
343         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
344
345         prParamNetAddrList->u4AddressCount = 0;
346         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
347
348         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
349         rStatus = kalIoctl(prGlueInfo,
350                 wlanoidSetP2pSetNetworkAddress,
351                 (PVOID)prParamNetAddrList,
352                 u4Len,
353                 FALSE,
354                 FALSE,
355                 TRUE,
356                 TRUE,
357                 &u4SetInfoLen);
358
359         if (rStatus != WLAN_STATUS_SUCCESS) {
360             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
361         }
362     }
363 }
364
365 #if defined(CONFIG_HAS_EARLYSUSPEND)
366 static struct early_suspend mt6620_p2p_early_suspend_desc = {
367     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
368 };
369
370 static void p2p_early_suspend(struct early_suspend *h)
371 {
372     printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
373     wlanP2PEarlySuspend();
374 }
375
376 static void p2p_late_resume(struct early_suspend *h)
377 {
378     printk(KERN_INFO "*********wlanP2P_late_resume************\n");
379     wlanP2PLateResume();
380 }
381 #endif
382
383 /*----------------------------------------------------------------------------*/
384 /*!
385 * \brief
386 *       run p2p init procedure, include register pointer to wlan
387 *                                                     glue register p2p
388 *                                                     set p2p registered flag
389 * \retval 1     Success
390 */
391 /*----------------------------------------------------------------------------*/
392 BOOLEAN
393 p2pLaunch(
394     P_GLUE_INFO_T prGlueInfo
395     )
396 {
397
398     printk("p2p Launch\n");
399
400     if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
401         printk("p2p already registered\n");
402         return FALSE;
403     }
404     else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
405         prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
406
407         printk("Launch success, fgIsP2PRegistered TRUE.\n");
408
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);
412 #endif
413
414         return TRUE;
415     }
416     else {
417         printk("Launch Fail\n");
418     }
419
420     return FALSE;
421 }
422
423
424 VOID
425 p2pSetMode (
426     IN BOOLEAN fgIsAPMOde
427     ) 
428 {
429     if (fgIsAPMOde) {
430         mode = RUNNING_AP_MODE;
431         ifname = AP_MODE_INF_NAME;
432     }
433     else {
434         mode = RUNNING_P2P_MODE;
435         ifname = P2P_MODE_INF_NAME;
436     }
437
438     return;
439 } /* p2pSetMode */
440
441
442 /*----------------------------------------------------------------------------*/
443 /*!
444 * \brief
445 *       run p2p exit procedure, include unregister pointer to wlan
446 *                                                     glue unregister p2p
447 *                                                     set p2p registered flag
448
449 * \retval 1     Success
450 */
451 /*----------------------------------------------------------------------------*/
452 BOOLEAN
453 p2pRemove(
454     P_GLUE_INFO_T prGlueInfo
455     )
456 {
457     if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
458         printk("p2p is not Registered.\n");
459         return FALSE;
460     }
461     else {
462
463 #if defined(CONFIG_HAS_EARLYSUSPEND)
464         glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
465 #endif
466         /*Check p2p fsm is stop or not. If not then stop now*/
467         if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
468             p2pStopImmediate(prGlueInfo);
469         }
470         prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
471         glUnregisterP2P(prGlueInfo);
472         /*p2p is removed successfully*/
473         return TRUE;
474     }
475     return FALSE;
476 }
477
478 #if 0
479 /*----------------------------------------------------------------------------*/
480 /*!
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.
484 *
485 * \retval 0     Success
486 */
487 /*----------------------------------------------------------------------------*/
488 static int initP2P(void)
489 {
490     P_GLUE_INFO_T prGlueInfo;
491
492     /*check interface name validation*/
493     p2pCheckInterfaceName();
494
495     printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
496
497     /*register p2p init & exit function to wlan sub module handler*/
498     wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
499
500     /*if wlan is not start yet, do nothing
501         * p2pLaunch will be called by txthread while wlan start
502         */
503     /*if wlan is not started yet, return FALSE*/
504     if(wlanExportGlueInfo(&prGlueInfo)) {
505         wlanSubModInit(prGlueInfo);
506         return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
507     }
508
509     return 0;
510 } /* end of initP2P() */
511
512
513 /*----------------------------------------------------------------------------*/
514 /*!
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.
518 *
519 * \return (none)
520 */
521 /*----------------------------------------------------------------------------*/
522 //1 Module Leave Point
523 static VOID __exit exitP2P(void)
524 {
525     P_GLUE_INFO_T prGlueInfo;
526
527     printk( KERN_INFO DRV_NAME "ExitP2P\n");
528
529     /*if wlan is not started yet, return FALSE*/
530     if(wlanExportGlueInfo(&prGlueInfo)) {
531         wlanSubModExit(prGlueInfo);
532     }
533     /*UNregister p2p init & exit function to wlan sub module handler*/
534     wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
535 } /* end of exitP2P() */
536 #endif
537