wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931_kk / drv_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 * Copyright (c) 2011 MediaTek Inc.
14 *
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
18 * MediaTek Inc.
19 ********************************************************************************
20 */
21
22 /*******************************************************************************
23 * LEGAL DISCLAIMER
24 *
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
38 *
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
44 *
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
50 * (ICC).
51 ********************************************************************************
52 */
53
54 /*******************************************************************************
55 *                         C O M P I L E R   F L A G S
56 ********************************************************************************
57 */
58
59 /*******************************************************************************
60 *                    E X T E R N A L   R E F E R E N C E S
61 ********************************************************************************
62 */
63
64 #include "precomp.h"
65
66
67 /*******************************************************************************
68 *                              C O N S T A N T S
69 ********************************************************************************
70 */
71
72 #define P2P_MODE_INF_NAME "p2p%d";
73 #define AP_MODE_INF_NAME "wlan%d";  
74
75 //#define MAX_INF_NAME_LEN 15
76 //#define MIN_INF_NAME_LEN 1
77
78 #define RUNNING_P2P_MODE 0
79 #define RUNNING_AP_MODE 1
80
81 /*******************************************************************************
82 *                             D A T A   T Y P E S
83 ********************************************************************************
84 */
85
86 /*******************************************************************************
87 *                            P U B L I C   D A T A
88 ********************************************************************************
89 */
90
91
92
93 /*******************************************************************************
94 *                           P R I V A T E   D A T A
95 ********************************************************************************
96 */
97
98 /*  Get interface name and running mode from module insertion parameter
99 *       Usage: insmod p2p.ko mode=1
100 *       default: interface name is p2p%d
101 *                   running mode is P2P
102 */
103 static PUCHAR ifname = P2P_MODE_INF_NAME;
104 static UINT_16 mode = RUNNING_P2P_MODE;
105
106 /*******************************************************************************
107 *                                 M A C R O S
108 ********************************************************************************
109 */
110
111 /*******************************************************************************
112 *                   F U N C T I O N   D E C L A R A T I O N S
113 ********************************************************************************
114 */
115 #if defined(CONFIG_HAS_EARLYSUSPEND)
116 extern int glRegisterEarlySuspend(
117     struct early_suspend        *prDesc,
118     early_suspend_callback      wlanSuspend,
119     late_resume_callback        wlanResume);
120
121 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
122 #endif
123
124 /*******************************************************************************
125 *                              F U N C T I O N S
126 ********************************************************************************
127 */
128
129
130 /*----------------------------------------------------------------------------*/
131 /*!
132 * \brief    check interface name parameter is valid or not
133 *             if invalid, set ifname to P2P_MODE_INF_NAME
134 *
135 *
136 * \retval
137 */
138 /*----------------------------------------------------------------------------*/
139 VOID
140 p2pCheckInterfaceName(
141     VOID
142     )
143 {
144
145     if(mode) {
146         mode = RUNNING_AP_MODE;
147         ifname = AP_MODE_INF_NAME;
148     }
149 #if 0
150     UINT_32 ifLen = 0;
151
152     if(ifname) {
153         ifLen = strlen(ifname);
154
155         if(ifLen > MAX_INF_NAME_LEN) {
156             ifname[MAX_INF_NAME_LEN] = '\0';
157         }
158         else if( ifLen < MIN_INF_NAME_LEN  ) {
159             ifname = P2P_MODE_INF_NAME;
160         }
161     } else {
162         ifname = P2P_MODE_INF_NAME;
163     }
164 #endif
165 }
166
167
168 extern UINT_8 g_aucBufIpAddr[32];
169
170 static void wlanP2PEarlySuspend(void)
171 {
172     struct net_device *prDev = NULL;
173     P_GLUE_INFO_T prGlueInfo = NULL;
174     UINT_8  ip[4] = { 0 };
175     UINT_32 u4NumIPv4 = 0;
176 #ifdef  CONFIG_IPV6
177     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
178     UINT_32 u4NumIPv6 = 0;
179 #endif
180     UINT_32 i;
181         P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
182
183     printk(KERN_INFO "*********p2pEarlySuspend************\n");
184
185     if(!wlanExportGlueInfo(&prGlueInfo)) {
186         printk(KERN_INFO "*********p2pEarlySuspend ignored************\n");
187         return;
188     }
189
190     ASSERT(prGlueInfo);
191     // <1> Sanity check and acquire the net_device
192     prDev = prGlueInfo->prP2PInfo->prDevHandler;
193     ASSERT(prDev);
194
195     // <3> get the IPv4 address
196     if(!prDev || !(prDev->ip_ptr)||\
197         !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
198         !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
199         printk(KERN_INFO "ip is not avaliable.\n");
200         return;
201     }
202
203     // <4> copy the IPv4 address
204     kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
205     printk(KERN_INFO"ip is %d.%d.%d.%d\n",
206             ip[0],ip[1],ip[2],ip[3]);
207
208    // todo: traverse between list to find whole sets of IPv4 addresses
209     if (!((ip[0] == 0) &&
210          (ip[1] == 0) &&
211          (ip[2] == 0) &&
212          (ip[3] == 0))) {
213         u4NumIPv4++;
214     }
215
216 #ifdef  CONFIG_IPV6
217     // <5> get the IPv6 address
218     if(!prDev || !(prDev->ip6_ptr)||\
219         !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
220         !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
221         printk(KERN_INFO "ipv6 is not avaliable.\n");
222         return;
223     }
224     // <6> copy the IPv6 address
225     kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
226     printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
227             ip6[0],ip6[1],ip6[2],ip6[3],
228             ip6[4],ip6[5],ip6[6],ip6[7],
229             ip6[8],ip6[9],ip6[10],ip6[11],
230             ip6[12],ip6[13],ip6[14],ip6[15]
231             );
232     // todo: traverse between list to find whole sets of IPv6 addresses
233
234     if (!((ip6[0] == 0) &&
235          (ip6[1] == 0) &&
236          (ip6[2] == 0) &&
237          (ip6[3] == 0) &&
238          (ip6[4] == 0) &&
239          (ip6[5] == 0))) {
240     }
241
242 #endif
243     // <7> set up the ARP filter
244     {
245         WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
246         UINT_32 u4SetInfoLen = 0;
247 //        UINT_8 aucBuf[32] = {0};
248         UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
249         P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
250         P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
251
252         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
253
254         prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
255         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
256         for (i = 0; i < u4NumIPv4; i++) {
257             prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
258             prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
259 #if 0
260             kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
261             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
262             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
263 #else
264             prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
265             kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
266
267 //            prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));    // TODO: frog. The pointer is not right.
268
269             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
270             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
271
272             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP);
273 #endif
274         }
275 #ifdef  CONFIG_IPV6
276         for (i = 0; i < u4NumIPv6; i++) {
277             prParamNetAddr->u2AddressLength = 6;;
278             prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
279             kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
280 //            prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
281
282             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr +
283             (UINT_32) (prParamNetAddr->u2AddressLength + OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress)));
284
285             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
286        }
287 #endif
288         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
289
290         rStatus = kalIoctl(prGlueInfo,
291                 wlanoidSetP2pSetNetworkAddress,
292                 (PVOID)prParamNetAddrList,
293                 u4Len,
294                 FALSE,
295                 FALSE,
296                 TRUE,
297                 TRUE,
298                 &u4SetInfoLen);
299
300         if (rStatus != WLAN_STATUS_SUCCESS) {
301             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
302         }
303     }
304 }
305
306
307 static void wlanP2PLateResume(void)
308 {
309     struct net_device *prDev = NULL;
310     P_GLUE_INFO_T prGlueInfo = NULL;
311     UINT_8  ip[4] = { 0 };
312 #ifdef  CONFIG_IPV6
313     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
314 #endif
315
316     printk(KERN_INFO "*********wlanP2PLateResume************\n");
317     if(!wlanExportGlueInfo(&prGlueInfo)) {
318         printk(KERN_INFO "*********p2pLateResume ignored************\n");
319         return;
320     }
321
322     ASSERT(prGlueInfo);
323     // <1> Sanity check and acquire the net_device
324     prDev = prGlueInfo->prP2PInfo->prDevHandler;
325     ASSERT(prDev);
326
327    // <3> get the IPv4 address
328     if(!prDev || !(prDev->ip_ptr)||\
329         !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
330         !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
331         printk(KERN_INFO "ip is not avaliable.\n");
332         return;
333     }
334
335     // <4> copy the IPv4 address
336     kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
337     printk(KERN_INFO"ip is %d.%d.%d.%d\n",
338             ip[0],ip[1],ip[2],ip[3]);
339
340 #ifdef  CONFIG_IPV6
341     // <5> get the IPv6 address
342     if(!prDev || !(prDev->ip6_ptr)||\
343         !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
344         !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
345         printk(KERN_INFO "ipv6 is not avaliable.\n");
346         return;
347     }
348     // <6> copy the IPv6 address
349     kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
350     printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
351             ip6[0],ip6[1],ip6[2],ip6[3],
352             ip6[4],ip6[5],ip6[6],ip6[7],
353             ip6[8],ip6[9],ip6[10],ip6[11],
354             ip6[12],ip6[13],ip6[14],ip6[15]
355             );
356 #endif
357     // <7> clear the ARP filter
358     {
359         WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
360         UINT_32 u4SetInfoLen = 0;
361 //        UINT_8 aucBuf[32] = {0};
362         UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
363         P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
364
365         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
366
367         prParamNetAddrList->u4AddressCount = 0;
368         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
369
370         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
371         rStatus = kalIoctl(prGlueInfo,
372                 wlanoidSetP2pSetNetworkAddress,
373                 (PVOID)prParamNetAddrList,
374                 u4Len,
375                 FALSE,
376                 FALSE,
377                 TRUE,
378                 TRUE,
379                 &u4SetInfoLen);
380
381         if (rStatus != WLAN_STATUS_SUCCESS) {
382             printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus);
383         }
384     }
385 }
386
387 #if defined(CONFIG_HAS_EARLYSUSPEND)
388 static struct early_suspend mt6620_p2p_early_suspend_desc = {
389     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
390 };
391
392 static void p2p_early_suspend(struct early_suspend *h)
393 {
394     printk(KERN_INFO "*********wlanP2P_early_suspend************\n");
395     wlanP2PEarlySuspend();
396 }
397
398 static void p2p_late_resume(struct early_suspend *h)
399 {
400     printk(KERN_INFO "*********wlanP2P_late_resume************\n");
401     wlanP2PLateResume();
402 }
403 #endif
404
405 /*----------------------------------------------------------------------------*/
406 /*!
407 * \brief
408 *       run p2p init procedure, include register pointer to wlan
409 *                                                     glue register p2p
410 *                                                     set p2p registered flag
411 * \retval 1     Success
412 */
413 /*----------------------------------------------------------------------------*/
414 BOOLEAN
415 p2pLaunch(
416     P_GLUE_INFO_T prGlueInfo
417     )
418 {
419
420     printk("p2p Launch\n");
421
422     if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) {
423         printk("p2p already registered\n");
424         return FALSE;
425     }
426     else if(glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) {
427         prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE;
428
429         printk("Launch success, fgIsP2PRegistered TRUE.\n");
430
431 #if defined(CONFIG_HAS_EARLYSUSPEND)
432         /* Here, we register the early suspend and resume callback  */
433         glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc, p2p_early_suspend, p2p_late_resume);
434 #endif
435
436         return TRUE;
437     }
438     else {
439         printk("Launch Fail\n");
440     }
441
442     return FALSE;
443 }
444
445
446 VOID
447 p2pSetMode (
448     IN BOOLEAN fgIsAPMOde
449     ) 
450 {
451     if (fgIsAPMOde) {
452         mode = RUNNING_AP_MODE;
453         ifname = AP_MODE_INF_NAME;
454     }
455     else {
456         mode = RUNNING_P2P_MODE;
457         ifname = P2P_MODE_INF_NAME;
458     }
459
460     return;
461 } /* p2pSetMode */
462
463
464 /*----------------------------------------------------------------------------*/
465 /*!
466 * \brief
467 *       run p2p exit procedure, include unregister pointer to wlan
468 *                                                     glue unregister p2p
469 *                                                     set p2p registered flag
470
471 * \retval 1     Success
472 */
473 /*----------------------------------------------------------------------------*/
474 BOOLEAN
475 p2pRemove(
476     P_GLUE_INFO_T prGlueInfo
477     )
478 {
479     if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
480         printk("p2p is not Registered.\n");
481         return FALSE;
482     }
483     else {
484
485 #if defined(CONFIG_HAS_EARLYSUSPEND)
486         glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc);
487 #endif
488         /*Check p2p fsm is stop or not. If not then stop now*/
489         if(IS_P2P_ACTIVE(prGlueInfo->prAdapter)) {
490             p2pStopImmediate(prGlueInfo);
491         }
492         prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE;
493         glUnregisterP2P(prGlueInfo);
494         /*p2p is removed successfully*/
495         return TRUE;
496     }
497     return FALSE;
498 }
499
500 #if 0
501 /*----------------------------------------------------------------------------*/
502 /*!
503 * \brief Driver entry point when the driver is configured as a Linux Module, and
504 *        is called once at module load time, by the user-level modutils
505 *        application: insmod or modprobe.
506 *
507 * \retval 0     Success
508 */
509 /*----------------------------------------------------------------------------*/
510 static int initP2P(void)
511 {
512     P_GLUE_INFO_T prGlueInfo;
513
514     /*check interface name validation*/
515     p2pCheckInterfaceName();
516
517     printk( KERN_INFO DRV_NAME "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP":"P2P");
518
519     /*register p2p init & exit function to wlan sub module handler*/
520     wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE);
521
522     /*if wlan is not start yet, do nothing
523         * p2pLaunch will be called by txthread while wlan start
524         */
525     /*if wlan is not started yet, return FALSE*/
526     if(wlanExportGlueInfo(&prGlueInfo)) {
527         wlanSubModInit(prGlueInfo);
528         return ( prGlueInfo->prAdapter->fgIsP2PRegistered? 0: -EIO);
529     }
530
531     return 0;
532 } /* end of initP2P() */
533
534
535 /*----------------------------------------------------------------------------*/
536 /*!
537 * \brief Driver exit point when the driver as a Linux Module is removed. Called
538 *        at module unload time, by the user level modutils application: rmmod.
539 *        This is our last chance to clean up after ourselves.
540 *
541 * \return (none)
542 */
543 /*----------------------------------------------------------------------------*/
544 //1 Module Leave Point
545 static VOID __exit exitP2P(void)
546 {
547     P_GLUE_INFO_T prGlueInfo;
548
549     printk( KERN_INFO DRV_NAME "ExitP2P\n");
550
551     /*if wlan is not started yet, return FALSE*/
552     if(wlanExportGlueInfo(&prGlueInfo)) {
553         wlanSubModExit(prGlueInfo);
554     }
555     /*UNregister p2p init & exit function to wlan sub module handler*/
556     wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE);
557 } /* end of exitP2P() */
558 #endif
559