| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- /*
- ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1
- */
- /*! \file "platform.c"
- \brief This file including the protocol layer privacy function.
- This file provided the macros and functions library support for the
- protocol layer security setting from wlan_oid.c and for parse.c and
- rsn.c and nic_privacy.c
- */
- /*
- ** Log: platform.c
- *
- * 11 14 2011 cm.chang
- * NULL
- * Fix compiling warning
- *
- * 11 10 2011 cp.wu
- * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
- * 1. eliminaite direct calls to printk in porting layer.
- * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
- *
- * 09 13 2011 jeffrey.chang
- * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection
- * fix the pointer casting
- *
- * 06 29 2011 george.huang
- * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
- * .
- *
- * 06 28 2011 george.huang
- * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6
- * remove un-used code
- *
- * 05 11 2011 jeffrey.chang
- * NULL
- * fix build error
- *
- * 05 09 2011 jeffrey.chang
- * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
- * support ARP filter through kernel notifier
- *
- * 04 08 2011 pat.lu
- * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
- * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver
- *
- * 03 22 2011 pat.lu
- * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
- * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
- *
- * 03 21 2011 cp.wu
- * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
- * improve portability for awareness of early version of linux kernel and wireless extension.
- *
- * 03 18 2011 jeffrey.chang
- * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
- * remove early suspend functions
- *
- * 03 03 2011 jeffrey.chang
- * NULL
- * add the ARP filter callback
- *
- * 02 15 2011 jeffrey.chang
- * NULL
- * to support early suspend in android
- *
- * 02 01 2011 cp.wu
- * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1
- * branch
- * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/...
- *
- * 11 01 2010 cp.wu
- * [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
- * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
- * 2) Remove CNM CH-RECOVER event handling
- * 3) cfg read/write API renamed with kal prefix for unified naming rules.
- *
- * 10 18 2010 cp.wu
- * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver]
- * The mac address is all zero at android
- * complete implementation of Android NVRAM access
- *
- * 10 05 2010 cp.wu
- * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
- * 1) add NVRAM access API
- * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
- * 3) add OID implementation for NVRAM read/write service
- *
- **
- */
- /*******************************************************************************
- * C O M P I L E R F L A G S
- ********************************************************************************
- */
- /*******************************************************************************
- * E X T E R N A L R E F E R E N C E S
- ********************************************************************************
- */
- #include <linux/version.h>
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include "gl_os.h"
- #ifndef CONFIG_X86
- #if defined(CONFIG_HAS_EARLY_SUSPEND)
- #include <linux/earlysuspend.h>
- #endif
- #endif
- /*******************************************************************************
- * C O N S T A N T S
- ********************************************************************************
- */
- #define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI"
- #define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/WIFI_CUSTOM"
- /*******************************************************************************
- * D A T A T Y P E S
- ********************************************************************************
- */
- /*******************************************************************************
- * P U B L I C D A T A
- ********************************************************************************
- */
- /*******************************************************************************
- * P R I V A T E D A T A
- ********************************************************************************
- */
- /*******************************************************************************
- * M A C R O S
- ********************************************************************************
- */
- /*******************************************************************************
- * F U N C T I O N D E C L A R A T I O N S
- ********************************************************************************
- */
- /*******************************************************************************
- * F U N C T I O N S
- ********************************************************************************
- */
- static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
- {
- UINT_8 ip[4] = { 0 };
- UINT_32 u4NumIPv4 = 0;
- /* #ifdef CONFIG_IPV6 */
- #if 0
- UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */
- UINT_32 u4NumIPv6 = 0;
- #endif
- struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
- struct net_device *prDev = ifa->ifa_dev->dev;
- UINT_32 i;
- P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
- P_GLUE_INFO_T prGlueInfo = NULL;
- if (prDev == NULL) {
- DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n");
- return NOTIFY_DONE;
- }
- DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n",
- ifa->ifa_address, notification, prDev->name);
- if (!fgIsUnderSuspend)
- return NOTIFY_DONE;
- if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
- DBGLOG(REQ, WARN, "netdev_event: not our device\n");
- return NOTIFY_DONE;
- }
- #if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */
- {
- /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */
- prGlueInfo->fgIsDad = FALSE;
- }
- #endif
- prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
- if (prGlueInfo == NULL) {
- DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n");
- return NOTIFY_DONE;
- }
- ASSERT(prGlueInfo);
- /* <3> get the IPv4 address */
- if (!prDev || !(prDev->ip_ptr) ||
- !((struct in_device *)(prDev->ip_ptr))->ifa_list ||
- !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) {
- DBGLOG(REQ, INFO, "ip is not available.\n");
- return NOTIFY_DONE;
- }
- kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
- DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
- /* todo: traverse between list to find whole sets of IPv4 addresses */
- if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)))
- u4NumIPv4++;
- /* #ifdef CONFIG_IPV6 */
- #if 0
- if (!prDev || !(prDev->ip6_ptr) ||
- !((struct in_device *)(prDev->ip6_ptr))->ifa_list ||
- !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) {
- DBGLOG(REQ, INFO, "ipv6 is not available.\n");
- return NOTIFY_DONE;
- }
- kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
- DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
- ip6[0], ip6[1], ip6[2], ip6[3],
- ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]);
- /* todo: traverse between list to find whole sets of IPv6 addresses */
- if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0)))
- /* u4NumIPv6++; */
- #endif
- /* here we can compare the dev with other network's netdev to */
- /* set the proper arp filter */
- /* */
- /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */
- /* we should schedule a kernel thread to do this for us */
- /* <7> set up the ARP filter */
- {
- WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
- UINT_32 u4SetInfoLen = 0;
- UINT_8 aucBuf[32] = { 0 };
- UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
- P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf;
- P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
- /* #ifdef CONFIG_IPV6 */
- #if 0
- prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
- #else
- prParamNetAddrList->u4AddressCount = u4NumIPv4;
- #endif
- prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
- for (i = 0; i < u4NumIPv4; i++) {
- prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */
- prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
- #if 0
- kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
- prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip));
- u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
- #else
- prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress;
- kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
- prParamNetAddr =
- (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
- u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
- #endif
- }
- /* #ifdef CONFIG_IPV6 */
- #if 0
- for (i = 0; i < u4NumIPv6; i++) {
- prParamNetAddr->u2AddressLength = 6;
- prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
- kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
- prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6));
- u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
- }
- #endif
- ASSERT(u4Len <= sizeof(aucBuf));
- DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList);
- rStatus = kalIoctl(prGlueInfo,
- wlanoidSetNetworkAddress,
- (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen);
- if (rStatus != WLAN_STATUS_SUCCESS)
- DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus);
- }
- return NOTIFY_DONE;
- }
- /* #if CFG_SUPPORT_HOTSPOT_2_0 */
- #if 0
- static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
- {
- struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
- struct net_device *prDev = ifa->idev->dev;
- P_GLUE_INFO_T prGlueInfo = NULL;
- if (prDev == NULL) {
- DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n");
- return NOTIFY_DONE;
- }
- if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) {
- DBGLOG(REQ, INFO, "net6dev_event: xxx\n");
- return NOTIFY_DONE;
- }
- if (strncmp(prDev->name, "p2p", 3) == 0) {
- /* because we store the address of prGlueInfo in p2p's private date of net device */
- /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */
- prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
- } else { /* wlan0 */
- prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
- }
- if (prGlueInfo == NULL) {
- DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n");
- return NOTIFY_DONE;
- }
- /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */
- prGlueInfo->fgIs6Dad = FALSE;
- return NOTIFY_DONE;
- }
- #endif
- static struct notifier_block inetaddr_notifier = {
- .notifier_call = netdev_event,
- };
- #if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */
- static struct notifier_block inet6addr_notifier = {
- .notifier_call = net6dev_event,
- };
- #endif
- void wlanRegisterNotifier(void)
- {
- register_inetaddr_notifier(&inetaddr_notifier);
- #if CFG_SUPPORT_HOTSPOT_2_0
- /* register_inet6addr_notifier(&inet6addr_notifier); */
- #endif
- }
- /* EXPORT_SYMBOL(wlanRegisterNotifier); */
- void wlanUnregisterNotifier(void)
- {
- unregister_inetaddr_notifier(&inetaddr_notifier);
- #if CFG_SUPPORT_HOTSPOT_2_0
- /* unregister_inetaddr_notifier(&inet6addr_notifier); */
- #endif
- }
- /* EXPORT_SYMBOL(wlanUnregisterNotifier); */
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief Utility function for reading data from files on NVRAM-FS
- *
- * \param[in]
- * filename
- * len
- * offset
- * \param[out]
- * buf
- * \return
- * actual length of data being read
- */
- /*----------------------------------------------------------------------------*/
- static int nvram_read(char *filename, char *buf, ssize_t len, int offset)
- {
- #if CFG_SUPPORT_NVRAM
- struct file *fd;
- int retLen = -1;
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- fd = filp_open(filename, O_RDONLY, 0644);
- if (IS_ERR(fd)) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n");
- return -1;
- }
- do {
- if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n");
- break;
- }
- if (fd->f_pos != offset) {
- if (fd->f_op->llseek) {
- if (fd->f_op->llseek(fd, offset, 0) != offset) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n");
- break;
- }
- } else {
- fd->f_pos = offset;
- }
- }
- retLen = fd->f_op->read(fd, buf, len, &fd->f_pos);
- } while (FALSE);
- filp_close(fd, NULL);
- set_fs(old_fs);
- return retLen;
- #else /* !CFG_SUPPORT_NVRAM */
- return -EIO;
- #endif
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief Utility function for writing data to files on NVRAM-FS
- *
- * \param[in]
- * filename
- * buf
- * len
- * offset
- * \return
- * actual length of data being written
- */
- /*----------------------------------------------------------------------------*/
- static int nvram_write(char *filename, char *buf, ssize_t len, int offset)
- {
- #if CFG_SUPPORT_NVRAM
- struct file *fd;
- int retLen = -1;
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- fd = filp_open(filename, O_WRONLY | O_CREAT, 0644);
- if (IS_ERR(fd)) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n");
- return -1;
- }
- do {
- if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n");
- break;
- }
- /* End of if */
- if (fd->f_pos != offset) {
- if (fd->f_op->llseek) {
- if (fd->f_op->llseek(fd, offset, 0) != offset) {
- DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n");
- break;
- }
- } else {
- fd->f_pos = offset;
- }
- }
- retLen = fd->f_op->write(fd, buf, len, &fd->f_pos);
- } while (FALSE);
- filp_close(fd, NULL);
- set_fs(old_fs);
- return retLen;
- #else /* !CFG_SUPPORT_NVRAMS */
- return -EIO;
- #endif
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief API for reading data on NVRAM
- *
- * \param[in]
- * prGlueInfo
- * u4Offset
- * \param[out]
- * pu2Data
- * \return
- * TRUE
- * FALSE
- */
- /*----------------------------------------------------------------------------*/
- BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data)
- {
- if (pu2Data == NULL)
- return FALSE;
- if (nvram_read(WIFI_NVRAM_FILE_NAME,
- (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
- return FALSE;
- } else {
- return TRUE;
- }
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief API for writing data on NVRAM
- *
- * \param[in]
- * prGlueInfo
- * u4Offset
- * u2Data
- * \return
- * TRUE
- * FALSE
- */
- /*----------------------------------------------------------------------------*/
- BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data)
- {
- if (nvram_write(WIFI_NVRAM_FILE_NAME,
- (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) {
- return FALSE;
- } else {
- return TRUE;
- }
- }
- BOOLEAN kalCfgDataRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset,
- IN UINT_32 u4Len, OUT PUINT_16 pu2Data)
- {
- if (pu2Data == NULL)
- return FALSE;
- if (nvram_read(WIFI_NVRAM_FILE_NAME,
- (char *)pu2Data, u4Len, u4Offset) != u4Len) {
- return FALSE;
- } else {
- return TRUE;
- }
- }
|