1 /* Copyright Statement:
3 * This software/firmware and related documentation ("MediaTek Software") are
4 * protected under relevant copyright laws. The information contained herein
5 * is confidential and proprietary to MediaTek Inc. and/or its licensors.
6 * Without the prior written permission of MediaTek inc. and/or its licensors,
7 * any reproduction, modification, use or disclosure of MediaTek Software,
8 * and information contained herein, in whole or in part, shall be strictly prohibited.
10 /* MediaTek Inc. (C) 2010. All rights reserved.
12 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
13 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
14 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
15 * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
18 * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
19 * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
20 * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
21 * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
22 * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
23 * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
24 * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
25 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
26 * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
27 * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
28 * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
29 * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
31 * The following software/firmware and/or related documentation ("MediaTek Software")
32 * have been modified by MediaTek Inc. All revisions are subject to any receiver's
33 * applicable license agreements with MediaTek Inc.
37 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/platform.c#1 $
40 /*! \file "platform.c"
41 \brief This file including the protocol layer privacy function.
43 This file provided the macros and functions library support for the
44 protocol layer security setting from wlan_oid.c and for parse.c and
45 rsn.c and nic_privacy.c
49 /*******************************************************************************
50 * Copyright (c) 2007 MediaTek Inc.
52 * All rights reserved. Copying, compilation, modification, distribution
53 * or any other use whatsoever of this material is strictly prohibited
54 * except in accordance with a Software License Agreement with
56 ********************************************************************************
59 /*******************************************************************************
62 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
63 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
64 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
65 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
66 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
67 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
68 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
69 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
70 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
71 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
72 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
73 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
74 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
76 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
77 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
78 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
79 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
80 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
82 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
83 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
84 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
85 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
86 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
88 ********************************************************************************
96 * Fix compiling warning
99 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
100 * 1. eliminaite direct calls to printk in porting layer.
101 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
103 * 10 19 2011 yuche.tsai
104 * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
106 * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926.
108 * 09 13 2011 jeffrey.chang
109 * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection
110 * fix pointer casting
112 * 06 29 2011 george.huang
113 * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
116 * 06 28 2011 george.huang
117 * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
118 * remove un-used code
120 * 05 09 2011 jeffrey.chang
121 * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
122 * support ARP filter through kernel notifier
125 * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
126 * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
128 * 03 18 2011 jeffrey.chang
129 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
130 * remove early suspend functions
132 * 03 03 2011 jeffrey.chang
134 * add the ARP filter callback
136 * 02 15 2011 jeffrey.chang
138 * to support early suspend in android
141 * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 branch
142 * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/...
145 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
146 * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
147 * 2) Remove CNM CH-RECOVER event handling
148 * 3) cfg read/write API renamed with kal prefix for unified naming rules.
151 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
152 * complete implementation of Android NVRAM access
155 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
156 * 1) add NVRAM access API
157 * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
158 * 3) add OID implementation for NVRAM read/write service
162 /*******************************************************************************
163 * C O M P I L E R F L A G S
164 ********************************************************************************
167 /*******************************************************************************
168 * E X T E R N A L R E F E R E N C E S
169 ********************************************************************************
171 #include <linux/version.h>
172 #include <linux/init.h>
173 #include <linux/types.h>
174 #include <linux/module.h>
175 #include <linux/fs.h>
177 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
178 #include <linux/uaccess.h>
184 #if defined(CONFIG_HAS_EARLY_SUSPEND)
185 #include <linux/earlysuspend.h>
190 extern BOOLEAN fgIsUnderEarlierSuspend;
192 /*******************************************************************************
194 ********************************************************************************
196 #define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI"
197 #define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/WIFI_CUSTOM"
200 /*******************************************************************************
202 ********************************************************************************
205 /*******************************************************************************
206 * P U B L I C D A T A
207 ********************************************************************************
210 /*******************************************************************************
211 * P R I V A T E D A T A
212 ********************************************************************************
215 /*******************************************************************************
217 ********************************************************************************
220 /*******************************************************************************
221 * F U N C T I O N D E C L A R A T I O N S
222 ********************************************************************************
225 /*******************************************************************************
227 ********************************************************************************
232 static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
234 UINT_8 ip[4] = { 0 };
235 UINT_32 u4NumIPv4 = 0;
238 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
239 UINT_32 u4NumIPv6 = 0;
241 struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
242 struct net_device *prDev = ifa->ifa_dev->dev;
244 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
245 P_GLUE_INFO_T prGlueInfo = NULL;
248 DBGLOG(REQ, INFO, ("netdev_event: device is empty.\n"));
252 if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
253 DBGLOG(REQ, INFO, ("netdev_event: xxx\n"));
257 if (strncmp(prDev->name, "p2p", 3) == 0) {
258 // because we store the address of prGlueInfo in p2p's private date of net device
259 // *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo;
260 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
262 prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
265 if (prGlueInfo == NULL) {
266 DBGLOG(REQ, INFO, ("netdev_event: prGlueInfo is empty.\n"));
271 if (fgIsUnderEarlierSuspend == false) {
272 DBGLOG(REQ, INFO, ("netdev_event: PARAM_MEDIA_STATE_DISCONNECTED. (%d)\n", prGlueInfo->eParamMediaStateIndicated));
278 // <3> get the IPv4 address
279 if(!prDev || !(prDev->ip_ptr)||\
280 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
281 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
282 DBGLOG(REQ, INFO, ("ip is not avaliable.\n"));
286 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
287 DBGLOG(REQ, INFO, ("ip is %d.%d.%d.%d\n",
288 ip[0],ip[1],ip[2],ip[3]));
290 // todo: traverse between list to find whole sets of IPv4 addresses
291 if (!((ip[0] == 0) &&
300 if(!prDev || !(prDev->ip6_ptr)||\
301 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
302 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
303 printk(KERN_INFO "ipv6 is not avaliable.\n");
307 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
308 printk(KERN_INFO"ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
309 ip6[0],ip6[1],ip6[2],ip6[3],
310 ip6[4],ip6[5],ip6[6],ip6[7],
311 ip6[8],ip6[9],ip6[10],ip6[11],
312 ip6[12],ip6[13],ip6[14],ip6[15]
315 // todo: traverse between list to find whole sets of IPv6 addresses
316 if (!((ip6[0] == 0) &&
326 // here we can compare the dev with other network's netdev to
327 // set the proper arp filter
329 // IMPORTANT: please make sure if the context can sleep, if the context can't sleep
330 // we should schedule a kernel thread to do this for us
332 // <7> set up the ARP filter
334 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
335 UINT_32 u4SetInfoLen = 0;
336 UINT_8 aucBuf[32] = {0};
337 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
338 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)aucBuf;
339 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
343 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
345 prParamNetAddrList->u4AddressCount = u4NumIPv4;
347 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
348 for (i = 0; i < u4NumIPv4; i++) {
349 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
350 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
352 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
353 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
354 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
356 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
357 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
358 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
359 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
364 for (i = 0; i < u4NumIPv6; i++) {
365 prParamNetAddr->u2AddressLength = 6;;
366 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
367 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
368 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
369 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
372 ASSERT(u4Len <= sizeof(aucBuf));
374 DBGLOG(REQ, INFO, ("kalIoctl (0x%x, 0x%x)\n", prGlueInfo, prParamNetAddrList));
376 rStatus = kalIoctl(prGlueInfo,
377 wlanoidSetNetworkAddress,
378 (PVOID)prParamNetAddrList,
386 if (rStatus != WLAN_STATUS_SUCCESS) {
387 DBGLOG(REQ, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
395 static struct notifier_block inetaddr_notifier = {
396 .notifier_call = netdev_event,
399 void wlanRegisterNotifier(void)
401 register_inetaddr_notifier(&inetaddr_notifier);
404 EXPORT_SYMBOL(wlanRegisterNotifier);
406 void wlanUnregisterNotifier(void)
408 unregister_inetaddr_notifier(&inetaddr_notifier);
411 EXPORT_SYMBOL(wlanUnregisterNotifier);
414 #if defined(CONFIG_HAS_EARLYSUSPEND)
417 /*----------------------------------------------------------------------------*/
419 * \brief This function will register platform driver to os
421 * \param[in] wlanSuspend Function pointer to platform suspend function
422 * \param[in] wlanResume Function pointer to platform resume function
424 * \return The result of registering earlysuspend
426 /*----------------------------------------------------------------------------*/
428 int glRegisterEarlySuspend(
429 struct early_suspend *prDesc,
430 early_suspend_callback wlanSuspend,
431 late_resume_callback wlanResume)
435 if(NULL != wlanSuspend)
436 prDesc->suspend = wlanSuspend;
438 DBGLOG(REQ, INFO, ("glRegisterEarlySuspend wlanSuspend ERROR.\n"));
442 if(NULL != wlanResume)
443 prDesc->resume = wlanResume;
445 DBGLOG(REQ, INFO, ("glRegisterEarlySuspend wlanResume ERROR.\n"));
449 register_early_suspend(prDesc);
453 EXPORT_SYMBOL(glRegisterEarlySuspend);
455 /*----------------------------------------------------------------------------*/
457 * \brief This function will un-register platform driver to os
459 * \return The result of un-registering earlysuspend
461 /*----------------------------------------------------------------------------*/
463 int glUnregisterEarlySuspend(struct early_suspend *prDesc)
467 unregister_early_suspend(prDesc);
469 prDesc->suspend = NULL;
470 prDesc->resume = NULL;
475 EXPORT_SYMBOL(glUnregisterEarlySuspend);
477 #endif // !CONFIG_X86
479 /*----------------------------------------------------------------------------*/
481 * \brief Utility function for reading data from files on NVRAM-FS
490 * actual length of data being read
492 /*----------------------------------------------------------------------------*/
500 #if CFG_SUPPORT_NVRAM
504 mm_segment_t old_fs = get_fs();
507 fd = filp_open(filename, O_RDONLY, 0644);
510 DBGLOG(INIT, INFO, ("[MT6620][nvram_read] : failed to open!!\n"));
515 if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) {
516 DBGLOG(INIT, INFO, ("[MT6620][nvram_read] : file can not be read!!\n"));
520 if (fd->f_pos != offset) {
521 if (fd->f_op->llseek) {
522 if(fd->f_op->llseek(fd, offset, 0) != offset) {
523 DBGLOG(INIT, INFO, ("[MT6620][nvram_read] : failed to seek!!\n"));
532 retLen = fd->f_op->read(fd,
539 filp_close(fd, NULL);
545 #else // !CFG_SUPPORT_NVRAM
553 /*----------------------------------------------------------------------------*/
555 * \brief Utility function for writing data to files on NVRAM-FS
563 * actual length of data being written
565 /*----------------------------------------------------------------------------*/
573 #if CFG_SUPPORT_NVRAM
577 mm_segment_t old_fs = get_fs();
580 fd = filp_open(filename, O_WRONLY|O_CREAT, 0644);
583 DBGLOG(INIT, INFO, ("[MT6620][nvram_write] : failed to open!!\n"));
588 if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) {
589 DBGLOG(INIT, INFO, ("[MT6620][nvram_write] : file can not be write!!\n"));
593 if (fd->f_pos != offset) {
594 if (fd->f_op->llseek) {
595 if(fd->f_op->llseek(fd, offset, 0) != offset) {
596 DBGLOG(INIT, INFO, ("[MT6620][nvram_write] : failed to seek!!\n"));
605 retLen = fd->f_op->write(fd,
612 filp_close(fd, NULL);
618 #else // !CFG_SUPPORT_NVRAMS
626 /*----------------------------------------------------------------------------*/
628 * \brief API for reading data on NVRAM
639 /*----------------------------------------------------------------------------*/
642 IN P_GLUE_INFO_T prGlueInfo,
647 if(pu2Data == NULL) {
651 if(nvram_read(WIFI_NVRAM_FILE_NAME,
653 sizeof(unsigned short),
654 u4Offset) != sizeof(unsigned short)) {
663 /*----------------------------------------------------------------------------*/
665 * \brief API for writing data on NVRAM
675 /*----------------------------------------------------------------------------*/
678 IN P_GLUE_INFO_T prGlueInfo,
683 if(nvram_write(WIFI_NVRAM_FILE_NAME,
685 sizeof(unsigned short),
686 u4Offset) != sizeof(unsigned short)) {