2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#3 $
6 \brief This file including the protocol layer privacy function.
8 This file provided the macros and functions library support for the
9 protocol layer security setting from wlan_oid.c and for parse.c and
10 rsn.c and nic_privacy.c
19 ** 09 17 2012 cm.chang
20 ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
21 ** Duplicate source from MT6620 v2.3 driver branch
22 ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
25 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
30 * Fix compiling warning
33 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
34 * 1. eliminaite direct calls to printk in porting layer.
35 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
37 * 09 13 2011 jeffrey.chang
38 * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection
39 * fix the pointer casting
41 * 06 29 2011 george.huang
42 * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
45 * 06 28 2011 george.huang
46 * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
49 * 05 11 2011 jeffrey.chang
53 * 05 09 2011 jeffrey.chang
54 * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
55 * support ARP filter through kernel notifier
58 * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
59 * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile settting for PC Linux driver
62 * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
63 * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
66 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
67 * improve portability for awareness of early version of linux kernel and wireless extension.
69 * 03 18 2011 jeffrey.chang
70 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
71 * remove early suspend functions
73 * 03 03 2011 jeffrey.chang
75 * add the ARP filter callback
77 * 02 15 2011 jeffrey.chang
79 * to support early suspend in android
82 * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 branch
83 * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/...
86 * [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
87 * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
88 * 2) Remove CNM CH-RECOVER event handling
89 * 3) cfg read/write API renamed with kal prefix for unified naming rules.
92 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
93 * complete implementation of Android NVRAM access
96 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
97 * 1) add NVRAM access API
98 * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
99 * 3) add OID implementation for NVRAM read/write service
103 /*******************************************************************************
104 * C O M P I L E R F L A G S
105 ********************************************************************************
108 /*******************************************************************************
109 * E X T E R N A L R E F E R E N C E S
110 ********************************************************************************
112 #include <linux/version.h>
113 #include <linux/init.h>
114 #include <linux/types.h>
115 #include <linux/module.h>
116 #include <linux/fs.h>
118 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
119 #include <linux/uaccess.h>
124 #if CFG_ENABLE_EARLY_SUSPEND
125 #include <linux/earlysuspend.h>
128 /*******************************************************************************
130 ********************************************************************************
132 #define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI"
133 #define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/WIFI_CUSTOM"
136 /*******************************************************************************
138 ********************************************************************************
141 /*******************************************************************************
142 * P U B L I C D A T A
143 ********************************************************************************
146 /*******************************************************************************
147 * P R I V A T E D A T A
148 ********************************************************************************
151 /*******************************************************************************
153 ********************************************************************************
156 /*******************************************************************************
157 * F U N C T I O N D E C L A R A T I O N S
158 ********************************************************************************
161 /*******************************************************************************
163 ********************************************************************************
166 static int netdev_event(struct notifier_block
*nb
, unsigned long notification
, void *ptr
)
168 struct in_ifaddr
*ifa
= (struct in_ifaddr
*)ptr
;
169 struct net_device
*prDev
= ifa
->ifa_dev
->dev
;
170 P_GLUE_INFO_T prGlueInfo
= NULL
;
173 /* DBGLOG(REQ, INFO, ("netdev_event: device is empty.\n")); */
177 if ((strncmp(prDev
->name
, "p2p", 3) != 0) && (strncmp(prDev
->name
, "wlan", 4) != 0)) {
178 /* DBGLOG(REQ, INFO, ("netdev_event: xxx\n")); */
181 #if 0 /* CFG_SUPPORT_PASSPOINT */
183 /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */
184 prGlueInfo
->fgIsDad
= FALSE
;
186 #endif /* CFG_SUPPORT_PASSPOINT */
188 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
189 if (prGlueInfo
== NULL
) {
190 DBGLOG(REQ
, INFO
, ("netdev_event: prGlueInfo is empty.\n"));
194 if (prGlueInfo
->fgIsInSuspendMode
== FALSE
) {
195 /* DBGLOG(REQ, INFO, ("netdev_event: PARAM_MEDIA_STATE_DISCONNECTED. (%d)\n", prGlueInfo->eParamMediaStateIndicated)); */
199 kalSetNetAddressFromInterface(prGlueInfo
, prDev
, TRUE
);
206 #if 0 /* CFG_SUPPORT_PASSPOINT */
207 static int net6dev_event(struct notifier_block
*nb
, unsigned long notification
, void *ptr
)
209 struct inet6_ifaddr
*ifa
= (struct inet6_ifaddr
*)ptr
;
210 struct net_device
*prDev
= ifa
->idev
->dev
;
211 P_GLUE_INFO_T prGlueInfo
= NULL
;
214 DBGLOG(REQ
, INFO
, ("net6dev_event: device is empty.\n"));
218 if ((strncmp(prDev
->name
, "p2p", 3) != 0) && (strncmp(prDev
->name
, "wlan", 4) != 0)) {
219 DBGLOG(REQ
, INFO
, ("net6dev_event: xxx\n"));
223 if (strncmp(prDev
->name
, "p2p", 3) == 0) {
224 /* because we store the address of prGlueInfo in p2p's private date of net device */
225 /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */
226 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(prDev
));
228 prGlueInfo
= (P_GLUE_INFO_T
) netdev_priv(prDev
);
231 if (prGlueInfo
== NULL
) {
232 DBGLOG(REQ
, INFO
, ("netdev_event: prGlueInfo is empty.\n"));
235 /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */
236 prGlueInfo
->fgIs6Dad
= FALSE
;
240 #endif /* CFG_SUPPORT_PASSPOINT */
243 static struct notifier_block inetaddr_notifier
= {
244 .notifier_call
= netdev_event
,
247 #if 0 /* CFG_SUPPORT_PASSPOINT */
248 static struct notifier_block inet6addr_notifier
= {
249 .notifier_call
= net6dev_event
,
251 #endif /* CFG_SUPPORT_PASSPOINT */
254 void wlanRegisterNotifier(void)
256 register_inetaddr_notifier(&inetaddr_notifier
);
257 #if 0 /* CFG_SUPPORT_PASSPOINT */
258 register_inet6addr_notifier(&inet6addr_notifier
);
259 #endif /* CFG_SUPPORT_PASSPOINT */
262 void wlanUnregisterNotifier(void)
264 unregister_inetaddr_notifier(&inetaddr_notifier
);
265 #if 0 /* CFG_SUPPORT_PASSPOINT */
266 unregister_inetaddr_notifier(&inet6addr_notifier
);
267 #endif /* CFG_SUPPORT_PASSPOINT */
270 #if CFG_ENABLE_EARLY_SUSPEND
271 /*----------------------------------------------------------------------------*/
273 * \brief This function will register platform driver to os
275 * \param[in] wlanSuspend Function pointer to platform suspend function
276 * \param[in] wlanResume Function pointer to platform resume function
278 * \return The result of registering earlysuspend
280 /*----------------------------------------------------------------------------*/
282 int glRegisterEarlySuspend(struct early_suspend
*prDesc
,
283 early_suspend_callback wlanSuspend
, late_resume_callback wlanResume
)
287 if (NULL
!= wlanSuspend
)
288 prDesc
->suspend
= wlanSuspend
;
290 DBGLOG(REQ
, INFO
, ("glRegisterEarlySuspend wlanSuspend ERROR.\n"));
294 if (NULL
!= wlanResume
)
295 prDesc
->resume
= wlanResume
;
297 DBGLOG(REQ
, INFO
, ("glRegisterEarlySuspend wlanResume ERROR.\n"));
301 register_early_suspend(prDesc
);
305 /*----------------------------------------------------------------------------*/
307 * \brief This function will un-register platform driver to os
309 * \return The result of un-registering earlysuspend
311 /*----------------------------------------------------------------------------*/
313 int glUnregisterEarlySuspend(struct early_suspend
*prDesc
)
317 unregister_early_suspend(prDesc
);
319 prDesc
->suspend
= NULL
;
320 prDesc
->resume
= NULL
;
326 /*----------------------------------------------------------------------------*/
328 * \brief Utility function for reading data from files on NVRAM-FS
337 * actual length of data being read
339 /*----------------------------------------------------------------------------*/
340 static int nvram_read(char *filename
, char *buf
, ssize_t len
, int offset
)
342 #if CFG_SUPPORT_NVRAM
346 mm_segment_t old_fs
= get_fs();
349 fd
= filp_open(filename
, O_RDONLY
, 0644);
352 DBGLOG(INIT
, INFO
, ("[nvram_read] : failed to open!!\n"));
357 if ((fd
->f_op
== NULL
) || (fd
->f_op
->read
== NULL
)) {
358 DBGLOG(INIT
, INFO
, ("[nvram_read] : file can not be read!!\n"));
362 if (fd
->f_pos
!= offset
) {
363 if (fd
->f_op
->llseek
) {
364 if (fd
->f_op
->llseek(fd
, offset
, 0) != offset
) {
365 DBGLOG(INIT
, INFO
, ("[nvram_read] : failed to seek!!\n"));
373 retLen
= fd
->f_op
->read(fd
, buf
, len
, &fd
->f_pos
);
377 filp_close(fd
, NULL
);
383 #else /* !CFG_SUPPORT_NVRAM */
391 /*----------------------------------------------------------------------------*/
393 * \brief Utility function for writing data to files on NVRAM-FS
401 * actual length of data being written
403 /*----------------------------------------------------------------------------*/
404 static int nvram_write(char *filename
, char *buf
, ssize_t len
, int offset
)
406 #if CFG_SUPPORT_NVRAM
410 mm_segment_t old_fs
= get_fs();
413 fd
= filp_open(filename
, O_WRONLY
| O_CREAT
, 0644);
416 DBGLOG(INIT
, INFO
, ("[nvram_write] : failed to open!!\n"));
421 if ((fd
->f_op
== NULL
) || (fd
->f_op
->write
== NULL
)) {
422 DBGLOG(INIT
, INFO
, ("[nvram_write] : file can not be write!!\n"));
426 if (fd
->f_pos
!= offset
) {
427 if (fd
->f_op
->llseek
) {
428 if (fd
->f_op
->llseek(fd
, offset
, 0) != offset
) {
429 DBGLOG(INIT
, INFO
, ("[nvram_write] : failed to seek!!\n"));
437 retLen
= fd
->f_op
->write(fd
, buf
, len
, &fd
->f_pos
);
441 filp_close(fd
, NULL
);
447 #else /* !CFG_SUPPORT_NVRAMS */
455 /*----------------------------------------------------------------------------*/
457 * \brief API for reading data on NVRAM
468 /*----------------------------------------------------------------------------*/
469 BOOLEAN
kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo
, IN UINT_32 u4Offset
, OUT PUINT_16 pu2Data
)
471 if (pu2Data
== NULL
) {
475 if (nvram_read(WIFI_NVRAM_FILE_NAME
,
477 sizeof(unsigned short), u4Offset
) != sizeof(unsigned short)) {
485 /*----------------------------------------------------------------------------*/
487 * \brief API for writing data on NVRAM
497 /*----------------------------------------------------------------------------*/
498 BOOLEAN
kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo
, UINT_32 u4Offset
, UINT_16 u2Data
)
500 if (nvram_write(WIFI_NVRAM_FILE_NAME
,
502 sizeof(unsigned short), u4Offset
) != sizeof(unsigned short)) {