summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/nmi_android4.4_driver
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/net/wireless/nmi_android4.4_driver
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/net/wireless/nmi_android4.4_driver')
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/Kconfig83
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/Makefile845
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h55
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsKconfig/Kconfig116
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.libbin0 -> 356008 bytes
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/PublicAPI.doxygen263
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/runDoxygen.bat1
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_ErrorSupport.h84
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Event.h124
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_FileOps.h456
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Log.h43
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Math.h368
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Memory.h330
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_MsgQueue.h134
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_OSWrapper.h133
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Semaphore.h116
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Sleep.h45
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Socket.h95
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_StrUtils.h415
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Thread.h155
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Time.h207
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Timer.h154
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_platform.h207
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/Makefile67
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/include/NMI_platform.h209
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Event.c112
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c539
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Math.c440
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c72
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c213
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c67
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c27
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c188
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c483
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c52
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Time.c167
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c181
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/Makefile87
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h184
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c71
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c233
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c78
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c39
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c482
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c38
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c163
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c51
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/win32/include/NMI_platform.h160
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile138
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile_US53
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/NMI_host_AP.c3522
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/core_configurator/CoreConfigurator.c2330
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/CoreConfigSimulator.c4739
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/FIFO_Buffer.c182
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigSimulator.h20
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigurator.h506
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/FIFO_Buffer.h23
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/NMI_host_AP.h422
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/host_interface.h1341
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/itypes.h59
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/linux_wlan_common.h145
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_type.h34
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan.h351
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_cfg.h33
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_if.h989
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/Makefile177
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/allwinner_run_eval.sh4
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/ap_soft.conf30
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_CfgOperations.h105
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_NetDevice.h304
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/init_deinit_test.sh51
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_load10
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_unload6
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_eval.sh7
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_fpga.sh4
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_CfgOperations.c4503
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_NetDevice.c969
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_mon.c693
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan.c3332
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.c277
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.h14
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.c489
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.h14
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_custom_gpio.c169
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_debugfs.c264
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.c235
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.h56
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_wm8880_gpio.c87
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_driver_interface/host_interface.c8371
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_sdio.c1491
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_spi.c1466
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan.c3131
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan_cfg.c641
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_Tx_Rx.c63
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_tx_Rx_socket.c465
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/Makefile3
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/nmc1000_exported_buf.c79
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/svnrevision.h5
-rwxr-xr-xdrivers/net/wireless/nmi_android4.4_driver/src/verify_fw_version.c141
99 files changed, 51375 insertions, 0 deletions
diff --git a/drivers/net/wireless/nmi_android4.4_driver/Kconfig b/drivers/net/wireless/nmi_android4.4_driver/Kconfig
new file mode 100755
index 00000000..e41d4df7
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/Kconfig
@@ -0,0 +1,83 @@
+config NMC1XXX_WIFI_MODULE
+# depends on AM_WIFI_SD_MMC || SD_MMC && SDIO
+ tristate "Newportmedia NMC1XXX wireless cards support"
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ ---help---
+ This module adds support for wireless adapters based on
+ NewportMedia Inc., NMC1000 chipset.
+
+choice
+ depends on NMC1XXX_WIFI_MODULE
+ prompt "Wi-Fi chipset type"
+ default NMC1000_WIFI_CHIP
+
+ config NMC1000_WIFI_CHIP
+ bool "NMC1000 without bluetooth"
+ config NMC1100_WIFI_CHIP
+ bool "NMC1100 with bluetooth"
+
+endchoice
+
+choice
+ depends on NMC1XXX_WIFI_MODULE
+ prompt "Wi-Fi bus type"
+ default NMC1XXX_USE_SDIO
+
+ config NMC1XXX_USE_SDIO_BUS
+ bool "communication by SDIO"
+# depends on AM_WIFI_SD_MMC || SD_MMC && SDIO
+ config NMC1XXX_USE_SPI_BUS
+ bool "communication by SPI"
+endchoice
+
+choice
+ depends on NMC1XXX_WIFI_MODULE
+ prompt "Memory Allocation"
+ default NMC1XXX_PREALLOCATE_DURING_SYSTEM_BOOT
+
+ config NMC1XXX_PREALLOCATE_DURING_SYSTEM_BOOT
+ bool "Preallocate memory pool during system boot"
+
+ config NMC1XXX_PREALLOCATE_AT_LOADING_DRIVER
+ bool "Preallocate memory at loading driver"
+
+ config NMC1XXX_DYNAMICALLY_ALLOCATE_MEMROY
+ bool "Dynamically allocate memory in real time"
+endchoice
+
+config SDIO_HARD_IRQ
+ depends on NMC1XXX_WIFI_MODULE && NMC1XXX_USE_SDIO
+ bool "SDIO HARD IRQ"
+ default n
+ ---help---
+ hard irq wake up polling process
+
+#config NMC1XXX_WIFI_CONTROL_FUNC
+# bool "Use NMC1XXX_wlan device"
+# depends on NMC1XXX_WIFI_MODULE
+# default n
+# ---help---
+# Use this option to get various parameters from architecture specific
+# NMC1XXX_wlan platform device. Say n if unsure.
+
+config NMC1XXX_HW_OOB_INTR
+ bool "Use out of band interrupt"
+ depends on NMC1XXX_WIFI_MODULE && NMC1XXX_USE_SDIO_BUS
+ default n
+ ---help---
+ Use out of band interrupt for wake on wireless.
+
+#config NMC1XXX_OOB_INTR_ONLY
+# bool "Use out of band interrupt only"
+# depends on NMC1XXX_WIFI_MODULE && NMC1XXX_USE_SDIO_BUS
+# default n
+# ---help---
+# Use out of band interrupt for all interrupts(including SDIO interrupts).
+
+config NMC1XXX_ENABLE_DEBUGFS
+ bool "Export debugfs for NMC1XXX status"
+ depends on NMC1XXX_WIFI_MODULE
+ default n
+ ---help---
+ Export status information via debugfs.
diff --git a/drivers/net/wireless/nmi_android4.4_driver/Makefile b/drivers/net/wireless/nmi_android4.4_driver/Makefile
new file mode 100755
index 00000000..127b59c3
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/Makefile
@@ -0,0 +1,845 @@
+#############################################################################################
+#
+# The supported Target List. ( TARGET_PLATFORM = Core Name + Code Name + Product Name )
+# Input one of the list below in TARGET_PLATFORM.
+# If new target is needed, Add item in the list below and Fill the relative options later.
+#
+# 1. TARGET_AML8726M3_MESON_VI30
+# 2. TARGET_MTK6575M_EAGLE75V1
+# 3. TARGET_ALLWINNER_A10_EVB
+# 4. TARGET_PANDABOARD_ES_EVB
+# 5. TARGET_VIA_WMS8304
+# 6. TARGET_VIA_WM8880
+# 7. TARGET_ALLWINNER_A20
+# 8. TARGET_ALLWINNER_A23
+# 9. TARGET_CLG_CLM9722
+# 10. TARGET_ALLWINNER_A31
+# 11. TARGET_RKXXXX
+#
+#############################################################################################
+
+
+#TARGET_PLATFORM = TARGET_AML8726M3_MESON_VI30
+#TARGET_PLATFORM = TARGET_ALLWINNER_A10_EVB
+#TARGET_PLATFORM = TARGET_PANDABOARD_ES_EVB
+#TARGET_PLATFORM = TARGET_VIA_WMS8304
+TARGET_PLATFORM = TARGET_VIA_WM8880
+#TARGET_PLATFORM = TARGET_CLG_CLM9722
+#TARGET_PLATFORM = TARGET_AMBRELLA
+#TARGET_PLATFORM = TARGET_LINUX_X86
+#TARGET_PLATFORM = TARGET_ALLWINNER_A20
+#TARGET_PLATFORM = TARGET_ALLWINNER_A23
+#TARGET_PLATFORM = TARGET_ALLWINNER_A31
+#TARGET_PLATFORM = TARGET_RKXXXX
+
+#############################################################################################
+# Makefile generated by johnny
+#
+# If you want to use the current Makefile in another platform, modify environment value below.
+# 1. TARGET_PLATFORM
+# 2. NMC1000_SRC_VERSION [define for NMC1000 Driver Version ( This has to be equal to Driver folder and Firmware file name )]
+# NMC1000_FW_VERSION [ Not define by default. But if there is the updated bin additionally, 1,2,3,... ]
+# 3. MODULE_NAME
+# 4. DEBFLAGS
+# 5. bus type
+# 6. Additional Bus type
+# 7. CONFIG_DEBUGFS_ENABLE
+# 8. Host AP
+#############################################################################################
+
+################################################################
+# Amlogic
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_AML8726M3_MESON_VI30)
+
+# 1.
+ TARGET_ARCH = PLAT_AML8726_M3
+
+# 2.
+ NMC1000_SRC_VERSION = 5.1
+
+# 3.
+ MODULE_NAME = nmi_wifi
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ else
+
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+
+################################################################
+# MediaTek
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_MTK6575M_EAGLE75V1)
+
+# 1.
+ TARGET_ARCH = PLAT_MT6575M
+
+# 2.
+ NMC1000_SRC_VERSION = 4.0
+
+# 3.
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# Allwinner (A10 EVB)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_ALLWINNER_A10_EVB)
+
+# 1.
+ TARGET_ARCH = PLAT_ALLWINNER_A10
+
+# 2.
+ NMC1000_SRC_VERSION = 6.2
+ NMC1000_FW_VERSION = 1
+
+# 3.
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ BUS_TYPE = NMI_SDIO
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+ endif
+
+endif
+
+################################################################
+# Allwinner (A20)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_ALLWINNER_A20)
+
+# 1.
+ TARGET_ARCH = PLAT_ALLWINNER_A20
+
+# 2.
+ NMC1000_SRC_VERSION = 9.3
+ PATCHLEVEL = 3
+ NMC1000_FW_VERSION = 0
+
+# 3.
+ MODULE_NAME = nmi_wifi
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ else
+
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# Allwinner (A23)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_ALLWINNER_A23)
+
+# 1.
+ TARGET_ARCH = PLAT_ALLWINNER_A23
+
+# 2.
+ NMC1000_SRC_VERSION = 9.3
+ PATCHLEVEL = 3
+ NMC1000_FW_VERSION = 0
+
+# 3.
+ MODULE_NAME = nmi_wifi
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ else
+
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# Allwinner (A31)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_ALLWINNER_A31)
+
+# 1.
+ TARGET_ARCH = PLAT_ALLWINNER_A31
+
+# 2.
+ NMC1000_SRC_VERSION = 9.3
+ PATCHLEVEL = 6
+ NMC1000_FW_VERSION = 0
+
+# 3.
+ MODULE_NAME = nmi_wifi
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ else
+
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# Pandaboard
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_PANDABOARD_ES_EVB)
+
+# 1.
+ TARGET_ARCH = PLAT_PANDA_ES_OMAP4460
+
+# 2.
+ NMC1000_SRC_VERSION = 7.0
+ #NMC1000_FW_VERSION = 1
+
+# 3.
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ BUS_TYPE = NMI_SDIO
+endif
+
+################################################################
+# VIA WM8801 ( == Masking Name)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_VIA_WMS8304)
+
+# 1.
+ TARGET_ARCH = PLAT_WMS8304
+
+# 2.
+ NMC1000_SRC_VERSION = 6.2
+ #NMC1000_FW_VERSION = 1
+
+# 3.
+ MODULE_NAME = nmc1000
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ #EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# VIA WM8880 ( == Masking Name)
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_VIA_WM8880)
+
+# 1.
+ TARGET_ARCH = PLAT_WM8880
+
+# 2.
+ NMC1000_SRC_VERSION = 9.3
+ PATCHLEVEL = 6
+ NMC1000_FW_VERSION = 0
+
+# 3.
+ MODULE_NAME = nmc1000_android4.4
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ CONFIG_NMC1XXX_USE_SDIO_BUS = y
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ CONFIG_NMC1XXX_HW_OOB_INTR = y
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ #EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# CORELOGIC CLM9722
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_CLG_CLM9722)
+
+# 1.
+ TARGET_ARCH = PLAT_CLM9722
+
+# 2.
+ NMC1000_SRC_VERSION = 7.2
+ PATCHLEVEL = 4
+ NMC1000_FW_VERSION = 3
+
+# 3.
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ #EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+################################################################
+# Rockchip
+################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_RKXXXX)
+
+# 1.
+ TARGET_ARCH = PLAT_RKXXXX
+
+# 2.
+ NMC1000_SRC_VERSION = 9.3
+ PATCHLEVEL = 4
+ NMC1000_FW_VERSION = 0
+
+# 3.
+ MODULE_NAME = nmc1000
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+
+# 4.
+ DEBFLAGS = -O -g
+
+# 5.
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)),y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+# 6.
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)),y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ endif
+
+# 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+
+endif
+
+
+#################################################################
+# AMBRELLA LINUX PLATFORM
+#################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_AMBRELLA)
+ TARGET_ARCH = PLAT_AMBRELLA
+ NMC1000_SRC_VERSION = 7.2
+ PATCHLEVEL = 4
+ NMC1000_FW_VERSION = 3
+
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+ DEBFLAGS = -O -g
+
+ ifeq ($(strip $(CONFIG_NMC1XXX_USE_SDIO_BUS)), y)
+ BUS_TYPE = NMI_SDIO
+ else
+ BUS_TYPE = NMI_SPI
+ endif
+
+ ifeq ($(strip $(CONFIG_NMC1XXX_HW_OOB_INTR)), y)
+ IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ endif
+
+ ifeq ($(strip, $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)), y)
+ EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+endif
+######################################################################################
+
+#################################################################
+# AMBRELLA LINUX PLATFORM
+#################################################################
+ifeq ($(strip $(TARGET_PLATFORM)), TARGET_LINUX_X86)
+ TARGET_ARCH = PLAT_UBUNTU_X86
+ NMC1000_SRC_VERSION = 7.2
+ NMC1000_FW_VERSION = 2
+ MODULE_NAME = nmi_wifi
+ CONFIG_NMC1XXX_WIFI_MODULE=m
+ DEBFLAGS = -O -g
+
+ BUS_TYPE = NMI_SDIO
+
+ #IRQ_MODE = USE_EXT_IRQ_FOR_SDIO
+ #EXTRA_CFLAGS += -DNMC_DEBUGFS
+ endif
+######################################################################################
+
+#_____________________________________________________________________________________
+
+# 1.
+EXTRA_CFLAGS += -D$(TARGET_ARCH)
+
+# 2.
+NMC1000_STA_FW_VERSION = STA_FIRMWARE=\"wifi_firmware$(NMC1000_SRC_VERSION).$(NMC1000_FW_VERSION).bin\"
+NMC1000_AP_FW_VERSION = AP_FIRMWARE=\"wifi_firmware_ap$(NMC1000_SRC_VERSION).$(NMC1000_FW_VERSION).bin\"
+NMC1000_P2P_CONCURRENCY_FIRMWARE = P2P_CONCURRENCY_FIRMWARE=\"wifi_firmware_p2p_concurrency$(NMC1000_SRC_VERSION).$(NMC1000_FW_VERSION).bin\"
+
+#EXTRA_CFLAGS += -D$(NMC1000_STA_FW_VERSION)
+#EXTRA_CFLAGS += -D$(NMC1000_AP_FW_VERSION)
+#EXTRA_CFLAGS += -D$(NMC1000_P2P_CONCURRENCY_FIRMWARE)
+
+EXTRA_CFLAGS += -D__DRIVER_VERSION__=\"$(NMC1000_SRC_VERSION).$(PATCHLEVEL)\"
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 3.2)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 4.0)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 5.0)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 5.1)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 5.2)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+
+ # EXTRA_CFLAGS += -DNMI_AP_EXTERNAL_MLME
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 6.0)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 6.1)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #johnny private debug (default use)
+ #EXTRA_CFLAGS += -DUNUSE_POWER_MGMT
+endif
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 6.2)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #johnny private debug (default use)
+ #EXTRA_CFLAGS += -DUNUSE_POWER_MGMT
+
+ #Host AP
+ #FULLY_HOSTING_AP = Y
+endif #6.2
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 7.0)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ #EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ ifeq ($(strip $(NMC1000_FW_VERSION)), 2)
+ EXTRA_CFLAGS += -DTCP_ACK_FILTER
+ endif
+
+ ifeq ($(strip $(NMC1000_FW_VERSION)), 3)
+ EXTRA_CFLAGS += -DTCP_ACK_FILTER
+ endif
+
+ ifeq ($(strip $(NMC1000_FW_VERSION)), 4)
+ EXTRA_CFLAGS += -DAGING_ALG
+ EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ endif
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #Host AP
+ #FULLY_HOSTING_AP = Y
+
+ #firmware log prints in the host
+ #EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+
+ # to support SoftAP mode
+ EXTRA_CFLAGS += -DNMI_AP_EXTERNAL_MLME
+ EXTRA_CFLAGS += -DSTATIC_MACADDRESS
+endif #7.0
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 7.1)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ #EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #Host AP
+ #FULLY_HOSTING_AP = Y
+
+ #firmware log prints in the host
+ #EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+
+ # to support SoftAP mode
+ EXTRA_CFLAGS += -DNMI_AP_EXTERNAL_MLME
+
+ EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ ifeq ($(strip $(BUS_TYPE)),NMI_SDIO)
+ EXTRA_CFLAGS += -DNMI_SDIO -DNMI_OPTIMIZE_SLEEP_INT
+ endif
+
+ EXTRA_CFLAGS += -DTCP_ACK_FILTER
+ EXTRA_CFLAGS += -DSTATIC_MACADDRESS
+endif #7.1
+
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 7.2)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ #EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #firmware log prints in the host
+ #EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+
+ # to support SoftAP mode
+ #EXTRA_CFLAGS += -DNMI_AP_EXTERNAL_MLME
+
+ ifeq ($(strip $(BUS_TYPE)),NMI_SDIO)
+ EXTRA_CFLAGS += -DNMI_SDIO -DNMI_OPTIMIZE_SLEEP_INT
+ endif
+
+ #EXTRA_CFLAGS += -DTCP_ACK_FILTER
+ EXTRA_CFLAGS += -DAGING_ALG
+ EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ EXTRA_CFLAGS += -DSTATIC_MACADDRESS
+
+ #Host AP (?????)
+ #FULLY_HOSTING_AP = Y
+ #EXTRA_CFLAGS += -DNMI_FULLY_HOSTING_AP
+
+ ifeq ($(strip $(NMC1000_FW_VERSION)),2)
+ # Check boot status
+ EXTRA_CFLAGS += -DCOMPLEMENT_BOOT
+ endif
+
+ ifeq ($(strip $(NMC1000_FW_VERSION)), 3)
+ EXTRA_CFLAGS += -DCOMPLEMENT_BOOT
+ endif
+endif #7.2
+
+
+ifeq ($(findstring 9.,$(NMC1000_SRC_VERSION)), 9.)
+ EXTRA_CFLAGS += -DNMC_ASIC_A0
+ EXTRA_CFLAGS += -DPLL_WORKAROUND
+ EXTRA_CFLAGS += -DCONNECT_DIRECT
+ EXTRA_CFLAGS += -DNMI_PARSE_SCAN_IN_HOST
+ #EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+ #Use external 1.4V VDD_VCO
+ # EXTRA_CFLAGS += -DVCO_14_SUPPLY
+
+ #firmware log prints in the host
+ #EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+
+ # to support SoftAP mode
+ #EXTRA_CFLAGS += -DNMI_AP_EXTERNAL_MLME
+
+ ifeq ($(strip $(BUS_TYPE)),NMI_SDIO)
+ EXTRA_CFLAGS += -DNMI_SDIO -DNMI_OPTIMIZE_SLEEP_INT
+ endif
+
+ #EXTRA_CFLAGS += -DTCP_ACK_FILTER
+ EXTRA_CFLAGS += -DAGING_ALG
+ EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ #Host AP (?????)
+ #FULLY_HOSTING_AP = Y
+ #EXTRA_CFLAGS += -DNMI_FULLY_HOSTING_AP
+
+ #EXTRA_CFLAGS += -DXTAL_24
+ #EXTRA_CFLAGS += -DDISABLE_NMC_UART
+
+ #[[ Add KR Team
+ EXTRA_CFLAGS += -DSTATIC_MACADDRESS
+ EXTRA_CFLAGS += -DCOMPLEMENT_BOOT
+ #EXTRA_CFLAGS += -DFW_VERSION_VERIFICATION
+
+ ifeq ($(strip $(CONFIG_NMC1XXX_PREALLOCATE_DURING_SYSTEM_BOOT)),y)
+ EXTRA_CFLAGS += -DNMC_PREALLOC_AT_BOOT
+ # for rx_buffer
+ EXTRA_CFLAGS += -DMEMORY_STATIC
+ else
+ ifeq ($(strip $(CONFIG_NMC1XXX_PREALLOCATE_AT_LOADING_DRIVER)),y)
+ EXTRA_CFLAGS += -DMEMORY_STATIC
+ EXTRA_CFLAGS += -DNMC_PREALLOC_AT_INSMOD
+ else
+ ifeq ($(strip $(CONFIG_NMC1XXX_DYNAMICALLY_ALLOCATE_MEMROY)),y)
+ EXTRA_CFLAGS += -DNMC_NORMAL_ALLOC
+ endif
+ endif
+ endif
+ #]]
+
+endif #9.X
+
+
+NMC1000_ROOT_PATH = $(src)/src/driver/linux
+NMC1000_SRC_PATH = src/driver/linux
+
+# 3.
+obj-$(CONFIG_NMC1XXX_WIFI_MODULE) += $(MODULE_NAME).o
+
+# 4.
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+# 5.
+EXTRA_CFLAGS += -D$(BUS_TYPE)
+
+# 6.
+ifeq ($(strip $(IRQ_MODE)), USE_EXT_IRQ_FOR_SDIO)
+ EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+endif
+
+OUT_ARCH = ARM-3.0
+
+EXTRA_CFLAGS += -I$(NMC1000_ROOT_PATH)/../../NMI_OsWrapper/include/
+EXTRA_CFLAGS += -I$(NMC1000_ROOT_PATH)/../../
+EXTRA_CFLAGS += -I$(NMC1000_ROOT_PATH)/../include
+EXTRA_CFLAGS += -I$(NMC1000_ROOT_PATH)/../
+EXTRA_CFLAGS += -I$(NMC1000_ROOT_PATH)/include
+EXTRA_CFLAGS += -DNMI_PLATFORM=NMI_LINUXKERNEL
+EXTRA_CFLAGS += -Wno-unused-function
+EXTRA_CFLAGS += -DUSE_WIRELESS
+#EXTRA_CFLAGS += -DNMC1000_SINGLE_TRANSFER
+
+
+#EXTRA_CFLAGS += -L$(NMC1000_ROOT_PATH)/../binary/linux/$(OUT_ARCH) -lNMI_WiFi_Driver
+
+ifneq ($(KERNELRELEASE),)
+
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/NMI_WFI_NetDevice.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/NMI_WFI_CfgOperations.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/linux_wlan.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/linux_mon.o
+
+ # 5.
+ ifeq ($(strip $(BUS_TYPE)),NMI_SDIO)
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/linux_wlan_sdio.o
+ else
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/linux_wlan_spi.o
+ endif
+
+ # 7.
+ ifeq ($(strip $(CONFIG_NMC1XXX_ENABLE_DEBUGFS)),y)
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/nmi_debugfs.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/source/nmi_queue.o
+ endif
+
+ # OS Wrapper #
+ #$(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Time.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../../NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.o
+
+ # NMC1000 Core #
+ #$(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../core_configurator/CoreConfigurator.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../nmi_driver_interface/host_interface.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../core_simulator/FIFO_Buffer.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../nmi_sdio.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../nmi_spi.o
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../nmi_wlan_cfg.o
+ifeq ($(strip $(NMC1000_SRC_VERSION)), 7.2)
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../nmi_wlan.o
+endif
+
+ # 8.
+ ifeq ($(strip $(FULLY_HOSTING_AP)), Y)
+ $(MODULE_NAME)-objs += $(NMC1000_SRC_PATH)/../NMI_host_AP.o
+ endif
+
+else
+
+ CONFIG_NMC1XXX_ENABLE_DEBUGFS = y
+
+
+endif
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h
new file mode 100755
index 00000000..0e723261
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h
@@ -0,0 +1,55 @@
+/*
+ * Automatically generated C config: don't edit
+ * Tue Aug 10 19:52:12 2010
+ */
+
+/* OSes supported */
+#define NMI_WIN32 0
+#define NMI_NU 1
+#define NMI_MTK 2
+#define NMI_LINUX 3
+#define NMI_LINUXKERNEL 4
+/* the current OS */
+//#define NMI_PLATFORM NMI_LINUXKERNEL
+
+
+/* Logs options */
+#define NMI_LOGS_NOTHING 0
+#define NMI_LOGS_WARN 1
+#define NMI_LOGS_WARN_INFO 2
+#define NMI_LOGS_WARN_INFO_DBG 3
+#define NMI_LOGS_WARN_INFO_DBG_FN 4
+#define NMI_LOGS_ALL 5
+
+#define NMI_LOG_VERBOSITY_LEVEL NMI_LOGS_ALL
+
+/* OS features supported */
+
+#define CONFIG_NMI_THREAD_FEATURE 1
+//#define CONFIG_NMI_THREAD_SUSPEND_CONTROL 1
+//#define CONFIG_NMI_THREAD_STRICT_PRIORITY 1
+#define CONFIG_NMI_SEMAPHORE_FEATURE 1
+//#define CONFIG_NMI_SEMAPHORE_TIMEOUT 1
+#define CONFIG_NMI_SLEEP_FEATURE 1
+#define CONFIG_NMI_SLEEP_HI_RES 1
+#define CONFIG_NMI_TIMER_FEATURE 1
+//#define CONFIG_NMI_TIMER_PERIODIC 1
+#define CONFIG_NMI_MEMORY_FEATURE 1
+//#define CONFIG_NMI_MEMORY_POOLS 1
+//#define CONFIG_NMI_MEMORY_DEBUG 1
+//#define CONFIG_NMI_ASSERTION_SUPPORT 1
+#define CONFIG_NMI_STRING_UTILS 1
+#define CONFIG_NMI_MSG_QUEUE_FEATURE
+//#define CONFIG_NMI_MSG_QUEUE_IPC_NAME
+//#define CONFIG_NMI_MSG_QUEUE_TIMEOUT
+//#define CONFIG_NMI_FILE_OPERATIONS_FEATURE
+//#define CONFIG_NMI_FILE_OPERATIONS_STRING_API
+//#define CONFIG_NMI_FILE_OPERATIONS_PATH_API
+#define CONFIG_NMI_TIME_FEATURE
+//#define CONFIG_NMI_EVENT_FEATURE
+//#define CONFIG_NMI_EVENT_TIMEOUT
+//#define CONFIG_NMI_SOCKET_FEATURE
+//#define CONFIG_NMI_MATH_OPERATIONS_FEATURE
+//#define CONFIG_NMI_EXTENDED_FILE_OPERATIONS
+//#define CONFIG_NMI_EXTENDED_STRING_OPERATIONS
+//#define CONFIG_NMI_EXTENDED_TIME_OPERATIONS
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsKconfig/Kconfig b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsKconfig/Kconfig
new file mode 100755
index 00000000..9da064d8
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/OsKconfig/Kconfig
@@ -0,0 +1,116 @@
+
+menu "THREADS"
+
+config NMI_THREAD_FEATURE
+ boolean "Enable Using Threads"
+
+config NMI_THREAD_SUSPEND_CONTROL
+ boolean "Enable Suspending Thread"
+ depends on NMI_THREAD_FEATURE
+
+config NMI_THREAD_STRICT_PRIORITY
+ boolean "Enable Setting Thread Priority"
+ depends on NMI_THREAD_FEATURE
+
+endmenu
+
+menu "SEMAPHORES"
+
+config NMI_SEMAPHORE_FEATURE
+ boolean "Enable Using Semaphores"
+
+config NMI_SEMAPHORE_TIMEOUT
+ boolean "Enable Semaphore Timeout"
+ depends on NMI_SEMAPHORE_FEATURE
+
+endmenu
+
+menu "SLEEP"
+
+config NMI_SLEEP_FEATURE
+ boolean "Enable Using Sleep"
+
+config NMI_SLEEP_HI_RES
+ boolean "Enable High Resolution Sleep"
+ depends on NMI_SLEEP_FEATURE
+
+endmenu
+
+menu "TIMER"
+
+config NMI_TIMER_FEATURE
+ boolean "Enable Using Timer"
+
+config NMI_TIMER_PERIODIC
+ boolean "Enable periodic Timer support"
+ depends on NMI_TIMER_FEATURE
+
+endmenu
+
+menu "MEMORY"
+
+config NMI_MEMORY_FEATURE
+ boolean "Enable dynamic memory management"
+
+config NMI_MEMORY_POOLS
+ boolean "Enable memory manager pools"
+ depends on NMI_MEMORY_FEATURE
+
+config NMI_MEMORY_DEBUG
+ boolean "Enable memory debugging and tracing (could be heavy wieght)"
+ depends on NMI_MEMORY_FEATURE
+
+endmenu
+
+menu "ASSERSIONS"
+
+config NMI_ASSERTION_SUPPORT
+ boolean "Enable assertions"
+
+endmenu
+
+menu "Utilities"
+
+config NMI_STRING_UTILS
+ boolean "Enable String standard utilities (usually found in string.h)"
+
+endmenu
+
+menu "Message Queue"
+
+config NMI_MSG_QUEUE_FEATURE
+ boolean "Enable Message Queues"
+
+config NMI_MSG_QUEUE_IPC_NAME
+ boolean "Enable IPC communications via named message queues"
+ depends on NMI_MSG_QUEUE_FEATURE
+
+config NMI_MSG_QUEUE_TIMEOUT
+ boolean "Enable Message Queue timeout"
+ depends on NMI_MSG_QUEUE_FEATURE
+
+endmenu
+
+menu "File operations"
+
+config NMI_FILE_OPERATIONS_FEATURE
+ boolean "Enable File operations"
+
+config NMI_FILE_OPERATIONS_STRING_API
+ boolean "Enable API to read/write strings to files"
+ depends on NMI_FILE_OPERATIONS_FEATURE
+
+endmenu
+
+menu "Events"
+
+config NMI_EVENT_FEATURE
+ boolean "Enable Event objects"
+
+config NMI_EVENT_TIMEOUT
+ boolean "Enable Event timeout"
+ depends on NMI_EVENT_FEATURE
+
+endmenu
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib
new file mode 100755
index 00000000..f76d5bfd
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib
Binary files differ
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/PublicAPI.doxygen b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/PublicAPI.doxygen
new file mode 100755
index 00000000..7f92699e
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/PublicAPI.doxygen
@@ -0,0 +1,263 @@
+# Doxyfile 1.5.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = NMI_OsWrapper
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH = "C:/Program Files/Common Files/SYSTEM/MSMAPI/1033/"
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 8
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = YES
+OPTIMIZE_OUTPUT_JAVA = NO
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE = PublicAPI.log
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ../include
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = PublicAPI_html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE = OsWrapperAPI.tag
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/runDoxygen.bat b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/runDoxygen.bat
new file mode 100755
index 00000000..ed03d6b2
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/doc/runDoxygen.bat
@@ -0,0 +1 @@
+doxygen PublicAPI.doxygen \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_ErrorSupport.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_ErrorSupport.h
new file mode 100755
index 00000000..7924e4e2
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_ErrorSupport.h
@@ -0,0 +1,84 @@
+#ifndef __NMI_ERRORSUPPORT_H__
+#define __NMI_ERRORSUPPORT_H__
+
+/*!
+* @file NMI_ErrorSupport.h
+* @brief Error reporting and handling support
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+/* Psitive Numbers to indicate sucess with special status */
+#define NMI_ALREADY_EXSIT +100 /** The requested object already exists */
+
+/* Generic success will return 0 */
+#define NMI_SUCCESS 0 /** Generic success */
+
+/* Negative numbers to indicate failures */
+#define NMI_FAIL -100 /** Generic Fail */
+#define NMI_BUSY -101 /** Busy with another operation*/
+#define NMI_INVALID_ARGUMENT -102 /** A given argument is invalid*/
+#define NMI_INVALID_STATE -103 /** An API request would violate the Driver state machine (i.e. to start PID while not camped)*/
+#define NMI_BUFFER_OVERFLOW -104 /** In copy operations if the copied data is larger than the allocated buffer*/
+#define NMI_NULL_PTR -105 /** null pointer is passed or used */
+#define NMI_EMPTY -107
+#define NMI_FULL -108
+#define NMI_TIMEOUT -109
+#define NMI_CANCELED -110 /** The required operation have been canceled by the user*/
+#define NMI_INVALID_FILE -112 /** The Loaded file is corruped or having an invalid format */
+#define NMI_NOT_FOUND -113 /** Cant find the file to load */
+#define NMI_NO_MEM -114
+#define NMI_UNSUPPORTED_VERSION -115
+#define NMI_FILE_EOF -116
+
+
+/* Error type */
+typedef NMI_Sint32 NMI_ErrNo;
+
+#define NMI_IS_ERR(__status__) (__status__ < NMI_SUCCESS)
+
+#define NMI_ERRORCHECK(__status__) do{\
+ if(NMI_IS_ERR(__status__))\
+ {\
+ NMI_ERROR("NMI_ERRORCHECK(%d)\n", __status__);\
+ goto ERRORHANDLER;\
+ }\
+}while(0)
+
+#define NMI_ERRORREPORT(__status__, __err__) do{\
+ NMI_ERROR("NMI_ERRORREPORT(%d)\n", __err__);\
+ __status__ = __err__;\
+ goto ERRORHANDLER;\
+}while(0)
+
+#define NMI_NULLCHECK(__status__, __ptr__) do{\
+ if(__ptr__ == NMI_NULL)\
+ {\
+ NMI_ERRORREPORT(__status__, NMI_NULL_PTR);\
+ }\
+}while(0)
+
+#define NMI_CATCH(__status__) \
+ERRORHANDLER :\
+if(NMI_IS_ERR(__status__)) \
+
+#ifdef CONFIG_NMI_ASSERTION_SUPPORT
+
+/**
+ * @brief prints a diagnostic message and aborts the program
+ * @param[in] pcExpression The expression that triggered the assertion
+ * @param[in] pcFileName The name of the current source file.
+ * @param[in] u32LineNumber The line number in the current source file.
+ * @warning DO NOT CALL DIRECTLY. USE EQUIVALENT MACRO FUNCTION INSTEAD.
+ */
+void NMI_assert_INTERNAL(NMI_Char* pcExpression, NMI_Char* pcFileName, NMI_Uint32 u32LineNumber);
+
+#define NMI_assert(__expression__) (void)(!!(__expression__) || (NMI_assert_INTERNAL((#__expression__), __NMI_FILE__, __NMI_LINE__), 0))
+
+#else
+#define NMI_assert(__expression__) ((void)0)
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Event.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Event.h
new file mode 100755
index 00000000..0d38f5da
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Event.h
@@ -0,0 +1,124 @@
+#ifndef __NMI_EVENT_H__
+#define __NMI_EVENT_H__
+
+/*!
+* @file NMI_Event.h
+* @brief Event OS wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Oct 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_EVENT_FEATURE
+#error the feature CONFIG_NMI_EVENT_FEATURE must be supported to include this file
+#endif
+
+
+/*!
+* @struct tstrNMI_TimerAttrs
+* @brief Timer API options
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /* a dummy member to avoid compiler errors*/
+ NMI_Uint8 dummy;
+
+ #ifdef CONFIG_NMI_EVENT_TIMEOUT
+ /*!<
+ Timeout for use with NMI_EventWait, 0 to return immediately and
+ NMI_OS_INFINITY to wait forever. default is NMI_OS_INFINITY
+ */
+ NMI_Uint32 u32TimeOut;
+ #endif
+
+}tstrNMI_EventAttrs;
+
+/*!
+* @brief Fills the NMI_TimerAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+static void NMI_EventFillDefault(tstrNMI_EventAttrs* pstrAttrs)
+{
+ #ifdef CONFIG_NMI_EVENT_TIMEOUT
+ pstrAttrs->u32TimeOut = NMI_OS_INFINITY;
+ #endif
+}
+
+/*!
+* @brief Creates a new Event
+* @details the Event is an object that allows a thread to wait until an external
+ event occuers, Event objects have 2 states, either TRIGGERED or
+ UNTRIGGERED
+* @param[out] pHandle handle to the newly created event object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_EventAttrs
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventCreate(NMI_EventHandle* pHandle, tstrNMI_EventAttrs* pstrAttrs);
+
+
+/*!
+* @brief Destroys a given event
+* @details This will destroy a given event freeing any resources used by it
+ if there are any thread blocked by the NMI_EventWait call the the
+ behaviour is undefined
+* @param[in] pHandle handle to the event object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_EventAttrs
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventDestroy(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs);
+
+/*!
+* @brief Triggers a given event
+* @details This function will set the given event into the TRIGGERED state,
+ if the event is already in TRIGGERED, this function will have no
+ effect
+* @param[in] pHandle handle to the event object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_EventAttrs
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventTrigger(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs);
+
+
+/*!
+* @brief waits until a given event is triggered
+* @details This function will block the calling thread until the event becomes
+ in the TRIGGERED state. the call will retun the event into the
+ UNTRIGGERED state upon completion
+ if multible threads are waiting on the same event at the same time,
+ behaviour is undefined
+* @param[in] pHandle handle to the event object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_EventAttrs
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventWait(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs);
+
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_FileOps.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_FileOps.h
new file mode 100755
index 00000000..42f0c8cd
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_FileOps.h
@@ -0,0 +1,456 @@
+#ifndef __NMI_FILEOPS_H__
+#define __NMI_FILEOPS_H__
+
+/*!
+* @file FileOps.h
+* @brief File Operations OS wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 31 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_FILE_OPERATIONS_FEATURE
+#error the feature CONFIG_NMI_FILE_OPS_FEATURE must be supported to include this file
+#endif
+
+
+typedef enum{
+ NMI_FILE_READ_ONLY,
+ NMI_FILE_READ_WRITE_EXISTING,
+ NMI_FILE_READ_WRITE_NEW
+}tenuNMI_AccessMode;
+
+typedef enum{
+ NMI_SEEK_FROM_START,
+ NMI_SEEK_FROM_END,
+ NMI_SEEK_FROM_CURRENT
+}tenuNMI_SeekOrigin;
+
+/*!
+* @struct tstrNMI_FileOpsAttrs
+* @brief Message Queue API options
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /*!< access mode of the file, default is READ_WRITE_EXISTING */
+ tenuNMI_AccessMode enuAccess;
+
+ /*!< origin for seeking operations, default is NMI_FILE_SEEK_CUR */
+ tenuNMI_SeekOrigin enuSeekOrigin;
+
+}tstrNMI_FileOpsAttrs;
+
+/*!
+* @brief Fills the MsgQueueAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+static void NMI_FileOpsFillDefault(tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ pstrAttrs->enuAccess = NMI_FILE_READ_WRITE_EXISTING;
+ pstrAttrs->enuSeekOrigin = NMI_SEEK_FROM_CURRENT;
+}
+
+
+/**
+* @brief Opens a file
+* @details Opens a file, possibly creating a new file if write enabled and
+ pstrAttrs->bCreate is set to true
+* @param[in,out] pHandle Handle to the opened file
+* @param[in] pcPath path to the File
+* @param[in] pstrAttrs Optional attributes, NULL for defaults. bCreate will
+ create the file if does not exit, enuAccess will control access
+ mode
+* @return Error code indicating success/failure
+* @note Original Standard Function:
+ FILE *fopen( const char *filename, const char *mode );
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_fopen(NMI_FileHandle* pHandle, const NMI_Char* pcPath,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Closes a file.
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @note Original Standard Function: int fclose( FILE *stream );
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+ */
+NMI_ErrNo NMI_fclose(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Reads data from a file.
+ * @param[in] pHandle Handle to the file object
+ * @param[out] pu8Buffer Storage location for data
+ * @param[in] u32Size Number of bytes to be read
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Returns the number of bytes actually read, which may be less
+ than count if an error occurs or if the end of the file is
+ encountered before reaching count.
+ Use the NMI_feof function to distinguish a read error from an
+ end-of-file condition.
+ If size or count is 0, NMI_fread returns 0 and the buffer
+ contents are unchanged.
+ * @note Original Standard Function:
+ size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_fread(NMI_FileHandle* pHandle, NMI_Uint8* pu8Buffer,
+ NMI_Uint32 u32Size, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Writes data to a FILE.
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pu8Buffer Storage location for data
+ * @param[in] u32Size Number of bytes to be write
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Returns the number of full items actually written, which may be
+ less than count if an error occurs
+ Also, if an error occurs, the file-position indicator cannot be
+ determined.
+ * @note Original Standard Function:
+ size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_fwrite(NMI_FileHandle* pHandle, NMI_Uint8* pu8Buffer,
+ NMI_Uint32 u32Size, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Tests for end-of-file
+ * @param[in] pHandle Handle to the file object
+ * @retval NMI_FALSE if the current position is not end of file
+ * @retval NMI_TRUE after the first read operation that attempts to read past
+ the end of the file.
+ * @note Original Standard Function: int feof( FILE *stream );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Bool NMI_feof(NMI_FileHandle* pHandle);
+
+/**
+ * @brief Moves the file pointer to a specified location.
+ * @param[in] pHandle Handle to the file object
+ * @param[in] s32Offset Number of bytes to move, origin of seeking depends on
+ pstrAttrs->enuSeekOrigin, if pstrAttrs is NULL then origin is the
+ current position at the file
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ enuSeekOrigin defines the origin of seek operations
+ * @return Error code indicating success/failure
+ * @note Original Standard Function:
+ int fseek( FILE *stream, long offset, int origin );
+ */
+NMI_ErrNo NMI_fseek(NMI_FileHandle* pHandle, NMI_Sint32 s32Offset,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Gets the current position of a file pointer.
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Returns the current file position. Or NMI_FAIL on error.
+ * @note Original Standard Function: long ftell( FILE *stream );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_ftell(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+
+/**
+ * @brief Flushes the file, writing all data that may be in buffers
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @note Original Standard Function: int fflush( FILE *stream );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fflush(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+
+
+/**
+ * @brief Gets the size of the file.
+ * @param[in] pHandle Handle to the file object
+ * @param[out] pu32Size returned size of file in question
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @note
+ * @author remil
+ * @date 25 Oct 2010
+ * @version 2.0
+ */
+NMI_ErrNo NMI_FileSize(NMI_FileHandle* pstrFileHandle, NMI_Uint32* pu32Size,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+
+
+#ifdef CONFIG_NMI_EXTENDED_FILE_OPERATIONS
+/**
+ * @brief Returns the character currently pointed by the internal file position
+ * indicator of the specified stream.
+ * The internal file position indicator is then advanced by one
+ * character to point to the next character.
+ * @param[in] NMI_FileHandle* pHandle
+ * @return Returns the character currently pointed by the internal file position
+ * @note Original Standard Function: int getc
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_Sint32 NMI_getc(NMI_FileHandle* pHandle);
+
+
+/**
+ * @brief pushes the byte specified by c (converted to an unsigned char)
+ * back onto the input stream pointed to by stream.
+ * @param[in] NMI_Sint32 c
+ * @param[in] NMI_FileHandle* pHandle
+ * @return returns the byte pushed back after conversion. Otherwise it returns EOF.
+ * @note Original Standard Function: ungetc
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_Sint32 NMI_ungetc(NMI_Sint32 c,
+ NMI_FileHandle* pHandle);
+
+
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_freopen(NMI_FileHandle* pHandle, const NMI_Char* pcPath,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+* @brief Translates character file open mode to the appropriate Enum Value
+* @details
+* @param[in] const NMI_Char* cpMode
+* @return tenuNMI_AccessMode
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+tenuNMI_AccessMode NMI_resolveFileMode(const NMI_Char* cpMode);
+
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_rename(const NMI_Char *old_filename, const NMI_Char *new_filename);
+
+NMI_ErrNo NMI_setbuf(NMI_FileHandle *pHandle, NMI_Char* buffer);
+
+
+NMI_ErrNo NMI_setvbuf(NMI_FileHandle *pHandle,
+ NMI_Char* buffer,
+ NMI_Sint32 mode,
+ NMI_Uint32 size);
+
+/*
+*Creates a temporary file in binary update mode (wb+).
+*The tempfile is removed when the program terminates or the stream is closed.
+*On success a pointer to a file stream is returned. On error a null pointer is returned.
+*/
+NMI_ErrNo NMI_tmpfile(NMI_FileHandle *pHandle);
+
+
+/*
+ * Reads a line from the specified stream and stores it into the string pointed to by str.
+ * It stops when either (n-1) characters are read,
+ * the newline character is read, or the end-of-file is reached,
+ * whichever comes first. The newline character is copied to the string.
+ * A null character is appended to the end of the string.
+ * On success a pointer to the string is returned. On error a null pointer is returned.
+ * If the end-of-file occurs before any characters have been read, the string remains unchanged.
+*/
+
+//NMI_Char* NMI_fgets(NMI_Char* str, NMI_Sint32 n, NMI_FileHandle stream);
+
+
+/**
+* @brief Clears the end-of-file and error indicators for the given stream.
+* @details As long as the error indicator is set,
+ all stream operations will return an error until NMI_clearerr is called.
+* @param[in] NMI_FileHandle* pHandle
+* @return N/A
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+void NMI_clearerr(NMI_FileHandle* pHandle);
+
+
+/**
+* @brief Tests the error indicator for the given stream.
+* @details If the error indicator is set, then it returns NMI_FAIL.
+ If the error indicator is not set, then it returns NMI_SUCCESS.
+* @param[in] NMI_FileHandle* pHandle
+* @return NMI_ErrNo
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ferror(NMI_FileHandle* pHandle);
+
+/**
+* @brief Generates and returns a valid temporary filename which does not exist.
+* @details If the argument str is a null pointer, then the function returns
+ a pointer to a valid filename.
+ If the argument str is a valid pointer to an array,
+ then the filename is written to the array and a pointer to the same array
+ is returned.The filename may be up to L_tmpnam characters long.
+* @param[in] NMI_Char* str
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_tmpnam(NMI_Char* str);
+
+
+#endif
+
+
+#ifdef CONFIG_NMI_FILE_OPERATIONS_STRING_API
+
+/**
+ * @brief Reads a line.
+ * @param[in] pHandle Handle to the file object
+ * @param[out] pcBuffer Storage location for data
+ * @param[in] u32Maxsize Maximum number of data to be read including NULL terminator
+ * @return Error code indicating success/failure
+ * @retval NMI_FILE_EOF If the End-of-File is encountered, no characters
+ have been read and the contents of buffer remain unchanged
+ * @retval NMI_FAIL If an error occurs, no characters
+ have been read and the contents of buffer remain unchanged
+ * @note Original Standard Function:
+ char *fgets(char *s,int n,FILE *stream);
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fgets(NMI_FileHandle* pHandle, NMI_Char* pcBuffer
+ , NMI_Uint32 u32Maxsize);
+
+/**
+ * @brief Prints formatted data to a stream
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pcFormat Format-control string
+ * @param[in] ... Optional arguments
+ * @return Error code indicating success/failure
+ * @note Original Standard Function:
+ int fprintf( FILE *stream, const char *format, ... );
+ */
+NMI_ErrNo NMI_fprintf(NMI_FileHandle* pHandle, const NMI_Char* pcFormat, ...);
+
+/**
+ * @brief Writes formatted output using a pointer to a list of arguments
+ * @param[in] pHandle Handle to the file object
+ * @param[in] pcFormat Format specification
+ * @param[in] argptr Pointer to list of arguments
+ * @return Error code indicating success/failure
+ * @note riginal Standard Function:
+ int vfprintf( FILE *stream, const char *format, va_list argptr );
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_vfprintf(NMI_FileHandle* pHandle, const NMI_Char* pcFormat,
+ va_list argptr);
+
+#endif
+
+#ifdef CONFIG_NMI_FILE_OPERATIONS_PATH_API
+
+/**
+ * @brief Renames/Moves a file or directory
+ * @param[in] pcOldPath the old path
+ * @param[in] pcNewPath the new path
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @note if there is a file or folder exsiting in the new path, the
+ * operation fails
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 2.0
+ */
+NMI_ErrNo NMI_PathMove(NMI_Char* pcOldPath, NMI_Char* pcNewPath,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Checks for the path exsitance
+ * @details Checks for the path exsitance, the path could be either a file or
+ a directory, to test differentiate between files/directories
+ send a non-null poiter to the argument pbIsDirectory
+ * @param[in] pcPath path of the examined file/directory
+ * @param[out] pbIsDirectory set to NMI_TRUE if the path is directory, optional
+ and could be NMI_NULL
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return NMI_TRUE if path exsits, NMI_FALSE if does not exist
+ * @note if there is a file or folder exsiting in the new path, the
+ * operation fails
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 2.0
+ */
+NMI_Bool NMI_PathExsits(NMI_Char* pcPath, NMI_Bool* pbIsDirectory,
+ tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief Deletes the given path
+ * @details Deletes the given path, wheather it is a file or a directory
+ * if it is a directory that contains other files and diretories,
+ * they will be recusively deleted
+ * @param[in] pcPath path to the File
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @note if the path does not exist, the function returns an error
+ * @author mabubakr, syounan
+ * @date 31 Oct 2010
+ * @version 2.0
+ */
+NMI_ErrNo NMI_PathDelete(NMI_Char* pcPath, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+/**
+ * @brief creates a new directory
+ * @details creates a new directory in the given path, if a file or directory
+ already exsits in this path the operation fails
+ * @param[in] pcPath path to be created
+ * @param[in] pstrAttrs Optional attributes, NULL for default.
+ * @return Error code indicating success/failure
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 2.0
+ */
+NMI_ErrNo NMI_DirectoryCreate(NMI_Char* pcPath, tstrNMI_FileOpsAttrs* pstrAttrs);
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Log.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Log.h
new file mode 100755
index 00000000..2c149e06
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Log.h
@@ -0,0 +1,43 @@
+#ifndef __NMI_LOG_H__
+#define __NMI_LOG_H__
+
+/* Errors will always get printed */
+#define NMI_ERROR(...) do { NMI_PRINTF("(ERR)(%s:%d) ",__NMI_FUNCTION__,__NMI_LINE__);\
+ NMI_PRINTF(__VA_ARGS__); } while(0)
+
+/* Wraning only printed if verbosity is 1 or more */
+#if (NMI_LOG_VERBOSITY_LEVEL > 0)
+#define NMI_WARN(...) do { NMI_PRINTF("(WRN)");\
+ NMI_PRINTF(__VA_ARGS__); } while(0)
+#else
+#define NMI_WARN(...) (0)
+#endif
+
+/* Info only printed if verbosity is 2 or more */
+#if (NMI_LOG_VERBOSITY_LEVEL > 1)
+#define NMI_INFO(...) do { NMI_PRINTF("(INF)");\
+ NMI_PRINTF(__VA_ARGS__); } while(0)
+#else
+#define NMI_INFO(...) (0)
+#endif
+
+/* Debug is only printed if verbosity is 3 or more */
+#if (NMI_LOG_VERBOSITY_LEVEL > 2)
+#define NMI_DBG(...) do { NMI_PRINTF("(DBG)(%s:%d) ",__NMI_FUNCTION__,__NMI_LINE__);\
+ NMI_PRINTF(__VA_ARGS__); } while(0)
+
+#else
+#define NMI_DBG(...) (0)
+#endif
+
+/* Function In/Out is only printed if verbosity is 4 or more */
+#if (NMI_LOG_VERBOSITY_LEVEL > 3)
+#define NMI_FN_IN do { NMI_PRINTF("(FIN) (%s:%d) \n", __NMI_FUNCTION__, __NMI_LINE__); } while(0)
+#define NMI_FN_OUT(ret) do { NMI_PRINTF("(FOUT) (%s:%d) %d.\n",__NMI_FUNCTION__,__NMI_LINE__,(ret)); } while(0)
+#else
+#define NMI_FN_IN (0)
+#define NMI_FN_OUT(ret) (0)
+#endif
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Math.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Math.h
new file mode 100755
index 00000000..7adcc78b
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Math.h
@@ -0,0 +1,368 @@
+#ifndef __NMI_MATH_H__
+#define __NMI_MATH_H__
+
+/*!
+* @file NMI_Math.h
+* @brief Math Operations OS wrapper functionality
+* @author remil
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 2 Nov 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_MATH_OPERATIONS_FEATURE
+#error the feature CONFIG_NMI_MATH_OPS_FEATURE must be supported to include this file
+#endif
+
+
+
+/**
+* @brief Returns the arc cosine of x in radians.
+* @details Returns the arc cosine of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value x must be within the range of -1 to +1 (inclusive).
+ The returned value is in the range of 0 to pi (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_acos(NMI_Double x);
+
+/**
+* @brief Returns the arc sine of x in radians.
+* @details Returns the arc sine of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value x must be within the range of -1 to +1 (inclusive).
+ The returned value is in the range of 0 to pi (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_asin(NMI_Double x);
+
+/**
+* @brief Returns the arc tangent of x in radians.
+* @details Returns the arc tangent of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -p/2 to +p/2 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_atan(NMI_Double x);
+
+/**
+* @brief Returns the arc tangent in radians
+* @details Returns the arc tangent in radians of y/x based on the
+ signs of both values to determine the correct quadrant.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note Both y and x cannot be zero.
+ The returned value is in the range of -p/2 to +p/2 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_atan2(NMI_Double y, NMI_Double x);
+
+
+/**
+* @brief Returns the cosine of a radian angle x.
+* @details Returns the cosine of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_cos(NMI_Double x);
+
+
+/**
+* @brief Returns the hyperbolic cosine of x.
+* @details Returns the hyperbolic cosine of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_cosh(NMI_Double x);
+
+
+/**
+* @brief Returns the sine of a radian angle x.
+* @details Returns the sine of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sin(NMI_Double x);
+
+
+/**
+* @brief Returns the hyperbolic sine of x.
+* @details Returns the hyperbolic sine of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sinh(NMI_Double x);
+/**
+* @brief Returns the tangent of a radian angle x.
+* @details Returns the tangent of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_tan(NMI_Double x);
+
+/**
+* @brief Returns the hyperbolic tangent of x.
+* @details Returns the hyperbolic tangent of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_tanh(NMI_Double x);
+
+
+/**
+* @brief Returns the value of e raised to the xth power.
+* @details Returns the value of e raised to the xth power.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_exp(NMI_Double x);
+
+/**
+* @brief The returned value is the mantissa and the integer pointed to by exponent is the exponent.
+* @details The returned value is the mantissa and the integer pointed to by exponent is the exponent.
+ The resultant value is x=mantissa * 2^exponent.
+* @param[in] NMI_Double x
+* @param[out] NMI_Sint32* exponent
+* @return NMI_Double
+* @note The mantissa is in the range of .5 (inclusive) to 1 (exclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_frexp(NMI_Double x, NMI_Sint32* exponent);
+
+
+
+/**
+* @brief Returns x multiplied by 2 raised to the power of exponent.
+* @details Returns x multiplied by 2 raised to the power of exponent.
+ x*2^exponent
+* @param[in] NMI_Double x
+* @param[out] NMI_Sint32 exponent
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_ldexp(NMI_Double x, NMI_Sint32 exponent);
+
+
+/**
+* @brief Returns the natural logarithm (base-e logarithm) of x.
+* @details Returns the natural logarithm (base-e logarithm) of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_log(NMI_Double x);
+
+
+/**
+* @brief Returns the common logarithm (base-10 logarithm) of x.
+* @details Returns the common logarithm (base-10 logarithm) of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_log10(NMI_Double x);
+
+
+/**
+* @brief Breaks the floating-point number x into integer and fraction components.
+* @details Breaks the floating-point number x into integer and fraction components.
+ The returned value is the fraction component (part after the decimal),
+ and sets integer to the integer component.
+
+* @param[in] NMI_Double x
+* @param[out] NMI_Double* dInteger
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_modf(NMI_Double x,NMI_Double* dInteger);
+
+
+
+/**
+* @brief Returns x raised to the power of y.
+* @details Returns x raised to the power of y.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note x cannot be negative if y is a fractional value.
+ x cannot be zero if y is less than or equal to zero.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_pow(NMI_Double x,NMI_Double y);
+
+
+
+/**
+* @brief Returns the square root of x.
+* @details Returns the square root of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The argument cannot be negative. The returned value is always positive.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sqrt(NMI_Double x);
+
+/**
+* @brief Returns the smallest integer value greater than or equal to x.
+* @details Returns the smallest integer value greater than or equal to x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_ceil(NMI_Double x);
+
+/**
+* @brief Returns the absolute value of x
+* @details Returns the absolute value of x
+ (a negative value becomes positive, positive value is unchanged).
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument.
+ The return value is always positive.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_fabs(NMI_Double x);
+
+/**
+* @brief Returns the largest integer value less than or equal to x.
+* @details Returns the largest integer value less than or equal to x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_floor(NMI_Double x);
+
+/**
+* @brief Returns the remainder of x divided by y.
+* @details Returns the remainder of x divided by y.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note There is no range limit on the return value.
+ If y is zero, then either a range error will occur or the function
+ will return zero (implementation-defined).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_fmod(NMI_Double x,NMI_Double y);
+
+
+/**
+* @brief
+* @details Returns the absolute value of x.
+ Note that in two's compliment that the most maximum number cannot be
+ represented as a positive number. The result in this case is undefined.
+ The absolute value is returned.
+* @param[in] NMI_Sint32 x
+* @return NMI_Sint32
+* @note
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_abs(NMI_Sint32 x);
+
+
+
+
+/**
+* @brief
+* @details Returns a pseudo-random number in the range of 0 to RAND_MAX.
+* @return NMI_Sint32
+* @note
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_rand();
+
+
+/**
+* @brief
+* @details This function seeds the random number generator used by the function rand.
+ Seeding srand with the same seed will cause rand to return the same sequence
+ of pseudo-random numbers.
+ If srand is not called, NMI_rand acts as if NMI_srand(1) has been called.
+
+* @param[in] NMI_Uint32 seed
+* @note No value is returned.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+void NMI_srand(NMI_Uint32 seed);
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Memory.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Memory.h
new file mode 100755
index 00000000..27ac5e2b
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Memory.h
@@ -0,0 +1,330 @@
+#ifndef __NMI_MEMORY_H__
+#define __NMI_MEMORY_H__
+
+/*!
+* @file NMI_Memory.h
+* @brief Memory OS wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 16 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_MEMORY_FEATURE
+#error the feature CONFIG_NMI_MEMORY_FEATURE must be supported to include this file
+#endif
+
+/*!
+* @struct tstrNMI_MemoryAttrs
+* @brief Memory API options
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+typedef struct {
+ #ifdef CONFIG_NMI_MEMORY_POOLS
+ /*!< the allocation pool to use for this memory, NULL for system
+ allocation. Default is NULL
+ */
+ NMI_MemoryPoolHandle* pAllocationPool;
+ #endif
+
+ /* a dummy member to avoid compiler errors*/
+ NMI_Uint8 dummy;
+}tstrNMI_MemoryAttrs;
+
+/*!
+* @brief Fills the tstrNMI_MemoryAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa tstrNMI_MemoryAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+static void NMI_MemoryFillDefault(tstrNMI_MemoryAttrs* pstrAttrs)
+{
+ #ifdef CONFIG_NMI_MEMORY_POOLS
+ pstrAttrs->pAllocationPool = NMI_NULL;
+ #endif
+}
+
+/*!
+* @brief Allocates a given size of bytes
+* @param[in] u32Size size of memory in bytes to be allocated
+* @param[in] strAttrs Optional attributes, NULL for default
+ if not NULL, pAllocationPool should point to the pool to use for
+ this allocation. if NULL memory will be allocated directly from
+ the system
+* @param[in] pcFileName file name of the calling code for debugging
+* @param[in] u32LineNo line number of the calling code for debugging
+* @return The new allocated block, NULL if allocation fails
+* @note It is recommended to use of of the wrapper macros instead of
+ calling this function directly
+* @sa sttrNMI_MemoryAttrs
+* @sa NMI_MALLOC
+* @sa NMI_MALLOC_EX
+* @sa NMI_NEW
+* @sa NMI_NEW_EX
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryAlloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo);
+
+/*!
+* @brief Allocates a given size of bytes and zero filling it
+* @param[in] u32Size size of memory in bytes to be allocated
+* @param[in] strAttrs Optional attributes, NULL for default
+ if not NULL, pAllocationPool should point to the pool to use for
+ this allocation. if NULL memory will be allocated directly from
+ the system
+* @param[in] pcFileName file name of the calling code for debugging
+* @param[in] u32LineNo line number of the calling code for debugging
+* @return The new allocated block, NULL if allocation fails
+* @note It is recommended to use of of the wrapper macros instead of
+ calling this function directly
+* @sa sttrNMI_MemoryAttrs
+* @sa NMI_CALLOC
+* @sa NMI_CALLOC_EX
+* @sa NMI_NEW_0
+* @sa NMI_NEW_0_EX
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryCalloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo);
+
+/*!
+* @brief Reallocates a given block to a new size
+* @param[in] pvOldBlock the old memory block, if NULL then this function
+ behaves as a new allocation function
+* @param[in] u32NewSize size of the new memory block in bytes, if zero then
+ this function behaves as a free function
+* @param[in] strAttrs Optional attributes, NULL for default
+ if pAllocationPool!=NULL and pvOldBlock==NULL, pAllocationPool
+ should point to the pool to use for this allocation.
+ if pAllocationPool==NULL and pvOldBlock==NULL memory will be
+ allocated directly from the system
+ if and pvOldBlock!=NULL, pAllocationPool will not be inspected
+ and reallocation is done from the same pool as the original block
+* @param[in] pcFileName file name of the calling code for debugging
+* @param[in] u32LineNo line number of the calling code for debugging
+* @return The new allocated block, possibly same as pvOldBlock
+* @note It is recommended to use of of the wrapper macros instead of
+ calling this function directly
+* @sa sttrNMI_MemoryAttrs
+* @sa NMI_REALLOC
+* @sa NMI_REALLOC_EX
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryRealloc(void* pvOldBlock, NMI_Uint32 u32NewSize,
+ tstrNMI_MemoryAttrs* strAttrs, NMI_Char* pcFileName, NMI_Uint32 u32LineNo);
+
+/*!
+* @brief Frees given block
+* @param[in] pvBlock the memory block to be freed
+* @param[in] strAttrs Optional attributes, NULL for default
+* @param[in] pcFileName file name of the calling code for debugging
+* @param[in] u32LineNo line number of the calling code for debugging
+* @note It is recommended to use of of the wrapper macros instead of
+ calling this function directly
+* @sa sttrNMI_MemoryAttrs
+* @sa NMI_FREE
+* @sa NMI_FREE_EX
+* @sa NMI_FREE_SET_NULL
+* @sa NMI_FREE_IF_TRUE
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+void NMI_MemoryFree(void* pvBlock, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo);
+
+/*!
+* @brief Creates a new memory pool
+* @param[out] pHandle the handle to the new Pool
+* @param[in] u32PoolSize The pool size in bytes
+* @param[in] strAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa sttrNMI_MemoryAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MemoryNewPool(NMI_MemoryPoolHandle* pHandle, NMI_Uint32 u32PoolSize,
+ tstrNMI_MemoryAttrs* strAttrs);
+
+/*!
+* @brief Deletes a memory pool, freeing all memory allocated from it as well
+* @param[in] pHandle the handle to the deleted Pool
+* @param[in] strAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa sttrNMI_MemoryAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MemoryDelPool(NMI_MemoryPoolHandle* pHandle, tstrNMI_MemoryAttrs* strAttrs);
+
+
+#ifdef CONFIG_NMI_MEMORY_DEBUG
+
+ /*!
+ @brief standrad malloc wrapper with custom attributes
+ */
+ #define NMI_MALLOC_EX(__size__, __attrs__)\
+ (NMI_MemoryAlloc(\
+ (__size__), __attrs__,\
+ (NMI_Char*)__NMI_FILE__, (NMI_Uint32)__NMI_LINE__))
+
+ /*!
+ @brief standrad calloc wrapper with custom attributes
+ */
+ #define NMI_CALLOC_EX(__size__, __attrs__)\
+ (NMI_MemoryCalloc(\
+ (__size__), __attrs__,\
+ (NMI_Char*)__NMI_FILE__, (NMI_Uint32)__NMI_LINE__))
+
+ /*!
+ @brief standrad realloc wrapper with custom attributes
+ */
+ #define NMI_REALLOC_EX(__ptr__, __new_size__, __attrs__)\
+ (NMI_MemoryRealloc(\
+ (__ptr__), (__new_size__), __attrs__,\
+ (NMI_Char*)__NMI_FILE__, (NMI_Uint32)__NMI_LINE__))
+
+ /*!
+ @brief standrad free wrapper with custom attributes
+ */
+ #define NMI_FREE_EX(__ptr__, __attrs__)\
+ (NMI_MemoryFree(\
+ (__ptr__), __attrs__,\
+ (NMI_Char*)__NMI_FILE__, (NMI_Uint32)__NMI_LINE__))
+
+#else
+
+ /*!
+ @brief standrad malloc wrapper with custom attributes
+ */
+ #define NMI_MALLOC_EX(__size__, __attrs__)\
+ (NMI_MemoryAlloc(\
+ (__size__), __attrs__, NMI_NULL, 0))
+
+ /*!
+ @brief standrad calloc wrapper with custom attributes
+ */
+ #define NMI_CALLOC_EX(__size__, __attrs__)\
+ (NMI_MemoryCalloc(\
+ (__size__), __attrs__, NMI_NULL, 0))
+
+ /*!
+ @brief standrad realloc wrapper with custom attributes
+ */
+ #define NMI_REALLOC_EX(__ptr__, __new_size__, __attrs__)\
+ (NMI_MemoryRealloc(\
+ (__ptr__), (__new_size__), __attrs__, NMI_NULL, 0))
+ /*!
+ @brief standrad free wrapper with custom attributes
+ */
+ #define NMI_FREE_EX(__ptr__, __attrs__)\
+ (NMI_MemoryFree(\
+ (__ptr__), __attrs__, NMI_NULL, 0))
+
+#endif
+
+/*!
+@brief Allocates a block (with custom attributes) of given type and number of
+elements
+*/
+#define NMI_NEW_EX(__struct_type__, __n_structs__, __attrs__)\
+ ((__struct_type__*)NMI_MALLOC_EX(\
+ sizeof(__struct_type__) * (NMI_Uint32)(__n_structs__), __attrs__))
+
+/*!
+@brief Allocates a block (with custom attributes) of given type and number of
+elements and Zero-fills it
+*/
+#define NMI_NEW_0_EX(__struct_type__, __n_structs__, __attrs__)\
+ ((__struct_type__*)NMI_CALLOC_EX(\
+ sizeof(__struct_type__) * (NMI_Uint32)(__n_structs__), __attrs__))
+
+/*!
+@brief Frees a block (with custom attributes), also setting the original pointer
+to NULL
+*/
+#define NMI_FREE_SET_NULL_EX(__ptr__, __attrs__) do{\
+ if(__ptr__ != NMI_NULL){\
+ NMI_FREE_EX(__ptr__, __attrs__);\
+ __ptr__ = NMI_NULL ;\
+ }\
+}while(0)
+
+/*!
+@brief Frees a block (with custom attributes) if the pointer expression evaluates
+to true
+*/
+#define NMI_FREE_IF_TRUE_EX(__ptr__, __attrs__) do{\
+ if (__ptr__ != NMI_NULL){\
+ NMI_FREE_EX(__ptr__, __attrs__);\
+ }\
+} while(0)
+
+/*!
+@brief standrad malloc wrapper with default attributes
+*/
+#define NMI_MALLOC(__size__)\
+ NMI_MALLOC_EX(__size__, NMI_NULL)
+
+/*!
+@brief standrad calloc wrapper with default attributes
+*/
+#define NMI_CALLOC(__size__)\
+ NMI_CALLOC_EX(__size__, NMI_NULL)
+
+/*!
+@brief standrad realloc wrapper with default attributes
+*/
+#define NMI_REALLOC(__ptr__, __new_size__)\
+ NMI_REALLOC_EX(__ptr__, __new_size__, NMI_NULL)
+
+/*!
+@brief standrad free wrapper with default attributes
+*/
+#define NMI_FREE(__ptr__)\
+ NMI_FREE_EX(__ptr__, NMI_NULL)
+
+/*!
+@brief Allocates a block (with default attributes) of given type and number of
+elements
+*/
+#define NMI_NEW(__struct_type__, __n_structs__)\
+ NMI_NEW_EX(__struct_type__, __n_structs__, NMI_NULL)
+
+/*!
+@brief Allocates a block (with default attributes) of given type and number of
+elements and Zero-fills it
+*/
+#define NMI_NEW_0(__struct_type__, __n_structs__)\
+ NMI_NEW_O_EX(__struct_type__, __n_structs__, NMI_NULL)
+
+/*!
+@brief Frees a block (with default attributes), also setting the original pointer
+to NULL
+*/
+#define NMI_FREE_SET_NULL(__ptr__)\
+ NMI_FREE_SET_NULL_EX(__ptr__, NMI_NULL)
+
+/*!
+@brief Frees a block (with default attributes) if the pointer expression evaluates
+to true
+*/
+#define NMI_FREE_IF_TRUE(__ptr__)\
+ NMI_FREE_IF_TRUE_EX(__ptr__, NMI_NULL)
+
+
+#endif
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_MsgQueue.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_MsgQueue.h
new file mode 100755
index 00000000..e2d21572
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_MsgQueue.h
@@ -0,0 +1,134 @@
+#ifndef __NMI_MSG_QUEUE_H__
+#define __NMI_MSG_QUEUE_H__
+
+/*!
+* @file NMI_MsgQueue.h
+* @brief Message Queue OS wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 30 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_MSG_QUEUE_FEATURE
+#error the feature CONFIG_NMI_MSG_QUEUE_FEATURE must be supported to include this file
+#endif
+
+/*!
+* @struct tstrNMI_MsgQueueAttrs
+* @brief Message Queue API options
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+typedef struct
+{
+ #ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+ NMI_Char* pcName;
+ #endif
+
+ #ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+ NMI_Uint32 u32Timeout;
+ #endif
+
+ /* a dummy member to avoid compiler errors*/
+ NMI_Uint8 dummy;
+
+}tstrNMI_MsgQueueAttrs;
+
+/*!
+* @brief Fills the MsgQueueAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+static void NMI_MsgQueueFillDefault(tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+ #ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+ pstrAttrs->pcName = NMI_NULL;
+ #endif
+
+ #ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+ pstrAttrs->u32Timeout = NMI_OS_INFINITY;
+ #endif
+}
+/*!
+* @brief Creates a new Message queue
+* @details Creates a new Message queue, if the feature
+ CONFIG_NMI_MSG_QUEUE_IPC_NAME is enabled and pstrAttrs->pcName
+ is not Null, then this message queue can be used for IPC with
+ any other message queue having the same name in the system
+* @param[in,out] pHandle handle to the message queue object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_MsgQueueAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueCreate(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs);
+
+
+/*!
+* @brief Sends a message
+* @details Sends a message, this API will block unil the message is
+ actually sent or until it is timedout (as long as the feature
+ CONFIG_NMI_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout
+ is not set to NMI_OS_INFINITY), zero timeout is a valid value
+* @param[in] pHandle handle to the message queue object
+* @param[in] pvSendBuffer pointer to the data to send
+* @param[in] u32SendBufferSize the size of the data to send
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_MsgQueueAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueSend(NMI_MsgQueueHandle* pHandle,
+ const void * pvSendBuffer, NMI_Uint32 u32SendBufferSize,
+ tstrNMI_MsgQueueAttrs* pstrAttrs);
+
+
+/*!
+* @brief Receives a message
+* @details Receives a message, this API will block unil a message is
+ received or until it is timedout (as long as the feature
+ CONFIG_NMI_MSG_QUEUE_TIMEOUT is enabled and pstrAttrs->u32Timeout
+ is not set to NMI_OS_INFINITY), zero timeout is a valid value
+* @param[in] pHandle handle to the message queue object
+* @param[out] pvRecvBuffer pointer to a buffer to fill with the received message
+* @param[in] u32RecvBufferSize the size of the receive buffer
+* @param[out] pu32ReceivedLength the length of received data
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_MsgQueueAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueRecv(NMI_MsgQueueHandle* pHandle,
+ void * pvRecvBuffer, NMI_Uint32 u32RecvBufferSize,
+ NMI_Uint32* pu32ReceivedLength,
+ tstrNMI_MsgQueueAttrs* pstrAttrs);
+
+
+/*!
+* @brief Destroys an existing Message queue
+* @param[in] pHandle handle to the message queue object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa tstrNMI_MsgQueueAttrs
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueDestroy(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs);
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_OSWrapper.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_OSWrapper.h
new file mode 100755
index 00000000..07d755d4
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_OSWrapper.h
@@ -0,0 +1,133 @@
+#ifndef __NMI_OSWRAPPER_H__
+#define __NMI_OSWRAPPER_H__
+
+/*!
+* @file NMI_OSWrapper.h
+* @brief Top level OS Wrapper, include this file and it will include all
+ other files as necessary
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+/* OS Wrapper interface version */
+#define NMI_OSW_INTERFACE_VER 2
+
+/* Integer Types */
+typedef unsigned char NMI_Uint8;
+typedef unsigned short NMI_Uint16;
+typedef unsigned int NMI_Uint32;
+typedef unsigned long long NMI_Uint64;
+typedef signed char NMI_Sint8;
+typedef signed short NMI_Sint16;
+typedef signed int NMI_Sint32;
+typedef signed long long NMI_Sint64;
+
+/* Floating types */
+typedef float NMI_Float;
+typedef double NMI_Double;
+
+/* Boolean type */
+typedef enum {
+ NMI_FALSE = 0,
+ NMI_TRUE = 1
+}NMI_Bool;
+
+/* Character types */
+typedef char NMI_Char;
+typedef NMI_Uint16 NMI_WideChar;
+
+#define NMI_OS_INFINITY (~((NMI_Uint32)0))
+#define NMI_NULL ((void*)0)
+
+/* standard min and max macros */
+#define NMI_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define NMI_MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+/* Os Configuration File */
+#include "NMI_OsWrapper/OsConfig/NMI_OSConfig.h"
+
+/* Platform specific include */
+#if NMI_PLATFORM == NMI_WIN32
+#include "NMI_OsWrapper/source/win32/include/NMI_platform.h"
+#elif NMI_PLATFORM == NMI_NU
+#include "NMI_OsWrapper/source/nucleus/include/NMI_platform.h"
+#elif NMI_PLATFORM == NMI_MTK
+#include "NMI_OsWrapper/source/mtk/include/NMI_platform.h"
+#elif NMI_PLATFORM == NMI_LINUX
+#include "NMI_OsWrapper/source/linux/include/NMI_platform.h"
+#elif NMI_PLATFORM == NMI_LINUXKERNEL
+#include "NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h"
+#else
+#error "OS not supported"
+#endif
+
+/* Logging Functions */
+#include "NMI_Log.h"
+
+/* Error reporting and handling support */
+#include "NMI_ErrorSupport.h"
+
+/* Thread support */
+#ifdef CONFIG_NMI_THREAD_FEATURE
+#include "NMI_Thread.h"
+#endif
+
+/* Semaphore support */
+#ifdef CONFIG_NMI_SEMAPHORE_FEATURE
+#include "NMI_Semaphore.h"
+#endif
+
+/* Sleep support */
+#ifdef CONFIG_NMI_SLEEP_FEATURE
+#include "NMI_Sleep.h"
+#endif
+
+/* Timer support */
+#ifdef CONFIG_NMI_TIMER_FEATURE
+#include "NMI_Timer.h"
+#endif
+
+/* Memory support */
+#ifdef CONFIG_NMI_MEMORY_FEATURE
+#include "NMI_Memory.h"
+#endif
+
+/* String Utilities */
+#ifdef CONFIG_NMI_STRING_UTILS
+#include "NMI_StrUtils.h"
+#endif
+
+/* Message Queue */
+#ifdef CONFIG_NMI_MSG_QUEUE_FEATURE
+#include "NMI_MsgQueue.h"
+#endif
+
+/* File operations */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_FEATURE
+#include "NMI_FileOps.h"
+#endif
+
+/* Time operations */
+#ifdef CONFIG_NMI_TIME_FEATURE
+#include "NMI_Time.h"
+#endif
+
+/* Event support */
+#ifdef CONFIG_NMI_EVENT_FEATURE
+#include "NMI_Event.h"
+#endif
+
+/* Socket operations */
+#ifdef CONFIG_NMI_SOCKET_FEATURE
+#include "NMI_Socket.h"
+#endif
+
+/* Math operations */
+#ifdef CONFIG_NMI_MATH_OPERATIONS_FEATURE
+#include "NMI_Math.h"
+#endif
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Semaphore.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Semaphore.h
new file mode 100755
index 00000000..dc65fb84
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Semaphore.h
@@ -0,0 +1,116 @@
+#ifndef __NMI_SEMAPHORE_H__
+#define __NMI_SEMAPHORE_H__
+
+/*!
+* @file NMI_Semaphore.h
+* @brief Semaphore OS Wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+
+#ifndef CONFIG_NMI_SEMAPHORE_FEATURE
+#error the feature NMI_OS_FEATURE_SEMAPHORE must be supported to include this file
+#endif
+
+/*!
+* @struct NMI_SemaphoreAttrs
+* @brief Semaphore API options
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /*!<
+ Initial count when the semaphore is created. default is 1
+ */
+ NMI_Uint32 u32InitCount;
+
+ #ifdef CONFIG_NMI_SEMAPHORE_TIMEOUT
+ /*!<
+ Timeout for use with NMI_SemaphoreAcquire, 0 to return immediately and
+ NMI_OS_INFINITY to wait forever. default is NMI_OS_INFINITY
+ */
+ NMI_Uint32 u32TimeOut;
+ #endif
+
+}tstrNMI_SemaphoreAttrs;
+
+
+/*!
+* @brief Fills the NMI_SemaphoreAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_SemaphoreAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+static void NMI_SemaphoreFillDefault(tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ pstrAttrs->u32InitCount = 1;
+ #ifdef CONFIG_NMI_SEMAPHORE_TIMEOUT
+ pstrAttrs->u32TimeOut = NMI_OS_INFINITY;
+ #endif
+}
+/*!
+* @brief Creates a new Semaphore object
+* @param[out] pHandle handle to the newly created semaphore
+* @param[in] pstrAttrs Optional attributes, NULL for defaults
+ pstrAttrs->u32InitCount controls the initial count
+* @return Error code indicating success/failure
+* @sa NMI_SemaphoreAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_SemaphoreCreate(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs);
+
+/*!
+* @brief Destroyes an existing Semaphore, releasing any resources
+* @param[in] pHandle handle to the semaphore object
+* @param[in] pstrAttrs Optional attributes, NULL for defaults
+* @return Error code indicating success/failure
+* @sa NMI_SemaphoreAttrs
+* @todo need to define behaviour if the semaphore delayed while it is pending
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_SemaphoreDestroy(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs);
+
+/*!
+* @brief Acquire the Semaphore object
+* @details This function will block until it can Acquire the given
+* semaphore, if the feature NMI_OS_FEATURE_SEMAPHORE_TIMEOUT is
+* eanbled a timeout value can be passed in pstrAttrs
+* @param[in] pHandle handle to the semaphore object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating success/failure
+* @sa NMI_SemaphoreAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_SemaphoreAcquire(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs);
+
+/*!
+* @brief Release the Semaphore object
+* @param[in] pHandle handle to the semaphore object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_SemaphoreAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_SemaphoreRelease(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs);
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Sleep.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Sleep.h
new file mode 100755
index 00000000..f183ed17
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Sleep.h
@@ -0,0 +1,45 @@
+#ifndef __NMI_SLEEP_H__
+#define __NMI_SLEEP_H__
+
+/*!
+* @file NMI_Sleep.h
+* @brief Sleep OS Wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_SLEEP_FEATURE
+#error the feature NMI_OS_FEATURE_SLEEP must be supported to include this file
+#endif
+
+/*!
+* @brief forces the current thread to sleep until the given time has elapsed
+* @param[in] u32TimeMilliSec Time to sleep in Milli seconds
+* @sa NMI_SleepMicrosec
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+* @note This function offers a relatively innacurate and low resolution
+ sleep, for accurate high resolution sleep use u32TimeMicoSec
+*/
+void NMI_Sleep(NMI_Uint32 u32TimeMilliSec);
+
+#ifdef CONFIG_NMI_SLEEP_HI_RES
+/*!
+* @brief forces the current thread to sleep until the given time has elapsed
+* @param[in] u32TimeMicoSec Time to sleep in Micro seconds
+* @sa NMI_Sleep
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+* @note This function offers an acurare high resolution sleep, depends on
+ the feature NMI_OS_FEATURE_SLEEP_HI_RES and may not be supported
+ on all Operating Systems
+*/
+void NMI_SleepMicrosec(NMI_Uint32 u32TimeMicoSec);
+#endif
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Socket.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Socket.h
new file mode 100755
index 00000000..cd7ff454
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Socket.h
@@ -0,0 +1,95 @@
+#ifndef __NMI_SOCKET_H__
+#define __NMI_SOCKET_H__
+
+/*!
+* @file NMI_Socket.h
+* @brief Socket Connection functionality
+* @author remil
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 19 Oct 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_SOCKET_FEATURE
+#error the feature CONFIG_NMI_SOCKET_FEATURE must be supported to include this file
+#endif
+
+
+/*!
+* Maximum length of IP address
+*/
+#define MAX_IP_LENGTH 16
+
+/*============================================================================*/
+/*!
+* @struct tpfNMI_TcpReceptionCB
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+typedef void (*tpfNMI_TcpReceptionCB)(NMI_Uint8* pu8Buffer,
+ NMI_Uint32 u32ReceivedDataLength,
+ void* vpUserData);
+/*============================================================================*/
+/*!
+* @struct tstrTcpConnection
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+typedef struct _tstrTcpConnection
+{
+ NMI_Uint32 u32SocketFd;
+ NMI_Sint32 s32Port;
+ NMI_Char cpIPAddress[MAX_IP_LENGTH];
+ tpfNMI_TcpReceptionCB fpTcpReceptionCB;
+ NMI_ThreadHandle strThreadHandle;
+ tstrNMI_ThreadAttrs strThreadAttrs;
+ void* vpUserData;
+
+}tstrTcpConnection;
+
+
+/*============================================================================*/
+/*!
+* @brief
+* @return
+* @note
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+NMI_ErrNo NMI_TcpConnect(tstrTcpConnection* pstrTcpConnection);
+
+/*============================================================================*/
+/*!
+* @brief
+* @return
+* @note
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+void NMI_TcpDisconnect(tstrTcpConnection* pstrTcpConnection);
+
+/*============================================================================*/
+/*!
+* @brief
+* @return
+* @note
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+NMI_ErrNo NMI_TcpSend(tstrTcpConnection* pstrTcpConnection,
+ NMI_Uint8* u8Buf,
+ NMI_Uint32 u32DataSize);
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_StrUtils.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_StrUtils.h
new file mode 100755
index 00000000..ae99958d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_StrUtils.h
@@ -0,0 +1,415 @@
+#ifndef __NMI_STRUTILS_H__
+#define __NMI_STRUTILS_H__
+
+/*!
+* @file NMI_StrUtils.h
+* @brief Basic string utilities
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 16 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_STRING_UTILS
+#error the feature CONFIG_NMI_STRING_UTILS must be supported to include this file
+#endif
+
+/*!
+* @brief Compares two memory buffers
+* @param[in] pvArg1 pointer to the first memory location
+* @param[in] pvArg2 pointer to the second memory location
+* @param[in] u32Count the size of the memory buffers
+* @return 0 if the 2 buffers are equal, 1 if pvArg1 is bigger than pvArg2,
+ -1 if pvArg1 smaller than pvArg2
+* @note this function repeats the functionality of standard memcmp
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_memcmp(const void* pvArg1, const void* pvArg2, NMI_Uint32 u32Count);
+
+/*!
+* @brief Internal implementation for memory copy
+* @param[in] pvTarget the target buffer to which the data is copied into
+* @param[in] pvSource pointer to the second memory location
+* @param[in] u32Count the size of the data to copy
+* @note this function should not be used directly, use NMI_memcpy instead
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void NMI_memcpy_INTERNAL(void* pvTarget, const void* pvSource, NMI_Uint32 u32Count);
+
+/*!
+* @brief Copies the contents of a memory buffer into another
+* @param[in] pvTarget the target buffer to which the data is copied into
+* @param[in] pvSource pointer to the second memory location
+* @param[in] u32Count the size of the data to copy
+* @return NMI_SUCCESS if copy is successfully handeled
+ NMI_FAIL if copy failed
+* @note this function repeats the functionality of standard memcpy,
+ however memcpy is undefined if the two buffers overlap but this
+ implementation will check for overlap and report error
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+static NMI_ErrNo NMI_memcpy(void* pvTarget, const void* pvSource, NMI_Uint32 u32Count)
+{
+ if(
+ (((NMI_Uint8*)pvTarget <= (NMI_Uint8*)pvSource)
+ && (((NMI_Uint8*)pvTarget+u32Count) > (NMI_Uint8*)pvSource))
+
+ || (((NMI_Uint8*)pvSource <= (NMI_Uint8*)pvTarget)
+ && (((NMI_Uint8*)pvSource+u32Count) > (NMI_Uint8*)pvTarget))
+ )
+ {
+ /* ovelapped memory, return Error */
+ return NMI_FAIL;
+ }
+ else
+ {
+ NMI_memcpy_INTERNAL(pvTarget, pvSource, u32Count);
+ return NMI_SUCCESS;
+ }
+}
+
+/*!
+* @brief Sets the contents of a memory buffer with the given value
+* @param[in] pvTarget the target buffer which contsnts will be set
+* @param[in] u8SetValue the value to be used
+* @param[in] u32Count the size of the memory buffer
+* @return value of pvTarget
+* @note this function repeats the functionality of standard memset
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_memset(void* pvTarget, NMI_Uint8 u8SetValue, NMI_Uint32 u32Count);
+
+/*!
+* @brief Concatenates the contents of 2 strings up to a given count
+* @param[in] pcTarget the target string, its null character will be overwritten
+ and contents of pcSource will be concatentaed to it
+* @param[in] pcSource the source string the will be concatentaed
+* @param[in] u32Count copying will proceed until a null character in pcSource
+ is encountered or u32Count of bytes copied
+* @return value of pcTarget
+* @note this function repeats the functionality of standard strncat
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncat(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count);
+
+/*!
+* @brief copies the contents of source string into the target string
+* @param[in] pcTarget the target string buffer
+* @param[in] pcSource the source string the will be copied
+* @param[in] u32Count copying will proceed until a null character in pcSource
+ is encountered or u32Count of bytes copied
+* @return value of pcTarget
+* @note this function repeats the functionality of standard strncpy
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncpy(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count);
+
+/*!
+* @brief Compares two strings
+* @details Compares 2 strings reporting which is bigger, NMI_NULL is considered
+ the smallest string, then a zero length string then all other
+ strings depending on thier ascii characters order
+* @param[in] pcStr1 the first string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] pcStr2 the second string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2,
+ -1 if pcStr1 smaller than pcStr2
+* @note this function repeats the functionality of standard strcmp
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strcmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2);
+
+/*!
+* @brief Compares two strings up to u32Count characters
+* @details Compares 2 strings reporting which is bigger, NMI_NULL is considered
+ the smallest string, then a zero length string then all other
+ strings depending on thier ascii characters order with small case
+ converted to uppder case
+* @param[in] pcStr1 the first string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] pcStr2 the second string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] u32Count copying will proceed until a null character in pcStr1 or
+ pcStr2 is encountered or u32Count of bytes copied
+* @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2,
+ -1 if pcStr1 smaller than pcStr2
+* @author aabozaeid
+* @date 7 Dec 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strncmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count);
+
+/*!
+* @brief Compares two strings ignoring the case of its latin letters
+* @details Compares 2 strings reporting which is bigger, NMI_NULL is considered
+ the smallest string, then a zero length string then all other
+ strings depending on thier ascii characters order with small case
+ converted to uppder case
+* @param[in] pcStr1 the first string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] pcStr2 the second string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2,
+ -1 if pcStr1 smaller than pcStr2
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_Sint32 NMI_strcmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2);
+
+/*!
+* @brief Compares two strings ignoring the case of its latin letters up to
+* u32Count characters
+* @details Compares 2 strings reporting which is bigger, NMI_NULL is considered
+ the smallest string, then a zero length string then all other
+ strings depending on thier ascii characters order with small case
+ converted to uppder case
+* @param[in] pcStr1 the first string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] pcStr2 the second string, NMI_NULL is valid and considered smaller
+ than any other non-NULL string (incliding zero lenght strings)
+* @param[in] u32Count copying will proceed until a null character in pcStr1 or
+ pcStr2 is encountered or u32Count of bytes copied
+* @return 0 if the 2 strings are equal, 1 if pcStr1 is bigger than pcStr2,
+ -1 if pcStr1 smaller than pcStr2
+* @author aabozaeid
+* @date 7 Dec 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strncmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count);
+
+/*!
+* @brief gets the length of a string
+* @param[in] pcStr the string
+* @return the length
+* @note this function repeats the functionality of standard strlen
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strlen(const NMI_Char* pcStr);
+
+/*!
+* @brief convert string to integer
+* @param[in] pcStr the string
+* @return the value of string
+* @note this function repeats the functionality of the libc atoi
+* @author bfahmy
+* @date 28 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strtoint(const NMI_Char* pcStr);
+
+/*!
+* @brief print a formatted string into a buffer
+* @param[in] pcTarget the buffer where the resulting string is written
+* @param[in] u32Size size of the output beffer including the \0 terminating
+ character
+* @param[in] pcFormat format of the string
+* @return number of character written or would have been written if the
+ string were not truncated
+* @note this function repeats the functionality of standard snprintf
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_Sint32 NMI_snprintf(NMI_Char* pcTarget, NMI_Uint32 u32Size,
+ const NMI_Char* pcFormat, ...);
+
+
+#ifdef CONFIG_NMI_EXTENDED_STRING_OPERATIONS
+
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c in the first n bytes
+ of the string pointed to by the argument str.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_memchr(const void *str, NMI_Char c, NMI_Sint32 n);
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c (an unsigned char)
+ in the string pointed to by the argument str.
+ The terminating null character is considered to be part of the string.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strchr(const NMI_Char *str, NMI_Char c);
+
+/**
+* @brief
+* @details Appends the string pointed to by str2 to the end of the string pointed to by str1.
+ The terminating null character of str1 is overwritten.
+ Copying stops once the terminating null character of str2 is copied. If overlapping occurs, the result is undefined.
+ The argument str1 is returned.
+* @param[in] NMI_Char* str1,
+* @param[in] NMI_Char* str2,
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcat(NMI_Char *str1, const NMI_Char *str2);
+
+
+/**
+* @brief
+* @details Copy pcSource to pcTarget
+* @param[in] NMI_Char* pcTarget
+* @param[in] const NMI_Char* pcSource
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcpy(NMI_Char* pcTarget, const NMI_Char* pcSource);
+
+
+
+/**
+* @brief
+* @details Finds the first sequence of characters in the string str1 that
+ does not contain any character specified in str2.
+ Returns the length of this first sequence of characters found that
+ do not match with str2.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strcspn(const NMI_Char *str1, const NMI_Char *str2);
+
+
+/**
+* @brief
+* @details Searches an internal array for the error number errnum and returns a pointer
+ to an error message string.
+ Returns a pointer to an error message string.
+* @param[in] NMI_Sint32 errnum
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strerror(NMI_Sint32 errnum);
+
+/**
+* @brief
+* @details Finds the first occurrence of the entire string str2
+ (not including the terminating null character) which appears in the string str1.
+ Returns a pointer to the first occurrence of str2 in str1.
+ If no match was found, then a null pointer is returned.
+ If str2 points to a string of zero length, then the argument str1 is returned.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strstr(const NMI_Char *str1, const NMI_Char *str2);
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c (an unsigned char)
+ in the string pointed to by the argument str.
+ The terminating null character is considered to be part of the string.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strchr(const NMI_Char *str, NMI_Char c);
+
+
+/**
+* @brief
+* @details Parses the C string str interpreting its content as a floating point
+ number and returns its value as a double.
+ If endptr is not a null pointer, the function also sets the value pointed
+ by endptr to point to the first character after the number.
+* @param[in] const NMI_Char* str
+* @param[in] NMI_Char** endptr
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_StringToDouble(const NMI_Char* str,
+ NMI_Char** endptr);
+
+
+/**
+* @brief Parses the C string str interpreting its content as an unsigned integral
+ number of the specified base, which is returned as an unsigned long int value.
+* @details The function first discards as many whitespace characters as necessary
+ until the first non-whitespace character is found.
+ Then, starting from this character, takes as many characters as possible
+ that are valid following a syntax that depends on the base parameter,
+ and interprets them as a numerical value.
+ Finally, a pointer to the first character following the integer
+ representation in str is stored in the object pointed by endptr.
+* @param[in] const NMI_Char *str
+* @param[in] NMI_Char **endptr
+* @param[in] NMI_Sint32 base
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringToUint32(const NMI_Char *str,
+ NMI_Char **endptr,
+ NMI_Sint32 base);
+
+
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Thread.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Thread.h
new file mode 100755
index 00000000..42ff55cd
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Thread.h
@@ -0,0 +1,155 @@
+#ifndef __NMI_THREAD_H__
+#define __NMI_THREAD_H__
+
+/*!
+* @file NMI_Thread.h
+* @brief Thread OS Wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_THREAD_FEATURE
+#error the feature NMI_OS_FEATURE_THREAD must be supported to include this file
+#endif
+
+typedef void (*tpfNMI_ThreadFunction)(void*);
+
+typedef enum
+{
+ #ifdef CONFIG_NMI_THREAD_STRICT_PRIORITY
+ NMI_OS_THREAD_PIORITY_0 = 0,
+ NMI_OS_THREAD_PIORITY_1 = 1,
+ NMI_OS_THREAD_PIORITY_2 = 2,
+ NMI_OS_THREAD_PIORITY_3 = 3,
+ NMI_OS_THREAD_PIORITY_4 = 4,
+ #endif
+
+ NMI_OS_THREAD_PIORITY_HIGH = 0,
+ NMI_OS_THREAD_PIORITY_NORMAL = 2,
+ NMI_OS_THREAD_PIORITY_LOW = 4
+}tenuNMI_ThreadPiority;
+
+/*!
+* @struct NMI_ThreadAttrs
+* @brief Thread API options
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /*!<
+ stack size for use with NMI_ThreadCreate, default is NMI_OS_THREAD_DEFAULT_STACK
+ */
+ NMI_Uint32 u32StackSize;
+
+ /*!<
+ piority for the thread, if NMI_OS_FEATURE_THREAD_STRICT_PIORITY is defined
+ this value is strictly observed and can take a larger resolution
+ */
+ tenuNMI_ThreadPiority enuPiority;
+
+ #ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+ /*!
+ if true the thread will be created suspended
+ */
+ NMI_Bool bStartSuspended;
+ #endif
+
+}tstrNMI_ThreadAttrs;
+
+#define NMI_OS_THREAD_DEFAULT_STACK (10*1024)
+
+/*!
+* @brief Fills the NMI_ThreadAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_ThreadAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+static void NMI_ThreadFillDefault(tstrNMI_ThreadAttrs* pstrAttrs)
+{
+ pstrAttrs->u32StackSize = NMI_OS_THREAD_DEFAULT_STACK;
+ pstrAttrs->enuPiority = NMI_OS_THREAD_PIORITY_NORMAL;
+
+ #ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+ pstrAttrs->bStartSuspended = NMI_FALSE;
+ #endif
+}
+
+/*!
+* @brief Creates a new thread
+* @details if the feature NMI_OS_FEATURE_THREAD_SUSPEND_CONTROL is
+ defined and tstrNMI_ThreadAttrs.bStartSuspended is set to true
+ the new thread will be created in suspended state, otherwise
+ it will start executing immeadiately
+ if the feature NMI_OS_FEATURE_THREAD_STRICT_PIORITY is defined
+ piorities are strictly observed, otherwise the underlaying OS
+ may not observe piorities
+* @param[out] pHandle handle to the newly created thread object
+* @param[in] pfEntry pointer to the entry point of the new thread
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_ThreadAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ThreadCreate(NMI_ThreadHandle* pHandle, tpfNMI_ThreadFunction pfEntry,
+ void* pvArg, tstrNMI_ThreadAttrs* pstrAttrs);
+
+/*!
+* @brief Destroys the Thread object
+* @details This function is used for clean up and freeing any used resources
+* This function will block until the destroyed thread exits cleanely,
+* so, the thread code thould handle an exit case before this calling
+* this function
+* @param[in] pHandle handle to the thread object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_ThreadAttrs
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ThreadDestroy(NMI_ThreadHandle* pHandle,
+ tstrNMI_ThreadAttrs* pstrAttrs);
+
+#ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+
+/*!
+* @brief Suspends an executing Thread object
+* @param[in] pHandle handle to the thread object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_ThreadAttrs
+* @note Optional part, NMI_OS_FEATURE_THREAD_SUSPEND_CONTROL must be enabled
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ThreadSuspend(NMI_ThreadHandle* pHandle,
+ tstrNMI_ThreadAttrs* pstrAttrs);
+
+/*!
+* @brief Resumes a suspened Thread object
+* @param[in] pHandle handle to the thread object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_ThreadAttrs
+* @note Optional part, NMI_OS_FEATURE_THREAD_SUSPEND_CONTROL must be enabled
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ThreadResume(NMI_ThreadHandle* pHandle,
+ tstrNMI_ThreadAttrs* pstrAttrs);
+
+#endif
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Time.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Time.h
new file mode 100755
index 00000000..653d9099
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Time.h
@@ -0,0 +1,207 @@
+#ifndef __NMI_TIME_H__
+#define __NMI_TIME_H__
+
+/*!
+* @file NMI_Time.h
+* @brief Time retrival functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 2 Sep 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_TIME_FEATURE
+#error the feature CONFIG_NMI_TIME_FEATURE must be supported to include this file
+#endif
+
+/*!
+* @struct NMI_ThreadAttrs
+* @brief Thread API options
+* @author syounan
+* @date 2 Sep 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /* a dummy type to prevent compile errors on empty structure*/
+ NMI_Uint8 dummy;
+}tstrNMI_TimeAttrs;
+
+typedef struct
+{
+ /*!< current year */
+ NMI_Uint16 u16Year;
+ /*!< current month */
+ NMI_Uint8 u8Month;
+ /*!< current day */
+ NMI_Uint8 u8Day;
+
+ /*!< current hour (in 24H format) */
+ NMI_Uint8 u8Hour;
+ /*!< current minute */
+ NMI_Uint8 u8Miute;
+ /*!< current second */
+ NMI_Uint8 u8Second;
+
+}tstrNMI_TimeCalender;
+
+/*!
+* @brief returns the number of msec elapsed since system start up
+* @return number of msec elapsed singe system start up
+* @note since this returned value is 32 bit, the caller must handle
+ wraparounds in values every about 49 of continous operations
+* @author syounan
+* @date 2 Sep 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_TimeMsec(void);
+
+
+
+#ifdef CONFIG_NMI_EXTENDED_TIME_OPERATIONS
+/**
+* @brief
+* @details function returns the implementation's best approximation to the
+ processor time used by the process since the beginning of an
+ implementation-dependent time related only to the process invocation.
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_Clock();
+
+/**
+* @brief
+* @details The difftime() function computes the difference between two calendar
+ times (as returned by NMI_GetTime()): time1 - time0.
+* @param[in] NMI_Time time1
+* @param[in] NMI_Time time0
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_DiffTime(NMI_Time time1, NMI_Time time0);
+
+/**
+* @brief
+* @details The gmtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time,
+ expressed as Coordinated Universal Time (UTC).
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_GmTime(const NMI_Time* timer);
+
+
+/**
+* @brief
+* @details The localtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time, expressed
+ as a local time. The function corrects for the timezone and any
+ seasonal time adjustments. Local timezone information is used as
+ though localtime() calls tzset().
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_LocalTime(const NMI_Time* timer);
+
+
+/**
+* @brief
+* @details The mktime() function converts the broken-down time,
+ expressed as local time, in the structure pointed to by timeptr,
+ into a time since the Epoch value with the same encoding as that
+ of the values returned by time(). The original values of the tm_wday
+ and tm_yday components of the structure are ignored, and the original
+ values of the other components are not restricted to the ranges described
+ in the <time.h> entry.
+* @param[in] NMI_tm* timer
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_MkTime(NMI_tm* timer);
+
+
+/**
+* @brief
+* @details The strftime() function places bytes into the array
+ pointed to by s as controlled by the string pointed to by format.
+* @param[in] NMI_Char* s
+* @param[in] NMI_Uint32 maxSize
+* @param[in] const NMI_Char* format
+* @param[in] const NMI_tm* timptr
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringFormatTime(NMI_Char* s,
+ NMI_Uint32 maxSize,
+ const NMI_Char* format,
+ const NMI_tm* timptr);
+
+
+/**
+* @brief The NMI_GetTime() function returns the value of time in seconds since the Epoch.
+* @details The tloc argument points to an area where the return value is also stored.
+ If tloc is a null pointer, no value is stored.
+* @param[in] NMI_Time* tloc
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_GetTime(NMI_Time* tloc);
+
+#endif
+
+#ifdef CONFIG_NMI_TIME_UTC_SINCE_1970
+
+/*!
+* @brief returns the number of seconds elapsed since 1970 (in UTC)
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return number of seconds elapsed since 1970 (in UTC)
+* @sa tstrNMI_TimeAttrs
+* @author syounan
+* @date 2 Sep 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_TimeUtcSince1970(tstrNMI_TimeAttrs* pstrAttrs);
+
+#endif
+
+#ifdef CONFIG_NMI_TIME_CALENDER
+
+/*!
+* @brief gets the current calender time
+* @return number of seconds elapsed since 1970 (in UTC)
+* @param[out] ptstrCalender calender structure to be filled with time
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @sa NMI_ThreadAttrs
+* @author syounan
+* @date 2 Sep 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_TimeCalender(tstrNMI_TimeCalender* ptstrCalender,
+ tstrNMI_TimeAttrs* pstrAttrs);
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Timer.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Timer.h
new file mode 100755
index 00000000..ee1978f7
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_Timer.h
@@ -0,0 +1,154 @@
+#ifndef __NMI_TIMER_H__
+#define __NMI_TIMER_H__
+
+/*!
+* @file NMI_Timer.h
+* @brief Timer (One Shot and Periodic) OS wrapper functionality
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 16 Aug 2010
+* @version 1.0
+*/
+
+#ifndef CONFIG_NMI_TIMER_FEATURE
+#error the feature CONFIG_NMI_TIMER_FEATURE must be supported to include this file
+#endif
+
+typedef void (*tpfNMI_TimerFunction)(void*);
+
+/*!
+* @struct tstrNMI_TimerAttrs
+* @brief Timer API options
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+typedef struct
+{
+ /*!< if set to NMI_TRUE the callback function will be called
+ periodically. */
+ #ifdef CONFIG_NMI_TIMER_PERIODIC
+ NMI_Bool bPeriodicTimer;
+ #endif
+
+ /* a dummy member to avoid compiler errors*/
+ NMI_Uint8 dummy;
+}tstrNMI_TimerAttrs;
+
+/*!
+* @brief Fills the NMI_TimerAttrs with default parameters
+* @param[out] pstrAttrs structure to be filled
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+
+static void NMI_TimerFillDefault(tstrNMI_TimerAttrs* pstrAttrs)
+{
+ #ifdef CONFIG_NMI_TIMER_PERIODIC
+ pstrAttrs->bPeriodicTimer = NMI_FALSE;
+ #endif
+}
+
+
+/*!
+* @brief Creates a new timer
+* @details Timers are a useful utility to execute some callback function
+ in the future.
+ A timer object has 3 states : IDLE, PENDING and EXECUTING
+ IDLE : initial timer state after creation, no execution for the
+ callback function is planned
+ PENDING : a request to execute the callback function is made
+ using NMI_TimerStart.
+ EXECUTING : the timer has expired and its callback is now
+ executing, when execution is done the timer returns to PENDING
+ if the feature CONFIG_NMI_TIMER_PERIODIC is enabled and
+ the flag tstrNMI_TimerAttrs.bPeriodicTimer is set. otherwise the
+ timer will return to IDLE
+* @param[out] pHandle handle to the newly created timer object
+* @param[in] pfEntry pointer to the callback function to be called when the
+ timer expires
+ the underlaying OS may put many restrictions on what can be
+ called inside a timer's callback, as a general rule no blocking
+ operations (IO or semaphore Acquision) should be perfomred
+ It is recommended that the callback will be as short as possible
+ and only flags other threads to do the actual work
+ also it should be noted that the underlaying OS maynot give any
+ guarentees on which contect this callback will execute in
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_TimerCreate(NMI_TimerHandle* pHandle,
+ tpfNMI_TimerFunction pfCallback, tstrNMI_TimerAttrs* pstrAttrs);
+
+
+/*!
+* @brief Destroys a given timer
+* @details This will destroy a given timer freeing any resources used by it
+ if the timer was PENDING Then must be cancelled as well(i.e.
+ goes to IDLE, same effect as calling NMI_TimerCancel first)
+ if the timer was EXECUTING then the callback will be allowed to
+ finish first then all resources are freed
+* @param[in] pHandle handle to the timer object
+* @param[in] pstrAttrs Optional attributes, NULL for default
+* @return Error code indicating sucess/failure
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_TimerDestroy(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs);
+
+/*!
+* @brief Starts a given timer
+* @details This function will move the timer to the PENDING state until the
+ given time expires (in msec) then the callback function will be
+ executed (timer in EXECUTING state) after execution is dene the
+ timer either goes to IDLE (if bPeriodicTimer==NMI_FALSE) or
+ PENDING with same timeout value (if bPeriodicTimer==NMI_TRUE)
+* @param[in] pHandle handle to the timer object
+* @param[in] u32Timeout timeout value in msec after witch the callback
+ function will be executed. Timeout value of 0 is not allowed for
+ periodic timers
+* @param[in] pstrAttrs Optional attributes, NULL for default,
+ set bPeriodicTimer to run this timer as a periodic timer
+* @return Error code indicating sucess/failure
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_TimerStart(NMI_TimerHandle* pHandle, NMI_Uint32 u32Timeout, void* pvArg,
+ tstrNMI_TimerAttrs* pstrAttrs);
+
+
+/*!
+* @brief Stops a given timer
+* @details This function will move the timer to the IDLE state cancelling
+ any sheduled callback execution.
+ if this function is called on a timer already in the IDLE state
+ it will have no effect.
+ if this function is called on a timer in EXECUTING state
+ (callback has already started) it will wait until executing is
+ done then move the timer to the IDLE state (which is trivial
+ work if the timer is non periodic)
+* @param[in] pHandle handle to the timer object
+* @param[in] pstrAttrs Optional attributes, NULL for default,
+* @return Error code indicating sucess/failure
+* @sa NMI_TimerAttrs
+* @author syounan
+* @date 16 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_TimerStop(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs);
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_platform.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_platform.h
new file mode 100755
index 00000000..f814dd97
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/include/NMI_platform.h
@@ -0,0 +1,207 @@
+#ifndef __NMI_platfrom_H__
+#define __NMI_platfrom_H__
+
+/*!
+* @file NMI_platform.h
+* @brief platform specific file, when creating OS wrapper for a
+ new platform start wih this file
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 10 Aug 2010
+* @version 1.0
+*/
+
+
+/******************************************************************
+ Feature support checks
+*******************************************************************/
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_STRICT_PRIORITY
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SEMAPHORE_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SEMAPHORE_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SLEEP_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SLEEP_HI_RES
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIMER_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIMER_PERIODIC
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_POOLS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_DEBUG
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_ASSERTION_SUPPORT
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_STRING_UTILS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_STRING_API
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_PATH_API
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_UTC_SINCE_1970
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_CALENDER
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MATH_OPERATIONS_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EXTENDED_FILE_OPERATIONS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EXTENDED_STRING_OPERATIONS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EXTENDED_TIME_OPERATIONS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SOCKET_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/******************************************************************
+ OS specific includes
+*******************************************************************/
+
+
+/******************************************************************
+ OS specific types
+*******************************************************************/
+
+/* change into OS specific type */
+typedef void* NMI_ThreadHandle;
+
+/* change into OS specific type */
+typedef void* NMI_SemaphoreHandle;
+
+/* change into OS specific type */
+typedef void* NMI_TimerHandle;
+
+/* change into OS specific type */
+typedef void* NMI_MemoryPoolHandle;
+
+/* change into OS specific type */
+typedef void* NMI_MsgQueueHandle;
+
+/* change into OS specific type */
+typedef void* NMI_FileHandle;
+
+/* change into OS specific type */
+typedef void* NMI_EventHandle;
+
+/*******************************************************************
+ others
+********************************************************************/
+
+/* Generic printf function, map it to the standard printf */
+#define NMI_PRINTF(...)
+#define __NMI_FILE__
+#define __NMI_FUNCTION__
+#define __NMI_LINE__
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/Makefile b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/Makefile
new file mode 100755
index 00000000..7482ef0d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/Makefile
@@ -0,0 +1,67 @@
+#ARCH = arm
+MAKE = make
+#CC = arm-linux-gcc
+#AR = arm-linux-ar
+ifeq ($(TARGET),PANDA)
+CC = arm-eabi-gcc
+AR = arm-eabi-ar
+else
+CC = gcc
+AR = ar
+endif
+RM = rm
+MV = mv
+ECHO = echo
+CFLAGS = -g
+ifeq ($(TARGET),PANDA)
+CFLAGS += -mabi=aapcs-linux
+endif
+PROGS = liboswrapper.a
+OBJECTS = NMI_Event.o NMI_FileOps.o NMI_Math.o NMI_Memory.o NMI_MsgQueue.o NMI_Semaphore.o NMI_Sleep.o NMI_Socket.o NMI_StrUtils.o NMI_Thread.o NMI_Time.o NMI_Timer.o
+
+
+PWD = $(shell pwd)
+ifeq ($(TARGET),PANDA)
+OBJDIR = $(PWD)/../../binary/linux/panda
+else
+OBJDIR = $(PWD)/../../binary/linux/x86
+endif
+
+INCHDR = -I$(PWD)/../
+INCHDR += -I$(PWD).
+INCHDR += -I$(PWD)/../../
+INCHDR += -I$(PWD)/../../../
+INCHDR += -I$(PWD)/include
+INCHDR += -I$(PWD)/source
+ifeq ($(TARGET),PANDA)
+INCHDR += -I/home/npminc/pandaboard/android4.0/system/core/include/
+INCHDR += -I/home/npminc/pandaboard/android4.0/prebuilt/ndk/android-ndk-r4/platforms/android-3/arch-arm/usr/include
+endif
+INCHDR += -DNMI_PLATFORM=NMI_LINUX
+
+VPATH = $(OBJDIR)
+VPATH += source
+
+
+$(OBJDIR)/%.o : %.c
+ @$(ECHO) "###########################################"
+ @$(ECHO) "#### Building" $<
+ $(CC) $(INCHDR) $(CFLAGS) -c $< -o $@
+
+OBJPROG = $(addprefix $(OBJDIR)/, $(PROGS))
+
+$(OBJPROG): $(addprefix $(OBJDIR)/, $(OBJECTS))
+ @$(ECHO) "###########################################"
+ @$(ECHO) "#### Linking library" $@
+ $(AR) rcs $@ $^
+
+all:build
+Debug:build
+Release:build
+cleanDebug:clean
+cleanRelease:clean
+
+clean:
+ $(RM) -f $(OBJPROG) $(addprefix $(OBJDIR)/, $(OBJECTS))
+
+build: $(OBJPROG)
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/include/NMI_platform.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/include/NMI_platform.h
new file mode 100755
index 00000000..14883a7c
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/include/NMI_platform.h
@@ -0,0 +1,209 @@
+#ifndef __NMI_platfrom_H__
+#define __NMI_platfrom_H__
+
+/*!
+* @file NMI_platform.h
+* @brief platform specific file for Linux port
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 15 Dec 2010
+* @version 1.0
+*/
+
+
+/******************************************************************
+ Feature support checks
+*******************************************************************/
+
+// CONFIG_NMI_THREAD_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_STRICT_PRIORITY
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_SEMAPHORE_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SEMAPHORE_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_SLEEP_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SLEEP_HI_RES
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_TIMER_FEATURE is implemented
+
+// CONFIG_NMI_TIMER_PERIODIC is implemented
+
+// CONFIG_NMI_MEMORY_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_POOLS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_DEBUG
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_ASSERTION_SUPPORT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_STRING_UTILS is implemented
+
+// CONFIG_NMI_MSG_QUEUE_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_FILE_OPERATIONS_FEATURE is implemented
+
+// CONFIG_NMI_FILE_OPERATIONS_STRING_API is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_PATH_API
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_TIME_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_UTC_SINCE_1970
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_CALENDER
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_MATH_OPERATIONS_FEATURE is implemented
+
+// CONFIG_NMI_EXTENDED_FILE_OPERATIONS is implemented
+
+// CONFIG_NMI_EXTENDED_STRING_OPERATIONS is implemented
+
+// CONFIG_NMI_EXTENDED_TIME_OPERATIONS is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SOCKET_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/******************************************************************
+ OS specific includes
+*******************************************************************/
+#define _XOPEN_SOURCE 600
+
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+
+/******************************************************************
+ OS specific types
+*******************************************************************/
+
+typedef pthread_t NMI_ThreadHandle;
+
+typedef sem_t NMI_SemaphoreHandle;
+
+typedef struct{
+
+ /* the underlaying posix timer stored here */
+ timer_t timerObject;
+
+ /* semaphore for protection */
+ NMI_SemaphoreHandle hAccessProtection;
+
+ /* the callback is kept here */
+ /* shoud be a proper pointer to function type
+ insted of void*, but the timer callback type is
+ defined later in its header */
+ void* pfCallbackFunction;
+
+ /* the invocation argument is kept here */
+ void* pvArgument;
+
+ /* if NMI_TRUE then the system expects a timer callback after a while
+ if NMI_FALSE then the callback should be ignored */
+ NMI_Bool bPendingTimer;
+
+}NMI_TimerHandle;
+
+/* change into OS specific type */
+typedef void* NMI_MemoryPoolHandle;
+
+/* Message Queue type is a structure */
+typedef struct __Message_struct
+{
+ void* pvBuffer;
+ NMI_Uint32 u32Length;
+ struct __Message_struct *pstrNext;
+} Message;
+
+typedef struct __MessageQueue_struct
+{
+ NMI_SemaphoreHandle hSem;
+ NMI_Bool bExiting;
+ NMI_Uint32 u32ReceiversCount;
+ NMI_SemaphoreHandle strCriticalSection;
+ Message * pstrMessageList;
+} NMI_MsgQueueHandle;
+
+typedef FILE* NMI_FileHandle;
+
+/* change into OS specific type */
+typedef void* NMI_EventHandle;
+
+/*Time represented in 64 bit format*/
+typedef time_t NMI_Time;
+
+/*Time and date represented in a data structure*/
+typedef struct tm NMI_tm;
+
+/*******************************************************************
+ others
+********************************************************************/
+
+/* Generic printf function */
+#define NMI_PRINTF(...) printf(__VA_ARGS__)
+#define __NMI_FILE__ __FILE__
+#define __NMI_FUNCTION__ __FUNCTION__
+#define __NMI_LINE__ __LINE__
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Event.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Event.c
new file mode 100755
index 00000000..29bd2cfa
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Event.c
@@ -0,0 +1,112 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_EVENT_FEATURE
+
+
+/*!
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventCreate(NMI_EventHandle* pHandle, tstrNMI_EventAttrs* pstrAttrs)
+{
+ *pHandle = CreateEvent(
+ NULL, /* default security attributes */
+ FALSE, /* auto reset */
+ FALSE, /* initial state is non-signalled (UNTRIGGERED) */
+ NULL /* unnamed object */);
+
+ if(*pHandle != NULL)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+/*!
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventDestroy(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs)
+{
+ if(CloseHandle(*pHandle) != 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+/*!
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventTrigger(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs)
+{
+ if( SetEvent(*pHandle) != 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+/*!
+* @author syounan
+* @date 10 Oct 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_EventWait(NMI_EventHandle* pHandle,
+ tstrNMI_EventAttrs* pstrAttrs)
+{
+
+ DWORD dwMilliseconds = INFINITE;
+ DWORD dwWaitResult;
+ NMI_ErrNo s32RetStatus;
+
+ #ifdef CONFIG_NMI_EVENT_TIMEOUT
+ if((pstrAttrs != NMI_NULL)
+ && (pstrAttrs->u32TimeOut != NMI_OS_INFINITY))
+ {
+ dwMilliseconds = pstrAttrs->u32TimeOut;
+ }
+ #endif
+
+ dwWaitResult = WaitForSingleObject(*pHandle, dwMilliseconds);
+
+ switch(dwWaitResult)
+ {
+ case WAIT_OBJECT_0:
+ s32RetStatus = NMI_SUCCESS;
+ break;
+
+ case WAIT_TIMEOUT:
+ s32RetStatus = NMI_TIMEOUT;
+ break;
+
+ default:
+ case WAIT_FAILED:
+ s32RetStatus = NMI_FAIL;
+ }
+
+ return s32RetStatus;
+
+}
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c
new file mode 100755
index 00000000..a9ce643d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c
@@ -0,0 +1,539 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef CONFIG_NMI_FILE_OPERATIONS_FEATURE
+
+/**
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_fopen(NMI_FileHandle* pHandle, const NMI_Char* pcPath,
+ tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ tstrNMI_FileOpsAttrs strFileDefaultAttrs;
+ char* mode;
+
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_FileOpsFillDefault(&strFileDefaultAttrs);
+ pstrAttrs = &strFileDefaultAttrs;
+ }
+
+ switch(pstrAttrs->enuAccess)
+ {
+ case NMI_FILE_READ_ONLY:
+ mode = "rb";
+ break;
+
+ case NMI_FILE_READ_WRITE_NEW:
+ mode = "wb+";
+ break;
+
+ default:
+ case NMI_FILE_READ_WRITE_EXISTING:
+ mode = "rb+";
+ break;
+ }
+
+ *pHandle = fopen(pcPath, mode);
+
+ if(*pHandle != NULL)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+
+}
+
+/**
+* @author syounan
+* @date 30 Aug 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_fclose(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ if(fclose(*pHandle) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_fread(NMI_FileHandle* pHandle, NMI_Uint8* pu8Buffer,
+ NMI_Uint32 u32Size, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ return (NMI_Uint32)fread(pu8Buffer, 1, u32Size, *pHandle);
+}
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_fwrite(NMI_FileHandle* pHandle, NMI_Uint8* pu8Buffer,
+ NMI_Uint32 u32Size, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ return (NMI_Uint32)fwrite(pu8Buffer, 1, u32Size, *pHandle);
+}
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Bool NMI_feof(NMI_FileHandle* pHandle)
+{
+ if(feof(*pHandle) != 0)
+ {
+ return NMI_TRUE;
+ }
+ else
+ {
+ return NMI_FALSE;
+ }
+}
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fseek(NMI_FileHandle* pHandle, NMI_Sint32 s32Offset,
+ tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ tstrNMI_FileOpsAttrs strFileDefaultAttrs;
+ int mode;
+
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_FileOpsFillDefault(&strFileDefaultAttrs);
+ pstrAttrs = &strFileDefaultAttrs;
+ }
+
+ switch(pstrAttrs->enuSeekOrigin)
+ {
+ case NMI_SEEK_FROM_START:
+ mode = SEEK_SET;
+ break;
+
+ case NMI_SEEK_FROM_END:
+ mode = SEEK_END;
+ break;
+
+ default:
+ case NMI_SEEK_FROM_CURRENT:
+ mode = SEEK_CUR;
+ }
+
+ if(fseek(* pHandle, s32Offset, mode) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_Uint32 NMI_ftell(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ return ftell(*pHandle);
+}
+
+
+/**
+ * @author syounan
+ * @date 30 Aug 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fflush(NMI_FileHandle* pHandle, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ if(fflush(*pHandle) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/**
+ * @author mabubakr
+ * @date 10 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fdelete(const NMI_Char* pcPath, tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ if(remove(pcPath) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/**
+ * @author remil, syounan
+ * @date 31 Oct 2010
+ * @version 2.0
+ */
+NMI_ErrNo NMI_FileSize(NMI_FileHandle* pstrFileHandle, NMI_Uint32* pu32Size,
+ tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+ struct stat buffer;
+ if(fstat( (*pstrFileHandle)->_fileno, &buffer) != 0)
+ {
+ return NMI_FAIL;
+ }
+ else
+ {
+ *pu32Size = (NMI_Uint32)buffer.st_size;
+ return NMI_SUCCESS;
+ }
+}
+
+#ifdef CONFIG_NMI_EXTENDED_FILE_OPERATIONS
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_Sint32 NMI_getc(NMI_FileHandle* pHandle)
+{
+ return getc(*pHandle);
+}
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_Sint32 NMI_ungetc(NMI_Sint32 c,NMI_FileHandle* pHandle)
+{
+ return ungetc(c,*pHandle);
+}
+
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_freopen(NMI_FileHandle* pHandle, const NMI_Char* pcPath,
+ tstrNMI_FileOpsAttrs* pstrAttrs)
+{
+
+ tstrNMI_FileOpsAttrs strFileDefaultAttrs;
+ char* mode;
+
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_FileOpsFillDefault(&strFileDefaultAttrs);
+ pstrAttrs = &strFileDefaultAttrs;
+ }
+
+ switch(pstrAttrs->enuAccess)
+ {
+ case NMI_FILE_READ_ONLY:
+ mode = "rb";
+ break;
+
+ case NMI_FILE_READ_WRITE_NEW:
+ mode = "wb";
+ break;
+
+ default:
+ case NMI_FILE_READ_WRITE_EXISTING:
+ mode = "rb+";
+ break;
+ }
+
+ *pHandle = freopen(pcPath, mode,*pHandle);
+
+ if(*pHandle != NULL)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+/**
+* @brief Translates character file open mode to the appropriate Enum Value
+* @details
+* @param[in] const NMI_Char* cpMode
+* @return tenuNMI_AccessMode
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+tenuNMI_AccessMode NMI_resolveFileMode(const NMI_Char* cpMode)
+{
+ tenuNMI_AccessMode enumAccessMode;
+ NMI_Char* mode = (NMI_Char*) cpMode;
+
+ while(*mode!= 0)
+ {
+ switch(*mode)
+ {
+ case 'r':
+ enumAccessMode = NMI_FILE_READ_ONLY;
+ break;
+
+ case 'w':
+ enumAccessMode = NMI_FILE_READ_WRITE_NEW;
+ break;
+
+ case 'a':
+ enumAccessMode = NMI_FILE_READ_WRITE_EXISTING;
+ break;
+
+ case '+':
+ enumAccessMode= NMI_FILE_READ_WRITE_EXISTING;
+ }
+ mode++;
+ }
+
+ return enumAccessMode;
+}
+
+
+
+/**
+ * @author remil
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_rename(const NMI_Char *old_filename, const NMI_Char *new_filename)
+{
+ if (rename(old_filename,new_filename)== 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+NMI_ErrNo NMI_setbuf(NMI_FileHandle *pHandle, NMI_Char* buffer)
+{
+ if(pHandle == NMI_NULL || buffer == NMI_NULL)
+ {
+ return NMI_FAIL;
+ }else
+ {
+ setbuf (*pHandle,buffer);
+ return NMI_SUCCESS;
+ }
+}
+
+
+NMI_ErrNo NMI_setvbuf(NMI_FileHandle *pHandle,
+ NMI_Char* buffer,
+ NMI_Sint32 mode,
+ NMI_Uint32 size)
+{
+ if(pHandle != NMI_NULL && buffer != NMI_NULL)
+ {
+ if(setvbuf(*pHandle,buffer,mode,(size_t)size)==0)
+ {
+ return NMI_SUCCESS;
+ }
+ }
+
+ return NMI_FAIL;
+
+}
+
+/*
+*Creates a temporary file in binary update mode (wb+).
+*The tempfile is removed when the program terminates or the stream is closed.
+*On success a pointer to a file stream is returned. On error a null pointer is returned.
+*/
+NMI_ErrNo NMI_tmpfile(NMI_FileHandle *pHandle)
+{
+ *pHandle = tmpfile();
+ if(*pHandle == NMI_NULL)
+ {
+ return NMI_FAIL;
+ }
+ else
+ {
+ return NMI_SUCCESS;
+ }
+}
+
+
+
+/*
+ * Reads a line from the specified stream and stores it into the string pointed to by str.
+ * It stops when either (n-1) characters are read,
+ * the newline character is read, or the end-of-file is reached,
+ * whichever comes first. The newline character is copied to the string.
+ * A null character is appended to the end of the string.
+ * On success a pointer to the string is returned. On error a null pointer is returned.
+ * If the end-of-file occurs before any characters have been read, the string remains unchanged.
+*/
+
+//NMI_Char* NMI_fgets(NMI_Char* str, NMI_Sint32 n, NMI_FileHandle stream)
+//{
+// return fgets(str,n,stream);
+//}
+
+
+/**
+* @brief Clears the end-of-file and error indicators for the given stream.
+* @details As long as the error indicator is set,
+ all stream operations will return an error until NMI_clearerr is called.
+* @param[in] NMI_FileHandle* pHandle
+* @return N/A
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+void NMI_clearerr(NMI_FileHandle* pHandle)
+{
+ clearerr(*pHandle);
+}
+
+
+/**
+* @brief Tests the error indicator for the given stream.
+* @details If the error indicator is set, then it returns NMI_FAIL.
+ If the error indicator is not set, then it returns NMI_SUCCESS.
+* @param[in] NMI_FileHandle* pHandle
+* @return NMI_ErrNo
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_ErrNo NMI_ferror(NMI_FileHandle* pHandle)
+{
+ if(ferror(*pHandle)==0)
+ {
+ return NMI_SUCCESS;
+ }else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/**
+* @brief Generates and returns a valid temporary filename which does not exist.
+* @details If the argument str is a null pointer, then the function returns
+ a pointer to a valid filename.
+ If the argument str is a valid pointer to an array,
+ then the filename is written to the array and a pointer to the same array
+ is returned.The filename may be up to L_tmpnam characters long.
+* @param[in] NMI_Char* str
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_tmpnam(NMI_Char* str)
+{
+ return tmpnam(str);
+}
+
+#endif
+
+
+#ifdef CONFIG_NMI_FILE_OPERATIONS_STRING_API
+
+/**
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fgets(NMI_FileHandle* pHandle, NMI_Char* pcBuffer
+ , NMI_Uint32 u32Maxsize)
+{
+ if( fgets(pcBuffer, u32Maxsize, * pHandle) != NMI_NULL)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+
+}
+
+/**
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_fprintf(NMI_FileHandle* pHandle, const NMI_Char* pcFormat, ...)
+{
+ va_list argptr;
+ va_start(argptr, pcFormat);
+ if(vfprintf(*pHandle, pcFormat, argptr) > 0)
+ {
+ va_end(argptr);
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ va_end(argptr);
+ return NMI_FAIL;
+ }
+}
+
+/**
+ * @author syounan
+ * @date 31 Oct 2010
+ * @version 1.0
+ */
+NMI_ErrNo NMI_vfprintf(NMI_FileHandle* pHandle, const NMI_Char* pcFormat,
+ va_list argptr)
+{
+ if(vfprintf(*pHandle, pcFormat, argptr) > 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Math.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Math.c
new file mode 100755
index 00000000..48bfa805
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Math.c
@@ -0,0 +1,440 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_MATH_OPERATIONS_FEATURE
+
+#include "math.h"
+
+
+/**
+* @brief Returns the arc cosine of x in radians.
+* @details Returns the arc cosine of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value x must be within the range of -1 to +1 (inclusive).
+ The returned value is in the range of 0 to pi (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_acos(NMI_Double x)
+{
+ return acos(x);
+}
+
+/**
+* @brief Returns the arc sine of x in radians.
+* @details Returns the arc sine of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value x must be within the range of -1 to +1 (inclusive).
+ The returned value is in the range of 0 to pi (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_asin(NMI_Double x)
+{
+ return asin(x);
+}
+
+
+/**
+* @brief Returns the arc tangent of x in radians.
+* @details Returns the arc tangent of x in radians.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -p/2 to +p/2 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_atan(NMI_Double x)
+{
+ return atan(x);
+}
+
+/**
+* @brief Returns the arc tangent in radians
+* @details Returns the arc tangent in radians of y/x based on the
+ signs of both values to determine the correct quadrant.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note Both y and x cannot be zero.
+ The returned value is in the range of -p/2 to +p/2 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_atan2(NMI_Double y, NMI_Double x)
+{
+ return atan2(y,x);
+}
+
+
+/**
+* @brief Returns the cosine of a radian angle x.
+* @details Returns the cosine of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_cos(NMI_Double x)
+{
+ return cos(x);
+}
+
+
+/**
+* @brief Returns the hyperbolic cosine of x.
+* @details Returns the hyperbolic cosine of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_cosh(NMI_Double x)
+{
+ return cosh(x);
+}
+
+
+/**
+* @brief Returns the sine of a radian angle x.
+* @details Returns the sine of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sin(NMI_Double x)
+{
+ return sin(x);
+}
+
+
+/**
+* @brief Returns the hyperbolic sine of x.
+* @details Returns the hyperbolic sine of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sinh(NMI_Double x)
+{
+ return sinh(x);
+}
+
+/**
+* @brief Returns the tangent of a radian angle x.
+* @details Returns the tangent of a radian angle x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_tan(NMI_Double x)
+{
+ return tan(x);
+}
+
+/**
+* @brief Returns the hyperbolic tangent of x.
+* @details Returns the hyperbolic tangent of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The value of x has no range.
+ The returned value is in the range of -1 to +1 (inclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_tanh(NMI_Double x)
+{
+ return tanh(x);
+}
+
+
+/**
+* @brief Returns the value of e raised to the xth power.
+* @details Returns the value of e raised to the xth power.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_exp(NMI_Double x)
+{
+ return exp(x);
+}
+
+/**
+* @brief The returned value is the mantissa and the integer pointed to by exponent is the exponent.
+* @details The returned value is the mantissa and the integer pointed to by exponent is the exponent.
+ The resultant value is x=mantissa * 2^exponent.
+* @param[in] NMI_Double x
+* @param[out] NMI_Sint32* exponent
+* @return NMI_Double
+* @note The mantissa is in the range of .5 (inclusive) to 1 (exclusive).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_frexp(NMI_Double x, NMI_Sint32* exponent)
+{
+ return frexp(x,exponent);
+}
+
+
+
+/**
+* @brief Returns x multiplied by 2 raised to the power of exponent.
+* @details Returns x multiplied by 2 raised to the power of exponent.
+ x*2^exponent
+* @param[in] NMI_Double x
+* @param[out] NMI_Sint32 exponent
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_ldexp(NMI_Double x, NMI_Sint32 exponent)
+{
+ return ldexp(x,exponent);
+}
+
+
+/**
+* @brief Returns the natural logarithm (base-e logarithm) of x.
+* @details Returns the natural logarithm (base-e logarithm) of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_log(NMI_Double x)
+{
+ return log(x);
+}
+
+
+
+/**
+* @brief Returns the common logarithm (base-10 logarithm) of x.
+* @details Returns the common logarithm (base-10 logarithm) of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_log10(NMI_Double x)
+{
+ return log10(x);
+}
+
+
+/**
+* @brief Breaks the floating-point number x into integer and fraction components.
+* @details Breaks the floating-point number x into integer and fraction components.
+ The returned value is the fraction component (part after the decimal),
+ and sets integer to the integer component.
+
+* @param[in] NMI_Double x
+* @param[out] NMI_Double* dInteger
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_modf(NMI_Double x,NMI_Double* dInteger)
+{
+ return modf(x,dInteger);
+}
+
+
+
+/**
+* @brief Returns x raised to the power of y.
+* @details Returns x raised to the power of y.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note x cannot be negative if y is a fractional value.
+ x cannot be zero if y is less than or equal to zero.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_pow(NMI_Double x,NMI_Double y)
+{
+ return pow(x,y);
+}
+
+
+
+/**
+* @brief Returns the square root of x.
+* @details Returns the square root of x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note The argument cannot be negative. The returned value is always positive.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_sqrt(NMI_Double x)
+{
+ return sqrt(x);
+}
+
+/**
+* @brief Returns the smallest integer value greater than or equal to x.
+* @details Returns the smallest integer value greater than or equal to x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_ceil(NMI_Double x)
+{
+ return ceil(x);
+}
+
+
+/**
+* @brief Returns the absolute value of x
+* @details Returns the absolute value of x
+ (a negative value becomes positive, positive value is unchanged).
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument.
+ The return value is always positive.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_fabs(NMI_Double x)
+{
+ return fabs(x);
+}
+
+/**
+* @brief Returns the largest integer value less than or equal to x.
+* @details Returns the largest integer value less than or equal to x.
+* @param[in] NMI_Double x
+* @return NMI_Double
+* @note There is no range limit on the argument or return value.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_floor(NMI_Double x)
+{
+ return floor(x);
+}
+
+
+/**
+* @brief Returns the remainder of x divided by y.
+* @details Returns the remainder of x divided by y.
+* @param[in] NMI_Double x
+* @param[in] NMI_Double y
+* @return NMI_Double
+* @note There is no range limit on the return value.
+ If y is zero, then either a range error will occur or the function
+ will return zero (implementation-defined).
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_fmod(NMI_Double x,NMI_Double y)
+{
+ return fmod(x,y);
+}
+
+
+/**
+* @brief
+* @details Returns the absolute value of x.
+ Note that in two's compliment that the most maximum number cannot be
+ represented as a positive number. The result in this case is undefined.
+ The absolute value is returned.
+* @param[in] NMI_Sint32 x
+* @return NMI_Sint32
+* @note
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_abs(NMI_Sint32 x)
+{
+ return abs(x);
+}
+
+
+
+
+/**
+* @brief
+* @details Returns a pseudo-random number in the range of 0 to RAND_MAX.
+* @return NMI_Sint32
+* @note
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_rand()
+{
+ return rand();
+}
+
+
+/**
+* @brief
+* @details This function seeds the random number generator used by the function rand.
+ Seeding srand with the same seed will cause rand to return the same sequence
+ of pseudo-random numbers.
+ If srand is not called, NMI_rand acts as if NMI_srand(1) has been called.
+
+* @param[in] NMI_Uint32 seed
+* @note No value is returned.
+* @author remil
+* @date 2 Nov 2010
+* @version 1.0
+*/
+void NMI_srand(NMI_Uint32 seed)
+{
+ srand(seed);
+}
+
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c
new file mode 100755
index 00000000..d3b4ecaa
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c
@@ -0,0 +1,72 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_MEMORY_FEATURE
+
+#include "stdlib.h"
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryAlloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ if(u32Size > 0)
+ {
+ return malloc(u32Size);
+ }
+ else
+ {
+ return NMI_NULL;
+ }
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryCalloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ return calloc(u32Size, 1);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryRealloc(void* pvOldBlock, NMI_Uint32 u32NewSize,
+ tstrNMI_MemoryAttrs* strAttrs, NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ if(u32NewSize==0)
+ {
+ free(pvOldBlock);
+ return NMI_NULL;
+ }
+ else if(pvOldBlock==NMI_NULL)
+ {
+ return malloc(u32NewSize);
+ }
+ else
+ {
+ return realloc(pvOldBlock, u32NewSize);
+ }
+
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void NMI_MemoryFree(void* pvBlock, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ free(pvBlock);
+}
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c
new file mode 100755
index 00000000..caa814bb
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c
@@ -0,0 +1,213 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_MSG_QUEUE_FEATURE
+
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueCreate(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+ tstrNMI_SemaphoreAttrs strSemAttrs;
+ NMI_SemaphoreFillDefault(&strSemAttrs);
+ strSemAttrs.u32InitCount = 0;
+
+ if( (NMI_SemaphoreCreate(&pHandle->hSem, &strSemAttrs) == NMI_SUCCESS)
+ && (NMI_SemaphoreCreate(&pHandle->strCriticalSection, NMI_NULL) == NMI_SUCCESS))
+ {
+
+ pHandle->pstrMessageList = NULL;
+ pHandle->u32ReceiversCount = 0;
+ pHandle->bExiting = NMI_FALSE;
+
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueDestroy(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+
+ pHandle->bExiting = NMI_TRUE;
+
+ // Release any waiting receiver thread.
+ while(pHandle->u32ReceiversCount > 0)
+ {
+ NMI_SemaphoreRelease(&(pHandle->hSem), NMI_NULL);
+ pHandle->u32ReceiversCount--;
+ }
+
+ NMI_SemaphoreDestroy(&pHandle->hSem, NMI_NULL);
+ NMI_SemaphoreDestroy(&pHandle->strCriticalSection, NMI_NULL);
+
+ while(pHandle->pstrMessageList != NULL)
+ {
+ Message * pstrMessge = pHandle->pstrMessageList->pstrNext;
+ NMI_FREE(pHandle->pstrMessageList);
+ pHandle->pstrMessageList = pstrMessge;
+ }
+
+ return NMI_SUCCESS;
+}
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueSend(NMI_MsgQueueHandle* pHandle,
+ const void * pvSendBuffer, NMI_Uint32 u32SendBufferSize,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+
+ Message * pstrMessage = NULL;
+
+ if( (pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL) )
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_INVALID_ARGUMENT);
+ }
+
+ if(pHandle->bExiting == NMI_TRUE)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ NMI_SemaphoreAcquire(&pHandle->strCriticalSection, NMI_NULL);
+
+ /* construct a new message */
+ pstrMessage = NMI_NEW(Message, 1);
+ NMI_NULLCHECK(s32RetStatus, pstrMessage);
+ pstrMessage->u32Length = u32SendBufferSize;
+ pstrMessage->pstrNext = NULL;
+ pstrMessage->pvBuffer = NMI_MALLOC(u32SendBufferSize);
+ NMI_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
+ NMI_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
+
+
+ /* add it to the message queue */
+ if(pHandle->pstrMessageList == NULL)
+ {
+ pHandle->pstrMessageList = pstrMessage;
+ }
+ else
+ {
+ Message * pstrTailMsg = pHandle->pstrMessageList;
+ while(pstrTailMsg->pstrNext != NULL)
+ {
+ pstrTailMsg = pstrTailMsg->pstrNext;
+ }
+ pstrTailMsg->pstrNext = pstrMessage;
+ }
+
+ NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL);
+
+ NMI_SemaphoreRelease(&pHandle->hSem, NMI_NULL);
+
+ NMI_CATCH(s32RetStatus)
+ {
+ /* error occured, free any allocations */
+ if(pstrMessage != NULL)
+ {
+ if(pstrMessage->pvBuffer != NULL)
+ {
+ NMI_FREE(pstrMessage->pvBuffer);
+ }
+ NMI_FREE(pstrMessage);
+ }
+ }
+
+ return s32RetStatus;
+}
+
+
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueRecv(NMI_MsgQueueHandle* pHandle,
+ void * pvRecvBuffer, NMI_Uint32 u32RecvBufferSize,
+ NMI_Uint32* pu32ReceivedLength,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+
+ Message * pstrMessage;
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+
+ if( (pHandle == NULL) || (u32RecvBufferSize == 0)
+ || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL) )
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_INVALID_ARGUMENT);
+ }
+
+ if(pHandle->bExiting == NMI_TRUE)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ NMI_SemaphoreAcquire(&pHandle->strCriticalSection, NMI_NULL);
+ pHandle->u32ReceiversCount++;
+ NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL);
+
+ s32RetStatus = NMI_SemaphoreAcquire(&(pHandle->hSem), NMI_NULL);
+ NMI_ERRORCHECK(s32RetStatus);
+
+ if(pHandle->bExiting)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ NMI_SemaphoreAcquire(&pHandle->strCriticalSection, NMI_NULL);
+
+ pstrMessage = pHandle->pstrMessageList;
+ if(pstrMessage == NULL)
+ {
+ NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL);
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+ /* check buffer size */
+ if(u32RecvBufferSize < pstrMessage->u32Length)
+ {
+ NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL);
+ NMI_SemaphoreRelease(&pHandle->hSem, NMI_NULL);
+ NMI_ERRORREPORT(s32RetStatus, NMI_BUFFER_OVERFLOW);
+ }
+
+ /* consume the message */
+ pHandle->u32ReceiversCount--;
+ NMI_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
+ *pu32ReceivedLength = pstrMessage->u32Length;
+
+ pHandle->pstrMessageList = pstrMessage->pstrNext;
+
+ NMI_FREE(pstrMessage->pvBuffer);
+ NMI_FREE(pstrMessage);
+
+ NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL);
+
+ NMI_CATCH(s32RetStatus)
+ {
+ }
+ return s32RetStatus;
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c
new file mode 100755
index 00000000..d07bfa0d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c
@@ -0,0 +1,67 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_SEMAPHORE_FEATURE
+
+NMI_ErrNo NMI_SemaphoreCreate(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ tstrNMI_SemaphoreAttrs strDefaultAttrs;
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_SemaphoreFillDefault(&strDefaultAttrs);
+ pstrAttrs = &strDefaultAttrs;
+ }
+
+ if(sem_init(pHandle, 0, pstrAttrs->u32InitCount) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+NMI_ErrNo NMI_SemaphoreDestroy(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ if(sem_destroy(pHandle) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+NMI_ErrNo NMI_SemaphoreAcquire(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ if(sem_wait(pHandle) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+NMI_ErrNo NMI_SemaphoreRelease(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ if(sem_post(pHandle) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c
new file mode 100755
index 00000000..b55abaaa
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c
@@ -0,0 +1,27 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_SLEEP_FEATURE
+
+/*
+* @author syounan
+* @date 10 Aug 2010
+* @version 1.0
+*/
+void NMI_Sleep(NMI_Uint32 u32TimeMilliSec)
+{
+
+ struct timespec tspec, trem;
+ tspec.tv_sec = u32TimeMilliSec/1000L;
+ u32TimeMilliSec %= 1000L;
+ tspec.tv_nsec = u32TimeMilliSec * 1000000L;
+
+ while(nanosleep(&tspec, &trem) != 0)
+ {
+ tspec.tv_sec = trem.tv_sec;
+ tspec.tv_nsec = trem.tv_nsec;
+ }
+}
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c
new file mode 100755
index 00000000..0f76f79a
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c
@@ -0,0 +1,188 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_SOCKET_FEATURE
+
+
+
+/*=============================================================================
+ Includes
+==============================================================================*/
+
+#ifdef _WIN32
+//#include <winsock2.h>
+//#include <ws2tcpip.h>
+#elif defined unix
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
+
+
+#ifdef _WIN32
+#pragma comment(lib,"ws2_32.lib")
+#endif
+
+#ifdef _WIN32
+#define SOCKET_ERROR_CODE (WSAGetLastError())
+#elif defined unix
+#define SOCKET_ERROR_CODE (errno)
+#endif
+
+
+/*=============================================================================
+ Macros
+==============================================================================*/
+
+#define BUFSIZE ((NMI_Uint32)1024)
+
+
+
+
+/*=============================================================================
+ API Implementation
+==============================================================================*/
+
+/*============================================================================*/
+/*!
+* @struct
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+void tcpReceiverThread(void* args)
+{
+ NMI_Sint32 s32Status;
+ NMI_Uint32 u32SocketFd;
+ NMI_Uint8 buf[BUFSIZE];
+
+ tstrTcpConnection* pstrTcpConnection = (tstrTcpConnection*)args;
+
+ NMI_NULLCHECK(s32Status,pstrTcpConnection);
+
+
+ u32SocketFd = pstrTcpConnection->u32SocketFd;
+
+ while(recv(u32SocketFd,buf,BUFSIZ,0)> 0)
+ {
+ if(pstrTcpConnection->fpTcpReceptionCB!= NMI_NULL)
+ {
+ pstrTcpConnection->fpTcpReceptionCB(buf,
+ BUFSIZE,
+ (void*)pstrTcpConnection);
+ }
+ }
+ERRORHANDLER:
+
+ closesocket(pstrTcpConnection->u32SocketFd);
+ return;
+
+}
+
+
+
+/*============================================================================*/
+/*!
+* @struct
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+NMI_ErrNo NMI_TcpConnect(tstrTcpConnection* pstrTcpConnection)
+{
+ struct sockaddr_in server;
+ struct hostent * hp;
+
+ NMI_Sint32 s32Status;
+ NMI_Uint32 addr;
+
+
+#ifdef _MSC_VER
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(2,2), &wsaData);
+#endif
+
+
+ NMI_ThreadFillDefault(&(pstrTcpConnection->strThreadAttrs));
+
+ pstrTcpConnection->u32SocketFd =(NMI_Uint32) socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+
+ if(inet_addr(pstrTcpConnection->cpIPAddress)==INADDR_NONE)
+ {
+ hp=gethostbyname(pstrTcpConnection->cpIPAddress);
+ }
+ else
+ {
+ addr=inet_addr(pstrTcpConnection->cpIPAddress);
+ hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
+ }
+
+ NMI_NULLCHECK(pstrTcpConnection->u32SocketFd,hp);
+
+ server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
+ server.sin_family=AF_INET;
+ server.sin_port=htons(pstrTcpConnection->s32Port);
+
+ s32Status = connect(pstrTcpConnection->u32SocketFd,(struct sockaddr*)&server, sizeof(server));
+ NMI_ERRORCHECK(s32Status);
+
+ return NMI_ThreadCreate(&(pstrTcpConnection->strThreadHandle),
+ tcpReceiverThread,
+ pstrTcpConnection,
+ &(pstrTcpConnection->strThreadAttrs));
+
+ERRORHANDLER:
+ return NMI_FAIL;
+}
+
+/*============================================================================*/
+/*!
+* @struct
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+NMI_ErrNo NMI_TcpSend(tstrTcpConnection* pstrTcpConnection,
+ NMI_Uint8* u8Buf,
+ NMI_Uint32 u32DataSize)
+{
+ if( send(pstrTcpConnection->u32SocketFd,u8Buf, u32DataSize,0) > 0)
+ {
+ return NMI_SUCCESS;
+ }
+ return NMI_FAIL;
+}
+/*============================================================================*/
+/*!
+* @struct
+* @brief
+* @author remil
+* @date 19 Oct 2010
+* @version 1.0
+*/
+/*============================================================================*/
+void NMI_TcpDisconnect(tstrTcpConnection* pstrTcpConnection)
+{
+ closesocket(pstrTcpConnection->u32SocketFd);
+}
+
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c
new file mode 100755
index 00000000..18a14937
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c
@@ -0,0 +1,483 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_STRING_UTILS
+
+#include "string.h"
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_memcmp(const void* pvArg1, const void* pvArg2, NMI_Uint32 u32Count)
+{
+ return memcmp(pvArg1, pvArg2, u32Count);
+}
+
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void NMI_memcpy_INTERNAL(void* pvTarget, const void* pvSource, NMI_Uint32 u32Count)
+{
+ memcpy(pvTarget, pvSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_memset(void* pvTarget, NMI_Uint8 u8SetValue, NMI_Uint32 u32Count)
+{
+ return memset(pvTarget, u8SetValue, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncat(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count)
+{
+ return strncat(pcTarget, pcSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncpy(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count)
+{
+ return strncpy(pcTarget, pcSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strcmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ s32Result = strcmp(pcStr1, pcStr2);
+ if(s32Result < 0)
+ {
+ s32Result = -1;
+ }
+ else if(s32Result > 0)
+ {
+ s32Result = 1;
+ }
+ }
+
+ return s32Result;
+}
+
+NMI_Sint32 NMI_strncmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ s32Result = strncmp(pcStr1, pcStr2, u32Count);
+ if(s32Result < 0)
+ {
+ s32Result = -1;
+ }
+ else if(s32Result > 0)
+ {
+ s32Result = 1;
+ }
+ }
+
+ return s32Result;
+}
+
+/*
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_Sint32 NMI_strcmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ NMI_Char cTestedChar1, cTestedChar2;
+ do
+ {
+ cTestedChar1 = *pcStr1;
+ if((*pcStr1 >= 'a') && (*pcStr1 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar1 -= 32;
+ }
+
+ cTestedChar2 = *pcStr2;
+ if((*pcStr2 >= 'a') && (*pcStr2 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar2 -= 32;
+ }
+
+ pcStr1++;
+ pcStr2++;
+
+ }while((cTestedChar1 == cTestedChar2)
+ && (cTestedChar1 != 0)
+ && (cTestedChar2 != 0));
+
+ if(cTestedChar1 > cTestedChar2)
+ {
+ s32Result = 1;
+ }
+ else if(cTestedChar1 < cTestedChar2)
+ {
+ s32Result = -1;
+ }
+ else
+ {
+ s32Result = 0;
+ }
+ }
+
+ return s32Result;
+}
+
+/*!
+* @author aabozaeid
+* @date 8 Dec 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strncmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ NMI_Char cTestedChar1, cTestedChar2;
+ do
+ {
+ cTestedChar1 = *pcStr1;
+ if((*pcStr1 >= 'a') && (*pcStr1 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar1 -= 32;
+ }
+
+ cTestedChar2 = *pcStr2;
+ if((*pcStr2 >= 'a') && (*pcStr2 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar2 -= 32;
+ }
+
+ pcStr1++;
+ pcStr2++;
+ u32Count--;
+
+ }while( (u32Count > 0)
+ && (cTestedChar1 == cTestedChar2)
+ && (cTestedChar1 != 0)
+ && (cTestedChar2 != 0));
+
+ if(cTestedChar1 > cTestedChar2)
+ {
+ s32Result = 1;
+ }
+ else if(cTestedChar1 < cTestedChar2)
+ {
+ s32Result = -1;
+ }
+ else
+ {
+ s32Result = 0;
+ }
+ }
+
+ return s32Result;
+
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strlen(const NMI_Char* pcStr)
+{
+ return (NMI_Uint32)strlen(pcStr);
+}
+
+/*!
+* @author bfahmy
+* @date 28 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strtoint(const NMI_Char* pcStr)
+{
+ return (NMI_Sint32)(atoi(pcStr));
+}
+
+/*
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_ErrNo NMI_snprintf(NMI_Char* pcTarget, NMI_Uint32 u32Size,
+ const NMI_Char* pcFormat, ...)
+{
+ va_list argptr;
+ va_start(argptr, pcFormat);
+ if(vsnprintf(pcTarget, u32Size, pcFormat, argptr) < 0)
+ {
+ /* if turncation happens windows does not properly terminate strings */
+ pcTarget[u32Size - 1] = 0;
+ }
+ va_end(argptr);
+
+ /* I find no sane way of detecting errors in windows, so let it all succeed ! */
+ return NMI_SUCCESS;
+}
+
+#ifdef CONFIG_NMI_EXTENDED_STRING_OPERATIONS
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c in the first n bytes
+ of the string pointed to by the argument str.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_memchr(const void *str, NMI_Char c, NMI_Sint32 n)
+{
+ return (NMI_Char*) memchr(str,c,(size_t)n);
+}
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c (an unsigned char)
+ in the string pointed to by the argument str.
+ The terminating null character is considered to be part of the string.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strchr(const NMI_Char *str, NMI_Char c)
+{
+ return strchr(str,c);
+}
+
+/**
+* @brief
+* @details Appends the string pointed to by str2 to the end of the string pointed to by str1.
+ The terminating null character of str1 is overwritten.
+ Copying stops once the terminating null character of str2 is copied. If overlapping occurs, the result is undefined.
+ The argument str1 is returned.
+* @param[in] NMI_Char* str1,
+* @param[in] NMI_Char* str2,
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcat(NMI_Char *str1, const NMI_Char *str2)
+{
+ return strcat(str1, str2);
+}
+
+/**
+* @brief
+* @details Copy pcSource to pcTarget
+* @param[in] NMI_Char* pcTarget
+* @param[in] const NMI_Char* pcSource
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcpy(NMI_Char* pcTarget, const NMI_Char* pcSource)
+{
+ return strncpy(pcTarget, pcSource, strlen(pcSource));
+}
+
+/**
+* @brief
+* @details Finds the first sequence of characters in the string str1 that
+ does not contain any character specified in str2.
+ Returns the length of this first sequence of characters found that
+ do not match with str2.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strcspn(const NMI_Char *str1, const NMI_Char *str2)
+{
+ return (NMI_Uint32)strcspn(str1, str2);
+}
+
+/**
+* @brief
+* @details Searches an internal array for the error number errnum and returns a pointer
+ to an error message string.
+ Returns a pointer to an error message string.
+* @param[in] NMI_Sint32 errnum
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strerror(NMI_Sint32 errnum)
+{
+ return strerror(errnum);
+}
+
+
+/**
+* @brief
+* @details Finds the first occurrence of the entire string str2
+ (not including the terminating null character) which appears in the string str1.
+ Returns a pointer to the first occurrence of str2 in str1.
+ If no match was found, then a null pointer is returned.
+ If str2 points to a string of zero length, then the argument str1 is returned.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strstr(const NMI_Char *str1, const NMI_Char *str2)
+{
+ return strstr(str1, str2);
+}
+
+/**
+* @brief
+* @details Parses the C string str interpreting its content as a floating point
+ number and returns its value as a double.
+ If endptr is not a null pointer, the function also sets the value pointed
+ by endptr to point to the first character after the number.
+* @param[in] const NMI_Char* str
+* @param[in] NMI_Char** endptr
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_StringToDouble(const NMI_Char* str, NMI_Char** endptr)
+{
+ return strtod (str,endptr);
+}
+
+
+/**
+* @brief Parses the C string str interpreting its content as an unsigned integral
+ number of the specified base, which is returned as an unsigned long int value.
+* @details The function first discards as many whitespace characters as necessary
+ until the first non-whitespace character is found.
+ Then, starting from this character, takes as many characters as possible
+ that are valid following a syntax that depends on the base parameter,
+ and interprets them as a numerical value.
+ Finally, a pointer to the first character following the integer
+ representation in str is stored in the object pointed by endptr.
+* @param[in] const NMI_Char *str
+* @param[in] NMI_Char **endptr
+* @param[in] NMI_Sint32 base
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringToUint32(const NMI_Char *str, NMI_Char **endptr, NMI_Sint32 base)
+{
+ return strtoul(str, endptr, base);
+}
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c
new file mode 100755
index 00000000..0db814b9
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c
@@ -0,0 +1,52 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_THREAD_FEATURE
+
+NMI_ErrNo NMI_ThreadCreate(NMI_ThreadHandle* pHandle, tpfNMI_ThreadFunction pfEntry,
+ void* pvArg, tstrNMI_ThreadAttrs* pstrAttrs)
+{
+ pthread_attr_t attr;
+ tstrNMI_ThreadAttrs strDefaultAttrs;
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_ThreadFillDefault(&strDefaultAttrs);
+ pstrAttrs = &strDefaultAttrs;
+ }
+
+ if(pthread_attr_init(&attr) == 0)
+ {
+ /*if(pthread_attr_setstacksize(&attr, pstrAttrs->u32StackSize) != 0)
+ {
+ return NMI_FAIL;
+ }*/
+
+ if(pthread_create(pHandle, &attr, (void*(*)(void*))pfEntry, pvArg) == 0)
+ {
+ s32RetStatus = NMI_SUCCESS;
+ }
+
+ pthread_attr_destroy(&attr);
+ }
+
+ return s32RetStatus;
+}
+
+NMI_ErrNo NMI_ThreadDestroy(NMI_ThreadHandle* pHandle,
+ tstrNMI_ThreadAttrs* pstrAttrs)
+{
+ if(pthread_join(*pHandle, NULL) == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Time.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Time.c
new file mode 100755
index 00000000..2db75643
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Time.c
@@ -0,0 +1,167 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_TIME_FEATURE
+
+
+NMI_Uint32 NMI_TimeMsec(void)
+{
+ NMI_Uint32 u32Time = 0;
+ struct timespec current_time;
+
+ if (clock_gettime(CLOCK_REALTIME, &current_time) == 0)
+ {
+ u32Time = current_time.tv_sec * 1000;
+ u32Time += current_time.tv_nsec / 1000000;
+ }
+
+ return u32Time;
+}
+
+
+#ifdef CONFIG_NMI_EXTENDED_TIME_OPERATIONS
+
+/**
+* @brief
+* @details function returns the implementation's best approximation to the
+ processor time used by the process since the beginning of an
+ implementation-dependent time related only to the process invocation.
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_Clock()
+{
+ return (NMI_Uint32)clock();
+}
+
+
+/**
+* @brief
+* @details The difftime() function computes the difference between two calendar
+ times (as returned by NMI_GetTime()): time1 - time0.
+* @param[in] NMI_Time time1
+* @param[in] NMI_Time time0
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_DiffTime(NMI_Time time1, NMI_Time time0)
+{
+ return difftime(time1,time0);
+}
+
+
+
+/**
+* @brief
+* @details The gmtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time,
+ expressed as Coordinated Universal Time (UTC).
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_GmTime(const NMI_Time* timer)
+{
+ return gmtime(timer);
+}
+
+
+/**
+* @brief
+* @details The localtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time, expressed
+ as a local time. The function corrects for the timezone and any
+ seasonal time adjustments. Local timezone information is used as
+ though localtime() calls tzset().
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_LocalTime(const NMI_Time* timer)
+{
+ return localtime(timer);
+}
+
+
+/**
+* @brief
+* @details The mktime() function converts the broken-down time,
+ expressed as local time, in the structure pointed to by timeptr,
+ into a time since the Epoch value with the same encoding as that
+ of the values returned by time(). The original values of the tm_wday
+ and tm_yday components of the structure are ignored, and the original
+ values of the other components are not restricted to the ranges described
+ in the <time.h> entry.
+* @param[in] NMI_tm* timer
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_MkTime(NMI_tm* timer)
+{
+ return mktime(timer);
+}
+
+
+/**
+* @brief
+* @details The strftime() function places bytes into the array
+ pointed to by s as controlled by the string pointed to by format.
+* @param[in] NMI_Char* s
+* @param[in] NMI_Uint32 maxSize
+* @param[in] const NMI_Char* format
+* @param[in] const NMI_tm* timptr
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringFormatTime(NMI_Char* s,
+ NMI_Uint32 maxSize,
+ const NMI_Char* format,
+ const NMI_tm* timptr)
+{
+ return (NMI_Uint32)strftime(s,
+ (size_t) maxSize,
+ format,
+ timptr);
+}
+
+
+/**
+* @brief The NMI_GetTime() function returns the value of time in seconds since the Epoch.
+* @details The tloc argument points to an area where the return value is also stored.
+ If tloc is a null pointer, no value is stored.
+* @param[in] NMI_Time* tloc
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_GetTime(NMI_Time* tloc)
+{
+ return time(tloc);
+}
+
+
+#endif
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c
new file mode 100755
index 00000000..0d3d136d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c
@@ -0,0 +1,181 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_TIMER_FEATURE
+
+#include <signal.h>
+
+static void TimerCallbackWrapper(union sigval val)
+{
+ NMI_TimerHandle* pHandle = (NMI_TimerHandle*)val.sival_ptr;
+
+ if(NMI_SemaphoreAcquire(&(pHandle->hAccessProtection),
+ NMI_NULL) == NMI_SUCCESS)
+ {
+ if(pHandle->bPendingTimer == NMI_TRUE)
+ {
+ ((tpfNMI_TimerFunction)pHandle->pfCallbackFunction)
+ (pHandle->pvArgument);
+ }
+ NMI_SemaphoreRelease(&(pHandle->hAccessProtection), NMI_NULL);
+ }
+}
+
+NMI_ErrNo NMI_TimerCreate(NMI_TimerHandle* pHandle,
+ tpfNMI_TimerFunction pfCallback, tstrNMI_TimerAttrs* pstrAttrs)
+{
+
+ struct sigevent strSigEv;
+
+ strSigEv.sigev_notify = SIGEV_THREAD;
+ strSigEv.sigev_value.sival_ptr = pHandle;
+ strSigEv.sigev_notify_function = TimerCallbackWrapper;
+ strSigEv.sigev_notify_attributes = NULL;
+
+ pHandle->pfCallbackFunction = pfCallback;
+ pHandle->pvArgument = NMI_NULL;
+
+ if((NMI_SemaphoreCreate(&(pHandle->hAccessProtection), NMI_NULL) == NMI_SUCCESS)
+ && (timer_create(CLOCK_REALTIME, &strSigEv, &(pHandle->timerObject)) == 0))
+ {
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+NMI_ErrNo NMI_TimerDestroy(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+
+ s32RetStatus = NMI_TimerStop(pHandle, NMI_NULL);
+
+ /* important : I use the AND operator '&' here instead of '&&' on purpose
+ because I want both functions to be called anyway */
+ if( (timer_delete(pHandle->timerObject) == 0)
+ & (NMI_SemaphoreDestroy(&(pHandle->hAccessProtection), NMI_NULL)
+ == NMI_SUCCESS))
+ {
+ /* do nothing */
+ }
+ else
+ {
+ s32RetStatus = NMI_FAIL;
+ }
+
+ return s32RetStatus;
+}
+
+static NMI_ErrNo SetupTimer(NMI_TimerHandle* pHandle, NMI_Uint32 u32Timeout, void* pvArg, NMI_Bool bPeriodic)
+{
+ struct itimerspec strTimeValue;
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+
+ strTimeValue.it_value.tv_sec = u32Timeout/1000L;
+ strTimeValue.it_value.tv_nsec = (u32Timeout % 1000L) * 1000000L;
+
+ if(bPeriodic == NMI_TRUE)
+ {
+ /* enable periodic timer */
+ strTimeValue.it_interval.tv_sec = strTimeValue.it_value.tv_sec;
+ strTimeValue.it_interval.tv_nsec = strTimeValue.it_value.tv_nsec;
+ }
+ else
+ {
+ /* disable periodic timer */
+ strTimeValue.it_interval.tv_sec = 0;
+ strTimeValue.it_interval.tv_nsec = 0;
+ }
+
+ s32RetStatus = NMI_SemaphoreAcquire(&(pHandle->hAccessProtection),
+ NMI_NULL);
+ NMI_ERRORCHECK(s32RetStatus);
+
+ if(u32Timeout != 0)
+ {
+ pHandle->pvArgument = pvArg;
+ pHandle->bPendingTimer = NMI_TRUE;
+ }
+ else
+ {
+ pHandle->bPendingTimer = NMI_FALSE;
+ }
+ if(timer_settime(pHandle->timerObject,
+ 0,
+ &strTimeValue,
+ NMI_NULL) != 0)
+ {
+ s32RetStatus = NMI_FAIL;
+ }
+
+ /* this part does not follow the usual error checking coventions, because :
+ - I want to release the semaphore even if earlier function returned error
+ - I don't want to overwrite s32RetStatus in case of an earlier failure
+ */
+ if(NMI_SemaphoreRelease(&(pHandle->hAccessProtection), NMI_NULL)
+ != NMI_SUCCESS)
+ {
+ s32RetStatus = NMI_FAIL;
+ }
+
+ NMI_CATCH(s32RetStatus)
+ {
+ }
+
+ return s32RetStatus;
+
+
+}
+
+NMI_ErrNo NMI_TimerStart(NMI_TimerHandle* pHandle, NMI_Uint32 u32Timeout,
+ void* pvArg, tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_Bool bPeriodic = NMI_FALSE;
+ NMI_ErrNo s32RetStatus;
+
+ #ifdef CONFIG_NMI_TIMER_PERIODIC
+ if((pstrAttrs != NMI_NULL)
+ && (pstrAttrs->bPeriodicTimer == NMI_TRUE))
+ {
+ /* enable periodic timer */
+ bPeriodic = NMI_TRUE;
+ }
+ #endif
+
+ if(u32Timeout == 0)
+ {
+ if(bPeriodic == NMI_TRUE)
+ {
+ /* a periodic timer with zero timeout does not make any sense,
+ so we error on that */
+ NMI_ERRORREPORT(s32RetStatus, NMI_INVALID_ARGUMENT);
+ }
+ else
+ {
+ /* in Linux timer API a timeout of zero means 'disable timer'
+ but in NMI API a timeout of zero means 'run it as soon as
+ possible' so here we workaround it by waiting just one msec */
+ u32Timeout = 1;
+ }
+ }
+
+ s32RetStatus = SetupTimer(pHandle, u32Timeout, pvArg, bPeriodic);
+
+ NMI_CATCH(s32RetStatus)
+ {
+ }
+
+ return s32RetStatus;
+}
+
+
+NMI_ErrNo NMI_TimerStop(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs)
+{
+ return SetupTimer(pHandle, 0, NMI_NULL, NMI_FALSE);
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/Makefile b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/Makefile
new file mode 100755
index 00000000..c50e8a99
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/Makefile
@@ -0,0 +1,87 @@
+MAKE = make
+RM = rm
+MV = mv
+ECHO = echo
+CP = cp
+PWD = $(shell pwd)
+
+
+obj-m := lib.a
+lib-y := source/NMI_MsgQueue.o source/NMI_StrUtils.o source/NMI_Memory.o\
+ source/NMI_Sleep.o source/NMI_Thread.o source/NMI_Time.o\
+ source/NMI_Semaphore.o source/NMI_Timer.o\
+
+ccflags-y += -I$(src)/../../../
+ccflags-y += -DNMI_PLATFORM=NMI_LINUXKERNEL
+ccflags-y += -Wno-unused-function
+
+
+
+
+
+ifeq ($(TARGET),SIMULATION)
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+OUT_ARCH = x86
+else ifeq ($(TARGET),PANDA)
+KERNELDIR ?= $(DEV_TREE)/kernel/omap
+ifeq ($(ANDR_VER),4.3)
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi- ARCH=arm
+else ifeq ($(ANDR_VER),4.2)
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- ARCH=arm
+else
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm
+endif
+OUT_ARCH = ARM-3.0
+else ifeq ($(TARGET),BEAGLE)
+KERNELDIR ?= $(DEV_TREE)
+OUT_ARCH = ARM-2.6.39
+MAKE_FLAGS := CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DBEAGLE_BOARD
+else ifeq ($(TARGET),NM73131)
+KERNELDIR ?= $(DEV_TREE_LPC)
+OUT_ARCH = ARM-2.6.28.2
+MAKE_FLAGS := CROSS_COMPILE=arm-linux- ARCH=arm
+#EXTRA_CFLAGS += -DNM73131_0_BOARD -DUSE_WIRELESS
+EXTRA_CFLAGS += -DNM73131_0_BOARD
+else ifeq ($(TARGET),ALLWINNER)
+KERNELDIR ?= $(DEV_TREE)/linux-3.0
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/buildroot/output/external-toolchain/bin/arm-none-linux-gnueabi- ARCH=arm
+OUT_ARCH = ARM-3.0
+else ifeq ($(TARGET),ALLWINNER_A20)
+KERNELDIR ?= $(DEV_TREE)/linux-3.3
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A20 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.3
+else ifeq ($(TARGET),ALLWINNER_A23)
+KERNELDIR ?= $(DEV_TREE)/linux-3.4
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A23 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.4
+else
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+OUT_ARCH = x86
+TARGET=SIMULATION
+endif
+
+
+
+all:
+ @$(ECHO) "###########################################"
+ @$(ECHO) "###### Building NMI OS Wrapper lib #######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules $(MAKE_FLAGS)
+ mkdir -p ../../binary/linux/$(OUT_ARCH)
+ $(MV) $(PWD)/lib.a ../../binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+
+
+
+clean:
+ @$(ECHO) "###########################################"
+ @$(ECHO) "###### Cleaning NMI OS Wrapper lib #######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
+ $(RM) -f $(OBJPROG)
+ $(RM) -f ../../binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h
new file mode 100755
index 00000000..24ce63d9
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h
@@ -0,0 +1,184 @@
+#ifndef __NMI_platfrom_H__
+#define __NMI_platfrom_H__
+
+/*!
+* @file NMI_platform.h
+* @brief platform specific file for Linux port
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 15 Dec 2010
+* @version 1.0
+*/
+
+
+/******************************************************************
+ Feature support checks
+*******************************************************************/
+
+// CONFIG_NMI_THREAD_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_SUSPEND_CONTROL
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_STRICT_PRIORITY
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_SEMAPHORE_FEATURE is implemented
+
+/* remove the following block when implementing its feature
+#ifdef CONFIG_NMI_SEMAPHORE_TIMEOUT
+#error This feature is not supported by this OS
+#endif*/
+
+// CONFIG_NMI_SLEEP_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+//#ifdef CONFIG_NMI_SLEEP_HI_RES
+//#error This feature is not supported by this OS
+//#endif
+
+// CONFIG_NMI_TIMER_FEATURE is implemented
+
+// CONFIG_NMI_TIMER_PERIODIC is implemented
+
+// CONFIG_NMI_MEMORY_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_POOLS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_DEBUG
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_ASSERTION_SUPPORT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_STRING_UTILS is implemented
+
+// CONFIG_NMI_MSG_QUEUE_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+/*#ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+#error This feature is not supported by this OS
+#endif*/
+
+// CONFIG_NMI_FILE_OPERATIONS_FEATURE is implemented
+
+// CONFIG_NMI_FILE_OPERATIONS_STRING_API is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_FILE_OPERATIONS_PATH_API
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_TIME_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_UTC_SINCE_1970
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_CALENDER
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_EVENT_TIMEOUT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_MATH_OPERATIONS_FEATURE is implemented
+
+// CONFIG_NMI_EXTENDED_FILE_OPERATIONS is implemented
+
+// CONFIG_NMI_EXTENDED_STRING_OPERATIONS is implemented
+
+// CONFIG_NMI_EXTENDED_TIME_OPERATIONS is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SOCKET_FEATURE
+#error This feature is not supported by this OS
+#endif
+
+/******************************************************************
+ OS specific includes
+*******************************************************************/
+#define _XOPEN_SOURCE 600
+
+#include <linux/kthread.h>
+#include <linux/semaphore.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/time.h>
+#include <linux/version.h>
+#include "linux/string.h"
+/******************************************************************
+ OS specific types
+*******************************************************************/
+
+typedef struct task_struct *NMI_ThreadHandle;
+
+typedef void* NMI_MemoryPoolHandle;
+typedef struct semaphore NMI_SemaphoreHandle;
+
+typedef struct timer_list NMI_TimerHandle ;
+
+
+
+/* Message Queue type is a structure */
+typedef struct __Message_struct
+{
+ void* pvBuffer;
+ NMI_Uint32 u32Length;
+ struct __Message_struct *pstrNext;
+} Message;
+
+typedef struct __MessageQueue_struct
+{
+ NMI_SemaphoreHandle hSem;
+ spinlock_t strCriticalSection;
+ NMI_Bool bExiting;
+ NMI_Uint32 u32ReceiversCount;
+ Message * pstrMessageList;
+} NMI_MsgQueueHandle;
+
+
+
+/*Time represented in 64 bit format*/
+typedef time_t NMI_Time;
+
+
+/*******************************************************************
+ others
+********************************************************************/
+
+/* Generic printf function */
+#define NMI_PRINTF(...) printk(__VA_ARGS__)
+#define __NMI_FILE__ __FILE__
+#define __NMI_FUNCTION__ __FUNCTION__
+#define __NMI_LINE__ __LINE__
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c
new file mode 100755
index 00000000..d73bdaf4
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c
@@ -0,0 +1,71 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_MEMORY_FEATURE
+
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryAlloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ if(u32Size > 0)
+ {
+ return kmalloc(u32Size, GFP_ATOMIC);
+ }
+ else
+ {
+ return NMI_NULL;
+ }
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryCalloc(NMI_Uint32 u32Size, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ return kcalloc(u32Size, 1,GFP_KERNEL);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_MemoryRealloc(void* pvOldBlock, NMI_Uint32 u32NewSize,
+ tstrNMI_MemoryAttrs* strAttrs, NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ if(u32NewSize==0)
+ {
+ kfree(pvOldBlock);
+ return NMI_NULL;
+ }
+ else if(pvOldBlock==NMI_NULL)
+ {
+ return kmalloc(u32NewSize, GFP_KERNEL);
+ }
+ else
+ {
+ return krealloc(pvOldBlock, u32NewSize, GFP_KERNEL);
+ }
+
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void NMI_MemoryFree(void* pvBlock, tstrNMI_MemoryAttrs* strAttrs,
+ NMI_Char* pcFileName, NMI_Uint32 u32LineNo)
+{
+ kfree(pvBlock);
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c
new file mode 100755
index 00000000..a4468eaf
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c
@@ -0,0 +1,233 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include <linux/spinlock.h>
+#ifdef CONFIG_NMI_MSG_QUEUE_FEATURE
+
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueCreate(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+ tstrNMI_SemaphoreAttrs strSemAttrs;
+ NMI_SemaphoreFillDefault(&strSemAttrs);
+ strSemAttrs.u32InitCount = 0;
+
+ spin_lock_init(&pHandle->strCriticalSection);
+ if( (NMI_SemaphoreCreate(&pHandle->hSem, &strSemAttrs) == NMI_SUCCESS))
+ {
+
+ pHandle->pstrMessageList = NULL;
+ pHandle->u32ReceiversCount = 0;
+ pHandle->bExiting = NMI_FALSE;
+
+ return NMI_SUCCESS;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+}
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueDestroy(NMI_MsgQueueHandle* pHandle,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+
+ pHandle->bExiting = NMI_TRUE;
+
+ // Release any waiting receiver thread.
+ while(pHandle->u32ReceiversCount > 0)
+ {
+ NMI_SemaphoreRelease(&(pHandle->hSem), NMI_NULL);
+ pHandle->u32ReceiversCount--;
+ }
+
+ NMI_SemaphoreDestroy(&pHandle->hSem, NMI_NULL);
+
+ while(pHandle->pstrMessageList != NULL)
+ {
+ Message * pstrMessge = pHandle->pstrMessageList->pstrNext;
+ NMI_FREE(pHandle->pstrMessageList);
+ pHandle->pstrMessageList = pstrMessge;
+ }
+
+ return NMI_SUCCESS;
+}
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueSend(NMI_MsgQueueHandle* pHandle,
+ const void * pvSendBuffer, NMI_Uint32 u32SendBufferSize,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+ unsigned long flags;
+ Message * pstrMessage = NULL;
+
+ if( (pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL) )
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_INVALID_ARGUMENT);
+ }
+
+ if(pHandle->bExiting == NMI_TRUE)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ spin_lock_irqsave(&pHandle->strCriticalSection,flags);
+
+ /* construct a new message */
+ pstrMessage = NMI_NEW(Message, 1);
+ NMI_NULLCHECK(s32RetStatus, pstrMessage);
+ pstrMessage->u32Length = u32SendBufferSize;
+ pstrMessage->pstrNext = NULL;
+ pstrMessage->pvBuffer = NMI_MALLOC(u32SendBufferSize);
+ NMI_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer);
+ NMI_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize);
+
+
+ /* add it to the message queue */
+ if(pHandle->pstrMessageList == NULL)
+ {
+ pHandle->pstrMessageList = pstrMessage;
+ }
+ else
+ {
+ Message * pstrTailMsg = pHandle->pstrMessageList;
+ while(pstrTailMsg->pstrNext != NULL)
+ {
+ pstrTailMsg = pstrTailMsg->pstrNext;
+ }
+ pstrTailMsg->pstrNext = pstrMessage;
+ }
+
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+
+ NMI_SemaphoreRelease(&pHandle->hSem, NMI_NULL);
+
+ NMI_CATCH(s32RetStatus)
+ {
+ /* error occured, free any allocations */
+ if(pstrMessage != NULL)
+ {
+ if(pstrMessage->pvBuffer != NULL)
+ {
+ NMI_FREE(pstrMessage->pvBuffer);
+ }
+ NMI_FREE(pstrMessage);
+ }
+ }
+
+ return s32RetStatus;
+}
+
+
+
+/*!
+* @author syounan
+* @date 1 Sep 2010
+* @note copied from FLO glue implementatuion
+* @version 1.0
+*/
+NMI_ErrNo NMI_MsgQueueRecv(NMI_MsgQueueHandle* pHandle,
+ void * pvRecvBuffer, NMI_Uint32 u32RecvBufferSize,
+ NMI_Uint32* pu32ReceivedLength,
+ tstrNMI_MsgQueueAttrs* pstrAttrs)
+{
+
+ Message * pstrMessage;
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+ tstrNMI_SemaphoreAttrs strSemAttrs;
+ unsigned long flags;
+ if( (pHandle == NULL) || (u32RecvBufferSize == 0)
+ || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL) )
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_INVALID_ARGUMENT);
+ }
+
+ if(pHandle->bExiting == NMI_TRUE)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ spin_lock_irqsave(&pHandle->strCriticalSection,flags);
+ pHandle->u32ReceiversCount++;
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+
+ NMI_SemaphoreFillDefault(&strSemAttrs);
+ #ifdef CONFIG_NMI_MSG_QUEUE_TIMEOUT
+ if(pstrAttrs != NMI_NULL)
+ {
+ strSemAttrs.u32TimeOut = pstrAttrs->u32Timeout;
+ }
+ #endif
+ s32RetStatus = NMI_SemaphoreAcquire(&(pHandle->hSem), &strSemAttrs);
+ if(s32RetStatus == NMI_TIMEOUT)
+ {
+ /* timed out, just exit without consumeing the message */
+ spin_lock_irqsave(&pHandle->strCriticalSection,flags);
+ pHandle->u32ReceiversCount--;
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+ }
+ else
+ {
+ /* other non-timeout scenarios */
+ NMI_ERRORCHECK(s32RetStatus);
+
+ if(pHandle->bExiting)
+ {
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+
+ spin_lock_irqsave(&pHandle->strCriticalSection,flags);
+
+ pstrMessage = pHandle->pstrMessageList;
+ if(pstrMessage == NULL)
+ {
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+ NMI_ERRORREPORT(s32RetStatus, NMI_FAIL);
+ }
+ /* check buffer size */
+ if(u32RecvBufferSize < pstrMessage->u32Length)
+ {
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+ NMI_SemaphoreRelease(&pHandle->hSem, NMI_NULL);
+ NMI_ERRORREPORT(s32RetStatus, NMI_BUFFER_OVERFLOW);
+ }
+
+ /* consume the message */
+ pHandle->u32ReceiversCount--;
+ NMI_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length);
+ *pu32ReceivedLength = pstrMessage->u32Length;
+
+ pHandle->pstrMessageList = pstrMessage->pstrNext;
+
+ NMI_FREE(pstrMessage->pvBuffer);
+ NMI_FREE(pstrMessage);
+
+ spin_unlock_irqrestore(&pHandle->strCriticalSection,flags);
+
+ }
+
+ NMI_CATCH(s32RetStatus)
+ {
+ }
+
+ return s32RetStatus;
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c
new file mode 100755
index 00000000..203ff42c
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c
@@ -0,0 +1,78 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#ifdef CONFIG_NMI_SEMAPHORE_FEATURE
+
+
+NMI_ErrNo NMI_SemaphoreCreate(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ tstrNMI_SemaphoreAttrs strDefaultAttrs;
+ if(pstrAttrs == NMI_NULL)
+ {
+ NMI_SemaphoreFillDefault(&strDefaultAttrs);
+ pstrAttrs = &strDefaultAttrs;
+ }
+
+ sema_init(pHandle,pstrAttrs->u32InitCount);
+ return NMI_SUCCESS;
+
+}
+
+
+NMI_ErrNo NMI_SemaphoreDestroy(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ /* nothing to be done ! */
+
+ return NMI_SUCCESS;
+
+}
+
+
+NMI_ErrNo NMI_SemaphoreAcquire(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+
+ #ifndef CONFIG_NMI_SEMAPHORE_TIMEOUT
+ down(pHandle);
+
+ #else
+ if(pstrAttrs == NMI_NULL)
+ {
+ down(pHandle);
+ }
+ else
+ {
+
+ s32RetStatus = down_timeout(pHandle, msecs_to_jiffies(pstrAttrs->u32TimeOut));
+ }
+ #endif
+
+ if(s32RetStatus == 0)
+ {
+ return NMI_SUCCESS;
+ }
+ else if (s32RetStatus == -ETIME)
+ {
+ return NMI_TIMEOUT;
+ }
+ else
+ {
+ return NMI_FAIL;
+ }
+
+ return NMI_SUCCESS;
+
+}
+
+NMI_ErrNo NMI_SemaphoreRelease(NMI_SemaphoreHandle* pHandle,
+ tstrNMI_SemaphoreAttrs* pstrAttrs)
+{
+
+ up(pHandle);
+ return NMI_SUCCESS;
+
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c
new file mode 100755
index 00000000..9d0334d9
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c
@@ -0,0 +1,39 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_SLEEP_FEATURE
+
+/*
+* @author mdaftedar
+* @date 10 Aug 2010
+* @version 1.0
+*/
+void NMI_Sleep(NMI_Uint32 u32TimeMilliSec)
+{
+ if(u32TimeMilliSec <= 4000000)
+ {
+ NMI_Uint32 u32Temp = u32TimeMilliSec * 1000;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
+ usleep_range(u32Temp, u32Temp);
+#else
+ udelay(u32Temp);
+#endif
+ }
+ else
+ {
+ msleep(u32TimeMilliSec);
+ }
+
+}
+#endif
+
+//#ifdef CONFIG_NMI_SLEEP_HI_RES
+void NMI_SleepMicrosec(NMI_Uint32 u32TimeMicoSec)
+{
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
+ usleep_range(u32TimeMicoSec,u32TimeMicoSec);
+ #else
+ udelay(u32TimeMicoSec);
+ #endif
+}
+//#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c
new file mode 100755
index 00000000..2e3c206e
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c
@@ -0,0 +1,482 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_STRING_UTILS
+
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_memcmp(const void* pvArg1, const void* pvArg2, NMI_Uint32 u32Count)
+{
+ return memcmp(pvArg1, pvArg2, u32Count);
+}
+
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void NMI_memcpy_INTERNAL(void* pvTarget, const void* pvSource, NMI_Uint32 u32Count)
+{
+ memcpy(pvTarget, pvSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+void* NMI_memset(void* pvTarget, NMI_Uint8 u8SetValue, NMI_Uint32 u32Count)
+{
+ return memset(pvTarget, u8SetValue, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncat(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count)
+{
+ return strncat(pcTarget, pcSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strncpy(NMI_Char* pcTarget, const NMI_Char* pcSource,
+ NMI_Uint32 u32Count)
+{
+ return strncpy(pcTarget, pcSource, u32Count);
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strcmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ s32Result = strcmp(pcStr1, pcStr2);
+ if(s32Result < 0)
+ {
+ s32Result = -1;
+ }
+ else if(s32Result > 0)
+ {
+ s32Result = 1;
+ }
+ }
+
+ return s32Result;
+}
+
+NMI_Sint32 NMI_strncmp(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ s32Result = strncmp(pcStr1, pcStr2, u32Count);
+ if(s32Result < 0)
+ {
+ s32Result = -1;
+ }
+ else if(s32Result > 0)
+ {
+ s32Result = 1;
+ }
+ }
+
+ return s32Result;
+}
+
+/*
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_Sint32 NMI_strcmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ NMI_Char cTestedChar1, cTestedChar2;
+ do
+ {
+ cTestedChar1 = *pcStr1;
+ if((*pcStr1 >= 'a') && (*pcStr1 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar1 -= 32;
+ }
+
+ cTestedChar2 = *pcStr2;
+ if((*pcStr2 >= 'a') && (*pcStr2 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar2 -= 32;
+ }
+
+ pcStr1++;
+ pcStr2++;
+
+ }while((cTestedChar1 == cTestedChar2)
+ && (cTestedChar1 != 0)
+ && (cTestedChar2 != 0));
+
+ if(cTestedChar1 > cTestedChar2)
+ {
+ s32Result = 1;
+ }
+ else if(cTestedChar1 < cTestedChar2)
+ {
+ s32Result = -1;
+ }
+ else
+ {
+ s32Result = 0;
+ }
+ }
+
+ return s32Result;
+}
+
+/*!
+* @author aabozaeid
+* @date 8 Dec 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strncmp_IgnoreCase(const NMI_Char* pcStr1, const NMI_Char* pcStr2,
+ NMI_Uint32 u32Count)
+{
+ NMI_Sint32 s32Result;
+
+ if(pcStr1 == NMI_NULL && pcStr2 == NMI_NULL)
+ {
+ s32Result = 0;
+ }
+ else if(pcStr1 == NMI_NULL)
+ {
+ s32Result = -1;
+ }
+ else if(pcStr2 == NMI_NULL)
+ {
+ s32Result = 1;
+ }
+ else
+ {
+ NMI_Char cTestedChar1, cTestedChar2;
+ do
+ {
+ cTestedChar1 = *pcStr1;
+ if((*pcStr1 >= 'a') && (*pcStr1 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar1 -= 32;
+ }
+
+ cTestedChar2 = *pcStr2;
+ if((*pcStr2 >= 'a') && (*pcStr2 <= 'z'))
+ {
+ /* turn a lower case character to an upper case one */
+ cTestedChar2 -= 32;
+ }
+
+ pcStr1++;
+ pcStr2++;
+ u32Count--;
+
+ }while( (u32Count > 0)
+ && (cTestedChar1 == cTestedChar2)
+ && (cTestedChar1 != 0)
+ && (cTestedChar2 != 0));
+
+ if(cTestedChar1 > cTestedChar2)
+ {
+ s32Result = 1;
+ }
+ else if(cTestedChar1 < cTestedChar2)
+ {
+ s32Result = -1;
+ }
+ else
+ {
+ s32Result = 0;
+ }
+ }
+
+ return s32Result;
+
+}
+
+/*!
+* @author syounan
+* @date 18 Aug 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strlen(const NMI_Char* pcStr)
+{
+ return (NMI_Uint32)strlen(pcStr);
+}
+
+/*!
+* @author bfahmy
+* @date 28 Aug 2010
+* @version 1.0
+*/
+NMI_Sint32 NMI_strtoint(const NMI_Char* pcStr)
+{
+ return (NMI_Sint32)(simple_strtol(pcStr,NULL,10));
+}
+
+/*
+* @author syounan
+* @date 1 Nov 2010
+* @version 2.0
+*/
+NMI_ErrNo NMI_snprintf(NMI_Char* pcTarget, NMI_Uint32 u32Size,
+ const NMI_Char* pcFormat, ...)
+{
+ va_list argptr;
+ va_start(argptr, pcFormat);
+ if(vsnprintf(pcTarget, u32Size, pcFormat, argptr) < 0)
+ {
+ /* if turncation happens windows does not properly terminate strings */
+ pcTarget[u32Size - 1] = 0;
+ }
+ va_end(argptr);
+
+ /* I find no sane way of detecting errors in windows, so let it all succeed ! */
+ return NMI_SUCCESS;
+}
+
+#ifdef CONFIG_NMI_EXTENDED_STRING_OPERATIONS
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c in the first n bytes
+ of the string pointed to by the argument str.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_memchr(const void *str, NMI_Char c, NMI_Sint32 n)
+{
+ return (NMI_Char*) memchr(str,c,(size_t)n);
+}
+
+/**
+* @brief
+* @details Searches for the first occurrence of the character c (an unsigned char)
+ in the string pointed to by the argument str.
+ The terminating null character is considered to be part of the string.
+ Returns a pointer pointing to the first matching character,
+ or null if no match was found.
+* @param[in]
+* @return
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strchr(const NMI_Char *str, NMI_Char c)
+{
+ return strchr(str,c);
+}
+
+/**
+* @brief
+* @details Appends the string pointed to by str2 to the end of the string pointed to by str1.
+ The terminating null character of str1 is overwritten.
+ Copying stops once the terminating null character of str2 is copied. If overlapping occurs, the result is undefined.
+ The argument str1 is returned.
+* @param[in] NMI_Char* str1,
+* @param[in] NMI_Char* str2,
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcat(NMI_Char *str1, const NMI_Char *str2)
+{
+ return strcat(str1, str2);
+}
+
+/**
+* @brief
+* @details Copy pcSource to pcTarget
+* @param[in] NMI_Char* pcTarget
+* @param[in] const NMI_Char* pcSource
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strcpy(NMI_Char* pcTarget, const NMI_Char* pcSource)
+{
+ return strncpy(pcTarget, pcSource, strlen(pcSource));
+}
+
+/**
+* @brief
+* @details Finds the first sequence of characters in the string str1 that
+ does not contain any character specified in str2.
+ Returns the length of this first sequence of characters found that
+ do not match with str2.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_strcspn(const NMI_Char *str1, const NMI_Char *str2)
+{
+ return (NMI_Uint32)strcspn(str1, str2);
+}
+#if 0
+/**
+* @brief
+* @details Searches an internal array for the error number errnum and returns a pointer
+ to an error message string.
+ Returns a pointer to an error message string.
+* @param[in] NMI_Sint32 errnum
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strerror(NMI_Sint32 errnum)
+{
+ return strerror(errnum);
+}
+#endif
+
+/**
+* @brief
+* @details Finds the first occurrence of the entire string str2
+ (not including the terminating null character) which appears in the string str1.
+ Returns a pointer to the first occurrence of str2 in str1.
+ If no match was found, then a null pointer is returned.
+ If str2 points to a string of zero length, then the argument str1 is returned.
+* @param[in] const NMI_Char *str1
+* @param[in] const NMI_Char *str2
+* @return NMI_Char*
+* @note
+* @author remil
+* @date 3 Nov 2010
+* @version 1.0
+*/
+NMI_Char* NMI_strstr(const NMI_Char *str1, const NMI_Char *str2)
+{
+ return strstr(str1, str2);
+}
+#if 0
+/**
+* @brief
+* @details Parses the C string str interpreting its content as a floating point
+ number and returns its value as a double.
+ If endptr is not a null pointer, the function also sets the value pointed
+ by endptr to point to the first character after the number.
+* @param[in] const NMI_Char* str
+* @param[in] NMI_Char** endptr
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_StringToDouble(const NMI_Char* str, NMI_Char** endptr)
+{
+ return strtod (str,endptr);
+}
+#endif
+
+/**
+* @brief Parses the C string str interpreting its content as an unsigned integral
+ number of the specified base, which is returned as an unsigned long int value.
+* @details The function first discards as many whitespace characters as necessary
+ until the first non-whitespace character is found.
+ Then, starting from this character, takes as many characters as possible
+ that are valid following a syntax that depends on the base parameter,
+ and interprets them as a numerical value.
+ Finally, a pointer to the first character following the integer
+ representation in str is stored in the object pointed by endptr.
+* @param[in] const NMI_Char *str
+* @param[in] NMI_Char **endptr
+* @param[in] NMI_Sint32 base
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringToUint32(const NMI_Char *str, NMI_Char **endptr, NMI_Sint32 base)
+{
+ return simple_strtoul(str, endptr, base);
+}
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c
new file mode 100755
index 00000000..325afbd7
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c
@@ -0,0 +1,38 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_THREAD_FEATURE
+
+
+
+NMI_ErrNo NMI_ThreadCreate(NMI_ThreadHandle* pHandle, tpfNMI_ThreadFunction pfEntry,
+ void* pvArg, tstrNMI_ThreadAttrs* pstrAttrs)
+{
+
+
+ *pHandle = kthread_run((int(*)(void *))pfEntry ,pvArg, "NMI_kthread");
+
+
+ if(IS_ERR(*pHandle))
+ {
+ return NMI_FAIL;
+ }
+ else
+ {
+ return NMI_SUCCESS;
+ }
+
+}
+
+NMI_ErrNo NMI_ThreadDestroy(NMI_ThreadHandle* pHandle,
+ tstrNMI_ThreadAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+
+ kthread_stop(*pHandle);
+ return s32RetStatus;
+}
+
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c
new file mode 100755
index 00000000..63dbbdbb
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c
@@ -0,0 +1,163 @@
+
+#define _CRT_SECURE_NO_DEPRECATE
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_TIME_FEATURE
+
+
+NMI_Uint32 NMI_TimeMsec(void)
+{
+ NMI_Uint32 u32Time = 0;
+ struct timespec current_time;
+
+ current_time = current_kernel_time();
+ u32Time = current_time.tv_sec * 1000;
+ u32Time += current_time.tv_nsec / 1000000;
+
+
+ return u32Time;
+}
+
+
+#ifdef CONFIG_NMI_EXTENDED_TIME_OPERATIONS
+
+/**
+* @brief
+* @details function returns the implementation's best approximation to the
+ processor time used by the process since the beginning of an
+ implementation-dependent time related only to the process invocation.
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_Clock()
+{
+ /*printk("Not implemented")*/
+}
+
+
+/**
+* @brief
+* @details The difftime() function computes the difference between two calendar
+ times (as returned by NMI_GetTime()): time1 - time0.
+* @param[in] NMI_Time time1
+* @param[in] NMI_Time time0
+* @return NMI_Double
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Double NMI_DiffTime(NMI_Time time1, NMI_Time time0)
+{
+ /*printk("Not implemented")*/
+}
+
+
+
+/**
+* @brief
+* @details The gmtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time,
+ expressed as Coordinated Universal Time (UTC).
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_GmTime(const NMI_Time* timer)
+{
+ /*printk("Not implemented")*/
+}
+
+
+/**
+* @brief
+* @details The localtime() function converts the time in seconds since
+ the Epoch pointed to by timer into a broken-down time, expressed
+ as a local time. The function corrects for the timezone and any
+ seasonal time adjustments. Local timezone information is used as
+ though localtime() calls tzset().
+* @param[in] const NMI_Time* timer
+* @return NMI_tm*
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_tm* NMI_LocalTime(const NMI_Time* timer)
+{
+ /*printk("Not implemented")*/
+}
+
+
+/**
+* @brief
+* @details The mktime() function converts the broken-down time,
+ expressed as local time, in the structure pointed to by timeptr,
+ into a time since the Epoch value with the same encoding as that
+ of the values returned by time(). The original values of the tm_wday
+ and tm_yday components of the structure are ignored, and the original
+ values of the other components are not restricted to the ranges described
+ in the <time.h> entry.
+* @param[in] NMI_tm* timer
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_MkTime(NMI_tm* timer)
+{
+ /*printk("Not implemented")*/
+}
+
+
+/**
+* @brief
+* @details The strftime() function places bytes into the array
+ pointed to by s as controlled by the string pointed to by format.
+* @param[in] NMI_Char* s
+* @param[in] NMI_Uint32 maxSize
+* @param[in] const NMI_Char* format
+* @param[in] const NMI_tm* timptr
+* @return NMI_Uint32
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Uint32 NMI_StringFormatTime(NMI_Char* s,
+ NMI_Uint32 maxSize,
+ const NMI_Char* format,
+ const NMI_tm* timptr)
+{
+ /*printk("Not implemented")*/
+}
+
+
+/**
+* @brief The NMI_GetTime() function returns the value of time in seconds since the Epoch.
+* @details The tloc argument points to an area where the return value is also stored.
+ If tloc is a null pointer, no value is stored.
+* @param[in] NMI_Time* tloc
+* @return NMI_Time
+* @note
+* @author remil
+* @date 11 Nov 2010
+* @version 1.0
+*/
+NMI_Time NMI_GetTime(NMI_Time* tloc)
+{
+ /*printk("Not implemented")*/
+}
+
+
+#endif
+#endif
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c
new file mode 100755
index 00000000..250a3b44
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c
@@ -0,0 +1,51 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+#ifdef CONFIG_NMI_TIMER_FEATURE
+
+
+
+NMI_ErrNo NMI_TimerCreate(NMI_TimerHandle* pHandle,
+ tpfNMI_TimerFunction pfCallback, tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_SUCCESS;
+ setup_timer(pHandle,(void(*)(unsigned long))pfCallback,0);
+
+ return s32RetStatus;
+}
+
+NMI_ErrNo NMI_TimerDestroy(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+ if(pHandle != NULL){
+ s32RetStatus = del_timer_sync(pHandle);
+ pHandle = NULL;
+ }
+
+ return s32RetStatus;
+}
+
+
+NMI_ErrNo NMI_TimerStart(NMI_TimerHandle* pHandle, NMI_Uint32 u32Timeout,
+ void* pvArg, tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+ if(pHandle != NULL){
+ pHandle->data = (unsigned long)pvArg;
+ s32RetStatus = mod_timer(pHandle, (jiffies + msecs_to_jiffies(u32Timeout)));
+ }
+ return s32RetStatus;
+}
+
+NMI_ErrNo NMI_TimerStop(NMI_TimerHandle* pHandle,
+ tstrNMI_TimerAttrs* pstrAttrs)
+{
+ NMI_ErrNo s32RetStatus = NMI_FAIL;
+ if(pHandle != NULL)
+ s32RetStatus = del_timer(pHandle);
+
+ return s32RetStatus;
+}
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/win32/include/NMI_platform.h b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/win32/include/NMI_platform.h
new file mode 100755
index 00000000..868d8473
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/NMI_OsWrapper/source/win32/include/NMI_platform.h
@@ -0,0 +1,160 @@
+#ifndef __NMI_platfrom_H__
+#define __NMI_platfrom_H__
+
+/*!
+* @file NMI_platform.h
+* @brief top level header for win32 implementation
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 18 Aug 2010
+* @version 1.0
+*/
+
+/******************************************************************
+ Feature support checks
+*******************************************************************/
+
+// CONFIG_NMI_THREAD_FEATURE is implemented
+
+// CONFIG_NMI_THREAD_SUSPEND_CONTROL is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_THREAD_STRICT_PRIORITY
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_SEMAPHORE_FEATURE is implemented
+
+// CONFIG_NMI_SEMAPHORE_TIMEOUT is implemented
+
+// CONFIG_NMI_SLEEP_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_SLEEP_HI_RES
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_TIMER_FEATURE is implemented
+
+// CONFIG_NMI_TIMER_PERIODIC is implemented
+
+// CONFIG_NMI_MEMORY_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_POOLS
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MEMORY_DEBUG
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_ASSERTION_SUPPORT
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_STRING_UTILS is implemented
+
+// CONFIG_NMI_MSG_QUEUE_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_MSG_QUEUE_IPC_NAME
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_MSG_QUEUE_TIMEOUT is implemented
+
+// CONFIG_NMI_FILE_OPERATIONS_FEATURE is implemented
+
+// CONFIG_NMI_FILE_OPERATIONS_STRING_API is implemented
+
+// CONFIG_NMI_TIME_FEATURE is implemented
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_UTC_SINCE_1970
+#error This feature is not supported by this OS
+#endif
+
+/* remove the following block when implementing its feature */
+#ifdef CONFIG_NMI_TIME_CALENDER
+#error This feature is not supported by this OS
+#endif
+
+// CONFIG_NMI_EVENT_FEATURE is implemented
+
+// CONFIG_NMI_EVENT_TIMEOUT is implemented
+
+/******************************************************************
+ OS specific includes
+*******************************************************************/
+#include "stdio.h"
+#define _WIN32_WINNT 0x0500
+#include "Windows.h"
+
+/******************************************************************
+ OS specific types
+*******************************************************************/
+
+/* Thread Handle is a windows HANDLE */
+typedef HANDLE NMI_ThreadHandle;
+
+/* Semaphore Handle is a windows HANDLE */
+typedef HANDLE NMI_SemaphoreHandle;
+
+/* Timer Handle is a complex structure */
+typedef struct{
+
+ /* the underlaying windwos timer stored here */
+ HANDLE hTimer;
+
+ /* critical section for protection */
+ CRITICAL_SECTION csProtectionCS;
+
+ /* the callback is kept here */
+ /* shoud be a proper pointer to function type
+ insted of void*, but the timer callback type is
+ defined later in its header */
+ void* pfCallbackFunction;
+
+ /* the invocation argument is kept here */
+ void* pvArgument;
+
+}NMI_TimerHandle;
+
+/* change into OS specific type */
+typedef void* NMI_MemoryPoolHandle;
+
+/* Message Queue type is a structure */
+typedef struct __Message_struct
+{
+ LPVOID pvBuffer;
+ DWORD u32Length;
+ struct __Message_struct *pstrNext;
+} Message;
+
+typedef struct __MessageQueue_struct
+{
+ HANDLE hSem;
+ BOOLEAN bExiting;
+ DWORD ReceiversCount;
+ CRITICAL_SECTION strCriticalSection;
+ Message * pstrMessageList;
+} NMI_MsgQueueHandle;
+
+typedef FILE* NMI_FileHandle;
+
+/* Event Handle is a windows HANDLE */
+typedef HANDLE NMI_EventHandle;
+
+/*******************************************************************
+ others
+********************************************************************/
+
+/* Generic printf function */
+#define NMI_PRINTF(...) printf(__VA_ARGS__)
+#define __NMI_FILE__ __FILE__
+#define __NMI_FUNCTION__ __FUNCTION__
+#define __NMI_LINE__ __LINE__
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile b/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile
new file mode 100755
index 00000000..58fbd28c
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile
@@ -0,0 +1,138 @@
+MAKE = make
+RM = rm
+MV = mv
+ECHO = echo
+CP = cp
+PWD = $(shell pwd)
+
+#EXTRA_CFLAGS += -DNMI_HOST_HAS_RTC
+#EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+EXTRA_CFLAGS += -DAGING_ALG
+
+obj-m := lib.a
+ifeq ($(FULLY_HOSTING_AP),Y)
+lib-y := NMI_host_AP.o core_configurator/CoreConfigurator.o nmi_driver_interface/host_interface.o\
+ core_simulator/FIFO_Buffer.o nmi_sdio.o\
+ nmi_spi.o nmi_wlan_cfg.o nmi_wlan.o
+
+else
+lib-y := core_configurator/CoreConfigurator.o nmi_driver_interface/host_interface.o\
+ core_simulator/FIFO_Buffer.o nmi_sdio.o\
+ nmi_spi.o nmi_wlan_cfg.o nmi_wlan.o
+endif
+
+
+ccflags-y = -I$(src)/include
+ccflags-y += -I$(src)/../NMI_OsWrapper/include
+ccflags-y += -I$(src)/..
+ccflags-y += -DNMI_PLATFORM=NMI_LINUXKERNEL
+ccflags-y += -Wno-unused-function
+
+#Use external 1.4V VCO
+EXTRA_CFLAGS += -DVCO_14_SUPPLY
+#Default to NMI=EVAL if NMI isn't defined
+ifeq ($(strip $(NMI)),)
+NMI=EVAL
+endif
+
+ifeq ($(NMI),EVAL)
+EXTRA_CFLAGS += -DNMC_ASIC_A0 -DPLL_WORKAROUND
+else ifeq ($(NMI),FPGA)
+endif
+
+EXTRA_CFLAGS += -DCONNECT_DIRECT -DNMI_PARSE_SCAN_IN_HOST
+
+
+ifeq ($(BUS),SDIO)
+EXTRA_CFLAGS += -DNMI_SDIO
+#EXTRA_CFLAGS += -DNMI_OPTIMIZE_SLEEP_INT
+endif
+
+ifeq ($(SDIO_IRQ),GPIO)
+EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+endif
+
+ifeq ($(DMA_VER),VER_1)
+EXTRA_CFLAGS += -DUSE_DMA_VER_1
+endif
+
+ifeq ($(TARGET),SIMULATION)
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+lib-y += core_simulator/CoreConfigSimulator.o transport/Packet_Tx_Rx.o
+ccflags-y += -DSIMULATION
+EXTRA_CFLAGS += -DCONNECT_DIRECT
+OUT_ARCH = x86
+else ifeq ($(TARGET),PANDA)
+#lib-y += core_simulator/CoreConfigSimulator.o transport/Packet_Tx_Rx.o
+#ccflags-y += -DSIMULATION
+EXTRA_CFLAGS += -DPANDA_BOARD -DUSE_WIRELESS
+KERNELDIR ?= $(DEV_TREE)/kernel/omap
+ifeq ($(ANDR_VER),4.3)
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi- ARCH=arm
+else
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm
+endif
+OUT_ARCH = ARM-3.0
+else ifeq ($(TARGET),BEAGLE)
+KERNELDIR ?= $(DEV_TREE)
+OUT_ARCH = ARM-2.6.39
+MAKE_FLAGS := CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DBEAGLE_BOARD
+else ifeq ($(TARGET),NM73131)
+KERNELDIR ?= $(DEV_TREE_LPC)
+OUT_ARCH = ARM-2.6.28.2
+MAKE_FLAGS := CROSS_COMPILE=arm-linux- ARCH=arm
+EXTRA_CFLAGS += -DNM73131_0_BOARD
+else ifeq ($(TARGET),ALLWINNER)
+KERNELDIR ?= $(DEV_TREE)/linux-3.0
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/buildroot/output/external-toolchain/bin/arm-none-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DALLWINNER_BOARD -DUSE_WIRELESS
+OUT_ARCH = ARM-3.0
+else ifeq ($(TARGET),ALLWINNER_A20)
+KERNELDIR ?= $(DEV_TREE)/linux-3.3
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A20 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.3
+else ifeq ($(TARGET),ALLWINNER_A23)
+KERNELDIR ?= $(DEV_TREE)/linux-3.4
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A23 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.4
+else
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+lib-y += core_simulator/CoreConfigSimulator.o transport/Packet_Tx_Rx.o
+ccflags-y += -DSIMULATION
+EXTRA_CFLAGS += -DCONNECT_DIRECT
+OUT_ARCH = x86
+endif
+
+ifeq ($(FIRMLOG),HOST)
+ EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+endif
+
+EXTRA_CFLAGS += -DTCP_ACK_FILTER
+all:
+
+ $(MAKE) TARGET=$(TARGET) -C ../NMI_OsWrapper/source/linuxkernel
+ @$(ECHO) "###########################################"
+ @$(ECHO) "####### Building NMI WiFi Driver lib ######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules $(MAKE_FLAGS)
+ mkdir -p binary/linux/$(OUT_ARCH)
+ $(MV) $(PWD)/lib.a binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a
+
+
+
+
+clean:
+ $(MAKE) TARGET=$(TARGET) -C ../NMI_OsWrapper/source/linuxkernel clean
+ @$(ECHO) "###########################################"
+ @$(ECHO) "####### Cleaning NMI WiFi Driver lib ######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
+ $(RM) -f $(OBJPROG)
+ $(RM) -f binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile_US b/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile_US
new file mode 100755
index 00000000..b8863b69
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/Makefile_US
@@ -0,0 +1,53 @@
+#ARCH = arm
+MAKE = make
+#CC = arm-linux-gcc
+#AR = arm-linux-ar
+CC = gcc
+AR = ar
+RM = rm
+MV = mv
+ECHO = echo
+CFLAGS = -g -Wall
+PROGS = libdriver.a
+OBJECTS = core_configurator/CoreConfigurator.o core_simulator/CoreConfigSimulator.o nmi_driver_interface/host_interface.o transport/Packet_tx_Rx_socket.o core_simulator/FIFO_Buffer.o transport/Packet_Tx_Rx.o
+
+
+PWD = $(shell pwd)
+OBJDIR = $(PWD)
+OSPWD = $(PWD)/../NMI_OsWrapper
+INCHDR += -I$(PWD)/include -I .
+INCHDR += -I$(OSPWD)/include
+#INCHDR += -DNMI_LINUX -I$(PWD)/../NMI_OsWrapper/include
+INCHDR += -DNMI_PLATFORM=NMI_LINUX -I$(PWD)/../
+CFLAGS += -DSIMULATION_SHARED_SOCKET
+OSMAKEFILE = $(PWD)/../NMI_OsWrapper/source/linux
+OSLIB = $(PWD)/../NMI_OsWrapper/binary/linux/x86
+
+VPATH = $(OBJDIR)
+VPATH += source
+
+
+$(OBJDIR)/%.o : %.c
+ $(MAKE) -C $(OSPWD)/source/linux
+ @$(ECHO) "###########################################"
+ @$(ECHO) "#### Building" $<
+ $(CC) $(INCHDR) $(CFLAGS) -c $< -o $@ #-L$(OSLIB) -loswrapper
+
+OBJPROG = $(addprefix $(OBJDIR)/, $(PROGS))
+
+$(OBJPROG): $(addprefix $(OBJDIR)/, $(OBJECTS))
+ @$(ECHO) "###########################################"
+ @$(ECHO) "#### Linking library" $@
+ $(AR) rcs $@ $^
+
+all:build
+Debug:build
+Release:build
+cleanDebug:clean
+cleanRelease:clean
+
+clean:
+ $(RM) -f $(OBJPROG) $(addprefix $(OBJDIR)/, $(OBJECTS))
+
+build: $(OBJPROG)
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/NMI_host_AP.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/NMI_host_AP.c
new file mode 100755
index 00000000..77886e79
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/NMI_host_AP.c
@@ -0,0 +1,3522 @@
+/*!
+* @file NMI_host_AP.c
+* @brief code related to AP mode on driver
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+
+
+
+#ifndef SIMULATION
+#include "linux_wlan_common.h"
+#endif
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include "NMI_host_AP.h"
+#ifdef NMI_FULLY_HOSTING_AP
+
+
+extern void NMI_WFI_monitor_rx(uint8_t *buff, uint32_t size);
+void linux_wlan_free(void* vp);
+
+struct tx_complete_data{
+ struct tx_complete_data* next;
+ int size;
+ void* buff;
+ struct sk_buff *skb;
+};
+
+/*****************************************************************************/
+/* Static Global Variables */
+/*****************************************************************************/
+
+static const NMI_Uint8 g_bmap[8] = {1, 2, 4, 8, 16, 32, 64, 128}; /* Bit map */
+
+/*****************************************************************************/
+/* Global variables */
+/*****************************************************************************/
+
+table_t g_sta_table = {0,};
+beacon_info strBeaconInfo = {0};
+NMI_Uint8 g_snap_header[SNAP_HDR_ID_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+
+/* Power management related globals */
+NMI_Uint8 g_num_sta_ps = 0; /* Num of STA in PS */
+NMI_Uint32 g_num_mc_bc_pkt = 0; /* Num of BC/MC pkts in PSQ */
+NMI_Uint32 g_num_ps_pkt = 0; /* Num of UC/BC/MC pkts in PSQ */
+NMI_Uint16 g_num_mc_bc_qd_pkt = 0; /* Num of BC/MC pkts in Hw */
+list_buff_t g_mc_q;
+//NMI_Uint8 g_vbmap[VBMAP_SIZE] = {0,};
+//NMI_Uint8 g_tim_element_index = 0;
+//NMI_Uint16 g_tim_element_trailer_len = 0;
+q_head_t g_ps_pending_q = {0,};
+NMI_Uint16 g_aging_thresh_in_sec = AGING_THR_IN_SEC;
+NMI_ieee80211_sta *g_max_ps_ae = NULL; /* Association entry of STA, with max num of PS pkts */
+
+
+void* find_entry(NMI_Uint8* key);
+void add_entry(void* entry, NMI_Uint8* key);
+void delete_entry(NMI_Uint8* key);
+void frmw_to_linux(uint8_t *buff, uint32_t size);
+void ap_enabled_rx_data( NMI_Uint8 *msg);
+REQUEUE_STATUS_T requeue_ps_packet(NMI_ieee80211_sta* ae, list_buff_t *qh,
+ NMI_Bool ps_q_legacy, NMI_Bool eosp);
+NMI_Bool buffer_tx_packet(NMI_Uint8 *entry, NMI_Uint8 *da, NMI_Uint8 priority,
+ struct tx_complete_data *tx_dscr);
+void handle_ps_tx_comp_ap(struct tx_complete_data *tx_dscr );
+void check_and_reset_tim_bit(NMI_Uint16 asoc_id);
+NMI_Bool handle_ps_poll(wlan_rx_t *wlan_rx );
+
+
+/* This function returns whether the Multicast bit is set in the given beacon*/
+/* frame */
+inline NMI_Bool get_mc_bit_bcn(void)
+{
+ NMI_Bool ret_value;
+ ret_value = (NMI_Bool)(strBeaconInfo.u8beacon_frame[strBeaconInfo.u8tim_element_index + BMAP_CTRL_OFFSET] &
+ 0x01);
+ return (ret_value);
+}
+
+/* This function returns whether the Multicast bit is set in the given beacon*/
+/* frame */
+inline void reset_mc_bit_bcn(void)
+{
+ strBeaconInfo.u8beacon_frame[strBeaconInfo.u8tim_element_index + TIM_OFFSET] &= 0xFE;
+ strBeaconInfo.u8beacon_frame[strBeaconInfo.u8tim_element_index + BMAP_CTRL_OFFSET] &= 0xFE;
+}
+
+
+/*
+* @brief NMI_beacon_tx_complete
+* @details call back function for beacon transmission through vmm , does nothing at the moment
+* @return
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+static void NMI_beacon_tx_complete(void* priv, int status)
+{
+ // Do nothing
+
+ /*
+ beacon_data* pv_data = (beacon_data*)priv;
+ NMI_Uint8 * buf= pv_data->buff;
+
+ if(status == 1)
+ {
+ if(INFO || buf[0] == 0x80 || buf[0] == 0xb0)
+ PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",pv_data->size,pv_data->buff);
+ }
+ else
+ {
+ PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",pv_data->size,pv_data->buff);
+ }
+ */
+}
+
+
+/*
+* @brief NMI_beacon_xmit
+* @details send beacon frame to firmware
+* @param[in] u8 *buf : pointer to the beacon frame
+* size_t len : beacon frame length
+* @return Error code.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+static int NMI_beacon_xmit(const u8 *buf, size_t len)
+{
+ beacon_data *strBeacon_tx =NULL;
+
+ /* allocate the beacon_data struct */
+ strBeacon_tx = (beacon_data*)kmalloc(sizeof(beacon_data),GFP_ATOMIC);
+ if(strBeacon_tx == NULL){
+ PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
+ return NMI_FAIL;
+ }
+
+ /* allocate buffer for beacon data within the beacon_data struct */
+ strBeacon_tx->buff= (char*)kmalloc(len,GFP_ATOMIC);
+ if(strBeacon_tx->buff == NULL)
+ {
+ PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
+ return NMI_FAIL;
+
+ }
+
+ /* fill in the beacon data stuct */
+ memcpy(strBeacon_tx->buff,buf,len);
+ strBeacon_tx->size=len;
+
+ /* the actual transmission of beacon to firmware*/
+ //NMI_PRINTF("--IN beacon_tx: Sending beacon Pkt to tx queue--\n");
+ nmi_wlan_txq_add_mgmt_pkt(strBeacon_tx,strBeacon_tx->buff,strBeacon_tx->size,NMI_beacon_tx_complete);
+
+ return 0;
+}
+
+
+/**
+* @brief host_add_beacon
+* @details Setting add beacon params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8Tail
+* @return Error code.
+* @author Abd Al-Rahman Diab
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_add_beacon(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,
+ NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8Tail)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Bool bIsBeaconSet = NMI_FALSE;
+ NMI_Uint8 *pu8BeaconFrame;
+ NMI_Uint16 u16size=0;
+ nmi_wlan_dev_t* strWlan = Get_wlan_context(&u16size);
+
+ if(u16size != sizeof(nmi_wlan_dev_t))
+ PRINT_ER("size of nmi_wlan_dev_t in nmi_wlan != it's size in NMI_HOST_AP\n");
+
+
+ //NMI_PRINTF("--IN host_add_beacon--\n");
+
+ /* calculate beacon length */
+ strBeaconInfo.u16beacon_len = u32HeadLen + u32TailLen + DEFAULT_TIM_LEN + 2 ;
+ PRINT_D(HOSTAPD_DBG,"beacon_len=%d\n",strBeaconInfo.u16beacon_len);
+
+
+ /* set beacon interval in chip */
+ if(u32Interval>0)
+ {
+ strBeaconInfo.u16Beacon_Period = u32Interval;
+ PRINT_D(HOSTAPD_DBG,"Beacon_Period=%d\n",strBeaconInfo.u16Beacon_Period );
+ strWlan->hif_func.hif_write_reg(rMAC_BEACON_PERIOD, u32Interval);
+
+ }
+
+ /* allocate beacon frame */
+ if(strBeaconInfo.u8beacon_frame == NULL)
+ {
+ PRINT_D(HOSTAPD_DBG,"beacon_frame wasn't allocated. allocating new buffers\n");
+ /* Allocate 2 global beacon buffers as the beacon for AP may be modfied */
+ /* for which 2 buffers are needed. */
+ strBeaconInfo.u8beacon_frame = (NMI_Uint8 *)kmalloc(strBeaconInfo.u16beacon_len,GFP_ATOMIC);
+ if(strBeaconInfo.u8beacon_frame == NULL)
+ {
+ PRINT_ER("Couldn't allocate beacon_frame\n");
+ /* Exception - no memory for beacons */
+ s32Error = NMI_FAIL;
+ return s32Error;
+ }
+ }
+ else
+ {
+ bIsBeaconSet = NMI_TRUE;
+ }
+
+ /* set beacon DTIM period in chip */
+ if(u32DTIMPeriod>0)
+ {
+ strBeaconInfo.u8DTIMPeriod= u32DTIMPeriod;
+ PRINT_D(HOSTAPD_DBG,"DTIMPeriod=%d\n",strBeaconInfo.u8DTIMPeriod);
+ strWlan->hif_func.hif_write_reg(rMAC_DTIM_PERIOD, u32DTIMPeriod);
+ }
+
+ /* save TIM element location within the beacon */
+ strBeaconInfo.u8tim_element_index = u32HeadLen;
+ strBeaconInfo.u16tim_element_trailer_len = u32TailLen;
+
+ /* Copy beacon head part*/
+ pu8BeaconFrame = strBeaconInfo.u8beacon_frame;
+ NMI_memcpy(pu8BeaconFrame, pu8Head, u32HeadLen);
+ pu8BeaconFrame += u32HeadLen;
+
+ /* Set the TIM element field with default parameters and update the */
+ /* index value with the default length. */
+ *(pu8BeaconFrame++) = ITIM;
+ *(pu8BeaconFrame++) = DEFAULT_TIM_LEN;
+ *(pu8BeaconFrame++) = 0;
+ *(pu8BeaconFrame++) = strBeaconInfo.u8DTIMPeriod;
+ *(pu8BeaconFrame++) = 0;
+ *(pu8BeaconFrame++) = 0;
+
+ NMI_memcpy(pu8BeaconFrame, pu8Tail, u32TailLen);
+ pu8BeaconFrame+=u32TailLen;
+
+ NMI_beacon_xmit(strBeaconInfo.u8beacon_frame,strBeaconInfo.u16beacon_len);
+
+ PRINT_D(HOSTAPD_DBG,"Starting TSF timer \n");
+ //printk("sizeof(struct tx_complete_data) = %d \n--------------------------------------\n",sizeof(struct tx_complete_data));
+
+ /* Initialize the virtual bitmap */
+ strBeaconInfo.u8vbmap[TYPE_OFFSET] = ITIM; /* Element ID */
+ strBeaconInfo.u8vbmap[LENGTH_OFFSET] = DEFAULT_TIM_LEN; /* Element Length */
+ strBeaconInfo.u8vbmap[DTIM_CNT_OFFSET] = 0; /* Dtim Count */
+ strBeaconInfo.u8vbmap[DTIM_PERIOD_OFFSET] = strBeaconInfo.u8DTIMPeriod; /* Dtim Period */
+ strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] = 0; /* Bitmap Control */
+ strBeaconInfo.u8vbmap[TIM_OFFSET] = 0; /* Copy TIM element */
+
+
+ /* Start TSF timer in chip to start sending beacons*/
+ strWlan->hif_func.hif_write_reg(rMAC_TSF_CON, BIT1 | BIT0);
+
+ return s32Error;
+
+}
+
+/*
+* @brief host_del_beacon
+* @details delete the allocated beacon
+* @param[in] NMI_WFIDrvHandle hWFIDrv
+* @return Error code.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+NMI_Sint32 host_del_beacon(NMI_WFIDrvHandle hWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ PRINT_D(HOSTAPD_DBG,"host_del_beacon \n");
+
+ if(strBeaconInfo.u8beacon_frame != NULL)
+ {
+ kfree(strBeaconInfo.u8beacon_frame);
+ strBeaconInfo.u8beacon_frame=NULL;
+ strBeaconInfo.u16beacon_len = 0;
+ }
+
+ NMI_ERRORCHECK(s32Error);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+/*
+* @brief handle tbtt ISR and send updated beacon to chip
+* @details
+* @param[in]
+* @return
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+void process_tbtt_isr(void)
+{
+
+ NMI_Uint16 i = 0;
+ NMI_Uint8 u8OldTimLen = 0;
+ NMI_Uint32 dtim_count = 0;
+ NMI_Uint16 u16size=0;
+ nmi_wlan_dev_t* strWlan = Get_wlan_context(&u16size);
+
+ //Warning : This is a development only print to notify the developer, it should be removed later on
+ if(u16size != sizeof(nmi_wlan_dev_t))
+ PRINT_ER("size of nmi_wlan_dev_t in nmi_wlan != it's size in NMI_HOST_AP\n");
+
+ //PRINT_D(HOSTAPD_DBG,"--IN process_tbtt_isr--\n");
+
+ /* Read the current DTIM count from H/W */
+ strWlan->hif_func.hif_read_reg(rMAC_DTIM_COUNT_ADDR, &dtim_count);
+
+ //NMI_PRINTF("dtim_count = %d",dtim_count);
+
+ /* If the beacon pointer has been updated to a new value, the free */
+ /* beacon buffer index is updated to the other buffer. */
+ if(dtim_count == 0)
+ {
+ dtim_count = strBeaconInfo.u8DTIMPeriod - 1;
+
+
+ /* The beacon transmitted at this TBTT is the DTIM. Requeue all */
+ /* MC/BC packets to the high priority queue. */
+ /* Check if the beacon that is being transmitted has the MC bit */
+ /* set */
+ if(NMI_TRUE == get_mc_bit_bcn())
+ while(requeue_ps_packet(NULL, &g_mc_q, NMI_TRUE, NMI_FALSE)
+ == PKT_REQUEUED);
+
+ }
+ else
+ {
+ /* Do nothing */
+ dtim_count--;
+ }
+
+ /* If the buffer that is not currently in use has not been freed*/
+ if(strBeaconInfo.u8beacon_frame != NULL)
+ {
+
+#ifdef NMI_AP_EXTERNAL_MLME
+
+
+ /* Shift the position of the trailer after the TIM element if needed*/
+ u8OldTimLen = strBeaconInfo.u8beacon_frame[strBeaconInfo.u8tim_element_index + LENGTH_OFFSET];
+ if(u8OldTimLen > strBeaconInfo.u8vbmap[LENGTH_OFFSET])
+ {
+ NMI_Uint32 u32ShiftOffset = u8OldTimLen - strBeaconInfo.u8vbmap[LENGTH_OFFSET];
+ NMI_Uint32 u32TrailerIndex = strBeaconInfo.u8tim_element_index+u8OldTimLen+2;
+ /*need to shrink the old TIM; i.e. shift the trailer backwards*/
+ for(i=u32TrailerIndex; i<(u32TrailerIndex+strBeaconInfo.u16tim_element_trailer_len); i++)
+ {
+ strBeaconInfo.u8beacon_frame[i-u32ShiftOffset] = strBeaconInfo.u8beacon_frame[i];
+ }
+ }
+ else if(u8OldTimLen < strBeaconInfo.u8vbmap[LENGTH_OFFSET])
+ {
+ NMI_Uint32 u32ShiftOffset = strBeaconInfo.u8vbmap[LENGTH_OFFSET] - u8OldTimLen;
+ NMI_Uint32 u32TrailerIndex = strBeaconInfo.u8tim_element_index+u8OldTimLen+2;
+ /*need to enlarge the old TIM; i.e. shift the trailer forward*/
+ for(i=(u32TrailerIndex+strBeaconInfo.u16tim_element_trailer_len-1); i>=u32TrailerIndex; i--)
+ {
+ strBeaconInfo.u8beacon_frame[i+u32ShiftOffset] = strBeaconInfo.u8beacon_frame[i];
+ }
+ }
+ /* Other wise TIM element has the same length, and no shifting is required*/
+#endif /*NMI_AP_EXTERNAL_MLME*/
+ strBeaconInfo.u8vbmap[DTIM_CNT_OFFSET] = dtim_count;
+
+ for(i = 0; i < strBeaconInfo.u8vbmap[LENGTH_OFFSET] + 2; i++)
+ {
+ strBeaconInfo.u8beacon_frame[strBeaconInfo.u8tim_element_index + i] =
+ strBeaconInfo.u8vbmap[i];
+ }
+ strBeaconInfo.u16beacon_len= strBeaconInfo.u8tim_element_index + strBeaconInfo.u16tim_element_trailer_len +
+ strBeaconInfo.u8vbmap[LENGTH_OFFSET] + 2 ;
+
+
+ /* The status of BC/MC packets queued for PS should be updated only */
+ /* in DTIM beacon dtim_count==0. For the rest of the becons reset */
+ /* the BC/MC bit in TIM */
+ if(dtim_count != 0)
+ reset_mc_bit_bcn();
+
+ /* send the updated beacon to firmware */
+ NMI_beacon_xmit(strBeaconInfo.u8beacon_frame,strBeaconInfo.u16beacon_len);
+
+
+ }
+
+
+}
+
+
+/*****************************************************************************/
+/* Inline Functions */
+/*****************************************************************************/
+
+/* List buffer is a queue maintained as a singly-linked link list of the */
+/* elements to be stored in the queue. It uses 4 bytes from the element */
+/* itself to store the link address of the next element. This has low */
+/* processing overhead & memory requirements. However, it assumes the */
+/* availability of the extra 4 Bytes in the element for creating the */
+/* link. These 4 bytes are specified by the user during the */
+/* initialization phase & the assigned bytes should not be modified by */
+/* the user. */
+/* Note that no critical sections are currently used in this module. Hence */
+/* a List Buffer should be accessed from only one context/thread. */
+
+/* This function initializes the List Buffer handle. The offset within the */
+/* element which can be used for storing the link is specified as input. */
+inline void init_list_buffer(list_buff_t *lbuff, NMI_Uint32 lnk_byte_ofst)
+{
+ lbuff->head = NULL;
+ lbuff->tail = NULL;
+ lbuff->count = 0;
+ lbuff->lnk_byte_ofst = lnk_byte_ofst;
+}
+
+/* This function adds a new element to the end of the queue. */
+inline void add_list_element(list_buff_t *lbuff, void *elem)
+{
+ NEXT_ELEMENT_ADDR(elem, lbuff->lnk_byte_ofst) = 0;
+
+ if(lbuff->tail == NULL)
+ lbuff->head = elem;
+ else
+ NEXT_ELEMENT_ADDR(lbuff->tail, lbuff->lnk_byte_ofst) = (NMI_Uint32)elem;
+
+ lbuff->tail = elem;
+ lbuff->count++;
+}
+
+/* This function removes the first element from the head of the queue */
+inline void *remove_list_element_head(list_buff_t *lbuff)
+{
+ void *retval = NULL;
+
+ if(lbuff->head == NULL)
+ return NULL;
+
+ retval = lbuff->head;
+ lbuff->head = (void *)NEXT_ELEMENT_ADDR(lbuff->head, lbuff->lnk_byte_ofst);
+
+ if(lbuff->head == NULL)
+ lbuff->tail = NULL;
+
+ lbuff->count--;
+
+ return retval;
+}
+
+/* This function removes a given element from the queue */
+/* The previous element also needs to be given. The previous element ptr */
+/* will be NULL if the curr element is the head */
+/* CAUTION: There is no check done if the element exist in the link list */
+inline void remove_list_element(list_buff_t *lbuff, void *prev_el,
+ void *curr_el)
+{
+
+ void *next_el;
+ next_el = (void *)NEXT_ELEMENT_ADDR(curr_el, lbuff->lnk_byte_ofst);
+
+ if(prev_el == NULL)
+ {
+ /* The current element is the head */
+ lbuff->head = next_el;
+ }
+ else
+ {
+ NEXT_ELEMENT_ADDR(prev_el, lbuff->lnk_byte_ofst) = (NMI_Uint32)next_el;
+ }
+
+ if(next_el == NULL)
+ {
+ /* The current element is the tail */
+ lbuff->tail = prev_el;
+ }
+
+ lbuff->count--;
+
+}
+
+/* This function is used to check the head of the queue */
+inline void *peek_list(list_buff_t *lbuff)
+{
+ return (lbuff->head);
+}
+
+/* This function is used to get the pointer to the next element in the list */
+/* The reference is the current element */
+inline void *next_element_list(list_buff_t *lbuff, void *curr_el)
+{
+ if(curr_el == NULL)
+ return lbuff->head;
+ else
+ return (void *)NEXT_ELEMENT_ADDR(curr_el, lbuff->lnk_byte_ofst);
+}
+
+
+/* This function merges 2 queues of the SAME type */
+/* Queue 2 is reset */
+inline void merge_list(list_buff_t *q1, list_buff_t *q2)
+{
+ if(q1->head == NULL)
+ {
+ q1->head = q2->head;
+ }
+ else
+ {
+ NEXT_ELEMENT_ADDR(q1->tail, q1->lnk_byte_ofst)
+ = (NMI_Uint32) q2->head;
+ }
+
+ if(q2->tail != NULL)
+ q1->tail = q2->tail;
+
+ q1->count += q2->count;
+
+ /* empty the 2nd Q */
+ q2->head = NULL;
+ q2->tail = NULL;
+ q2->count = 0;
+}
+
+
+/*!
+ * @fn void NMI_AP_AddSta(u8 *mac, struct station_parameters *params)
+ * @brief add a station entry in the stations' table
+ * @details Stations are identified by the SSID
+ * @return
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 9 May 2013
+ * @version 1.1 moved to driver
+ */
+inline void NMI_AP_AddSta(u8 *mac, struct station_parameters *params)
+{
+ NMI_Uint8 au8Sa[6];
+ NMI_Uint8 * pu8CurrData;
+ NMI_ieee80211_sta* pstrAsocEntry = NULL;
+ NMI_Uint32 i;
+ NMI_Bool bIsPrevAsoc = NMI_FALSE;
+ NMI_Uint8 ht_info_mod = 0;
+ NMI_Uint16 u16CapInfo = 0;
+
+
+ NMI_memcpy(au8Sa, mac, ETH_ALEN);
+
+ PRINT_D(HOSTAPD_DBG,"Add station BSSID: %x, %x, %x,%x,%x,%x,\n",
+ au8Sa[0], au8Sa[1], au8Sa[2], au8Sa[3], au8Sa[4], au8Sa[5]);
+
+ pstrAsocEntry = (NMI_ieee80211_sta*)find_entry(au8Sa);
+
+
+ pstrAsocEntry = (NMI_ieee80211_sta *)kmalloc(sizeof(NMI_ieee80211_sta),GFP_ATOMIC);
+
+
+ if(pstrAsocEntry == NULL)
+ {
+ PRINT_ER("No memory available to add new station\n");
+ return;
+ }
+
+ /* Reset the AE Handle */
+ NMI_memset(pstrAsocEntry, 0, sizeof(NMI_ieee80211_sta));
+
+ // TODO: Implement inactivity timer
+ /*Add timer for the first new station entry*/
+ /* if(g_inactive_timer == 0)
+ {
+ PRINTK("FIRST STA: CREATE TIMER\n");
+ g_inactive_timer = create_alarm(ap_inactive_timeout, 0,"sta_inactive");
+ start_alarm(g_inactive_timer,1000);
+ }
+ */
+
+ add_entry((void*)pstrAsocEntry, au8Sa);
+ pstrAsocEntry->aging_cnt = 0;
+
+
+
+ /* Set the power save state to default ACTIVE. Will be checked/updated */
+ /* as required later. */
+ pstrAsocEntry->ps_state = ACTIVE_PS;
+ pstrAsocEntry->ps_poll_rsp_qed = NMI_FALSE;
+ pstrAsocEntry->num_ps_pkt = 0;
+ pstrAsocEntry->num_qd_pkt = 0;
+ init_list_buffer(&(pstrAsocEntry->ps_q_lgcy),
+ 0);
+
+
+
+
+ pstrAsocEntry->u16AID = params->aid;
+ PRINT_D(HOSTAPD_DBG,"Assoc ID: %x\n", pstrAsocEntry->u16AID);
+
+
+ // TODO: Really ?
+ /* The 2 MSB bits of Association ID is set to 1 as required by the */
+ /* standard. */
+ //pstrAsocEntry->asoc_id = (pstrAsocEntry->sta_index | 0xc000);
+
+
+ pstrAsocEntry->op_rates.num_rates = params->supported_rates_len;
+ //strStaParams.pu8Rates = params->supported_rates;
+
+ if(pstrAsocEntry->op_rates.num_rates > MAX_RATES_SUPPORTED)
+ {
+ PRINT_ER("number of rates %d exceeds MAX_NUM_RATES %d. will use max!\n",
+ pstrAsocEntry->op_rates.num_rates, MAX_RATES_SUPPORTED);
+ pstrAsocEntry->op_rates.num_rates = MAX_RATES_SUPPORTED;
+ }
+ PRINT_D(HOSTAPD_DBG,"Num rates: %d \n",pstrAsocEntry->op_rates.num_rates);
+
+ for(i=0; i<pstrAsocEntry->op_rates.num_rates; i++)
+ {
+ pstrAsocEntry->op_rates.rates[i] = (params->supported_rates)[i]&0x7F;
+ PRINT_D(HOSTAPD_DBG,"%d ",pstrAsocEntry->op_rates.rates[i]);
+ }
+ PRINT_D(HOSTAPD_DBG,"\n");
+
+
+
+
+ /* TODO: Rates should be sorted by here, if not, the code should sort it*/
+#if 0
+ for(i = 0; i < num_rates; i++)
+ {
+ NMI_Uint8 min = (ae->op_rates.rates[i] & 0x7F);
+ NMI_Uint8 mid = i;
+ NMI_Uint8 tmp = 0;
+
+ for(j = i + 1; j < num_rates; j++)
+ {
+ if(min > (ae->op_rates.rates[j] & 0x7F))
+ {
+ min = (ae->op_rates.rates[j] & 0x7F);
+ mid = j;
+ }
+ }
+
+ tmp = ae->op_rates.rates[i];
+ ae->op_rates.rates[i] = ae->op_rates.rates[mid];
+ ae->op_rates.rates[mid] = tmp;
+ }
+#endif
+
+ /* TODO: If the STA does not support all the basic rates respond with */
+ /* failure (unsupported rates) status. */
+#if 0
+ for(i = 0; i < get_num_basic_rates(); i++)
+ {
+ NMI_Bool found = NMI_FALSE;
+ NMI_Uint8 mac_br = get_mac_basic_rate(i);
+
+ for(j = 0; j < pstrAsocEntry->op_rates.num_rates; j++)
+ {
+ if((pstrAsocEntry->op_rates.rates[j] & 0x7F) == (mac_br & 0x7F))
+ {
+ found = NMI_TRUE;
+ break;
+ }
+ }
+
+ /* Return unsupported rates if the joining station does not */
+ /* support any of the basic rates. */
+ if(found == NMI_FALSE)
+ return UNSUP_RATE;
+ }
+#endif
+
+ // TODO: Add 11n support
+ pstrAsocEntry->ht_cap.ht_supported = (params->ht_capa != NMI_NULL);
+ PRINT_D(HOSTAPD_DBG,"HT supported: %d\n", pstrAsocEntry->ht_cap.ht_supported);
+ if(pstrAsocEntry->ht_cap.ht_supported)
+ {
+ /*
+ pu8CurrData += NMI_AP_ParseHTCap(pu8CurrData, &pstrAsocEntry->ht_hdl,
+ bIsPrevAsoc, &ht_info_mod);*/
+ u16CapInfo = params->ht_capa->cap_info;
+ pstrAsocEntry->ht_cap.cap = params->ht_capa->cap_info;
+ }
+ /* If the STA is not HT capable disallow association if 11n operating */
+ /* mode is not HT_MIXED. If it is HT_MIXED, update the Operating Mode to */
+ /* 3. Also update the global number of non-HT STAs */
+ //if(pstrAsocEntry->ht_cap.ht_supported == 0)
+ //{
+ // TODO: update this according to the FSM
+ /*if(get_11n_op_mode() == HT_MIXED_MODE)
+ {
+ if(mget_HTOperatingMode() != 3)
+ {
+ ht_info_mod = 1;
+ set_ht_operating_mode(3);
+ disable_rifs();
+ }
+
+ g_num_sta_nonht_asoc++;
+
+ /* If auto protection is set, and neither ERP nor HT protection */
+ /* is currently in use, enable HT protection. */
+ /*if((is_autoprot_enabled() == NMI_TRUE) &&
+ (get_protection() != ERP_PROT) &&
+ (get_protection() != HT_PROT))
+ {
+ set_protection(HT_PROT);
+ }
+ }
+ else
+ {
+ // return STA_NOT_HTCAP;
+ PRINT_D(HOSTAPD_DBG,"Station is not HT capable and AP mode don't support HT_MIXED_MODE");
+ }*/
+ //}
+
+
+
+
+
+ /* Print the STA's HT-Capabilities */
+ /*PRINT_D(HOSTAPD_DBG,"STA HT-Capabilities:\n\r");
+ PRINT_D(HOSTAPD_DBG,"ht_capable = %x\n\r", pstrAsocEntry->ht_hdl.ht_capable);
+ PRINT_D(HOSTAPD_DBG,"ldpc_cod_cap = %x\n\r", pstrAsocEntry->ht_hdl.ldpc_cod_cap);
+ PRINT_D(HOSTAPD_DBG,"smps_mode = %x\n\r", pstrAsocEntry->ht_hdl.smps_mode);
+ PRINT_D(HOSTAPD_DBG,"greenfield = %x\n\r", pstrAsocEntry->ht_hdl.greenfield);
+ PRINT_D(HOSTAPD_DBG,"short_gi_20 = %x\n\r", pstrAsocEntry->ht_hdl.short_gi_20);
+ PRINT_D(HOSTAPD_DBG,"short_gi_40 = %x\n\r", pstrAsocEntry->ht_hdl.short_gi_40);
+ PRINT_D(HOSTAPD_DBG,"rx_stbc = %x\n\r", pstrAsocEntry->ht_hdl.rx_stbc);
+ PRINT_D(HOSTAPD_DBG,"max_rx_ampdu_factor = %x\n\r", pstrAsocEntry->ht_hdl.max_rx_ampdu_factor);
+ PRINT_D(HOSTAPD_DBG,"min_mpdu_start_spacing = %x\n\r", pstrAsocEntry->ht_hdl.min_mpdu_start_spacing);
+ PRINT_D(HOSTAPD_DBG,"htc_support = %x\n\r", pstrAsocEntry->ht_hdl.htc_support);
+ PRINT_D(HOSTAPD_DBG,"sta_amsdu_maxsize = %x\n\r", pstrAsocEntry->ht_hdl.sta_amsdu_maxsize);
+ PRINT_D(HOSTAPD_DBG,"chan_width = %x\n\r", pstrAsocEntry->ht_hdl.chan_width);
+ PRINT_D(HOSTAPD_DBG,"dsss_cck_40mhz = %x\n\r", pstrAsocEntry->ht_hdl.dsss_cck_40mhz);*/
+ //PRINT_D(HOSTAPD_DBG,"cipher_type = %x\n\r", pstrAsocEntry->cipher_type);
+
+ // return SUCCESSFUL_STATUSCODE;
+
+ // TODO: Update This in the firmware
+ /* Update the tx rate index */
+ //pstrAsocEntry->tx_rate_index = pstrAsocEntry->op_rates.num_rates - 1;
+
+ /* Assign the index to the maximum rate supported by the station */
+ //pstrAsocEntry->tx_rate_mbps = get_user_rate((NMI_Uint8)
+ //(pstrAsocEntry->op_rates.rates[pstrAsocEntry->op_rates.num_rates- 1] & 0x7F));
+
+
+
+ // TODO: Do we need this
+ #if 0
+ /* If the associated STA does not support Short Slot Time option, */
+ /* the AP needs to use Long Slot Time from the next beacon interval. */
+ if((u16CapInfo & SHORTSLOT) != SHORTSLOT)
+ {
+ /* If STA is already associated as a long slot STA, don't update */
+ /* g_num_sta_no_short_slot */
+ if((pstrAsocEntry->state != ASOC) || (pstrAsocEntry->short_slot == 1))
+ {
+ /* Set the short slot supported field to 0. Also increment */
+ /* the global indicating number of stations not supporting */
+ /* ShortSlot */
+ pstrAsocEntry->short_slot = 0;
+ g_num_sta_no_short_slot++;
+
+ disable_short_slot();
+ set_machw_long_slot_select();
+
+ }
+ }
+ else
+ {
+ /* If STA is already associated as a long slot STA, but trying */
+ /* to reassociate as a short slot STA, update the global */
+ /* g_num_sta_no_short_slot */
+ if((pstrAsocEntry->state == ASOC) && (pstrAsocEntry->short_slot == 0))
+ {
+ g_num_sta_no_short_slot--;
+ if(g_num_sta_no_short_slot == 0)
+ {
+ if(g_short_slot_allowed == NMI_TRUE)
+ {
+ enable_short_slot();
+ set_machw_short_slot_select();
+ }
+ }
+
+ }
+ pstrAsocEntry->short_slot = 1;
+ }
+
+ /* Check if the station is 11b station and enable the ERP protection */
+ /* If the running mode is G_ONLY_MODE, it would have returned */
+ /* UNSUP_RATE and not allow the station to associate with AP. */
+ if(pstrAsocEntry->op_rates.num_rates <= NUM_BR_PHY_802_11G_11B_1)
+ {
+ /* If STA is already associated as an non ERP STA, do not update */
+ /* g_num_sta_non_erp */
+ if((pstrAsocEntry->state != ASOC) ||
+ (u8NumRatesOld > NUM_BR_PHY_802_11G_11B_1))
+ {
+ /* The associated STA is 11b (non-ERP) station */
+ g_num_sta_non_erp++;
+
+ /* Enable protection in case of auto protection */
+ if(is_autoprot_enabled() == NMI_TRUE)
+ {
+ set_protection(ERP_PROT);
+ set_machw_prot_control();
+ }
+ }
+ }
+ else
+ {
+ /* If STA is already associated as a non ERP STA, but trying to */
+ /* reassociate as an ERP STA, update g_num_sta_non_erp */
+ if((pstrAsocEntry->state == ASOC) &&
+ (u8NumRatesOld <= NUM_BR_PHY_802_11G_11B_1))
+ {
+ g_num_sta_non_erp--;
+
+ if(g_num_sta_non_erp == 0)
+ {
+ if(is_autoprot_enabled() == NMI_TRUE)
+ {
+ set_protection(ERP_PROT);
+ set_machw_prot_control();
+ }
+ }
+ }
+ }
+
+ /* Check if the station supports only long preamble */
+ if((u16CapInfo & SHORTPREAMBLE) != SHORTPREAMBLE)
+ {
+ /* If STA is already associated as a long preamble STA, do not */
+ /* update g_num_sta_no_short_pream */
+ if((pstrAsocEntry->state != ASOC) || (pstrAsocEntry->short_preamble == 1))
+ {
+ /* Set the short preamble supported field to 0 and increment */
+ /* the global indicating number of stations not supporting */
+ /* short preamble. */
+ pstrAsocEntry->short_preamble = 0;
+ g_num_sta_no_short_pream++;
+ g_short_preamble_enabled = NMI_FALSE;
+ set_machw_prot_pream(1);
+ }
+ }
+ else
+ {
+ /* If STA is already associated as a long preamble STA, but */
+ /* trying to reassociate as a short preamble STA, update */
+ /* g_num_sta_no_short_pream */
+ if((pstrAsocEntry->state == ASOC) && (pstrAsocEntry->short_preamble == 0))
+ {
+ g_num_sta_no_short_pream--;
+ if(g_num_sta_no_short_pream == 0)
+ {
+ g_short_preamble_enabled = NMI_TRUE;
+ set_machw_prot_pream(0);
+ }
+ }
+ pstrAsocEntry->short_preamble = 1;
+ }
+ #endif
+
+ /* Update the protocol capability in association entry for the STA */
+
+ // TODO: Update This in the firmware
+ /* Update the retry rate set table for this station based on the current */
+ /* transmit rate of this station */
+ //update_entry_retry_rate_set((void *)pstrAsocEntry, get_phy_rate(get_tx_rate_ap(pstrAsocEntry)));
+
+ // TODO: Autorate is not enabled in our case
+#if 0
+ /* Update the minimum and maximum rate index in the global auto */
+ /* rate table for this STA */
+ update_min_rate_idx_ap(pstrAsocEntry);
+ update_max_rate_idx_ap(pstrAsocEntry);
+
+ /* Update the current transmit rate index to minimum supported */
+ /* rate index in case of auto rate */
+ init_tx_rate_idx_ap(pstrAsocEntry);
+ reinit_tx_rate_idx_ap(pstrAsocEntry);
+
+ ar_stats_init(&(pstrAsocEntry->ar_stats));
+#endif /* AUTORATE_FEATURE */
+
+ pstrAsocEntry->state = ASOC;
+}
+
+
+/*!
+ * @fn void NMI_AP_EditSta(u8 *mac, struct station_parameters *params)
+ * @brief Edits a station entry in the stations' table
+ * @details Stations are identified by the SSID
+ * @return
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 9 May 2013
+ * @version 1.1 moved to driver
+ */
+inline void NMI_AP_EditSta(u8 *mac, struct station_parameters *params)
+{
+ NMI_Uint8 au8Sa[6];
+ NMI_ieee80211_sta* pstrAsocEntry = NULL;
+ NMI_Uint8 u8NumRatesOld = 0;
+ NMI_Uint16 u16Mask, u16Set;
+
+ NMI_memcpy(au8Sa, mac, ETH_ALEN);
+
+ PRINT_D(HOSTAPD_DBG,"change station : BSSID: %x, %x, %x,%x,%x,%x,\n",
+ au8Sa[0], au8Sa[1], au8Sa[2], au8Sa[3], au8Sa[4], au8Sa[5]);
+
+ pstrAsocEntry = (NMI_ieee80211_sta*)find_entry(au8Sa);
+
+
+ if(pstrAsocEntry->state == ASOC)
+ {
+ u8NumRatesOld = pstrAsocEntry->op_rates.num_rates;
+
+ // TODO: add security key
+ #if 0
+ /*Associated Station*/
+ if(is_wep_allowed() == NMI_TRUE)
+ {
+ PRINTK("SETTING WEP ENTRY\n");
+ add_wep_entry(pstrAsocEntry->sta_index,mget_WEPDefaultKeyID(),au8Sa);
+ }
+ #endif
+ }
+
+ u16Mask = params->sta_flags_mask;
+ u16Set = params->sta_flags_set;
+
+}
+
+
+/*!
+ * @fn inline void NMI_AP_RemoveSta(NMI_Uint8 * pu8StaInfo)
+ * @brief Removes station from the stations' table
+ * @details Stations are identified by the SSID
+ * @return
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 4 July 2012
+ * @version 1.1 moved to driver
+ */
+inline void NMI_AP_RemoveSta(u8 *mac)
+{
+ NMI_ieee80211_sta* pstrAsocEntry = NULL;
+ NMI_Uint8 au8Sa[6];
+ NMI_Uint8 * pu8CurrData;
+ table_elmnt_t *tbl_elm = 0;
+ NMI_Uint8 elem_numb=0;
+ NMI_Uint32 i;
+
+
+ NMI_memcpy(au8Sa, mac, ETH_ALEN);
+
+ PRINT_D(HOSTAPD_DBG,"Removing stationg BSSID: %x, %x, %x,%x,%x,%x,\n",
+ au8Sa[0], au8Sa[1], au8Sa[2], au8Sa[3], au8Sa[4], au8Sa[5]);
+ pstrAsocEntry = (NMI_ieee80211_sta*)find_entry(au8Sa);
+
+ if(pstrAsocEntry != NULL)
+ {
+ delete_entry(au8Sa);
+ }
+ else
+ {
+ PRINT_ER("couldn't find station in table\n");
+ }
+
+ // TODO: Implement inactivity timer
+ #if 0
+ for(i = 0; i < MAX_HASH_VALUES; i++)
+ {
+ tbl_elm = g_sta_table[i];
+ if(tbl_elm)
+ {
+ PRINTK("There exists assoc stats dont DELETE\n");
+ elem_numb++;
+ break;
+ }
+ }
+ if(elem_numb==0)
+ {
+ if(g_inactive_timer)
+ {
+ PRINTK("DELETING ALARM\n");
+ delete_alarm(g_inactive_timer);
+ }
+ }
+ #endif
+
+ return;
+}
+
+/*****************************************************************************/
+/* Inline functions */
+/*****************************************************************************/
+
+/* This function checks whether SNAP header is present in the frame */
+inline NMI_Bool is_snap_header_present(wlan_rx_t *strWlan_rx)
+{
+ NMI_Uint8 *data = NULL;
+
+ if(strWlan_rx->u16data_len < SNAP_HDR_LEN)
+ return NMI_FALSE;
+
+ data = strWlan_rx->u8msa + strWlan_rx->u8hdr_len;
+
+ if(NMI_memcmp(data, g_snap_header, SNAP_HDR_ID_LEN) != 0)
+ return NMI_FALSE;
+
+ return NMI_TRUE;
+}
+
+
+/* This function sets the 'frame control' bits in the MAC header of the */
+/* input frame to the given 16-bit value. */
+inline void set_frame_control(NMI_Uint8* header, NMI_Uint16 fc)
+{
+ header[0] = (NMI_Uint8)(fc & 0x00FF);
+ header[1] = (NMI_Uint8)(fc >> 8);
+}
+
+inline NMI_Uint8 set_mac_hdr(NMI_Uint8 *mac_hdr)
+{
+ set_frame_control(mac_hdr, DATA);
+
+ return MAC_HDR_LEN;
+}
+
+/* Update the MAC header depending on the protocol */
+inline NMI_Uint8 set_mac_hdr_prot(NMI_Uint8 *mac_hdr, NMI_Uint8 priority,
+ NMI_Uint8 service_class, NMI_Bool qos, NMI_Bool is_ht,
+ NMI_Uint8 is_amsdu)
+{
+ // TODO: implement 11n
+#if 0
+ if(NMI_TRUE == qos)
+ {
+ NMI_Uint8 mac_hdr_len = 0;
+
+ mac_hdr_len = set_mac_hdr_11e(mac_hdr, priority, service_class);
+
+ if(NMI_TRUE == is_ht)
+ mac_hdr_len += set_ht_control(mac_hdr, mac_hdr_len);
+
+ if(NMI_TRUE == is_amsdu)
+ advt_amsdu_frame(mac_hdr);
+
+ return mac_hdr_len;
+ }
+#endif
+ return set_mac_hdr(mac_hdr);
+}
+
+
+/* This function adjusts the frame descriptor data length and offset to */
+/* account for presence of SNAP header */
+inline void adjust_for_snap_header(wlan_rx_t *strWlan_rx)
+{
+ strWlan_rx->u16data_len -= SNAP_HDR_LEN;
+ strWlan_rx->u8hdr_len += SNAP_HDR_LEN;
+}
+
+/* This function sets the 'from ds' bit in the MAC header of the input frame */
+/* to the given value stored in the LSB bit. */
+/* The bit position of the 'from ds' in the 'frame control field' of the MAC */
+/* header is represented by the bit pattern 0x00000010. */
+inline void set_from_ds(NMI_Uint8* header, NMI_Uint8 from_ds)
+{
+ header[1] &= 0xFD;
+ header[1] |= (from_ds << 1);
+}
+
+
+/* This function sets the 'address1' field in the MAC header of the input */
+/* frame to the input MAC Address 'addr'. The 16 LSB bits of 'addr' are */
+/* ignored. */
+inline void set_address1(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(msa + 4, addr, ETH_ALEN);
+}
+
+/* This function sets the 'address2' field in the MAC header of the input */
+/* frame to the input MAC Address 'addr'. The 16 LSB bits of 'addr' are */
+/* ignored. */
+inline void set_address2(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(msa + 10, addr, ETH_ALEN);
+}
+
+
+/* This function sets the 'address3' field in the MAC header of the input */
+/* frame to the input MAC Address 'addr'. The 16 LSB bits of 'addr' are */
+/* ignored. */
+inline void set_address3(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(msa + 16, addr, ETH_ALEN);
+}
+
+
+/* This function extracts the MAC Address in 'address1' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+inline void get_address1(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, msa + 4, ETH_ALEN);
+}
+
+/* This function returns the pointer to the MAC Address in 'Address-1" field */
+/* of the MAC header. */
+inline NMI_Uint8 *get_address1_ptr(NMI_Uint8* msa)
+{
+ return (msa + 4);
+}
+
+/* This function extracts the MAC Address in 'address2' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+inline void get_address2(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, msa + 10, ETH_ALEN);
+}
+
+/* This function extracts the MAC Address in 'address3' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+inline void get_address3(NMI_Uint8* msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, msa + 16, ETH_ALEN);
+}
+
+/* This function returns the pointer to the MAC Address in 'Address-3" field */
+/* of the MAC header. */
+inline NMI_Uint8 *get_address3_ptr(NMI_Uint8* msa)
+{
+ return (msa + 16);
+}
+
+/* This function extracts the 'frame type' bits from the MAC header of the */
+/* input frame. */
+/* Returns the value in the LSB of the returned value. */
+inline BASICTYPE_T get_type(NMI_Uint8* header)
+{
+ return ((BASICTYPE_T)(header[0] & 0x0C));
+}
+
+/* This function extracts the 'frame type and sub type' bits from the MAC */
+/* header of the input frame. */
+/* Returns the value in the LSB of the returned value. */
+inline TYPESUBTYPE_T get_sub_type(NMI_Uint8* header)
+{
+ return ((TYPESUBTYPE_T)(header[0] & 0xFC));
+}
+
+/* This function extracts the 'to ds' bit from the MAC header of the input */
+/* frame. */
+/* Returns the value in the LSB of the returned value. */
+inline NMI_Uint8 get_to_ds(NMI_Uint8* header)
+{
+ return (header[1] & 0x01);
+}
+
+/* This function extracts the 'from ds' bit from the MAC header of the input */
+/* frame. */
+/* Returns the value in the LSB of the returned value. */
+inline NMI_Uint8 get_from_ds(NMI_Uint8* header)
+{
+ return ((header[1] & 0x02) >> 1);
+}
+
+/* This function extracts the 'power management' bit from the MAC header of */
+/* the input frame. */
+/* Returns the value in the LSB of the returned value. */
+inline NMI_Uint8 get_pwr_mgt(NMI_Uint8* header)
+{
+ return ((header[1] & 0x10) >> 4);
+}
+
+/* This function compares the address with the (last bit on air) BIT24 to */
+/* determine if the address is a group address. */
+/* Returns NMI_TRUE if the input address has the group bit set. */
+inline NMI_Bool is_group(NMI_Uint8* addr)
+{
+ if((addr[0] & BIT0) != 0)
+ return NMI_TRUE;
+
+ return NMI_FALSE;
+}
+
+inline NMI_Bool is_sub_type_null_prot(NMI_Uint16 frm_type)
+{
+
+ if(frm_type == QOS_NULL_FRAME)
+ return NMI_TRUE;
+
+
+ return NMI_FALSE;
+}
+
+
+/* This function extracts the 'protocol version' bits from the MAC header of */
+/* the input frame. */
+/* Returns the value in the LSB of the returned value. */
+inline NMI_Uint8 get_protocol_version(NMI_Uint8* header)
+{
+ return header[0] & 0x03;
+}
+
+/* This function is used to handle the Address4 field in the header. */
+/* This checks the from and to DS bits in the header and if both are set */
+/* returns NMI_TRUE, NMI_FALSE otherwise */
+inline NMI_Bool check_from_to_ds(wlan_rx_t *wlan_rx)
+{
+ if(wlan_rx->u8frm_ds && wlan_rx->u8to_ds)
+ return NMI_TRUE;
+
+ return NMI_FALSE;
+}
+
+/* This function compares two given MAC addresses (m1 and m2). */
+/* Returns NMI_Bool, NMI_TRUE if the two addresses are same and NMI_FALSE otherwise. */
+inline NMI_Bool mac_addr_cmp(NMI_Uint8* m1, NMI_Uint8* m2)
+{
+ if(memcmp(m1, m2, 6) == 0)
+ return NMI_TRUE;
+
+ return NMI_FALSE;
+}
+
+/* In AP/STA mode, check if the packet is from this BSS, once state is ENABLED */
+inline NMI_Bool check_bssid_match(wlan_rx_t *strWlan_rx)
+{
+
+ linux_wlan_t *pd = g_linux_wlan;
+ NMI_Uint8* u8macaddr = NULL;
+
+ // TODO: add FSM
+ //if((get_mac_state() == ENABLED) && (strWlan_rx->type != CONTROL))
+ if(strWlan_rx->enumType != CONTROL)
+ {
+ /* Management frames are processed (probe request may have broadcast */
+ /* cast BSSID, coalescing may be required) */
+ if(strWlan_rx->enumType == MANAGEMENT)
+ return NMI_TRUE;
+
+ // Warning: temperorary untill FSM is implemented
+ if((pd->nmc_netdev )== NULL)
+ return NMI_FALSE;
+
+ /**
+ get the bssid address, since we are th AP , the dev address is the BSSID
+ **/
+ //PRINT_D(HOSTAPD_DBG,"Calling cfg_get to get MAC_ADDR\n");
+ u8macaddr =(NMI_Uint8*) pd->nmc_netdev->dev_addr;
+ //PRINT_D(HOSTAPD_DBG,"%2x.%2x.%2x.%2x.%2x.%2x.\n",u8macaddr[0],u8macaddr[1],u8macaddr[2],u8macaddr[3],u8macaddr[4],u8macaddr[5]);
+
+ if(mac_addr_cmp(strWlan_rx->u8bssid, u8macaddr) == NMI_FALSE)
+ return NMI_FALSE;
+ }
+
+ return NMI_TRUE;
+}
+
+/* This function extracts the updates the SA, DA & BSSID address pointers to */
+/* addr1, addr2 & addr3 fields in the WLAN RX structure. */
+inline void set_SA_DA_BSSID_ptr(wlan_rx_t *strWlan_rx)
+{
+ NMI_Uint8 frm_ds = strWlan_rx->u8frm_ds;
+ NMI_Uint8 to_ds = strWlan_rx->u8to_ds;
+ if((to_ds == 0) && (frm_ds == 0))
+ {
+ strWlan_rx->u8sa = strWlan_rx->u8addr2;
+ strWlan_rx->u8da = strWlan_rx->u8addr1;
+ strWlan_rx->u8bssid = strWlan_rx->u8addr3;
+ }
+ else if((to_ds == 0) && (frm_ds == 1))
+ {
+ strWlan_rx->u8sa = strWlan_rx->u8addr3;
+ strWlan_rx->u8da = strWlan_rx->u8addr1;
+ strWlan_rx->u8bssid = strWlan_rx->u8addr2;
+ }
+ else if((to_ds == 1) && (frm_ds == 0))
+ {
+ strWlan_rx->u8sa = strWlan_rx->u8addr2;
+ strWlan_rx->u8da = strWlan_rx->u8addr3;
+ strWlan_rx->u8bssid = strWlan_rx->u8addr1;
+ }
+
+ strWlan_rx->u8ta = strWlan_rx->u8addr2;
+}
+
+
+/* This function checks if QoS bit is set in the given QoS frame */
+inline NMI_Bool is_qos_bit_set(NMI_Uint8* msa)
+{
+ return (msa[0] & 0x80)?NMI_TRUE:NMI_FALSE;
+}
+
+/* This function sets the 'more data' bit in the MAC header of the input */
+/* frame to the LSB of the given value. */
+/* The bit position of the 'more data' bit in the 'frame control field' of */
+/* the MAC header is represented by the bit pattern 0x00100000. */
+inline void set_more_data(NMI_Uint8* header, NMI_Uint8 more_data)
+{
+ header[1] &= 0xDF;
+ header[1] |= (more_data << 5);
+}
+
+/* This function sets the end of service period bit */
+inline void set_qos_prot(NMI_Uint8 *msa)
+{
+#if 0 //def MAC_WMM
+ set_eosp(msa);
+#endif /* MAC_WMM */
+}
+
+/* This function sets the AID0 bit or the Bit 7 in bit map control according */
+/* to the type given as input. */
+inline void set_dtim_bit(NMI_Uint8 type)
+{
+ if(type == AID0_BIT)
+ strBeaconInfo.u8vbmap[TIM_OFFSET] |= 0x1; /* AID = 0 */
+ else
+ strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] |= 0x1; /* Set multicast bit */
+}
+
+/* This function resets the AID0 bit or Bit 7 in bit map control according */
+/* to the type given as input. */
+inline void reset_dtim_bit(NMI_Uint8 type)
+{
+ if(type == AID0_BIT)
+ strBeaconInfo.u8vbmap[TIM_OFFSET] &= 0xFE; /* AID = 0 */
+ else
+ strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] &= 0xFE; /* Reset multicast bit */
+}
+
+
+/* This function extracts the 'order' bit from the frame control field */
+/* within the MAC header. */
+inline NMI_Uint8 get_order_bit(NMI_Uint8 *header)
+{
+ return ((header[1] & 0x80) >> 7);
+
+}
+
+/* This function check whether the MAC header contains HT control field */
+inline NMI_Bool is_ht_frame(NMI_Uint8 *header)
+{
+ if((NMI_TRUE == is_qos_bit_set(header)) && (1 == get_order_bit(header)))
+ return NMI_TRUE;
+
+ return NMI_FALSE;
+}
+
+
+/* This function extracts the destination MAC Address from the incoming WLAN */
+/* packet based on the 'to ds' bit,and updates the MAC Address in the */
+/* allocated 'addr' variable. */
+inline void get_DA(NMI_Uint8* data, NMI_Uint8* da)
+{
+ if(get_to_ds(data) == 1)
+ get_address3(data, da);
+ else
+ get_address1(data, da);
+}
+
+/* This function extracts the destination MAC Address from the incoming WLAN */
+/* packet based on the 'to ds' bit and returns the pointer to the same. */
+inline NMI_Uint8 *get_DA_ptr(NMI_Uint8* data)
+{
+ if(get_to_ds(data) == 1)
+ return get_address3_ptr(data);
+
+ return get_address1_ptr(data);
+}
+
+
+/* Get the MAC header length depending on the protocol used */
+inline NMI_Uint8 get_mac_hdr_len(NMI_Uint8 *msa)
+{
+ NMI_Uint8 mac_hdr_len = MAC_HDR_LEN;
+
+ /* The MAC Header len is 26 only when in QOD Data frames */
+ if((is_qos_bit_set(msa) == NMI_TRUE) && (get_type(msa) == DATA_BASICTYPE))
+ mac_hdr_len += QOS_CTRL_FIELD_LEN;
+
+
+ if(NMI_TRUE == is_ht_frame(msa))
+ mac_hdr_len += HT_CTRL_FIELD_LEN;
+
+ return mac_hdr_len;
+}
+
+
+/* update the appropriate PS queue counters after a Tx complete interrupt */
+/* returns NMI_TRUE if TIM needs to be reset */
+inline NMI_Bool update_ps_counts_txcomp(NMI_ieee80211_sta *ae, NMI_Uint8 *msa)
+{
+ NMI_Bool retval = NMI_FALSE;
+
+ /* TBD: Device a method avoid all this processing in every Tx comp */
+ /* interrupt */
+#if 0//def MAC_WMM
+ BOOL_T del_ena = NMI_FALSE;
+ if(NMI_TRUE == is_qos_bit_set(msa))
+ {
+ NMI_Uint8 priority = get_tid_value(msa);
+
+ if(NMI_TRUE == check_ac_is_del_en(ae, priority))
+ del_ena = NMI_TRUE;
+ }
+
+ if(NMI_TRUE == del_ena)
+ {
+ /* Check the no. of packets queued for a USP, if an USP is in */
+ /* progress. Clear the flag if all packets queued in an USP are */
+ /* transmitted */
+ /* This is done to ignore multiple trigger frames during an USP */
+ /* "USP_in_progress" flag is cleared when the STA wakes up */
+
+ if(ae->USP_in_progress == NMI_TRUE)
+ {
+ ae->num_USP_pkts_qed--;
+ if(ae->num_USP_pkts_qed == 0)
+ ae->USP_in_progress = NMI_FALSE;
+ }
+ }
+ else
+#endif /* MAC_WMM */
+ {
+ /* Non Delivery PS Q Frame are sent only on PS poll */
+ /* Clear the Flag for PS poll response */
+ //ae->ps_poll_rsp_qed = NMI_FALSE;
+ }
+
+ if(ae->num_qd_pkt)
+ {
+ ae->num_qd_pkt--;
+ }
+
+#if 0//def MAC_WMM
+ if(is_all_ac_del(ae) == NMI_TRUE)
+ {
+ if( (ae->num_ps_pkt + ae->num_qd_pkt) == 0)
+ retval = NMI_TRUE;
+ }
+ else
+#endif /* MAC_WMM */
+ {
+ /* If no packets are queued in Sw PSQ or Hw for the */
+ /* station, reset TIM bit */
+ if( (ae->num_ps_pkt + ae->num_qd_pkt) == 0)
+ {
+ retval = NMI_TRUE;
+ }
+ }
+
+ return retval;
+}
+
+
+/* Adjust length and data offset of the received packet */
+/* Returns the length of the frame header. */
+inline NMI_Uint16 modify_frame_length( NMI_Uint8 *msa, NMI_Uint16 *rx_len, NMI_Uint16 *data_len)
+{
+ NMI_Uint32 mac_hdr_len = get_mac_hdr_len(msa);
+
+
+
+ /* Start of data is end of mac header offseted by the security header */
+ *data_len = *rx_len - mac_hdr_len;
+
+ /* If MAC header length is not a multiple of 4 (QOS is Enabled), then */
+ /* the H/w will be offsetting two extra bytes after the header to make */
+ /* it word aligned */
+ if(mac_hdr_len & 3)
+ mac_hdr_len += 2;
+
+ return (mac_hdr_len );
+}
+
+
+inline void flush_ps_queues(NMI_ieee80211_sta *ae)
+{
+ struct tx_complete_data* tx_dscr = NULL;
+
+ /* Free the elements in Legacy PS queue */
+ while(NULL != (tx_dscr = remove_list_element_head(&(ae->ps_q_lgcy))))
+ {
+
+ if(tx_dscr->skb)
+ dev_kfree_skb(tx_dscr->skb);
+
+ linux_wlan_free(tx_dscr);
+
+ g_num_ps_pkt--;
+ }
+
+#if 0//def MAC_WMM
+ /* Free the elements in Delivery enabled PS queue */
+ while(NULL != (tx_dscr = remove_list_element_head(&(ae->ps_q_del_ac))))
+ {
+ /* Free the buffers associated with the transmit descriptor */
+ free_tx_dscr(tx_dscr);
+ g_num_ps_pkt--;
+ }
+ ae->num_ps_pkt_del_ac = 0;
+ ae->USP_in_progress = NMI_FALSE;
+#endif /* MAC_WMM */
+}
+
+
+/* This function handles the change of state of a station from power save to */
+/* active state by requeing all buffered packets to the H/w queue. */
+/* It also reduces the global count of power save stations and requeues all */
+/* multicast/broadcast packets if this count becomes 0. */
+inline void handle_ps_sta_change_to_active(NMI_ieee80211_sta *ae)
+{
+ REQUEUE_STATUS_T status = RE_Q_ERROR;
+
+ //handle_ba_active_ap_prot(ae);
+
+ /* Continue to requeue buffered packets from the station's power save */
+ /* queue to the MAC H/w queue till the power save queue is empty. */
+
+ //status = handle_ps_sta_change_to_active_prot(ae);
+/*
+ if(status == PKT_NOT_REQUEUED)
+ {
+ return;
+ }
+ else*/
+ {
+ while((status=requeue_ps_packet(ae, &(ae->ps_q_lgcy), NMI_TRUE, NMI_FALSE))
+ == PKT_REQUEUED);
+#if 0 //def PS_DSCR_JIT
+ /* This path is not valid currently */
+ /* May be valid if descriptor are not buffered and are */
+ /* created just in time before transmission */
+ if(status == PKT_NOT_REQUEUED)
+ {
+ handle_requeue_pending_packet(ae, &g_ps_pending_q, NMI_TRUE);
+ }
+#endif /* PS_DSCR_JIT */
+ }
+
+ /* To be safe flush all the PS queues. Though they should have been */
+ /* handled in the requeuing functions */
+ /* Reset other variables and TIM */
+ flush_ps_queues(ae);
+ ae->ps_poll_rsp_qed = NMI_FALSE;
+ check_and_reset_tim_bit(ae->u16AID);
+
+
+ /* Decrement the global power save station count */
+ g_num_sta_ps--;
+
+ /* If there are no stations in Power save mode, requeue all multicast/ */
+ /* broadcast packets. */
+ if(g_num_sta_ps == 0)
+ {
+ while(requeue_ps_packet(NULL, &g_mc_q, NMI_TRUE, NMI_FALSE) == PKT_REQUEUED);
+ }
+}
+
+
+/* This function handles the change of state of a station from active to */
+/* power save state by removing all packets from the H/w queue and buffering */
+/* these in the S/w power save queue. Also ii increments the global count of */
+/* power save stations. In case this is the only station in power save state */
+/* the multicast/broadcast packets also need to be removed from the H/w */
+/* queues and buffered in the multicast queue. */
+inline void handle_ps_sta_change_to_powersave(NMI_ieee80211_sta *ae)
+{
+ NMI_Bool ps_del_en_ac = NMI_FALSE;
+
+ /* TBD. Remove packets from all H/w queue destined for this station and */
+ /* add to the ae queue. */
+
+ if(g_num_sta_ps == 0)
+ {
+ // TODO: add mc/bc frames from hardware tx queue to ps queue
+ /* TBD - no stations were in power save. mc/bc packets need to be */
+ /* removed and added to g_mc_q */
+ }
+
+ /* To be safe flush all the PS queues. Though they should have been */
+ /* handled in the requeuing functions */
+ /* Reset other variables and TIM */
+ flush_ps_queues(ae);
+ ae->ps_poll_rsp_qed = NMI_FALSE;
+
+ // TODO: decide wither to set flags here
+ //update_ps_flags_ap(ae, NMI_FALSE, num_elements_moved,ps_del_en_ac);
+
+ /* Power Save buffering for 11n protocol related */
+ //handle_ps_sta_change_to_powersave_prot(ae);
+
+ /* Increment the global power save station count */
+ g_num_sta_ps++;
+}
+
+
+/*
+* @brief This function checks the power save state of the station
+* from all received packets.
+*
+* @details The power management bit in the received packet is
+* checked and the association entry of the corresponding
+* transmitting station is updated with the power save
+* state. Also if there is any change in power save state
+* the appropriate handling function is called.
+*
+* @param[in] 1) Pointer to association entry
+* 2) Power Save value
+*
+* @return
+* @author Abd Al-Rahman Diab
+* @date 5 june 2013
+* @version 1.0
+*/
+void check_ps_state(NMI_ieee80211_sta* ae, STA_PS_STATE_T ps)
+{
+ /* 1 - POWER_SAVE, 0 - ACTIVE */
+ if((ae == NULL ) || (ae->ps_state == ps))
+ {
+ /* There is no change in station power save mode. Do nothing. */
+ return;
+ }
+
+ /* Station has changed power save state. Update the entry and handle the */
+ /* change as required. */
+ ae->ps_state = ps;
+
+ if(ps == ACTIVE_PS)
+ {
+ handle_ps_sta_change_to_active(ae);
+ }
+ else
+ {
+ handle_ps_sta_change_to_powersave(ae);
+ }
+
+}
+
+/*
+* @brief filter_wlan_rx_frame
+* @details This function filters the incoming wlan rx packet and
+* sends the results of the operation.
+* @param[in] 1) MAC header of incoming packet.
+* 2) Pointer to rx descriptor
+* 3) Pointer to wlan_rx structure
+* @return True if the frame is to be discarded, False otherwise
+* @author Abd Al-Rahman Diab
+* @date 21 APRIL 2013
+* @version 1.0
+*/
+NMI_Bool filter_wlan_rx_frame(wlan_rx_t *strWlan_rx)
+{
+ NMI_ieee80211_sta *ae = (NMI_ieee80211_sta *)strWlan_rx->u8sa_entry;
+ NMI_Uint8 *msa = strWlan_rx->u8msa;
+
+ if(strWlan_rx->enumType == DATA_BASICTYPE)
+ {
+ if(ae == 0)
+ {
+ // TODO: handle this station either by reporting to HOSTAPD or sending deauth frame
+ /* Send the De-authentication Frame to the station */
+ //send_deauth_frame(wlan_rx->ta, error);
+
+ /* Return TRUE for filter frame */
+ return NMI_TRUE;
+ }
+ else if (ae->state != ASOC)
+ {
+
+ // TODO: handle this station either by reporting to HOSTAPD or sending disassoc frame
+ /* Send the Disassociation Frame to the station */
+ //send_disasoc_frame(wlan_rx->ta, error);
+
+ /* Return TRUE for filter frame */
+ return NMI_TRUE;
+ }
+
+
+ /* This STA is active, set the count to 0 */
+ ae->aging_cnt = 0;
+
+
+ }
+ else
+ {
+ if(ae != 0)
+ {
+
+ /* This STA is active, set the count to 0 */
+ ae->aging_cnt = 0;
+
+ }
+ }
+ return NMI_FALSE;
+}
+
+
+/*
+* @brief NMI_Process_rx_frame
+* @details handle incoming data & mgmt frames
+* @param[in] u8Buff : pointer to frame
+* u32Size : size of frame buffer
+* @return 1 if it's data frame, 0 otherwise
+* @author Abd Al-Rahman Diab
+* @date 21 APRIL 2013
+* @version 1.0
+*/
+void NMI_Process_rx_frame(NMI_Uint8 *u8Buff, NMI_Uint32 u32Size)
+{
+ wlan_rx_t strWlan_rx = {0};
+ NMI_Uint32 min_pkt_len = MAC_HDR_LEN ; //null frame
+ NMI_Uint8 * mac_addr = g_linux_wlan->nmc_netdev->dev_addr;
+
+ //skip the host header offset
+ u8Buff +=HOST_HDR_OFFSET;
+
+ /* Extract Addresses from the MAC Header */
+ get_address1(u8Buff, strWlan_rx.u8addr1);
+ get_address2(u8Buff, strWlan_rx.u8addr2);
+ get_address3(u8Buff, strWlan_rx.u8addr3);
+
+ strWlan_rx.enumType = get_type(u8Buff);
+ strWlan_rx.u8frm_ds = get_from_ds(u8Buff);
+ strWlan_rx.u8to_ds = get_to_ds(u8Buff);
+ strWlan_rx.u8Sub_type = get_sub_type(u8Buff);
+ strWlan_rx.bIs_grp_addr = is_group(strWlan_rx.u8addr1);
+
+ strWlan_rx.u16rx_len = u32Size;
+ strWlan_rx.u8msa = u8Buff;
+
+
+ /* Update the SA, DA & BSSID pointers to corresponding addr1, addr2 or */
+ /* addr3 fields of wlan_rx structure. */
+ set_SA_DA_BSSID_ptr(&strWlan_rx);
+
+ // TODO: Update the statistics for get_station
+ //update_debug_rx_stats(status);
+
+ /* Exception case 1: Maximum length exceeded */
+ if(strWlan_rx.u16rx_len > MAX_MSDU_LEN)
+ {
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxMaxLenExc:%d > %d\n\r",strWlan_rx.u16rx_len, MAX_MSDU_LEN);
+ //g_mac_stats.pwrx_maxlenexc++;
+ /* Do nothing and return */
+ return;
+ }
+
+
+ /* Exception case 2: Protocol Version Match Fail */
+ if(get_protocol_version(u8Buff) != PROTOCOL_VERSION)
+ {
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxFrmHdrProtVerFail\n\r");
+ //g_mac_stats.rxfrmhdrprotverfail++;
+ /* Do nothing and return */
+ return;
+ }
+
+ /* Exception case 3: Address-4 Field Present */
+ if(check_from_to_ds(&strWlan_rx) == NMI_TRUE)
+ {
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxFrmHdrAddr4Prsnt\n\r");
+ //g_mac_stats.rxfrmhdraddr4prsnt++;
+ /* Do nothing and return */
+ return;
+ }
+
+
+
+ /* Exception case 4: BSSID Match Fail */
+ if(check_bssid_match(&strWlan_rx) == NMI_FALSE)
+ {
+ if(strWlan_rx.bIs_grp_addr == NMI_FALSE)
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxFrmHdrBssidChkFail\n\r");
+ //g_mac_stats.rxfrmhdrbssidchkfail++;
+ /* Do nothing and return */
+ return;
+ }
+
+ if(strWlan_rx.u8Sub_type == PS_POLL)
+ min_pkt_len = PS_POLL_LEN - FCS_LEN;
+
+ /* Exception case 6: Less than minimum acceptable length */
+ if(strWlan_rx.u16rx_len < min_pkt_len)
+ {
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxMinLenExc: %d < %d\n\r", strWlan_rx.u16rx_len, min_pkt_len);
+ //g_mac_stats.pwrx_minlenexc++;
+ /* Do nothing and return */
+ return;
+ }
+
+ // TODO: decide if i need these 2 elements
+ /* Extract required parameters from the frame header */
+ //wlan_rx.priority_val = get_priority_value(msa);
+ //wlan_rx.service_class = get_ack_policy(msa, wlan_rx.addr1);
+
+
+ strWlan_rx.u8sa_entry = find_entry(strWlan_rx.u8addr2);
+
+
+ /* Exception case 8: Not a BC/MC frame and not directed */
+ if((strWlan_rx.bIs_grp_addr == NMI_FALSE) &&
+ (mac_addr_cmp(strWlan_rx.u8addr1,mac_addr) == NMI_FALSE) )
+ {
+ NMI_Uint8 *addr1 = strWlan_rx.u8addr1;
+ PRINT_D(HOSTAPD_DBG,"HwEr:RxUnexpFrm:%x:%x:%x:%x:%x:%x\n\r",addr1[0],addr1[1],addr1[2],
+ addr1[3],addr1[4],addr1[5]);
+ //g_mac_stats.rxunexpfrm++;
+ /* Do nothing and return */
+ return;
+ }
+
+
+ /* Filter the frame based on mode of operation */
+ if(filter_wlan_rx_frame(&strWlan_rx) == NMI_TRUE)
+ {
+ //g_mac_stats.pewrxft++;
+ return;
+ }
+
+ /* Modify the frame length and get the frame header length depending on */
+ /* the QoS and HT features enabled. */
+ strWlan_rx.u8hdr_len = modify_frame_length( strWlan_rx.u8msa,
+ &(strWlan_rx.u16rx_len), &(strWlan_rx.u16data_len));
+
+
+ /* Check for the type of frame and process accordingly */
+ if((strWlan_rx.bIs_grp_addr == NMI_FALSE) && (strWlan_rx.enumType == CONTROL))
+ {
+ // TODO: we don't handle BA control frames , so we only need to handle PS POLL frames with Power managemnet
+ if(handle_ps_poll(&strWlan_rx) == NMI_FALSE)
+ {
+ // TODO: add support for 11n
+ /* Handle control frames other than PS Poll */
+ // ap_enabled_rx_control((NMI_Uint8 *)req);
+ }
+ }
+ else if(strWlan_rx.enumType == MANAGEMENT)
+ {
+ NMI_Uint32* u32header=0;
+
+ // TODO: update statistics
+ /* Update receive MIB counters */
+ // mincr_ReceivedFragmentCount();
+
+ //Get NMI header
+ //u32header = (strWlan_rx.u8msa)-HOST_HDR_OFFSET;
+
+#ifdef USE_WIRELESS
+ NMI_WFI_monitor_rx(strWlan_rx.u8msa,strWlan_rx.u16rx_len);
+#endif
+
+ }
+ else if(strWlan_rx.enumType == DATA_BASICTYPE)
+ {
+
+ // TODO: MEASURE_PROCESSING_DELAY
+ /*
+#ifdef MEASURE_PROCESSING_DELAY
+ g_delay_stats.numrxdscr += num_dscr;
+#endif /* MEASURE_PROCESSING_DELAY */
+
+
+ // TODO: update statistics
+ /* Update receive MIB counters */
+ /* if(wlan_rx.is_grp_addr == NMI_TRUE) {
+ print_log_debug_level_1("\n[DL1][INFO][Rx] {Multicast WLAN Rx}");
+ mincr_MulticastReceivedFrameCount();
+ } else {
+ print_log_debug_level_1("\n[DL1][INFO][Rx] {Unicast WLAN Rx}");
+ mincr_ReceivedFragmentCount();
+ }
+
+ update_rx_mib_prot(msa, wlan_rx.data_len);*/
+
+ ap_enabled_rx_data(&strWlan_rx);
+
+ }
+
+}
+
+
+/*
+* @brief ap_enabled_rx_data
+* @details This function handles the incoming DATA frame to send to the host.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+void ap_enabled_rx_data(NMI_Uint8* msg)
+{
+ //NMI_Uint8 priority_rx = 0;
+ STA_PS_STATE_T ps = ACTIVE_PS;
+ NMI_Uint8 data_trailer = 0;
+ NMI_Uint8* buffer = 0 ;
+ NMI_Uint8* host_hdr =0;
+ wlan_rx_t *wlan_rx = (wlan_rx_t *)msg;
+ NMI_Uint8 *msa = wlan_rx->u8msa;
+ NMI_ieee80211_sta *da_ae = 0;
+ NMI_ieee80211_sta *sa_ae = 0;
+ struct tx_complete_data* tx_data = NULL;
+ // msdu_desc_t *frame_desc = 0;
+ //CIPHER_T ct = (CIPHER_T)wlan_rx->ct;
+ //MSDU_PROC_STATUS_T status = PROC_ERROR;
+ TYPESUBTYPE_T frm_type = DATA;
+ //msdu_indicate_t msdu = {{0},};
+ //msdu_proc_state_t msdu_state = {0};
+
+ /* Get association entry for the source address */
+ sa_ae = (NMI_ieee80211_sta *)wlan_rx->u8sa_entry;
+
+
+ /* Power management checks */
+ ps = (STA_PS_STATE_T)get_pwr_mgt(msa);
+ frm_type = (TYPESUBTYPE_T)wlan_rx->u8Sub_type;
+
+ // TODO: add PS
+ /* Check if the received function is the Null function Packet */
+ if((frm_type == NULL_FRAME) ||
+ (is_sub_type_null_prot(frm_type) == NMI_TRUE))
+ {
+ check_ps_state(sa_ae, ps);
+
+//#ifdef DEBUG_MODE
+ //g_mac_stats.pewrxnf++;
+//#endif /* DEBUG_MODE */
+ return;
+ }
+
+ /* Get the priority of the incoming frame */
+ //priority_rx = wlan_rx->priority_val;
+ //msdu.priority = priority_rx;
+
+
+ /* Check for WMM-PS trigger frame and process accordingly */
+ //pwr_mgt_handle_prot(sa_ae, ps, priority_rx, msa);
+
+ // TODO: add PS
+ /* Check the Power Save Bit in the receive frame */
+ check_ps_state(sa_ae, ps);
+
+ /* Create the MSDU descriptors for the received frame */
+
+ /* Create the MSDU decsriptor */
+ //status = update_msdu_info(wlan_rx, &msdu, &msdu_state);
+
+
+ /* Get the frame descriptor pointer */
+ //frame_desc = &(msdu.frame_desc);
+
+ /* Get association entry based on the source address to determine */
+ /* the next path of the packet. */
+ sa_ae = (NMI_ieee80211_sta* )find_entry(wlan_rx->u8sa);
+ da_ae = (NMI_ieee80211_sta* )find_entry(wlan_rx->u8da);
+
+ if(da_ae != 0)
+ {
+ //NMI_Uint8 key_type = 0;
+ //NMI_Bool wlan2wlan = NMI_FALSE;
+ NMI_Bool use_same_buffer = NMI_TRUE;
+
+ /* CipherType is reset to no encryption and is set as per the */
+ /* policy used for the out going sta */
+ //ct = NO_ENCRYP;
+
+ /* Set the Key type required for transmission */
+ //key_type = UCAST_KEY_TYPE;
+
+ /* If the station is associated with the AP, the packet is put */
+ /* onto the wireless network. */
+ if(da_ae->state == ASOC)
+ {
+
+ // TODO: recheck this
+ /* If the received frame is not a QoS frame, create a */
+ /* copy of the frame in a separate buffer to fit the QoS */
+ /* header. */
+ //if(is_qos_bit_set(msa) == NMI_FALSE)
+ //use_same_buffer = NMI_FALSE;
+
+ /* The MAC Header offset field in TX-Dscr is 8 bits long. */
+ /* Hence a frame copy is created if the MAC Header field */
+ /* exceeds 256 when it is created in place. */
+ //if(frame_desc->data_offset > 255)
+ // use_same_buffer = NMI_FALSE;
+
+
+ // TODO: security stuff
+ /* Before forwarding the packet onto the WLAN interface */
+ /* security checks needs to performed on the states of the */
+ /* transmitting and receiving stations */
+ //wlan2wlan = check_sec_ucast_wlan_2_wlan_ap(da_ae, sa_ae, &ct,
+ //&data_trailer);
+
+ /* Update length of the frame to accommodate the security */
+ /* trailers if any. */
+ //update_frame_length(frame_desc, data_trailer);
+
+ //if(wlan2wlan == NMI_TRUE)
+ //{
+
+ // send this packet to wlan interface
+ tx_data = (struct tx_complete_data*)kmalloc(sizeof(struct tx_complete_data),GFP_ATOMIC);
+
+ if(tx_data == NULL){
+ PRINT_ER("Failed to allocate memory for tx_data structure\n");
+ return ;
+ }
+
+ /* Set Address1 field in the WLAN Header with destination address */
+ set_address1(msa, wlan_rx->u8da);
+
+ /* Set Address2 field in the WLAN Header with the BSSID */
+ set_address2(msa, wlan_rx->u8bssid);
+
+ /* Set Address2 field in the WLAN Header with the source address */
+ set_address3(msa, wlan_rx->u8sa);
+
+ /*{int i ;
+ for(i = 0; i < wlan_rx->u16rx_len; i++)
+ {
+
+ printk("msa[%d] = %2x \n", i, msa[i]);
+ }
+ }*/
+
+ tx_data->buff =msa;
+ tx_data->size = wlan_rx->u16rx_len;
+ tx_data->skb = NULL;
+ NMI_Xmit_data((void*)tx_data, WLAN_TO_WLAN);
+
+ // }
+
+ // TODO: update stat
+ //g_mac_stats.pewrxu++;
+
+
+ }
+
+ }
+ else
+ {
+ /* Broadcast/Multicast frames need to be forwarded on WLAN also */
+ if(is_group(wlan_rx->u8da) == NMI_TRUE)
+ {
+ //CIPHER_T grp_ct = NO_ENCRYP;
+
+ /* Before forwarding the packet on WLAN and HOST interface */
+ /* security checks needs to performed on the states of the */
+ /* transmitting station */
+ // if(ap_check_sec_tx_sta_state(sa_ae) != NMI_TRUE)
+ //{
+ // continue;
+ //}
+
+//#ifdef DEBUG_MODE
+ // g_mac_stats.pewrxb++;
+//#endif /* DEBUG_MODE */
+
+ /* Before forwarding the packet on the WLAN interface */
+ /* security checks needs to performed on the states of the */
+ /* transmitting station */
+ //data_trailer = check_sec_bcast_wlan_2_wlan_ap(&grp_ct);
+
+ /* Update the length of the frame to accommodate the */
+ /* security trailers if any. */
+ //update_frame_length(frame_desc, data_trailer);
+
+
+ tx_data = (struct tx_complete_data*)kmalloc(sizeof(struct tx_complete_data),GFP_ATOMIC);
+
+ if(tx_data == NULL){
+ PRINT_ER("Failed to allocate memory for tx_data structure\n");
+ return ;
+ }
+
+ /* Set Address1 field in the WLAN Header with destination address */
+ set_address1(msa, wlan_rx->u8da);
+
+ /* Set Address2 field in the WLAN Header with the BSSID */
+ set_address2(msa, wlan_rx->u8bssid);
+
+ /* Set Address2 field in the WLAN Header with the source address */
+ set_address3(msa, wlan_rx->u8sa);
+
+ /*{int i ;
+ for(i = 0; i < wlan_rx->u16rx_len; i++)
+ {
+
+ printk("msa[%d] = %2x \n", i, msa[i]);
+ }
+ }*/
+
+
+ tx_data->buff =msa;
+ tx_data->size = wlan_rx->u16rx_len;
+ tx_data->skb = NULL;
+ NMI_Xmit_data((void*)tx_data, WLAN_TO_WLAN);
+
+ }
+ //else
+ //{
+ /* Packet is a Unicast packet to the AP */
+//#ifdef DEBUG_MODE
+ //g_mac_stats.pewrxu++;
+//#endif /* DEBUG_MODE */
+ //}
+
+ /* Check for SNAP header at beginning of the data and set the */
+ /* data pointer and length accordingly. */
+ if(NMI_TRUE == is_snap_header_present(wlan_rx))
+ {
+ /* If received packet is a security handshake packet process */
+ /* it in the security layer */
+ /*if(is_sec_handshake_pkt_ap(sa_ae, frame_desc->buffer_addr,
+ frame_desc->data_offset,
+ frame_desc->data_len,
+ (CIPHER_T)wlan_rx->ct) == NMI_TRUE)
+ {
+ continue;
+ }*/
+
+ /* Adjust the frame to account for the SNAP header */
+ adjust_for_snap_header(wlan_rx);
+ }
+ //else
+ //{
+ /* Before forwarding the packet on WLAN and HOST interface */
+ /* security checks needs to performed on the states of the */
+ /* transmitting station */
+ //if(ap_check_sec_tx_sta_state(sa_ae) != NMI_TRUE)
+ // {
+ //continue;
+ //}
+ // }
+
+ /* Call MSDU Indicate API with the MSDU to be sent to the host */
+
+ //msdu_indicate_ap(&msdu);
+ host_hdr = msa + ((wlan_rx->u8hdr_len) - ETHERNET_HDR_LEN);
+
+ NMI_memcpy(host_hdr, wlan_rx->u8da, ETH_ALEN);
+ NMI_memcpy(host_hdr+6, wlan_rx->u8sa, ETH_ALEN);
+
+ buffer = msa + wlan_rx->u8hdr_len - ETHERNET_HDR_LEN ;
+
+ frmw_to_linux(buffer, (wlan_rx->u16data_len) + ETHERNET_HDR_LEN);
+
+ }
+
+}
+
+
+static void linux_FH_wlan_tx_complete(void* priv, int status){
+
+ struct tx_complete_data* pv_data = (struct tx_complete_data*)priv;
+ if(status == 1){
+ PRINT_D(TX_DBG,"Packet sent successfully - Size = %d - Address = %p - SKB = %p\n",pv_data->size,pv_data->buff, pv_data->skb);
+ } else {
+ PRINT_D(TX_DBG,"Couldn't send packet - Size = %d - Address = %p - SKB = %p\n",pv_data->size,pv_data->buff, pv_data->skb);
+ }
+
+
+ /*{
+ int i;
+ printk("tx_data = %x\n",pv_data);
+ printk("data_len = %d\n",pv_data->size);
+ for(i = 0 ; i < pv_data->size ; i++)
+ printk("msa3[%d] = %x\n",i,((NMI_Uint8*)(pv_data->buff))[i]);
+ } */
+
+ /* Power Management */
+ handle_ps_tx_comp_ap(pv_data);
+
+ /* Free the SK Buffer, its work is done */
+ if(pv_data->skb)
+ dev_kfree_skb(pv_data->skb);
+
+ linux_wlan_free(pv_data);
+}
+
+/*
+* @brief NMI_Xmit_data
+* @details This function transmit the data frames to firmware.
+* @Processing This function computes hash value of a given MAC address.
+* This value is used to access the hash table.
+* @return hash value
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+int NMI_Xmit_data(void* ptx_data, Data_Interface InterfaceType)
+{
+ struct tx_complete_data* tx_data = (struct tx_complete_data*)ptx_data;
+ struct sk_buff *skb = tx_data-> skb;
+ struct sk_buff *xmit_skb;
+ struct ethhdr *eth;
+ NMI_ieee80211_sta *asoc_entry = NULL;
+ NMI_Uint8 ethsaddr[ETH_ALEN];
+ NMI_Uint8 ethdaddr[ETH_ALEN];
+ NMI_Uint8 mac_hdr_len;
+ NMI_Uint8* da;
+ NMI_Uint8 service_class, is_qos,is_htc, is_amsdu;
+ NMI_Uint8 priority = BEST_EFFORT_PRIORITY; // TODO: this should not be fixed
+ NMI_Uint8* BSSID = g_linux_wlan->nmc_netdev->dev_addr;
+ NMI_Uint8* snap_hdr;
+ NMI_Uint8* mac_hdr;
+ NMI_Uint8* data_start;
+ NMI_Uint16 eth_type;
+ NMI_Uint16 pkt_len = 0;
+ NMI_Uint16 data_len =0;
+ NMI_Uint16 u16size=0;
+
+ int QueueCount =0;
+
+ //if(nic->oup.wlan_add_to_tx_que == NULL){printk("g_wlan == null return \n\n");
+ //return;}
+
+ /*int i;
+ printk("skb->len = %d\n",skb->len);
+ for(i = 0 ; i < skb->len ; i++)
+ printk("%x\n",(skb->data)[i]);*/
+
+ if (InterfaceType == HOST_TO_WLAN)
+ {
+ pkt_len = skb->len;
+
+ eth = (struct ethhdr *)(skb->data);
+
+ /* Set the destination address field in the WLAN Tx Request structure. */
+ NMI_memcpy(ethdaddr, &eth->h_dest, ETH_ALEN);
+
+ /* For AP, the source address should be sent with the frame. */
+ NMI_memcpy(ethsaddr, &eth->h_source, ETH_ALEN);
+
+
+ /* Here check whether the destination is associated, */
+ /* If its not associated, then drop the packet */
+
+ /* For unicast packets, check if the destination STA is associated. */
+ if(is_group(ethdaddr) == NMI_FALSE)
+ {
+ /* Get association entry for association state */
+ asoc_entry = (NMI_ieee80211_sta*)find_entry(ethdaddr);
+
+ /* If the destination STA is not associated free the data packet and */
+ /* return. */
+ if((asoc_entry == 0) || (asoc_entry->state != ASOC))
+ {
+ //Wait for station to be associated
+
+ /* Free the SK Buffer */
+ dev_kfree_skb(skb);
+ linux_wlan_free(tx_data);
+ return ;
+ }
+
+ service_class = NORMAL_ACK;
+ }
+ else
+ {
+ service_class = BCAST_NO_ACK;
+ }
+
+ // allocate new skb to accomodate the MAC header
+ xmit_skb = dev_alloc_skb((skb->len) +ETH_ETHERNET_HDR_OFFSET);
+
+
+ /* Check whether QoS option is implemented */
+ // TODO: 11n is not enabled yet
+ is_qos = 0; //is_qos_required(sta_index);
+
+ /* Check whether receiver is HT capable */
+ // HTC is not supported yet
+ is_htc = 0;
+
+ // we currently don't support amsdu
+ is_amsdu = 0;
+
+ mac_hdr = xmit_skb->data;
+
+
+ }
+ else if(InterfaceType == WLAN_TO_WLAN)
+ {
+ // TODO: try to eliminate the copying here to improve performance
+
+ skb=dev_alloc_skb( tx_data->size );
+
+ memcpy(skb->data , tx_data->buff, tx_data->size );
+
+
+ /* frames coming from wlan are freed within vmm handle rxq
+ null frames from ps-poll are freed here
+ */
+ if(get_sub_type(tx_data->buff) == NULL_FRAME)
+ {
+ kfree(tx_data->buff);
+ }
+
+ /* Check whether receiver is HT capable */
+ // HTC is not supported yet
+ is_htc = 0;
+
+ // we currently don't support amsdu
+ is_amsdu = 0;
+
+ mac_hdr = skb->data;
+
+ #if 0
+ if(is_group(da) == NMI_FALSE)
+ {
+ service_class = NORMAL_ACK;
+ }
+ else
+ {
+ service_class = BCAST_NO_ACK;
+ }
+ #endif
+
+ tx_data->buff = skb->data;
+ tx_data->skb = skb;
+
+ /*{int i ;
+ for(i = 0; i < tx_data->size; i++)
+ {
+
+ printk("msa2[%d] = %2x \n", i, mac_hdr[i]);
+ }
+ }*/
+
+ }
+ else if(InterfaceType == MONITOR_TO_WLAN)
+ {
+
+ mac_hdr = tx_data->buff;
+
+
+ /* Get the Destination address */
+ da = get_DA_ptr(mac_hdr);
+
+ /* Get association entry for association state */
+ asoc_entry = (NMI_ieee80211_sta*)find_entry(da);
+
+
+ if(buffer_tx_packet(asoc_entry, da, priority , tx_data) == NMI_FALSE)
+ {
+ nmi_wlan_txq_add_mgmt_pkt((void*)tx_data,tx_data->buff,tx_data->size,linux_FH_wlan_tx_complete);
+ }
+
+ return;
+
+ }
+
+ mac_hdr_len = set_mac_hdr_prot(mac_hdr, priority,
+ service_class, is_qos,
+ is_htc, is_amsdu);
+
+ set_from_ds(mac_hdr, 1);
+
+ if (InterfaceType == HOST_TO_WLAN)
+ {
+
+ // TODO: add security
+ //if(ct != NO_ENCRYP)
+ //set_wep(mac_hdr, 1);
+
+ /* Set Address1 field in the WLAN Header with destination address */
+ set_address1(mac_hdr, ethdaddr);
+
+ /* Set Address2 field in the WLAN Header with the BSSID */
+ set_address2(mac_hdr, BSSID);
+
+ /* Set Address2 field in the WLAN Header with the source address */
+ set_address3(mac_hdr, ethsaddr);
+
+ /* Get the Destination address */
+ da = get_DA_ptr(mac_hdr);
+
+
+ /* SNAP header needs to be set for IP/ARP packets. Note that there is */
+ /* sufficient space allocated for SNAP and MAC header in the buffer. */
+
+ /* Extract the type of the ethernet packet and set the SNAP header */
+ /* contents. Also set the data pointer field in the WLAN Tx Request */
+ /* structure, as required, to the correct value. */
+
+ #ifdef LITTLE_ENDIAN
+ eth_type= eth->h_proto;
+ #else
+ eth_type = ( eth->h_proto>>8) | ( eth->h_proto<<8);
+ #endif
+ //printk("eth->h_proto= %x \n or eth_type =%x \n",eth->h_proto, ( eth->h_proto>>8) | ( eth->h_proto<<8));
+ //printk("eth_type =%x \n",eth_type);
+
+ if((eth_type == ARP_TYPE) ||
+ (eth_type == IP_TYPE) ||
+ (eth_type == ONE_X_TYPE) ||
+ (eth_type == VLAN_TYPE) ||
+ (eth_type == LLTD_TYPE))
+ {
+ /* The SNAP header is set before the ethernet payload. */
+ /* */
+ /* +--------+--------+--------+----------+---------+---------------+ */
+ /* | DSAP | SSAP | UI | OUI | EthType | EthPayload | */
+ /* +--------+--------+--------+----------+---------+---------------+ */
+ /* | 1 byte | 1 byte | 1 byte | 3 bytes | 2 bytes | x bytes | */
+ /* +--------+--------+--------+----------+---------+---------------+ */
+ /* <---------------- SNAP Header ----------------> */
+ /* <------------------------ 802.11 Payload -----------------------> */
+ snap_hdr = xmit_skb->data + mac_hdr_len;
+
+
+ *snap_hdr++ = 0xAA;
+ *snap_hdr++ = 0xAA;
+ *snap_hdr++ = 0x03;
+ *snap_hdr++ = 0x00;
+ *snap_hdr++ = 0x00;
+ *snap_hdr++ = 0x00;
+ *snap_hdr++ = (NMI_Uint8)((eth_type>>8) &0x00ff);
+ *snap_hdr++ = (NMI_Uint8)(eth_type &0x00ff);
+
+ /* Set the data length parameter to the MAC data length only (does */
+ /* not include headers) */
+ data_len = pkt_len + mac_hdr_len - ETHERNET_HDR_LEN + SNAP_HDR_LEN;
+
+ data_start = snap_hdr;
+
+ /* Note that the Ethernet Type field is already set in the ethernet */
+ /* header and follows this. */
+ }
+ else
+ {
+ /* Set the data length parameter to the MAC data length only (does */
+ /* not include headers) */
+ data_len = pkt_len+ mac_hdr_len - ETHERNET_HDR_LEN;
+
+ data_start = xmit_skb->data + mac_hdr_len;
+ }
+
+ NMI_memcpy(data_start, (skb->data) + ETHERNET_HDR_LEN , pkt_len - ETHERNET_HDR_LEN);
+
+ dev_kfree_skb(skb);
+
+ tx_data->buff = xmit_skb->data;
+ tx_data->size = data_len;
+ tx_data->skb = xmit_skb;
+
+ }
+ else
+ {
+ /* Get the Destination address */
+ da = get_DA_ptr(mac_hdr);
+
+ /* Get association entry for association state */
+ asoc_entry = (NMI_ieee80211_sta*)find_entry(da);
+ }
+
+ /*if (InterfaceType == WLAN_TO_WLAN)
+ {
+ int i;
+ printk("tx_data = %x\n",tx_data);
+ printk("data_len = %d\n",tx_data->size);
+ for(i = 0 ; i < tx_data->size ; i++)
+ printk("msa2[%d] = %x\n",i,((NMI_Uint8*)(tx_data->buff))[i]);
+ } */
+
+ /*QueueCount = nmi_wlan_txq_add_mgmt_pkt((void*)tx_data,
+ tx_data->buff,
+ tx_data->size,
+ linux_FH_wlan_tx_complete);*/
+
+ //QueueCount = nmi_FH_wlan_txq_add_net_pkt(tx_data,tx_data->buff,tx_data->size,linux_FH_wlan_tx_complete);
+
+
+
+ if(buffer_tx_packet(asoc_entry, da, priority , tx_data) == NMI_FALSE)
+ {
+ QueueCount = nmi_FH_wlan_txq_add_net_pkt((void*)tx_data,
+ tx_data->buff,
+ tx_data->size,
+ linux_FH_wlan_tx_complete);
+ }
+
+ return QueueCount;
+}
+
+
+
+/*
+* @brief hash
+* @details This function computes the hash value for given address.
+* @Processing This function computes hash value of a given MAC address.
+* This value is used to access the hash table.
+* @return hash value
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+NMI_Uint32 hash(NMI_Uint8* addr)
+{
+ NMI_Uint32 sum = 0;
+ NMI_Uint32 i = 0;
+
+ for(i = 0; i < 6; i++)
+ sum += addr[i];
+
+ return sum % MAX_HASH_VALUES;
+}
+
+/*
+* @brief find_entry
+* @details This function searches the table for an entry having the given key value.
+* @Processing The hash value (val) for the given key is computed
+* using the hash function. The table entry holding the
+* given key is then searched. If such an entry is
+* found the pointer to the entry stored in the table
+* entry is returned.
+* @return The element of the corresponding table entry, if an entry , having a key
+* identical to the given key was found.
+* Zero is returned if no matching entry is found.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+void* find_entry(NMI_Uint8* key)
+{
+ table_elmnt_t *tbl_ptr = 0;
+ NMI_Uint32 val = 0;
+
+ /* Zero entry is fixed for Bcast/Mcast address */
+ /* If the address is BCast/MCast Address, return 0 */
+ if(key[0] & BIT0)
+ {
+ return 0;
+ }
+
+
+ /* Calculate hash value for the key */
+ val = hash(key);
+ tbl_ptr = g_sta_table[val];
+
+ while(tbl_ptr)
+ {
+ if(mac_addr_cmp(tbl_ptr->key, key) == NMI_TRUE)
+ return tbl_ptr->element;
+
+ tbl_ptr = tbl_ptr->next_hash_elmnt;
+ }
+
+ return 0;
+}
+
+
+
+/*
+* @brief add_entry
+* @details This function adds an entry to asoc table..
+* @Processing A table element is created. The entry and key values
+* are set in table element and the table element is
+* inserted in the appropriate hash bucket of association
+* table.
+*
+* There is no maximum limit set for creation of assoc
+* entries. But there is a maximum limit for number of
+* associated stations, MAX_ELEMENTS.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+void add_entry(void* entry, NMI_Uint8* key)
+{
+ NMI_Uint32 val = 0;
+ table_elmnt_t *new_elm = 0;
+
+ /* Create a buffer to hold table element */
+ new_elm = (table_elmnt_t*)kmalloc( sizeof(table_elmnt_t),GFP_ATOMIC);
+
+ if(new_elm == NULL)
+ {
+ return;
+ }
+
+ /* Compute the hash value */
+ val = hash(key);
+
+ /* Insert the element at head of the hash */
+ NMI_memcpy(new_elm->key, key, ETH_ALEN);
+
+ new_elm->next_hash_elmnt = g_sta_table[val];
+ new_elm->element = entry;
+
+ g_sta_table[val] = new_elm;
+}
+
+
+/*
+* @brief delete_entry
+* @details This function deletes the entry having the given key
+* value from the table. The space occupied by the entry
+* is not freed here.
+*
+* @Processing The hash value (val) for the given key is computed
+* using the hash function. The table entry holding the
+* given key is then searched. If such an entry is
+* found the corresponding table entry is removed from
+* the hash list and freed. If no matching entry is
+* found no action is taken.
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+void delete_entry(NMI_Uint8* key)
+{
+ table_elmnt_t *tbl_ptr = 0;
+ table_elmnt_t *prev_ptr = 0;
+ NMI_Uint32 val = 0;
+
+ /* Calculate hash value for the key */
+ val = hash(key);
+
+ /* Initialize temporary pointers to be used in the loop below */
+ tbl_ptr = g_sta_table[val];
+ prev_ptr = g_sta_table[val];
+
+ /* Given the hash bucket, find out the entry that has the key */
+ while(tbl_ptr)
+ {
+ if(mac_addr_cmp(tbl_ptr->key, key) == NMI_TRUE)
+ {
+ /* Got a match. Modify the next pointer of the element pointing */
+ /* to this element. */
+ if(tbl_ptr == g_sta_table[val])
+ /* The element to be freed is the first element */
+ g_sta_table[val] = tbl_ptr->next_hash_elmnt;
+ else
+ /* The element to be freed is not the first element */
+ prev_ptr->next_hash_elmnt = tbl_ptr->next_hash_elmnt;
+
+ // TODO: recheck this
+ /* Free the element referred to by this key */
+ //delete_element(tbl_ptr->element);
+ kfree(tbl_ptr->element);
+
+ /* Free this element */
+ kfree(tbl_ptr);
+
+ return;
+ }
+
+ prev_ptr = tbl_ptr;
+ tbl_ptr = tbl_ptr->next_hash_elmnt;
+ }
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : handle_ps_tx_comp_ap */
+/* */
+/* Description : This function handles transmit complete interrupt for */
+/* power management purpose. */
+/* */
+/* Inputs : 1) Pointer to the transmit descriptor */
+/* */
+/* Globals : g_num_mc_bc_pkt */
+/* */
+/* Processing : This function checks if the frame transmitted was a */
+/* broadcast/multicast frame. If so it reduces the global */
+/* bc/mc packet count in case it is non-zero (indicating */
+/* that the packets were queued). If it is unicast the */
+/* association entry is searched and corresponding number */
+/* of packets are decremented if non-zero (indicating they */
+/* were queued). */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void handle_ps_tx_comp_ap(struct tx_complete_data *tx_dscr )
+{
+ NMI_ieee80211_sta *ae;
+ NMI_Uint8 *msa = tx_dscr->buff;
+ NMI_Uint8 *da = NULL;
+
+ /* Get the Destination address */
+ da = get_DA_ptr(msa);
+
+ ae = (NMI_ieee80211_sta*)find_entry(da);
+
+ if(is_group(da) == NMI_TRUE)
+ {
+
+ if(g_num_mc_bc_qd_pkt > 0)
+ {
+ g_num_mc_bc_qd_pkt--;
+
+ /* If no packets are queued in Sw PSQ or Hw for the */
+ /* station, reset DTIM bit */
+ if((g_num_mc_bc_pkt + g_num_mc_bc_qd_pkt) == 0)
+ {
+ reset_dtim_bit(AID0_BIT);
+ reset_dtim_bit(DTIM_BIT);
+ }
+ }
+ }
+ else
+ {
+ if(ae == 0)
+ {
+ /* Exception. Should not happen */
+ return;
+ }
+
+ /* Reset the age counter as this STA is active */
+ ae->aging_cnt = 0;
+
+ /* Get the type of frame transmitted */
+ if(get_type(msa) == (BASICTYPE_T)(DATA))
+ {
+ if(NMI_TRUE == update_ps_counts_txcomp(ae, msa))
+ {
+ check_and_reset_tim_bit(ae->u16AID);
+ }
+ }
+
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : check_and_reset_tim_bit */
+/* */
+/* Description : This function sets the TIM bit corresponding to the */
+/* association ID in virtual bit map. */
+/* */
+/* Inputs : 1) Association ID */
+/* */
+/* Globals : g_vbmap */
+/* */
+/* Processing : This function is called whenever a packet is removed */
+/* from the power save queue for a sleeping station. Given */
+/* the association ID, set the bit corresponding to that. */
+/* Recalculate length and offset fields and update the */
+/* the virtual bit map. */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void check_and_reset_tim_bit(NMI_Uint16 asoc_id)
+{
+ NMI_Uint8 byte_offset = 0;
+ NMI_Uint8 bit_offset = 0;
+ NMI_Uint8 pvb_offset = 0;
+ NMI_Uint8 length = 0;
+ NMI_Uint8 new_pvb_offset = 0;
+ int16_t i = 0;
+ NMI_Uint8 new_length = MIN_TIM_LEN;
+
+ /* Traffic Indication Virtual Bit Map within the AP, generates the TIM */
+ /* such that if a station has buffered packets, then the corresponding */
+ /* bit (which can be found from the association ID) is set. The byte */
+ /* offset is obtained by dividing the association ID by '8' and the bit */
+ /* offset is the remainder of the association ID when divided by '8'. */
+ byte_offset = (asoc_id & (~0xC000)) >> 3;
+ bit_offset = (asoc_id & (~0xC000)) & 0x07;
+
+ /* Calculate the current byte offset in vbmap */
+ pvb_offset = (strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] & 0xFE) >> 1;
+ length = strBeaconInfo.u8vbmap[LENGTH_OFFSET];
+
+ /* Reset the TIM bit */
+ strBeaconInfo.u8vbmap[TIM_OFFSET + byte_offset] &= ~g_bmap[bit_offset];
+
+ /* Calculate new offset using the following algorithm: */
+ /* The new offset will be equal to or greater than the current offset as */
+ /* the TIM bit is reset. Also the new TIM length cannot be more the */
+ /* existing length. So the algorithm is starting from old offset to */
+ /* old offset + TIM length, find out the first occurance of non-zero byte*/
+ /* in the TIM element array. This will be the new offset. If no non-zero */
+ /* bytes are found, new offset is zero (as initialized). */
+ for(i = pvb_offset; i < pvb_offset + length - MIN_TIM_LEN; i++)
+ {
+ if(strBeaconInfo.u8vbmap[TIM_OFFSET + i])
+ {
+ new_pvb_offset = i;
+ break;
+ }
+ }
+
+ /* Calculate new length using the following algorithm */
+ /* The new TIM length will be less than or equal to old length as TIM bit*/
+ /* is reset. Having new offset calculated, the new length can be */
+ /* calculated as the last occurance of non-zero byte from new offset to */
+ /* new offset+old length in the TIM element array. (In other words the */
+ /* first occurance of non-zero byte in the reverse direction) */
+ for(i = pvb_offset + length - MIN_TIM_LEN; i >= 0; i--)
+ {
+ if(strBeaconInfo.u8vbmap[TIM_OFFSET + i])
+ {
+ new_length += (i - new_pvb_offset);
+ break;
+ }
+ }
+
+ /* Assign the new offset and length to the vbmap */
+ strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] |= (new_pvb_offset & 0xEF) << 1;
+ strBeaconInfo.u8vbmap[LENGTH_OFFSET] = new_length;
+}
+
+
+
+/*
+* @brief delete_entry
+* @details This function requeues a packet in the H/w queue for
+* transmission after removing it from the S/w queue where
+* it was buffered for power management purpose.
+*
+* @Processing First the H/w queue is checked to see if it is full.
+* If H/w queue is full then pkt is not requeued.
+* If H/w queue is available then pkt is requeued.
+* A packet is removed from the head of the given power
+* save queue. The transmit descriptor is extracted and
+* added to the H/w queue. The power save queue element
+* buffer is freed.
+* @author Abd Al-Rahman Diab
+* @date 05 june 2013
+* @version 1.0
+*/
+REQUEUE_STATUS_T requeue_ps_packet(NMI_ieee80211_sta* ae, list_buff_t *qh,
+ NMI_Bool ps_q_legacy, NMI_Bool eosp)
+{
+ NMI_Uint8 q_num = 0;
+ NMI_Uint8 *mac_hdr = 0;
+ NMI_Uint8 addr1[6] = {0};
+ NMI_Uint8 tx_rate = 0;
+ NMI_Uint8 pream = 0;
+ NMI_Uint8 srv_cls = 0;
+ NMI_Uint8 tid = 0;
+ NMI_Uint32 phy_tx_mode = 0;
+ NMI_Bool is_qos = NMI_FALSE;
+ NMI_Uint32 retry_set[2] = {0};
+ struct tx_complete_data *tx_dscr = 0;
+
+ /* Remove the power save queue element structure from the head of the */
+ /* given queue. */
+ tx_dscr = remove_list_element_head(qh);
+
+ /* If the queue has no packets return NMI_FALSE to indicate that no packets */
+ /* were available to be requeued. */
+ if(tx_dscr == 0)
+ {
+ return NO_PKT_IN_QUEUE;
+ }
+
+ /* Extract the pointer to the MAC header from the Tx-Descriptor */
+ mac_hdr = tx_dscr->buff;
+
+
+
+ /* Extract DA, TID and QoS from the MAC header of the MSDU */
+ get_address1(mac_hdr, addr1);
+ tid = BEST_EFFORT_PRIORITY;//get_priority_value(mac_hdr);
+ is_qos = is_qos_bit_set(mac_hdr);
+
+
+
+ /* Peek and check if the queue is empty. If so, set the more data bit to */
+ /* 0. Otherwise set it to 1. */
+ if(peek_list(qh) == NULL)
+ {
+
+ if(is_qos == NMI_TRUE)
+ {
+ // TODO: look at this comment if you will handle addba & delba
+ // make sure this is not a management frame with Action subtype and BA category
+ //if((is_qos == NMI_TRUE) && ( !((get_sub_type(mac_hdr) == ACTION ) && (mac_hdr[MAC_HDR_LEN+CATEGORY_OFFSET] == BA_CATEGORY))))
+ set_qos_prot(mac_hdr);
+ }
+
+ set_more_data(mac_hdr, 0);
+ }
+ else
+ {
+ set_more_data(mac_hdr, 1);
+ }
+
+#if 0
+ /* Currently disabled */
+ /* If current sp length = max sp length-1 eosp bit set and END_OF_QUEUE */
+ /* is returned */
+ if(ps_q_legacy == NMI_FALSE)
+ {
+ if(is_end_prot(ae) == NMI_TRUE)
+ {
+ set_qos_prot(mac_hdr);
+ end_of_q = NMI_TRUE;
+ }
+ }
+#endif
+
+ /* If current sp length = max sp length-1 eosp bit set and END_OF_QUEUE */
+ /* is returned */
+ if(NMI_TRUE == eosp)
+ set_qos_prot(mac_hdr);
+
+
+
+ /* Update PS queue counters */
+ if(ps_q_legacy == NMI_TRUE)
+ {
+ if(is_group(addr1) == NMI_TRUE)
+ {
+ g_num_mc_bc_pkt--;
+ }
+ else
+ {
+ ae->num_ps_pkt--;
+ }
+ }
+ else
+ {
+ //ae->num_ps_pkt_del_ac--;
+ }
+ g_num_ps_pkt--;
+
+ /* Check if the packet needs to be buffered for BA. If Block ACK session */
+ /* is active then donot queue in the HW queue. */
+ /* When STA has come out of sleep then BA is !HALTED */
+
+ // TODO: add this check when enabling 11n
+ //if(NMI_FALSE == is_serv_cls_buff_pkt((NMI_Uint8 *)ae, q_num, tid, tx_dscr))
+ {
+
+ // TODO: add EAPOL and other monitor types check here
+ if(get_sub_type(tx_dscr->buff) == NULL_FRAME)
+ {
+ nmi_wlan_txq_add_mgmt_pkt((void*)tx_dscr,
+ tx_dscr->buff,
+ tx_dscr->size,
+ linux_FH_wlan_tx_complete);
+ }
+ else
+ {
+ nmi_FH_wlan_txq_add_net_pkt((void*)tx_dscr,
+ tx_dscr->buff,
+ tx_dscr->size,
+ linux_FH_wlan_tx_complete);
+ }
+ //PRINTK("QMU ADD PS PKT\n");
+ /* Queue the frame for transmission */
+ //if(qmu_add_tx_packet(&g_q_handle.tx_handle, q_num, tx_dscr) != QMU_OK)
+ //{
+ /* Exception. Do nothing. */
+//#ifdef DEBUG_MODE
+ // g_mac_stats.qaexc++;
+//#endif /* DEBUG_MODE */
+ // free_tx_dscr((NMI_Uint32 *)tx_dscr);
+
+ // return RE_Q_ERROR;
+ // }
+
+ /* Update UC/BC/MC Hw queue packet count */
+ if(is_group(addr1) == NMI_TRUE)
+ {
+ g_num_mc_bc_qd_pkt++;
+ }
+ else
+ {
+ ae->num_qd_pkt++;
+ }
+
+ }
+
+ return PKT_REQUEUED;
+}
+
+
+/*
+* @brief set_tim_bit
+* @details This function sets the TIM bit corresponding to the
+* association ID in virtual bit map.
+*
+* @Processing This function is called whenever a new packet is added
+* to the power save queue for a sleeping station. Given
+* the association ID, set the bit corresponding to that.
+* If this bit is not already included in the offset and
+* length fields of virtual bit map adjust offset and
+* length fields.
+*
+* @author Abd Al-Rahman Diab
+* @date 05 june 2013
+* @version 1.0
+*/
+void set_tim_bit(NMI_Uint16 asoc_id)
+{
+ NMI_Uint8 byte_offset = 0;
+ NMI_Uint8 bit_offset = 0;
+ NMI_Uint8 pvb_offset = 0;
+ NMI_Uint8 length = 0;
+
+ /* Traffic Indication Virtual Bit Map within the AP, generates the TIM */
+ /* such that if a station has buffered packets, then the corresponding */
+ /* bit (which can be found from the association ID) is set. The byte */
+ /* offset is obtained by dividing the association ID by '8' and the bit */
+ /* offset is the remainder of the association ID when divided by '8'. */
+ byte_offset = (asoc_id & (~0xC000)) >> 3;
+ bit_offset = (asoc_id & (~0xC000)) & 0x07;
+
+ /* Calculate the current byte offset in vbmap */
+ pvb_offset = (strBeaconInfo.u8vbmap[BMAP_CTRL_OFFSET] & 0xFE) >> 1;
+ length = strBeaconInfo.u8vbmap[LENGTH_OFFSET];
+
+ /* Compare the existing offset and the offset for the new STA. Create */
+ /* new length and offset and add that to vbmap. */
+ if(byte_offset < pvb_offset)
+ {
+ pvb_offset = byte_offset;
+ length = pvb_offset - byte_offset;
+ }
+ else if(byte_offset > pvb_offset + length - MIN_TIM_LEN)
+ {
+ length += byte_offset - pvb_offset;
+ }
+
+ /* Set the TIM bit and length */
+ strBeaconInfo.u8vbmap[TIM_OFFSET + byte_offset] |= g_bmap[bit_offset];
+ strBeaconInfo.u8vbmap[LENGTH_OFFSET] = length;
+}
+
+
+/*
+* @brief update_ps_flags_ap
+* @details This function updates the flags after a packet in enqued
+* in the power save buffer
+*
+* @Processing This function updates the flags after a packet in enqued
+* in the power save buffer
+*
+* @author Abd Al-Rahman Diab
+* @date 05 june 2013
+* @version 1.0
+*/
+void update_ps_flags_ap(NMI_ieee80211_sta *ae, NMI_Bool bc_mc_pkt,
+ NMI_Uint8 num_buff_added, NMI_Bool ps_add_del_ac)
+{
+ if(num_buff_added == 0)
+ return;
+
+ if(bc_mc_pkt == NMI_TRUE)
+ {
+ /* The global count for queued BC/MC packets is incremented here. */
+ /* This count is checked for resetting the AID0 bit in the TIM */
+ /* element once all buffered BC/MC packets have been transmitted. It */
+ /* is decremented in Tx complete for BC/MC packets. */
+ g_num_mc_bc_pkt += num_buff_added;
+ g_num_ps_pkt++;
+
+ /* Set the AID0 bit. This is reset BC/MC packet queue becomes empty. */
+ /* It is updated in transmit complete processing. */
+ set_dtim_bit(AID0_BIT);
+ set_dtim_bit(DTIM_BIT);
+ }
+ else
+ {
+ ae->num_ps_pkt += num_buff_added;
+ g_num_ps_pkt += num_buff_added;
+
+ /* Set the TIM bit for this station */
+ set_tim_bit(ae->u16AID);
+ }
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : is_ps_buff_pkt_ap */
+/* */
+/* Description : This function checks if a packet requries buffering */
+/* based on the power save state of the destination. */
+/* */
+/* Inputs : 1) Pointer to the association table */
+/* 2) Pointer to the destination address */
+/* 3) Pointer to the Q-number */
+/* 4) Pointer to the Q-head to which the packet must be q-d */
+/* */
+/* Globals : g_mc_q */
+/* g_num_mc_bc_pkt */
+/* g_num_sta_ps */
+/* */
+/* Processing : In case the packet is a broadcast/multicast packet, the */
+/* global g_num_sta_ps is checked to determine if any of */
+/* the associated stations are in power save mode. */
+/* In case of a unicast packet the association */
+/* entry is checked to determine the power save state of */
+/* the station. The queue limits are checked and if the */
+/* maximum is reached the queue header pointer is set to */
+/* zero so that the calling function can free the buffer. */
+/* Otherwise the queue details are set appropriately. */
+/* */
+/* Outputs : Q-Num to which the packet must be queued and the Queue */
+/* pointer to which the packet must be queued. */
+/* */
+/* Returns : NMI_TRUE, if the packet should be buffered for power save */
+/* NMI_FALSE, if the packet should not be buffered */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Draft */
+/* */
+/*****************************************************************************/
+
+NMI_Bool is_ps_buff_pkt_ap(NMI_ieee80211_sta *ae, NMI_Uint8 *da, struct tx_complete_data* dscr)
+{
+ NMI_Bool ps_del_en_ac = NMI_FALSE;
+ NMI_Bool bc_mc_pkt = is_group(da);
+ NMI_Uint8 priority = 0;
+ list_buff_t *qh = NULL;
+
+
+ /* check if pkt is BC/MC or Unicast */
+ if(bc_mc_pkt == NMI_TRUE)
+ {
+ if(g_num_sta_ps == 0)
+ {
+ /* All stations are in Active mode. No buffering required. */
+ return NMI_FALSE;
+ }
+
+ /* If the global BC/MC queue has not reached the maximum size */
+ /* received BC/MC packet should be queued in it. Else packet */
+ /* should be dropped */
+
+ if(g_num_ps_pkt < PS_PKT_Q_MAX_LEN)
+ {
+ qh = &g_mc_q;
+ }
+ }
+ else
+ {
+ if(ae == 0)
+ {
+ /* Exception. Should not occur. */
+ return NMI_FALSE;
+ }
+
+ if(ae->ps_state == ACTIVE_PS)
+ {
+ /* Station is in Active mode. No buffering required. */
+ return NMI_FALSE;
+ }
+
+ if(g_num_ps_pkt < PS_PKT_Q_MAX_LEN)
+ {
+ qh = (&(ae->ps_q_lgcy));
+
+ }
+ }
+
+
+ if( qh != NULL)
+ {
+ add_list_element(qh, dscr);
+ update_ps_flags_ap(ae, bc_mc_pkt, 1, NMI_FALSE);
+ }
+ else
+ {
+ if(dscr->skb)
+ dev_kfree_skb(dscr->skb);
+
+ linux_wlan_free(dscr);
+ }
+
+ return NMI_TRUE;
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : buffer_tx_packet */
+/* */
+/* Description : This function buffers a packet ready for transmission */
+/* */
+/* Inputs : 1) Pointer to the transmit descriptor */
+/* 2) Number of the queue to which the packet belongs */
+/* 3) Destination address */
+/* */
+/* Globals : g_mc_q */
+/* g_num_mc_bc_pkt */
+/* g_num_sta_ps */
+/* */
+/* Processing : The packet is buffered based on the service class or the */
+/* power save mode of the receiving STA */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : NMI_TRUE, if the given packet is buffered in any queue */
+/* NMI_FALSE, if the packet is not buffered and can be sent */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Draft */
+/* */
+/*****************************************************************************/
+
+NMI_Bool buffer_tx_packet(NMI_Uint8 *entry, NMI_Uint8 *da, NMI_Uint8 priority,
+ struct tx_complete_data *tx_dscr)
+{
+ if(NMI_TRUE == is_ps_buff_pkt_ap((NMI_ieee80211_sta*)entry, da, tx_dscr))
+ {
+#ifdef DEBUG_MODE
+ g_mac_stats.psbuff++;
+#endif /* DEBUG_MODE */
+ }
+#if 0 // open this if you handle Block Ack
+ else if(NMI_TRUE == is_serv_cls_buff_pkt(entry, priority, tx_dscr))
+ {
+#ifdef DEBUG_MODE
+ g_mac_stats.bapendingtx++;
+#endif /* DEBUG_MODE */
+ }
+#endif
+ else
+ {
+ return NMI_FALSE;
+ }
+
+ /* If the packet is buffered return NMI_TRUE */
+ return NMI_TRUE;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : tx_null_frame */
+/* */
+/* Description : This function prepares and sends a NULL frame to the */
+/* given station. */
+/* */
+/* Inputs : 1) Address of station to which NULL frame is directed */
+/* */
+/* Globals : None */
+/* */
+/* Processing : The NULL frame is prepared and added to the H/w queue */
+/* with the required descriptor. */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Draft */
+/* */
+/*****************************************************************************/
+
+void tx_null_frame(NMI_Uint8 *sa, NMI_ieee80211_sta *ae, NMI_Bool is_qos, NMI_Uint8 priority,NMI_Uint8 more_data)
+{
+ NMI_Uint8 q_num = 0;
+ NMI_Uint8 tx_rate = 0;
+ NMI_Uint8 pream = 0;
+ struct tx_complete_data* tx_data;
+ NMI_Uint8 *msa = 0;
+ NMI_Uint8 len = 0;
+ // UWORD32 phy_tx_mode = 0;
+ //UWORD32 retry_set[2] = {0};
+
+ /* Allocate buffer for the NULL frame and set its contents */
+ tx_data = (struct tx_complete_data*)kmalloc(sizeof(struct tx_complete_data),GFP_ATOMIC);
+
+ if(tx_data == NULL)
+ PRINT_ER("Failed to allocate memory for tx_data structure\n");
+
+
+ if(is_qos == NMI_TRUE)
+ {
+ //len = set_frame_ctrl_qos_null_ap(msa, priority, 0);
+ // q_num = get_txq_num(priority);
+ }
+ else
+ {
+
+ len = MAC_HDR_LEN ;//+ FCS_LEN;
+
+ msa = (NMI_Uint8*)kmalloc(len,GFP_ATOMIC);
+
+ if(msa == NULL)
+ {
+ PRINT_ER("No Mem for NULL Tx DSCR\n");
+ kfree(tx_data);
+ return;
+ }
+
+ tx_data->buff = msa;
+ tx_data->size = len;
+ tx_data->skb = NULL;
+
+ set_frame_control(msa, (NMI_Uint16)NULL_FRAME);
+
+ /* NULL frames will be put in Normal priority queue */
+ //q_num = NORMAL_PRI_Q;
+ }
+
+ /* Set the from ds bit */
+ set_from_ds(msa, 1);
+
+ /* Set the address fields */
+ set_address1(msa, sa);
+ set_address2(msa, g_linux_wlan->nmc_netdev->dev_addr);
+ set_address3(msa, g_linux_wlan->nmc_netdev->dev_addr);
+
+ /* Get the transmit rate for the associated station based on the */
+ /* auto-rate, multi-rate or user-rate settings. The preamble must be */
+ /* set accordingly. */
+ //tx_rate = get_tx_rate_to_sta(ae);
+ //pream = get_preamble(tx_rate);
+
+ /* Update the retry set information for this frame */
+ //update_retry_rate_set(1, tx_rate, ae, retry_set);
+
+ /* Get the PHY transmit mode based on the transmit rate and preamble */
+ //phy_tx_mode = get_dscr_phy_tx_mode(tx_rate, pream, (void *)ae);
+
+ /* Create the transmit descriptor and set the contents */
+ //tx_dscr = create_default_tx_dscr(0, 0, 0);
+
+
+ NMI_Xmit_data((void*)tx_data, WLAN_TO_WLAN);
+
+#if 0
+ /* Set various transmit descriptor parameters */
+ set_tx_params(tx_dscr, tx_rate, pream, NORMAL_ACK, phy_tx_mode, retry_set);
+ set_tx_buffer_details(tx_dscr, msa, 0, len-FCS_LEN, 0);
+ set_tx_dscr_q_num((UWORD32 *)tx_dscr, q_num);
+ /* This is already done in create_default_tx_dscr */
+ /* set_tx_security(tx_dscr, NO_ENCRYP, 0, se->sta_index); */
+ set_ht_ps_params(tx_dscr, (void *)ae, tx_rate);
+ set_ht_ra_lut_index(tx_dscr, NULL, 0, tx_rate);
+ update_tx_dscr_tsf_ts((UWORD32 *)tx_dscr);
+
+
+ if(qmu_add_tx_packet(&g_q_handle.tx_handle, q_num, tx_dscr) != QMU_OK)
+ {
+//#ifdef DEBUG_MODE
+ //g_mac_stats.qaexc++;
+//#endif /* DEBUG_MODE */
+
+ /* Exception. Free the transmit descriptor and packet buffers if it */
+ /* cannot be added to the H/w queue. */
+ free_tx_dscr((UWORD32 *)tx_dscr);
+ }
+ else if(ae != NULL)
+ {
+ ae->num_qd_pkt++;
+ }
+#endif
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : handle_ps_poll */
+/* */
+/* Description : This function handles a received PS-Poll frame in the */
+/* access point mode. */
+/* */
+/* Inputs : 1) Pointer to the PS-Poll frame */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function checks if a previous PS-Poll frame is yet */
+/* to be processed (checks a flag in the association entry) */
+/* If not, the first frame from the power save queue is */
+/* requeued. If requeuing is not successful, a null frame */
+/* is transmitted to the station. */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : BOOL_T, BTRUE, If it was a PS Poll frame */
+/* BFALSE, otherwise */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 10 2005 Draft */
+/* */
+/*****************************************************************************/
+
+NMI_Bool handle_ps_poll(wlan_rx_t *wlan_rx )
+{
+
+ NMI_ieee80211_sta *ae = (NMI_ieee80211_sta*)(wlan_rx->u8sa_entry);
+
+ /* Check if the frame is a PS Poll frame and return BFALSE if not */
+ if(wlan_rx->u8Sub_type != PS_POLL)
+ return NMI_FALSE;
+
+
+ /* PS-Poll frames are processed only if the station is associated to AP. */
+ if((ae == 0) || (ae->state != ASOC))
+ {
+ // TODO: find a way to make hostapd send a deauth frame
+ /* Send a De-authentication Frame to the station as PS-Poll is a */
+ /* Class 3 frame. */
+ //send_deauth_frame(wlan_rx->sa, (UWORD16)CLASS3_ERR);
+
+ /* No further processing is required */
+ return NMI_TRUE;
+ }
+
+ if(ae->ps_poll_rsp_qed == NMI_TRUE)
+ {
+ /* If a frame has been queued in response to a previous PS Poll */
+ /* received, further PS Poll frames will not be honoured till the */
+ /* response frame exchange is complete (indicated by resetting this */
+ /* flag in the Tx Complete for this frame). */
+ return NMI_TRUE;
+ }
+
+ /* Requeue one buffered packet from the station's non-delivery enabled Q */
+ /* to the MAC H/w queue */
+ /* If the non-delivery enabled Q is empty queue a NULL frame */
+ /* ASSUMPTION: legacy queue should be empty if all queues are delivery */
+ /* enabled */
+ if(peek_list(&(ae->ps_q_lgcy)) == NULL)
+ tx_null_frame(wlan_rx->u8sa, ae, NMI_FALSE, 0, 0);
+ else
+ requeue_ps_packet(ae, &(ae->ps_q_lgcy), NMI_TRUE, NMI_FALSE) ;
+
+ ae->ps_poll_rsp_qed = NMI_TRUE;
+
+ return NMI_TRUE;
+}
+
+
+/*
+* @brief filter_monitor_data_frames
+* @details This function check for data frames sent by hostapd and
+* transmit it through the data path
+*
+* @author Abd Al-Rahman Diab
+* @date 05 june 2013
+* @version 1.0
+*/
+NMI_Bool filter_monitor_data_frames(NMI_Uint8 *buf, NMI_Uint16 len)
+{
+ NMI_Bool ret = NMI_FALSE;
+ struct tx_complete_data* tx_data = NULL;
+
+ if(get_type(buf)== DATA_BASICTYPE)
+ {
+ tx_data = (struct tx_complete_data*)kmalloc(sizeof(struct tx_complete_data),GFP_ATOMIC);
+
+ if(tx_data == NULL)
+ {
+ PRINT_ER("Failed to allocate memory for tx_data structure\n");
+ return ret;
+ }
+
+ tx_data->buff =buf;
+ tx_data->size = len;
+ tx_data->skb = NULL;
+ NMI_Xmit_data((void*)tx_data, MONITOR_TO_WLAN);
+
+ ret = NMI_TRUE;
+ }
+
+ return ret;
+}
+
+
+#endif
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_configurator/CoreConfigurator.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_configurator/CoreConfigurator.c
new file mode 100755
index 00000000..a7c1dab3
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_configurator/CoreConfigurator.c
@@ -0,0 +1,2330 @@
+
+/*!
+* @file CoreConfigurator.c
+* @brief
+* @author
+* @sa CoreConfigurator.h
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include "itypes.h"
+#include "CoreConfigurator.h"
+/*****************************************************************************/
+/* Constants */
+/*****************************************************************************/
+#define INLINE static __inline
+#define PHY_802_11n
+#define MAX_CFG_PKTLEN 1450
+#define MSG_HEADER_LEN 4
+#define QUERY_MSG_TYPE 'Q'
+#define WRITE_MSG_TYPE 'W'
+#define RESP_MSG_TYPE 'R'
+#define WRITE_RESP_SUCCESS 1
+#define INVALID 255
+#define MAC_ADDR_LEN 6
+#define TAG_PARAM_OFFSET MAC_HDR_LEN + TIME_STAMP_LEN + \
+ BEACON_INTERVAL_LEN + CAP_INFO_LEN
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Type Definitions */
+/*****************************************************************************/
+
+/* Basic Frame Type Codes (2-bit) */
+typedef enum {FRAME_TYPE_CONTROL = 0x04,
+ FRAME_TYPE_DATA = 0x08,
+ FRAME_TYPE_MANAGEMENT = 0x00,
+ FRAME_TYPE_RESERVED = 0x0C,
+ FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF
+} tenuBasicFrmType;
+
+/* Frame Type and Subtype Codes (6-bit) */
+typedef enum {ASSOC_REQ = 0x00,
+ ASSOC_RSP = 0x10,
+ REASSOC_REQ = 0x20,
+ REASSOC_RSP = 0x30,
+ PROBE_REQ = 0x40,
+ PROBE_RSP = 0x50,
+ BEACON = 0x80,
+ ATIM = 0x90,
+ DISASOC = 0xA0,
+ AUTH = 0xB0,
+ DEAUTH = 0xC0,
+ ACTION = 0xD0,
+ PS_POLL = 0xA4,
+ RTS = 0xB4,
+ CTS = 0xC4,
+ ACK = 0xD4,
+ CFEND = 0xE4,
+ CFEND_ACK = 0xF4,
+ DATA = 0x08,
+ DATA_ACK = 0x18,
+ DATA_POLL = 0x28,
+ DATA_POLL_ACK = 0x38,
+ NULL_FRAME = 0x48,
+ CFACK = 0x58,
+ CFPOLL = 0x68,
+ CFPOLL_ACK = 0x78,
+ QOS_DATA = 0x88,
+ QOS_DATA_ACK = 0x98,
+ QOS_DATA_POLL = 0xA8,
+ QOS_DATA_POLL_ACK = 0xB8,
+ QOS_NULL_FRAME = 0xC8,
+ QOS_CFPOLL = 0xE8,
+ QOS_CFPOLL_ACK = 0xF8,
+ BLOCKACK_REQ = 0x84,
+ BLOCKACK = 0x94,
+ FRAME_SUBTYPE_FORCE_32BIT = 0xFFFFFFFF
+} tenuFrmSubtype;
+
+/* Basic Frame Classes */
+typedef enum{CLASS1_FRAME_TYPE = 0x00,
+ CLASS2_FRAME_TYPE = 0x01,
+ CLASS3_FRAME_TYPE = 0x02,
+ FRAME_CLASS_FORCE_32BIT = 0xFFFFFFFF
+}tenuFrameClass;
+
+/* Element ID of various Information Elements */
+typedef enum {ISSID = 0, /* Service Set Identifier */
+ ISUPRATES = 1, /* Supported Rates */
+ IFHPARMS = 2, /* FH parameter set */
+ IDSPARMS = 3, /* DS parameter set */
+ ICFPARMS = 4, /* CF parameter set */
+ ITIM = 5, /* Traffic Information Map */
+ IIBPARMS = 6, /* IBSS parameter set */
+ ICOUNTRY = 7, /* Country element */
+ IEDCAPARAMS = 12, /* EDCA parameter set */
+ ITSPEC = 13, /* Traffic Specification */
+ ITCLAS = 14, /* Traffic Classification */
+ ISCHED = 15, /* Schedule */
+ ICTEXT = 16, /* Challenge Text */
+ IPOWERCONSTRAINT = 32, /* Power Constraint */
+ IPOWERCAPABILITY = 33, /* Power Capability */
+ ITPCREQUEST = 34, /* TPC Request */
+ ITPCREPORT = 35, /* TPC Report */
+ ISUPCHANNEL = 36, /* Supported channel list */
+ ICHSWANNOUNC = 37, /* Channel Switch Announcement */
+ IMEASUREMENTREQUEST = 38, /* Measurement request */
+ IMEASUREMENTREPORT = 39, /* Measurement report */
+ IQUIET = 40, /* Quiet element Info */
+ IIBSSDFS = 41, /* IBSS DFS */
+ IERPINFO = 42, /* ERP Information */
+ ITSDELAY = 43, /* TS Delay */
+ ITCLASPROCESS = 44, /* TCLAS Processing */
+ IHTCAP = 45, /* HT Capabilities */
+ IQOSCAP = 46, /* QoS Capability */
+ IRSNELEMENT = 48, /* RSN Information Element */
+ IEXSUPRATES = 50, /* Extended Supported Rates */
+ IEXCHSWANNOUNC = 60, /* Extended Ch Switch Announcement*/
+ IHTOPERATION = 61, /* HT Information */
+ ISECCHOFF = 62, /* Secondary Channel Offeset */
+ I2040COEX = 72, /* 20/40 Coexistence IE */
+ I2040INTOLCHREPORT = 73, /* 20/40 Intolerant channel report*/
+ IOBSSSCAN = 74, /* OBSS Scan parameters */
+ IEXTCAP = 127, /* Extended capability */
+ IWMM = 221, /* WMM parameters */
+ IWPAELEMENT = 221, /* WPA Information Element */
+ INFOELEM_ID_FORCE_32BIT = 0xFFFFFFFF
+} tenuInfoElemID;
+
+
+typedef struct
+{
+ NMI_Char* pcRespBuffer;
+ NMI_Sint32 s32MaxRespBuffLen;
+ NMI_Sint32 s32BytesRead;
+ NMI_Bool bRespRequired;
+} tstrConfigPktInfo;
+
+
+
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+extern NMI_Sint32 SendRawPacket(NMI_Sint8* ps8Packet, NMI_Sint32 s32PacketLen);
+extern void NetworkInfoReceived(NMI_Uint8* pu8Buffer,NMI_Uint32 u32Length);
+extern void GnrlAsyncInfoReceived(NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length);
+extern void host_int_ScanCompleteReceived(NMI_Uint8 * pu8Buffer, NMI_Uint32 u32Length);
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+static NMI_SemaphoreHandle SemHandleSendPkt;
+static NMI_SemaphoreHandle SemHandlePktResp;
+
+static NMI_Sint8* gps8ConfigPacket = NULL;
+
+static tstrConfigPktInfo gstrConfigPktInfo;
+
+static NMI_Uint8 g_seqno = 0;
+
+static NMI_Sint16 g_wid_num = -1;
+
+static NMI_Uint16 Res_Len;
+
+static NMI_Uint8 g_oper_mode = SET_CFG;
+
+/* WID Switches */
+static tstrWID gastrWIDs[] =
+{
+ {WID_FIRMWARE_VERSION, WID_STR},
+ {WID_PHY_VERSION, WID_STR},
+ {WID_HARDWARE_VERSION, WID_STR},
+ {WID_BSS_TYPE, WID_CHAR},
+ {WID_QOS_ENABLE, WID_CHAR},
+ {WID_11I_MODE, WID_CHAR},
+ {WID_CURRENT_TX_RATE, WID_CHAR},
+ {WID_LINKSPEED, WID_CHAR},
+ {WID_RTS_THRESHOLD, WID_SHORT},
+ {WID_FRAG_THRESHOLD, WID_SHORT},
+ {WID_SSID, WID_STR},
+ {WID_BSSID, WID_ADR},
+ {WID_BEACON_INTERVAL, WID_SHORT},
+ {WID_POWER_MANAGEMENT, WID_CHAR},
+ {WID_LISTEN_INTERVAL, WID_CHAR},
+ {WID_DTIM_PERIOD, WID_CHAR},
+ {WID_CURRENT_CHANNEL, WID_CHAR},
+ {WID_TX_POWER_LEVEL_11A, WID_CHAR},
+ {WID_TX_POWER_LEVEL_11B, WID_CHAR},
+ {WID_PREAMBLE, WID_CHAR},
+ {WID_11G_OPERATING_MODE, WID_CHAR},
+ {WID_MAC_ADDR, WID_ADR},
+ {WID_IP_ADDRESS, WID_ADR},
+ {WID_ACK_POLICY, WID_CHAR},
+ {WID_PHY_ACTIVE_REG, WID_CHAR},
+ {WID_AUTH_TYPE, WID_CHAR},
+ {WID_REKEY_POLICY, WID_CHAR},
+ {WID_REKEY_PERIOD, WID_INT},
+ {WID_REKEY_PACKET_COUNT, WID_INT},
+#if 0
+ {WID_WEP_KEY_VALUE0, WID_STR},
+#endif
+ {WID_11I_PSK, WID_STR},
+ {WID_1X_KEY, WID_STR},
+ {WID_1X_SERV_ADDR, WID_IP},
+ {WID_SUPP_USERNAME, WID_STR},
+ {WID_SUPP_PASSWORD, WID_STR},
+ {WID_USER_CONTROL_ON_TX_POWER, WID_CHAR},
+ {WID_MEMORY_ADDRESS, WID_INT},
+ {WID_MEMORY_ACCESS_32BIT, WID_INT},
+ {WID_MEMORY_ACCESS_16BIT, WID_SHORT},
+ {WID_MEMORY_ACCESS_8BIT, WID_CHAR},
+ {WID_SITE_SURVEY_RESULTS, WID_STR},
+ {WID_PMKID_INFO, WID_STR},
+ {WID_ASSOC_RES_INFO, WID_STR},
+ {WID_MANUFACTURER, WID_STR}, /* 4 Wids added for the CAPI tool*/
+ {WID_MODEL_NAME, WID_STR},
+ {WID_MODEL_NUM, WID_STR},
+ {WID_DEVICE_NAME, WID_STR},
+{WID_SSID_PROBE_REQ, WID_STR},
+
+#ifdef MAC_802_11N
+ {WID_11N_ENABLE, WID_CHAR},
+ {WID_11N_CURRENT_TX_MCS, WID_CHAR},
+ {WID_TX_POWER_LEVEL_11N, WID_CHAR},
+ {WID_11N_OPERATING_MODE, WID_CHAR},
+ {WID_11N_SMPS_MODE, WID_CHAR},
+ {WID_11N_PROT_MECH, WID_CHAR},
+ {WID_11N_ERP_PROT_TYPE, WID_CHAR},
+ {WID_11N_HT_PROT_TYPE, WID_CHAR},
+ {WID_11N_PHY_ACTIVE_REG_VAL, WID_INT},
+ {WID_11N_PRINT_STATS, WID_CHAR},
+ {WID_11N_AUTORATE_TABLE, WID_BIN_DATA},
+ {WID_HOST_CONFIG_IF_TYPE, WID_CHAR},
+ {WID_HOST_DATA_IF_TYPE, WID_CHAR},
+ {WID_11N_SIG_QUAL_VAL, WID_SHORT},
+ {WID_11N_IMMEDIATE_BA_ENABLED, WID_CHAR},
+ {WID_11N_TXOP_PROT_DISABLE, WID_CHAR},
+ {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR},
+ {WID_SHORT_SLOT_ALLOWED, WID_CHAR},
+ {WID_11W_ENABLE, WID_CHAR},
+ {WID_11W_MGMT_PROT_REQ, WID_CHAR},
+ {WID_2040_ENABLE, WID_CHAR},
+ {WID_2040_COEXISTENCE, WID_CHAR},
+ {WID_USER_SEC_CHANNEL_OFFSET, WID_CHAR},
+ {WID_2040_CURR_CHANNEL_OFFSET, WID_CHAR},
+ {WID_2040_40MHZ_INTOLERANT, WID_CHAR},
+ {WID_HUT_RESTART, WID_CHAR},
+ {WID_HUT_NUM_TX_PKTS, WID_INT},
+ {WID_HUT_FRAME_LEN, WID_SHORT},
+ {WID_HUT_TX_FORMAT, WID_CHAR},
+ {WID_HUT_BANDWIDTH, WID_CHAR},
+ {WID_HUT_OP_BAND, WID_CHAR},
+ {WID_HUT_STBC, WID_CHAR},
+ {WID_HUT_ESS, WID_CHAR},
+ {WID_HUT_ANTSET, WID_CHAR},
+ {WID_HUT_HT_OP_MODE, WID_CHAR},
+ {WID_HUT_RIFS_MODE, WID_CHAR},
+ {WID_HUT_SMOOTHING_REC, WID_CHAR},
+ {WID_HUT_SOUNDING_PKT, WID_CHAR},
+ {WID_HUT_HT_CODING, WID_CHAR},
+ {WID_HUT_TEST_DIR, WID_CHAR},
+ {WID_HUT_TXOP_LIMIT, WID_SHORT},
+ {WID_HUT_DEST_ADDR, WID_ADR},
+ {WID_HUT_TX_PATTERN, WID_BIN_DATA},
+ {WID_HUT_TX_TIME_TAKEN, WID_INT},
+ {WID_HUT_PHY_TEST_MODE, WID_CHAR},
+ {WID_HUT_PHY_TEST_RATE_HI, WID_CHAR},
+ {WID_HUT_PHY_TEST_RATE_LO, WID_CHAR},
+ {WID_HUT_TX_TEST_TIME, WID_INT},
+ {WID_HUT_LOG_INTERVAL, WID_INT},
+ {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR},
+ {WID_HUT_TEST_ID, WID_STR},
+ {WID_HUT_KEY_ORIGIN, WID_CHAR},
+ {WID_HUT_BCST_PERCENT, WID_CHAR},
+ {WID_HUT_GROUP_CIPHER_TYPE, WID_CHAR},
+ {WID_HUT_STATS, WID_BIN_DATA},
+ {WID_HUT_TSF_TEST_MODE, WID_CHAR},
+ {WID_HUT_SIG_QUAL_AVG, WID_SHORT},
+ {WID_HUT_SIG_QUAL_AVG_CNT, WID_SHORT},
+ {WID_HUT_TSSI_VALUE, WID_CHAR},
+ {WID_HUT_MGMT_PERCENT, WID_CHAR},
+ {WID_HUT_MGMT_BCST_PERCENT, WID_CHAR},
+ {WID_HUT_MGMT_ALLOW_HT, WID_CHAR},
+ {WID_HUT_UC_MGMT_TYPE, WID_CHAR},
+ {WID_HUT_BC_MGMT_TYPE, WID_CHAR},
+ {WID_HUT_UC_MGMT_FRAME_LEN, WID_SHORT},
+ {WID_HUT_BC_MGMT_FRAME_LEN, WID_SHORT},
+ {WID_HUT_11W_MFP_REQUIRED_TX, WID_CHAR},
+ {WID_HUT_11W_MFP_PEER_CAPABLE, WID_CHAR},
+ {WID_HUT_11W_TX_IGTK_ID, WID_CHAR},
+ {WID_HUT_FC_TXOP_MOD, WID_CHAR},
+ {WID_HUT_FC_PROT_TYPE, WID_CHAR},
+ {WID_HUT_SEC_CCA_ASSERT, WID_CHAR},
+#endif /* MAC_802_11N */
+};
+
+NMI_Uint16 g_num_total_switches = (sizeof(gastrWIDs)/sizeof(tstrWID));
+/*****************************************************************************/
+/* Static Function Declarations */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Functions */
+/*****************************************************************************/
+INLINE NMI_Uint8 ascii_hex_to_dec(NMI_Uint8 num)
+{
+ if((num >= '0') && (num <= '9'))
+ return (num - '0');
+ else if((num >= 'A') && (num <= 'F'))
+ return (10 + (num - 'A'));
+ else if((num >= 'a') && (num <= 'f'))
+ return (10 + (num - 'a'));
+
+ return INVALID;
+}
+
+INLINE NMI_Uint8 get_hex_char(NMI_Uint8 inp)
+{
+ NMI_Uint8 *d2htab = "0123456789ABCDEF";
+
+ return d2htab[inp & 0xF];
+}
+
+/* This function extracts the MAC address held in a string in standard format */
+/* into another buffer as integers. */
+INLINE NMI_Uint16 extract_mac_addr(NMI_Char *str, NMI_Uint8 *buff)
+{
+ *buff = 0;
+ while(*str != '\0')
+ {
+ if((*str == ':') || (*str == '-'))
+ *(++buff) = 0;
+ else
+ *buff = (*buff << 4) + ascii_hex_to_dec(*str);
+
+ str++;
+ }
+
+ return MAC_ADDR_LEN;
+}
+
+/* This function creates MAC address in standard format from a buffer of */
+/* integers. */
+INLINE void create_mac_addr(NMI_Uint8 *str, NMI_Uint8 *buff)
+{
+ NMI_Uint32 i = 0;
+ NMI_Uint32 j = 0;
+
+ for(i = 0; i < MAC_ADDR_LEN; i++)
+ {
+ str[j++] = get_hex_char((NMI_Uint8)((buff[i] >> 4) & 0x0F));
+ str[j++] = get_hex_char((NMI_Uint8)(buff[i] & 0x0F));
+ str[j++] = ':';
+ }
+ str[--j] = '\0';
+}
+
+/* This function converts the IP address string in dotted decimal format to */
+/* unsigned integer. This functionality is similar to the library function */
+/* inet_addr() but is reimplemented here since I could not confirm that */
+/* inet_addr is platform independent. */
+/* ips=>IP Address String in dotted decimal format */
+/* ipn=>Pointer to IP Address in integer format */
+INLINE NMI_Uint8 conv_ip_to_int(NMI_Uint8 *ips, NMI_Uint32 *ipn)
+{
+ NMI_Uint8 i = 0;
+ NMI_Uint8 ipb = 0;
+ *ipn = 0;
+ /* Integer to string for each component */
+ while(ips[i] != '\0')
+ {
+ if(ips[i] == '.')
+ {
+ *ipn = ((*ipn) << 8) | ipb;
+ ipb = 0;
+ }
+ else
+ {
+ ipb = ipb * 10 + ascii_hex_to_dec(ips[i]);
+ }
+
+ i++;
+ }
+
+ /* The last byte of the IP address is read in here */
+ *ipn = ((*ipn) << 8) | ipb;
+
+ return 0;
+}
+
+/* This function converts the IP address from integer format to dotted */
+/* decimal string format. Alternative to std library fn inet_ntoa(). */
+/* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B) */
+/* ipn=>IP Address in integer format */
+INLINE NMI_Uint8 conv_int_to_ip(NMI_Uint8 *ips, NMI_Uint32 ipn)
+{
+ NMI_Uint8 i = 0;
+ NMI_Uint8 ipb = 0;
+ NMI_Uint8 cnt = 0;
+ NMI_Uint8 ipbsize = 0;
+
+ for(cnt = 4; cnt > 0; cnt--)
+ {
+ ipb = (ipn >> (8*(cnt-1)))& 0xFF;
+
+ if(ipb >= 100)
+ ipbsize = 2;
+ else if(ipb >= 10)
+ ipbsize = 1;
+ else
+ ipbsize = 0;
+
+ switch(ipbsize)
+ {
+ case 2:
+ ips[i++] = get_hex_char(ipb/100);
+ ipb %= 100;
+ case 1:
+ ips[i++] = get_hex_char(ipb/10);
+ ipb %= 10;
+ default:
+ ips[i++] = get_hex_char(ipb);
+ }
+
+ if(cnt > 1)
+ ips[i++] = '.';
+ }
+
+ ips[i] = '\0';
+
+ return i;
+}
+
+INLINE tenuWIDtype get_wid_type(NMI_Uint32 wid_num)
+{
+ /* Check for iconfig specific WID types first */
+ if((wid_num == WID_BSSID) ||
+ (wid_num == WID_MAC_ADDR) ||
+ (wid_num == WID_IP_ADDRESS) ||
+ (wid_num == WID_HUT_DEST_ADDR))
+ {
+ return WID_ADR;
+ }
+
+ if((WID_1X_SERV_ADDR == wid_num) ||
+ (WID_STACK_IP_ADDR == wid_num) ||
+ (WID_STACK_NETMASK_ADDR == wid_num))
+ {
+ return WID_IP;
+ }
+
+ /* Next check for standard WID types */
+ if(wid_num < 0x1000)
+ return WID_CHAR;
+ else if(wid_num < 0x2000)
+ return WID_SHORT;
+ else if(wid_num < 0x3000)
+ return WID_INT;
+ else if(wid_num < 0x4000)
+ return WID_STR;
+ else if(wid_num < 0x5000)
+ return WID_BIN_DATA;
+
+ return WID_UNDEF;
+}
+
+
+/* This function extracts the beacon period field from the beacon or probe */
+/* response frame. */
+INLINE NMI_Uint16 get_beacon_period(NMI_Uint8* data)
+{
+ NMI_Uint16 bcn_per = 0;
+
+ bcn_per = data[0];
+ bcn_per |= (data[1] << 8) ;
+
+ return bcn_per;
+}
+
+INLINE NMI_Uint32 get_beacon_timestamp_lo(NMI_Uint8* data)
+{
+ NMI_Uint32 time_stamp = 0;
+ NMI_Uint32 index = MAC_HDR_LEN;
+
+ time_stamp |= data[index++];
+ time_stamp |= (data[index++] << 8);
+ time_stamp |= (data[index++] << 16);
+ time_stamp |= (data[index] << 24);
+
+ return time_stamp;
+}
+
+INLINE UWORD32 get_beacon_timestamp_hi(UWORD8* data)
+{
+ UWORD32 time_stamp = 0;
+ UWORD32 index = (MAC_HDR_LEN + 4);
+
+ time_stamp |= data[index++];
+ time_stamp |= (data[index++] << 8);
+ time_stamp |= (data[index++] << 16);
+ time_stamp |= (data[index] << 24);
+
+ return time_stamp;
+}
+
+/* This function extracts the 'frame type' bits from the MAC header of the */
+/* input frame. */
+/* Returns the value in the LSB of the returned value. */
+INLINE tenuBasicFrmType get_type(NMI_Uint8* header)
+{
+ return ((tenuBasicFrmType)(header[0] & 0x0C));
+}
+
+/* This function extracts the 'frame type and sub type' bits from the MAC */
+/* header of the input frame. */
+/* Returns the value in the LSB of the returned value. */
+INLINE tenuFrmSubtype get_sub_type(NMI_Uint8* header)
+{
+ return ((tenuFrmSubtype)(header[0] & 0xFC));
+}
+
+/* This function extracts the 'to ds' bit from the MAC header of the input */
+/* frame. */
+/* Returns the value in the LSB of the returned value. */
+INLINE NMI_Uint8 get_to_ds(NMI_Uint8* header)
+{
+ return (header[1] & 0x01);
+}
+
+/* This function extracts the 'from ds' bit from the MAC header of the input */
+/* frame. */
+/* Returns the value in the LSB of the returned value. */
+INLINE NMI_Uint8 get_from_ds(NMI_Uint8* header)
+{
+ return ((header[1] & 0x02) >> 1);
+}
+
+/* This function extracts the MAC Address in 'address1' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+INLINE void get_address1(NMI_Uint8* pu8msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, pu8msa + 4, 6);
+}
+
+/* This function extracts the MAC Address in 'address2' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+INLINE void get_address2(NMI_Uint8* pu8msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, pu8msa + 10, 6);
+}
+
+/* This function extracts the MAC Address in 'address3' field of the MAC */
+/* header and updates the MAC Address in the allocated 'addr' variable. */
+INLINE void get_address3(NMI_Uint8* pu8msa, NMI_Uint8* addr)
+{
+ NMI_memcpy(addr, pu8msa + 16, 6);
+}
+
+/* This function extracts the BSSID from the incoming WLAN packet based on */
+/* the 'from ds' bit, and updates the MAC Address in the allocated 'addr' */
+/* variable. */
+INLINE void get_BSSID(NMI_Uint8* data, NMI_Uint8* bssid)
+{
+ if(get_from_ds(data) == 1)
+ get_address2(data, bssid);
+ else if(get_to_ds(data) == 1)
+ get_address1(data, bssid);
+ else
+ get_address3(data, bssid);
+}
+
+/* This function extracts the SSID from a beacon/probe response frame */
+INLINE void get_ssid(NMI_Uint8* data, NMI_Uint8* ssid, NMI_Uint8* p_ssid_len)
+{
+ NMI_Uint8 len = 0;
+ NMI_Uint8 i = 0;
+ NMI_Uint8 j = 0;
+
+ len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
+ CAP_INFO_LEN + 1];
+ j = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
+ CAP_INFO_LEN + 2;
+
+ /* If the SSID length field is set wrongly to a value greater than the */
+ /* allowed maximum SSID length limit, reset the length to 0 */
+ if(len >= MAX_SSID_LEN)
+ len = 0;
+
+ for(i = 0; i < len; i++, j++)
+ ssid[i] = data[j];
+
+ ssid[len] = '\0';
+
+ *p_ssid_len = len;
+}
+
+/* This function extracts the capability info field from the beacon or probe */
+/* response frame. */
+INLINE NMI_Uint16 get_cap_info(NMI_Uint8* data)
+{
+ NMI_Uint16 cap_info = 0;
+ NMI_Uint16 index = MAC_HDR_LEN;
+ tenuFrmSubtype st = BEACON;
+
+ st = get_sub_type(data);
+
+ /* Location of the Capability field is different for Beacon and */
+ /* Association frames. */
+ if((st == BEACON) || (st == PROBE_RSP))
+ index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN;
+
+ cap_info = data[index];
+ cap_info |= (data[index + 1] << 8);
+
+ return cap_info;
+}
+
+/* This function extracts the capability info field from the Association */
+/* response frame. */
+INLINE NMI_Uint16 get_assoc_resp_cap_info(NMI_Uint8* data)
+{
+ NMI_Uint16 cap_info = 0;
+
+ cap_info = data[0];
+ cap_info |= (data[1] << 8);
+
+ return cap_info;
+}
+
+/* This funcion extracts the association status code from the incoming */
+/* association response frame and returns association status code */
+INLINE NMI_Uint16 get_asoc_status(NMI_Uint8* data)
+{
+ NMI_Uint16 asoc_status = 0;
+
+ asoc_status = data[3];
+ asoc_status = (asoc_status << 8) | data[2];
+
+ return asoc_status;
+}
+
+/* This function extracts association ID from the incoming association */
+/* response frame */
+INLINE NMI_Uint16 get_asoc_id(NMI_Uint8* data)
+{
+ NMI_Uint16 asoc_id = 0;
+
+ asoc_id = data[4];
+ asoc_id |= (data[5] << 8) ;
+
+ return asoc_id;
+}
+
+/**
+* @brief initializes the Core Configurator
+* @details
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 CoreConfiguratorInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_SemaphoreAttrs strSemSendPktAttrs;
+ tstrNMI_SemaphoreAttrs strSemPktRespAttrs;
+
+ PRINT_D(CORECONFIG_DBG,"CoreConfiguratorInit() \n");
+
+ NMI_SemaphoreFillDefault(&strSemSendPktAttrs);
+ strSemSendPktAttrs.u32InitCount = 1;
+ NMI_SemaphoreCreate(&SemHandleSendPkt, &strSemSendPktAttrs);
+
+ NMI_SemaphoreFillDefault(&strSemPktRespAttrs);
+ strSemPktRespAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&SemHandlePktResp, &strSemPktRespAttrs);
+
+ gps8ConfigPacket = (NMI_Sint8*)NMI_MALLOC(MAX_PACKET_BUFF_SIZE);
+ if(gps8ConfigPacket == NULL)
+ {
+ NMI_ERROR("failed in gps8ConfigPacket allocation \n");
+ s32Error = NMI_NO_MEM;
+ goto _fail_;
+ }
+
+ NMI_memset((void*)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE);
+
+ NMI_memset((void*)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
+ _fail_:
+ return s32Error;
+}
+
+NMI_Uint8* get_tim_elm(NMI_Uint8* pu8msa, NMI_Uint16 u16RxLen, NMI_Uint16 u16TagParamOffset)
+{
+ NMI_Uint16 u16index = 0;
+
+ /*************************************************************************/
+ /* Beacon Frame - Frame Body */
+ /* --------------------------------------------------------------------- */
+ /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm | */
+ /* --------------------------------------------------------------------- */
+ /* |8 |2 |2 |2-34 |3-10 |3 |4-256 | */
+ /* --------------------------------------------------------------------- */
+ /* */
+ /*************************************************************************/
+
+ u16index = u16TagParamOffset;
+
+ /* Search for the TIM Element Field and return if the element is found */
+ while(u16index < (u16RxLen - FCS_LEN))
+ {
+ if(pu8msa[u16index] == ITIM)
+ {
+ return(&pu8msa[u16index]);
+ }
+ else
+ {
+ u16index += (IE_HDR_LEN + pu8msa[u16index + 1]);
+ }
+ }
+
+ return(0);
+}
+
+/* This function gets the current channel information from
+ the 802.11n beacon/probe response frame */
+NMI_Uint8 get_current_channel_802_11n(NMI_Uint8 *pu8msa,NMI_Uint16 u16RxLen)
+{
+ NMI_Uint16 index;
+
+ index = TAG_PARAM_OFFSET;
+ while(index < (u16RxLen - FCS_LEN))
+ {
+ if(pu8msa[index] == IDSPARMS)
+ return (pu8msa[index + 2]);
+ else
+ /* Increment index by length information and header */
+ index += pu8msa[index + 1] + IE_HDR_LEN;
+ }
+
+ /* Return current channel information from the MIB, if beacon/probe */
+ /* response frame does not contain the DS parameter set IE */
+ //return (mget_CurrentChannel() + 1);
+ return 0; /* no MIB here */
+}
+
+NMI_Uint8 get_current_channel(NMI_Uint8 *pu8msa, NMI_Uint16 u16RxLen)
+{
+#ifdef PHY_802_11n
+#ifdef FIVE_GHZ_BAND
+ /* Get the current channel as its not set in */
+ /* 802.11a beacons/probe response */
+ return (get_rf_channel() + 1);
+#else /* FIVE_GHZ_BAND */
+ /* Extract current channel information from */
+ /* the beacon/probe response frame */
+ return (get_current_channel_802_11n(pu8msa, u16RxLen));
+#endif /* FIVE_GHZ_BAND */
+#else
+ return 0;
+#endif /* PHY_802_11n */
+}
+
+/**
+* @brief parses the received 'N' message
+* @details
+* @param[in] pu8MsgBuffer The message to be parsed
+* @param[out] ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+NMI_Sint32 ParseNetworkInfo(NMI_Uint8* pu8MsgBuffer, tstrNetworkInfo** ppstrNetworkInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNetworkInfo* pstrNetworkInfo = NMI_NULL;
+ NMI_Uint8 u8MsgType = 0;
+ NMI_Uint8 u8MsgID = 0;
+ NMI_Uint16 u16MsgLen = 0;
+
+ NMI_Uint16 u16WidID = (NMI_Uint16)WID_NIL;
+ NMI_Uint16 u16WidLen = 0;
+ NMI_Uint8 *pu8WidVal = 0;
+
+ u8MsgType = pu8MsgBuffer[0];
+
+ /* Check whether the received message type is 'N' */
+ if('N' != u8MsgType)
+ {
+ NMI_ERROR("Received Message format incorrect.\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ /* Extract message ID */
+ u8MsgID = pu8MsgBuffer[1];
+
+ /* Extract message Length */
+ u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]);
+
+ /* Extract WID ID */
+ u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]);
+
+ /* Extract WID Length */
+ u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]);
+
+ /* Assign a pointer to the WID value */
+ pu8WidVal = &pu8MsgBuffer[8];
+
+ /* parse the WID value of the WID "WID_NEWORK_INFO" */
+ {
+ NMI_Uint8 *pu8msa = 0;
+ NMI_Uint16 u16RxLen = 0;
+ NMI_Uint8 *pu8TimElm = 0;
+ NMI_Uint8 *pu8IEs = 0;
+ NMI_Uint16 u16IEsLen = 0;
+ NMI_Uint8 u8index = 0;
+ NMI_Uint32 u32Tsf_Lo;
+ NMI_Uint32 u32Tsf_Hi;
+
+ pstrNetworkInfo = (tstrNetworkInfo*)NMI_MALLOC(sizeof(tstrNetworkInfo));
+ NMI_memset((void*)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo));
+
+ pstrNetworkInfo->s8rssi = pu8WidVal[0];
+
+ /* Assign a pointer to msa "Mac Header Start Address" */
+ pu8msa = &pu8WidVal[1];
+
+ u16RxLen = u16WidLen - 1;
+
+ /* parse msa*/
+
+ /* Get the cap_info */
+ pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa);
+ #ifdef NMI_P2P
+ /* Get time-stamp [Low only 32 bit] */
+ pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa);
+ PRINT_D(CORECONFIG_DBG,"TSF :%x\n",pstrNetworkInfo->u32Tsf );
+ #endif
+
+ /* Get full time-stamp [Low and High 64 bit] */
+ u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa);
+ u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa);
+
+ pstrNetworkInfo->u64Tsf = u32Tsf_Lo | (u32Tsf_Hi << 32);
+
+ /* Get SSID */
+ get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen));
+
+ /* Get BSSID */
+ get_BSSID(pu8msa, pstrNetworkInfo->au8bssid);
+
+ /* Get the current channel */
+ pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN));
+
+ /* Get beacon period */
+ u8index = (MAC_HDR_LEN + TIME_STAMP_LEN);
+
+ pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index);
+
+ u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN;
+
+ /* Get DTIM Period */
+ pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index);
+ if(pu8TimElm != 0)
+ {
+ pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3];
+ }
+ pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN];
+ u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN);
+
+ if(u16IEsLen > 0)
+ {
+ pstrNetworkInfo->pu8IEs = (NMI_Uint8*)NMI_MALLOC(u16IEsLen);
+ NMI_memset((void*)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen);
+
+ NMI_memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen);
+ }
+ pstrNetworkInfo->u16IEsLen = u16IEsLen;
+
+ }
+
+ *ppstrNetworkInfo = pstrNetworkInfo;
+
+ERRORHANDLER:
+ return s32Error;
+}
+
+/**
+* @brief Deallocates the parsed Network Info
+* @details
+* @param[in] pstrNetworkInfo Network Info to be deallocated
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+NMI_Sint32 DeallocateNetworkInfo(tstrNetworkInfo* pstrNetworkInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ if(pstrNetworkInfo != NMI_NULL)
+ {
+ if(pstrNetworkInfo->pu8IEs != NMI_NULL)
+ {
+ NMI_FREE(pstrNetworkInfo->pu8IEs);
+ pstrNetworkInfo->pu8IEs = NMI_NULL;
+ }
+ else
+ {
+ s32Error = NMI_FAIL;
+ }
+
+ NMI_FREE(pstrNetworkInfo);
+ pstrNetworkInfo = NMI_NULL;
+
+ }
+ else
+ {
+ s32Error = NMI_FAIL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief parses the received Association Response frame
+* @details
+* @param[in] pu8Buffer The Association Response frame to be parsed
+* @param[out] ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 2 Apr 2012
+* @version 1.0
+*/
+NMI_Sint32 ParseAssocRespInfo(NMI_Uint8* pu8Buffer, NMI_Uint32 u32BufferLen,
+ tstrConnectRespInfo** ppstrConnectRespInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrConnectRespInfo* pstrConnectRespInfo = NMI_NULL;
+ NMI_Uint16 u16AssocRespLen = 0;
+ NMI_Uint8 *pu8IEs = 0;
+ NMI_Uint16 u16IEsLen = 0;
+
+ pstrConnectRespInfo = (tstrConnectRespInfo*)NMI_MALLOC(sizeof(tstrConnectRespInfo));
+ NMI_memset((void*)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo));
+
+ //u16AssocRespLen = pu8Buffer[0];
+ u16AssocRespLen = (NMI_Uint16)u32BufferLen;
+
+ /* get the status code */
+ pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer);
+ if(pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)
+ {
+
+ /* get the capability */
+ pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer);
+
+ /* get the Association ID */
+ pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer);
+
+ /* get the Information Elements */
+ pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN];
+ u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN);
+
+ pstrConnectRespInfo->pu8RespIEs = (NMI_Uint8*)NMI_MALLOC(u16IEsLen);
+ NMI_memset((void*)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen);
+
+ NMI_memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen);
+ pstrConnectRespInfo->u16RespIEsLen = u16IEsLen;
+ }
+
+ *ppstrConnectRespInfo = pstrConnectRespInfo;
+
+
+ return s32Error;
+}
+
+/**
+* @brief Deallocates the parsed Association Response Info
+* @details
+* @param[in] pstrNetworkInfo Network Info to be deallocated
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 2 Apr 2012
+* @version 1.0
+*/
+NMI_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo* pstrConnectRespInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ if(pstrConnectRespInfo != NMI_NULL)
+ {
+ if(pstrConnectRespInfo->pu8RespIEs != NMI_NULL)
+ {
+ NMI_FREE(pstrConnectRespInfo->pu8RespIEs);
+ pstrConnectRespInfo->pu8RespIEs = NMI_NULL;
+ }
+ else
+ {
+ s32Error = NMI_FAIL;
+ }
+
+ NMI_FREE(pstrConnectRespInfo);
+ pstrConnectRespInfo = NMI_NULL;
+
+ }
+ else
+ {
+ s32Error = NMI_FAIL;
+ }
+
+ return s32Error;
+}
+
+#ifndef CONNECT_DIRECT
+NMI_Sint32 ParseSurveyResults(NMI_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
+ wid_site_survey_reslts_s** ppstrSurveyResults,
+ NMI_Uint32* pu32SurveyResultsCount)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ wid_site_survey_reslts_s* pstrSurveyResults = NULL;
+ NMI_Uint32 u32SurveyResultsCount = 0;
+ NMI_Uint32 u32SurveyBytesLength = 0;
+ NMI_Uint8* pu8BufferPtr;
+ NMI_Uint32 u32RcvdSurveyResultsNum = 2;
+ NMI_Uint8 u8ReadSurveyResFragNum;
+ NMI_Uint32 i;
+ NMI_Uint32 j;
+
+ for(i = 0; i < u32RcvdSurveyResultsNum; i++)
+ {
+ u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0];
+
+
+ for(j = 0; j < u32SurveyBytesLength; j+= SURVEY_RESULT_LENGTH)
+ {
+ u32SurveyResultsCount++;
+ }
+ }
+
+ //NMI_PRINTF("u32SurveyResultsCount = %d \n", u32SurveyResultsCount);
+
+ pstrSurveyResults = (wid_site_survey_reslts_s*)NMI_MALLOC(u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s));
+ if(pstrSurveyResults == NULL)
+ {
+ u32SurveyResultsCount = 0;
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ NMI_memset((void*)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s));
+
+ u32SurveyResultsCount = 0;
+
+ for(i = 0; i < u32RcvdSurveyResultsNum; i++)
+ {
+ pu8BufferPtr = ppu8RcvdSiteSurveyResults[i];
+
+ u32SurveyBytesLength = pu8BufferPtr[0];
+
+ //TODO: mostafa: pu8BufferPtr[1] contains the fragment num
+ u8ReadSurveyResFragNum = pu8BufferPtr[1];
+
+ //NMI_PRINTF("Read fragment num value in Survey Result Fragmnet %d = %d \n", i, u8ReadSurveyResFragNum);
+
+ pu8BufferPtr += 2;
+
+ for(j = 0; j < u32SurveyBytesLength; j+= SURVEY_RESULT_LENGTH)
+ {
+ NMI_memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH);
+ pu8BufferPtr += SURVEY_RESULT_LENGTH;
+ u32SurveyResultsCount++;
+ }
+ }
+
+ERRORHANDLER:
+ *ppstrSurveyResults = pstrSurveyResults;
+ *pu32SurveyResultsCount = u32SurveyResultsCount;
+
+ return s32Error;
+}
+
+
+NMI_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s* pstrSurveyResults)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ if(pstrSurveyResults != NMI_NULL)
+ {
+ NMI_FREE(pstrSurveyResults);
+ }
+
+ return s32Error;
+}
+#endif
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessCharWid */
+/* */
+/* Description : This function processes a WID of type WID_CHAR and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessCharWid(NMI_Char* pcPacket, NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Sint8* ps8WidVal)
+{
+ NMI_Uint8* pu8val = (NMI_Uint8*)ps8WidVal;
+ NMI_Uint8 u8val = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set CHAR val 0x%x ,NULL structure\n",u8val);
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid >> 8) & 0xFF;
+ if(g_oper_mode == SET_CFG)
+ {
+ u8val = *pu8val;
+
+ /* Length */
+ pcPacket[s32PktLen++] = sizeof(NMI_Uint8);
+
+
+ /* Value */
+ pcPacket[s32PktLen++] = u8val;
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessShortWid */
+/* */
+/* Description : This function processes a WID of type WID_SHORT and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessShortWid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Sint8* ps8WidVal)
+{
+ NMI_Uint16* pu16val = (NMI_Uint16*)ps8WidVal;
+ NMI_Uint16 u16val = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set SHORT val 0x%x ,NULL structure\n",u16val);
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ u16val = *pu16val;
+
+ /* Length */
+ pcPacket[s32PktLen++] = sizeof(NMI_Uint16);
+
+ /* Value */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(u16val & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u16val >> 8) & 0xFF);
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessIntWid */
+/* */
+/* Description : This function processes a WID of type WID_INT and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessIntWid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Sint8* ps8WidVal)
+{
+ NMI_Uint32* pu32val = (NMI_Uint32*)ps8WidVal;
+ NMI_Uint32 u32val = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set INT val 0x%x , NULL structure\n",u32val);
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ u32val = *pu32val;
+
+ /* Length */
+ pcPacket[s32PktLen++] = sizeof(NMI_Uint32);
+
+ /* Value */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(u32val & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 8) & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 16) & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 24) & 0xFF);
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessIPwid */
+/* */
+/* Description : This function processes a WID of type WID_IP and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessIPwid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Uint8 *pu8ip)
+{
+ NMI_Uint32 u32val = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set IP Addr , NULL structure\n");
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ /* Length */
+ pcPacket[s32PktLen++] = sizeof(NMI_Uint32);
+
+ /* Convert the IP Address String to Integer */
+ conv_ip_to_int(pu8ip, &u32val);
+
+ /* Value */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(u32val & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 8) & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 16) & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u32val >> 24) & 0xFF);
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessStrWid */
+/* */
+/* Description : This function processes a WID of type WID_STR and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessStrWid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Uint8 *pu8val, NMI_Sint32 s32ValueSize)
+{
+ NMI_Uint16 u16MsgLen = 0;
+ NMI_Uint16 idx = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set STR val, NULL structure\n");
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ /* Message Length */
+ //u16MsgLen = NMI_strlen(pu8val);
+ u16MsgLen = (NMI_Uint16)s32ValueSize;
+
+ /* Length */
+ pcPacket[s32PktLen++] = (NMI_Uint8)u16MsgLen;
+
+ /* Value */
+ for(idx = 0; idx < u16MsgLen; idx++)
+ pcPacket[s32PktLen++] = pu8val[idx];
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessAdrWid */
+/* */
+/* Description : This function processes a WID of type WID_ADR and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Value to set */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessAdrWid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Uint8 *pu8val)
+{
+ NMI_Uint16 u16MsgLen = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set Addr WID, NULL structure\n");
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ /* Message Length */
+ u16MsgLen = MAC_ADDR_LEN;
+
+ /* Length */
+ pcPacket[s32PktLen++] = (NMI_Uint8)u16MsgLen;
+
+ /* Value */
+ extract_mac_addr(pu8val, pcPacket + s32PktLen);
+ s32PktLen += u16MsgLen;
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ProcessBinWid */
+/* */
+/* Description : This function processes a WID of type WID_BIN_DATA and */
+/* updates the cfg packet with the supplied value. */
+/* */
+/* Inputs : 1) Pointer to WID cfg structure */
+/* 2) Name of file containing the binary data in text mode */
+/* */
+/* Globals : */
+/* */
+/* Processing : The binary data is expected to be supplied through a */
+/* file in text mode. This file is expected to be in the */
+/* finject format. It is parsed, converted to binary format */
+/* and copied into g_cfg_pkt for further processing. This */
+/* is obviously a round-about way of processing involving */
+/* multiple (re)conversions between bin & ascii formats. */
+/* But it is done nevertheless to retain uniformity and for */
+/* ease of debugging. */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void ProcessBinWid(NMI_Char* pcPacket,NMI_Sint32* ps32PktLen,
+ tstrWID *pstrWID, NMI_Uint8 *pu8val, NMI_Sint32 s32ValueSize)
+{
+ //NMI_ERROR("processing Binary WIDs is not supported \n");
+
+ NMI_Uint16 u16MsgLen = 0;
+ NMI_Uint16 idx = 0;
+ NMI_Sint32 s32PktLen = *ps32PktLen;
+ NMI_Uint8 u8checksum = 0;
+
+ if(pstrWID == NULL)
+ {
+ PRINT_WRN(CORECONFIG_DBG,"Can't set BIN val, NULL structure\n");
+ return;
+ }
+
+ /* WID */
+ pcPacket[s32PktLen++] = (NMI_Uint8)(pstrWID->u16WIDid & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((pstrWID->u16WIDid >> 8) & 0xFF);
+
+ if(g_oper_mode == SET_CFG)
+ {
+ /* Message Length */
+ u16MsgLen = (NMI_Uint16)s32ValueSize;
+
+ /* Length */
+ //pcPacket[s32PktLen++] = (NMI_Uint8)u16MsgLen;
+ pcPacket[s32PktLen++] = (NMI_Uint8)(u16MsgLen & 0xFF);
+ pcPacket[s32PktLen++] = (NMI_Uint8)((u16MsgLen >> 8) & 0xFF);
+
+ /* Value */
+ for(idx = 0; idx < u16MsgLen; idx++)
+ {
+ pcPacket[s32PktLen++] = pu8val[idx];
+ }
+
+ /* checksum */
+ for (idx = 0; idx < u16MsgLen; idx++)
+ {
+ u8checksum += pcPacket[MSG_HEADER_LEN+idx+4];
+ }
+ pcPacket[s32PktLen++] = u8checksum;
+ }
+ *ps32PktLen = s32PktLen;
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : further_process_response */
+/* */
+/* Description : This function parses the response frame got from the */
+/* device. */
+/* */
+/* Inputs : 1) The received response frame */
+/* 2) WID */
+/* 3) WID Length */
+/* 4) Output file handle */
+/* 5) Process Wid Number(i.e wid from --widn switch) */
+/* 6) Index the array in the Global Wid Structure. */
+/* */
+/* Globals : g_wid_num, gastrWIDs */
+/* */
+/* Processing : This function parses the response of the device depending*/
+/* WID type and writes it to the output file in Hex or */
+/* decimal notation depending on the --getx or --get switch.*/
+/* */
+/* Outputs : None */
+/* */
+/* Returns : 0 on Success & -2 on Failure */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2009 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+NMI_Sint32 further_process_response(NMI_Uint8* resp,
+ NMI_Uint16 u16WIDid,
+ NMI_Uint16 cfg_len,
+ NMI_Bool process_wid_num,
+ NMI_Uint32 cnt,
+ tstrWID* pstrWIDresult)
+{
+ NMI_Uint32 retval = 0;
+ NMI_Uint32 idx = 0;
+ NMI_Uint8 cfg_chr = 0;
+ NMI_Uint16 cfg_sht = 0;
+ NMI_Uint32 cfg_int = 0;
+ NMI_Uint8 cfg_str[256] = {0};
+ tenuWIDtype enuWIDtype = WID_UNDEF;
+
+ if(process_wid_num)
+ {
+ enuWIDtype = get_wid_type(g_wid_num);
+ }
+ else
+ {
+ enuWIDtype = gastrWIDs[cnt].enuWIDtype;
+ }
+
+
+ switch(enuWIDtype)
+ {
+ case WID_CHAR:
+ {
+ cfg_chr = resp[idx];
+ /*Set local copy of WID*/
+ *(pstrWIDresult->ps8WidVal) = cfg_chr;
+ break;
+ }
+ case WID_SHORT:
+ {
+ NMI_Uint16* pu16val = (NMI_Uint16*)(pstrWIDresult->ps8WidVal);
+ cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]);
+ /*Set local copy of WID*/
+ //pstrWIDresult->ps8WidVal = (NMI_Sint8*)(NMI_Sint32)cfg_sht;
+ *pu16val = cfg_sht;
+ break;
+ }
+
+ case WID_INT:
+ {
+ NMI_Uint32* pu32val = (NMI_Uint32*)(pstrWIDresult->ps8WidVal);
+ cfg_int = MAKE_WORD32(
+ MAKE_WORD16(resp[idx], resp[idx + 1]),
+ MAKE_WORD16(resp[idx + 2], resp[idx + 3])
+ );
+ /*Set local copy of WID*/
+ //pstrWIDresult->ps8WidVal = (NMI_Sint8*)cfg_int;
+ *pu32val = cfg_int;
+ break;
+ }
+ case WID_STR:
+ {
+ NMI_memcpy(cfg_str, resp + idx, cfg_len);
+ //cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination
+ if(process_wid_num)
+ {
+ /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num,
+ cfg_str);*/
+ }
+ else
+ {
+ /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch,
+ cfg_str);*/
+ }
+
+ if(pstrWIDresult->s32ValueSize >= cfg_len)
+ {
+ NMI_memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); //mostafa: no need currently for the extra NULL byte
+ pstrWIDresult->s32ValueSize = cfg_len;
+ }
+ else
+ {
+ NMI_ERROR("allocated WID buffer length is smaller than the received WID Length \n");
+ retval = -2;
+ }
+
+ break;
+ }
+
+ case WID_ADR:
+ create_mac_addr(cfg_str, resp + idx);
+
+ NMI_strncpy(pstrWIDresult->ps8WidVal,cfg_str,NMI_strlen(cfg_str));
+ pstrWIDresult->ps8WidVal[NMI_strlen(cfg_str)] = '\0';
+ if(process_wid_num)
+ {
+ /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num,
+ cfg_str);*/
+ }
+ else
+ {
+ /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch,
+ cfg_str);*/
+ }
+ break;
+
+ case WID_IP:
+ cfg_int = MAKE_WORD32(
+ MAKE_WORD16(resp[idx], resp[idx + 1]),
+ MAKE_WORD16(resp[idx + 2], resp[idx + 3])
+ );
+ conv_int_to_ip(cfg_str, cfg_int);
+ if(process_wid_num)
+ {
+ /*fprintf(out_file,"0x%4.4x = %s\n",g_wid_num,
+ cfg_str);*/
+ }
+ else
+ {
+ /*fprintf(out_file,"%s = %s\n",gastrWIDs[cnt].cfg_switch,
+ cfg_str);*/
+ }
+ break;
+ case WID_BIN_DATA:
+ {
+ #if 0
+ //FILE *fp_bin = NULL;
+ NMI_Uint8 first_bin_wid = 1;
+ if(first_bin_wid)
+ {
+ //fp_bin = fopen("wid_response.bin","wb");
+ first_bin_wid = 0;
+ }
+ else
+ {
+ //fp_bin = fopen("wid_response.bin","ab");
+ }
+
+ if(/*fp_bin == NULL*/0)
+ {
+ NMI_PRINTF("Error: Could not open wid_response.bin for write\n");
+ return -2;
+ }
+
+ //fwrite(resp + idx, cfg_len, 1, fp_bin);
+
+ //fclose(fp_bin);
+ #endif
+
+ if(pstrWIDresult->s32ValueSize >= cfg_len)
+ {
+ NMI_memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len);
+ pstrWIDresult->s32ValueSize = cfg_len;
+ }
+ else
+ {
+ PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n",retval);
+ retval = -2;
+ }
+ }
+ break;
+ default:
+ PRINT_ER("ERROR: Check config database: Error(%d)\n",retval);
+ retval = -2;
+ }
+
+ return retval;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ParseResponse */
+/* */
+/* Description : This function parses the command-line options and */
+/* creates the config packets which can be sent to the WLAN */
+/* station. */
+/* */
+/* Inputs : 1) The received response frame */
+/* */
+/* Globals : g_opt_list, gastrWIDs */
+/* */
+/* Processing : This function parses the options and creates different */
+/* types of packets depending upon the WID-type */
+/* corresponding to the option. */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : 0 on Success & -1 on Failure */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 01 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+NMI_Sint32 ParseResponse(NMI_Uint8 *resp,tstrWID* pstrWIDcfgResult)
+{
+ NMI_Uint16 u16RespLen = 0;
+ NMI_Uint16 u16WIDid = 0;
+ NMI_Uint16 cfg_len = 0;
+ tenuWIDtype enuWIDtype = WID_UNDEF;
+ NMI_Bool num_wid_processed = NMI_FALSE;
+ NMI_Uint32 cnt = 0;
+ NMI_Uint32 idx = 0;
+ NMI_Uint32 ResCnt = 0;
+ /* Check whether the received frame is a valid response */
+ if(RESP_MSG_TYPE != resp[0])
+ {
+ PRINT_INFO(CORECONFIG_DBG,"Received Message format incorrect.\n");
+ return -1;
+ }
+
+ /* Extract Response Length */
+ u16RespLen = MAKE_WORD16(resp[2], resp[3]);
+ Res_Len = u16RespLen;
+
+ for(idx = MSG_HEADER_LEN; idx < u16RespLen; )
+ {
+ u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]);
+ cfg_len = resp[idx + 2];
+ /* Incase of Bin Type Wid, the length is given by two byte field */
+ if(WID_BIN_DATA == (enuWIDtype = get_wid_type(u16WIDid)))
+ {
+ cfg_len |= ((NMI_Uint16)resp[idx + 3] << 8) & 0xFF00 ;
+ idx++;
+ }
+ idx += 3;
+ if((u16WIDid == g_wid_num) && (num_wid_processed == NMI_FALSE))
+ {
+ num_wid_processed = NMI_TRUE;
+
+ if(-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, NMI_TRUE , 0 ,&pstrWIDcfgResult[ResCnt]))
+ {
+ return -2;
+ }
+ ResCnt++;
+ }
+ else
+ {
+ for(cnt = 0; cnt < g_num_total_switches ; cnt++)
+ {
+ if(gastrWIDs[cnt].u16WIDid == u16WIDid)
+ {
+ if(-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, NMI_FALSE , cnt,
+ &pstrWIDcfgResult[ResCnt]))
+ {
+ return -2;
+ }
+ ResCnt++;
+ }
+ }
+ }
+ idx += cfg_len;
+ /* In case if BIN type Wid, The last byte of the Cfg packet is the */
+ /* Checksum. The WID Length field does not accounts for the checksum. */
+ /* The Checksum is discarded. */
+ if(WID_BIN_DATA == enuWIDtype)
+ {
+ idx++;
+ }
+ }
+
+ return 0;
+}
+
+/**
+* @brief parses the write response [just detects its status: success or failure]
+* @details
+* @param[in] pu8RespBuffer The Response to be parsed
+* @return Error code indicating Write Operation status:
+ WRITE_RESP_SUCCESS (1) => Write Success.
+ NMI_FAIL (-100) => Write Failure.
+* @note
+* @author Ittiam
+* @date 11 Aug 2009
+* @version 1.0
+*/
+
+NMI_Sint32 ParseWriteResponse(NMI_Uint8* pu8RespBuffer)
+{
+ NMI_Sint32 s32Error = NMI_FAIL;
+ NMI_Uint16 u16RespLen = 0;
+ NMI_Uint16 u16WIDtype = (NMI_Uint16)WID_NIL;
+
+ /* Check whether the received frame is a valid response */
+ if(RESP_MSG_TYPE != pu8RespBuffer[0])
+ {
+ NMI_ERROR("Received Message format incorrect.\n");
+ return NMI_FAIL;
+ }
+
+ /* Extract Response Length */
+ u16RespLen = MAKE_WORD16(pu8RespBuffer[2], pu8RespBuffer[3]);
+
+ u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]);
+
+ /* Check for WID_STATUS ID and then check the length and status value */
+ if((u16WIDtype == WID_STATUS) &&
+ (pu8RespBuffer[6] == 1) &&
+ (pu8RespBuffer[7] == WRITE_RESP_SUCCESS))
+ {
+ s32Error = WRITE_RESP_SUCCESS;
+ return s32Error;
+ }
+
+ /* If the length or status are not as expected return failure */
+ s32Error = NMI_FAIL;
+ return s32Error;
+
+}
+
+/**
+* @brief creates the header of the Configuration Packet
+* @details
+* @param[in,out] pcpacket The Configuration Packet
+* @param[in,out] ps32PacketLength Length of the Configuration Packet
+* @return Error code indicating success/failure
+* @note
+* @author aismail
+* @date 18 Feb 2012
+* @version 1.0
+*/
+
+NMI_Sint32 CreatePacketHeader(NMI_Char* pcpacket,NMI_Sint32* ps32PacketLength)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint16 u16MsgLen = (NMI_Uint16)(*ps32PacketLength);
+ NMI_Uint16 u16MsgInd=0;
+
+ /* The format of the message is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | Message Type | Message ID | Message Length |Message body | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 1 Byte | 1 Byte | 2 Bytes | Message Length - 4 | */
+ /* +-------------------------------------------------------------------+ */
+
+ /* The format of a message body of a message type 'W' is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | WID0 | WID0 Length | WID0 Value | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 2 Bytes | 1 Byte | WID0 Length | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+
+
+
+ /* Message Type */
+ if(g_oper_mode == SET_CFG)
+ pcpacket[u16MsgInd++] = WRITE_MSG_TYPE;
+ else
+ pcpacket[u16MsgInd++] = QUERY_MSG_TYPE;
+
+ /* Sequence Number */
+ pcpacket[u16MsgInd++] = g_seqno++;
+
+ /* Message Length */
+ pcpacket[u16MsgInd++] = (NMI_Uint8)(u16MsgLen & 0xFF);
+ pcpacket[u16MsgInd++] = (NMI_Uint8)((u16MsgLen >> 8) & 0xFF);
+
+ * ps32PacketLength = u16MsgLen;
+
+ return s32Error;
+}
+
+/**
+* @brief creates Configuration packet based on the Input WIDs
+* @details
+* @param[in] pstrWIDs WIDs to be sent in the configuration packet
+* @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet
+* @param[out] ps8packet The created Configuration Packet
+* @param[out] ps32PacketLength Length of the created Configuration Packet
+* @return Error code indicating success/failure
+* @note
+* @author
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 CreateConfigPacket(NMI_Sint8* ps8packet, NMI_Sint32*ps32PacketLength,
+ tstrWID * pstrWIDs, NMI_Uint32 u32WIDsCount)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint32 u32idx = 0;
+ *ps32PacketLength = MSG_HEADER_LEN;
+ for(u32idx = 0; u32idx < u32WIDsCount; u32idx++)
+ {
+ switch(pstrWIDs[u32idx].enuWIDtype)
+ {
+ case WID_CHAR:
+ ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal);
+ break;
+ case WID_SHORT:
+ ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal);
+ break;
+ case WID_INT:
+ ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal);
+ break;
+ case WID_STR:
+ ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
+ break;
+ #if 0
+ case WID_ADR:
+ ProcessAdrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal);
+ break;
+ #endif
+ case WID_IP:
+ ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal);
+ break;
+ case WID_BIN_DATA:
+ ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
+ pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
+ break;
+ default:
+ NMI_ERROR("ERROR: Check Config database\n");
+ }
+ }
+
+ CreatePacketHeader(ps8packet, ps32PacketLength);
+
+ return s32Error;
+}
+
+NMI_Sint32 ConfigWaitResponse(NMI_Char* pcRespBuffer, NMI_Sint32 s32MaxRespBuffLen, NMI_Sint32 *ps32BytesRead,
+ NMI_Bool bRespRequired)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ /*bug 3878*/
+ /*removed to caller function*/
+ /*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer;
+ gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen;
+ NMI_PRINTF("GLOBAL =bRespRequired =%d\n", bRespRequired);
+ gstrConfigPktInfo.bRespRequired = bRespRequired;*/
+
+
+ if(gstrConfigPktInfo.bRespRequired == NMI_TRUE)
+ {
+ NMI_SemaphoreAcquire(&SemHandlePktResp, NMI_NULL);
+
+ *ps32BytesRead = gstrConfigPktInfo.s32BytesRead;
+ }
+
+ NMI_memset((void*)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
+
+ return s32Error;
+}
+
+/**
+* @brief sends certain Configuration Packet based on the input WIDs pstrWIDs
+ and retrieves the packet response pu8RxResp
+* @details
+* @param[in] pstrWIDs WIDs to be sent in the configuration packet
+* @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet
+* @param[out] pu8RxResp The received Packet Response
+* @param[out] ps32RxRespLen Length of the received Packet Response
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+#ifdef SIMULATION
+NMI_Sint32 SendConfigPkt(NMI_Uint8 u8Mode, tstrWID* pstrWIDs,
+ NMI_Uint32 u32WIDsCount,NMI_Bool bRespRequired,NMI_Uint32 drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Sint32 err = NMI_SUCCESS;
+ NMI_Sint32 s32ConfigPacketLen = 0;
+ NMI_Sint32 s32RcvdRespLen = 0;
+
+ NMI_SemaphoreAcquire(&SemHandleSendPkt, NMI_NULL);
+
+ /*set the packet mode*/
+ g_oper_mode = u8Mode;
+
+ NMI_memset((void*)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE);
+
+ if(CreateConfigPacket(gps8ConfigPacket, &s32ConfigPacketLen, pstrWIDs, u32WIDsCount) != NMI_SUCCESS)
+ {
+ s32Error = NMI_FAIL;
+ goto End_ConfigPkt;
+ }
+ /*bug 3878*/
+ gstrConfigPktInfo.pcRespBuffer = gps8ConfigPacket;
+ gstrConfigPktInfo.s32MaxRespBuffLen = MAX_PACKET_BUFF_SIZE;
+ PRINT_INFO(CORECONFIG_DBG,"GLOBAL =bRespRequired =%d\n", bRespRequired);
+ gstrConfigPktInfo.bRespRequired = bRespRequired;
+
+ s32Error = SendRawPacket(gps8ConfigPacket, s32ConfigPacketLen);
+ if(s32Error != NMI_SUCCESS)
+ {
+ goto End_ConfigPkt;
+ }
+
+ NMI_memset((void*)gps8ConfigPacket, 0, MAX_PACKET_BUFF_SIZE);
+
+ ConfigWaitResponse(gps8ConfigPacket, MAX_PACKET_BUFF_SIZE, &s32RcvdRespLen, bRespRequired);
+
+
+ if(bRespRequired == NMI_TRUE)
+ {
+ /* If the operating Mode is GET, then we expect a response frame from */
+ /* the driver. Hence start listening to the port for response */
+ if(g_oper_mode == GET_CFG)
+ {
+ #if 1
+ err = ParseResponse(gps8ConfigPacket, pstrWIDs);
+ if(err != 0)
+ {
+ s32Error = NMI_FAIL;
+ goto End_ConfigPkt;
+ }
+ else
+ {
+ s32Error = NMI_SUCCESS;
+ }
+ #endif
+ }
+ else
+ {
+ err = ParseWriteResponse(gps8ConfigPacket);
+ if(err != WRITE_RESP_SUCCESS)
+ {
+ s32Error = NMI_FAIL;
+ goto End_ConfigPkt;
+ }
+ else
+ {
+ s32Error = NMI_SUCCESS;
+ }
+ }
+
+
+ }
+
+
+End_ConfigPkt:
+ NMI_SemaphoreRelease(&SemHandleSendPkt, NMI_NULL);
+
+ return s32Error;
+}
+#endif
+NMI_Sint32 ConfigProvideResponse(NMI_Char* pcRespBuffer, NMI_Sint32 s32RespLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ if(gstrConfigPktInfo.bRespRequired == NMI_TRUE)
+ {
+ if(s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen)
+ {
+ NMI_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen);
+ gstrConfigPktInfo.s32BytesRead = s32RespLen;
+ }
+ else
+ {
+ NMI_memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen);
+ gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen;
+ NMI_ERROR("BusProvideResponse() Response greater than the prepared Buffer Size \n");
+ }
+
+ NMI_SemaphoreRelease(&SemHandlePktResp, NMI_NULL);
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief writes the received packet pu8RxPacket in the global Rx FIFO buffer
+* @details
+* @param[in] pu8RxPacket The received packet
+* @param[in] s32RxPacketLen Length of the received packet
+* @return Error code indicating success/failure
+* @note
+
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 ConfigPktReceived(NMI_Uint8* pu8RxPacket, NMI_Sint32 s32RxPacketLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 u8MsgType = 0;
+
+ u8MsgType = pu8RxPacket[0];
+
+ switch(u8MsgType)
+ {
+ case 'R':
+ {
+ ConfigProvideResponse(pu8RxPacket, s32RxPacketLen);
+
+ break;
+ }
+ case 'N':
+ {
+ PRINT_INFO(CORECONFIG_DBG,"NetworkInfo packet received\n");
+ NetworkInfoReceived(pu8RxPacket, s32RxPacketLen);
+ break;
+ }
+ case 'I':
+ {
+ //NMI_ERROR("ConfigPktReceived(): 'I' msg type is received at the Core Configurator and it is not supported yet \n");
+ GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen);
+ break;
+ }
+ case 'S':
+ {
+
+ host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen);
+ break;
+ }
+ default:
+ {
+ NMI_ERROR("ConfigPktReceived(): invalid received msg type at the Core Configurator \n");
+ }
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Deinitializes the Core Configurator
+* @details
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 CoreConfiguratorDeInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ PRINT_D(CORECONFIG_DBG,"CoreConfiguratorDeInit() \n");
+
+
+ NMI_SemaphoreDestroy(&SemHandleSendPkt, NMI_NULL);
+ NMI_SemaphoreDestroy(&SemHandlePktResp, NMI_NULL);
+
+
+ if(gps8ConfigPacket != NULL)
+ {
+
+ NMI_FREE(gps8ConfigPacket);
+ gps8ConfigPacket = NULL;
+ }
+
+ return s32Error;
+}
+
+
+#ifndef SIMULATION
+#if NMI_PLATFORM !=NMI_WIN32
+/*Using the global handle of the driver*/
+extern nmi_wlan_oup_t* gpstrWlanOps;
+/**
+* @brief sends certain Configuration Packet based on the input WIDs pstrWIDs
+* using driver config layer
+
+* @details
+* @param[in] pstrWIDs WIDs to be sent in the configuration packet
+* @param[in] u32WIDsCount number of WIDs to be sent in the configuration packet
+* @param[out] pu8RxResp The received Packet Response
+* @param[out] ps32RxRespLen Length of the received Packet Response
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 1 Mar 2012
+* @version 1.0
+*/
+NMI_Sint32 SendConfigPkt(NMI_Uint8 u8Mode, tstrWID* pstrWIDs,
+ NMI_Uint32 u32WIDsCount,NMI_Bool bRespRequired,NMI_Uint32 drvHandler)
+{
+ NMI_Sint32 counter = 0,ret = 0;
+ if(gpstrWlanOps == NULL)
+ {
+ PRINT_INFO(CORECONFIG_DBG,"Net Dev is still not initialized\n");
+ return 1;
+ }
+ else
+ {
+ //NMI_PRINTF("Net Dev is initialized\n");
+ }
+ if( gpstrWlanOps->wlan_cfg_set == NULL ||
+ gpstrWlanOps->wlan_cfg_get == NULL)
+ {
+ PRINT_INFO(CORECONFIG_DBG,"Set and Get is still not initialized\n");
+ return 1;
+ }
+ else
+ {
+ //NMI_PRINTF("SET is initialized\n");
+ }
+ if(u8Mode == GET_CFG)
+ {
+ for(counter = 0;counter<u32WIDsCount;counter++)
+ {
+ PRINT_INFO(CORECONFIG_DBG,"Sending CFG packet [%d][%d]\n",!counter,
+ (counter == u32WIDsCount - 1));
+ if(!gpstrWlanOps->wlan_cfg_get(!counter,
+ pstrWIDs[counter].u16WIDid,
+ (counter == u32WIDsCount - 1),drvHandler))
+ {
+ ret = -1;
+ printk("[Sendconfigpkt]Get Timed out\n");
+ break;
+ }
+ }
+ /**
+ get the value
+ **/
+ //NMI_Sleep(1000);
+ counter = 0;
+ for(counter = 0;counter<u32WIDsCount;counter++)
+ {
+ pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value(
+ pstrWIDs[counter].u16WIDid,
+ pstrWIDs[counter].ps8WidVal,pstrWIDs[counter].s32ValueSize);
+
+ }
+ }
+ else if(u8Mode == SET_CFG)
+ {
+ for(counter = 0;counter<u32WIDsCount;counter++)
+ {
+ PRINT_D(CORECONFIG_DBG,"Sending config SET PACKET WID:%x\n",pstrWIDs[counter].u16WIDid);
+ if(!gpstrWlanOps->wlan_cfg_set(!counter,
+ pstrWIDs[counter].u16WIDid,pstrWIDs[counter].ps8WidVal,
+ pstrWIDs[counter].s32ValueSize,
+ (counter == u32WIDsCount - 1),drvHandler))
+ {
+ ret = -1;
+ printk("[Sendconfigpkt]Set Timed out\n");
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+#endif
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/CoreConfigSimulator.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/CoreConfigSimulator.c
new file mode 100755
index 00000000..f088506e
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/CoreConfigSimulator.c
@@ -0,0 +1,4739 @@
+
+/*!
+* @file CoreConfigSimulator.c
+* @briefCoreConfigSimulatorDeInit
+* @author
+* @sa CoreConfigSimulator.h
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include "itypes.h"
+#include "driver/include/FIFO_Buffer.h"
+#include "nmi_wlan_if.h"
+
+/*****************************************************************************/
+/* Constants */
+/*****************************************************************************/
+#define INLINE static __inline
+
+#define SIMULATOR_MSG_EXIT ((NMI_Uint32)100)
+
+//#define CONFIG_PRINT
+
+#define MAX_BUFFER_LEN 1596
+#define MAX_FIFO_BUFF_LEN 2000
+
+
+#define MAX_CFG_LEN 256
+#define MAX_STRING_LEN 256
+#define SCAN_COMPLETE_MSG_LEN 8
+#define FCS_LEN 4
+
+/* Number of basic WIDS */
+#define NUM0_CHAR_WID 45
+#define NUM0_SHORT_WID 18
+#define NUM0_INT_WID 26
+#define NUM0_STR_WID 30
+
+/* Number of WIDS for this platform */
+#define NUM1_CHAR_WID (NUM0_CHAR_WID + 1)
+#define NUM1_SHORT_WID NUM0_SHORT_WID
+#define NUM1_INT_WID NUM0_INT_WID
+#define NUM1_STR_WID NUM0_STR_WID
+
+/* Number of WIDS with the current configuration */
+#define NUM2_CHAR_WID NUM1_CHAR_WID
+#define NUM2_SHORT_WID NUM1_SHORT_WID
+#define NUM2_INT_WID NUM1_INT_WID
+#define NUM2_STR_WID NUM1_STR_WID
+
+/* Final number if WIDs */
+#define NUM_CHAR_WID NUM2_CHAR_WID
+#define NUM_SHORT_WID NUM2_SHORT_WID
+#define NUM_INT_WID NUM2_INT_WID
+#define NUM_STR_WID NUM2_STR_WID
+#define NUM_BIN_DATA_WID 9
+
+#define NUM_WID (NUM_CHAR_WID + NUM_SHORT_WID\
+ + NUM_INT_WID + NUM_STR_WID + NUM_BIN_DATA_WID)
+
+#define MSG_DATA_OFFSET 8
+#define WID_VALUE_OFFSET 3
+#define WID_LENGTH_OFFSET 2
+#define WRITE_RSP_LEN 4
+#define MAX_QRSP_LEN 1000
+#define MAX_WRSP_LEN 20
+#define MSG_HDR_LEN 8
+#define MAX_ADDRESS_LEN 6
+#define WRSP_SUCCESS 1
+#define WRSP_ERR_MSG (-1)
+#define WRSP_ERR_SEQ (-2)
+#define WRSP_ERR_LEN (-3)
+#define WRSP_ERR_WID (-4)
+#define MAX_SUPRATE_LEN 34
+#define MAX_PROD_VER_LEN 10
+#define MAX_GRPADDR_LEN 38
+#define SITE_SURVEY_ELM_LEN (MAX_SSID_LEN + 1 + 1 + 1)
+#define WID_BIN_DATA_LEN_MASK 0x3FFF
+#define STATUS_MSG_LEN 12
+#define MAC_CONNECTED 1
+#define MAC_DISCONNECTED 0
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+#define MAKE_WORD16(lsb, msb) (((NMI_Uint16)(msb) << 8) & 0xFF00) | (lsb)
+#define MAKE_WORD32(lsw, msw) (((NMI_Uint32)(msw) << 16) & 0xFFFF0000) | (lsw)
+
+/*****************************************************************************/
+/* Type definitions */
+/*****************************************************************************/
+#if 0
+WID_SHORT = 1,
+WID_INT = 2,
+WID_STR = 3,
+WID_BIN_DATA = 4,
+} WID_TYPE_T;
+
+/* WLAN Identifiers */
+typedef enum {
+ WID_NIL = -1,
+ WID_BSS_TYPE = 0x0000,
+ WID_CURRENT_TX_RATE = 0x0001,
+ WID_CURRENT_CHANNEL = 0x0002,
+ WID_PREAMBLE = 0x0003,
+ WID_11G_OPERATING_MODE = 0x0004,
+ WID_STATUS = 0x0005,
+ WID_11G_PROT_MECH = 0x0006,
+
+#ifdef MAC_HW_UNIT_TEST_MODE
+ WID_GOTO_SLEEP = 0x0007,
+#else /* MAC_HW_UNIT_TEST_MODE */
+ WID_SCAN_TYPE = 0x0007,
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ WID_PRIVACY_INVOKED = 0x0008,
+ WID_KEY_ID = 0x0009,
+ WID_QOS_ENABLE = 0x000A,
+ WID_POWER_MANAGEMENT = 0x000B,
+ WID_802_11I_MODE = 0x000C,
+ WID_AUTH_TYPE = 0x000D,
+ WID_SITE_SURVEY = 0x000E,
+ WID_LISTEN_INTERVAL = 0x000F,
+ WID_DTIM_PERIOD = 0x0010,
+ WID_ACK_POLICY = 0x0011,
+ WID_RESET = 0x0012,
+ WID_PCF_MODE = 0x0013,
+ WID_CFP_PERIOD = 0x0014,
+ WID_BCAST_SSID = 0x0015,
+
+#ifdef MAC_HW_UNIT_TEST_MODE
+ WID_PHY_TEST_PATTERN = 0x0016,
+#else /* MAC_HW_UNIT_TEST_MODE */
+ WID_DISCONNECT = 0x0016,
+#endif /* MAC_HW_UNIT_TEST_MODE */
+
+ WID_READ_ADDR_SDRAM = 0x0017,
+ WID_TX_POWER_LEVEL_11A = 0x0018,
+ WID_REKEY_POLICY = 0x0019,
+ WID_SHORT_SLOT_ALLOWED = 0x001A,
+ WID_PHY_ACTIVE_REG = 0x001B,
+ WID_PHY_ACTIVE_REG_VAL = 0x001C,
+ WID_TX_POWER_LEVEL_11B = 0x001D,
+ WID_START_SCAN_REQ = 0x001E,
+ WID_RSSI = 0x001F,
+ WID_JOIN_REQ = 0x0020,
+ WID_ANTENNA_SELECTION = 0x0021,
+ WID_USER_CONTROL_ON_TX_POWER = 0x0027,
+ WID_MEMORY_ACCESS_8BIT = 0x0029,
+ WID_CURRENT_MAC_STATUS = 0x0031,
+ WID_AUTO_RX_SENSITIVITY = 0x0032,
+ WID_DATAFLOW_CONTROL = 0x0033,
+ WID_SCAN_FILTER = 0x0036,
+ WID_LINK_LOSS_THRESHOLD = 0x0037,
+ WID_AUTORATE_TYPE = 0x0038,
+ WID_CCA_THRESHOLD = 0x0039,
+
+ WID_UAPSD_SUPPORT_AP = 0x002A,
+
+ WID_802_11H_DFS_MODE = 0x003B,
+ WID_802_11H_TPC_MODE = 0x003C,
+
+ WID_RTS_THRESHOLD = 0x1000,
+ WID_FRAG_THRESHOLD = 0x1001,
+ WID_SHORT_RETRY_LIMIT = 0x1002,
+ WID_LONG_RETRY_LIMIT = 0x1003,
+ WID_CFP_MAX_DUR = 0x1004,
+ WID_PHY_TEST_FRAME_LEN = 0x1005,
+ WID_BEACON_INTERVAL = 0x1006,
+ WID_MEMORY_ACCESS_16BIT = 0x1008,
+
+ WID_RX_SENSE = 0x100B,
+ WID_ACTIVE_SCAN_TIME = 0x100C,
+ WID_PASSIVE_SCAN_TIME = 0x100D,
+ WID_SITE_SURVEY_SCAN_TIME = 0x100E,
+ WID_JOIN_TIMEOUT = 0x100F,
+ WID_AUTH_TIMEOUT = 0x1010,
+ WID_ASOC_TIMEOUT = 0x1011,
+ WID_11I_PROTOCOL_TIMEOUT = 0x1012,
+ WID_EAPOL_RESPONSE_TIMEOUT = 0x1013,
+ WID_CCA_BUSY_STATUS = 0x1014,
+
+ WID_FAILED_COUNT = 0x2000,
+ WID_RETRY_COUNT = 0x2001,
+ WID_MULTIPLE_RETRY_COUNT = 0x2002,
+ WID_FRAME_DUPLICATE_COUNT = 0x2003,
+ WID_ACK_FAILURE_COUNT = 0x2004,
+ WID_RECEIVED_FRAGMENT_COUNT = 0x2005,
+ WID_MULTICAST_RECEIVED_FRAME_COUNT = 0x2006,
+ WID_FCS_ERROR_COUNT = 0x2007,
+ WID_SUCCESS_FRAME_COUNT = 0x2008,
+ WID_PHY_TEST_PKT_CNT = 0x2009,
+ WID_PHY_TEST_TXD_PKT_CNT = 0x200A,
+ WID_TX_FRAGMENT_COUNT = 0x200B,
+ WID_TX_MULTICAST_FRAME_COUNT = 0x200C,
+ WID_RTS_SUCCESS_COUNT = 0x200D,
+ WID_RTS_FAILURE_COUNT = 0x200E,
+ WID_WEP_UNDECRYPTABLE_COUNT = 0x200F,
+ WID_REKEY_PERIOD = 0x2010,
+ WID_REKEY_PACKET_COUNT = 0x2011,
+#ifdef MAC_HW_UNIT_TEST_MODE
+ WID_Q_ENABLE_INFO = 0x2012,
+#else /* MAC_HW_UNIT_TEST_MODE */
+ WID_802_1X_SERV_ADDR = 0x2012,
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ WID_STACK_IP_ADDR = 0x2013,
+ WID_STACK_NETMASK_ADDR = 0x2014,
+ WID_HW_RX_COUNT = 0x2015,
+ WID_MEMORY_ADDRESS = 0x201E,
+ WID_MEMORY_ACCESS_32BIT = 0x201F,
+ WID_RF_REG_VAL = 0x2021,
+ WID_FIRMWARE_INFO = 0x2023,
+
+ WID_SSID = 0x3000,
+ WID_FIRMWARE_VERSION = 0x3001,
+ WID_OPERATIONAL_RATE_SET = 0x3002,
+ WID_BSSID = 0x3003,
+ WID_WEP_KEY_VALUE0 = 0x3004,
+ WID_WEP_KEY_VALUE1 = 0x3005,
+ WID_WEP_KEY_VALUE2 = 0x3006,
+ WID_WEP_KEY_VALUE3 = 0x3007,
+ WID_802_11I_PSK = 0x3008,
+ WID_HCCA_ACTION_REQ = 0x3009,
+ WID_802_1X_KEY = 0x300A,
+ WID_HARDWARE_VERSION = 0x300B,
+ WID_MAC_ADDR = 0x300C,
+ WID_PHY_TEST_DEST_ADDR = 0x300D,
+ WID_PHY_TEST_STATS = 0x300E,
+ WID_PHY_VERSION = 0x300F,
+ WID_SUPP_USERNAME = 0x3010,
+ WID_SUPP_PASSWORD = 0x3011,
+ WID_SITE_SURVEY_RESULTS = 0x3012,
+ WID_RX_POWER_LEVEL = 0x3013,
+
+ WID_ADD_WEP_KEY = 0x3019,
+ WID_REMOVE_WEP_KEY = 0x301A,
+ WID_ADD_PTK = 0x301B,
+ WID_ADD_RX_GTK = 0x301C,
+ WID_ADD_TX_GTK = 0x301D,
+ WID_REMOVE_KEY = 0x301E,
+ WID_ASSOC_REQ_INFO = 0x301F,
+ WID_ASSOC_RES_INFO = 0x3020,
+ WID_UPDATE_RF_SUPPORTED_INFO = 0x3021,
+ WID_COUNTRY_IE = 0x3022,
+ WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */
+ WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */
+ WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */
+ WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */
+ WID_PMKID_INFO = 0x3082,
+
+
+
+ WID_CONFIG_HCCA_ACTION_REQ = 0x4000,
+ WID_UAPSD_CONFIG = 0x4001,
+ WID_UAPSD_STATUS = 0x4002,
+ WID_WMM_AP_AC_PARAMS = 0x4003,
+ WID_WMM_STA_AC_PARAMS = 0x4004,
+ WID_NEWORK_INFO = 0x4005,
+ WID_STA_JOIN_INFO = 0x4006,
+ WID_CONNECTED_STA_LIST = 0x4007,
+ WID_HUT_STATS = 0x4082,
+ WID_SCAN_CHANNEL_LIST = 0x4084,
+ /*BugID_3746 WID to add IE to be added in next probe request*/
+ WID_INFO_ELEMENT_PROBE = 0x4085,
+ /*BugID_3746 WID to add IE to be added in next associate request*/
+ WID_INFO_ELEMENT_ASSOCIATE = 0x4086,
+ WID_ALL = 0x7FFE,
+ WID_MAX = 0xFFFF
+} WID_T;
+
+typedef enum {
+
+DONT_RESET = 0,
+DO_RESET = 1,
+NO_REQUEST = 2
+
+} RESET_REQ;
+
+#endif
+typedef struct _tstrSimulatorMsg
+{
+ NMI_Uint32 u32SimThreadCmd;
+ NMI_Uint8 au8PktData[MAX_BUFFER_LEN];
+ NMI_Sint32 s32PktDataLen;
+}tstrSimulatorMsg;
+
+typedef struct
+{
+ UWORD16 id; /* WID Identifier */
+ BOOL_T rsp; /* WID_ALL response */
+ BOOL_T reset; /* Reset MAC required */
+ void *get; /* Get Function Pointer */
+ void *set; /* Set Function Pointer */
+} host_wid_struct_t;
+
+
+#ifdef CONNECT_DIRECT
+typedef struct _tstrWidJoinReqExt
+{
+ NMI_Char SSID[MAX_SSID_LEN];
+ NMI_Uint8 u8channel;
+ NMI_Uint8 BSSID[6];
+}tstrWidJoinReqExt;
+#endif
+
+
+static void SimulatorThread(void* pvUsrArg);
+static void SendMacStatus(void* pvUsrArg);
+
+extern void send_host_rsp(NMI_Uint8 *host_rsp, NMI_Uint16 host_rsp_len);
+
+/*****************************************************************************/
+/* Global Variables */
+/*****************************************************************************/
+static NMI_MsgQueueHandle gMsgQSimulator;
+
+static NMI_ThreadHandle ThrdHandleSimulator = NMI_NULL;
+static NMI_ThreadHandle ThrdHandleScan = NMI_NULL;
+static NMI_ThreadHandle ThrdHandleMacStatus = NMI_NULL;
+static NMI_SemaphoreHandle SemHandleScanReq ;
+static NMI_SemaphoreHandle SemHandleScanExit ;
+static NMI_SemaphoreHandle SemHandleMacStsExit;
+static NMI_Bool gbTermntMacStsThrd = NMI_FALSE;
+BOOL_T bscan_code = NMI_FALSE;
+
+BOOL_T g_reset_mac = BFALSE;
+UWORD16 g_current_len = 0;
+UWORD8 g_current_settings[MAX_QRSP_LEN] = {0};
+UWORD8 g_cfg_val[MAX_CFG_LEN] = {0};
+UWORD8 g_phy_ver[MAX_PROD_VER_LEN + 1] = {0};
+UWORD32 g_last_w_seq = 0x1FF;
+UWORD8 g_info_id = 0;
+UWORD8 g_network_info_id = 0;
+UWORD8 g_scan_complete_id = 0;
+RESET_REQ_T g_reset_req_from_user = NO_REQUEST;
+UWORD16 Rsp_Len;
+
+BOOL_T g_short_slot_allowed = BTRUE;
+BOOL_T g_reset_mac_in_progress = BFALSE;
+static UWORD8 g_current_mac_status = MAC_DISCONNECTED;
+
+static tHANDLE ghTxFifoBuffer;
+static int g_connected_bssIdx = 0xFFFF;
+
+/*****************************************************************************/
+/* Inline Functions */
+/*****************************************************************************/
+//#include "host_if.h"
+INLINE UWORD16 config_host_hdr_offset(BOOL_T more_frag, UWORD16 frag_offset)
+{
+#ifdef ETHERNET_HOST
+ if((frag_offset == 0) && (more_frag == BFALSE))
+ {
+ return CONFIG_PKT_HDR_LEN;
+ }
+ else
+ {
+ return (CONFIG_PKT_HDR_LEN - UDP_HDR_OFFSET);
+ }
+#endif /* ETHERNET_HOST */
+
+
+
+
+ return 0;
+}
+
+/* The purpose of dot11StationID is to allow a manager to identify a station */
+/* for its own purposes. This attribute provides for that eventuality while */
+/* keeping the true MAC address independent. The default value is the STA's */
+/* assigned, unique MAC address. */
+UWORD8 mac[6] = {0x11,0x22,0x33,0x44,0x55,0x66};
+INLINE UWORD8* mget_StationID(void)
+{
+ return mac;
+}
+
+INLINE void mset_StationID(UWORD8* inp)
+{
+
+}
+
+/* This attribute shall specify the number of TUs that requesting STA should */
+/* wait for a response to a transmitted association-request MMPDU. */
+INLINE UWORD32 mget_AssociationResponseTimeOut(void)
+{
+ return 0;
+}
+
+INLINE void mset_AssociationResponseTimeOut(UWORD32 inp)
+{
+
+}
+
+
+INLINE UWORD32 get_enable_ch(void);
+
+
+
+INLINE void set_reset_req(UWORD8 val)
+{
+ g_reset_req_from_user =(RESET_REQ_T) val;
+}
+NMI_Uint8* au8WepKey[30];
+INLINE void set_wep_key()
+{
+ PRINT_INFO(CORECONFIG_DBG,"In set wep key \n");
+}
+
+/* Function to update PMKID Information */
+INLINE void set_pmkid_info(UWORD8 *val)
+{
+#ifdef IBSS_BSS_STATION_MODE
+ set_pmkid_cache(val);
+#endif /* IBSS_BSS_STATION_MODE */
+}
+
+/* Function to query PMKID Information */
+INLINE UWORD8 *get_pmkid_info(void)
+{
+ UWORD8 *retval = NULL;
+
+#ifdef IBSS_BSS_STATION_MODE
+ retval = get_pmkid_cache();
+#endif /* IBSS_BSS_STATION_MODE */
+
+ return retval;
+}
+
+#ifdef IBSS_BSS_STATION_MODE
+INLINE UWORD8* get_assoc_req_info(void)
+{
+ return ( ( UWORD8* )g_assoc_req_info );
+}
+INLINE UWORD8* get_assoc_res_info(void)
+{
+ return ( ( UWORD8* )g_assoc_res_info );
+}
+#endif /* IBSS_BSS_STATION_MODE */
+
+/* Set the Short Slot option */
+/* This function needs to be here because it is used in the */
+/* subsequent functions */
+INLINE void set_short_slot_allowed(UWORD8 val)
+{
+
+}
+
+/* This function returns the current slot option */
+//INLINE UWORD8 get_short_slot_allowed(void)
+//{
+// return g_short_slot_allowed;
+//}
+
+/* This function returns the SSID in the format required by the host. */
+//INLINE WORD8* get_DesiredSSID(void)
+//{
+// WORD8 *ssid_temp = mget_DesiredSSID();
+//
+// g_cfg_val[0] = strlen((const char*)ssid_temp);
+// strcpy( (char *)( g_cfg_val + 1 ), (const char*)ssid_temp);
+//
+// return ( ( WORD8* )g_cfg_val );
+//}
+
+/* This function returns the group address in the format required by host. */
+//INLINE UWORD8* get_GroupAddress(void)
+//{
+// UWORD8 *grpa_temp = mget_GroupAddress();
+//
+// g_cfg_val[0] = grpa_temp[GROUP_ADDRESS_SIZE_OFFSET]*6;
+// strcpy((char *)(g_cfg_val + 1), (const char*)grpa_temp);
+//
+// return g_cfg_val;
+//}
+
+/* This function returns the product version in the format required by host. */
+char firmver[] = "10.0";
+INLINE UWORD8* get_manufacturerProductVersion(void)
+{
+ UWORD8 *prod_ver_temp = firmver; /* mget_manufacturerProductVersion(); */
+
+ g_cfg_val[0] = strlen((const char*)prod_ver_temp);
+ NMI_memcpy((char *)(g_cfg_val + 1), (const char*)prod_ver_temp,NMI_strlen(firmver));
+
+ return g_cfg_val;
+}
+
+/* This function returns the product version in the format required by host. */
+//INLINE UWORD8* get_hardwareProductVersion(void)
+//{
+// UWORD32 hard_ver_temp = get_machw_pa_ver();
+// UWORD8 index = 1;
+// UWORD8 temp = 0;
+//
+// /* Format version as 'x.x.x' */
+// temp = ((hard_ver_temp & 0xF0000000) >> 28) * 16 +
+// ((hard_ver_temp & 0x0F000000) >> 24);
+// if(temp > 9)
+// {
+// g_cfg_val[index++] = (UWORD8)(temp/10) + '0';
+// }
+// g_cfg_val[index++] = temp - (((UWORD8)(temp/10))*10) + '0';
+// g_cfg_val[index++] = '.';
+// temp = ((hard_ver_temp & 0x00F00000) >> 20) * 16 +
+// ((hard_ver_temp & 0x000F0000) >> 16);
+// if(temp > 9)
+// {
+// g_cfg_val[index++] = (UWORD8)(temp/10) + '0';
+// }
+// g_cfg_val[index++] = temp - (((UWORD8)(temp/10))*10) + '0';
+// g_cfg_val[index++] = '.';
+// temp = ((hard_ver_temp & 0x0000F000) >> 12) * 16 +
+// ((hard_ver_temp & 0x00000F00) >> 8);
+// if(temp > 9)
+// {
+// g_cfg_val[index++] = (UWORD8)(temp/10) + '0';
+// }
+// g_cfg_val[index++] = temp - (((UWORD8)(temp/10))*10) + '0';
+// g_cfg_val[0] = index - 1;
+// return g_cfg_val;
+//}
+
+
+/* This function returns the product version in the format required by host. */
+INLINE UWORD8* get_phyProductVersion(void)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Product version\n");
+ return g_phy_ver;
+}
+
+/* This function returns the BSSID in the format required by the host.*/
+NMI_Uint8 bssid_addr [6] = {0x66,0x55,0x44,0x33,0x22,0x11};
+INLINE UWORD8* get_bssid(void)
+{
+
+ UWORD8 *bssid_temp = bssid_addr;//mget_bssid();
+
+ g_cfg_val[0] = MAX_ADDRESS_LEN;
+ NMI_memcpy(g_cfg_val + 1, bssid_temp, MAX_ADDRESS_LEN);
+
+ return g_cfg_val;
+
+}
+
+/* This function returns the MAC Address in the format required by the host.*/
+UWORD8 mac_address[] = {0x11,0x22,0x33,0x44,0x55,0x66};
+INLINE UWORD8* get_mac_addr(void)
+{
+#ifndef MAC_HW_UNIT_TEST_MODE
+ UWORD8 *mac_addr_temp = mac_address; /* mget_StationID(); */
+
+ g_cfg_val[0] = MAX_ADDRESS_LEN;
+ NMI_memcpy(g_cfg_val + 1, mac_addr_temp, MAX_ADDRESS_LEN);
+
+
+ return g_cfg_val;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ g_cfg_val[0] = MAX_ADDRESS_LEN;
+ NMI_memcpy(&g_cfg_val[1], g_test_params.mac_address, MAX_ADDRESS_LEN);
+ return g_cfg_val;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function returns the Supported Rates in the format required by host. */
+INLINE UWORD8* get_supp_rates(void)
+{
+
+#ifdef PHY_802_11b
+ UWORD8 *str = (UWORD8 *)"1,2,5.5,11";
+ g_cfg_val[0] = strlen((const char*)str);
+ NMI_memcpy(g_cfg_val + 1, str, g_cfg_val[0]);
+#endif /* PHY_802_11b */
+
+#ifdef PHY_802_11a
+ UWORD8 *str = (UWORD8 *)"6,9,12,18,24,36,48,54";
+ g_cfg_val[0] = strlen((const char*)str);
+ NMI_memcpy(g_cfg_val + 1, str, g_cfg_val[0]);
+#endif /* PHY_802_11a */
+
+#ifdef PHY_802_11g
+ UWORD8 *str = (UWORD8 *)"1,2,5.5,11,6,9,12,18,24,36,48,54";
+ g_cfg_val[0] = strlen((const char*)str);
+ NMI_memcpy(g_cfg_val + 1, str, g_cfg_val[0]);
+#endif /* PHY_802_11g */
+
+ return g_cfg_val;
+}
+
+/* BSS Type formats for Host and MAC */
+/* -------------------------------------------------------------------- */
+/* Infrastructure Independent Access Point */
+/* Host : 0 1 2 */
+/* MIB : 1 2 3 */
+/* -------------------------------------------------------------------- */
+
+/* This function returns the BSS Type in the format required by the host. */
+INLINE UWORD8 get_DesiredBSSType(void)
+{
+
+
+ return 0;
+}
+
+/* This function returns the BSS Type in the format required by the MAC.*/
+INLINE void set_DesiredBSSType(UWORD8 bss_type)
+{
+
+}
+
+/* Channel formats for Host and MAC */
+/* -------------------------------------------------------------------- */
+/* CHANNEL1 CHANNEL2 .... CHANNEL14 */
+/* Host : 1 2 14 */
+/* MIB : 0 1 13 */
+/* -------------------------------------------------------------------- */
+
+/* This function returns the Channel in the format required by the host.*/
+int g_chnum = 0;
+INLINE UWORD8 get_host_chnl_num(void)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Get MAC channel [%d]\n",g_chnum);
+ return g_chnum;
+}
+
+/* This function returns the Channel in the format required by the MAC.*/
+INLINE void set_mac_chnl_num(UWORD8 cnum)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Set MAC channel to [%d]\n",cnum);
+ g_chnum = cnum;
+}
+
+static NMI_Uint8 au8SrvyResFrstFrag[91] = {90, 88, 0, 'b', 'o', 'o', 'n', 'd', 'o', 'g', 'g', 'l',
+ 'e', '\0', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0x02, 0x0b, 0x51,
+ 0x00, 0x1a, 0x70, 0xfc, 0xc0, 0x6f, 0x17, 1,
+ 'N', 'P', 'M', 'E', 'D', 'C', '-', 'B', 'G', '\0', 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0x52, 0x04, 0x13,
+ 0x00, 0x1a, 0xc1, 0x26, 0x11, 0xc0, 0x42, 0x30};
+
+static NMI_Uint8 au8SrvyResScndFrag[47] = {46, 44, 1, 'n', 'w', 'i', 'f', 'i', '\0', 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x02, 0x0b, 0x51, 0x1c, 0x7e, 0xe5, 0x49, 0x76,
+ 0x31, 0x17, 1};
+
+NMI_Uint32 gu32ReqSrvyResFrag = 0;
+/* This function returns the site survey results */
+INLINE UWORD8 *get_site_survey_results(void)
+{
+#ifdef IBSS_BSS_STATION_MODE
+ return get_site_survey_results_sta();
+#else /* IBSS_BSS_STATION_MODE */
+ if((gu32ReqSrvyResFrag >= 0) && (gu32ReqSrvyResFrag < 1))
+ {
+ gu32ReqSrvyResFrag++;
+ return au8SrvyResFrstFrag;
+ }
+ else if(gu32ReqSrvyResFrag == 1)
+ {
+ gu32ReqSrvyResFrag = 0;
+ return au8SrvyResScndFrag;
+ }
+ else
+ {
+ NMI_ERROR("invalid fragment num of Site Survey Results \n");
+ return NULL;
+ }
+#endif /* IBSS_BSS_STATION_MODE */
+}
+
+
+static NMI_Uint8 g_assoc_res_info[] = {71, 0x21, 0x04, 0x00, 0x00, 0x02, 0xc0, 0x01, 0x08, 0x82, 0x84, 0x8b, 0x0c,
+ 0x12, 0x96, 0x18, 0x24, 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0xdd, 0x18,
+ 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x83, 0x00, 0x03, 0xa4, 0x00, 0x00,
+ 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, 0x62, 0x32, 0x2f, 0x00,
+ 0xdd, 0x09, 0x00, 0x03, 0x7f, 0x01, 0x01, 0x00, 0x00, 0xff, 0x7f, 0xdd,
+ 0x0a, 0x00, 0x03, 0x7f, 0x04, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00};
+
+INLINE UWORD8* get_assoc_res_info(void)
+{
+ return g_assoc_res_info;
+}
+
+
+/* Rate formats for Host and MAC */
+/* ----------------------------------------------------------------------- */
+/* 1 2 5.5 11 6 9 12 18 24 36 48 54 Auto */
+/* Host : 1 2 3 4 5 6 7 8 9 10 11 12 0 */
+
+/* MAC : 1 2 5 11 6 9 12 18 24 36 48 54 Not supported */
+/* ----------------------------------------------------------------------- */
+
+/* This function returns the transmission rate to the user.*/
+int g_txrate = 0;
+INLINE UWORD8 get_tx_rate(void)
+{
+ return g_txrate;
+}
+
+/* This function sets the transmission rate as requested by the user.*/
+INLINE void set_tx_rate(UWORD8 rate)
+{
+ /*NMI_PRINTF("\nRate is set: %d",rate);*/
+ g_txrate = rate;
+
+}
+
+/* Preamble formats for Host and MAC */
+/* ----------------------------------------------------------------------- */
+/* Long Short */
+/* Host : 1 0 */
+/* MAC : 1 0 */
+/* ----------------------------------------------------------------------- */
+
+/* This function returns the preamble type as set by the user.*/
+INLINE UWORD8 get_preamble_type(void)
+{
+ //Whether auto or long only
+ return 0;
+}
+
+/* This function sets the preamble type as requested by the user.*/
+INLINE void set_preamble_type(UWORD8 idx)
+{
+}
+
+/* This function sets the RTS threshold as requested by the user. The MAC */
+/* H/w register is also set accordingly. */
+INLINE void set_RTSThreshold(UWORD16 limit)
+{
+
+}
+
+/* This function sets the Fragmentation threshold as requested by the user. */
+/* The MAC H/w register is also set accordingly. */
+INLINE void set_FragmentationThreshold(UWORD16 limit)
+{
+ #if 0
+ set_machw_frag_thresh(limit);
+ #endif
+}
+
+/* This function sets the Short Retry Limit as requested by the user. The */
+/* MAC H/w register is also set accordingly. */
+INLINE void set_ShortRetryLimit(UWORD8 limit)
+{
+
+}
+
+/* This function sets the Long Retry Limit as requested by the user. The */
+/* MAC H/w register is also set accordingly. */
+INLINE void set_LongRetryLimit(UWORD8 limit)
+{
+
+}
+
+/* This function returns the current protection mode */
+INLINE UWORD8 get_protection_mode(void)
+{
+
+ return 0;
+}
+
+/* This function sets the protection mode */
+INLINE void set_protection_mode(UWORD8 prot_mode)
+{
+
+
+}
+
+/* Station power save modes */
+typedef enum {MIB_ACTIVE = 1,
+ MIB_POWERSAVE = 2
+} PS_MODE_T;
+/* Get the current value of power management mode */
+INLINE UWORD8 get_PowerManagementMode(void)
+{
+ return 0;
+}
+
+/* Set the power management mode according to value */
+INLINE void set_PowerManagementMode(UWORD8 val)
+{
+
+}
+
+
+/* Get the current value of ack policy type */
+INLINE UWORD8 get_ack_type(void)
+{
+ return 0;
+}
+
+/* Set the value of the Ack Policy to the value */
+INLINE void set_ack_type(UWORD8 val)
+{
+
+}
+
+/* Get the current value of PCF mode supported */
+INLINE UWORD8 get_pcf_mode(void)
+{
+ return 0;
+}
+
+/* Set the value of the of PCF mode to the value */
+INLINE void set_pcf_mode(UWORD8 val)
+{
+
+}
+
+/* Get the current value of PCF mode supported */
+INLINE UWORD8 get_bcst_ssid(void)
+{
+ return 0;
+}
+
+/* Set the value of the of PCF mode to the value */
+INLINE void set_bcst_ssid(UWORD8 val)
+{
+
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD16 get_phy_test_frame_len(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+#ifndef MAC_WMM
+ return g_test_config.tx.nor.frame_len;
+#else /* MAC_WMM */
+ return g_test_config.tx.ac_vo.frame_len;
+#endif /* MAC_WMM */
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+
+}
+
+INLINE void set_phy_test_frame_len(UWORD16 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_test_stats.txci = 0;
+ g_test_stats.rxd.type.ack = 0;
+#ifndef MAC_WMM
+ g_test_config.tx.nor.frame_len = val;
+#else /* MAC_WMM */
+ g_test_config.tx.ac_vo.frame_len = val;
+#endif /* MAC_WMM */
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD8* get_phy_test_dst_addr(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_cfg_val[0] = MAX_ADDRESS_LEN;
+ NMI_memcpy(&g_cfg_val[1], g_test_config.tx.da, MAX_ADDRESS_LEN);
+ return g_cfg_val;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_phy_test_dst_addr(UWORD8* val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ NMI_memcpy(g_test_config.tx.da, val, MAX_ADDRESS_LEN);
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE UWORD32 get_q_enable_info(UWORD32 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ return (UWORD32) g_test_config.tx.q_enable_info;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_q_enable_info(UWORD32 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_test_config.tx.q_enable_info = val;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD32 get_phy_test_pkt_cnt(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ return g_test_config.tx.num_pkts;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_phy_test_pkt_cnt(UWORD32 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_test_config.tx.num_pkts = val;
+ g_test_stats.txci = 0;
+ g_test_stats.rxd.type.ack = 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD32 get_phy_test_txd_pkt_cnt(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ return g_test_stats.txci;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_phy_test_txd_pkt_cnt(UWORD32 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_test_stats.txci = 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD8 get_phy_test_pattern(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ return g_test_config.tx.pattern_type;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_phy_test_pattern(UWORD8 val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_test_config.tx.pattern_type = val;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function gets the current test statistics. To interpret these stats at */
+/* the host, structure test_stats_struct_t should be the same at the host and */
+/* device side. */
+INLINE UWORD8* get_hut_stats(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+
+ UWORD8 trigger_stat_lsb = 0;
+ UWORD8 trigger_stat_msb = 0;
+ UWORD16 stats_size = 0;
+
+ read_phy_reg(rAGCTRIGSTATLSB, &trigger_stat_lsb);
+ read_phy_reg(rAGCTRIGSTATMSB, &trigger_stat_msb);
+ g_test_stats.rxd.agc_trig_stats = (trigger_stat_msb << 8) + trigger_stat_lsb;
+
+ stats_size = MIN(sizeof(test_stats_struct_t),(MAX_STATS_BUFFER_LEN - 1));
+
+ g_stats_buf[0] = stats_size & 0x00FF;
+ g_stats_buf[1] = (stats_size & 0xFF00) >> 8;
+
+ NMI_memcpy(&g_stats_buf[2], &g_test_stats, stats_size);
+
+ return g_stats_buf;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function clears the current test statistics. */
+INLINE void set_hut_stats(UWORD8* val)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ memset(&g_test_stats, 0, sizeof(test_stats_struct_t));
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE UWORD8* get_phy_test_stats(void)
+{
+#ifdef MAC_HW_UNIT_TEST_MODE
+ g_cfg_val[0] = MIN(sizeof(test_stats_struct_t),(MAX_CFG_LEN - 1));
+ NMI_memcpy(&g_cfg_val[1], &g_test_stats, g_cfg_val[0]);
+ return g_cfg_val;
+#else /* MAC_HW_UNIT_TEST_MODE */
+ return 0;
+#endif /* MAC_HW_UNIT_TEST_MODE */
+}
+
+INLINE void set_phy_test_stats(UWORD8* val)
+{
+
+
+}
+
+/* Get/Set the read MAC Address from the SDRAM */
+INLINE void set_read_addr_sdram(UWORD8 val)
+{
+
+}
+
+INLINE UWORD8 get_read_addr_sdram(void)
+{
+ return 0;
+}
+
+/* Get/Set the Tx Power Level */
+INLINE void set_tx_power_level_11a(UWORD8 val)
+{
+
+}
+
+INLINE UWORD8 get_tx_power_level_11a(void)
+{
+ return 0;
+}
+
+/* Set the new DTIM Period */
+INLINE void set_dtim_period(UWORD8 val)
+{
+
+}
+
+/* Set the local Stack IP Address */
+INLINE void set_stack_ip_addr(UWORD32 val)
+{
+
+}
+
+INLINE UWORD32 get_stack_ip_addr(void)
+{
+
+ return 0;
+}
+
+
+/* Set the local Stack netmask */
+INLINE void set_stack_netmask_addr(UWORD32 val)
+{
+
+}
+
+INLINE UWORD32 get_stack_netmask_addr(void)
+{
+
+ return 0;
+}
+
+/* Set Phy active Register */
+INLINE void set_phy_active_reg(UWORD8 val)
+{
+
+}
+
+/* Set Phy active Register */
+INLINE UWORD8 get_phy_active_reg(UWORD8 val)
+{
+ return 0;
+}
+
+/* Set Phy active Register value */
+INLINE UWORD8 get_phy_active_reg_val(void)
+{
+
+ return 0;
+
+}
+
+INLINE void set_phy_active_reg_val(UWORD8 val)
+{
+
+}
+
+INLINE void set_rf_reg_val(UWORD32 val)
+{
+
+}
+
+/* Get/Set the Tx Power Level */
+INLINE void set_tx_power_level_11b(UWORD8 val)
+{
+
+}
+
+INLINE UWORD8 get_tx_power_level_11b(void)
+{
+ return 0;
+}
+
+/* Get the RSSI */
+INLINE WORD8 get_rssi(void)
+{
+ return 0;
+}
+
+
+/* Get the Current MAC Status */
+INLINE UWORD8 get_current_mac_status(void)
+{
+ return 0;
+}
+
+INLINE UWORD8 get_auto_rx_sensitivity(void)
+{
+ return 0;
+}
+
+INLINE void set_auto_rx_sensitivity(UWORD8 input)
+{
+
+}
+
+INLINE UWORD8 get_dataflow_control(void)
+{
+ return 0;
+}
+
+INLINE void set_dataflow_control(UWORD8 input)
+{
+
+}
+
+INLINE UWORD8 get_scan_filter(void)
+{
+
+ return 0;
+
+}
+
+INLINE void set_scan_filter(UWORD8 input)
+{
+
+}
+
+INLINE UWORD8 get_link_loss_threshold(void)
+{
+ return 0;
+}
+
+INLINE void set_link_loss_threshold(UWORD8 input)
+{
+
+}
+
+INLINE UWORD8 get_autorate_type(void)
+{
+ return 0;
+}
+
+INLINE void set_autorate_type(UWORD8 input)
+{
+
+}
+
+INLINE UWORD8 get_cca_threshold(void)
+{
+ return 0;
+}
+
+INLINE void set_cca_threshold(UWORD8 input)
+{
+
+}
+
+INLINE UWORD32 get_enable_ch(void)
+{
+ return 0;
+}
+
+INLINE void set_enable_ch(UWORD32 input)
+{
+
+}
+
+/* This function returns the antenna selected */
+INLINE UWORD8 get_antenna_selection(void)
+{
+ return 0;
+}
+
+/* This function sets the antenna to be used */
+INLINE void set_antenna_selection(UWORD8 mode)
+{
+
+}
+
+INLINE void set_FailedCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_RetryCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_MultipleRetryCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_FrameDuplicateCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_ACKFailureCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_ReceivedFragmentCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_MulticastReceivedFrameCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_FCSErrorCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_TransmittedFrameCount_to_zero(UWORD32 val)
+{
+
+}
+
+INLINE void set_config_HCCA_actionReq(UWORD8 *req)
+{
+
+}
+
+INLINE UWORD8 get_user_control_enabled(void)
+{
+ return 0;
+}
+
+INLINE void set_user_control_enabled(UWORD8 val)
+{
+
+}
+INLINE UWORD32 get_firmware_info(void)
+{
+ return 0;
+}
+
+UWORD32 g_memory_address = 0x0; //just for testing Integer WIDs
+
+INLINE void set_memory_address(UWORD32 input)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Set mem addr to [%x] \n", input);
+ g_memory_address = input;
+}
+INLINE UWORD32 get_memory_address(void)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Get mem addr [%x] \n", g_memory_address);
+ return g_memory_address;
+}
+INLINE UWORD8 get_memory_access_8bit(void)
+{
+
+ return 0;
+}
+INLINE void set_memory_access_8bit(UWORD8 input)
+{
+
+}
+INLINE UWORD16 get_memory_access_16bit(void)
+{
+
+ return 0;
+
+}
+INLINE void set_memory_access_16bit(UWORD16 input)
+{
+
+}
+INLINE UWORD32 get_memory_access_32bit(void)
+{
+
+ return 0;
+
+}
+INLINE void set_memory_access_32bit(UWORD32 input)
+{
+
+}
+
+/* This function sets the MAC Address required for the MH/PHY Test.*/
+INLINE void set_mac_addr(UWORD8 *val)
+{
+}
+
+
+/*
+ Rx sensitivity parameter format (WID view)
+ +----------------------+----------------------+
+ | PHYAGCMAXVGAGAIN | PHYAGCFINALVGAGAINTH |
+ +----------------------+----------------------+
+ 7 0 15 8 (bit)
+*/
+INLINE UWORD16 get_rx_sense(void)
+{
+ return 0;
+}
+
+INLINE void set_rx_sense(UWORD16 val)
+{
+}
+
+INLINE UWORD16 get_active_scan_time(void)
+{
+
+ return 0;
+
+}
+
+INLINE void set_active_scan_time(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_passive_scan_time(void)
+{
+
+ return 0;
+
+}
+
+INLINE void set_passive_scan_time(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_site_survey_scan_time(void)
+{
+
+ return 0;
+
+}
+
+INLINE void set_site_survey_scan_time(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_join_timeout(void)
+{
+ return 0;
+}
+
+INLINE void set_join_timeout(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_auth_timeout(void)
+{
+ return 0;
+}
+
+INLINE void set_auth_timeout(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_asoc_timeout(void)
+{
+ return (UWORD16)mget_AssociationResponseTimeOut();
+}
+
+INLINE void set_asoc_timeout(UWORD16 val)
+{
+ mset_AssociationResponseTimeOut((UWORD32)val);
+}
+
+INLINE UWORD16 get_11i_protocol_timeout(void)
+{
+ return 0;
+}
+
+INLINE void set_11i_protocol_timeout(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_eapol_response_timeout(void)
+{
+
+ return 0;
+}
+
+INLINE void set_eapol_response_timeout(UWORD16 val)
+{
+
+}
+
+INLINE UWORD16 get_cca_busy_status(void)
+{
+ return 0;
+}
+
+INLINE void set_cca_busy_start(UWORD16 val)
+{
+}
+
+/* Get the current value of site servey */
+INLINE UWORD8 get_site_survey_status(void)
+{
+
+ return 0;
+
+}
+
+/* Set the site survey option according to the value */
+INLINE void set_site_survey(UWORD8 val)
+{
+
+}
+
+
+INLINE void set_preferred_bssid(UWORD8 *val)
+{
+
+}
+
+NMI_Uint8 au8Psk[65] = {0};
+INLINE void set_RSNAConfigPSKPassPhrase(UWORD8* psk)
+{
+ NMI_memcpy(au8Psk,psk,NMI_strlen(psk));
+ au8Psk[NMI_strlen(au8Psk)] = '\0';
+ PRINT_INFO(CORECONFIG_DBG,"\n[CoreSimulator] %s", au8Psk);
+}
+INLINE UWORD8* get_RSNAConfigPSKPassPhrase(void)
+{
+ return au8Psk;
+}
+/* Function to set g_sta_uapsd_config value */
+NMI_Uint8 as8UapsdConfig[5]={0};
+INLINE void set_uapsd_config(UWORD8 *val)
+{
+ NMI_memcpy(as8UapsdConfig,val,sizeof(as8UapsdConfig));
+
+}
+
+/* Function to set g_sta_uapsd_config value */
+INLINE UWORD8* get_uapsd_config(void)
+{
+ return as8UapsdConfig;
+}
+
+/* Function to set g_sta_uapsd_status value */
+INLINE UWORD8* get_uapsd_status(void)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* WMM configuration functions for AP mode */
+/*****************************************************************************/
+
+/* Function to set AC parameter values to be used by the AP */
+INLINE void set_wmm_ap_ac_params(UWORD8 *val)
+{
+
+}
+
+/* Function to get AC parameter values in use by the AP */
+INLINE UWORD8* get_wmm_ap_ac_params(void)
+{
+
+ return 0;
+}
+
+/* Function to set AC parameter values for STA associated with the AP */
+INLINE void set_wmm_sta_ac_params(UWORD8 *val)
+{
+
+}
+
+/* Function to get AC parameter values for STA associated with the AP */
+INLINE UWORD8* get_wmm_sta_ac_params(void)
+{
+
+ return 0;
+}
+
+/* Function to set UAPSD SUPPORT in AP */
+INLINE void set_uapsd_support_ap(UWORD8 val)
+{
+
+}
+
+/* Function to get the UAPSD support of AP */
+INLINE UWORD8 get_uapsd_support_ap(void)
+{
+
+ return BFALSE;
+}
+
+/**************** 802.11H related functions************************/
+
+INLINE void set_802_11H_DFS_mode(BOOL_T val)
+{
+
+}
+
+INLINE BOOL_T get_802_11H_DFS_mode(void)
+{
+
+ return(BFALSE);
+}
+
+
+INLINE void set_802_11H_TPC_mode(BOOL_T val)
+{
+
+}
+
+INLINE BOOL_T get_802_11H_TPC_mode(void)
+{
+
+ return(BFALSE);
+}
+
+
+INLINE UWORD8* get_rf_supported_info(UWORD8 ch_num)
+{
+
+ return 0;
+
+}
+
+INLINE void set_rf_supported_info(UWORD8 *info)
+{
+}
+
+/* Get the connected station list */
+INLINE UWORD8* get_connected_sta_list(void)
+{
+ return 0;
+}
+
+/* Function to set the Country information element. Currently this is valid */
+/* only for 11h protocol and AP mode. Note that the incoming bytes are */
+/* directly stored in the global country information element. The assumption */
+/* is that the setting will be in the format specified in the standard. */
+/* Make sure RF Supported Info is set before, whenever this is updated */
+INLINE void set_country_ie(UWORD8 *val)
+{
+
+}
+
+/* Function to get the Country information element. Currently this is valid */
+/* only for 11h protocol and AP mode. The value returned will be in the */
+/* format specified in the standard. */
+INLINE UWORD8* get_country_ie(void)
+{
+ return 0;
+}
+
+INLINE void set_running_mode(UWORD8 mode)
+{
+
+}
+
+/* This function returns the running mode for 802.11g PHY */
+INLINE UWORD8 get_running_mode(void)
+{
+ return 0;
+}
+
+
+#ifdef DEBUG_MODE
+INLINE void set_test_case_name(const char* input)
+{
+#ifdef DEBUG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("\n ---- %s ---- \n",input);
+#endif /* DEBUG_PRINT */
+}
+#endif /* DEBUG_MODE */
+
+
+/* Scan Type that is to be used. 0 -> Passive Scan, 1 -> Active Scan */
+INLINE UWORD8 mget_scan_type(void)
+{
+ return 0;
+}
+
+INLINE void mset_scan_type(UWORD8 st)
+{
+
+}
+
+INLINE UWORD8 mget_listen_interval(void)
+{
+ return 0;
+}
+
+INLINE void mset_listen_interval(UWORD8 li)
+{
+
+}
+
+
+/* When this attribute is true, it shall indicate that the IEEE 802.11 WEP */
+/* mechanism is used for transmitting frames of type Data. The default value */
+/* of this attribute shall be false. */
+INLINE UWORD8 mget_PrivacyInvoked(void)
+{
+ return 0;
+}
+
+/* This attribute shall indicate use of the first, second, third, or fourth */
+/* element of the WEPDefaultKeys array when set to values of zero, one, two, */
+/* or three. The default value of this attribute shall be 0. */
+/* REFERENCE "ISO/IEC 8802-11:1999, 8.3.2" */
+NMI_Uint8 u8WepKey;
+INLINE UWORD8 mget_WEPDefaultKeyID(void)
+{
+ PRINT_INFO(CORECONFIG_DBG,"[CoreConfigSim]In get WEP default key: %d\n",u8WepKey);
+ return u8WepKey;
+}
+INLINE void mset_WEPDefaultKeyID(UWORD8 inp)
+{
+ u8WepKey = inp;
+ PRINT_INFO(CORECONFIG_DBG,"In set WEP default key: %d \n",u8WepKey);
+}
+
+INLINE UWORD8 get_qos_enable(void)
+{
+ return 0;
+}
+INLINE void set_qos_enable(UWORD8 val)
+{
+
+}
+NMI_Uint8 u8Mode11I;
+INLINE UWORD8 get_802_11I_mode(void)
+{
+ return u8Mode11I;
+}
+
+INLINE void set_802_11I_mode(UWORD8 val)
+{
+ u8Mode11I = val;
+}
+
+INLINE UWORD8 get_auth_type(void)
+{
+ return 0;
+}
+INLINE void set_auth_type(UWORD8 val)
+{
+
+}
+
+/* This attribute shall specify the number of beacon intervals that shall */
+/* elapse between transmission of Beacons frames containing a TIM element */
+/* whose DTIM Count field is 0. This value is transmitted in the DTIM Period */
+/* field of Beacon frames. */
+INLINE UWORD8 mget_DTIMPeriod(void)
+{
+ return 0;
+}
+
+/* The attribute shall describe the number of DTIM intervals between the */
+/* start of CFPs. It is modified by MLME-START.request primitive. */
+INLINE UWORD8 mget_CFPPeriod(void)
+{
+ return 0;
+}
+
+INLINE void mset_CFPPeriod(UWORD8 inp)
+{
+
+}
+
+void disconnect_station(UWORD8 assoc_id)
+{
+
+}
+
+INLINE UWORD8 get_RSNAConfigGroupRekeyMethod(void)
+{
+ return 0;
+}
+
+INLINE void set_RSNAConfigGroupRekeyMethod(UWORD8 val)
+{
+}
+
+INLINE UWORD8 get_short_slot_allowed(void)
+{
+ return 0;
+}
+
+
+/* our AP Beacon */
+
+char aBeacon[] = {0x80,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x1a,0xc1,0x26,0x11,0xc0,
+ 0x00,0x1a,0xc1,0x26,0x11,0xc0,0x30,0x41,0x81,0xc1,0x57,0xe3,0x1d,0x00,0x00,0x00,
+ 0x64,0x00,0x11,0x04,0x00,0x09,0x4e,0x50,0x4d,0x45,0x44,0x43,0x2d,0x42,0x47,0x01,
+ 0x08,0x82,0x84,0x8b,0x96,0x0c,0x18,0x30,0x48,0x03,0x01,0x04,0x05,0x04,0x00,0x01,
+ 0x00,0x00,0x07,0x06,0x45,0x47,0x20,0x01,0x0b,0x14,0x2a,0x01,0x04,0x32,0x04,0x12,
+ 0x24,0x60,0x6c,0x30,0x18,0x01,0x00,0x00,0x0f,0xac,0x02,0x02,0x00,0x00,0x0f,0xac,
+ 0x02,0x00,0x0f,0xac,0x04,0x01,0x00,0x00,0x0f,0xac,0x02,0x00,0x00,0xdd,0x1c,0x00,
+ 0x50,0xf2,0x01,0x01,0x00,0x00,0x50,0xf2,0x02,0x02,0x00,0x00,0x50,0xf2,0x04,0x00,
+ 0x50,0xf2,0x02,0x01,0x00,0x00,0x50,0xf2,0x02,0x00,0x00,0xf0,0xa1,0x1e,0x32};
+
+
+/* wepbeacon */
+
+char wepbeacon[] = {0x80,0x00 ,0x00 ,0x00 ,0xff ,0xff ,0xff ,0xff,
+ 0xff ,0xff ,0x1c ,0x7e ,0xe5 ,0x49 ,0x76 ,0x31 ,0x1c ,0x7e ,0xe5 ,0x49 ,0x76 ,0x31 ,0x60 ,0x85 ,
+ 0x80 ,0x7d ,0xd4 ,0x0c ,0x00 ,0x00 ,0x00 ,0x00 ,0x64 ,0x00 ,0x31 ,0x04 ,0x00 ,0x05 ,0x6e ,0x77 ,
+ 0x69 ,0x66 ,0x69 ,0x01 ,0x08 ,0x82 ,0x84 ,0x8b ,0x96 ,0x0c ,0x12 ,0x18 ,0x24 ,0x03 ,0x01 ,0x0b ,
+ 0x05 ,0x04 ,0x62 ,0x64 ,0x00 ,0x00 ,0x2a ,0x01 ,0x00 ,0x32 ,0x04 ,0x30 ,0x48 ,0x60 ,0x6c ,0xdd ,
+ 0x18 ,0x00 ,0x50 ,0xf2 ,0x02 ,0x01 ,0x01 ,0x84 ,0x00 ,0x03 ,0xa4 ,0x00 ,0x00 ,0x27 ,0xa4 ,0x00 ,
+ 0x00 ,0x42 ,0x43 ,0x5e ,0x00 ,0x62 ,0x32 ,0x2f ,0x00 ,0xdd ,0x09 ,0x00 ,0x03 ,0x7f ,0x01 ,0x01 ,
+ 0x00 ,0x00 ,0xff ,0x7f ,0xdd ,0x0a ,0x00 ,0x03 ,0x7f ,0x04 ,0x01 ,0x00 ,0x00 ,0x00 ,0x40 ,0x00 ,
+ 0xdd ,0x27 ,0x00 ,0x50 ,0xf2 ,0x04 ,0x10 ,0x4a ,0x00 ,0x01 ,0x10 ,0x10 ,0x44 ,0x00 ,0x01 ,0x02 ,
+ 0x10 ,0x47 ,0x00 ,0x10 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x00 ,0x00 ,0x1c ,0x7e ,
+ 0xe5 ,0x49 ,0x76 ,0x31 ,0x10 ,0x3c ,0x00 ,0x01 ,0x03 ,0xdd ,0x05 ,0x00 ,0x50 ,0xf2 ,0x05, 0x00,
+ 0xb2, 0x98, 0xd4, 0x6a};
+
+/* msa1 */
+
+/*
+char msa1[] = {0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x16, 0xb6, 0x19, 0x89, 0xde,
+ 0x00, 0x16, 0xb6, 0x19, 0x89, 0xde, 0x00, 0x00, 0xf8, 0xf1, 0xd5, 0xe7, 0x01, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x11, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x82, 0x84, 0x8b,
+ 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01, 0x05, 0x05, 0x04, 0x00, 0x01, 0x00, 0x04, 0x2a, 0x01,
+ 0x04, 0x2f, 0x01, 0x04, 0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f,
+ 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00, 0x32, 0x04, 0x0c, 0x12, 0x18, 0x60,
+ 0xdd, 0x06, 0x00, 0x10, 0x18, 0x02, 0x03, 0x00};
+*/
+
+/* msa2 */
+
+char msa2[] = {0x50, 0x00, 0x3a, 0x01, 0x00, 0x19, 0x7d, 0x1b, 0x03, 0xfa, 0x00, 0x1a, 0x70, 0xfc, 0xc0, 0x6f,
+ 0x00, 0x1a, 0x70, 0xfc, 0xc0, 0x6f, 0x10, 0x00, 0x7e, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x01, 0x04, 0x00, 0x0a, 0x62, 0x6f, 0x6f, 0x6e, 0x64, 0x6f, 0x67, 0x67, 0x6c, 0x65,
+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01, 0x0b, 0x2a, 0x01, 0x00,
+ 0x2f, 0x01, 0x00, 0x32, 0x04, 0x0c, 0x12, 0x18, 0x60, 0xdd, 0x06, 0x00, 0x10, 0x18, 0x02, 0x00,
+ 0x04};
+
+
+
+#define BEACON_TEST_RSSI 19
+void send_network_info_to_host(UWORD8 *msa, UWORD16 rx_len, signed char rssi);
+void send_scan_complete_to_host(UWORD8 scan_done);
+int gScanInProgress = 0;
+
+static void SendScanResult(void* pvUsrArg)
+{
+
+ while(1)
+ {
+ NMI_SemaphoreAcquire(&SemHandleScanReq,NMI_NULL);
+ if(bscan_code==NMI_TRUE)
+ {
+ NMI_Sleep(100);//100, 700, 2000
+
+ //send_network_info_to_host(aBeacon,BEACON_TEST_LENGTH,BEACON_TEST_RSSI);
+ /* TODO: Mostafa: uncomment the line: rx_len -= FCS_LEN; in the API send_network_info_to_host()
+ if its input argument rx_len includes FCS */
+ send_network_info_to_host(wepbeacon, sizeof(wepbeacon), BEACON_TEST_RSSI);
+
+ NMI_Sleep(100);
+
+ //send_network_info_to_host(aBeacon,BEACON_TEST_LENGTH,BEACON_TEST_RSSI);
+ /* TODO: Mostafa: uncomment the line: rx_len -= FCS_LEN; in the API send_network_info_to_host()
+ if its input argument rx_len includes FCS */
+ send_network_info_to_host(msa2, sizeof(msa2), BEACON_TEST_RSSI);
+
+
+ NMI_Sleep(100);
+
+ //send_network_info_to_host(aBeacon,BEACON_TEST_LENGTH,BEACON_TEST_RSSI);
+ /* TODO: Mostafa: uncomment the line: rx_len -= FCS_LEN; in the API send_network_info_to_host()
+ if its input argument rx_len includes FCS */
+ send_network_info_to_host(aBeacon, sizeof(aBeacon), BEACON_TEST_RSSI);
+ gScanInProgress = 0;
+ send_scan_complete_to_host(NMI_TRUE);
+ }
+ else
+ {
+ NMI_SemaphoreRelease(&SemHandleScanExit,NMI_NULL);
+ break;
+ }
+
+ }
+
+
+}
+
+INLINE void set_start_scan_req(UWORD8 val)
+{
+ PRINT_INFO(CORECONFIG_DBG,"Scan Started \n");
+ if(gScanInProgress)
+ {
+ return;
+ }
+
+ gScanInProgress = 1;
+
+ bscan_code = NMI_TRUE;
+ NMI_SemaphoreRelease(&SemHandleScanReq,NMI_NULL);
+
+}
+
+INLINE UWORD8 get_start_scan_req(void)
+{
+ return 0;
+}
+
+INLINE void set_join_req(UWORD8 val)
+{
+ g_connected_bssIdx = val;
+ PRINT_INFO(CORECONFIG_DBG,"Connected to Network with Bss Idx %d \n", g_connected_bssIdx);
+
+ g_current_mac_status = MAC_CONNECTED;
+}
+
+/*BugID_4124*/
+/*Setter function for the new WID WID_JOIN_REQ_EXTENDED*/
+/*function should copy the given desired AP parameters{SSID, Ch num and BSSID} to */
+/*the MIB database and to the desired AP global variables */
+/* No getter function implemented*/
+INLINE void set_join_req_ext(UWORD8* pu8JoinReq)
+{
+ tstrWidJoinReqExt* pstrWidJoinReqExt = (tstrWidJoinReqExt*)pu8JoinReq;
+
+ PRINT_INFO(CORECONFIG_DBG,"[Core Simulator]Connected to Network with SSID: %s,BSSID: %2x%2x%2x%2x%2x%2x,channel: %d \n",
+ pstrWidJoinReqExt->SSID,
+ pstrWidJoinReqExt->BSSID[0],
+ pstrWidJoinReqExt->BSSID[1],
+ pstrWidJoinReqExt->BSSID[2],
+ pstrWidJoinReqExt->BSSID[3],
+ pstrWidJoinReqExt->BSSID[4],
+ pstrWidJoinReqExt->BSSID[5],
+ pstrWidJoinReqExt->u8channel);
+
+ g_current_mac_status = MAC_CONNECTED;
+}
+
+/*BugID_3736*/
+/*Setter function for the New WID_SCAN_CHANNEL_LIST*/
+/*function should copy given list to the g_host_scan_channel_list */
+/* setter function should also 'or' CHANNEL_LIST_SCAN with the */
+/* global variable g_scan_source*/
+
+/*first byte of the message should contain num of channels*/
+/* then the channels list*/
+INLINE void set_scan_channel_list(UWORD8* chList)
+{
+ UWORD16 u16ChnlListLen = chList[0];
+
+ #ifdef IBSS_BSS_STATION_MODE
+ /*host channel List to be scanned after checking CHANNEL_LIST_SCAN*/
+ /*in the g_scan_source*/
+
+ memcpy(g_host_scan_channel_list,chList, u16ChnlListLen+2);
+
+ //g_scan_source |= CHANNEL_LIST_SCAN;
+
+ #else
+ return ;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+/*BugID_3736*/
+/* Getter Function for New WID_SCAN_CHANNEL_LIST*/
+/* this function should return the scan_channel list set*/
+/* previusly from the host interface*/
+/* first byte of the returned message contains the num of channels*/
+INLINE UWORD8* get_scan_channel_list(void)
+{
+ #ifdef IBSS_BSS_STATION_MODE
+
+ return g_host_scan_channel_list;
+ #else
+ return 0;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+/*BugID_3746*/
+/*Setter function for the New WID_INFO_ELEMENT_PROBE*/
+INLINE void set_info_element_probe(UWORD8* IEprobeReq)
+{
+ NMI_Uint16 u16WidLen;
+ NMI_Uint32 i;
+
+ //NMI_PRINTF("[Core_Simulator] IEprobeReq[0] = %02x \n", IEprobeReq[0]);
+ //NMI_PRINTF("[Core_Simulator] IEprobeReq[1] = %02x \n", IEprobeReq[1]);
+
+ u16WidLen = MAKE_WORD16(IEprobeReq[0], IEprobeReq[1]);
+
+ PRINT_INFO(CORECONFIG_DBG,"WidLen of Probe Req IE is %d \n", u16WidLen);
+
+ /*
+ for(i = 0; i < u16WidLen; i++)
+ {
+ NMI_PRINTF("IEprobeReq[%d] = %02x \n", 2+i, IEprobeReq[2+i]);
+ }
+ */
+ #ifdef IBSS_BSS_STATION_MODE
+ NMI_Uint16 u16WidLen;
+
+ u16WidLen = MAKE_WORD16(IEprobeReq[0], IEprobeReq[1]);
+
+ PRINT_INFO(CORECONFIG_DBG,"WidLen of Probe Req IE is %d \n", u16WidLen);
+
+
+
+ #else
+ return;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+
+/*BugID_3746*/
+/* Getter Function for New WID_INFO_ELEMENT_PROBE*/
+INLINE UWORD8* get_info_element_probe(void)
+{
+ #ifdef IBSS_BSS_STATION_MODE
+
+ //return g_host_scan_channel_list;
+ #else
+ return 0;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+/*BugID_3746*/
+/*Setter function for the New WID_INFO_ELEMENT_ASSOCIATE*/
+INLINE void set_info_element_associate(UWORD8* IEAssocReq)
+{
+ NMI_Uint16 u16WidLen;
+ NMI_Uint32 i;
+
+ //NMI_PRINTF("[Core_Simulator] IEAssocReq[0] = %02x \n", IEAssocReq[0]);
+ //PRINT_INFO(CORECONFIG_DBG,"[Core_Simulator] IEAssocReq[1] = %02x \n", IEAssocReq[1]);
+
+ u16WidLen = MAKE_WORD16(IEAssocReq[0], IEAssocReq[1]);
+
+ PRINT_INFO(CORECONFIG_DBG,"WidLen of Assoc Req IE is %d \n", u16WidLen);
+
+ /*
+ for(i = 0; i < u16WidLen; i++)
+ {
+ NMI_PRINTF("IEAssocReq[%d] = %02x \n", 2+i, IEAssocReq[2+i]);
+ }
+ */
+
+ #ifdef IBSS_BSS_STATION_MODE
+ NMI_Uint16 u16WidLen;
+
+ u16WidLen = MAKE_WORD16(IEAssocReq[0], IEAssocReq[1]);
+
+ PRINT_INFO(CORECONFIG_DBG,"WidLen of Assoc Req IE is %d \n", u16WidLen);
+
+
+
+ #else
+ return;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+
+/*BugID_3746*/
+/* Getter Function for New WID_INFO_ELEMENT_ASSOCIATE*/
+INLINE UWORD8* get_info_element_associate(void)
+{
+ #ifdef IBSS_BSS_STATION_MODE
+
+ //return g_host_scan_channel_list;
+ #else
+ return 0;
+ #endif /* IBSS_BSS_STATION_MODE */
+}
+
+
+UWORD8 au8CurrentSsid[30]={0};
+
+INLINE void mset_DesiredSSID(UWORD8* ps8DesiredSsid)
+{
+ NMI_memcpy(au8CurrentSsid,ps8DesiredSsid,NMI_strlen(ps8DesiredSsid)+1);
+}
+INLINE UWORD8* get_DesiredSSID(void)
+{
+ return au8CurrentSsid;
+}
+
+INLINE void set_manufacturer() {}
+INLINE void set_model_name() {}
+INLINE void set_model_num() {}
+INLINE void set_device_name() {}
+
+
+UWORD8 au8Manufacturer[20];
+INLINE UWORD8* get_manufacturer()
+{
+ UWORD8 temp[]= "NMIEDC";
+ au8Manufacturer[0] = (NMI_Uint8)NMI_strlen(temp);
+ //au8Manufacturer[1] = '\0';
+ //strcat(au8Manufacturer,temp);
+ NMI_memcpy(&au8Manufacturer[1],temp,NMI_strlen(temp));
+
+
+ return au8Manufacturer;
+}
+
+UWORD8 au8ModelName[5] = {0x03,'P','2','P'};
+INLINE UWORD8* get_model_name()
+{
+ return au8ModelName;
+}
+UWORD8 au8ModelNum[] = {0x02,'1','1'};
+INLINE UWORD8* get_model_num()
+{
+ return au8ModelNum;
+}
+UWORD8 au8DeviceName[] = {0x09,'\0'};
+INLINE UWORD8* get_device_name()
+{
+ NMI_Sint8 temp[] = "NMIDirect";
+ NMI_memcpy(au8DeviceName+1,temp,NMI_strlen(temp));
+ return au8DeviceName;
+}
+/* Host WLAN Identifier Structure */
+/* ID, Type, Response, Reset, Get Function Pointer, Set Function Pointer */
+#if 1
+host_wid_struct_t g_char_wid_struct[NUM_CHAR_WID]=
+{
+ {WID_BSS_TYPE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_DesiredBSSType, (void *)set_DesiredBSSType},
+
+ {WID_CURRENT_TX_RATE, /*WID_CHAR,*/
+#ifdef MAC_HW_UNIT_TEST_MODE
+ BTRUE, BTRUE,
+#else /* MAC_HW_UNIT_TEST_MODE */
+ BTRUE, BFALSE,
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ (void *)get_tx_rate, (void *)set_tx_rate},
+
+ {WID_CURRENT_CHANNEL, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_host_chnl_num, (void *)set_mac_chnl_num},
+
+ {WID_PREAMBLE, /*WID_CHAR,*/
+#ifndef MAC_HW_UNIT_TEST_MODE
+ BTRUE, BFALSE,
+#else /* MAC_HW_UNIT_TEST_MODE */
+ BTRUE, BTRUE,
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ (void *)get_preamble_type, (void *)set_preamble_type},
+
+ {WID_11G_OPERATING_MODE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_running_mode, (void *)set_running_mode},
+
+ {WID_STATUS, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ 0, 0},
+#if 0
+ {WID_11G_PROT_MECH, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_protection_mode, (void *)set_protection_mode},
+#endif
+
+#ifdef MAC_HW_UNIT_TEST_MODE
+ {WID_GOTO_SLEEP, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_machw_sleep},
+#else /* MAC_HW_UNIT_TEST_MODE */
+ {WID_SCAN_TYPE, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)mget_scan_type, (void *)mset_scan_type},
+#endif /* MAC_HW_UNIT_TEST_MODE */
+#if 0
+ {WID_PRIVACY_INVOKED, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)mget_PrivacyInvoked, (void *)0},
+#endif
+ {WID_KEY_ID, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)mget_WEPDefaultKeyID, (void *)mset_WEPDefaultKeyID},
+
+ {WID_QOS_ENABLE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_qos_enable, (void *)set_qos_enable},
+
+ {WID_POWER_MANAGEMENT, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_PowerManagementMode, (void *)set_PowerManagementMode},
+#if 0
+ {WID_802_11I_MODE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_802_11I_mode, (void *)set_802_11I_mode},
+#endif
+ {WID_AUTH_TYPE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_auth_type, (void *)set_auth_type},
+
+ {WID_SITE_SURVEY, /*WID_CHAR,*/
+ BTRUE, BFALSE,
+ (void *)get_site_survey_status, (void *)set_site_survey},
+
+ {WID_LISTEN_INTERVAL, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)mget_listen_interval, (void *)mset_listen_interval},
+
+ {WID_DTIM_PERIOD, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)mget_DTIMPeriod, (void *)set_dtim_period},
+
+ {WID_ACK_POLICY, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_ack_type, (void *)set_ack_type},
+
+ {WID_RESET, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_reset_req},
+#if 0
+ {WID_PCF_MODE, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)get_pcf_mode, (void *)set_pcf_mode},
+
+ {WID_CFP_PERIOD, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)mget_CFPPeriod, (void *)mset_CFPPeriod},
+
+ {WID_BCAST_SSID, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_bcst_ssid, (void *)set_bcst_ssid},
+#endif
+#ifdef MAC_HW_UNIT_TEST_MODE
+ {WID_PHY_TEST_PATTERN, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)get_phy_test_pattern, (void *)set_phy_test_pattern},
+#else /* MAC_HW_UNIT_TEST_MODE */
+ {WID_DISCONNECT, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)disconnect_station},
+#endif /* MAC_HW_UNIT_TEST_MODE */
+#if 0
+ {WID_READ_ADDR_SDRAM , /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)get_read_addr_sdram, (void *)set_read_addr_sdram},
+#endif
+ {WID_TX_POWER_LEVEL_11A, /*WID_CHAR,*/
+ BTRUE, BFALSE,
+ (void *)get_tx_power_level_11a, (void *)set_tx_power_level_11a},
+
+ {WID_REKEY_POLICY, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_RSNAConfigGroupRekeyMethod, (void *)set_RSNAConfigGroupRekeyMethod},
+
+ {WID_SHORT_SLOT_ALLOWED, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_short_slot_allowed, (void *)set_short_slot_allowed},
+
+ {WID_PHY_ACTIVE_REG, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_phy_active_reg, (void *)set_phy_active_reg},
+#if 0
+ {WID_PHY_ACTIVE_REG_VAL, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_phy_active_reg_val, (void *)set_phy_active_reg_val},
+#endif
+ {WID_TX_POWER_LEVEL_11B, /*WID_CHAR,*/
+ BTRUE, BFALSE,
+ (void *)get_tx_power_level_11b, (void *)set_tx_power_level_11b},
+
+ {WID_START_SCAN_REQ, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_start_scan_req, (void *)set_start_scan_req},
+
+ {WID_RSSI, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_rssi, (void *)0},
+
+ {WID_JOIN_REQ, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)0, (void *)set_join_req},
+#if 0
+ {WID_ANTENNA_SELECTION, /*WID_CHAR,*/
+ BTRUE, BFALSE,
+ (void *)get_antenna_selection, (void *)set_antenna_selection},
+#endif
+
+ {WID_USER_CONTROL_ON_TX_POWER, /*WID_CHAR,*/
+ BTRUE, BFALSE,
+ (void *)get_user_control_enabled, (void *)set_user_control_enabled},
+
+ {WID_MEMORY_ACCESS_8BIT, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_memory_access_8bit, (void *)set_memory_access_8bit},
+#if 0
+ {WID_CURRENT_MAC_STATUS, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_current_mac_status, (void *)0},
+#endif
+ {WID_AUTO_RX_SENSITIVITY, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_auto_rx_sensitivity, (void *)set_auto_rx_sensitivity},
+
+ {WID_DATAFLOW_CONTROL, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_dataflow_control, (void *)set_dataflow_control},
+
+ {WID_SCAN_FILTER, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_scan_filter, (void *)set_scan_filter},
+
+ {WID_LINK_LOSS_THRESHOLD, /*WID_CHAR,*/
+ BFALSE, BFALSE,
+ (void *)get_link_loss_threshold, (void *)set_link_loss_threshold},
+#if 0
+ {WID_AUTORATE_TYPE, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)get_autorate_type, (void *)set_autorate_type},
+#endif
+ {WID_CCA_THRESHOLD, /*WID_CHAR,*/
+ BFALSE, BTRUE,
+ (void *)get_cca_threshold, (void *)set_cca_threshold},
+
+#if 0
+ {WID_UAPSD_SUPPORT_AP, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_uapsd_support_ap, (void *)set_uapsd_support_ap},
+
+ /* dot11H parameters */
+ {WID_802_11H_DFS_MODE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_802_11H_DFS_mode, (void *)set_802_11H_DFS_mode},
+
+ {WID_802_11H_TPC_MODE, /*WID_CHAR,*/
+ BTRUE, BTRUE,
+ (void *)get_802_11H_TPC_mode, (void *)set_802_11H_TPC_mode},
+#endif
+};
+#endif
+const host_wid_struct_t g_short_wid_struct[NUM_SHORT_WID];
+#if 0
+=
+{
+ {WID_RTS_THRESHOLD, /*WID_SHORT,*/
+ BTRUE, BFALSE,
+ (void *)mget_RTSThreshold, (void *)set_RTSThreshold},
+
+ {WID_FRAG_THRESHOLD, /*WID_SHORT,*/
+ BTRUE, BFALSE,
+ (void *)mget_FragmentationThreshold, (void *)set_FragmentationThreshold},
+
+ {WID_SHORT_RETRY_LIMIT, /*WID_SHORT,*/
+ BTRUE, BFALSE,
+ (void *)mget_ShortRetryLimit, (void *)set_ShortRetryLimit},
+
+ {WID_LONG_RETRY_LIMIT, /*WID_SHORT,*/
+ BTRUE, BFALSE,
+ (void *)mget_LongRetryLimit, (void *)set_LongRetryLimit},
+
+ {WID_CFP_MAX_DUR, /*WID_SHORT,*/
+ BFALSE, BTRUE,
+ (void *)mget_CFPMaxDuration, (void *)mset_CFPMaxDuration},
+
+ {WID_PHY_TEST_FRAME_LEN, /*WID_SHORT,*/
+ BFALSE, BTRUE,
+ (void *)get_phy_test_frame_len, (void *)set_phy_test_frame_len},
+
+ {WID_BEACON_INTERVAL, /*WID_SHORT,*/
+ BTRUE, BTRUE,
+ (void *)mget_BeaconPeriod, (void *)mset_BeaconPeriod},
+
+
+
+ {WID_MEMORY_ACCESS_16BIT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_memory_access_16bit, (void *)set_memory_access_16bit},
+
+ {WID_RX_SENSE, /*WID_SHORT,*/
+ BFALSE, BTRUE,
+ (void *)get_rx_sense, (void *)set_rx_sense},
+
+ {WID_ACTIVE_SCAN_TIME, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_active_scan_time, (void *)set_active_scan_time},
+
+ {WID_PASSIVE_SCAN_TIME, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_passive_scan_time, (void *)set_passive_scan_time},
+
+ {WID_SITE_SURVEY_SCAN_TIME, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_site_survey_scan_time, (void *)set_site_survey_scan_time},
+
+ {WID_JOIN_TIMEOUT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_join_timeout, (void *)set_join_timeout},
+
+ {WID_AUTH_TIMEOUT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_auth_timeout, (void *)set_auth_timeout},
+
+ {WID_ASOC_TIMEOUT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_asoc_timeout, (void *)set_asoc_timeout},
+
+ {WID_11I_PROTOCOL_TIMEOUT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_11i_protocol_timeout, (void *)set_11i_protocol_timeout},
+
+ {WID_EAPOL_RESPONSE_TIMEOUT, /*WID_SHORT,*/
+ BFALSE, BFALSE,
+ (void *)get_eapol_response_timeout, (void *)set_eapol_response_timeout},
+};
+#endif
+const host_wid_struct_t g_int_wid_struct[NUM_INT_WID];
+#if 0
+=
+{
+
+ {WID_FAILED_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_FailedCount, (void *)set_FailedCount_to_zero},
+
+ {WID_RETRY_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_RetryCount, (void *)set_RetryCount_to_zero},
+
+ {WID_MULTIPLE_RETRY_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_MultipleRetryCount, (void *)set_MultipleRetryCount_to_zero},
+
+ {WID_FRAME_DUPLICATE_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_FrameDuplicateCount, (void *)set_FrameDuplicateCount_to_zero},
+
+ {WID_ACK_FAILURE_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_ACKFailureCount, (void *)set_ACKFailureCount_to_zero},
+
+ {WID_RECEIVED_FRAGMENT_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_ReceivedFragmentCount, (void *)set_ReceivedFragmentCount_to_zero},
+
+ {WID_MULTICAST_RECEIVED_FRAME_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_MulticastReceivedFrameCount, (void *)set_MulticastReceivedFrameCount_to_zero},
+
+ {WID_FCS_ERROR_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_FCSErrorCount, (void *)set_FCSErrorCount_to_zero},
+
+ {WID_SUCCESS_FRAME_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_TransmittedFrameCount, (void *)set_TransmittedFrameCount_to_zero},
+
+ {WID_PHY_TEST_PKT_CNT, /*WID_INT,*/
+ BFALSE, BTRUE,
+ (void *)get_phy_test_pkt_cnt, (void *)set_phy_test_pkt_cnt},
+
+ {WID_PHY_TEST_TXD_PKT_CNT, /*WID_INT,*/
+
+ BFALSE, BTRUE,
+ (void *)get_phy_test_txd_pkt_cnt, (void *)set_phy_test_txd_pkt_cnt},
+
+ {WID_TX_FRAGMENT_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_TransmittedFragmentCount, (void *)0},
+
+ {WID_TX_MULTICAST_FRAME_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_MulticastTransmittedFrameCount, (void *)0},
+
+ {WID_RTS_SUCCESS_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_RTSSuccessCount, (void *)0},
+
+ {WID_RTS_FAILURE_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_RTSFailureCount, (void *)0},
+
+ {WID_WEP_UNDECRYPTABLE_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)mget_WEPICVErrorCount, (void *)0},
+
+ {WID_REKEY_PERIOD, /*WID_INT,*/
+ BTRUE, BTRUE,
+ (void *)get_RSNAConfigGroupRekeyTime , (void *)set_RSNAConfigGroupRekeyTime},
+
+ {WID_REKEY_PACKET_COUNT, /*WID_INT,*/
+ BTRUE, BTRUE,
+ (void *)get_RSNAConfigGroupRekeyPackets, (void *)set_RSNAConfigGroupRekeyPackets},
+
+#ifdef MAC_HW_UNIT_TEST_MODE
+ {WID_Q_ENABLE_INFO, /*WID_INT,*/
+ BTRUE, BTRUE,
+ (void *)get_q_enable_info, (void *)set_q_enable_info},
+#else /* MAC_HW_UNIT_TEST_MODE */
+ {WID_802_1X_SERV_ADDR, /*WID_INT,*/
+ BTRUE, BTRUE,
+ (void *)get_1x_serv_addr, (void *)set_1x_serv_addr},
+#endif /* MAC_HW_UNIT_TEST_MODE */
+
+ {WID_STACK_IP_ADDR, /*WID_INT,*/
+ BTRUE, BFALSE,
+ (void *)get_stack_ip_addr, (void *)set_stack_ip_addr},
+
+ {WID_STACK_NETMASK_ADDR, /*WID_INT,*/
+ BTRUE, BFALSE,
+ (void *)get_stack_netmask_addr, (void *)set_stack_netmask_addr},
+
+ {WID_HW_RX_COUNT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)get_machw_rx_end_count, (void *)0},
+
+ {WID_RF_REG_VAL, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_rf_reg_val},
+
+ {WID_MEMORY_ADDRESS, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)get_memory_address, (void *)set_memory_address},
+
+
+ {WID_MEMORY_ACCESS_32BIT, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)get_memory_access_32bit, (void *)set_memory_access_32bit},
+
+ {WID_FIRMWARE_INFO, /*WID_INT,*/
+ BFALSE, BFALSE,
+ (void *)get_firmware_info, (void *)0},
+
+};
+#endif
+
+const host_wid_struct_t g_str_wid_struct[NUM_STR_WID]=
+{
+ /*BugID_3736*/
+ /*New WID Added to set a channel list*/
+ /*the input message should have the length of channel list in the fist */
+ /* byte and then the channels list*/
+ /*setter function should copy given list to the g_host_scan_channel_list */
+ /* setter function should also 'or' CHANNEL_LIST_SCAN with the */
+ /* global variable g_scan_source in order to handle both cases exiting way*/
+ /* of channel scanning and this new way*/
+ {WID_SCAN_CHANNEL_LIST, /* WID_STR, */
+ BFALSE, BFALSE,
+ (void *)get_scan_channel_list, (void *)set_scan_channel_list},
+
+ {WID_MAC_ADDR, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_mac_addr, (void *)set_mac_addr},
+
+
+ {WID_SSID, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_DesiredSSID, (void *)mset_DesiredSSID},
+
+
+ {WID_FIRMWARE_VERSION, /*WID_STR,*/
+ BTRUE, BFALSE,
+#ifdef DEBUG_MODE
+ (void *)get_manufacturerProductVersion, (void *)set_test_case_name},
+#else /* DEBUG_MODE */
+ (void *)get_manufacturerProductVersion, 0},
+#endif /* DEBUG_MODE */
+
+#if 0
+ {WID_OPERATIONAL_RATE_SET, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_supp_rates, 0},
+#endif
+ {WID_BSSID, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_bssid, (void *)set_preferred_bssid},
+#if 0
+
+ {WID_WEP_KEY_VALUE0, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_WEP_key, (void *)set_WEP_key},
+
+ {WID_WEP_KEY_VALUE1, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_WEP_key, (void *)set_WEP_key},
+
+ {WID_WEP_KEY_VALUE2, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_WEP_key, (void *)set_WEP_key},
+
+ {WID_WEP_KEY_VALUE3, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_WEP_key, (void *)set_WEP_key},
+#endif
+ {WID_11I_PSK, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_RSNAConfigPSKPassPhrase, (void *)set_RSNAConfigPSKPassPhrase},
+#if 0
+ {WID_HCCA_ACTION_REQ, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_action_request},
+
+ {WID_802_1X_KEY, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_1x_key, (void *)set_1x_key},
+
+ {WID_HARDWARE_VERSION, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_hardwareProductVersion, 0},
+#endif
+ {WID_MAC_ADDR, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_mac_addr, (void *)set_mac_addr},
+#if 0
+
+ {WID_PHY_TEST_DEST_ADDR, /*WID_STR,*/
+ BFALSE, BTRUE,
+ (void *)get_phy_test_dst_addr, (void *)set_phy_test_dst_addr},
+
+ {WID_PHY_TEST_STATS, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void *)get_phy_test_stats, (void *)set_phy_test_stats},
+
+ {WID_PHY_VERSION, /*WID_STR,*/
+ BTRUE, BFALSE,
+ (void *)get_phyProductVersion, 0},
+
+ {WID_SUPP_USERNAME, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_supp_username, (void *)set_supp_username},
+
+ {WID_SUPP_PASSWORD, /*WID_STR,*/
+ BTRUE, BTRUE,
+ (void *)get_supp_password, (void *)set_supp_password},
+#endif
+ {WID_SITE_SURVEY_RESULTS, /*WID_STR,*/ // TODO: mostafa: I'm not sure if WID_all flag is correct to be BTRUE,
+ // and also not sure of reset_mac flag to be BFALSE
+ BFALSE, BFALSE,
+ (void *)get_site_survey_results, (void *)0},
+
+ {WID_ADD_WEP_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_wep_key},
+
+ {WID_PMKID_INFO, /* WID_STR, */
+ BFALSE, BFALSE,
+ (void *)get_pmkid_info, (void *)set_pmkid_info},
+#if 0
+ {WID_RX_POWER_LEVEL, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void *)get_rx_power_level, (void *)0},
+
+#endif
+
+#ifdef IBSS_BSS_STATION_MODE
+ #if 0
+ {WID_ADD_WEP_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)add_wep_key_sta},
+
+ {WID_REMOVE_WEP_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)remove_wep_key_sta},
+
+ {WID_ADD_PTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)add_ptk_sta},
+
+ {WID_ADD_RX_GTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)add_rx_gtk_sta},
+
+ {WID_ADD_TX_GTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)add_tx_gtk},
+
+ {WID_REMOVE_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)remove_key_sta},
+
+ {WID_ASSOC_REQ_INFO,
+ BFALSE, BFALSE,
+ (void *)get_assoc_req_info, (void *)0},
+
+ {WID_ASSOC_RES_INFO,
+ BFALSE, BFALSE,
+ (void *)get_assoc_res_info, (void *)0},
+ #endif
+#else /* IBSS_BSS_STATION_MODE */
+ #if 0
+ {WID_REMOVE_WEP_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+
+ {WID_ADD_PTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+
+ {WID_ADD_RX_GTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+
+ {WID_ADD_TX_GTK,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+
+ {WID_REMOVE_KEY,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+
+ {WID_ASSOC_REQ_INFO,
+ BFALSE, BFALSE,
+ (void *)0, (void *)0},
+ #endif
+
+ {WID_ASSOC_RES_INFO,
+ BFALSE, BFALSE,
+ (void *)get_assoc_res_info, (void *)0},
+
+#endif /* IBSS_BSS_STATION_MODE */
+#if 0
+ {WID_UPDATE_RF_SUPPORTED_INFO,
+ BFALSE, BTRUE,
+ (void *)get_rf_supported_info, (void *)set_rf_supported_info},
+
+ {WID_COUNTRY_IE, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)get_country_ie, (void *)set_country_ie},
+#endif
+ {WID_MANUFACTURER, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void*) get_manufacturer, (void*)set_manufacturer},
+
+ {WID_MODEL_NAME, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void*)get_model_name, (void*) set_model_name},
+
+ {WID_MODEL_NUM, /*WID_STR,*/
+ BFALSE, BFALSE,
+ (void*)get_model_num, (void*)set_model_num},
+
+ {WID_DEVICE_NAME, /*WID_STR*/
+ BFALSE, BFALSE,
+ (void*) get_device_name, (void*) set_device_name},
+
+ /*BugID_4124*/
+ /*New WID Added to trigger modified Join Request using SSID, BSSID and channel num */
+ /*of the required AP instead of using bssListIdx (used by WID_JOIN_REQ)*/
+ /*The input message should have in the first 32 bytes the SSID, then the following byte */
+ /* should have the channel number and finally the following 6 bytes should have the BSSID*/
+ /*setter function should copy the given desired AP parameters{SSID, Ch num and BSSID} to */
+ /*the MIB database and to the desired AP global variables */
+ /* No getter function implemented*/
+ {WID_JOIN_REQ_EXTENDED, /* WID_STR, */
+ BFALSE, BTRUE,
+ (void *)0, (void *)set_join_req_ext}
+};
+
+const host_wid_struct_t g_binary_data_wid_struct[NUM_BIN_DATA_WID]
+=
+{
+#if 0
+ {WID_CONFIG_HCCA_ACTION_REQ, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)0, (void *)set_config_HCCA_actionReq},
+#endif
+
+
+ {WID_UAPSD_CONFIG, /*WID_BIN_DATA,*/
+ BFALSE, BTRUE,
+ (void *)get_uapsd_config, (void *)set_uapsd_config},
+#if 0
+
+
+ {WID_UAPSD_STATUS, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)get_uapsd_status, (void *)0},
+
+ {WID_WMM_AP_AC_PARAMS, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)get_wmm_ap_ac_params, (void *)set_wmm_ap_ac_params},
+
+ {WID_WMM_STA_AC_PARAMS, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)get_wmm_sta_ac_params, (void *)get_wmm_sta_ac_params},
+
+ {WID_CONNECTED_STA_LIST, /*WID_BIN_DATA,*/
+ BFALSE, BFALSE,
+ (void *)get_connected_sta_list, (void *)0},
+
+ {WID_HUT_STATS, /* WID_BIN_DATA, */
+ BFALSE, BFALSE,
+ (void *)get_hut_stats, (void *)set_hut_stats},
+#endif
+
+ /* BugID_3746*/
+ {WID_INFO_ELEMENT_PROBE, /* WID_BIN_DATA, */
+ BFALSE, BTRUE,
+ (void *)get_info_element_probe, (void *)set_info_element_probe},
+ /* BugID_3746*/
+ {WID_INFO_ELEMENT_ASSOCIATE, /* WID_BIN_DATA, */
+ BFALSE, BTRUE,
+ (void *)get_info_element_associate, (void *)set_info_element_associate},
+};
+
+
+
+NMI_Sint32 CoreConfigSimulatorInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_ThreadAttrs strThrdSimulatorAttrs;
+ tstrNMI_SemaphoreAttrs strSemaphoreAttrs;
+
+ PRINT_INFO(CORECONFIG_DBG,"CoreConfigSimulatorInit() \n");
+
+
+ g_current_mac_status = MAC_DISCONNECTED;
+ gbTermntMacStsThrd = NMI_FALSE;
+ g_connected_bssIdx = 0xFFFF;
+ gScanInProgress = 0;
+ gu32ReqSrvyResFrag = 0;
+
+ FIFO_InitBuffer(&ghTxFifoBuffer, MAX_FIFO_BUFF_LEN);
+ NMI_MsgQueueCreate(&gMsgQSimulator, NMI_NULL);
+
+ NMI_SemaphoreFillDefault(&strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+
+ NMI_SemaphoreCreate(&SemHandleScanReq,&strSemaphoreAttrs);
+ NMI_SemaphoreCreate(&SemHandleScanExit, &strSemaphoreAttrs);
+
+ NMI_SemaphoreCreate(&SemHandleMacStsExit, &strSemaphoreAttrs);
+
+
+ NMI_ThreadFillDefault(&strThrdSimulatorAttrs);
+ NMI_ThreadCreate(&ThrdHandleSimulator, SimulatorThread, NMI_NULL, &strThrdSimulatorAttrs);
+ NMI_ThreadCreate(&ThrdHandleScan, SendScanResult, NMI_NULL, &strThrdSimulatorAttrs);
+ NMI_ThreadCreate(&ThrdHandleMacStatus, SendMacStatus, NMI_NULL, &strThrdSimulatorAttrs);
+ return s32Error;
+}
+
+NMI_Sint32 SimConfigPktReceived(NMI_Sint8* pspacket, NMI_Sint32 s32PacketLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Sint32 s32Err = NMI_SUCCESS;
+
+ tstrSimulatorMsg* pstrSimulatorMsg = NMI_NULL;
+
+ pstrSimulatorMsg = (tstrSimulatorMsg*)NMI_MALLOC(sizeof(tstrSimulatorMsg));
+ NMI_memset((void*)(pstrSimulatorMsg), 0, sizeof(tstrSimulatorMsg));
+
+ s32Err = FIFO_WriteBytes(ghTxFifoBuffer, pspacket, s32PacketLen, NMI_TRUE);
+ if(s32Err != NMI_SUCCESS)
+ {
+ NMI_ERROR("SimConfigPktReceived(): FIFO_WriteBytes() returned error \n");
+ s32Error = NMI_FAIL;
+ pstrSimulatorMsg->s32PktDataLen = -1;
+ goto Send_Message;
+ }
+
+ pstrSimulatorMsg->s32PktDataLen = s32PacketLen;
+
+Send_Message:
+ NMI_MsgQueueSend(&gMsgQSimulator, pstrSimulatorMsg, sizeof(tstrSimulatorMsg), NMI_NULL);
+
+ if(pstrSimulatorMsg != NMI_NULL)
+ {
+ NMI_FREE(pstrSimulatorMsg);
+ pstrSimulatorMsg = NMI_NULL;
+ }
+
+ return s32Error;
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_wid_index */
+/* */
+/* Description : This function gets the WID index from WID ID & Type */
+/* */
+/* Inputs : 1) WID Identifier */
+/* 2) WID Type */
+/* */
+/* Globals : 1) g_char_wid_struct */
+/* 2) g_short_wid_struct */
+/* 2) g_int_wid_struct */
+/* 2) g_str_wid_struct */
+/* 2) g_binary_data_wid_struct */
+/* */
+/* Processing : This function searches for the WID ID in the relevent */
+/* global structure to find the index of the perticular WID */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Length of the query response */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+UWORD8 get_wid_index(UWORD16 wid_id,UWORD8 wid_type)
+{
+ UWORD8 count;
+
+ switch(wid_type)
+ {
+ case WID_CHAR:
+ for(count = 0; count < NUM_CHAR_WID; count++)
+ {
+ if(g_char_wid_struct[count].id == wid_id)
+ return count;
+ }
+ break;
+ case WID_SHORT:
+ for(count = 0; count < NUM_SHORT_WID; count++)
+ {
+ if(g_short_wid_struct[count].id == wid_id)
+ return count;
+ }
+ break;
+ case WID_INT:
+ for(count = 0; count < NUM_INT_WID; count++)
+ {
+ if(g_int_wid_struct[count].id == wid_id)
+ return count;
+ }
+ break;
+ case WID_STR:
+ for(count = 0; count < NUM_STR_WID; count++)
+ {
+ if(g_str_wid_struct[count].id == wid_id)
+ return count;
+ }
+ break;
+ case WID_BIN_DATA:
+ for(count = 0; count < NUM_BIN_DATA_WID; count++)
+ {
+ if(g_binary_data_wid_struct[count].id == wid_id)
+ return count;
+ }
+ break;
+ }
+
+ return 0xFF;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_wid */
+/* */
+/* Description : This function gets the WID value from the global WID */
+/* array and updates the response message contents. */
+/* */
+/* Inputs : 1) Pointer to the WID field */
+/* 2) Index of the global WID array */
+/* 3) The WID type */
+/* */
+/* Globals : g_wid_struct */
+/* */
+/* Processing : This function sets the WID ID, Length and Value in the */
+/* the incoming packet. */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Length of WID response */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+UWORD16 get_wid(UWORD8 *wid, UWORD8 count, UWORD8 wid_type)
+{
+ UWORD8 wid_len = 0;
+ UWORD16 wid_id = 0;
+ UWORD8 *wid_val = 0;
+ /* NULL response is corresponded */
+ BOOL_T null_rsp = BFALSE;
+
+ /* The WID is set in the following format: */
+ /* +-------------------------------------------------------------------+ */
+ /* | WID Type | WID Length | WID Value | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 2 Bytes | 1 Byte | WID length | */
+ /* +-------------------------------------------------------------------+ */
+
+ /* Set the WID value with the value returned by the get function */
+ /* associated with the particular WID type. */
+ wid_val = (wid + WID_VALUE_OFFSET);
+
+ /* If the member function is not NULL, get the value, else discard read */
+ switch(wid_type)
+ {
+ case WID_CHAR:
+ {
+ wid_id = g_char_wid_struct[count].id;
+ if(g_char_wid_struct[count].get)
+ {
+ UWORD8 val =
+ ((UWORD8 (*)(void))g_char_wid_struct[count].get)();
+
+ wid_len = 1;
+
+ wid_val[0] = val;
+ }
+ else
+ {
+ wid_len = 0;
+ }
+ }
+ break;
+
+ case WID_SHORT:
+ {
+ wid_id = g_short_wid_struct[count].id;
+ if(g_short_wid_struct[count].get)
+ {
+ UWORD16 val =
+ ((UWORD16 (*)(void))g_short_wid_struct[count].get)();
+
+ wid_len = 2;
+
+ wid_val[0] = (UWORD8)(val & 0x00FF);
+ wid_val[1] = (UWORD8)((val >> 8) & 0x00FF);
+ }
+ else
+ {
+ wid_len = 0;
+ }
+ }
+ break;
+
+ case WID_INT:
+ {
+ wid_id = g_int_wid_struct[count].id;
+ if(g_int_wid_struct[count].get)
+ {
+ UWORD32 val =
+ ((UWORD32 (*)(void))g_int_wid_struct[count].get)();
+
+ wid_len = 4;
+
+ wid_val[0] = (UWORD8)(val & 0x000000FF);
+ wid_val[1] = (UWORD8)((val >> 8) & 0x000000FF);
+ wid_val[2] = (UWORD8)((val >> 16) & 0x000000FF);
+ wid_val[3] = (UWORD8)((val >> 24) & 0x000000FF);
+ }
+ else
+ {
+ wid_len = 0;
+ }
+ }
+ break;
+
+ case WID_STR:
+ {
+ wid_id = g_str_wid_struct[count].id;
+ if(g_str_wid_struct[count].get)
+ {
+ UWORD8 *val =
+ ((UWORD8 *(*)(void))g_str_wid_struct[count].get)();
+
+ if(val != NULL)
+ {
+ wid_len = val[0];
+
+ NMI_memcpy(wid_val, (val + 1), wid_len);
+ }
+ else
+ {
+ /* NULL response is corresponded */
+ null_rsp = BTRUE;
+ wid_len = 0;
+ }
+ }
+ else
+ {
+ wid_len = 0;
+ }
+ }
+ break;
+
+ case WID_BIN_DATA:
+ {
+ /* WID_BIN_DATA is Set in the following format */
+ /* +---------------------------------------------------+ */
+ /* | WID | WID Length | WID Value | Checksum | */
+ /* +---------------------------------------------------+ */
+ /* | 2Bytes | 2Bytes | WID Length Bytes | 1Byte | */
+ /* +---------------------------------------------------+ */
+
+ wid_id = g_binary_data_wid_struct[count].id;
+ if(g_binary_data_wid_struct[count].get)
+ {
+ UWORD16 length = 0;
+ UWORD8 checksum = 0;
+ UWORD16 i = 0;
+ UWORD8 *val =
+ ((UWORD8 *(*)(void))g_binary_data_wid_struct[count].get)();
+
+ if(val == NULL)
+ {
+ return 0;
+ }
+
+ /* First 2 Bytes are length field and rest of the bytes are */
+ /* actual data */
+
+ /* Length field encoding */
+ /* +----------------------------------+ */
+ /* | BIT15 | BIT14 | BIT13 - BIT0 | */
+ /* +----------------------------------+ */
+ /* | First | Last | Message Length | */
+ /* +----------------------------------+ */
+ length = (val[0] & 0x00FF);
+ length |= ((UWORD16) val[1] << 8) & 0xFF00;
+ length &= WID_BIN_DATA_LEN_MASK;
+
+ if(length != 0 )
+ {
+ /* Set the WID type. */
+ wid[0] = wid_id & 0xFF;
+ wid[1] = (wid_id & 0xFF00) >> 8;
+
+ /* Copy the data including the length field */
+ NMI_memcpy((wid + WID_LENGTH_OFFSET), val, (length + 2));
+
+ /* Compute Checksum for the data field & append it at */
+ /* the end of the packet */
+ for(i = 0;i < length;i++)
+ {
+ checksum += val[2 + i];
+ }
+ *(wid + WID_LENGTH_OFFSET + 2 + length) = checksum;
+
+ /* Return the WID response length */
+ /*WID_TYPE WID_Length WID_Value Checksum*/
+ return (WID_LENGTH_OFFSET + 2 + length + 1);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ break;
+ } /* end of switch(wid_len) */
+
+ /* NULL response is corresponded */
+ if((wid_len != 0) || (BTRUE == null_rsp))
+ {
+ /* Set the WID type. The WID length field is set at the end after */
+ /* getting the value of the WID. In case of variable length WIDs the */
+ /* length s known only after the value is obtained. */
+ wid[0] = wid_id & 0xFF;
+ wid[1] = (wid_id & 0xFF00) >> 8;
+
+ /* Set the length of the WID */
+ wid[2] = wid_len;
+
+ /* Return the WID response length */
+ return (wid_len + WID_VALUE_OFFSET);
+ }
+ else
+ {
+ return (0);
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : set_wid */
+/* */
+/* Description : This function sets the WID value with the incoming WID */
+/* value. */
+/* */
+/* Inputs : 1) Pointer to the WID value */
+/* 2) Length of the WID value */
+/* 3) Index of the global WID array */
+/* 4) The WID type */
+/* */
+/* Globals : g_wid_struct */
+/* */
+/* Processing : This function sets the WID Value with the incoming value.*/
+/* */
+/* Outputs : The corresponding MAC parameter is set */
+/* */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void set_wid(UWORD8 *wid, UWORD16 len, UWORD8 count, UWORD8 wid_type)
+{
+ switch(wid_type)
+ {
+ case WID_CHAR:
+ {
+ if(g_char_wid_struct[count].set)
+ {
+ ((void (*)(UWORD8))g_char_wid_struct[count].set)(wid[0]);
+ }
+ else
+ {
+ /* WID cannot be set. Do nothing. */
+ }
+ }
+ break;
+
+ case WID_SHORT:
+ {
+ UWORD16 val = 0;
+
+ val = wid[1];
+ val = (val << 8) | wid[0];
+
+ if(g_short_wid_struct[count].set)
+ {
+ ((void (*)(UWORD16))g_short_wid_struct[count].set)(val);
+ }
+ else
+ {
+ /* WID cannot be set. Do nothing. */
+ }
+ }
+ break;
+
+ case WID_INT:
+ {
+ UWORD32 val = 0;
+
+ val = wid[3];
+ val = (val << 8) | wid[2];
+ val = (val << 8) | wid[1];
+ val = (val << 8) | wid[0];
+
+ if(g_int_wid_struct[count].set)
+ {
+ ((void (*)(UWORD32))g_int_wid_struct[count].set)(val);
+ }
+ else
+ {
+ /* WID cannot be set. Do nothing. */
+ }
+ }
+ break;
+
+ case WID_STR:
+ {
+ UWORD8 val[MAX_STRING_LEN];
+
+ NMI_memcpy(val, wid, len);
+ val[len] = '\0';
+
+ if(g_str_wid_struct[count].set)
+ {
+ ((void (*)(UWORD8*))g_str_wid_struct[count].set)(val);
+ }
+ else
+ {
+ /* WID cannot be set. Do nothing. */
+ }
+ }
+ break;
+
+ case WID_BIN_DATA:
+ {
+ if(g_binary_data_wid_struct[count].set)
+ {
+ ((void (*)(UWORD8*))g_binary_data_wid_struct[count].set)(wid);
+ }
+ else
+ {
+ /* WID cannot be set. Do nothing. */
+ }
+ }
+ break;
+
+ } /* end of switch(wid_type) */
+}
+/* This function copies the MAC address from a source to destination */
+/*
+INLINE void mac_addr_cpy(UWORD8 *dst, UWORD8 *src)
+{
+ UWORD8 i = 0;
+
+ for(i = 0; i < 6; i++)
+ dst[i] = src[i];
+}
+*/
+
+/* This function copies the IP address from a source to destination */
+/*
+INLINE void ip_addr_cpy(UWORD8 *dst, UWORD8 *src)
+{
+ UWORD8 i = 0;
+
+ for(i = 0; i < 4; i++)
+ dst[i] = src[i];
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* Function Name : checksum */
+/* */
+/* Description : This function computes the 16-bit CRC. */
+/* */
+/* Inputs : 1) Pointer to the buffer */
+/* 2) Length of the buffer */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function computes 16-bit CRC for the given packet. */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : 16-bit CRC checksum */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+UWORD16 checksum(UWORD8 *buffer, UWORD32 size)
+{
+ UWORD32 cksum = 0;
+
+ while (size > 1)
+ {
+ cksum += *buffer + (*(buffer+1) << 8);
+ buffer += 2 ;
+ size -= 2;
+ }
+
+ if (size)
+ {
+ cksum += *buffer;
+ }
+
+ cksum = (cksum >> 16) + (cksum & 0xFFFF);
+ cksum += (cksum >> 16);
+
+ return (UWORD16)(~cksum);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : process_query */
+/* */
+/* Description : This function processes the host query message. */
+/* */
+/* Inputs : 1) Pointer to the query request message */
+/* 2) Pointer to the query response message */
+/* 3) Length of the query request */
+/* */
+/* Globals : g_wid_struct */
+/* */
+/* Processing : This function reads the WID value in the Query message */
+/* and gets the corresponding WID length and value. It sets */
+/* the WID, WID Length and value in the response message. */
+/* The process is repeated for all the WID types requested */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Length of the query response */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+UWORD16 process_query(UWORD8* wid_req, UWORD8* wid_rsp, UWORD16 req_len)
+{
+ UWORD8 count = 0;
+ UWORD16 wid_id = 0;
+ UWORD16 req_idx = 0;
+ UWORD16 rsp_idx = 0;
+
+ /* The format of a message body of a message type 'Q' is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | WID0 | WID1 | WID2 | ................... | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 2 Bytes | 2 Bytes | 2 Bytes | ................... | */
+ /* +-------------------------------------------------------------------+ */
+
+ /* The format of a message body of a message type 'R' is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | WID0 | WID0 Length | WID0 Value | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 2 Bytes | 1 Byte | WID Length | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+
+ /* The processing of a Query message consists of the following steps: */
+ /* 1) Read the WID value in the Query message */
+ /* 2) Get the corresponding WID length and value */
+ /* 3) Set the WID, WID Length and value in the response message */
+ /* 4) Repeat for all the WID types requested by the host */
+ /* 5) Return the length of the response message */
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("\nWID Q: ");
+#endif /* CONFIG_PRINT */
+
+ while(req_idx < req_len)
+ {
+ /* Read the WID type (2 Bytes) from the Query message and increment */
+ /* the Request Index by 2 to point to the next WID. */
+ wid_id = wid_req[req_idx + 1];
+ wid_id = (wid_id << 8) | wid_req[req_idx];
+ req_idx += 2;
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("%x ",wid_id);
+#endif /* CONFIG_PRINT */
+
+ if(wid_id == WID_ALL)
+ {
+ /* If the WID type is WID_ALL all WID values need to be returned */
+ /* to the host. Thus all the array elements of the global WID */
+ /* array are accessed one by one. */
+ for(count = 0; count < NUM_CHAR_WID; count++)
+ {
+ if(g_char_wid_struct[count].rsp == BTRUE)
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, WID_CHAR);
+ }
+
+ for(count = 0; count < NUM_SHORT_WID; count++)
+ {
+ if(g_short_wid_struct[count].rsp == BTRUE)
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, WID_SHORT);
+ }
+
+ for(count = 0; count < NUM_INT_WID; count++)
+ {
+ if(g_int_wid_struct[count].rsp == BTRUE)
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, WID_INT);
+ }
+
+ for(count = 0; count < NUM_STR_WID; count++)
+ {
+ if(g_str_wid_struct[count].rsp == BTRUE)
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, WID_STR);
+ }
+ for(count = 0; count < NUM_BIN_DATA_WID; count++)
+ {
+ if(g_binary_data_wid_struct[count].rsp == BTRUE)
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, WID_BIN_DATA);
+ }
+
+ }
+ else
+ {
+ /* In case of any other WID, the static global WID array is */
+ /* searched to find a matching WID type for its corresponding */
+ /* length and value. */
+ UWORD8 wid_type = (wid_id & 0xF000) >> 12;
+ count = get_wid_index(wid_id,wid_type);
+
+ if(count == 0xFF)
+ {
+ /* If the Queried WID type is not found it is an exception. */
+ /* Skip this and continue. */
+ continue;
+ }
+ else
+ {
+ /* In case of a valid WID, fill up the WID type, WID length */
+ /* and WID values in the Response message. */
+ rsp_idx += get_wid(&wid_rsp[rsp_idx], count, wid_type);
+ }
+ }
+ } /* end of while(index < req_len) */
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("||\n");
+#endif /* CONFIG_PRINT */
+
+ /* Return Response length (given by the updated response index value) */
+ return rsp_idx;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : process_write */
+/* */
+/* Description : This function processes the host write message. */
+/* */
+/* Inputs : 1) Pointer to the write request message */
+/* 2) Length of the write request */
+/* */
+/* Globals : g_wid_struct */
+/* g_reset_mac */
+/* */
+/* Processing : This function reads the WID value in the Write message */
+/* and sets the corresponding WID length and value. The */
+/* process is repeated for all the WID types requested by */
+/* the host. In case the setting of any WID requires the */
+/* reset of MAC, the global g_reset_mac is updated. */
+/* */
+/* Outputs : g_reset_mac is updated to indicate if a reset is needed */
+/* */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+void process_write(UWORD8* wid_req, UWORD16 req_len)
+{
+ UWORD8 count = 0;
+ UWORD16 req_idx = 0;
+ UWORD16 wid_len = 0;
+ UWORD16 wid_id = 0;
+ UWORD8 *wid_val = 0;
+ UWORD32 wid_type = 0;
+
+ /* Set the global flag for reset MAC to BFALSE. This will be updated to */
+ /* BTRUE if any parameter setting calls for a reset. */
+ g_reset_mac = BFALSE;
+
+ /* The format of a message body of a message type 'W' is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | WID0 | WID0 Length | WID0 Value | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 2 Bytes | 1 Byte | WID Length | ......................... | */
+ /* +-------------------------------------------------------------------+ */
+
+ /* The processing of a Write message consists of the following steps: */
+ /* 1) Read the WID value in the Write message */
+ /* 2) Set the corresponding WID length and value */
+ /* 3) Repeat for all the WID types requested by the host */
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("\nWID S: ");
+#endif /* CONFIG_PRINT */
+
+ while(req_idx+3 < req_len)
+ {
+
+ /* Read the WID ID (2 Bytes) and the WID length from the Write */
+ /* message. */
+ wid_id = wid_req[req_idx + 1];
+ wid_id = (wid_id << 8) | wid_req[req_idx];
+ wid_type = (wid_id & 0xF000) >> 12;
+ count = get_wid_index(wid_id,wid_type);
+
+ //NMI_PRINTF(" wid_id = %02x , wid_type = %d \n", wid_id, wid_type);
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("%x %x",wid_id,count);
+#endif /* CONFIG_PRINT */
+
+ if(wid_type != WID_BIN_DATA)
+ {
+ wid_len = wid_req[req_idx + 2];
+
+ /* Set the 'wid' pointer to point to the WID value (skipping */
+ /* the ID and Length fields). This is used in the set_wid */
+ /* function. It is assumed that all 'set' functions use the */
+ /* value directly as input. */
+ wid_val = &wid_req[req_idx + WID_VALUE_OFFSET];
+
+ /* The Request Index is incremented by (WID Length + 3) to */
+ /* point to the next WID. */
+ req_idx += (wid_len + WID_VALUE_OFFSET);
+ }
+ else
+ {
+ UWORD16 i = 0;
+ UWORD8 checksum = 0;
+
+ /* WID_BIN_DATA format */
+ /* +---------------------------------------------------+ */
+ /* | WID | WID Length | WID Value | Checksum | */
+ /* +---------------------------------------------------+ */
+ /* | 2Bytes | 2Bytes | WID Length Bytes | 1Byte | */
+ /* +---------------------------------------------------+ */
+
+ wid_len = wid_req[req_idx + 2];
+ wid_len |= ((UWORD16)wid_req[req_idx + 3] << 8) & 0xFF00 ;
+ wid_len &= WID_BIN_DATA_LEN_MASK;
+
+ /* Set the 'wid' pointer to point to the WID length (skipping */
+ /* the ID field). This is used in the set_wid function. It */
+ /* is assumed that 'set' function for Binary data uses the */
+ /* length field for getting the WID Value */
+ wid_val = &wid_req[req_idx + WID_LENGTH_OFFSET];
+
+ /* The Request Index is incremented by (WID Length + 5) to */
+ /* point to the next WID. */
+ req_idx += (wid_len + WID_LENGTH_OFFSET + 2 + 1);
+
+ /* Compute checksum on the Data field */
+ for(i = 0;i < wid_len;i++)
+ {
+ checksum += wid_val[i + 2];
+ }
+ /* Drop the packet, if checksum failed */
+ if(checksum != wid_val[wid_len + 2])
+ {
+ continue;
+ }
+ }
+
+ if(count == 0xFF)
+ {
+ /* If the Queried WID type is not found it is an exception. */
+ /* Skip this and continue. */
+ continue;
+ }
+ else
+ {
+ /* In case of a valid WID, set the corresponding parameter with */
+ /* the incoming value. */
+ set_wid(wid_val, wid_len, count, wid_type);
+
+ /* Check if writing this WID requires resetting of MAC. The */
+ /* global g_reset_mac is 'OR'ed with the reset value obtained */
+ /* for this WID. */
+ switch(wid_type)
+ {
+ case WID_CHAR:
+ g_reset_mac |= g_char_wid_struct[count].reset;
+ break;
+ case WID_SHORT:
+ g_reset_mac |= g_short_wid_struct[count].reset;
+ break;
+ case WID_INT:
+ g_reset_mac |= g_int_wid_struct[count].reset;
+ break;
+ case WID_STR:
+ g_reset_mac |= g_str_wid_struct[count].reset;
+ break;
+ case WID_BIN_DATA:
+ g_reset_mac |= g_binary_data_wid_struct[count].reset;
+ break;
+ }
+ }
+ } /* end of while(index < req_len) */
+
+#ifdef CONFIG_PRINT
+ if(g_reset_mac_in_progress == BFALSE)
+ debug_print("||\n");
+#endif /* CONFIG_PRINT */
+
+ /* Overwrite the Reset Flag with User request */
+ if(g_reset_req_from_user == DONT_RESET)
+ {
+ g_reset_mac = BFALSE;
+ }
+ else if (g_reset_req_from_user == DO_RESET)
+ {
+ g_reset_mac = BTRUE;
+ }
+
+ /* Re-initialize user request variable */
+ g_reset_req_from_user = NO_REQUEST;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : prepare_config_hdr */
+/* */
+/* Description : This function prepares a configuration header as per the */
+/* host protocol in use. */
+/* */
+/* Inputs : 1) Pointer to the configuration message buffer */
+/* 2) More fragment BOOL value */
+/* 3) Fragment offset */
+/* */
+/* Globals : None */
+/* */
+/* Processing : For the ethernet host, a UDP packet with the given source*/
+/* and destination port is by protocol a configuration */
+/* message. Hence the host response is packed into a UDP */
+/* packet. For ther hosts, sepaerate host header is defined */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Length of the configuration message */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 20 01 2009 Ittiam Draft */
+/* */
+/*****************************************************************************/
+UWORD8 g_first_config_pkt = 1;
+UWORD8 g_config_eth_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+UWORD8 g_config_ip_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+UWORD8 g_src_eth_addr[6] = { 0x00, 0x50, 0xC2, 0x5E, 0x10, 0x92 };
+UWORD8 g_src_ip_addr[6] = {192,168,20,221};
+UWORD8 g_src_netmask_addr[6] = {0};
+
+
+UWORD16 prepare_config_hdr(UWORD8* data, UWORD16 len,
+ BOOL_T more_frag, UWORD16 frag_offset)
+{
+ UWORD16 ret_len = 0;
+#ifdef ETHERNET_HOST
+ UWORD8 index = 0;
+ UWORD16 csum = 0;
+ UWORD16 udp_len = 0;
+ UWORD16 ip_len = 0;
+#endif /* ETHERNET_HOST */
+
+#ifdef ETHERNET_HOST
+ /* Prepare the Ethernet Header - 14 bytes (format is shown below) */
+ /* */
+ /* +---------------------+-------------------+-------------+ */
+ /* | Destination address | Source address | Packet Type | */
+ /* +---------------------+-------------------+-------------+ */
+ /* | 0 | 6 |12 | */
+ /* +---------------------+-------------------+-------------+ */
+
+ /* Set the Ethernet destination address and Source address */
+ mac_addr_cpy(data, g_config_eth_addr);
+ mac_addr_cpy(data + 6, g_src_eth_addr);
+
+ /* Set the type to IP */
+ data[12] = (IP_TYPE & 0xFF00) >> 8;
+ data[13] = (IP_TYPE & 0xFF);
+
+ /* Prepare the IP Header - 20 bytes (format is shown below) */
+ /* */
+ /* --------------------------------------------------------------------- */
+ /* | Version | IHL | TOS | Total length | Identification | Flags */
+ /* --------------------------------------------------------------------- */
+ /* 0 1 2 4 6 */
+ /* --------------------------------------------------------------------- */
+ /* | Fragment offset | TTL | Protocol | Header checksum | */
+ /* --------------------------------------------------------------------- */
+ /* 7 8 9 10 */
+ /* --------------------------------------------------------------------- */
+ /* | Source IP address | Destination IP address | */
+ /* --------------------------------------------------------------------- */
+ /* 12 16 */
+ /* --------------------------------------------------------------------- */
+
+ index = IP_HDR_OFFSET;
+
+ if(frag_offset == 0)
+ {
+ ip_len = len + UDP_HDR_LEN + IP_HDR_LEN;
+ }
+ else
+ {
+ ip_len = len + IP_HDR_LEN;
+ }
+
+ data[index] = 0x45;
+ data[index + 1] = 0x00;
+ data[index + 2] = (ip_len & 0xFF00) >> 8;
+ data[index + 3] = (ip_len & 0xFF);
+ data[index + 4] = 0x00;
+ data[index + 5] = 0x00;
+
+ /* Flags & Fragment Offset */
+ if(more_frag == BTRUE)
+ {
+ data[index + 6] = 0x20;
+ }
+ else
+ {
+ data[index + 6] = 0x00;
+ }
+
+ data[index + 7] = frag_offset;
+
+ /* TTL */
+ data[index + 8] = 0x80;
+
+ /* Set the IP protocol to UDP */
+ data[index + 9] = UDP_TYPE;
+
+ /* Set the checksum to zero */
+ data[index + 10] = 0;
+ data[index + 11] = 0;
+
+ index += 12;
+
+ /* Set the IP source address to some value with different subnet */
+ ip_addr_cpy(data + index, g_src_ip_addr);
+ index += 4;
+
+ /* Set the IP destination address */
+ ip_addr_cpy(data + index, g_config_ip_addr);
+ index += 4;
+
+ /* Compute the checksum and set the field */
+ csum = checksum(&data[IP_HDR_OFFSET], IP_HDR_LEN);
+ data[IP_HDR_OFFSET + 11] = (csum & 0xFF00) >> 8;
+ data[IP_HDR_OFFSET + 10] = (csum & 0xFF);
+
+ if((frag_offset == 0) && (more_frag == BFALSE))
+ {
+ /* Prepare the UDP Header - 8 bytes (format is shown below) */
+ /* */
+ /* +--------------+--------------+--------+----------+ */
+ /* | UDP SRC Port | UDP DST Port | Length | Checksum | */
+ /* +--------------+--------------+--------+----------+ */
+ /* | 0 | 2 |4 | 6 | */
+ /* +--------------+--------------+--------+----------+ */
+
+ index = UDP_HDR_OFFSET;
+
+ /* Set the UDP source and destination ports */
+ data[index] = (WLAN_UDP_PORT & 0xFF00) >> 8;
+ data[index + 1] = (WLAN_UDP_PORT & 0xFF);
+ data[index + 2] = (HOST_UDP_PORT & 0xFF00) >> 8;
+ data[index + 3] = (HOST_UDP_PORT & 0xFF);
+ index += 4;
+
+ /* Set the length to the UDP data + UDP header */
+ udp_len = len + UDP_HDR_LEN;
+ data[index] = (udp_len & 0xFF00) >> 8;
+ data[index + 1] = (udp_len & 0xFF);
+ index += 2;
+
+ /* Set the checksum to zero - currently not set as it is not mandatory */
+ data[index] = 0;
+ data[index + 1] = 0;
+
+ ret_len = (len + CONFIG_PKT_HDR_LEN);
+ }
+ else
+ {
+ ret_len = (len + CONFIG_PKT_HDR_LEN - UDP_HDR_OFFSET);
+ }
+#endif /* ETHERNET_HOST */
+
+
+
+
+ return ret_len;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : send_mac_status */
+/* */
+/* Description : This function sends the status of MAC to host */
+/* */
+/* Inputs : MAC Status */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function prepares an Information frame having the */
+/* MAC Status and calls send_host_rsp function to send the */
+/* prepared frame to host */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 11 04 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void send_mac_status(UWORD8 mac_status)
+{
+//#ifdef SEND_MAC_STATUS
+ UWORD8 *info_msg = NULL;
+ UWORD16 offset = config_host_hdr_offset(BFALSE,0);
+
+
+#ifdef HOST_RX_LOCAL_MEM
+ if(g_eth2sram_trfr == BTRUE)
+ mem_handle = (void *) g_shared_mem_handle;
+ else
+ mem_handle = (void *) g_local_mem_handle;
+#endif /* HOST_RX_LOCAL_MEM */
+
+ info_msg = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(info_msg == NULL)
+ {
+ return;
+ }
+
+ info_msg[offset + 0] = 'I';
+ info_msg[offset + 1] = g_info_id;
+ /* Increment the id sequence counter by 1*/
+ g_info_id++;
+
+ info_msg[offset + 2] = (STATUS_MSG_LEN) & 0xFF;
+ info_msg[offset + 3] = ((STATUS_MSG_LEN) & 0xFF00) >> 8;
+
+ /* Set the WID_STATUS, Length to 1, Value to mac_status */
+ info_msg[offset + 4] = WID_STATUS & 0xFF;
+ info_msg[offset + 5] = (WID_STATUS & 0xFF00) >> 8;
+ info_msg[offset + 6] = 1;
+ info_msg[offset + 7] = mac_status;
+
+ /* The response is sent back to the host */
+ send_host_rsp(info_msg, STATUS_MSG_LEN);
+
+ if(info_msg != NULL)
+ {
+ NMI_FREE(info_msg);
+ }
+//#endif /* SEND_MAC_STATUS */
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : send_wake_status */
+/* */
+/* Description : This function sends the status of PS condition to host */
+/* */
+/* Inputs : PS Status */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function prepares an Information frame having the */
+/* PS Status and calls send_host_rsp function to send the */
+/* prepared frame to host */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 30 09 2008 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void send_wake_status(UWORD8 wake_status)
+{
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : send_network_info_to_host */
+/* */
+/* Description : This function sends the beacon/probe response from scan */
+/* */
+/* Inputs : BSSID, RSSI & InfoElements */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function prepares an Information frame having the */
+/* BSSID. RSSI value and Information elements and sends the */
+/* prepared frame to host */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 17 08 2009 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void send_network_info_to_host(UWORD8 *msa, UWORD16 rx_len, signed char rssi)
+{
+#ifndef ETHERNET_HOST
+ //mem_handle_t *mem_handle = g_shared_mem_handle;
+ UWORD8 *info_msg = NULL;
+ UWORD16 ninfo_data_len= 0;
+ UWORD16 offset = config_host_hdr_offset(BFALSE,0);
+
+ info_msg = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(info_msg == NULL)
+ {
+#ifdef DEBUG_PRINT
+ debug_print("No buffer to send Beacon/ProbeRsp\n");
+#endif /* DEBUG_PRINT */
+ return;
+ }
+
+ /* TODO: Mostafa: uncomment the following line if the input argument rx_len includes FCS */
+ //rx_len -= FCS_LEN; ///////////////
+
+ ninfo_data_len = (rx_len + 9);
+
+
+ info_msg[offset + 0] = 'N';
+ info_msg[offset + 1] = g_network_info_id;
+ /* Increment the id sequence counter by 1*/
+ g_network_info_id++;
+
+ info_msg[offset + 2] = ninfo_data_len & 0xFF;
+ info_msg[offset + 3] = (ninfo_data_len & 0xFF00) >> 8;
+
+ info_msg[offset + 4] = WID_NETWORK_INFO & 0xFF;
+ info_msg[offset + 5] = (WID_NETWORK_INFO & 0xFF00) >> 8;
+
+ info_msg[offset + 6] = (rx_len + 1) & 0xFF;
+ info_msg[offset + 7] = ((rx_len + 1) & 0xFF00) >> 8;
+
+ info_msg[offset + 8] = rssi;
+
+ NMI_memcpy(&info_msg[offset + 9],msa,rx_len);
+
+ send_host_rsp(info_msg, ninfo_data_len);
+
+ if(info_msg != NULL)
+ {
+ NMI_FREE(info_msg);
+ info_msg = NULL;
+ }
+
+#endif /* ETHERNET_HOST */
+}
+
+/*bug3819: Add Scan acomplete notification to host*/
+void send_scan_complete_to_host(UWORD8 scan_done)
+{
+
+#ifndef ETHERNET_HOST
+ UWORD8 *info_msg = NULL;
+ UWORD8 *info_buf = NULL;
+
+ info_buf = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+
+ if(info_buf == NULL) {
+ PRINT_ER("Can't alloc memory...\n");
+ return;
+ }
+
+ info_msg = info_buf + config_host_hdr_offset(BFALSE,0);
+
+ info_msg[0] = 'S';
+ info_msg[1] = g_scan_complete_id;
+
+ /* Increment the id sequence counter by 1*/
+ g_scan_complete_id++;
+
+ info_msg[2] = (SCAN_COMPLETE_MSG_LEN) & 0xFF;
+
+ info_msg[3] = ((SCAN_COMPLETE_MSG_LEN) & 0xFF00) >> 8;
+
+ /* Set the WID_SCAN_COMPLETE, Length to 1, Value to mac_status */
+ info_msg[4] = WID_SCAN_COMPLETE & 0xFF;
+ info_msg[5] = (WID_SCAN_COMPLETE & 0xFF00) >> 8;
+ info_msg[6] = 1;
+ info_msg[7] = scan_done;
+
+ /* The response is sent back to the host */
+ PRINT_INFO(CORECONFIG_DBG,"Sending scan complete notification\n");
+ send_host_rsp(info_buf, SCAN_COMPLETE_MSG_LEN);
+
+ if(info_buf != NULL)
+ {
+ NMI_FREE(info_buf);
+ info_buf = NULL;
+ }
+
+#endif
+}
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : send_sta_join_info_to_host */
+/* */
+/* Description : This function sends info of a joining/leaving sta to host*/
+/* */
+/* Inputs : station address */
+/* */
+/* Globals : None */
+/* */
+/* Processing : This function prepares an Information frame having the */
+/* information about a joining/leaving station. */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 08 06 2010 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void send_join_leave_info_to_host(UWORD16 aid, UWORD8* sta_addr, BOOL_T joining)
+{
+#if 0
+
+#ifndef ETHERNET_HOST
+ //mem_handle_t *mem_handle = g_shared_mem_handle;
+ UWORD8 *info_msg = NULL;
+ UWORD16 info_len = 16;
+ UWORD16 offset = config_host_hdr_offset(BFALSE,0);
+
+ info_msg = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(info_msg == NULL)
+ {
+#ifdef DEBUG_PRINT
+ debug_print("No buffer to send STA join/leave info to host\n");
+#endif /* DEBUG_PRINT */
+ return;
+ }
+
+ /* Get the infromation of joining station */
+ if(joining == BTRUE)
+ {
+ info_len = get_sta_join_info(sta_addr, &info_msg[offset + 8]);
+ }
+ /* prepare the information of leaving station */
+ else
+ {
+ /* Reset all the fields */
+ memset(&info_msg[offset + 8], 0, info_len);
+
+ /* Copy the association id of the leaving station */
+ info_msg[offset + 8] = aid & 0xFF;
+
+ /* Copy the MAC address of the leaving station */
+ NMI_memcpy(&info_msg[offset + 9], sta_addr, 6);
+ }
+
+ if(info_len)
+ {
+ info_msg[offset + 0] = 'N';
+ info_msg[offset + 1] = g_info_id;
+
+ /* Increment the id sequence counter by 1*/
+ g_info_id++;
+
+ /* Prepare the frame */
+ info_msg[offset + 2] = (info_len + 8) & 0xFF;
+ info_msg[offset + 3] = ((info_len + 8) & 0xFF00) >> 8;
+
+ info_msg[offset + 4] = WID_STA_JOIN_INFO & 0xFF;
+ info_msg[offset + 5] = (WID_STA_JOIN_INFO & 0xFF00) >> 8;
+
+ info_msg[offset + 6] = info_len & 0xFF;
+ info_msg[offset + 7] = (info_len & 0xFF00) >> 8;
+
+ send_host_rsp(info_msg, (info_len + 8));
+ }
+ else
+ {
+ //NMI_FREE(g_shared_mem_handle, info_msg);
+ }
+#endif /* ETHERNET_HOST */
+
+#endif
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : save_wids */
+/* */
+/* Description : This function saves all the wid values to a global arry */
+/* */
+/* Inputs : None */
+/* */
+/* Globals : g_char_wid_struct */
+/* g_short_wid_struct */
+/* g_int_wid_struct */
+/* g_str_wid_struct */
+/* g_binary_data_wid_struct */
+/* g_current_settings */
+/* g_current_len */
+/* */
+/* Processing : Checks if the WID has a get and set function and stores */
+/* the values of all such WIDs in to global array for */
+/* restoring from it later */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void save_wids(void)
+{
+ UWORD8 count = 0;
+ UWORD16 idx = 0;
+
+ /* Save all the settings in the global array. This is saved as a */
+ /* dummy Write message with all WID values. It is used to set */
+ /* the parameters once reset is done. */
+
+
+ /* The global WID array is accessed and all the current WID */
+ /* values are saved in the format of WID ID, Length, Value. */
+ for(count = 0; count < NUM_CHAR_WID; count++)
+ {
+ if((g_char_wid_struct[count].set) &&
+ (g_char_wid_struct[count].get))
+ idx += get_wid(&g_current_settings[idx], count,
+ WID_CHAR);
+ }
+
+ for(count = 0; count < NUM_SHORT_WID; count++)
+ {
+ if((g_short_wid_struct[count].set)&&
+ (g_short_wid_struct[count].get))
+ idx += get_wid(&g_current_settings[idx], count,
+ WID_SHORT);
+ }
+
+ for(count = 0; count < NUM_INT_WID; count++)
+ {
+ if((g_int_wid_struct[count].set)&&
+ (g_int_wid_struct[count].get))
+ idx += get_wid(&g_current_settings[idx], count,
+ WID_INT);
+ }
+
+ for(count = 0; count < NUM_STR_WID; count++)
+ {
+ if((g_str_wid_struct[count].set)&&
+ (g_str_wid_struct[count].get))
+ idx += get_wid(&g_current_settings[idx], count,
+ WID_STR);
+
+ /*To make sure that it doesnt cross g_current_settings array boundry*/
+ if(idx >= (MAX_QRSP_LEN - 50))
+ break;
+ }
+
+ /* There may not be enought memory for this operation, so */
+ /* disabling it for now */
+#if 0
+ for(count = 0; count < NUM_BIN_DATA_WID; count++)
+ {
+ if((g_binary_data_wid_struct[count].set)&&
+ (g_binary_data_wid_struct[count].get))
+ idx += get_wid(&g_current_settings[idx], count,
+ WID_BIN_DATA);
+ }
+#endif
+ /* Set the length of global current configuration settings */
+ g_current_len = idx;
+
+#ifdef DEBUG_MODE
+ /* Check whether query response length exceeded max length */
+ if(g_current_len > MAX_QRSP_LEN)
+ {
+ g_mac_stats.max_query_rsp_len_exceeded = BTRUE;
+ }
+#endif /* DEBUG_MODE */
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : restore_wids */
+/* */
+/* Description : This function restores all the wids from the global arry */
+/* */
+/* Inputs : None */
+/* */
+/* Globals : g_current_settings */
+/* g_current_len */
+/* */
+/* Processing : Calls the process write function for restoring all the */
+/* WID values */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void restore_wids(void)
+{
+ /* Set all the required parameters from the saved configuration */
+ /* settings. */
+ process_write(g_current_settings, g_current_len);
+}
+
+
+
+/*****************************************************************************/
+/* */
+/* Function Name : make_wid_rsp */
+/* */
+/* Description : This function make response massage to host */
+/* */
+/* Inputs : 1) buffer to response for wid */
+/* 2) massage id of wid */
+/* 3) massage data of wid */
+/* */
+/* Globals : None */
+/* */
+/* Processing : set massage data of response */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 15 04 2007 Draft */
+/* */
+/*****************************************************************************/
+void make_wid_rsp(UWORD8 *wid_rsp_data, UWORD8 msg_id, UWORD8 wid_massage)
+{
+ wid_rsp_data[0] = 'R';
+ wid_rsp_data[1] = msg_id;
+ wid_rsp_data[2] = (WRITE_RSP_LEN + MSG_HDR_LEN) & 0xFF;
+ wid_rsp_data[3] = ((WRITE_RSP_LEN + MSG_HDR_LEN) & 0xFF00) >> 8;
+
+ /* Set the WID_STATUS, Length to 1, Value to SUCCESS */
+ wid_rsp_data[4] = WID_STATUS & 0xFF;
+ wid_rsp_data[5] = (WID_STATUS & 0xFF00) >> 8;
+ wid_rsp_data[6] = 1;
+ wid_rsp_data[7] = wid_massage;
+
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : parse_config_message */
+/* */
+/* Description : This function parses the host configuration messages. */
+/* */
+/* Inputs : 1) Pointer to the MAC structure */
+/* 2) Pointer to configuration message */
+/* 3) Pointer to Buffer address */
+/* */
+/* Globals : g_reset_mac */
+/* g_current_settings */
+/* g_current_len */
+/* */
+/* Processing : This function processes all the configuration messages. */
+/* from the host based on the SME type. Currently only */
+/* SME types 'Test' and 'Auto' are supported. In case of a */
+/* Query request the query response is prepared using the */
+/* values of the queried parameters. No MAC state change */
+/* occurs in this case. In case of a Write request the */
+/* parameters are set and the Write response prepared. If */
+/* any parameter writing requires the MAC to be reset, the */
+/* appropriate function is called to reset MAC. The */
+/* paramters are saved in a global list. After MAC is reset */
+/* these parameters are set once again. Thereafter, a Scan */
+/* Request is prepared and sent to the MAC. Response to the */
+/* host is sent in the required format based on the SME */
+/* mode. */
+/* */
+/* Outputs : None */
+/* Returns : None */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void parse_config_message(UWORD8* host_req,
+ UWORD8 *buffer_addr, BOOL_T send_write_rsp)
+{
+ UWORD8 *rtn_buff = NULL;
+ UWORD16 rtn_len = 0;
+ UWORD8 msg_type = 0;
+ UWORD8 msg_id = 0;
+ UWORD16 msg_len = 0;
+ BOOL_T free_flag = BTRUE;
+ //mem_handle_t *mem_handle = g_shared_mem_handle;
+ UWORD16 offset = config_host_hdr_offset(BFALSE,0);
+ UWORD8 *query_rsp = NULL;
+ UWORD8 *write_rsp = NULL;
+ UWORD8 *error_rsp = NULL;
+
+#ifdef HOST_RX_LOCAL_MEM
+ if(g_eth2sram_trfr == BTRUE)
+ mem_handle = (void *) g_shared_mem_handle;
+ else
+ mem_handle = (void *) g_local_mem_handle;
+#endif /* HOST_RX_LOCAL_MEM */
+
+ /* Extract the Type, Length and ID of the incoming host message. The */
+ /* format of the message is: */
+ /* +-------------------------------------------------------------------+ */
+ /* | Message Type | Message ID | Message Length |Message body | */
+ /* +-------------------------------------------------------------------+ */
+ /* | 1 Byte | 1 Byte | 2 Bytes | Message Length | */
+ /* +-------------------------------------------------------------------+ */
+
+ msg_type = host_req[0];
+ msg_id = host_req[1];
+ msg_len = host_req[3];
+ msg_len = (msg_len << 8) | host_req[2];
+ msg_len -= MSG_HDR_LEN;
+
+ /* The valid types of incoming messages are 'Q' (Query) and 'W' (Write) */
+ switch(msg_type)
+ {
+ case 'Q':
+ {
+
+ UWORD16 rsp_len = 0;
+
+ /* To a Query message a Response message needs to be sent. This */
+ /* message has a type 'R' and should have an ID equal to the */
+ /* incoming Query message. */
+ query_rsp = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(query_rsp == NULL)
+ {
+#ifdef DEBUG_PRINT
+ debug_print("WID Q MemAlloc Fail\n");
+#endif /* DEBUG_PRINT */
+ return;
+ }
+
+ /* Set the Message Type and ID. The Message Length is set after the */
+ /* message contents are written. The length is known only after that.*/
+ /* Process the Query message and set the contents as required. */
+
+ rsp_len = process_query(&host_req[MSG_DATA_OFFSET],
+ &query_rsp[offset + MSG_DATA_OFFSET], msg_len);
+
+ /* The length of the message returned is set in the Message length */
+ /* field. */
+ if (0 == rsp_len)
+ {
+ make_wid_rsp((query_rsp + offset),msg_id,(UWORD8)WRSP_SUCCESS);
+ rsp_len = 4;
+ }
+ else
+ {
+ /* The length of the message returned is set in the Message length */
+ /* field. */
+ query_rsp[offset + 0] = 'R';
+ query_rsp[offset + 1] = msg_id;
+ query_rsp[offset + 2] = (rsp_len + MSG_HDR_LEN) & 0xFF;
+ query_rsp[offset + 3] = ((rsp_len + MSG_HDR_LEN) & 0xFF00) >> 8;
+ }
+ /* The response is sent back to the host. No MAC state changes occur */
+ /* on reception of a Query message. */
+ rtn_buff = query_rsp;
+ rtn_len = (UWORD16)(rsp_len + MSG_HDR_LEN);
+ Rsp_Len = rtn_len;
+
+ }
+ break;
+
+ case 'W':
+ {
+
+#ifdef BURST_TX_MODE
+ if(get_DesiredBSSType() != 4)
+ {
+ g_burst_tx_mode_enabled_earlier = BFALSE;
+ }
+ else
+ {
+ g_burst_tx_mode_enabled_earlier = BTRUE;
+ }
+#endif /* BURST_TX_MODE */
+
+ /* Process the request only if it's sequence number is correct */
+ if((g_last_w_seq != msg_id)
+ /* Exception for Debug mode as automation program sends seq no:0 always */
+ || (msg_id == 0)
+ )
+ {
+ /* Process the Write message and set the parameters with the given */
+ /* values. */
+ process_write(host_req + MSG_DATA_OFFSET, msg_len);
+
+ }
+ else
+ {
+ g_reset_mac = BFALSE;
+ }
+ g_last_w_seq = msg_id;
+
+
+ /* Change MAC states as required. If it is already in Enabled state */
+ /* reset MAC and start again. The previous configuration values are */
+ /* retained. */
+ if(g_reset_mac == BTRUE)
+#ifndef MAC_HW_UNIT_TEST_MODE
+ //if(mac->state != DISABLED)
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ {
+
+#ifdef DEBUG_MODE
+ g_reset_stats.configchange++;
+#endif /* DEBUG_MODE */
+
+ g_reset_mac_in_progress = BTRUE;
+
+ free_flag = BFALSE;
+
+ /* Save the current configuration before going for Reset */
+ save_wids();
+
+ /* Reset MAC - Bring down PHY and MAC H/W, disable MAC */
+ /* interrupts and release all OS structures. Further, this */
+ /* function restarts the MAC again from start. */
+ // reset_mac(mac);
+
+ /* Restore the saved configuration before resetting */
+ restore_wids();
+
+ g_reset_mac_in_progress = BFALSE;
+
+#ifdef BURST_TX_MODE
+ /* Start scaning only when burst tx mode is disabled */
+ if(g_burst_tx_mode_enabled == BTRUE)
+ {
+ init_mac_fsm_bt(&g_mac);
+ }
+#endif /* BURST_TX_MODE */
+ }
+
+#ifndef MAC_HW_UNIT_TEST_MODE
+ //if(mac->state == DISABLED)
+#else /* MAC_HW_UNIT_TEST_MODE */
+ if(g_test_start == BTRUE)
+#endif /* MAC_HW_UNIT_TEST_MODE */
+ {
+ //start_mac_and_phy(&g_mac);
+ }
+
+ if(BTRUE == send_write_rsp)
+ {
+ /* To a Write message a Response message needs to be sent. This */
+ /* message has a type 'R' and should have an ID equal to the */
+ /* incoming Write message. The Message contents contain 'Y' to */
+ /* indicate Success. */
+ write_rsp = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(write_rsp == NULL)
+ {
+#ifdef DEBUG_PRINT
+ debug_print("WID S MemAlloc Fail\n");
+#endif /* DEBUG_PRINT */
+
+ return;
+ }
+
+ make_wid_rsp((write_rsp + offset),msg_id,WRSP_SUCCESS);
+ rtn_buff = write_rsp;
+ rtn_len = WRITE_RSP_LEN + MSG_HDR_LEN;
+ Rsp_Len = rtn_len;
+ }
+
+ }
+ break;
+
+ default:
+ {
+ /* Unknown message type. Do nothing. */
+
+#ifdef DEBUG_PRINT
+ debug_print("WID: Neither Set Not Query\n");
+#endif /* DEBUG_PRINT */
+
+ /* To a Write message a Response message needs to be sent. This */
+ /* message has a type 'R' and should have an ID equal to the */
+ /* incoming Write message. The Message contents contain 'Y' to */
+ /* indicate Success. */
+ error_rsp = (UWORD8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(error_rsp == NULL)
+ {
+ return;
+ }
+ /* make returned data to host */
+ make_wid_rsp((error_rsp + offset),msg_id,WRSP_SUCCESS);
+ rtn_buff = error_rsp;
+ rtn_len = WRITE_RSP_LEN + MSG_HDR_LEN;
+ Rsp_Len = rtn_len;
+ }
+ } /* end of switch(msg_type) */
+
+ /* send returned data to host */
+ if(rtn_buff != NULL)
+ {
+ NMI_memcpy(buffer_addr,rtn_buff+ offset,rtn_len);
+ }
+
+ if(query_rsp != NULL)
+ {
+ NMI_FREE(query_rsp);
+ query_rsp = NULL;
+ }
+
+ if(write_rsp != NULL)
+ {
+ NMI_FREE(write_rsp);
+ write_rsp = NULL;
+ }
+
+ if(error_rsp != NULL)
+ {
+ NMI_FREE(write_rsp);
+ write_rsp = NULL;
+ }
+
+}
+
+
+
+static void SendMacStatus(void* pvUsrArg)
+{
+ while(NMI_TRUE)
+ {
+ NMI_Sleep(100);
+
+ if(gbTermntMacStsThrd == NMI_TRUE)
+ {
+ NMI_SemaphoreRelease(&SemHandleMacStsExit, NMI_NULL);
+ break;
+ }
+
+ send_mac_status(g_current_mac_status);
+ }
+}
+
+
+static void SimulatorThread(void* pvUsrArg)
+{
+ tstrSimulatorMsg* pstrSimulatorMsg = NMI_NULL;
+ NMI_Uint32 u32Ret;
+ NMI_Sint32 s32Err = NMI_SUCCESS;
+ NMI_Uint8* pu8ConfigPkt = NULL;
+ NMI_Sint32 s32PktDataLen = 0;
+ NMI_Uint8* pu8PktResponse = NULL;
+ NMI_Sint32 s32PktResponseLen = -1;
+ NMI_Sint32 s32RcvdPktLen = 0;
+
+ pstrSimulatorMsg = (tstrSimulatorMsg*)NMI_MALLOC(sizeof(tstrSimulatorMsg));
+
+ pu8ConfigPkt = (NMI_Uint8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(pu8ConfigPkt == NULL)
+ {
+ PRINT_D(CORECONFIG_DBG,"Failed in pu8ConfigPkt allocation \n");
+ }
+
+ pu8PktResponse = (NMI_Uint8*)NMI_MALLOC(MAX_BUFFER_LEN);
+ if(pu8PktResponse == NULL)
+ {
+ PRINT_D(CORECONFIG_DBG,"Failed in pu8PktResponse allocation \n");
+ }
+
+ while(NMI_TRUE)
+ {
+ NMI_memset((void*)(pstrSimulatorMsg), 0, sizeof(tstrSimulatorMsg));
+
+ NMI_MsgQueueRecv(&gMsgQSimulator, pstrSimulatorMsg,
+ sizeof(tstrSimulatorMsg), &u32Ret, NMI_NULL);
+
+ if(pstrSimulatorMsg->u32SimThreadCmd == SIMULATOR_MSG_EXIT)
+ {
+ /* exit the Thread function immediately without going to Send_Response
+ because the Semaphores to be used there are expected to be destroyed
+ because a Deinitialization mechanism is in progress */
+
+ goto Exit_Thread;
+ }
+
+ NMI_memset((void*)pu8ConfigPkt, 0, MAX_BUFFER_LEN);
+ NMI_memset((void*)pu8PktResponse, 0, MAX_BUFFER_LEN);
+
+ if(pstrSimulatorMsg->s32PktDataLen < 0)
+ {
+ s32PktResponseLen = -1;
+ goto Send_Response;
+ }
+
+
+ s32PktDataLen = pstrSimulatorMsg->s32PktDataLen;
+
+ s32Err = FIFO_ReadBytes(ghTxFifoBuffer, pu8ConfigPkt, s32PktDataLen, &s32RcvdPktLen);
+ if(s32Err != NMI_SUCCESS)
+ {
+ NMI_ERROR("SimulatorThread(): FIFO_ReadBytes() returned error \n");
+ s32PktResponseLen = -1;
+ goto Send_Response;
+ }
+
+ #if 0
+ /* The following lines are just for testing the architecture functionality of the FIFO Buffers,
+ the threads and the Message Queue */
+
+ ProcessMessage(pu8ConfigPkt, s32PktDataLen);
+ PrepareResponse(pu8ConfigPkt, s32PktDataLen, pu8PktResponse, &s32PktResponseLen);
+
+ #else
+
+ /* Passing data to parser to process it */
+ parse_config_message(pu8ConfigPkt, pu8PktResponse, 1);
+ s32PktResponseLen = Rsp_Len;
+
+ #endif
+
+
+ /* The following lines are just for testing sending asynchronous msg containing network scan results
+ via the API send_network_info_to_host(), such that expextin thread at the other side receiving this
+ msg and parses it */
+ #if 0
+ {
+ WORD8 rssi = 0;
+ UWORD16 rx_len = 0;
+
+
+
+ rx_len = sizeof(msa2);
+
+ NMI_PRINTF("rx_len = sizeof(msa2) = %d \n", rx_len);
+
+ rssi = (WORD8)-123;
+
+ /* TODO: Mostafa: uncomment the line: rx_len -= FCS_LEN; if the input argument rx_len includes FCS */
+ send_network_info_to_host(msa2, rx_len, rssi);
+ }
+
+
+ #else
+
+Send_Response:
+ send_host_rsp(pu8PktResponse, (UWORD16)s32PktResponseLen);
+
+ #endif
+
+ }
+
+
+Exit_Thread:
+
+ if(pstrSimulatorMsg != NMI_NULL)
+ {
+ NMI_FREE(pstrSimulatorMsg);
+ pstrSimulatorMsg = NMI_NULL;
+ }
+
+ if(pu8ConfigPkt != NULL)
+ {
+ NMI_FREE(pu8ConfigPkt);
+ pu8ConfigPkt = NULL;
+ }
+
+ if(pu8PktResponse != NULL)
+ {
+ NMI_FREE(pu8PktResponse);
+ pu8PktResponse = NULL;
+ }
+
+}
+
+NMI_Sint32 CoreConfigSimulatorDeInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrSimulatorMsg* pstrSimulatorMsg = NMI_NULL;
+
+ PRINT_D(CORECONFIG_DBG,"CoreConfigSimulatorDeInit() \n");
+
+ pstrSimulatorMsg = (tstrSimulatorMsg*)NMI_MALLOC(sizeof(tstrSimulatorMsg));
+ NMI_memset((void*)(pstrSimulatorMsg), 0, sizeof(tstrSimulatorMsg));
+
+ pstrSimulatorMsg->u32SimThreadCmd = SIMULATOR_MSG_EXIT;
+ NMI_MsgQueueSend(&gMsgQSimulator, pstrSimulatorMsg, sizeof(tstrSimulatorMsg), NMI_NULL);
+
+ if(pstrSimulatorMsg != NMI_NULL)
+ {
+ NMI_FREE(pstrSimulatorMsg);
+ pstrSimulatorMsg = NMI_NULL;
+ }
+
+ NMI_ThreadDestroy(&ThrdHandleSimulator, NMI_NULL);
+
+ NMI_MsgQueueDestroy(&gMsgQSimulator, NMI_NULL);
+
+ FIFO_DeInit(ghTxFifoBuffer);
+
+ bscan_code = NMI_FALSE;
+
+ NMI_SemaphoreRelease(&SemHandleScanReq,NMI_NULL);
+ NMI_SemaphoreAcquire(&SemHandleScanExit,NMI_NULL);
+
+ NMI_ThreadDestroy(&ThrdHandleScan, NMI_NULL);
+ NMI_SemaphoreDestroy(&SemHandleScanReq, NMI_NULL);
+ NMI_SemaphoreDestroy(&SemHandleScanExit, NMI_NULL);
+
+ gbTermntMacStsThrd = NMI_TRUE;
+ NMI_SemaphoreAcquire(&SemHandleMacStsExit, NMI_NULL);
+ NMI_ThreadDestroy(&ThrdHandleMacStatus, NMI_NULL);
+ NMI_SemaphoreDestroy(&SemHandleMacStsExit, NMI_NULL);
+
+ return s32Error;
+}
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/FIFO_Buffer.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/FIFO_Buffer.c
new file mode 100755
index 00000000..d70f6762
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/core_simulator/FIFO_Buffer.c
@@ -0,0 +1,182 @@
+
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include "driver/include/FIFO_Buffer.h"
+
+
+
+NMI_Uint32 FIFO_InitBuffer(tHANDLE * hBuffer,NMI_Uint32 u32BufferLength)
+{
+ NMI_Uint32 u32Error = 0;
+ tstrFifoHandler * pstrFifoHandler = NMI_MALLOC(sizeof(tstrFifoHandler));
+ if(pstrFifoHandler)
+ {
+ NMI_memset(pstrFifoHandler,0,sizeof(tstrFifoHandler));
+ pstrFifoHandler->pu8Buffer = NMI_MALLOC(u32BufferLength);
+ if(pstrFifoHandler->pu8Buffer)
+ {
+ tstrNMI_SemaphoreAttrs strSemBufferAttrs;
+ pstrFifoHandler->u32BufferLength = u32BufferLength;
+ NMI_memset(pstrFifoHandler->pu8Buffer,0,u32BufferLength);
+ //create semaphore
+ NMI_SemaphoreFillDefault(&strSemBufferAttrs);
+ strSemBufferAttrs.u32InitCount = 1;
+ NMI_SemaphoreCreate(&pstrFifoHandler->SemBuffer, &strSemBufferAttrs);
+ *hBuffer = pstrFifoHandler;
+ }
+ else
+ {
+ *hBuffer = NULL;
+ u32Error = 1;
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ return u32Error;
+}
+NMI_Uint32 FIFO_DeInit(tHANDLE hFifo)
+{
+ NMI_Uint32 u32Error = 0;
+ tstrFifoHandler * pstrFifoHandler = (tstrFifoHandler*)hFifo;
+ if(pstrFifoHandler)
+ {
+ if(pstrFifoHandler->pu8Buffer)
+ {
+ NMI_FREE(pstrFifoHandler->pu8Buffer);
+ }
+ else
+ {
+ u32Error = 1;
+ }
+
+ NMI_SemaphoreDestroy(&pstrFifoHandler->SemBuffer, NMI_NULL);
+
+ NMI_FREE(pstrFifoHandler);
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ return u32Error;
+}
+NMI_Uint32 FIFO_ReadBytes(tHANDLE hFifo,NMI_Uint8 *pu8Buffer,NMI_Uint32 u32BytesToRead,NMI_Uint32 *pu32BytesRead)
+{
+ NMI_Uint32 u32Error = 0;
+ tstrFifoHandler * pstrFifoHandler = (tstrFifoHandler*)hFifo;
+ if(pstrFifoHandler && pu32BytesRead)
+ {
+ if(pstrFifoHandler->u32TotalBytes)
+ {
+ if(NMI_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, NMI_NULL) == NMI_SUCCESS)
+ {
+ if(u32BytesToRead > pstrFifoHandler->u32TotalBytes)
+ {
+ *pu32BytesRead = pstrFifoHandler->u32TotalBytes;
+ }
+ else
+ {
+ *pu32BytesRead = u32BytesToRead;
+ }
+ if((pstrFifoHandler->u32ReadOffset + u32BytesToRead) <= pstrFifoHandler->u32BufferLength)
+ {
+ NMI_memcpy(pu8Buffer,pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset,
+ *pu32BytesRead);
+ //update read offset and total bytes
+ pstrFifoHandler->u32ReadOffset += u32BytesToRead;
+ pstrFifoHandler->u32TotalBytes -= u32BytesToRead;
+
+ }
+ else
+ {
+ NMI_Uint32 u32FirstPart =
+ pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32ReadOffset;
+ NMI_memcpy(pu8Buffer,pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset,
+ u32FirstPart);
+ NMI_memcpy(pu8Buffer + u32FirstPart,pstrFifoHandler->pu8Buffer,
+ u32BytesToRead - u32FirstPart);
+ //update read offset and total bytes
+ pstrFifoHandler->u32ReadOffset = u32BytesToRead - u32FirstPart;
+ pstrFifoHandler->u32TotalBytes -= u32BytesToRead;
+ }
+ NMI_SemaphoreRelease(&pstrFifoHandler->SemBuffer, NMI_NULL);
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ return u32Error;
+}
+
+NMI_Uint32 FIFO_WriteBytes(tHANDLE hFifo,NMI_Uint8 *pu8Buffer,NMI_Uint32 u32BytesToWrite,NMI_Bool bForceOverWrite)
+{
+ NMI_Uint32 u32Error = 0;
+ tstrFifoHandler * pstrFifoHandler = (tstrFifoHandler*)hFifo;
+ if(pstrFifoHandler)
+ {
+ if(u32BytesToWrite < pstrFifoHandler->u32BufferLength)
+ {
+ if((pstrFifoHandler->u32TotalBytes + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength ||
+ bForceOverWrite)
+ {
+ if(NMI_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, NMI_NULL) == NMI_SUCCESS)
+ {
+ if((pstrFifoHandler->u32WriteOffset + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength)
+ {
+ NMI_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset,pu8Buffer,
+ u32BytesToWrite);
+ //update read offset and total bytes
+ pstrFifoHandler->u32WriteOffset += u32BytesToWrite;
+ pstrFifoHandler->u32TotalBytes += u32BytesToWrite;
+
+ }
+ else
+ {
+ NMI_Uint32 u32FirstPart =
+ pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32WriteOffset;
+ NMI_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset,pu8Buffer,
+ u32FirstPart);
+ NMI_memcpy(pstrFifoHandler->pu8Buffer,pu8Buffer + u32FirstPart,
+ u32BytesToWrite - u32FirstPart);
+ //update read offset and total bytes
+ pstrFifoHandler->u32WriteOffset = u32BytesToWrite - u32FirstPart;
+ pstrFifoHandler->u32TotalBytes += u32BytesToWrite;
+ }
+ //if data overwriten
+ if(pstrFifoHandler->u32TotalBytes > pstrFifoHandler->u32BufferLength)
+ {
+ //adjust read offset to the oldest data available
+ pstrFifoHandler->u32ReadOffset = pstrFifoHandler->u32WriteOffset;
+ //data availabe is the buffer length
+ pstrFifoHandler->u32TotalBytes = pstrFifoHandler->u32BufferLength;
+ }
+ NMI_SemaphoreRelease(&pstrFifoHandler->SemBuffer, NMI_NULL);
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ }
+ else
+ {
+ u32Error = 1;
+ }
+ return u32Error;
+} \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigSimulator.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigSimulator.h
new file mode 100755
index 00000000..8df2ab35
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigSimulator.h
@@ -0,0 +1,20 @@
+
+/*!
+* @file CoreConfigSimulator.h
+* @brief
+* @author
+* @sa CoreConfigSimulator.c
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+
+#ifndef CORECONFIGSIMULATOR_H
+#define CORECONFIGSIMULATOR_H
+
+
+extern NMI_Sint32 CoreConfigSimulatorInit(void);
+extern NMI_Sint32 CoreConfigSimulatorDeInit(void);
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigurator.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigurator.h
new file mode 100755
index 00000000..0a1080b8
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/CoreConfigurator.h
@@ -0,0 +1,506 @@
+
+/*!
+* @file CoreConfigurator.h
+* @brief
+* @author
+* @sa CoreConfigurator.c
+* @date 1 Mar 2012
+* @version 1.0
+*/
+
+
+#ifndef CORECONFIGURATOR_H
+#define CORECONFIGURATOR_H
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include "nmi_wlan_if.h"
+/*****************************************************************************/
+/* Constants */
+/*****************************************************************************/
+/* Number of WID Options Supported */
+#define NUM_BASIC_SWITCHES 45
+#define NUM_FHSS_SWITCHES 0
+
+#define NUM_RSSI 5
+
+#ifdef MAC_802_11N
+#define NUM_11N_BASIC_SWITCHES 25
+#define NUM_11N_HUT_SWITCHES 47
+#else /* MAC_802_11N */
+#define NUM_11N_BASIC_SWITCHES 0
+#define NUM_11N_HUT_SWITCHES 0
+#endif /* MAC_802_11N */
+
+extern NMI_Uint16 g_num_total_switches;
+
+#define MAC_HDR_LEN 24 /* No Address4 - non-ESS */
+#define MAX_SSID_LEN 33
+#define FCS_LEN 4
+#define TIME_STAMP_LEN 8
+#define BEACON_INTERVAL_LEN 2
+#define CAP_INFO_LEN 2
+#define STATUS_CODE_LEN 2
+#define AID_LEN 2
+#define IE_HDR_LEN 2
+
+
+/* Operating Mode: SET */
+#define SET_CFG 0
+/* Operating Mode: GET */
+#define GET_CFG 1
+
+#define MAX_PACKET_BUFF_SIZE 1596
+
+#define MAX_STRING_LEN 256
+#define MAX_SURVEY_RESULT_FRAG_SIZE MAX_STRING_LEN
+#define SURVEY_RESULT_LENGTH 44
+#define MAX_ASSOC_RESP_FRAME_SIZE MAX_STRING_LEN
+
+#define STATUS_MSG_LEN 12
+#define MAC_CONNECTED 1
+#define MAC_DISCONNECTED 0
+
+
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+#define MAKE_WORD16(lsb, msb) (((NMI_Uint16)(msb) << 8) & 0xFF00) | (lsb)
+#define MAKE_WORD32(lsw, msw) (((NMI_Uint32)(msw) << 16) & 0xFFFF0000) | (lsw)
+
+
+/*****************************************************************************/
+/* Type Definitions */
+/*****************************************************************************/
+/* WID Data Types */
+#if 0
+typedef enum {WID_CHAR = 0,
+ WID_SHORT = 1,
+ WID_INT = 2,
+ WID_STR = 3,
+ WID_ADR = 4,
+ WID_BIN = 5,
+ WID_IP = 6,
+ WID_UNDEF = 7,
+ WID_TYPE_FORCE_32BIT = 0xFFFFFFFF
+} tenuWIDtype;
+
+/* WLAN Identifiers */
+typedef enum {WID_NIL = -1,
+
+ /* EMAC Character WID list */
+ WID_BSS_TYPE = 0x0000,
+ WID_CURRENT_TX_RATE = 0x0001,
+ WID_CURRENT_CHANNEL = 0x0002,
+ WID_PREAMBLE = 0x0003,
+ WID_11G_OPERATING_MODE = 0x0004,
+ WID_STATUS = 0x0005,
+ WID_11G_PROT_MECH = 0x0006,
+ WID_SCAN_TYPE = 0x0007,
+ WID_PRIVACY_INVOKED = 0x0008,
+ WID_KEY_ID = 0x0009,
+ WID_QOS_ENABLE = 0x000A,
+ WID_POWER_MANAGEMENT = 0x000B,
+ WID_11I_MODE = 0x000C,
+ WID_AUTH_TYPE = 0x000D,
+ WID_SITE_SURVEY = 0x000E,
+ WID_LISTEN_INTERVAL = 0x000F,
+ WID_DTIM_PERIOD = 0x0010,
+ WID_ACK_POLICY = 0x0011,
+ WID_RESET = 0x0012,
+ WID_PCF_MODE = 0x0013,
+ WID_CFP_PERIOD = 0x0014,
+ WID_BCAST_SSID = 0x0015,
+ WID_PHY_TEST_PATTERN = 0x0016,
+ WID_DISCONNECT = 0x0016,
+ WID_READ_ADDR_SDRAM = 0x0017,
+ WID_TX_POWER_LEVEL_11A = 0x0018,
+ WID_REKEY_POLICY = 0x0019,
+ WID_SHORT_SLOT_ALLOWED = 0x001A,
+ WID_PHY_ACTIVE_REG = 0x001B,
+ WID_PHY_ACTIVE_REG_VAL = 0x001C,
+ WID_TX_POWER_LEVEL_11B = 0x001D,
+ WID_START_SCAN_REQ = 0x001E,
+ WID_RSSI = 0x001F,
+ WID_JOIN_REQ = 0x0020,
+ WID_ANTENNA_SELECTION = 0x0021,
+ WID_USER_CONTROL_ON_TX_POWER = 0x0027,
+ WID_MEMORY_ACCESS_8BIT = 0x0029,
+ WID_UAPSD_SUPPORT_AP = 0x002A,
+ WID_CURRENT_MAC_STATUS = 0x0031,
+ WID_AUTO_RX_SENSITIVITY = 0x0032,
+ WID_DATAFLOW_CONTROL = 0x0033,
+ WID_SCAN_FILTER = 0x0036,
+ WID_LINK_LOSS_THRESHOLD = 0x0037,
+ WID_AUTORATE_TYPE = 0x0038,
+ WID_CCA_THRESHOLD = 0x0039,
+ WID_802_11H_DFS_MODE = 0x003B,
+ WID_802_11H_TPC_MODE = 0x003C,
+ WID_DEVICE_READY = 0x003D,
+ WID_PM_NULL_FRAME_INTERVAL = 0x003E,
+ WID_PM_ACTIVITY_TIMER = 0x003F,
+ WID_PM_NULL_FRAME_WAIT_ENABLE = 0x0040,
+ WID_SCAN_WAIT_TIME = 0x0041,
+ WID_WSC_IE_EN = 0x0042,
+ WID_WPS_START = 0x0043,
+ WID_WPS_DEV_MODE = 0x0044,
+ WID_BT_COEXISTENCE = 0x0050,
+ WID_TRACKING_ROAMING = 0x0070,
+ WID_NUM_PKTS_FOR_RSSI_AVG = 0x0071,
+ WID_FHSS_SCAN_CHAN_INDEX = 0x0072,
+ WID_FHSS_SCAN_STEP_INDEX = 0x0073,
+
+ /* NMAC Character WID list */
+ WID_11N_PROT_MECH = 0x0080,
+ WID_11N_ERP_PROT_TYPE = 0x0081,
+ WID_11N_ENABLE = 0x0082,
+ WID_11N_OPERATING_MODE = 0x0083,
+ WID_11N_OBSS_NONHT_DETECTION = 0x0084,
+ WID_11N_HT_PROT_TYPE = 0x0085,
+ WID_11N_RIFS_PROT_ENABLE = 0x0086,
+ WID_11N_SMPS_MODE = 0x0087,
+ WID_11N_CURRENT_TX_MCS = 0x0088,
+ WID_11N_PRINT_STATS = 0x0089,
+ WID_HUT_FCS_CORRUPT_MODE = 0x008A,
+ WID_HUT_RESTART = 0x008B,
+ WID_HUT_TX_FORMAT = 0x008C,
+ WID_11N_SHORT_GI_20MHZ_ENABLE = 0x008D,
+ WID_HUT_BANDWIDTH = 0x008E,
+ WID_HUT_OP_BAND = 0x008F,
+ WID_HUT_STBC = 0x0090,
+ WID_HUT_ESS = 0x0091,
+ WID_HUT_ANTSET = 0x0092,
+ WID_HUT_HT_OP_MODE = 0x0093,
+ WID_HUT_RIFS_MODE = 0x0094,
+ WID_HUT_SMOOTHING_REC = 0x0095,
+ WID_HUT_SOUNDING_PKT = 0x0096,
+ WID_HUT_HT_CODING = 0x0097,
+ WID_HUT_TEST_DIR = 0x0098,
+ WID_HUT_CAPTURE_MODE = 0x0099,
+ WID_HUT_PHY_TEST_MODE = 0x009A,
+ WID_HUT_PHY_TEST_RATE_HI = 0x009B,
+ WID_HUT_PHY_TEST_RATE_LO = 0x009C,
+ WID_HUT_DISABLE_RXQ_REPLENISH = 0x009D,
+ WID_HUT_KEY_ORIGIN = 0x009E,
+ WID_HUT_BCST_PERCENT = 0x009F,
+ WID_HUT_GROUP_CIPHER_TYPE = 0x00A0,
+ WID_TX_ABORT_CONFIG = 0x00A1,
+ WID_HOST_DATA_IF_TYPE = 0x00A2,
+ WID_HOST_CONFIG_IF_TYPE = 0x00A3,
+ WID_HUT_TSF_TEST_MODE = 0x00A4,
+ WID_HUT_TSSI_VALUE = 0x00A5,
+ WID_HUT_PKT_TSSI_VALUE = 0x00A5,
+ WID_REG_TSSI_11B_VALUE = 0x00A6,
+ WID_REG_TSSI_11G_VALUE = 0x00A7,
+ WID_REG_TSSI_11N_VALUE = 0x00A8,
+ WID_TX_CALIBRATION = 0x00A9,
+ WID_DSCR_TSSI_11B_VALUE = 0x00AA,
+ WID_DSCR_TSSI_11G_VALUE = 0x00AB,
+ WID_DSCR_TSSI_11N_VALUE = 0x00AC,
+ WID_HUT_RSSI_EX = 0x00AD,
+ WID_HUT_ADJ_RSSI_EX = 0x00AE,
+ WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF,
+ WID_11N_TXOP_PROT_DISABLE = 0x00B0,
+ WID_TX_POWER_LEVEL_11N = 0x00B1,
+ WID_HUT_MGMT_PERCENT = 0x00B3,
+ WID_HUT_MGMT_BCST_PERCENT = 0x00B4,
+ WID_HUT_MGMT_ALLOW_HT = 0x00B5,
+ WID_HUT_UC_MGMT_TYPE = 0x00B6,
+ WID_HUT_BC_MGMT_TYPE = 0x00B7,
+ WID_HUT_11W_MFP_REQUIRED_TX = 0x00B8,
+ WID_HUT_11W_MFP_PEER_CAPABLE = 0x00B9,
+ WID_HUT_11W_TX_IGTK_ID = 0x00BA,
+ WID_11W_ENABLE = 0x00BB,
+ WID_11W_MGMT_PROT_REQ = 0x00BC,
+ WID_USER_SEC_CHANNEL_OFFSET = 0x00C0,
+ WID_2040_COEXISTENCE = 0x00C1,
+ WID_HUT_FC_TXOP_MOD = 0x00C2,
+ WID_HUT_FC_PROT_TYPE = 0x00C3,
+ WID_HUT_SEC_CCA_ASSERT = 0x00C4,
+ WID_2040_ENABLE = 0x00C5,
+ WID_2040_CURR_CHANNEL_OFFSET = 0x00C6,
+ WID_2040_40MHZ_INTOLERANT = 0x00C7,
+
+
+ /* Custom Character WID list */
+ WID_POWER_SAVE = 0x0100,
+ WID_WAKE_STATUS = 0x0101,
+ WID_WAKE_CONTROL = 0x0102,
+ WID_CCA_BUSY_START = 0x0103,
+
+ /* EMAC Short WID list */
+ WID_RTS_THRESHOLD = 0x1000,
+ WID_FRAG_THRESHOLD = 0x1001,
+ WID_SHORT_RETRY_LIMIT = 0x1002,
+ WID_LONG_RETRY_LIMIT = 0x1003,
+ WID_CFP_MAX_DUR = 0x1004,
+ WID_PHY_TEST_FRAME_LEN = 0x1005,
+ WID_BEACON_INTERVAL = 0x1006,
+ WID_MEMORY_ACCESS_16BIT = 0x1008,
+ WID_RX_SENSE = 0x100B,
+ WID_ACTIVE_SCAN_TIME = 0x100C,
+ WID_PASSIVE_SCAN_TIME = 0x100D,
+ WID_SITE_SURVEY_SCAN_TIME = 0x100E,
+ WID_JOIN_START_TIMEOUT = 0x100F,
+ WID_AUTH_TIMEOUT = 0x1010,
+ WID_ASOC_TIMEOUT = 0x1011,
+ WID_11I_PROTOCOL_TIMEOUT = 0x1012,
+ WID_EAPOL_RESPONSE_TIMEOUT = 0x1013,
+ WID_WPS_PASS_ID = 0x1017,
+ WID_WPS_CONFIG_METHOD = 0x1018,
+ WID_FHSS_INIT_SCAN_TIME = 0x1070,
+ WID_FHSS_ROAM_SCAN_TIME = 0x1071,
+
+ /* NMAC Short WID list */
+ WID_11N_RF_REG_VAL = 0x1080,
+ WID_HUT_FRAME_LEN = 0x1081,
+ WID_HUT_TXOP_LIMIT = 0x1082,
+ WID_HUT_SIG_QUAL_AVG = 0x1083,
+ WID_HUT_SIG_QUAL_AVG_CNT = 0x1084,
+ WID_11N_SIG_QUAL_VAL = 0x1085,
+ WID_HUT_RSSI_EX_COUNT = 0x1086,
+ WID_HUT_UC_MGMT_FRAME_LEN = 0x1088,
+ WID_HUT_BC_MGMT_FRAME_LEN = 0x1089,
+
+ /* Custom Short WID list */
+
+ WID_CCA_BUSY_STATUS = 0x1100,
+
+ /* EMAC Integer WID list */
+ WID_FAILED_COUNT = 0x2000,
+ WID_RETRY_COUNT = 0x2001,
+ WID_MULTIPLE_RETRY_COUNT = 0x2002,
+ WID_FRAME_DUPLICATE_COUNT = 0x2003,
+ WID_ACK_FAILURE_COUNT = 0x2004,
+ WID_RECEIVED_FRAGMENT_COUNT = 0x2005,
+ WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006,
+ WID_FCS_ERROR_COUNT = 0x2007,
+ WID_SUCCESS_FRAME_COUNT = 0x2008,
+ WID_PHY_TEST_PKT_CNT = 0x2009,
+ WID_HUT_TX_COUNT = 0x200A,
+ WID_TX_FRAGMENT_COUNT = 0x200B,
+ WID_TX_MULTICAST_FRAME_COUNT = 0x200C,
+ WID_RTS_SUCCESS_COUNT = 0x200D,
+ WID_RTS_FAILURE_COUNT = 0x200E,
+ WID_WEP_UNDECRYPTABLE_COUNT = 0x200F,
+ WID_REKEY_PERIOD = 0x2010,
+ WID_REKEY_PACKET_COUNT = 0x2011,
+ WID_1X_SERV_ADDR = 0x2012,
+ WID_STACK_IP_ADDR = 0x2013,
+ WID_STACK_NETMASK_ADDR = 0x2014,
+ WID_HW_RX_COUNT = 0x2015,
+ WID_MEMORY_ADDRESS = 0x201E,
+ WID_MEMORY_ACCESS_32BIT = 0x201F,
+ WID_RF_REG_VAL = 0x2021,
+ WID_FIRMWARE_INFO = 0x2023,
+ WID_DEV_OS_VERSION = 0x2025,
+ WID_ROAM_RSSI_THESHOLDS = 0x2070,
+ WID_TRACK_INTERVAL_SEC = 0x2071,
+ WID_FHSS_HOPPING_PARAMS = 0x2072,
+ WID_FHSS_HOP_DWELL_TIME = 0x2073,
+
+ /* NMAC Integer WID list */
+ WID_11N_PHY_ACTIVE_REG_VAL = 0x2080,
+ WID_HUT_NUM_TX_PKTS = 0x2081,
+ WID_HUT_TX_TIME_TAKEN = 0x2082,
+ WID_HUT_TX_TEST_TIME = 0x2083,
+ WID_HUT_LOG_INTERVAL = 0x2084,
+
+ /* EMAC String WID list */
+ WID_SSID = 0x3000,
+ WID_FIRMWARE_VERSION = 0x3001,
+ WID_OPERATIONAL_RATE_SET = 0x3002,
+ WID_BSSID = 0x3003,
+#if 0
+ WID_WEP_KEY_VALUE0 = 0x3004,
+#endif
+ WID_11I_PSK = 0x3008,
+ WID_11E_P_ACTION_REQ = 0x3009,
+ WID_1X_KEY = 0x300A,
+ WID_HARDWARE_VERSION = 0x300B,
+ WID_MAC_ADDR = 0x300C,
+ WID_HUT_DEST_ADDR = 0x300D,
+ /*WID_HUT_STATS = 0x300E,*/
+ WID_PHY_VERSION = 0x300F,
+ WID_SUPP_USERNAME = 0x3010,
+ WID_SUPP_PASSWORD = 0x3011,
+ WID_SITE_SURVEY_RESULTS = 0x3012,
+ WID_RX_POWER_LEVEL = 0x3013,
+ WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */
+ WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */
+ WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */
+ WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */
+
+ WID_ASSOC_RES_INFO = 0x3020,
+
+ /* NMAC String WID list */
+ WID_11N_P_ACTION_REQ = 0x3080,
+ WID_HUT_TEST_ID = 0x3081,
+ WID_PMKID_INFO = 0x3082,
+
+ /* Custom String WID list */
+ WID_FLASH_DATA = 0x3100,
+ WID_EEPROM_DATA = 0x3101,
+ WID_SERIAL_NUMBER = 0x3102,
+
+ /* EMAC Binary WID list */
+ WID_UAPSD_CONFIG = 0x4001,
+ WID_UAPSD_STATUS = 0x4002,
+ WID_AC_PARAMS_AP = 0x4003,
+ WID_AC_PARAMS_STA = 0x4004,
+ WID_NEWORK_INFO = 0x4005,
+ WID_WPS_CRED_LIST = 0x4006,
+ WID_PRIM_DEV_TYPE = 0x4007,
+ WID_STA_JOIN_INFO = 0x4008,
+ WID_CONNECTED_STA_LIST = 0x4009,
+
+ /* NMAC Binary WID list */
+ WID_11N_AUTORATE_TABLE = 0x4080,
+ WID_HUT_TX_PATTERN = 0x4081,
+ WID_HUT_STATS = 0x4082,
+ WID_HUT_LOG_STATS = 0x4083,
+
+ /*BugID_3746 WID to add IE to be added in next probe request*/
+ WID_INFO_ELEMENT_PROBE = 0x4085,
+ /*BugID_3746 WID to add IE to be added in next associate request*/
+ WID_INFO_ELEMENT_ASSOCIATE = 0x4086,
+
+ /* Miscellaneous WIDs */
+ WID_ALL = 0x7FFE,
+ WID_MAX = 0xFFFF
+} tenuWIDid;
+#endif
+
+/* Status Codes for Authentication and Association Frames */
+typedef enum
+{
+ SUCCESSFUL_STATUSCODE = 0,
+ UNSPEC_FAIL = 1,
+ UNSUP_CAP = 10,
+ REASOC_NO_ASOC = 11,
+ FAIL_OTHER = 12,
+ UNSUPT_ALG = 13,
+ AUTH_SEQ_FAIL = 14,
+ CHLNG_FAIL = 15,
+ AUTH_TIMEOUT = 16,
+ AP_FULL = 17,
+ UNSUP_RATE = 18,
+ SHORT_PREAMBLE_UNSUP = 19,
+ PBCC_UNSUP = 20,
+ CHANNEL_AGIL_UNSUP = 21,
+ SHORT_SLOT_UNSUP = 25,
+ OFDM_DSSS_UNSUP = 26,
+ CONNECT_STS_FORCE_16_BIT = 0xFFFF
+} tenuConnectSts;
+
+typedef struct
+{
+ NMI_Uint16 u16WIDid;
+ tenuWIDtype enuWIDtype;
+ NMI_Sint32 s32ValueSize;
+ NMI_Sint8 *ps8WidVal;
+
+}tstrWID;
+
+typedef struct
+{
+ NMI_Uint8 u8Full;
+ NMI_Uint8 u8Index;
+ NMI_Sint8 as8RSSI[NUM_RSSI];
+}tstrRSSI;
+/* This structure is used to support parsing of the received 'N' message */
+typedef struct
+{
+ NMI_Sint8 s8rssi;
+ NMI_Uint16 u16CapInfo;
+ NMI_Uint8 au8ssid[MAX_SSID_LEN];
+ NMI_Uint8 u8SsidLen;
+ NMI_Uint8 au8bssid[6];
+ NMI_Uint16 u16BeaconPeriod;
+ NMI_Uint8 u8DtimPeriod;
+ NMI_Uint8 u8channel;
+ unsigned long u32TimeRcvdInScanCached; /* of type unsigned long to be accepted by the linux kernel macro time_after() */
+ unsigned long u32TimeRcvdInScan;
+ NMI_Bool bNewNetwork;
+#ifdef AGING_ALG
+ NMI_Uint8 u8Found;
+#endif
+#ifdef NMI_P2P
+ NMI_Uint32 u32Tsf;
+#endif
+ NMI_Uint8 *pu8IEs;
+ NMI_Uint16 u16IEsLen;
+ void* pJoinParams;
+ tstrRSSI strRssi;
+ NMI_Uint64 u64Tsf; /* time-stamp [Low and High 64 bit] */
+}tstrNetworkInfo;
+
+/* This structure is used to support parsing of the received Association Response frame */
+typedef struct
+{
+ NMI_Uint16 u16capability;
+ NMI_Uint16 u16ConnectStatus;
+ NMI_Uint16 u16AssocID;
+ NMI_Uint8 *pu8RespIEs;
+ NMI_Uint16 u16RespIEsLen;
+}tstrConnectRespInfo;
+
+
+typedef struct
+{
+ NMI_Uint8 au8bssid[6];
+ NMI_Uint8* pu8ReqIEs;
+ size_t ReqIEsLen;
+ NMI_Uint8 *pu8RespIEs;
+ NMI_Uint16 u16RespIEsLen;
+ NMI_Uint16 u16ConnectStatus;
+}tstrConnectInfo;
+
+
+
+typedef struct
+{
+ NMI_Uint16 u16reason;
+ NMI_Uint8 * ie;
+ size_t ie_len;
+}tstrDisconnectNotifInfo;
+
+#ifndef CONNECT_DIRECT
+typedef struct wid_site_survey_reslts
+{
+ NMI_Char SSID[MAX_SSID_LEN];
+ NMI_Uint8 BssType;
+ NMI_Uint8 Channel;
+ NMI_Uint8 SecurityStatus;
+ NMI_Uint8 BSSID[6];
+ NMI_Char RxPower;
+ NMI_Uint8 Reserved;
+
+}wid_site_survey_reslts_s;
+#endif
+
+extern NMI_Sint32 CoreConfiguratorInit(void);
+extern NMI_Sint32 CoreConfiguratorDeInit(void);
+
+extern NMI_Sint32 SendConfigPkt(NMI_Uint8 u8Mode, tstrWID* pstrWIDs,
+ NMI_Uint32 u32WIDsCount,NMI_Bool bRespRequired,NMI_Uint32 drvHandler);
+extern NMI_Sint32 ParseNetworkInfo(NMI_Uint8* pu8MsgBuffer, tstrNetworkInfo** ppstrNetworkInfo);
+extern NMI_Sint32 DeallocateNetworkInfo(tstrNetworkInfo* pstrNetworkInfo);
+
+extern NMI_Sint32 ParseAssocRespInfo(NMI_Uint8* pu8Buffer, NMI_Uint32 u32BufferLen,
+ tstrConnectRespInfo** ppstrConnectRespInfo);
+extern NMI_Sint32 DeallocateAssocRespInfo(tstrConnectRespInfo* pstrConnectRespInfo);
+
+#ifndef CONNECT_DIRECT
+extern NMI_Sint32 ParseSurveyResults(NMI_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
+ wid_site_survey_reslts_s** ppstrSurveyResults,
+ NMI_Uint32* pu32SurveyResultsCount);
+extern NMI_Sint32 DeallocateSurveyResults(wid_site_survey_reslts_s* pstrSurveyResults);
+#endif
+
+extern NMI_Sint32 SendRawPacket(NMI_Sint8* pspacket, NMI_Sint32 s32PacketLen);
+extern void NetworkInfoReceived(NMI_Uint8* pu8Buffer,NMI_Uint32 u32Length);
+void GnrlAsyncInfoReceived(NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length);
+void host_int_ScanCompleteReceived(NMI_Uint8 * pu8Buffer, NMI_Uint32 u32Length);
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/FIFO_Buffer.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/FIFO_Buffer.h
new file mode 100755
index 00000000..086ca1ac
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/FIFO_Buffer.h
@@ -0,0 +1,23 @@
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+
+#define tHANDLE void *
+
+typedef struct
+{
+ NMI_Uint8 *pu8Buffer;
+ NMI_Uint32 u32BufferLength;
+ NMI_Uint32 u32WriteOffset;
+ NMI_Uint32 u32ReadOffset;
+ NMI_Uint32 u32TotalBytes;
+ NMI_SemaphoreHandle SemBuffer;
+}tstrFifoHandler;
+
+
+extern NMI_Uint32 FIFO_InitBuffer(tHANDLE * hBuffer,NMI_Uint32 u32BufferLength);
+extern NMI_Uint32 FIFO_DeInit(tHANDLE hFifo);
+extern NMI_Uint32 FIFO_ReadBytes(tHANDLE hFifo,NMI_Uint8 *pu8Buffer,NMI_Uint32 u32BytesToRead,
+ NMI_Uint32 *pu32BytesRead);
+extern NMI_Uint32 FIFO_WriteBytes(tHANDLE hFifo,NMI_Uint8 *pu8Buffer,NMI_Uint32 u32BytesToWrite,
+ NMI_Bool bForceOverWrite); \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/NMI_host_AP.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/NMI_host_AP.h
new file mode 100755
index 00000000..9b5c839d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/NMI_host_AP.h
@@ -0,0 +1,422 @@
+#ifndef __NMI_HOST_AP__
+#define __NMI_HOST_AP__
+
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+#include "host_interface.h"
+#include "../linux/include/NMI_WFI_NetDevice.h"
+
+#ifdef NMI_FULLY_HOSTING_AP
+/*!
+* @file NMI_host_AP.h
+* @brief code related to AP fully hosting mode on NMI driver
+* @author Abd Al-Rahman Diab
+* @date 09 APRIL 2013
+* @version 1.0
+*/
+
+
+#define ITIM 5 /* Traffic Information Map */
+#define DEFAULT_TIM_LEN 4
+#define FCS_LEN 4
+#define VBMAP_SIZE 256
+
+#define MAX_LISTEN_INT 10
+#define VBMAP_SIZE 256
+#define MIN_TIM_LEN 4
+#define PS_PKT_Q_MAX_LEN 16
+#define PS_BUFF_TO 500 /* Time out for discarding a packets in */
+ /* PS queues in millisecs */
+#define AGING_THR_IN_SEC 60 /* 60 Seconds */
+
+#define WORD_OFFSET_4 4
+#define TX_DSCR_NEXT_ADDR_WORD_OFFSET WORD_OFFSET_4
+
+
+#define WIFI_PERIPH_BASE 0x00000000
+#define WIFI_PA_BASE (WIFI_PERIPH_BASE+0x9800)
+#define PA_BASE WIFI_PA_BASE
+
+#define rMAC_DTIM_COUNT_ADDR (( NMI_Uint32 )(PA_BASE + 0x021C))
+#define rMAC_BEACON_PERIOD (( NMI_Uint32 )(PA_BASE + 0x020C))
+#define rMAC_DTIM_PERIOD (( NMI_Uint32 )(PA_BASE + 0x0210))
+#define rMAC_TSF_CON (( NMI_Uint32 )(PA_BASE + 0x0200))
+
+
+#define BEST_EFFORT_PRIORITY 0
+
+#define NORMAL_ACK 0
+#define BCAST_NO_ACK 4
+
+
+#define PROTOCOL_VERSION 0x00
+#define MAX_MSDU_LEN 1596
+#define PS_POLL_LEN 20
+
+
+#define QOS_CTRL_FIELD_LEN 2
+#define HT_CTRL_FIELD_LEN 4 /* Length of HT Control Field */
+
+#define IS_MANAGMEMENT 0x100
+#define IS_MANAGMEMENT_CALLBACK 0x080
+#define IS_MGMT_STATUS_SUCCES 0x040
+#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
+
+
+/* Maximum number of hash values possible for the Sta Entry Table */
+#define MAX_HASH_VALUES 16
+
+
+#define SNAP_HDR_ID_LEN 6
+
+#define ETH_PKT_TYPE_OFFSET 12
+#define IP_TYPE 0x0800
+#define ARP_TYPE 0x0806
+#define ONE_X_TYPE 0x888E
+#define VLAN_TYPE 0x8100
+#define LLTD_TYPE 0x88D9
+#define UDP_TYPE 0x11
+#define TCP_TYPE 0x06
+
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+#define NEXT_ELEMENT_ADDR(base, ofst) (*((NMI_Uint32 *)((NMI_Uint8 *)base + ofst)))
+
+
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+/* Basic Frame Type Codes (2-bit) */
+typedef enum {CONTROL = 0x04,
+ DATA_BASICTYPE = 0x08,
+ MANAGEMENT = 0x00,
+ RESERVED = 0x0C
+} BASICTYPE_T;
+
+typedef enum {ACTIVE_PS = 0,
+ POWER_SAVE = 1
+} STA_PS_STATE_T;
+
+
+typedef enum {AID0_BIT = 0,
+ DTIM_BIT = 1
+} TIMBIT_T;
+
+
+typedef enum {RE_Q_ERROR = 0,
+ NO_PKT_IN_QUEUE = 1,
+ PKT_REQUEUED = 2,
+ END_OF_QUEUE = 3,
+ PKT_NOT_REQUEUED = 4
+} REQUEUE_STATUS_T;
+
+
+/* Data Pathes */
+typedef enum {HOST_TO_WLAN = 0,
+ WLAN_TO_WLAN = 1,
+ MONITOR_TO_WLAN = 2
+} Data_Interface;
+
+/* Capability Information field bit assignments */
+typedef enum{ESS = 0x01, /* ESS capability */
+ IBSS = 0x02, /* IBSS mode */
+ POLLABLE = 0x04, /* CF Pollable */
+ POLLREQ = 0x08, /* Request to be polled */
+ PRIVACY = 0x10, /* WEP encryption supported */
+ SHORTPREAMBLE = 0x20, /* Short Preamble is supported */
+ SHORTSLOT = 0x400, /* Short Slot is supported */
+ PBCC = 0x40, /* PBCC */
+ CHANNELAGILITY = 0x80, /* Channel Agility */
+ SPECTRUM_MGMT = 0x100, /* Spectrum Management */
+ DSSS_OFDM = 0x2000 /* DSSS-OFDM */
+} CAPABILITY_T;
+
+/* Authentication/Association states of STAs maintained by the Access Point */
+typedef enum {AUTH_COMPLETE = 1, /* Authenticated */
+ AUTH_KEY_SEQ1 = 2, /* Shared Key Auth (Sequence 1) done */
+ ASOC = 3 /* Associated */
+} STATIONSTATE_T;
+
+typedef enum {TYPE_OFFSET = 0,
+ LENGTH_OFFSET = 1,
+ DTIM_CNT_OFFSET = 2,
+ DTIM_PERIOD_OFFSET = 3,
+ BMAP_CTRL_OFFSET = 4,
+ TIM_OFFSET = 5
+} OFFSET_T;
+
+/* Frame Type and Subtype Codes (6-bit) */
+typedef enum {ASSOC_REQ = 0x00,
+ ASSOC_RSP = 0x10,
+ REASSOC_REQ = 0x20,
+ REASSOC_RSP = 0x30,
+ PROBE_REQ = 0x40,
+ PROBE_RSP = 0x50,
+ BEACON = 0x80,
+ ATIM = 0x90,
+ DISASOC = 0xA0,
+ AUTH = 0xB0,
+ DEAUTH = 0xC0,
+ ACTION = 0xD0,
+ PS_POLL = 0xA4,
+ RTS = 0xB4,
+ CTS = 0xC4,
+ ACK = 0xD4,
+ CFEND = 0xE4,
+ CFEND_ACK = 0xF4,
+ DATA = 0x08,
+ DATA_ACK = 0x18,
+ DATA_POLL = 0x28,
+ DATA_POLL_ACK = 0x38,
+ NULL_FRAME = 0x48,
+ CFACK = 0x58,
+ CFPOLL = 0x68,
+ CFPOLL_ACK = 0x78,
+ QOS_DATA = 0x88,
+ QOS_DATA_ACK = 0x98,
+ QOS_DATA_POLL = 0xA8,
+ QOS_DATA_POLL_ACK = 0xB8,
+ QOS_NULL_FRAME = 0xC8,
+ QOS_CFPOLL = 0xE8,
+ QOS_CFPOLL_ACK = 0xF8,
+ BLOCKACK_REQ = 0x84,
+ BLOCKACK = 0x94
+} TYPESUBTYPE_T;
+
+
+/*****************************************************************************/
+/* Structures */
+/*****************************************************************************/
+
+typedef struct _q_entry_t
+{
+ void *fa; /* Pointer to the element in the queue */
+ struct _q_entry_t *tqe_next; /* Pointer to the next element */
+ struct _q_entry_t *tqe_prev; /* Pointer to the previous element */
+} q_entry_t;
+
+typedef struct
+{
+ q_entry_t *head;
+ q_entry_t *tail;
+} q_head_t;
+
+typedef struct
+{
+ void *head; /* Head Element of the List */
+ void *tail; /* Tail Element of the List */
+ NMI_Uint16 count; /* Number of Elements in the List */
+ NMI_Uint16 lnk_byte_ofst; /* Offset to Link Pointer in the List in Bytes */
+} list_buff_t;
+
+
+/* Basic rate set. This contains the set of basic rates supported by any */
+/* IBSS. */
+typedef struct
+{
+ NMI_Uint8 rates[MAX_RATES_SUPPORTED];
+ NMI_Uint8 num_rates;
+} rate_t;
+
+typedef struct {
+ int size;
+ void* buff;
+}beacon_data;
+
+typedef struct {
+ NMI_Uint16 u16beacon_len;
+ NMI_Uint8 *u8beacon_frame;
+ NMI_Uint8 u8tim_element_index;
+ NMI_Uint16 u16tim_element_trailer_len;
+ NMI_Uint8 u8vbmap[VBMAP_SIZE];
+ NMI_Uint8 u8DTIMPeriod;
+ NMI_Uint16 u16Beacon_Period;
+}beacon_info;
+
+typedef struct
+{
+ NMI_Uint8 service_class; /* Service class extracted from header */
+ NMI_Uint8 priority_val; /* Priority value extracted from header */
+ NMI_Uint8 u8hdr_len; /* Length of header including offset */
+ NMI_Uint16 u16data_len; /* Length of the frame excluding headers */
+ NMI_Uint16 u16rx_len; /* Length of the frame including the headers */
+ NMI_Uint8 *u8sa_entry; /* Source Address station entry */
+ NMI_Uint8 *u8msa; /* MAC header start address */
+ NMI_Uint8 u8addr1[6]; /* Address1 field extracted from header */
+ NMI_Uint8 u8addr2[6]; /* Address2 field extracted from header */
+ NMI_Uint8 u8addr3[6]; /* Address3 field extracted from header */
+ NMI_Uint8 *u8sa; /* Pointer to source address */
+ NMI_Uint8 *u8da; /* Pointer to destination address */
+ NMI_Uint8 *u8bssid; /* Pointer to BSSID */
+ NMI_Uint8 *u8ta; /* Pointer to Transmitter address */
+ BASICTYPE_T enumType; /* Packet type extracted from the header */
+ NMI_Uint8 u8Sub_type; /* Packet Sub type extracted from the header */
+ NMI_Uint8 u8frm_ds; /* From DS field of MAC header */
+ NMI_Uint8 u8to_ds; /* To DS field of MAC header */
+ NMI_Bool bIs_grp_addr; /* Group address flag */
+} wlan_rx_t;
+
+typedef struct {
+ int quit;
+
+ /**
+ input interface functions
+ **/
+ nmi_wlan_os_func_t os_func;
+ nmi_wlan_io_func_t io_func;
+ nmi_wlan_net_func_t net_func;
+ nmi_wlan_indicate_func_t indicate_func;
+
+ /**
+ host interface functions
+ **/
+ nmi_hif_func_t hif_func;
+ void *hif_lock;
+
+ /**
+ configuration interface functions
+ **/
+ nmi_cfg_func_t cif_func;
+ int cfg_frame_in_use;
+ nmi_cfg_frame_t cfg_frame;
+ uint32_t cfg_frame_offset;
+ int cfg_seq_no;
+ void *cfg_wait;
+
+ /**
+ RX buffer
+ **/
+ uint32_t rx_buffer_size;
+ //uint8_t *rx_buffer;
+ //uint32_t rx_buffer_offset;
+
+ /**
+ TX buffer
+ **/
+ uint32_t tx_buffer_size;
+ uint8_t *tx_buffer;
+ uint32_t tx_buffer_offset;
+
+ /**
+ TX queue
+ **/
+ void *txq_lock;
+
+ /*Added by Amr - BugID_4720*/
+ void *txq_add_to_head_lock;
+ void *txq_spinlock;
+ unsigned long txq_spinlock_flags;
+
+ struct txq_entry_t *txq_head;
+ struct txq_entry_t *txq_tail;
+ int txq_entries;
+ void *txq_wait;
+ int txq_exit;
+
+ /**
+ RX queue
+ **/
+ void *rxq_lock;
+ struct rxq_entry_t *rxq_head;
+ struct rxq_entry_t *rxq_tail;
+ int rxq_entries;
+ void *rxq_wait;
+ int rxq_exit;
+
+#if DMA_VER == DMA_VER_2
+ int use_dma_v2;
+#endif
+} nmi_wlan_dev_t;
+
+
+typedef struct {
+ u32 supp_rates[IEEE80211_NUM_BANDS];
+ NMI_Uint8 addr[ETH_ALEN]; /* MAC address of the STA */
+ NMI_Uint16 u16AID; /* Association ID of the STA */
+ STATIONSTATE_T state; /* Auth/Asoc state of the STA */
+ struct ieee80211_sta_ht_cap ht_cap;
+ //struct ieee80211_sta_vht_cap vht_cap;
+ NMI_Uint32 aging_cnt; /* Aging cnt for STA */
+ rate_t op_rates; /* Operational rates of the STA */
+ STA_PS_STATE_T ps_state; /* Power save state of the STA */
+
+ list_buff_t ps_q_lgcy; /* Power save queue for the STA */
+ NMI_Uint16 num_ps_pkt; /* Number of UC pkts queued in PSQ */
+ NMI_Uint16 num_qd_pkt; /* Number of UC pkts queued in HW */
+ NMI_Bool ps_poll_rsp_qed; /* Flag to indicate PS poll rsp is */
+ /* already queued and pending */
+
+} NMI_ieee80211_sta;
+
+#if 0
+/* Association element structure. This is the element structure to which the */
+/* element pointers of the association table entries point. */
+typedef struct
+{
+
+
+
+
+ NMI_Uint16 listen_interval; /* Listen Interval of the STA */
+
+
+
+} asoc_entry_t;
+#endif
+
+typedef struct table_elmnt_t
+{
+ NMI_Uint8 key[6]; /* Key, i.e. the MAC address */
+ void* element; /* Pointer to the table element */
+ struct table_elmnt_t* next_hash_elmnt; /* Pointer to next bucket element */
+} table_elmnt_t;
+
+/*****************************************************************************/
+/* Data Types */
+/*****************************************************************************/
+
+typedef table_elmnt_t* table_t[MAX_HASH_VALUES];
+
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+extern table_t g_sta_table;
+extern linux_wlan_t* g_linux_wlan;
+
+
+ NMI_Sint32 host_add_beacon(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,
+ NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8Tail);
+
+ NMI_Sint32 host_del_beacon(NMI_WFIDrvHandle hWFIDrv);
+
+inline void NMI_AP_AddSta(u8 *mac, struct station_parameters *params);
+inline void NMI_AP_EditSta(u8 *mac, struct station_parameters *params);
+inline void NMI_AP_RemoveSta(u8 *mac);
+
+ void process_tbtt_isr(void);
+
+ nmi_wlan_dev_t* Get_wlan_context(NMI_Uint16* pu16size);
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+int nmi_wlan_txq_add_mgmt_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, nmi_tx_complete_func_t func);
+#endif
+
+int nmi_FH_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, nmi_tx_complete_func_t func);
+
+void NMI_Process_rx_frame(NMI_Uint8 *u8Buff, NMI_Uint32 u32Size);
+
+int NMI_Xmit_data(void* ptx_data, Data_Interface InterfaceType);
+
+NMI_Bool filter_monitor_data_frames(NMI_Uint8 *buf, NMI_Uint16 len);
+
+#endif // NMI_FULLY_HOSTING_AP
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/host_interface.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/host_interface.h
new file mode 100755
index 00000000..a1f051b9
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/host_interface.h
@@ -0,0 +1,1341 @@
+/*!
+* @file host_interface.h
+* @brief File containg host interface APIs
+* @author zsalah
+* @sa host_interface.c
+* @date 8 March 2012
+* @version 1.0
+*/
+
+#ifndef HOST_INT_H
+#define HOST_INT_H
+
+#include "CoreConfigurator.h"
+#include "CoreConfigSimulator.h"
+/*****************************************************************************/
+/* Macros */
+/*****************************************************************************/
+#if 0
+#define WID_BSS_TYPE 0x0000
+#define WID_CURRENT_TX_RATE 0x0001
+#define WID_CURRENT_CHANNEL 0x0002
+#define WID_PREAMBLE 0x0003
+#define WID_STATUS 0x0005
+#define WID_SCAN_TYPE 0x0007
+#define WID_KEY_ID 0x0009
+#define WID_DTIM_PERIOD 0x0010
+#define WID_POWER_MANAGEMENT 0x000B
+#define WID_AUTH_TYPE 0x000D
+#define WID_SITE_SURVEY 0x000E
+#define WID_DTIM_PERIOD 0x0010
+#define WID_DISCONNECT 0x0016
+#define WID_SHORT_SLOT_ALLOWED 0x001A
+#define WID_START_SCAN_REQ 0x001E
+#define WID_RSSI 0x001F
+#define WID_JOIN_REQ 0x0020
+#define WID_11N_TXOP_PROT_DISABLE 0x00B0
+#define WID_RTS_THRESHOLD 0x1000
+#define WID_FRAG_THRESHOLD 0x1001
+#define WID_SHORT_RETRY_LIMIT 0x1002
+#define WID_LONG_RETRY_LIMIT 0x1003
+#define WID_BEACON_INTERVAL 0x1006
+#define WID_ACTIVE_SCAN_TIME 0x100C
+#define WID_PASSIVE_SCAN_TIME 0x100D
+#define WID_SITE_SURVEY_SCAN_TIME 0x100E
+#define WID_AUTH_TIMEOUT 0x1010
+#define WID_11I_PSK 0x3008
+#define WID_SITE_SURVEY_RESULTS 0x3012
+#define WID_ADD_PTK 0x301B
+#define WID_ADD_RX_GTK 0x301C
+#define WID_ADD_TX_GTK 0x301D
+#define WID_ADD_WEP_KEY 0x3019
+#define WID_REMOVE_WEP_KEY 0x301A
+#define WID_REMOVE_KEY 0x301E
+#define WID_ASSOC_REQ_INFO 0x301F
+#define WID_ASSOC_RES_INFO 0x3020
+#define WID_PMKID_INFO 0x3082
+#define WID_SCAN_CHANNEL_LIST 0x4084
+#define WID_11I_MODE 0x000C
+#endif
+#define FAIL 0x0000
+#define SUCCESS 0x0001
+
+#define IP_ALEN 4
+
+#define BIT2 ((NMI_Uint32)(1 << 2))
+#define BIT1 ((NMI_Uint32)(1 << 1))
+#define BIT0 ((NMI_Uint32)(1 << 0))
+
+#define AP_MODE 0x01
+#define STATION_MODE 0x02
+#define GO_MODE 0x03
+#define CLIENT_MODE 0x04
+
+
+#define MAX_NUM_STA 8
+#define ACTIVE_SCAN_TIME 10
+#define PASSIVE_SCAN_TIME 1200
+#define MIN_SCAN_TIME 10
+#define MAX_SCAN_TIME 1200
+#define DEFAULT_SCAN 0
+#define USER_SCAN BIT0
+#define OBSS_PERIODIC_SCAN BIT1
+#define OBSS_ONETIME_SCAN BIT2
+#define GTK_RX_KEY_BUFF_LEN 24
+#define ADDKEY 0x1
+#define REMOVEKEY 0x2
+#define DEFAULTKEY 0x4
+#define ADDKEY_AP 0x8
+#define MAX_NUM_SCANNED_NETWORKS 100 //30 // rachel
+#define MAX_NUM_SCANNED_NETWORKS_SHADOW 130
+#define MAX_NUM_PROBED_SSID 10 /*One more than the number of scanned ssids*/
+#define CHANNEL_SCAN_TIME 250//250
+
+#define TX_MIC_KEY_LEN 8
+#define RX_MIC_KEY_LEN 8
+#define PTK_KEY_LEN 16
+
+#define TX_MIC_KEY_MSG_LEN 26
+#define RX_MIC_KEY_MSG_LEN 48
+#define PTK_KEY_MSG_LEN 39
+
+#define PMKSA_KEY_LEN 22
+#define ETH_ALEN 6
+#define PMKID_LEN 16
+#define NMI_MAX_NUM_PMKIDS 16
+#define NMI_SUPP_MCS_SET_SIZE 16
+#define NMI_ADD_STA_LENGTH 40 /* Not including the rates field cause it has variable length*/
+#define SCAN_EVENT_DONE_ABORTED
+/*****************************************************************************/
+/* Data Types */
+/*****************************************************************************/
+//typedef unsigned char uint8;
+//typedef signed char int8;
+//typedef unsigned short uint16;
+//typedef unsigned long uint32;
+//typedef uint32 Bool;
+
+#if 0
+typedef enum {WID_CHAR = 0,
+ WID_SHORT = 1,
+ WID_INT = 2,
+ WID_STR = 3,
+ WID_ADR = 4,
+ WID_BIN = 5,
+ WID_IP = 6,
+ WID_UNDEF = 7
+} WID_TYPE_T;
+#endif
+typedef struct
+{
+ NMI_Uint16 cfg_wid;
+ WID_TYPE_T cfg_type;
+ NMI_Sint8 *pu8Para;
+} cfg_param_t;
+
+typedef struct _tstrStatistics
+{
+ NMI_Uint8 u8LinkSpeed;
+ NMI_Sint8 s8RSSI;
+ NMI_Uint32 u32TxCount;
+ NMI_Uint32 u32RxCount;
+ NMI_Uint32 u32TxFailureCount;
+
+}tstrStatistics;
+
+
+typedef enum
+{
+ HOST_IF_IDLE = 0,
+ HOST_IF_SCANNING = 1,
+ HOST_IF_CONNECTING = 2,
+ HOST_IF_WAITING_CONN_RESP = 3,
+ HOST_IF_CONNECTED = 4,
+ HOST_IF_P2P_LISTEN =5,
+ HOST_IF_FORCE_32BIT = 0xFFFFFFFF
+}tenuHostIFstate;
+
+typedef struct _tstrHostIFpmkid
+{
+ NMI_Uint8 bssid[ETH_ALEN];
+ NMI_Uint8 pmkid[PMKID_LEN];
+}tstrHostIFpmkid;
+
+typedef struct _tstrHostIFpmkidAttr
+{
+ NMI_Uint8 numpmkid;
+ tstrHostIFpmkid pmkidlist[NMI_MAX_NUM_PMKIDS];
+}tstrHostIFpmkidAttr;
+#if 0
+/* Scan type parameter for scan request */
+typedef enum
+{
+ PASSIVE_SCAN = 0,
+ ACTIVE_SCAN = 1,
+ NUM_SCANTYPE
+} tenuScanType;
+
+typedef enum {SITE_SURVEY_1CH = 0,
+ SITE_SURVEY_ALL_CH = 1,
+ SITE_SURVEY_OFF = 2
+} SITE_SURVEY_T;
+#endif
+typedef enum{AUTORATE = 0,
+ MBPS_1 = 1,
+ MBPS_2 = 2,
+ MBPS_5_5 = 5,
+ MBPS_11 = 11,
+ MBPS_6 = 6,
+ MBPS_9 = 9,
+ MBPS_12 = 12,
+ MBPS_18 = 18,
+ MBPS_24 = 24,
+ MBPS_36 = 36,
+ MBPS_48 = 48,
+ MBPS_54 = 54
+
+}CURRENT_TX_RATE_T;
+
+typedef struct
+{
+ NMI_Uint32 u32SetCfgFlag;
+ NMI_Uint8 ht_enable;
+ NMI_Uint8 bss_type;
+ NMI_Uint8 auth_type;
+ NMI_Uint16 auth_timeout;
+ NMI_Uint8 power_mgmt_mode;
+ NMI_Uint16 short_retry_limit;
+ NMI_Uint16 long_retry_limit;
+ NMI_Uint16 frag_threshold;
+ NMI_Uint16 rts_threshold;
+ NMI_Uint16 preamble_type;
+ NMI_Uint8 short_slot_allowed;
+ NMI_Uint8 txop_prot_disabled;
+ NMI_Uint16 beacon_interval;
+ NMI_Uint16 dtim_period;
+ SITE_SURVEY_T site_survey_enabled;
+ NMI_Uint16 site_survey_scan_time;
+ NMI_Uint8 scan_source;
+ NMI_Uint16 active_scan_time;
+ NMI_Uint16 passive_scan_time;
+ CURRENT_TX_RATE_T curr_tx_rate;
+
+}tstrCfgParamVal;
+
+typedef enum {
+ RETRY_SHORT = 1 << 0,
+ RETRY_LONG = 1 << 1,
+ FRAG_THRESHOLD = 1 << 2,
+ RTS_THRESHOLD = 1 << 3,
+ BSS_TYPE = 1 << 4,
+ AUTH_TYPE = 1 << 5,
+ AUTHEN_TIMEOUT = 1 << 6,
+ POWER_MANAGEMENT = 1 << 7,
+ PREAMBLE = 1 << 8,
+ SHORT_SLOT_ALLOWED = 1 << 9,
+ TXOP_PROT_DISABLE = 1 << 10,
+ BEACON_INTERVAL = 1 << 11,
+ DTIM_PERIOD = 1 << 12,
+ SITE_SURVEY = 1 << 13,
+ SITE_SURVEY_SCAN_TIME = 1 << 14,
+ ACTIVE_SCANTIME = 1 << 15,
+ PASSIVE_SCANTIME = 1 << 16,
+ CURRENT_TX_RATE = 1 << 17,
+ HT_ENABLE = 1 <<18,
+}tenuCfgParam;
+
+typedef struct
+{
+ NMI_Uint8 au8bssid[6];
+ NMI_Sint8 s8rssi;
+}tstrFoundNetworkInfo;
+
+typedef enum {SCAN_EVENT_NETWORK_FOUND = 0,
+SCAN_EVENT_DONE = 1,
+SCAN_EVENT_ABORTED = 2,
+SCAN_EVENT_FORCE_32BIT = 0xFFFFFFFF
+}tenuScanEvent;
+
+typedef enum
+{
+ CONN_DISCONN_EVENT_CONN_RESP = 0,
+ CONN_DISCONN_EVENT_DISCONN_NOTIF = 1,
+ CONN_DISCONN_EVENT_FORCE_32BIT = 0xFFFFFFFF
+}tenuConnDisconnEvent;
+
+typedef enum
+{
+ WEP,
+ WPARxGtk,
+ //WPATxGtk,
+ WPAPtk,
+ PMKSA,
+}tenuKeyType;
+
+
+/*Scan callBack function definition*/
+typedef void(*tNMIpfScanResult)(tenuScanEvent, tstrNetworkInfo*, void*,void*);
+
+/*Connect callBack function definition*/
+typedef void(*tNMIpfConnectResult)(tenuConnDisconnEvent,
+ tstrConnectInfo*,
+ NMI_Uint8,
+ tstrDisconnectNotifInfo*,
+ void*);
+
+#ifdef NMI_P2P
+typedef void(*tNMIpfRemainOnChanExpired)(void*); /*Remain on channel expiration callback function*/
+typedef void(*tNMIpfRemainOnChanReady)(void*); /*Remain on channel callback function*/
+#endif
+
+//typedef NMI_Uint32 NMI_WFIDrvHandle;
+typedef struct
+{
+ NMI_Sint32 s32Dummy;
+}
+*NMI_WFIDrvHandle;
+
+/*!
+* @struct tstrRcvdNetworkInfo
+* @brief Structure to hold Received Asynchronous Network info
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrRcvdNetworkInfo
+{
+ NMI_Uint8* pu8Buffer;
+ NMI_Uint32 u32Length;
+} tstrRcvdNetworkInfo;
+
+/*BugID_4156*/
+typedef struct _tstrHiddenNetworkInfo
+{
+ NMI_Uint8 *pu8ssid;
+ NMI_Uint8 u8ssidlen;
+
+}tstrHiddenNetworkInfo;
+
+typedef struct _tstrHiddenNetwork
+{
+ //MAX_SSID_LEN
+ tstrHiddenNetworkInfo *pstrHiddenNetworkInfo;
+ NMI_Uint8 u8ssidnum;
+
+} tstrHiddenNetwork;
+
+typedef struct
+{
+ /* Scan user call back function */
+ tNMIpfScanResult pfUserScanResult;
+
+ /* User specific parameter to be delivered through the Scan User Callback function */
+ void* u32UserScanPvoid;
+
+ NMI_Uint32 u32RcvdChCount;
+ tstrFoundNetworkInfo astrFoundNetworkInfo[MAX_NUM_SCANNED_NETWORKS];
+}tstrNMI_UsrScanReq;
+
+typedef struct
+{
+ NMI_Uint8* pu8bssid;
+ NMI_Uint8* pu8ssid;
+ NMI_Uint8 u8security;
+ AUTHTYPE_T tenuAuth_type;
+ size_t ssidLen;
+ NMI_Uint8* pu8ConnReqIEs;
+ size_t ConnReqIEsLen;
+ /* Connect user call back function */
+ tNMIpfConnectResult pfUserConnectResult;
+ NMI_Bool IsHTCapable;
+ /* User specific parameter to be delivered through the Connect User Callback function */
+ void* u32UserConnectPvoid;
+}tstrNMI_UsrConnReq;
+
+typedef struct
+{
+ NMI_Uint32 u32Address;
+}tstrHostIfSetDrvHandler;
+
+typedef struct
+{
+ NMI_Uint32 u32Mode;
+}tstrHostIfSetOperationMode;
+
+/*BugID_5077*/
+typedef struct
+{
+ NMI_Uint8 u8MacAddress[ETH_ALEN];
+}tstrHostIfSetMacAddress;
+
+/*BugID_5213*/
+typedef struct
+{
+ NMI_Uint8* u8MacAddress;
+}tstrHostIfGetMacAddress;
+
+/*BugID_5222*/
+typedef struct
+{
+ NMI_Uint8 au8Bssid[ETH_ALEN];
+ NMI_Uint8 u8Ted;
+ NMI_Uint16 u16BufferSize;
+ NMI_Uint16 u16SessionTimeout;
+}tstrHostIfBASessionInfo;
+
+#ifdef NMI_P2P
+typedef struct
+{
+
+ NMI_Uint16 u16Channel;
+ NMI_Uint32 u32duration;
+ tNMIpfRemainOnChanExpired pRemainOnChanExpired;
+ tNMIpfRemainOnChanReady pRemainOnChanReady;
+ void * pVoid;
+}tstrHostIfRemainOnChan;
+
+typedef struct
+{
+
+NMI_Bool bReg;
+NMI_Uint16 u16FrameType;
+NMI_Uint8 u8Regid;
+
+
+}tstrHostIfRegisterFrame;
+
+
+#define ACTION 0xD0
+#define PROBE_REQ 0x40
+#define PROBE_RESP 0x50
+#define ACTION_FRM_IDX 0
+#define PROBE_REQ_IDX 1
+
+
+enum p2p_listen_state
+{
+ P2P_IDLE,
+ P2P_LISTEN,
+ P2P_GRP_FORMATION
+};
+
+#endif
+typedef struct
+{
+ /* Scan user structure */
+ tstrNMI_UsrScanReq strNMI_UsrScanReq;
+
+ /* Connect User structure */
+ tstrNMI_UsrConnReq strNMI_UsrConnReq;
+
+ #ifdef NMI_P2P
+ /*Remain on channel struvture*/
+ tstrHostIfRemainOnChan strHostIfRemainOnChan;
+ NMI_Uint8 u8RemainOnChan_pendingreq;
+ NMI_Uint64 u64P2p_MgmtTimeout;
+ NMI_Uint8 u8P2PConnect;
+ #endif
+
+ tenuHostIFstate enuHostIFstate;
+
+ //NMI_Bool bPendingConnRequest;
+
+ #ifndef CONNECT_DIRECT
+ NMI_Uint32 u32SurveyResultsCount;
+ wid_site_survey_reslts_s astrSurveyResults[MAX_NUM_SCANNED_NETWORKS];
+ #endif
+
+ NMI_Uint8 au8AssociatedBSSID[ETH_ALEN];
+ tstrCfgParamVal strCfgValues;
+//semaphores
+ NMI_SemaphoreHandle gtOsCfgValuesSem;
+ NMI_SemaphoreHandle hSemTestKeyBlock;
+
+ NMI_SemaphoreHandle hSemTestDisconnectBlock;
+ NMI_SemaphoreHandle hSemGetRSSI;
+ NMI_SemaphoreHandle hSemGetLINKSPEED;
+ NMI_SemaphoreHandle hSemGetCHNL;
+ NMI_SemaphoreHandle hSemInactiveTime;
+//timer handlers
+ NMI_TimerHandle hScanTimer;
+ NMI_TimerHandle hConnectTimer;
+ NMI_TimerHandle hPeriodicRSSI;
+ #ifdef NMI_P2P
+ NMI_TimerHandle hRemainOnChannel;
+ #endif
+
+ NMI_Bool IPaddrObtained;
+}tstrNMI_WFIDrv;
+
+/*!
+* @enum tenuNMI_StaFlag
+* @brief Used to decode the station flag set and mask in tstrNMI_AddStaParam
+* @details
+* @todo
+* @sa tstrNMI_AddStaParam, enum nl80211_sta_flags
+* @author Enumeraion's creator
+* @date 12 July 2012
+* @version 1.0 Description
+*/
+
+typedef enum
+{
+ NMI_STA_FLAG_INVALID = 0,
+ NMI_STA_FLAG_AUTHORIZED, /*!< station is authorized (802.1X)*/
+ NMI_STA_FLAG_SHORT_PREAMBLE, /*!< station is capable of receiving frames with short barker preamble*/
+ NMI_STA_FLAG_WME, /*!< station is WME/QoS capable*/
+ NMI_STA_FLAG_MFP, /*!< station uses management frame protection*/
+ NMI_STA_FLAG_AUTHENTICATED /*!< station is authenticated*/
+}tenuNMI_StaFlag;
+
+typedef struct
+{
+ NMI_Uint8 au8BSSID[ETH_ALEN];
+ NMI_Uint16 u16AssocID;
+ NMI_Uint8 u8NumRates;
+ NMI_Uint8* pu8Rates;
+ NMI_Bool bIsHTSupported;
+ NMI_Uint16 u16HTCapInfo;
+ NMI_Uint8 u8AmpduParams;
+ NMI_Uint8 au8SuppMCsSet[16];
+ NMI_Uint16 u16HTExtParams;
+ NMI_Uint32 u32TxBeamformingCap;
+ NMI_Uint8 u8ASELCap;
+ NMI_Uint16 u16FlagsMask; /*<! Determines which of u16FlagsSet were changed>*/
+ NMI_Uint16 u16FlagsSet; /*<! Decoded according to tenuNMI_StaFlag */
+}tstrNMI_AddStaParam;
+
+//extern void CfgDisconnected(void* pUserVoid, NMI_Uint16 u16reason, NMI_Uint8 * ie, size_t ie_len);
+
+/*****************************************************************************/
+/* */
+/* Host Interface API */
+/* */
+/*****************************************************************************/
+
+/**
+* @brief removes wpa/wpa2 keys
+* @details only in BSS STA mode if External Supplicant support is enabled.
+ removes all WPA/WPA2 station key entries from MAC hardware.
+* @param[in,out] handle to the wifi driver
+* @param[in] 6 bytes of Station Adress in the station entry table
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_remove_key(NMI_WFIDrvHandle hWFIDrv,const NMI_Uint8* pu8StaAddress);
+/**
+* @brief removes WEP key
+* @details valid only in BSS STA mode if External Supplicant support is enabled.
+ remove a WEP key entry from MAC HW.
+ The BSS Station automatically finds the index of the entry using its
+ BSS ID and removes that entry from the MAC hardware.
+* @param[in,out] handle to the wifi driver
+* @param[in] 6 bytes of Station Adress in the station entry table
+* @return Error code indicating success/failure
+* @note NO need for the STA add since it is not used for processing
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_remove_wep_key(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8Index);
+/**
+* @brief sets WEP deafault key
+* @details Sets the index of the WEP encryption key in use,
+ in the key table
+* @param[in,out] handle to the wifi driver
+* @param[in] key index ( 0, 1, 2, 3)
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_WEPDefaultKeyID(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8Index);
+
+/**
+* @brief sets WEP deafault key
+* @details valid only in BSS STA mode if External Supplicant support is enabled.
+ sets WEP key entry into MAC hardware when it receives the
+ corresponding request from NDIS.
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing WEP Key in the following format
+ |---------------------------------------|
+ |Key ID Value | Key Length | Key |
+ |-------------|------------|------------|
+ | 1byte | 1byte | Key Length |
+ |---------------------------------------|
+
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_wep_key_bss_sta(NMI_WFIDrvHandle hWFIDrv, const NMI_Uint8* pu8WepKey, NMI_Uint8 u8WepKeylen, NMI_Uint8 u8Keyidx);
+/**
+* @brief host_int_add_wep_key_bss_ap
+* @details valid only in AP mode if External Supplicant support is enabled.
+ sets WEP key entry into MAC hardware when it receives the
+ corresponding request from NDIS.
+* @param[in,out] handle to the wifi driver
+
+
+* @return Error code indicating success/failure
+* @note
+* @author mdaftedar
+* @date 28 Feb 2013
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_wep_key_bss_ap(NMI_WFIDrvHandle hWFIDrv, const NMI_Uint8* pu8WepKey, NMI_Uint8 u8WepKeylen, NMI_Uint8 u8Keyidx,NMI_Uint8 u8mode, AUTHTYPE_T tenuAuth_type);
+
+/**
+* @brief adds ptk Key
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing PTK Key in the following format
+|-------------------------------------------------------------------------|
+|Sta Adress | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key |
+|-----------|------------|---------------|----------------|---------------|
+| 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes |
+|-------------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_ptk(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8Ptk,NMI_Uint8 u8PtkKeylen,
+ const NMI_Uint8* mac_addr,NMI_Uint8* pu8RxMic,NMI_Uint8* pu8TxMic,NMI_Uint8 mode,NMI_Uint8 u8Ciphermode,NMI_Uint8 u8Idx);
+
+/**
+* @brief host_int_get_inactive_time
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing inactive time
+
+* @return Error code indicating success/failure
+* @note
+* @author mdaftedar
+* @date 15 April 2013
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_inactive_time(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 * mac,NMI_Uint32* pu32InactiveTime);
+
+/**
+* @brief adds Rx GTk Key
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing Rx GTK Key in the following format
+|----------------------------------------------------------------------------|
+|Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key |
+|------------|---------|-------|------------|---------------|----------------|
+| 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |
+|----------------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+ NMI_Sint32 host_int_add_rx_gtk(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8RxGtk,NMI_Uint8 u8GtkKeylen,
+ NMI_Uint8 u8KeyIdx,NMI_Uint32 u32KeyRSClen, NMI_Uint8* KeyRSC,
+ NMI_Uint8* pu8RxMic,NMI_Uint8* pu8TxMic,NMI_Uint8 mode,NMI_Uint8 u8Ciphermode);
+
+
+/**
+* @brief adds Tx GTk Key
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing Tx GTK Key in the following format
+ |----------------------------------------------------|
+ | KeyID | Key Length | Temporal Key | Tx Michael Key |
+ |-------|------------|--------------|----------------|
+ |1 byte | 1 byte | 16 bytes | 8 bytes |
+ |----------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_tx_gtk(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8KeyLen,NMI_Uint8* pu8TxGtk,NMI_Uint8 u8KeyIdx);
+
+/**
+* @brief caches the pmkid
+* @details valid only in BSS STA mode if External Supplicant
+ support is enabled. This Function sets the PMKID in firmware
+ when host drivr receives the corresponding request from NDIS.
+ The firmware then includes theset PMKID in the appropriate
+ management frames
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing PMKID Info in the following format
+|-----------------------------------------------------------------|
+|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] |
+|-----------|------------|----------|-------|----------|----------|
+| 1 | 6 | 16 | ... | 6 | 16 |
+|-----------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_set_pmkid_info(NMI_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr* pu8PmkidInfoArray);
+/**
+* @brief gets the cached the pmkid info
+* @details valid only in BSS STA mode if External Supplicant
+ support is enabled. This Function sets the PMKID in firmware
+ when host drivr receives the corresponding request from NDIS.
+ The firmware then includes theset PMKID in the appropriate
+ management frames
+* @param[in,out] handle to the wifi driver,
+
+ message containing PMKID Info in the following format
+ |-----------------------------------------------------------------|
+ |NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] |
+ |-----------|------------|----------|-------|----------|----------|
+ | 1 | 6 | 16 | ... | 6 | 16 |
+ |-----------------------------------------------------------------|
+* @param[in]
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_get_pmkid_info(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8PmkidInfoArray,
+ NMI_Uint32 u32PmkidInfoLen);
+
+/**
+* @brief sets the pass phrase
+* @details AP/STA mode. This function gives the pass phrase used to
+ generate the Pre-Shared Key when WPA/WPA2 is enabled
+ The length of the field can vary from 8 to 64 bytes,
+ the lower layer should get the
+* @param[in,out] handle to the wifi driver,
+* @param[in] String containing PSK
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_RSNAConfigPSKPassPhrase(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8PassPhrase,
+ NMI_Uint8 u8Psklength);
+/**
+* @brief gets the pass phrase
+* @details AP/STA mode. This function gets the pass phrase used to
+ generate the Pre-Shared Key when WPA/WPA2 is enabled
+ The length of the field can vary from 8 to 64 bytes,
+ the lower layer should get the
+* @param[in,out] handle to the wifi driver,
+ String containing PSK
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_RSNAConfigPSKPassPhrase(NMI_WFIDrvHandle hWFIDrv,
+ NMI_Uint8* pu8PassPhrase, NMI_Uint8 u8Psklength);
+
+/**
+* @brief gets mac address
+* @details
+* @param[in,out] handle to the wifi driver,
+
+* @return Error code indicating success/failure
+* @note
+* @author mdaftedar
+* @date 19 April 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_MacAddress(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8MacAddress);
+
+/**
+* @brief sets mac address
+* @details
+* @param[in,out] handle to the wifi driver,
+
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 16 July 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_MacAddress(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8MacAddress);
+
+/**
+* @brief wait until msg q is empty
+* @details
+* @param[in,out]
+
+* @return Error code indicating success/failure
+* @note
+* @author asobhy
+* @date 19 march 2014
+* @version 1.0
+*/
+NMI_Sint32 host_int_wait_msg_queue_idle(void);
+
+/**
+* @brief gets the site survey results
+* @details
+* @param[in,out] handle to the wifi driver,
+ Message containing site survey results in the
+ following formate
+|---------------------------------------------------|
+| MsgLength | fragNo. | MsgBodyLength | MsgBody |
+|-----------|-----------|---------------|-----------|
+| 1 | 1 | 1 | 1 |
+----------------------------------------- | ----------------
+ |
+ |---------------------------------------|
+ | Network1 | Netweork2 | ... | Network5 |
+ |---------------------------------------|
+ | 44 | 44 | ... | 44 |
+-------------------------- | ---------------------------------------
+ |
+|---------------------------------------------------------------------|
+| SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved |
+|------|----------|---------|----------------|-------|------|---------|
+| 33 | 1 | 1 | 1 | 6 | 1 | 1 |
+|---------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+#ifndef CONNECT_DIRECT
+NMI_Sint32 host_int_get_site_survey_results(NMI_WFIDrvHandle hWFIDrv,
+ NMI_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
+ NMI_Uint32 u32MaxSiteSrvyFragLen);
+#endif
+
+/**
+* @brief sets a start scan request
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Scan Source one of the following values
+ DEFAULT_SCAN 0
+ USER_SCAN BIT0
+ OBSS_PERIODIC_SCAN BIT1
+ OBSS_ONETIME_SCAN BIT2
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_set_start_scan_req(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 scanSource);
+/**
+* @brief gets scan source of the last scan
+* @details
+* @param[in,out] handle to the wifi driver,
+ Scan Source one of the following values
+ DEFAULT_SCAN 0
+ USER_SCAN BIT0
+ OBSS_PERIODIC_SCAN BIT1
+ OBSS_ONETIME_SCAN BIT2
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+ NMI_Sint32 host_int_get_start_scan_req(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8ScanSource);
+
+/**
+* @brief sets a join request
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Index of the bss descriptor
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_set_join_req(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8bssid,
+ NMI_Uint8* pu8ssid, size_t ssidLen,
+ const NMI_Uint8* pu8IEs, size_t IEsLen,
+ tNMIpfConnectResult pfConnectResult, void* pvUserArg,
+ NMI_Uint8 u8security, AUTHTYPE_T tenuAuth_type,
+ NMI_Uint8 u8channel,
+ void* pJoinParams);
+
+/**
+* @brief Flush a join request parameters to FW, but actual connection
+* @details The function is called in situation where NMC is connected to AP and
+ required to switch to hybrid FW for P2P connection
+* @param[in] handle to the wifi driver,
+* @return Error code indicating success/failure
+* @note
+* @author Amr Abdel-Moghny
+* @date 19 DEC 2013
+* @version 8.0
+*/
+
+NMI_Sint32 host_int_flush_join_req(NMI_WFIDrvHandle hWFIDrv);
+
+
+/**
+* @brief disconnects from the currently associated network
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Reason Code of the Disconnection
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_disconnect(NMI_WFIDrvHandle hWFIDrv, NMI_Uint16 u16ReasonCode);
+
+/**
+* @brief disconnects a sta
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Association Id of the station to be disconnected
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_disconnect_station(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 assoc_id);
+/**
+* @brief gets a Association request info
+* @details
+* @param[in,out] handle to the wifi driver,
+ Message containg assoc. req info in the following format
+------------------------------------------------------------------------
+| Management Frame Format |
+|-------------------------------------------------------------------|
+|Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS |
+|-------------|--------|--|--|-----|----------------|----------|----|
+| 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 |
+|-------------------------------------------------------------------|
+| |
+| Association Request Frame - Frame Body |
+|-------------------------------------------------------------------|
+| Capability Information | Listen Interval | SSID | Supported Rates |
+|------------------------|-----------------|------|-----------------|
+| 2 | 2 | 2-34 | 3-10 |
+| ---------------------------------------------------------------------
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_get_assoc_req_info(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8AssocReqInfo,
+ NMI_Uint32 u32AssocReqInfoLen);
+/**
+* @brief gets a Association Response info
+* @details
+* @param[in,out] handle to the wifi driver,
+ Message containg assoc. resp info
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_get_assoc_res_info(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8AssocRespInfo,
+ NMI_Uint32 u32MaxAssocRespInfoLen, NMI_Uint32* pu32RcvdAssocRespInfoLen);
+/**
+* @brief gets a Association Response info
+* @details Valid only in STA mode. This function gives the RSSI
+ values observed in all the channels at the time of scanning.
+ The length of the field is 1 greater that the total number of
+ channels supported. Byte 0 contains the number of channels while
+ each of Byte N contains the observed RSSI value for the channel index N.
+* @param[in,out] handle to the wifi driver,
+ array of scanned channels' RSSI
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_rx_power_level(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8RxPowerLevel,
+ NMI_Uint32 u32RxPowerLevelLen);
+
+/**
+* @brief sets a channel
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Index of the channel to be set
+|-------------------------------------------------------------------|
+| CHANNEL1 CHANNEL2 .... CHANNEL14 |
+| Input: 1 2 14 |
+|-------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_mac_chnl_num(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8ChNum);
+
+/**
+* @brief gets the current channel index
+* @details
+* @param[in,out] handle to the wifi driver,
+ current channel index
+|-----------------------------------------------------------------------|
+| CHANNEL1 CHANNEL2 .... CHANNEL14 |
+| Input: 1 2 14 |
+|-----------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_host_chnl_num(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8ChNo);
+/**
+* @brief gets the sta rssi
+* @details gets the currently maintained RSSI value for the station.
+ The received signal strength value in dB.
+ The range of valid values is -128 to 0.
+* @param[in,out] handle to the wifi driver,
+ rssi value in dB
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_rssi(NMI_WFIDrvHandle hWFIDrv, NMI_Sint8* ps8Rssi);
+NMI_Sint32 host_int_get_link_speed(NMI_WFIDrvHandle hWFIDrv, NMI_Sint8* ps8lnkspd);
+/**
+* @brief scans a set of channels
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Scan source
+ Scan Type PASSIVE_SCAN = 0,
+ ACTIVE_SCAN = 1
+ Channels Array
+ Channels Array length
+ Scan Callback function
+ User Argument to be delivered back through the Scan Cllback function
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_scan(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8 u8ScanSource,
+ NMI_Uint8 u8ScanType, NMI_Uint8* pu8ChnlFreqList,
+ NMI_Uint8 u8ChnlListLen, const NMI_Uint8* pu8IEs,
+ size_t IEsLen, tNMIpfScanResult ScanResult,
+ void* pvUserArg,tstrHiddenNetwork *pstrHiddenNetwork);
+/**
+* @brief sets configuration wids values
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] WID, WID value
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 hif_set_cfg(NMI_WFIDrvHandle hWFIDrv, tstrCfgParamVal * pstrCfgParamVal);
+
+/**
+* @brief gets configuration wids values
+* @details
+* @param[in,out] handle to the wifi driver,
+ WID value
+* @param[in] WID,
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 hif_get_cfg(NMI_WFIDrvHandle hWFIDrv,NMI_Uint16 u16WID,NMI_Uint16* pu16WID_Value);
+/*****************************************************************************/
+/* Notification Functions */
+/*****************************************************************************/
+/**
+* @brief notifies host with join and leave requests
+* @details This function prepares an Information frame having the
+ information about a joining/leaving station.
+* @param[in,out] handle to the wifi driver,
+* @param[in] 6 byte Sta Adress
+ Join or leave flag:
+ Join = 1,
+ Leave =0
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+void host_int_send_join_leave_info_to_host
+ (NMI_Uint16 assocId, NMI_Uint8* stationAddr, NMI_Bool joining);
+
+/**
+* @brief notifies host with stations found in scan
+* @details sends the beacon/probe response from scan
+* @param[in,out] handle to the wifi driver,
+* @param[in] Sta Address,
+ Frame length,
+ Rssi of the Station found
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+void host_int_send_network_info_to_host
+ (NMI_Uint8 *macStartAddress,NMI_Uint16 u16RxFrameLen, NMI_Sint8 s8Rssi);
+
+/**
+* @brief host interface initialization function
+* @details
+* @param[in,out] handle to the wifi driver,
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_init(NMI_WFIDrvHandle* phWFIDrv);
+
+/**
+* @brief host interface initialization function
+* @details
+* @param[in,out] handle to the wifi driver,
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_deinit(NMI_WFIDrvHandle hWFIDrv);
+
+
+/*!
+ * @fn NMI_Sint32 host_int_add_beacon(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8Index)
+ * @brief Sends a beacon to the firmware to be transmitted over the air
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] u32Interval Beacon Interval. Period between two successive beacons on air
+ * @param[in] u32DTIMPeriod DTIM Period. Indicates how many Beacon frames
+ * (including the current frame) appear before the next DTIM
+ * @param[in] u32Headlen Length of the head buffer in bytes
+ * @param[in] pu8Head Pointer to the beacon's head buffer. Beacon's head
+ * is the part from the beacon's start till the TIM element, NOT including the TIM
+ * @param[in] u32Taillen Length of the tail buffer in bytes
+ * @param[in] pu8Tail Pointer to the beacon's tail buffer. Beacon's tail
+ * starts just after the TIM inormation element
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 10 Julys 2012
+ * @version 1.0 Description
+
+ */
+NMI_Sint32 host_int_add_beacon(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,
+ NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8tail);
+
+
+/*!
+ * @fn NMI_Sint32 host_int_del_beacon(NMI_WFIDrvHandle hWFIDrv)
+ * @brief Removes the beacon and stops tranmitting it over the air
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 10 Julys 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_del_beacon(NMI_WFIDrvHandle hWFIDrv);
+
+/*!
+ * @fn NMI_Sint32 host_int_add_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam strStaParams)
+ * @brief Notifies the firmware with a new associated stations
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] pstrStaParams Station's parameters
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 12 July 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_add_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams);
+
+
+/*!
+ * @fn NMI_Sint32 host_int_del_station(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8MacAddr)
+ * @brief Notifies the firmware with a new deleted station
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] pu8MacAddr Station's mac address
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 15 July 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_del_station(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8MacAddr);
+
+/*!
+ * @fn NMI_Sint32 host_int_edit_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam strStaParams)
+ * @brief Notifies the firmware with new parameters of an already associated station
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] pstrStaParams Station's parameters
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 15 July 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_edit_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams);
+
+/*!
+ * @fn NMI_Sint32 host_int_set_power_mgmt(NMI_WFIDrvHandle hWFIDrv, NMI_Bool bIsEnabled, NMI_Uint32 u32Timeout)
+ * @brief Set the power management mode to enabled or disabled
+ * @details
+ * @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise
+ * @param[in] u32Timeout A timeout value of -1 allows the driver to adjust
+ * the dynamic ps timeout value
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 24 November 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_set_power_mgmt(NMI_WFIDrvHandle hWFIDrv, NMI_Bool bIsEnabled, NMI_Uint32 u32Timeout);
+/* @param[in,out] hWFIDrv handle to the wifi driver
+ * @param[in] bIsEnabled TRUE if enabled, FALSE otherwise
+ * @param[in] u8count count of mac address entries in the filter table
+ *
+ * @return 0 for Success, error otherwise
+ * @todo
+ * @sa
+ * @author Adham Abozaeid
+ * @date 24 November 2012
+ * @version 1.0 Description
+ */
+NMI_Sint32 host_int_setup_multicast_filter(NMI_WFIDrvHandle hWFIDrv, NMI_Bool bIsEnabled, NMI_Uint32 u32count);
+/**
+* @brief host_int_setup_ipaddress
+* @details set IP address on firmware
+* @param[in]
+* @return Error code.
+* @author Abdelrahman Sobhy
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_setup_ipaddress(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8IPAddr, NMI_Uint8 idx);
+
+
+NMI_Sint32 host_int_delBASession(NMI_WFIDrvHandle hWFIDrv, char* pBSSID,char TID,void * drvHandler);
+
+/**
+* @brief host_int_get_ipaddress
+* @details get IP address on firmware
+* @param[in]
+* @return Error code.
+* @author Abdelrahman Sobhy
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_ipaddress(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8IPAddr, NMI_Uint8 idx);
+
+#ifdef NMI_P2P
+/**
+* @brief host_int_remain_on_channel
+* @details
+* @param[in]
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_remain_on_channel(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32duration,NMI_Uint16 chan,tNMIpfRemainOnChanExpired RemainOnChanExpired, tNMIpfRemainOnChanReady RemainOnChanReady,void* pvUserArg);
+
+/**
+* @brief host_int_ListenStateExpired
+* @details
+* @param[in] Handle to wifi driver
+ Duration to remain on channel
+ Channel to remain on
+ Pointer to fn to be called on receive frames in listen state
+ Pointer to remain-on-channel expired fn
+ Priv
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_ListenStateExpired(NMI_WFIDrvHandle hWFIDrv);
+
+/**
+* @brief host_int_frame_register
+* @details
+* @param[in]
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_frame_register(NMI_WFIDrvHandle hWFIDrv, NMI_Uint16 u16FrameType,NMI_Bool bReg);
+#endif
+/**
+* @brief host_int_set_wfi_drv_handler
+* @details
+* @param[in]
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_wfi_drv_handler(NMI_Uint32 u32address);
+NMI_Sint32 host_int_set_operation_mode(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32mode);
+
+static NMI_Sint32 Handle_ScanDone(void* drvHandler,tenuScanEvent enuEvent);
+
+static int host_int_addBASession(NMI_WFIDrvHandle hWFIDrv, char* pBSSID,char TID,short int BufferSize,
+ short int SessionTimeout,void * drvHandler);
+
+
+void host_int_freeJoinParams(void* pJoinParams);
+
+NMI_Sint32 host_int_get_statistics(NMI_WFIDrvHandle hWFIDrv, tstrStatistics* pstrStatistics);
+
+/*****************************************************************************/
+/* */
+/* EOF */
+/* */
+/*****************************************************************************/
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/itypes.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/itypes.h
new file mode 100755
index 00000000..c3600183
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/itypes.h
@@ -0,0 +1,59 @@
+/*****************************************************************************/
+/* */
+/* Ittiam 802.11 MAC SOFTWARE */
+/* */
+/* ITTIAM SYSTEMS PVT LTD, BANGALORE */
+/* COPYRIGHT(C) 2005 */
+/* */
+/* This program is proprietary to Ittiam Systems Private Limited and */
+/* is protected under Indian Copyright Law as an unpublished work. Its use */
+/* and disclosure is limited by the terms and conditions of a license */
+/* agreement. It may not be copied or otherwise reproduced or disclosed to */
+/* persons outside the licensee's organization except in accordance with the*/
+/* terms and conditions of such an agreement. All copies and */
+/* reproductions shall be the property of Ittiam Systems Private Limited and*/
+/* must bear this notice in its entirety. */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* */
+/* File Name : itypes.h */
+/* */
+/* Description : This file contains all the data type definitions for */
+/* MAC implementation. */
+/* */
+/* List of Functions : None */
+/* Issues / Problems : None */
+/* */
+/* Revision History : */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 01 05 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+#ifndef ITYPES_H
+#define ITYPES_H
+
+
+/*****************************************************************************/
+/* Data Types */
+/*****************************************************************************/
+
+typedef int WORD32;
+typedef short WORD16;
+typedef char WORD8;
+typedef unsigned int UWORD32;
+typedef unsigned short UWORD16;
+typedef unsigned char UWORD8;
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+typedef enum {BFALSE = 0,
+ BTRUE = 1
+} BOOL_T;
+
+#endif /* ITYPES_H */
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/linux_wlan_common.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/linux_wlan_common.h
new file mode 100755
index 00000000..a70cb32d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/linux_wlan_common.h
@@ -0,0 +1,145 @@
+#ifndef LINUX_WLAN_COMMON_H
+#define LINUX_WLAN_COMMON_H
+
+enum debug_region{
+ Generic_debug = 0,
+ Hostapd_debug,
+ Hostinf_debug,
+ CFG80211_debug,
+ Coreconfig_debug,
+ Interrupt_debug,
+ TX_debug,
+ RX_debug,
+ Lock_debug,
+ Tcp_enhance,
+ /*Added by amr - BugID_4720*/
+ Spin_debug,
+
+ Init_debug,
+ Bus_debug,
+ Mem_debug,
+ Firmware_debug,
+ COMP = 0xFFFFFFFF,
+};
+
+#define GENERIC_DBG (1<<Generic_debug)
+#define HOSTAPD_DBG (1<<Hostapd_debug)
+#define HOSTINF_DBG (1<<Hostinf_debug)
+#define CORECONFIG_DBG (1<<Coreconfig_debug)
+#define CFG80211_DBG (1<<CFG80211_debug)
+#define INT_DBG (1<<Interrupt_debug)
+#define TX_DBG (1<<TX_debug)
+#define RX_DBG (1<<RX_debug)
+#define LOCK_DBG (1<<Lock_debug)
+#define TCP_ENH (1<<Tcp_enhance)
+
+
+/*Added by Amr - BugID_4720*/
+#define SPIN_DEBUG (1<<Spin_debug)
+
+#define INIT_DBG (1<<Init_debug)
+#define BUS_DBG (1<<Bus_debug)
+#define MEM_DBG (1<<Mem_debug)
+#define FIRM_DBG (1<<Firmware_debug)
+
+#if defined (NMC_DEBUGFS)
+extern void kmsgdump_write(char *fmt, ...);
+extern int nmc_debugfs_init(void);
+extern void nmc_debugfs_remove(void);
+
+extern atomic_t REGION;
+extern atomic_t DEBUG_LEVEL;
+
+#define DEBUG (1 << 0)
+#define INFO (1 << 1)
+#define WRN (1 << 2)
+#define ERR (1 << 3)
+
+#define PRINT_D(region,...) do{ if((atomic_read(&DEBUG_LEVEL) & DEBUG) && ((atomic_read(&REGION))&(region))){printk("DBG [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write("DBG [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write(__VA_ARGS__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_INFO(region,...) do{ if((atomic_read(&DEBUG_LEVEL) & INFO) && ((atomic_read(&REGION))&(region))){printk("INFO [%s]",__FUNCTION__);\
+ kmsgdump_write("INFO [%s]",__FUNCTION__);\
+ kmsgdump_write(__VA_ARGS__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_WRN(region,...) do{ if((atomic_read(&DEBUG_LEVEL) & WRN) && ((atomic_read(&REGION))&(region))){printk("WRN [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write("WRN [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write(__VA_ARGS__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_ER(...) do{ if((atomic_read(&DEBUG_LEVEL) & ERR)) { \
+ printk("ERR [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write("ERR [%s: %d]",__FUNCTION__,__LINE__);\
+ kmsgdump_write(__VA_ARGS__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#else
+
+#define REGION INIT_DBG|GENERIC_DBG|CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG
+
+#define DEBUG 1
+#define INFO 0
+#define WRN 0
+#define PRINT_D(region,...) do{ if(DEBUG == 1 && ((REGION)&(region))){printk("DBG [%s: %d]",__FUNCTION__,__LINE__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_INFO(region,...) do{ if(INFO == 1 && ((REGION)&(region))){printk("INFO [%s]",__FUNCTION__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_WRN(region,...) do{ if(WRN == 1 && ((REGION)&(region))){printk("WRN [%s: %d]",__FUNCTION__,__LINE__);\
+ printk(__VA_ARGS__);}}while(0)
+
+#define PRINT_ER(...) do{ printk("ERR [%s: %d]",__FUNCTION__,__LINE__);\
+ printk(__VA_ARGS__);}while(0)
+#endif
+
+#define FN_IN //PRINT_D(">>> \n")
+#define FN_OUT //PRINT_D("<<<\n")
+
+#ifdef MEMORY_STATIC
+#define LINUX_RX_SIZE (96*1024)
+#endif
+#define LINUX_TX_SIZE (64*1024)
+
+
+#define NMI_MULTICAST_TABLE_SIZE 8
+
+#if defined (NM73131_0_BOARD)
+
+#define MODALIAS "nmc_spi"
+#define GPIO_NUM IRQ_NMC1000_GPIO
+
+#elif defined (BEAGLE_BOARD)
+ #define SPI_CHANNEL 4
+
+ #if SPI_CHANNEL == 4
+ #define MODALIAS "nmc_spi4"
+ #define GPIO_NUM 162
+ #else
+ #define MODALIAS "nmc_spi3"
+ #define GPIO_NUM 133
+ #endif
+#elif defined(PANDA_BOARD)
+ #define MODALIAS "NMI_SPI"
+ #define GPIO_NUM 139
+#elif defined(PLAT_WMS8304) // rachel
+ #define MODALIAS "nmi_spi"
+ #define GPIO_NUM 139
+#elif defined (PLAT_RKXXXX)
+ #define MODALIAS "NMI_IRQ"
+ #define GPIO_NUM RK30_PIN3_PD2 //RK30_PIN3_PA1
+ //RK30_PIN3_PD2
+ //RK2928_PIN1_PA7
+
+#else
+ #define MODALIAS "NMI_SPI"
+ #define GPIO_NUM 139
+
+#endif
+
+
+void linux_wlan_enable_irq(void);
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_type.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_type.h
new file mode 100755
index 00000000..b04901b5
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_type.h
@@ -0,0 +1,34 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_type.h
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef NMI_TYPE_H
+#define NMI_TYPE_H
+
+/********************************************
+
+ Type Defines
+
+********************************************/
+#ifdef WIN32
+typedef char int8_t;
+typedef short int16_t;
+typedef long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#else
+#ifdef _linux_
+/*typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;*/
+#include <stdint.h>
+#else
+#include "NMI_OSWrapper.h"
+#endif
+#endif
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan.h
new file mode 100755
index 00000000..9b3deba6
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan.h
@@ -0,0 +1,351 @@
+#ifndef NMI_WLAN_H
+#define NMI_WLAN_H
+
+#include "nmi_type.h"
+
+
+#define ISNMC1000(id) (((id & 0xfffff000) == 0x100000) ? 1 : 0)
+
+/**
+ DMA_VER_1: Old DMA interface introduced since A0. It exists in all
+ later versions and all versions are backward compatible with this interface.
+**/
+#define DMA_VER_1 (1)
+/**
+ DMA_VER_21: DMA interface introduced in D0/E0 versions and later. It uses
+ fewer number of registers to setup the TX/RX DMA and makes used of SDIO
+ CMD52 mapped registers and SPI internal registers for faster SDIO and SPI
+ DMAs respectively.
+**/
+#define DMA_VER_2 (2)
+
+#ifdef USE_DMA_VER_1
+#define DMA_VER DMA_VER_1
+#else
+#define DMA_VER DMA_VER_2
+#endif
+
+
+/********************************************
+
+ Mac eth header length
+
+********************************************/
+#define DRIVER_HANDLER_SIZE 4
+#define MAX_MAC_HDR_LEN 26 //QOS_MAC_HDR_LEN
+#define SUB_MSDU_HEADER_LENGTH 14
+#define SNAP_HDR_LEN 8
+#define ETHERNET_HDR_LEN 14
+#define WORD_ALIGNMENT_PAD 0
+
+#define ETH_ETHERNET_HDR_OFFSET (MAX_MAC_HDR_LEN + SUB_MSDU_HEADER_LENGTH + \
+ SNAP_HDR_LEN - ETHERNET_HDR_LEN + WORD_ALIGNMENT_PAD)
+
+/*Bug3959: transmitting mgmt frames received from host*/
+#define HOST_HDR_OFFSET 4
+#define ETHERNET_HDR_LEN 14
+#define IP_HDR_LEN 20
+#define IP_HDR_OFFSET ETHERNET_HDR_LEN
+#define UDP_HDR_OFFSET (IP_HDR_LEN + IP_HDR_OFFSET)
+#define UDP_HDR_LEN 8
+#define UDP_DATA_OFFSET (UDP_HDR_OFFSET + UDP_HDR_LEN)
+#define ETH_CONFIG_PKT_HDR_LEN UDP_DATA_OFFSET
+
+#define ETH_CONFIG_PKT_HDR_OFFSET (ETH_ETHERNET_HDR_OFFSET + \
+ ETH_CONFIG_PKT_HDR_LEN)
+#define ACTION 0xD0
+#define PROBE_REQ 0x40
+#ifdef NMI_FULLY_HOSTING_AP
+#define FH_TX_HOST_HDR_OFFSET 24
+#endif
+
+/********************************************
+
+ Endian Conversion
+
+********************************************/
+
+#define BYTE_SWAP(val) ((((val) & 0x000000FF) << 24) + \
+ (((val) & 0x0000FF00) << 8) + \
+ (((val) & 0x00FF0000) >> 8) + \
+ (((val) & 0xFF000000) >> 24))
+
+/********************************************
+
+ Register Defines
+
+********************************************/
+#define NMI_PERIPH_REG_BASE 0x1000
+/*BugID_5137*/
+#define NMI_CHANGING_VIR_IF (0x108c)
+#define NMI_CHIPID (NMI_PERIPH_REG_BASE)
+#define NMI_GLB_RESET_0 (NMI_PERIPH_REG_BASE + 0x400)
+#define NMI_PIN_MUX_0 (NMI_PERIPH_REG_BASE + 0x408)
+#define NMI_HOST_TX_CTRL (NMI_PERIPH_REG_BASE + 0x6c)
+#define NMI_HOST_RX_CTRL_0 (NMI_PERIPH_REG_BASE + 0x70)
+#define NMI_HOST_RX_CTRL_1 (NMI_PERIPH_REG_BASE + 0x74)
+#define NMI_HOST_VMM_CTL (NMI_PERIPH_REG_BASE + 0x78)
+#define NMI_HOST_RX_CTRL (NMI_PERIPH_REG_BASE + 0x80)
+#define NMI_HOST_RX_EXTRA_SIZE (NMI_PERIPH_REG_BASE + 0x84)
+#define NMI_HOST_TX_CTRL_1 (NMI_PERIPH_REG_BASE + 0x88)
+#define NMI_MISC (NMI_PERIPH_REG_BASE+0x428)
+#define NMI_INTR_REG_BASE (NMI_PERIPH_REG_BASE+0xa00)
+#define NMI_INTR_ENABLE (NMI_INTR_REG_BASE)
+#define NMI_INTR2_ENABLE (NMI_INTR_REG_BASE+4)
+
+#define NMI_INTR_POLARITY (NMI_INTR_REG_BASE+0x10)
+#define NMI_INTR_TYPE (NMI_INTR_REG_BASE+0x20)
+#define NMI_INTR_CLEAR (NMI_INTR_REG_BASE+0x30)
+#define NMI_INTR_STATUS (NMI_INTR_REG_BASE+0x40)
+
+#define NMI_VMM_TBL_SIZE 64
+#define NMI_VMM_TX_TBL_BASE (0x150400)
+#define NMI_VMM_RX_TBL_BASE (0x150500)
+
+#define NMI_VMM_BASE 0x150000
+#define NMI_VMM_CORE_CTL (NMI_VMM_BASE)
+#define NMI_VMM_TBL_CTL (NMI_VMM_BASE+0x4)
+#define NMI_VMM_TBL_ENTRY (NMI_VMM_BASE+0x8)
+#define NMI_VMM_TBL0_SIZE (NMI_VMM_BASE+0xc)
+#define NMI_VMM_TO_HOST_SIZE (NMI_VMM_BASE+0x10)
+#define NMI_VMM_CORE_CFG (NMI_VMM_BASE+0x14)
+#define NMI_VMM_TBL_ACTIVE (NMI_VMM_BASE+040)
+#define NMI_VMM_TBL_STATUS (NMI_VMM_BASE+0x44)
+
+#define NMI_SPI_REG_BASE 0xe800
+#define NMI_SPI_CTL (NMI_SPI_REG_BASE)
+#define NMI_SPI_MASTER_DMA_ADDR (NMI_SPI_REG_BASE+0x4)
+#define NMI_SPI_MASTER_DMA_COUNT (NMI_SPI_REG_BASE+0x8)
+#define NMI_SPI_SLAVE_DMA_ADDR (NMI_SPI_REG_BASE+0xc)
+#define NMI_SPI_SLAVE_DMA_COUNT (NMI_SPI_REG_BASE+0x10)
+#define NMI_SPI_TX_MODE (NMI_SPI_REG_BASE+0x20)
+#define NMI_SPI_PROTOCOL_CONFIG (NMI_SPI_REG_BASE+0x24)
+#define NMI_SPI_INTR_CTL (NMI_SPI_REG_BASE+0x2c)
+
+#define NMI_SPI_PROTOCOL_OFFSET (NMI_SPI_PROTOCOL_CONFIG-NMI_SPI_REG_BASE)
+
+#define NMI_AHB_DATA_MEM_BASE 0x30000
+#define NMI_AHB_SHARE_MEM_BASE 0xd0000
+
+#define NMI_VMM_TBL_RX_SHADOW_BASE NMI_AHB_SHARE_MEM_BASE /* Bug 4477 fix */
+#define NMI_VMM_TBL_RX_SHADOW_SIZE (256) /* Bug 4477 fix */
+
+#define _NMI_INT_STATS_PRE_D0 0x1488
+#define _NMI_INT_STATS_D0_AND_LATER 0x149c
+
+/*
+ * General purpose register 1
+ * Bit 0: SDIO interrupt type: (This bit is ignored in case of SPI bus.)
+ * 1: SDIO uses a GPIO as interrupt.
+ * 0, SDIO native interrupt SDIO_DAT1 used.
+ * Bit 1: CLK type used
+ * 1: RTC clock is supplied externally from host
+ * 0: Use internal 80Mhz clock
+ */
+
+#define _NMI_GP_REG_1_PRE_D0 0x148c
+#define _NMI_GP_REG_1_D0_AND_LATER 0x14a0
+
+#define NMI_HAVE_SDIO_IRQ_GPIO (1 << 0)
+#define NMI_HAVE_RTC (1 << 1)
+#define NMI_HAVE_DMA_VER_2 (1 << 2)
+#define NMI_HAVE_VCO_14_SUPPLY (1 << 3)
+#define NMI_XTAL_24 (1 << 4)
+#define NMI_DISABLE_NMC_UART (1 << 5)
+
+
+
+/********************************************
+
+ Wlan Defines
+
+********************************************/
+#define NMI_CFG_PKT 1
+#define NMI_NET_PKT 0
+/*Bug3959: transmitting mgmt frames received from host*/
+#ifdef NMI_AP_EXTERNAL_MLME
+#define NMI_MGMT_PKT 2
+
+#ifdef NMI_FULLY_HOSTING_AP
+#define NMI_FH_DATA_PKT 4
+#endif
+
+#endif /*NMI_AP_EXTERNAL_MLME*/
+#define NMI_CFG_SET 1
+#define NMI_CFG_QUERY 0
+
+#define NMI_CFG_RSP 1
+#define NMI_CFG_RSP_STATUS 2
+#define NMI_CFG_RSP_SCAN 3
+
+#ifdef NMI_SDIO
+#define NMI_PLL_TO 4
+#else
+#define NMI_PLL_TO 2
+#endif
+
+/*******************************************/
+/* CA Interrupt flags. */
+/*******************************************/
+#define PLL_INT (1<<0)
+#define DATA_INT (1<<1)
+#define SLEEP_INT (1<<2)
+#define ABORT_INT (1<<31)
+
+#if DMA_VER == DMA_VER_2
+/*******************************************/
+/* E0 and later Interrupt flags. */
+/*******************************************/
+/*******************************************/
+/* E0 and later Interrupt flags. */
+/* IRQ Status word */
+/* 15:0 = DMA count in words. */
+/* 16: INT0 flag */
+/* 17: INT1 flag */
+/* 18: INT2 flag */
+/* 19: INT3 flag */
+/* 20: INT4 flag */
+/* 21: INT5 flag */
+/*******************************************/
+#define IRG_FLAGS_OFFSET 16
+#define IRQ_DMA_WD_CNT_MASK ((1ul << IRG_FLAGS_OFFSET) - 1)
+#define INT_0 (1<<(IRG_FLAGS_OFFSET))
+#define INT_1 (1<<(IRG_FLAGS_OFFSET+1))
+#define INT_2 (1<<(IRG_FLAGS_OFFSET+2))
+#define INT_3 (1<<(IRG_FLAGS_OFFSET+3))
+#define INT_4 (1<<(IRG_FLAGS_OFFSET+4))
+#define INT_5 (1<<(IRG_FLAGS_OFFSET+5))
+#define MAX_NUM_INT (6)
+
+/*******************************************/
+/* E0 and later Interrupt flags. */
+/* IRQ Clear word */
+/* 0: Clear INT0 */
+/* 1: Clear INT1 */
+/* 2: Clear INT2 */
+/* 3: Clear INT3 */
+/* 4: Clear INT4 */
+/* 5: Clear INT5 */
+/* 6: Select VMM table 1 */
+/* 7: Select VMM table 2 */
+/* 8: Enable VMM */
+/*******************************************/
+#define CLR_INT0 (1 << 0)
+#define CLR_INT1 (1 << 1)
+#define CLR_INT2 (1 << 2)
+#define CLR_INT3 (1 << 3)
+#define CLR_INT4 (1 << 4)
+#define CLR_INT5 (1 << 5)
+#define SEL_VMM_TBL0 (1 << 6)
+#define SEL_VMM_TBL1 (1 << 7)
+#define EN_VMM (1 << 8)
+
+#define DATA_INT_EXT INT_0
+#define PLL_INT_EXT INT_1
+#define SLEEP_INT_EXT INT_2
+#define ALL_INT_EXT (DATA_INT_EXT|PLL_INT_EXT|SLEEP_INT_EXT)
+#define NUM_INT_EXT (3)
+
+#define DATA_INT_CLR CLR_INT0
+#define PLL_INT_CLR CLR_INT1
+#define SLEEP_INT_CLR CLR_INT2
+
+#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM)
+#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM)
+
+#endif /* ENABLE_FAST_DMA */
+
+/*time for expiring the semaphores of cfg packets*/
+#define CFG_PKTS_TIMEOUT 2000
+/********************************************
+
+ Debug Type
+
+********************************************/
+typedef void (*nmi_debug_func)(uint32_t, char *, ...);
+
+/********************************************
+
+ Tx/Rx Queue Structure
+
+********************************************/
+
+struct txq_entry_t {
+ struct txq_entry_t *next;
+ struct txq_entry_t *prev;
+ int type;
+ int tcp_PendingAck_index;
+ uint8_t *buffer;
+ int buffer_size;
+ void *priv;
+ int status;
+ void (*tx_complete_func)(void *, int);
+};
+
+struct rxq_entry_t {
+ struct rxq_entry_t *next;
+ uint8_t *buffer;
+ int buffer_size;
+};
+
+/********************************************
+
+ Host IF Structure
+
+********************************************/
+
+typedef struct {
+ int (*hif_init)(nmi_wlan_inp_t *, nmi_debug_func);
+ int (*hif_deinit)(void *);
+ int (*hif_read_reg)(uint32_t, uint32_t *);
+ int (*hif_write_reg)(uint32_t, uint32_t);
+ int (*hif_block_rx)(uint32_t, uint8_t *, uint32_t);
+ int (*hif_block_tx)(uint32_t, uint8_t *, uint32_t);
+ int (*hif_sync)(void);
+ int (*hif_clear_int)(void);
+#if DMA_VER == DMA_VER_2
+ int (*hif_read_int)(uint32_t *);
+ int (*hif_clear_int_ext)(uint32_t);
+ int (*hif_read_size)(uint32_t *);
+ int (*hif_block_tx_ext)(uint32_t, uint8_t *, uint32_t);
+ int (*hif_block_rx_ext)(uint32_t, uint8_t *, uint32_t);
+ int (*hif_sync_ext)(int);
+#endif /* DMA_VER == DMA_VER_2 */
+ void (*hif_set_max_bus_speed)(void);
+ void (*hif_set_default_bus_speed)(void);
+} nmi_hif_func_t;
+
+/********************************************
+
+ Configuration Structure
+
+********************************************/
+
+#define MAX_CFG_FRAME_SIZE 1468
+
+typedef struct {
+ uint8_t ether_header[14];
+ uint8_t ip_header[20];
+ uint8_t udp_header[8];
+ uint8_t wid_header[8];
+ uint8_t frame[MAX_CFG_FRAME_SIZE];
+} nmi_cfg_frame_t;
+
+typedef struct {
+ int (*wlan_tx)(uint8_t *, uint32_t, nmi_tx_complete_func_t);
+} nmi_wlan_cfg_func_t;
+
+typedef struct {
+ int type;
+ uint32_t seq_no;
+} nmi_cfg_rsp_t;
+
+typedef struct {
+ int (*cfg_wid_set)(uint8_t *, uint32_t, uint16_t, uint8_t *, int);
+ int (*cfg_wid_get)(uint8_t *, uint32_t, uint16_t);
+ int (*cfg_wid_get_val)(uint16_t, uint8_t *, uint32_t);
+ int (*rx_indicate)(uint8_t *, int, nmi_cfg_rsp_t *);
+ int (*cfg_init)(nmi_debug_func);
+} nmi_cfg_func_t;
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_cfg.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_cfg.h
new file mode 100755
index 00000000..5f604cdf
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_cfg.h
@@ -0,0 +1,33 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_wlan_cfg.h
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef NMI_WLAN_CFG_H
+#define NMI_WLAN_CFG_H
+
+typedef struct {
+ uint16_t id;
+ uint16_t val;
+} nmi_cfg_byte_t;
+
+typedef struct {
+ uint16_t id;
+ uint16_t val;
+} nmi_cfg_hword_t;
+
+typedef struct {
+ uint32_t id;
+ uint32_t val;
+} nmi_cfg_word_t;
+
+typedef struct {
+ uint32_t id;
+ uint8_t *str;
+} nmi_cfg_str_t;
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_if.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_if.h
new file mode 100755
index 00000000..19d72da3
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/include/nmi_wlan_if.h
@@ -0,0 +1,989 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_wlan_if.h
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef NMI_WLAN_IF_H
+#define NMI_WLAN_IF_H
+
+/*bug 3887: [AP] Allow Management frames to be passed to the host*/
+#define NMI_AP_EXTERNAL_MLME
+#define NMI_P2P
+//#define MEMORY_STATIC
+//#define NMI_FULLY_HOSTING_AP
+//#define USE_OLD_SPI_SW
+
+//#define NMC1000_SINGLE_TRANSFER
+
+#include "nmi_type.h"
+#include "linux_wlan_common.h"
+
+
+/********************************************
+
+ Debug Flags
+
+********************************************/
+
+#define N_INIT 0x00000001
+#define N_ERR 0x00000002
+#define N_TXQ 0x00000004
+#define N_INTR 0x00000008
+#define N_RXQ 0x00000010
+
+/********************************************
+
+ Host Interface Defines
+
+********************************************/
+
+#define HIF_SDIO (0)
+#define HIF_SPI (1 << 0)
+#define HIF_SDIO_GPIO_IRQ (1 << 2)
+
+
+/********************************************
+
+ Tx/Rx Buffer Size Defines
+
+********************************************/
+
+#define CE_TX_BUFFER_SIZE (64 * 1024)
+#define CE_RX_BUFFER_SIZE (384 * 1024)
+
+/********************************************
+
+ Wlan Interface Defines
+
+********************************************/
+
+typedef struct {
+ uint32_t read_write:1;
+ uint32_t function:3;
+ uint32_t raw:1;
+ uint32_t address:17;
+ uint32_t data:8;
+} sdio_cmd52_t;
+
+typedef struct {
+ //struct {
+ uint32_t read_write:1;
+ uint32_t function:3;
+ uint32_t block_mode:1;
+ uint32_t increment:1;
+ uint32_t address:17;
+ uint32_t count:9;
+ //} bit;
+ uint8_t *buffer;
+ uint32_t block_size;
+} sdio_cmd53_t;
+
+typedef struct {
+ void (*os_sleep)(uint32_t);
+ void (*os_atomic_sleep)(uint32_t);
+ void (*os_debug)(uint8_t *);
+ void *(*os_malloc)(uint32_t);
+ void *(*os_malloc_atomic)(uint32_t);
+ void (*os_free)(void *);
+ void (*os_lock)(void *);
+ void (*os_unlock)(void *);
+ int (*os_wait)(void *,NMI_Uint32);
+ void (*os_signal)(void *);
+ void (*os_enter_cs)(void *);
+ void (*os_leave_cs)(void *);
+
+ /*Added by Amr - BugID_4720*/
+ void (*os_spin_lock)(void *, unsigned long *);
+ void (*os_spin_unlock)(void *, unsigned long *);
+
+} nmi_wlan_os_func_t;
+
+typedef struct {
+ int io_type;
+ int (*io_init)(void *);
+ void (*io_deinit)(void *);
+ union {
+ struct {
+ int (*sdio_cmd52)(sdio_cmd52_t *);
+ int (*sdio_cmd53)(sdio_cmd53_t *);
+ int (*sdio_set_max_speed)(void);
+ int (*sdio_set_default_speed)(void);
+ } sdio;
+ struct {
+ int (*spi_max_speed)(void);
+ int (*spi_tx)(uint8_t *, uint32_t);
+ int (*spi_rx)(uint8_t *, uint32_t);
+ int (*spi_trx)(uint8_t *, uint8_t *, uint32_t);
+ } spi;
+ } u;
+} nmi_wlan_io_func_t;
+
+typedef struct {
+ void (*rx_indicate)(uint8_t *, uint32_t,uint32_t);
+ void (*rx_complete)(void);
+} nmi_wlan_net_func_t;
+
+typedef struct {
+ void (*mac_indicate)(int);
+} nmi_wlan_indicate_func_t;
+#define NMI_MAC_INDICATE_STATUS 0x1
+#define NMI_MAC_STATUS_INIT -1
+#define NMI_MAC_STATUS_READY 0
+#define NMI_MAC_STATUS_CONNECT 1
+
+#define NMI_MAC_INDICATE_SCAN 0x2
+
+typedef struct {
+ void *os_private;
+
+ void *hif_critical_section;
+
+ uint32_t tx_buffer_size;
+ void *txq_critical_section;
+
+ /*Added by Amr - BugID_4720*/
+ void *txq_add_to_head_critical_section;
+ void *txq_spin_lock;
+
+ void *txq_wait_event;
+
+#if defined (MEMORY_STATIC)
+ uint32_t rx_buffer_size;
+#endif
+ void *rxq_critical_section;
+ void *rxq_wait_event;
+
+ void *cfg_wait_event;
+} nmi_wlan_os_context_t;
+
+typedef struct {
+ nmi_wlan_os_context_t os_context;
+ nmi_wlan_os_func_t os_func;
+ nmi_wlan_io_func_t io_func;
+ nmi_wlan_net_func_t net_func;
+ nmi_wlan_indicate_func_t indicate_func;
+} nmi_wlan_inp_t;
+
+#if 0
+typedef struct {
+ int start;
+ uint32_t id;
+ void *buffer;
+ uint32_t buffer_size;
+ int commit;
+} nmi_wlan_cfg_set_t;
+
+typedef struct {
+ int start;
+ uint32_t id;
+ int commit;
+} nmi_wlan_cfg_get_t;
+
+typedef struct {
+ uint32_t id;
+ void *buffer;
+ uint32_t buffer_size;
+} nmi_wlan_cfg_val_t;
+#endif
+
+struct tx_complete_data{
+ #ifdef NMI_FULLY_HOSTING_AP
+ struct tx_complete_data* next;
+ #endif
+ int size;
+ void* buff;
+ uint8_t* pBssid;
+ struct sk_buff *skb;
+};
+
+
+typedef void (*nmi_tx_complete_func_t)(void *, int);
+
+#define NMI_TX_ERR_NO_BUF (-2)
+
+typedef struct {
+ int (*wlan_firmware_download)(const uint8_t *, uint32_t);
+ int (*wlan_start)(void);
+ int (*wlan_stop)(void);
+ int (*wlan_add_to_tx_que)(void *, uint8_t *, uint32_t, nmi_tx_complete_func_t);
+ int (*wlan_handle_tx_que)(uint32_t *);
+ void (*wlan_handle_rx_que)(void);
+ void (*wlan_handle_rx_isr)(void);
+ void (*wlan_cleanup)(void);
+ int (*wlan_cfg_set)(int, uint32_t, uint8_t *, uint32_t, int,uint32_t);
+ int (*wlan_cfg_get)(int, uint32_t, int,uint32_t);
+ int (*wlan_cfg_get_value)(uint32_t, uint8_t *, uint32_t);
+ /*Bug3959: transmitting mgmt frames received from host*/
+ #if defined(NMI_AP_EXTERNAL_MLME) || defined(NMI_P2P)
+ int(*wlan_add_mgmt_to_tx_que)(void *, uint8_t *, uint32_t, nmi_tx_complete_func_t);
+
+ #ifdef NMI_FULLY_HOSTING_AP
+ int(*wlan_add_data_to_tx_que)(void *, uint8_t *, uint32_t, nmi_tx_complete_func_t);
+ #endif
+
+ #endif
+} nmi_wlan_oup_t;
+
+/********************************************
+
+ Wlan Configuration ID
+
+********************************************/
+
+#define MAX_SSID_LEN 33
+#define MAX_RATES_SUPPORTED 12
+
+#define INFINITE_SLEEP_TIME (NMI_Uint32)0xFFFFFFFF
+
+#ifdef NMI_PARSE_SCAN_IN_HOST
+typedef enum{
+ SUPP_RATES_IE = 1,
+ EXT_SUPP_RATES_IE =50,
+ HT_CAPABILITY_IE =45,
+ RSN_IE = 48,
+ WPA_IE = 221,
+ WMM_IE=221,
+ #ifdef NMI_P2P
+ P2P_IE=221,
+ #endif
+}BEACON_IE;
+#endif
+typedef enum{
+ INFRASTRUCTURE = 0,
+ INDEPENDENT,
+ AP,
+} BSSTYPE_T;
+
+typedef enum{
+ RATE_AUTO = 0,
+ RATE_1MB = 1,
+ RATE_2MB = 2,
+ RATE_5MB = 5,
+ RATE_6MB = 6,
+ RATE_9MB = 9,
+ RATE_11MB = 11,
+ RATE_12MB = 12,
+ RATE_18MB = 18,
+ RATE_24MB = 24,
+ RATE_26MB = 36,
+ RATE_48MB = 48,
+ RATE_54MB = 54
+} TX_RATE_T;
+
+typedef enum {
+ B_ONLY_MODE = 0, /* basic rate: 1, 2 Mbps, otherwise: 5, 11 Mbps */
+ G_ONLY_MODE, /* basic rate: 6, 12, 24 Mbps, otherwise: 9, 18, 36, 48, 54 Mbps */
+ G_MIXED_11B_1_MODE, /* basic rate: 1, 2, 5.5, 11 Mbps, otherwise: all on */
+ G_MIXED_11B_2_MODE, /* basic rate: 1, 2, 5, 11, 6, 12, 24 Mbps, otherwise: all on */
+} G_OPERATING_MODE_T;
+
+typedef enum {
+ G_SHORT_PREAMBLE = 0, /* Short Preamble */
+ G_LONG_PREAMBLE = 1, /* Long Preamble */
+ G_AUTO_PREAMBLE = 2, /* Auto Preamble Selection */
+} G_PREAMBLE_T;
+
+#define MAC_CONNECTED 1
+#define MAC_DISCONNECTED 0
+
+/*bug3819: */
+#define SCAN_DONE TRUE
+typedef enum{
+ PASSIVE_SCAN = 0,
+ ACTIVE_SCAN = 1,
+} SCANTYPE_T;
+
+typedef enum {
+ NO_POWERSAVE = 0,
+ MIN_FAST_PS = 1,
+ MAX_FAST_PS = 2,
+ MIN_PSPOLL_PS = 3,
+ MAX_PSPOLL_PS = 4
+} USER_PS_MODE_T;
+
+typedef enum {
+ CHIP_WAKEDUP = 0,
+ CHIP_SLEEPING_AUTO = 1,
+ CHIP_SLEEPING_MANUAL = 2
+} CHIP_PS_STATE_T;
+
+typedef enum {
+ ACQUIRE_ONLY = 0,
+ ACQUIRE_AND_WAKEUP = 1,
+} BUS_ACQUIRE_T;
+
+typedef enum {
+ RELEASE_ONLY = 0,
+ RELEASE_ALLOW_SLEEP = 1,
+} BUS_RELEASE_T;
+
+typedef enum {
+ NO_SECURITY = 0,
+ WEP_40 = 0x3,
+ WEP_104 = 0x7,
+ WPA_AES = 0x29,
+ WPA_TKIP = 0x49,
+ WPA_AES_TKIP = 0x69, /* Aes or Tkip */
+ WPA2_AES = 0x31,
+ WPA2_TKIP = 0x51,
+ WPA2_AES_TKIP = 0x71, /* Aes or Tkip */
+} SECURITY_T;
+
+typedef enum{
+ OPEN_SYSTEM = 1,
+ SHARED_KEY = 2,
+ ANY = 3,
+ IEEE8021 =5
+} AUTHTYPE_T;
+
+typedef enum {
+ SITE_SURVEY_1CH = 0,
+ SITE_SURVEY_ALL_CH = 1,
+ SITE_SURVEY_OFF = 2
+} SITE_SURVEY_T;
+
+typedef enum {
+ NORMAL_ACK = 0,
+ NO_ACK,
+} ACK_POLICY_T;
+
+typedef enum{
+ DONT_RESET = 0,
+ DO_RESET = 1,
+ NO_REQUEST = 2,
+} RESET_REQ_T;
+
+typedef enum {
+ REKEY_DISABLE = 1,
+ REKEY_TIME_BASE,
+ REKEY_PKT_BASE,
+ REKEY_TIME_PKT_BASE
+} RSNA_REKEY_POLICY_T;
+
+typedef enum {
+ FILTER_NO = 0x00,
+ FILTER_AP_ONLY = 0x01,
+ FILTER_STA_ONLY = 0x02
+} SCAN_CLASS_FITLER_T;
+
+typedef enum {
+ PRI_HIGH_RSSI = 0x00,
+ PRI_LOW_RSSI = 0x04,
+ PRI_DETECT = 0x08
+} SCAN_PRI_T;
+
+typedef enum {
+ CH_FILTER_OFF = 0x00,
+ CH_FILTER_ON = 0x10
+} CH_FILTER_T;
+
+typedef enum {
+ AUTO_PROT = 0, /* Auto */
+ NO_PROT, /* Do not use any protection */
+ ERP_PROT, /* Protect all ERP frame exchanges */
+ HT_PROT, /* Protect all HT frame exchanges */
+ GF_PROT, /* Protect all GF frame exchanges */
+} N_PROTECTION_MODE_T;
+
+typedef enum {
+ G_SELF_CTS_PROT,
+ G_RTS_CTS_PROT,
+} G_PROTECTION_MODE_T;
+
+typedef enum {
+ HT_MIXED_MODE = 1,
+ HT_ONLY_20MHZ_MODE,
+ HT_ONLY_20_40MHZ_MODE,
+} N_OPERATING_MODE_T;
+
+typedef enum {
+ NO_DETECT = 0,
+ DETECT_ONLY = 1,
+ DETECT_PROTECT = 2,
+ DETECT_PROTECT_REPORT = 3,
+} N_OBSS_DETECTION_T;
+
+typedef enum {
+ RTS_CTS_NONHT_PROT = 0, /* RTS-CTS at non-HT rate */
+ FIRST_FRAME_NONHT_PROT, /* First frame at non-HT rate */
+ LSIG_TXOP_PROT, /* LSIG TXOP Protection */
+ FIRST_FRAME_MIXED_PROT, /* First frame at Mixed format */
+} N_PROTECTION_TYPE_T;
+
+typedef enum {
+ STATIC_MODE = 1,
+ DYNAMIC_MODE = 2,
+ MIMO_MODE = 3, /* power save disable */
+} N_SMPS_MODE_T;
+
+typedef enum {
+ DISABLE_SELF_CTS,
+ ENABLE_SELF_CTS,
+ DISABLE_TX_ABORT,
+ ENABLE_TX_ABORT,
+ HW_TRIGGER_ABORT,
+ SW_TRIGGER_ABORT,
+} TX_ABORT_OPTION_T;
+
+typedef enum {
+ WID_CHAR = 0,
+ WID_SHORT = 1,
+ WID_INT = 2,
+ WID_STR = 3,
+ WID_BIN_DATA = 4,
+ WID_BIN = 5,
+ WID_IP = 6,
+ WID_ADR = 7,
+ WID_UNDEF = 8,
+ WID_TYPE_FORCE_32BIT = 0xFFFFFFFF
+
+} WID_TYPE_T,tenuWIDtype;
+
+typedef enum {
+ WID_NIL = 0xffff,
+
+
+ /* BSS Type */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Infrastructure Independent Access Point */
+ /* Values to set : 0 1 2 */
+ /* -------------------------------------------------------------- */
+ WID_BSS_TYPE = 0x0000,
+
+ /* Transmit Rate */
+ /* -------------------------------------------------------------- */
+ /* Configuration : 1 2 5.5 11 6 9 12 18 24 36 48 54 */
+ /* Values to set : 1 2 5 11 6 9 12 18 24 36 48 54 */
+ /* -------------------------------------------------------------- */
+ WID_CURRENT_TX_RATE = 0x0001,
+
+ /* Channel */
+ /* ------------------------------------------------------------------- */
+ /* Configuration(g) : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
+ /* Values to set : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
+ /* -------------------------------------------------------------------- */
+ WID_CURRENT_CHANNEL = 0x0002,
+
+ /* Preamble */
+ /* -------------------------------------------------------------- */
+ /* Configuration : short long Auto */
+ /* Values to set : 0 1 2 */
+ /* -------------------------------------------------------------- */
+ WID_PREAMBLE = 0x0003,
+
+ /* 11g operating mode (ignored if 11g not present) */
+ /* -------------------------------------------------------------- */
+ /* Configuration : HighPerf Compat(RSet #1) Compat(RSet #2) */
+ /* Values to set : 1 2 3 */
+ /* -------------------------------------------------------------- */
+ WID_11G_OPERATING_MODE = 0x0004,
+
+ /* Mac status (response only) */
+ /* -------------------------------------------------------------- */
+ /* Configuration : disconnect connect */
+ /* Values to get : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_STATUS = 0x0005,
+
+ /* Scan type */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Passive Scanning Active Scanning */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_SCAN_TYPE = 0x0007,
+
+ /* Key Id (WEP default key Id) */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Any value between 0 to 3 */
+ /* Values to set : Same value. Default is 0 */
+ /* -------------------------------------------------------------- */
+ WID_KEY_ID = 0x0009,
+
+ /* QoS Enable */
+ /* -------------------------------------------------------------- */
+ /* Configuration : QoS Disable WMM Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_QOS_ENABLE = 0x000A,
+
+ /* Power Management */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : NO_POWERSAVE MIN_POWERSAVE MAX_POWERSAVE */
+ /* Values to set : 0 1 2 */
+ /* ------------------------------------------------------------------ */
+ WID_POWER_MANAGEMENT = 0x000B,
+
+ /* WEP/802 11I Configuration */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Disable WP40 WP104 WPA-AES WPA-TKIP RSN-AES RSN-TKIP */
+ /* Values (0x) : 00 03 07 29 49 31 51 */
+ /* */
+ /* Configuration : WPA-AES+TKIP RSN-AES+TKIP */
+ /* Values (0x) : 69 71 */
+ /* ------------------------------------------------------------------ */
+ WID_11I_MODE = 0x000C,
+
+ /* WEP Configuration: Used in BSS STA mode only when WEP is enabled */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Open System Shared Key Any Type | 802.1x Auth */
+ /* Values (0x) : 01 02 03 | BIT2 */
+ /* ------------------------------------------------------------------ */
+ WID_AUTH_TYPE = 0x000D,
+
+ /* Site Survey Type */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Values to set */
+ /* Survey 1 Channel : 0 */
+ /* survey all Channels : 1 */
+ /* Disable Site Survey : 2 */
+ /* -------------------------------------------------------------- */
+ WID_SITE_SURVEY = 0x000E,
+
+ /* Listen Interval */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Any value between 1 to 255 */
+ /* Values to set : Same value. Default is 3 */
+ /* -------------------------------------------------------------- */
+ WID_LISTEN_INTERVAL = 0x000F,
+
+ /* DTIM Period */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Any value between 1 to 255 */
+ /* Values to set : Same value. Default is 3 */
+ /* -------------------------------------------------------------- */
+ WID_DTIM_PERIOD = 0x0010,
+
+ /* ACK Policy */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Normal Ack No Ack */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_ACK_POLICY = 0x0011,
+
+ /* Reset MAC (Set only) */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Don't Reset Reset No Request */
+ /* Values to set : 0 1 2 */
+ /* -------------------------------------------------------------- */
+ WID_RESET = 0x0012,
+
+ /* Broadcast SSID Option: Setting this will adhere to "" SSID element */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Enable Disable */
+ /* Values to set : 1 0 */
+ /* ------------------------------------------------------------------ */
+ WID_BCAST_SSID = 0x0015,
+
+ /* Disconnect (Station) */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Association ID */
+ /* Values to set : Association ID */
+ /* ------------------------------------------------------------------ */
+ WID_DISCONNECT = 0x0016,
+
+ /* 11a Tx Power Level */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Sets TX Power (Higher the value greater the power) */
+ /* Values to set : Any value between 0 and 63 (inclusive; Default is 48)*/
+ /* -------------------------------------------------------------------- */
+ WID_TX_POWER_LEVEL_11A = 0x0018,
+
+ /* Group Key Update Policy Selection */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Disabled timeBased packetBased timePacketBased */
+ /* Values to set : 1 2 3 4 */
+ /* -------------------------------------------------------------------- */
+ WID_REKEY_POLICY = 0x0019,
+
+ /* Allow Short Slot */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disallow Short Slot Allow Short Slot */
+ /* (Enable Only Long Slot) (Enable Short Slot if applicable)*/
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_SHORT_SLOT_ALLOWED = 0x001A,
+
+ WID_PHY_ACTIVE_REG = 0x001B,
+
+ /* 11b Tx Power Level */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Sets TX Power (Higher the value greater the power) */
+ /* Values to set : Any value between 0 and 63 (inclusive; Default is 48)*/
+ /* -------------------------------------------------------------------- */
+ WID_TX_POWER_LEVEL_11B = 0x001D,
+
+ /* Scan Request */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Request default scan */
+ /* Values to set : 0 */
+ /* -------------------------------------------------------------------- */
+ WID_START_SCAN_REQ = 0x001E,
+
+ /* Rssi (get only) */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : */
+ /* Values to get : Rssi value */
+ /* -------------------------------------------------------------------- */
+ WID_RSSI = 0x001F,
+
+ /* Join Request */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Request to join */
+ /* Values to set : index of scan result */
+ /* -------------------------------------------------------------------- */
+ WID_JOIN_REQ = 0x0020,
+
+ WID_LINKSPEED = 0x0026,
+
+ /* Enable User Control of TX Power */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------------- */
+ WID_USER_CONTROL_ON_TX_POWER = 0x0027,
+
+ WID_MEMORY_ACCESS_8BIT = 0x0029,
+
+ /* Enable Auto RX Sensitivity feature */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------------- */
+ WID_AUTO_RX_SENSITIVITY = 0x0032,
+
+ /* Receive Buffer Based Ack */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------------- */
+ WID_DATAFLOW_CONTROL = 0x0033,
+
+ /* Scan Filter */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Class No filter AP only Station Only */
+ /* Values to set : 0 1 2 */
+ /* Configuration : Priority High Rssi Low Rssi Detect */
+ /* Values to set : 0 0x4 0x08 */
+ /* Configuration : Channel filter off filter on */
+ /* Values to set : 0 0x10 */
+ /* -------------------------------------------------------------------- */
+ WID_SCAN_FILTER = 0x0036,
+
+ /* Link Loss Threshold (measure in the beacon period) */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Any value between 10 and 254 (Set to 255 to disable it) */
+ /* Values to set : Same value. Default is 10 */
+ /* -------------------------------------------------------------------- */
+ WID_LINK_LOSS_THRESHOLD = 0x0037,
+ #ifdef NMI_P2P
+ WID_REMAIN_ON_CHAN = 0x003D,
+ #endif
+
+ /*BugID_4978*/
+ WID_ABORT_RUNNING_SCAN = 0x003E,
+
+ /* NMAC Character WID list */
+ WID_WPS_START = 0x0043,
+
+ /* Protection mode for MAC */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Auto No protection ERP HT GF */
+ /* Values to set : 0 1 2 3 4 */
+ /* -------------------------------------------------------------- */
+ WID_11N_PROT_MECH = 0x0080,
+
+ /* ERP Protection type for MAC */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Self-CTS RTS-CTS */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_11N_ERP_PROT_TYPE = 0x0081,
+
+ /* HT Option Enable */
+ /* -------------------------------------------------------------- */
+ /* Configuration : HT Enable HT Disable */
+ /* Values to set : 1 0 */
+ /* -------------------------------------------------------------- */
+ WID_11N_ENABLE = 0x0082,
+
+ /* 11n Operating mode (Note that 11g operating mode will also be */
+ /* used in addition to this, if this is set to HT Mixed mode) */
+ /* -------------------------------------------------------------- */
+ /* Configuration : HT Mixed HT Only-20MHz HT Only-20/40MHz */
+ /* Values to set : 1 2 3 */
+ /* -------------------------------------------------------------- */
+ WID_11N_OPERATING_MODE = 0x0083,
+
+ /* 11n OBSS non-HT STA Detection flag */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Do not detect */
+ /* Values to set : 0 */
+ /* Configuration : Detect, do not protect or report */
+ /* Values to set : 1 */
+ /* Configuration : Detect, protect and do not report */
+ /* Values to set : 2 */
+ /* Configuration : Detect, protect and report to other BSS */
+ /* Values to set : 3 */
+ /* -------------------------------------------------------------- */
+ WID_11N_OBSS_NONHT_DETECTION = 0x0084,
+
+ /* 11n HT Protection Type */
+ /* -------------------------------------------------------------- */
+ /* Configuration : RTS-CTS First Frame Exchange at non-HT-rate */
+ /* Values to set : 0 1 */
+ /* Configuration : LSIG TXOP First Frame Exchange in Mixed Fmt */
+ /* Values to set : 2 3 */
+ /* -------------------------------------------------------------- */
+ WID_11N_HT_PROT_TYPE = 0x0085,
+
+ /* 11n RIFS Protection Enable Flag */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_11N_RIFS_PROT_ENABLE = 0x0086,
+
+ /* SMPS Mode */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Static Dynamic MIMO (Power Save Disabled) */
+ /* Values to set : 1 2 3 */
+ /* -------------------------------------------------------------- */
+ WID_11N_SMPS_MODE = 0x0087,
+
+ /* Current transmit MCS */
+ /* -------------------------------------------------------------- */
+ /* Configuration : MCS Index for data rate */
+ /* Values to set : 0 to 7 */
+ /* -------------------------------------------------------------- */
+ WID_11N_CURRENT_TX_MCS = 0x0088,
+
+ WID_11N_PRINT_STATS = 0x0089,
+
+ /* 11n Short GI Enable Flag */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_11N_SHORT_GI_ENABLE = 0x008D,
+
+ /* 11n RIFS Enable Flag */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_RIFS_MODE = 0x0094,
+
+ /* TX Abort Feature */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Self CTS Enable Self CTS */
+ /* Values to set : 0 1 */
+ /* Configuration : Disable TX Abort Enable TX Abort */
+ /* Values to set : 2 3 */
+ /* Configuration : Enable HW TX Abort Enable SW TX Abort */
+ /* Values to set : 4 5 */
+ /* -------------------------------------------------------------- */
+ WID_TX_ABORT_CONFIG = 0x00A1,
+
+ WID_REG_TSSI_11B_VALUE = 0x00A6,
+ WID_REG_TSSI_11G_VALUE = 0x00A7,
+ WID_REG_TSSI_11N_VALUE = 0x00A8,
+ WID_TX_CALIBRATION = 0x00A9,
+ WID_DSCR_TSSI_11B_VALUE = 0x00AA,
+ WID_DSCR_TSSI_11G_VALUE = 0x00AB,
+ WID_DSCR_TSSI_11N_VALUE = 0x00AC,
+
+ /* Immediate Block-Ack Support */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 0 1 */
+ /* -------------------------------------------------------------- */
+ WID_11N_IMMEDIATE_BA_ENABLED = 0x00AF,
+
+ /* TXOP Disable Flag */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Disable Enable */
+ /* Values to set : 1 0 */
+ /* -------------------------------------------------------------- */
+ WID_11N_TXOP_PROT_DISABLE = 0x00B0,
+
+
+ WID_TX_POWER_LEVEL_11N = 0x00B1,
+
+ /* Custom Character WID list */
+ WID_PC_TEST_MODE = 0x00C8,
+ /*bug3819: */
+ /* SCAN Complete notification WID*/
+ WID_SCAN_COMPLETE =0x00C9,
+
+#ifdef NMI_AP_EXTERNAL_MLME
+ WID_DEL_BEACON = 0x00CA,
+#endif
+
+ WID_LOGTerminal_Switch = 0x00CD,
+ /* EMAC Short WID list */
+ /* RTS Threshold */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Any value between 256 to 2347 */
+ /* Values to set : Same value. Default is 2347 */
+ /* -------------------------------------------------------------- */
+ WID_RTS_THRESHOLD = 0x1000,
+
+ /* Fragmentation Threshold */
+ /* -------------------------------------------------------------- */
+ /* Configuration : Any value between 256 to 2346 */
+ /* Values to set : Same value. Default is 2346 */
+ /* -------------------------------------------------------------- */
+ WID_FRAG_THRESHOLD = 0x1001,
+
+ WID_SHORT_RETRY_LIMIT = 0x1002,
+ WID_LONG_RETRY_LIMIT = 0x1003,
+ WID_BEACON_INTERVAL = 0x1006,
+ WID_MEMORY_ACCESS_16BIT = 0x1008,
+ WID_RX_SENSE = 0x100B,
+ WID_ACTIVE_SCAN_TIME = 0x100C,
+ WID_PASSIVE_SCAN_TIME = 0x100D,
+
+ WID_SITE_SURVEY_SCAN_TIME = 0x100E,
+ WID_JOIN_START_TIMEOUT = 0x100F,
+ WID_AUTH_TIMEOUT = 0x1010,
+ WID_ASOC_TIMEOUT = 0x1011,
+ WID_11I_PROTOCOL_TIMEOUT = 0x1012,
+ WID_EAPOL_RESPONSE_TIMEOUT = 0x1013,
+
+ /* NMAC Short WID list */
+ WID_11N_SIG_QUAL_VAL = 0x1085,
+ WID_CCA_THRESHOLD = 0x1087,
+
+ /* Custom Short WID list */
+
+ /* EMAC Integer WID list */
+ WID_FAILED_COUNT = 0x2000,
+ WID_RETRY_COUNT = 0x2001,
+ WID_MULTIPLE_RETRY_COUNT = 0x2002,
+ WID_FRAME_DUPLICATE_COUNT = 0x2003,
+ WID_ACK_FAILURE_COUNT = 0x2004,
+ WID_RECEIVED_FRAGMENT_COUNT = 0x2005,
+ WID_MCAST_RECEIVED_FRAME_COUNT = 0x2006,
+ WID_FCS_ERROR_COUNT = 0x2007,
+ WID_SUCCESS_FRAME_COUNT = 0x2008,
+ WID_HUT_TX_COUNT = 0x200A,
+ WID_TX_FRAGMENT_COUNT = 0x200B,
+ WID_TX_MULTICAST_FRAME_COUNT = 0x200C,
+ WID_RTS_SUCCESS_COUNT = 0x200D,
+ WID_RTS_FAILURE_COUNT = 0x200E,
+ WID_WEP_UNDECRYPTABLE_COUNT = 0x200F,
+ WID_REKEY_PERIOD = 0x2010,
+ WID_REKEY_PACKET_COUNT = 0x2011,
+ WID_1X_SERV_ADDR = 0x2012,
+ WID_STACK_IP_ADDR = 0x2013,
+ WID_STACK_NETMASK_ADDR = 0x2014,
+ WID_HW_RX_COUNT = 0x2015,
+ WID_MEMORY_ADDRESS = 0x201E,
+ WID_MEMORY_ACCESS_32BIT = 0x201F,
+ WID_RF_REG_VAL = 0x2021,
+
+
+ /* NMAC Integer WID list */
+ WID_11N_PHY_ACTIVE_REG_VAL = 0x2080,
+
+ /* Custom Integer WID list */
+ WID_GET_INACTIVE_TIME = 0x2084,
+ WID_SET_DRV_HANDLER= 0X2085,
+ WID_SET_OPERATION_MODE= 0X2086,
+ /* EMAC String WID list */
+ WID_SSID = 0x3000,
+ WID_FIRMWARE_VERSION = 0x3001,
+ WID_OPERATIONAL_RATE_SET = 0x3002,
+ WID_BSSID = 0x3003,
+ WID_WEP_KEY_VALUE = 0x3004,
+ WID_11I_PSK = 0x3008,
+ WID_11E_P_ACTION_REQ = 0x3009,
+ WID_1X_KEY = 0x300A,
+ WID_HARDWARE_VERSION = 0x300B,
+ WID_MAC_ADDR = 0x300C,
+ WID_HUT_DEST_ADDR = 0x300D,
+ WID_PHY_VERSION = 0x300F,
+ WID_SUPP_USERNAME = 0x3010,
+ WID_SUPP_PASSWORD = 0x3011,
+ WID_SITE_SURVEY_RESULTS = 0x3012,
+ WID_RX_POWER_LEVEL = 0x3013,
+ WID_SET_STA_MAC_INACTIVE_TIME = 0x3017,
+ WID_ADD_WEP_KEY = 0x3019,
+ WID_REMOVE_WEP_KEY = 0x301A,
+ WID_ADD_PTK = 0x301B,
+ WID_ADD_RX_GTK = 0x301C,
+ WID_ADD_TX_GTK = 0x301D,
+ WID_REMOVE_KEY = 0x301E,
+ WID_ASSOC_REQ_INFO = 0x301F,
+ WID_ASSOC_RES_INFO = 0x3020,
+ WID_MANUFACTURER = 0x3026, /*Added for CAPI tool */
+ WID_MODEL_NAME = 0x3027, /*Added for CAPI tool */
+ WID_MODEL_NUM = 0x3028, /*Added for CAPI tool */
+ WID_DEVICE_NAME = 0x3029, /*Added for CAPI tool */
+
+ /* NMAC String WID list */
+ WID_11N_P_ACTION_REQ = 0x3080,
+ WID_HUT_TEST_ID = 0x3081,
+ WID_PMKID_INFO = 0x3082,
+ WID_FIRMWARE_INFO = 0x3083,
+ #ifdef NMI_P2P
+ WID_REGISTER_FRAME = 0x3084,
+ #endif
+ /*BugID_4156*/
+ WID_SSID_PROBE_REQ = 0x3997,
+ /*BugID_4124 WID to trigger modified Join Request using SSID and BSSID instead of bssListIdx (used by WID_JOIN_REQ)*/
+ WID_JOIN_REQ_EXTENDED = 0x3998,
+
+ /* BugID 4951: WID toset IP address in firmware */
+ WID_IP_ADDRESS = 0x3999,
+
+
+
+ /* Custom String WID list */
+
+ /* EMAC Binary WID list */
+ WID_UAPSD_CONFIG = 0x4001,
+ WID_UAPSD_STATUS = 0x4002,
+ WID_WMM_AP_AC_PARAMS = 0x4003,
+ WID_WMM_STA_AC_PARAMS = 0x4004,
+ WID_NETWORK_INFO = 0x4005,
+ WID_STA_JOIN_INFO = 0x4006,
+ WID_CONNECTED_STA_LIST = 0x4007,
+
+ /* NMAC Binary WID list */
+ WID_11N_AUTORATE_TABLE = 0x4080,
+
+
+ /*Added here by Amr - BugID 4134*/
+ WID_SCAN_CHANNEL_LIST = 0x4084,
+
+ /*BugID_3746 WID to add IE to be added in next probe request*/
+ WID_INFO_ELEMENT_PROBE = 0x4085,
+ /*BugID_3746 WID to add IE to be added in next associate request*/
+ WID_INFO_ELEMENT_ASSOCIATE = 0x4086,
+ WID_ADD_STA = 0X4087,
+ WID_REMOVE_STA = 0X4088,
+ WID_EDIT_STA = 0X4089,
+ WID_ADD_BEACON = 0x408a,
+
+ /* BugID 5108 */
+ WID_SETUP_MULTICAST_FILTER = 0x408b,
+
+ /* Miscellaneous WIDs */
+ WID_ALL = 0x7FFE,
+ WID_MAX = 0xFFFF
+} WID_T;
+
+int nmi_wlan_init(nmi_wlan_inp_t *inp, nmi_wlan_oup_t *oup);
+
+void nmi_bus_set_max_speed(void);
+void nmi_bus_set_default_speed(void);
+uint32_t nmi_get_chipid(uint8_t update);
+
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/Makefile b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/Makefile
new file mode 100755
index 00000000..657a007a
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/Makefile
@@ -0,0 +1,177 @@
+# Comment/uncomment the following line to disable/enable debugging
+MAKE = make
+RM = rm
+MV = mv
+ECHO = echo
+CP = cp
+
+
+#DEBUG = y
+# Add your debugging flag (or not) to CFLAGS
+ifeq ($(DEBUG),y)
+DEBFLAGS = -O -g
+else
+DEBFLAGS = -O2
+endif
+
+#Use external 1.4V VCO
+EXTRA_CFLAGS += -DVCO_14_SUPPLY
+#EXTRA_CFLAGS += -DREG_0XF6_NOT_CLEAR_BUG_FIX
+
+EXTRA_CFLAGS += -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP
+EXTRA_CFLAGS += -DAGING_ALG
+
+#Default to NMI=EVAL if NMI isn't defined
+ifeq ($(strip $(NMI)),)
+NMI=EVAL
+endif
+
+ifeq ($(NMI),EVAL)
+EXTRA_CFLAGS += -DNMC_ASIC_A0
+else ifeq ($(NMI),FPGA)
+endif
+
+EXTRA_CFLAGS += -DCONNECT_DIRECT -DNMI_PARSE_SCAN_IN_HOST
+
+ifeq ($(BUS),SDIO)
+EXTRA_CFLAGS += -DNMI_SDIO
+endif
+
+ifeq ($(SDIO_IRQ),GPIO)
+EXTRA_CFLAGS += -DNMI_SDIO_IRQ_GPIO
+endif
+
+ifeq ($(DMA_VER),VER_1)
+EXTRA_CFLAGS += -DUSE_DMA_VER_1
+endif
+
+ifeq ($(TARGET),SIMULATION)
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+TARGET=SIMULATION
+EXTRA_CFLAGS += -DSIMULATION -g
+OUT_ARCH = x86
+else ifeq ($(TARGET),PANDA)
+KERNELDIR ?= $(DEV_TREE)/kernel/omap
+EXTRA_CFLAGS += -DPANDA_BOARD -DUSE_WIRELESS
+ifeq ($(ANDR_VER),4.3)
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi- ARCH=arm
+else ifeq ($(ANDR_VER),4.2)
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi- ARCH=arm
+else
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm
+endif
+OUT_ARCH = ARM-3.0
+#EXTRA_CFLAGS += -DSIMULATION
+else ifeq ($(TARGET),BEAGLE)
+KERNELDIR ?= $(DEV_TREE)
+OUT_ARCH = ARM-2.6.39
+MAKE_FLAGS := CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DBEAGLE_BOARD
+KERNELDIR ?= $(DEV_TREE)
+else ifeq ($(TARGET),NM73131)
+KERNELDIR ?= $(DEV_TREE_LPC)
+OUT_ARCH = ARM-2.6.28.2
+MAKE_FLAGS := CROSS_COMPILE=arm-linux- ARCH=arm
+EXTRA_CFLAGS += -DNM73131_0_BOARD
+else ifeq ($(TARGET),ALLWINNER)
+KERNELDIR ?= $(DEV_TREE)/linux-3.0
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/buildroot/output/external-toolchain/bin/arm-none-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DALLWINNER_BOARD -DUSE_WIRELESS
+OUT_ARCH = ARM-3.0
+else ifeq ($(TARGET),ALLWINNER_A20)
+KERNELDIR ?= $(DEV_TREE)/linux-3.3
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A20 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.3
+else ifeq ($(TARGET),ALLWINNER_A23)
+KERNELDIR ?= $(DEV_TREE)/linux-3.4
+MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/out/android/common/buildroot/external-toolchain/bin/arm-linux-gnueabi- ARCH=arm
+EXTRA_CFLAGS += -DPLAT_ALLWINNER_A23 -DUSE_WIRELESS
+OUT_ARCH = ARM-3.4
+else
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+OUT_ARCH = x86
+TARGET=SIMULATION
+EXTRA_CFLAGS += -DSIMULATION
+endif
+
+ifeq ($(FIRMLOG),HOST)
+ EXTRA_CFLAGS += -DSWITCH_LOG_TERMINAL
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS) -I $(PWD)/../../NMI_OsWrapper/include/
+EXTRA_CFLAGS += -I $(PWD)/../../ -I $(PWD)/../include -I $(PWD)/../ -I $(PWD)/include
+EXTRA_CFLAGS += -DNMI_PLATFORM=NMI_LINUXKERNEL
+EXTRA_CFLAGS += -Wno-unused-function
+
+
+
+obj-m := nmi_wifi.o
+ifeq ($(TARGET),NM73131)
+ifeq ($(BUS),SDIO)
+nmi_wifi-objs := source/linux_wlan.o source/linux_wlan_sdio.o\
+source/nmi_debugfs.o source/nmi_queue.o\
+../binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a\
+../../NMI_OsWrapper/binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+else
+nmi_wifi-objs := source/linux_wlan.o source/linux_wlan_spi.o\
+source/nmi_debugfs.o source/nmi_queue.o\
+../binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a\
+../../NMI_OsWrapper/binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+endif
+
+else
+
+ifeq ($(BUS),SDIO)
+nmi_wifi-objs := source/NMI_WFI_NetDevice.o source/NMI_WFI_CfgOperations.o\
+source/linux_wlan.o source/linux_wlan_sdio.o source/linux_mon.o\
+source/nmi_debugfs.o source/nmi_queue.o\
+../binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a\
+../../NMI_OsWrapper/binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+else
+nmi_wifi-objs := source/NMI_WFI_NetDevice.o source/NMI_WFI_CfgOperations.o\
+source/linux_wlan.o source/linux_wlan_spi.o source/linux_mon.o\
+source/nmi_debugfs.o source/nmi_queue.o\
+../binary/linux/$(OUT_ARCH)/NMI_WiFi_Driver.a\
+../../NMI_OsWrapper/binary/linux/$(OUT_ARCH)/NMI_OsWrapper.a
+endif
+
+endif
+
+ifneq ($(KERNELRELEASE),)
+# call from kernel build system
+
+
+else
+
+#KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+
+default:
+ echo KERNELDIR = $(KERNELDIR)
+ $(MAKE) TARGET=$(TARGET) NMI=$(NMI) BUS=$(BUS) FULLY_HOSTING_AP=$(FULLY_HOSTING_AP) -C ../
+ @$(ECHO) "###########################################"
+ @$(ECHO) "##### Building NMI WiFi for Linux ######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules $(MAKE_FLAGS)
+ mkdir -p binary/linux/$(OUT_ARCH)
+ $(MV) -f $(PWD)/nmi_wifi.ko binary/linux/$(OUT_ARCH)/nmi_wifi.ko
+
+endif
+
+clean:
+ $(MAKE) TARGET=$(TARGET) NMI=$(NMI) BUS=$(BUS) -C ../ clean
+ @$(ECHO) "###########################################"
+ @$(ECHO) "##### Cleaning NMI WiFi for Linux ######"
+ @$(ECHO) "##### TARGET =" $(TARGET) "######"
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
+ rm -rf binary/linux/$(OUT_ARCH)/nmi_wifi.ko
+
+depend .depend dep:
+ $(CC) $(CFLAGS) -M *.c > .depend
+
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/allwinner_run_eval.sh b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/allwinner_run_eval.sh
new file mode 100755
index 00000000..879a98fc
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/allwinner_run_eval.sh
@@ -0,0 +1,4 @@
+adb push ../../core/wifi_v111/ASIC_A0/wifi_firmware.bin /system/vendor/firmware/wifi_firmware.bin
+adb push binary/linux/ARM-3.0/nmi_wifi.ko /system/vendor/modules/nmi_wifi.ko
+adb shell "echo 0 > /proc/driver/sunxi-mmc.3/insert"
+adb shell "echo 1 > /proc/driver/sunxi-mmc.3/insert" \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/ap_soft.conf b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/ap_soft.conf
new file mode 100755
index 00000000..b23dbf50
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/ap_soft.conf
@@ -0,0 +1,30 @@
+interface=p2p0
+dump_file=/data/misc/wifi/hostapd.dump
+driver=nl80211
+ctrl_interface=/data/misc/wifi/hostapd
+ssid=HOSTAPD
+dtim_period=2
+beacon_int=100
+channel=6
+hw_mode=g
+ieee80211n=1
+#require_ht=1
+ht_capab=[RX-STBC01]
+max_num_sta=8
+#wmm_enabled=1
+#auth_algs=1
+ap_max_inactivity=300
+#wpa=2
+#wpa_passphrase=12345678
+#wpa_key_mgmt=WPA-PSK
+#wpa_pairwise= CCMP
+#rsn_pairwise=CCMP
+#auth_algs=3
+#ignore_broadcast_ssid=0
+#wep_default_key=0
+#wep_key0=1234567890
+#wep_key0=000102030405060708090a0b0c
+#wep_key0=0102030405060708090a0b0c0d
+#wep_key0=1234567890abcdef1234567890
+#wep_key_len_broadcast=10
+#wep_key_len_unicast=10
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_CfgOperations.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_CfgOperations.h
new file mode 100755
index 00000000..f5637324
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_CfgOperations.h
@@ -0,0 +1,105 @@
+/*!
+* @file NMI_WFI_CfgOperations.h
+* @brief Definitions for the network module
+* @author syounan
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 31 Aug 2010
+* @version 1.0
+*/
+#ifndef NM_WFI_CFGOPERATIONS
+#define NM_WFI_CFGOPERATIONS
+#include "linux/include/NMI_WFI_NetDevice.h"
+
+#ifdef NMI_FULLY_HOSTING_AP
+#include "NMI_host_AP.h"
+#endif
+
+
+/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
+#define NO_ENCRYPT 0
+#define ENCRYPT_ENABLED (1 << 0)
+#define WEP (1 << 1)
+#define WEP_EXTENDED (1 << 2)
+#define WPA (1 << 3)
+#define WPA2 (1 << 4)
+#define AES (1 << 5)
+#define TKIP (1 << 6)
+
+#ifdef NMI_P2P
+#define GO_INTENT_ATTR_ID 0x04
+#define CHANNEL_LIST_ATTR_ID 0x0b
+#define GO_NEG_REQ_ATTR_ID 0x00
+#define GO_NEG_RSP_ATTR_ID 0x01
+#define P2P_INVITE_REQ 0x03
+#define P2P_INVITE_RSP 0x04
+#define ACTION_FRAME 0xd0
+#define PUBLICACTION_CAT 0x04
+#define PUBLICACTION_FRAME 0x09
+#define DEFAULT_CHANNEL 7
+#define P2PELEM_ID 0xdd
+#define GO_INTENT_ATTR_ID 0x04
+#define CHANLIST_ATTR_ID 0x0b
+#define OPERCHAN_ATTR_ID 0x11
+#endif
+
+#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
+#define SCAN_RESULT_EXPIRE (40 * HZ)
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+ WLAN_CIPHER_SUITE_AES_CMAC,
+};
+#endif
+
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+static const struct ieee80211_txrx_stypes
+nmi_wfi_cfg80211_mgmt_types[NL80211_IFTYPE_MAX] =
+{
+ [NL80211_IFTYPE_STATION] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_AP] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
+ },
+ [NL80211_IFTYPE_P2P_CLIENT] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4)
+ }
+};
+#endif
+/* Time to stay on the channel */
+#define NMI_WFI_DWELL_PASSIVE 100
+#define NMI_WFI_DWELL_ACTIVE 40
+
+struct wireless_dev* NMI_WFI_CfgAlloc(void);
+struct wireless_dev * NMI_WFI_WiphyRegister(struct net_device *net);
+void NMI_WFI_WiphyFree(struct net_device *net);
+int NMI_WFI_update_stats(struct wiphy *wiphy, u32 pktlen , u8 changed);
+int NMI_WFI_DeInitHostInt(struct net_device *net);
+int NMI_WFI_InitHostInt(struct net_device *net);
+void NMI_WFI_monitor_rx(uint8_t *buff, uint32_t size);
+int NMI_WFI_deinit_mon_interface(void);
+struct net_device * NMI_WFI_init_mon_interface(char *name, struct net_device *real_dev );
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_NetDevice.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_NetDevice.h
new file mode 100755
index 00000000..9f99b85e
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/include/NMI_WFI_NetDevice.h
@@ -0,0 +1,304 @@
+/*!
+* @file NMI_WFI_NetDevice.h
+* @brief Definitions for the network module
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+#ifndef NMI_WFI_NETDEVICE
+#define NMI_WFI_NETDEVICE
+/*
+* Macros to help debugging
+*/
+
+#undef PDEBUG /* undef it, just in case */
+#ifdef SNULL_DEBUG
+# ifdef __KERNEL__
+/* This one if debugging is on, and kernel space */
+# define PDEBUG(fmt, args...) printk( KERN_DEBUG "snull: " fmt, ## args)
+# else
+/* This one for user space */
+# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
+# endif
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+#endif
+
+#undef PDEBUGG
+#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */
+
+
+/* These are the flags in the statusword */
+#define NMI_WFI_RX_INTR 0x0001
+#define NMI_WFI_TX_INTR 0x0002
+
+/* Default timeout period */
+#define NMI_WFI_TIMEOUT 5 /* In jiffies */
+#define NMI_MAX_NUM_PMKIDS 16
+#define PMKID_LEN 16
+#define PMKID_FOUND 1
+ #define NUM_STA_ASSOCIATED 8
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/slab.h> /* kmalloc() */
+#include <linux/errno.h> /* error codes */
+#include <linux/types.h> /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+#include <linux/time.h>
+#include <linux/in.h>
+#include <linux/netdevice.h> /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h> /* struct iphdr */
+#include <linux/tcp.h> /* struct tcphdr */
+#include <linux/skbuff.h>
+
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/if_arp.h>
+
+
+#include <linux/in6.h>
+#include <asm/checksum.h>
+#include "host_interface.h"
+#include "nmi_wlan.h"
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30)
+#include <net/wireless.h>
+#else
+#include <linux/wireless.h> // tony, 2013-06-12
+#endif
+
+
+#define FLOW_CONTROL_LOWER_THRESHOLD 128
+#define FLOW_CONTROL_UPPER_THRESHOLD 256
+
+/*iftype*/
+
+
+enum stats_flags
+{
+ NMI_WFI_RX_PKT = 1 << 0,
+ NMI_WFI_TX_PKT = 1 << 1,
+};
+
+struct NMI_WFI_stats
+{
+
+ unsigned long rx_packets;
+ unsigned long tx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_bytes;
+ u64 rx_time;
+ u64 tx_time;
+
+};
+
+/*
+* This structure is private to each device. It is used to pass
+* packets in and out, so there is place for a packet
+*/
+
+#define RX_BH_KTHREAD 0
+#define RX_BH_WORK_QUEUE 1
+#define RX_BH_THREADED_IRQ 2
+#define num_reg_frame 2
+/*
+ * If you use RX_BH_WORK_QUEUE on LPC3131: You may lose the first interrupt on
+ * LPC3131 which is important to get the MAC start status when you are blocked inside
+ * linux_wlan_firmware_download() which blocks mac_open().
+ */
+#if defined (NM73131_0_BOARD)
+#define RX_BH_TYPE RX_BH_KTHREAD
+#else
+#define RX_BH_TYPE RX_BH_WORK_QUEUE
+#endif
+
+struct nmi_wfi_key {
+ u8 * key;
+ u8 * seq;
+ int key_len;
+ int seq_len;
+ u32 cipher;
+};
+struct nmi_wfi_wep_key {
+ u8 * key;
+ u8 key_len;
+ u8 key_idx;
+};
+
+struct sta_info
+{
+ NMI_Uint8 au8Sta_AssociatedBss[MAX_NUM_STA][ETH_ALEN];
+};
+
+#ifdef NMI_P2P
+/*Parameters needed for host interface for remaining on channel*/
+struct nmi_wfi_p2pListenParams
+{
+ struct ieee80211_channel * pstrListenChan;
+ enum nl80211_channel_type tenuChannelType;
+ NMI_Uint32 u32ListenDuration;
+ NMI_Uint64 u64ListenCookie;
+};
+
+#endif /*NMI_P2P*/
+
+struct NMI_WFI_priv {
+ struct wireless_dev *wdev;
+ struct cfg80211_scan_request* pstrScanReq;
+
+ #ifdef NMI_P2P
+ NMI_Uint32 u32listen_freq;
+ struct nmi_wfi_p2pListenParams strRemainOnChanParams;
+ NMI_Uint64 u64tx_cookie;
+
+ #endif
+
+ /*Added by Amr - BugID_4793*/
+ NMI_Uint8 u8CurrChannel;
+
+ NMI_Bool bCfgScanning;
+ NMI_Uint32 u32RcvdChCount;
+
+
+
+ NMI_Uint8 au8AssociatedBss[ETH_ALEN];
+ struct sta_info assoc_stainfo;
+ struct net_device_stats stats;
+ NMI_Uint8 monitor_flag;
+ int status;
+ struct NMI_WFI_packet *ppool;
+ struct NMI_WFI_packet *rx_queue; /* List of incoming packets */
+ int rx_int_enabled;
+ int tx_packetlen;
+ u8 *tx_packetdata;
+ struct sk_buff *skb;
+ spinlock_t lock;
+ struct net_device *dev;
+ struct napi_struct napi;
+ NMI_WFIDrvHandle hNMIWFIDrv;
+ NMI_WFIDrvHandle hNMIWFIDrv_2;
+ tstrHostIFpmkidAttr pmkid_list;
+ struct NMI_WFI_stats netstats;
+ NMI_Uint8 NMI_WFI_wep_default;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+#define WLAN_KEY_LEN_WEP104 13
+#endif
+ NMI_Uint8 NMI_WFI_wep_key[4][WLAN_KEY_LEN_WEP104];
+ NMI_Uint8 NMI_WFI_wep_key_len[4];
+ struct net_device* real_ndev; /* The real interface that the monitor is on */
+ struct nmi_wfi_key* nmi_gtk[MAX_NUM_STA];
+ struct nmi_wfi_key* nmi_ptk[MAX_NUM_STA];
+ NMI_Uint8 nmi_groupkey;
+ //semaphores
+ NMI_SemaphoreHandle SemHandleUpdateStats;
+ NMI_SemaphoreHandle hSemScanReq;
+ //
+ NMI_Bool gbAutoRateAdjusted;
+
+
+};
+
+typedef struct
+{
+ NMI_Uint16 frame_type;
+ NMI_Bool reg;
+
+}struct_frame_reg;
+
+
+#define NUM_CONCURRENT_IFC 2
+typedef struct{
+uint8_t aSrcAddress[ETH_ALEN];
+uint8_t aBSSID[ETH_ALEN];
+uint32_t drvHandler;
+struct net_device* nmc_netdev;
+}tstrInterfaceInfo;
+typedef struct{
+ int mac_status;
+ int nmc1000_initialized;
+
+
+ #if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ unsigned short dev_irq_num;
+ #endif
+ nmi_wlan_oup_t oup;
+ int close;
+ uint8_t u8NoIfcs;
+ tstrInterfaceInfo strInterfaceInfo[NUM_CONCURRENT_IFC];
+ uint8_t open_ifcs;
+ struct mutex txq_cs;
+
+ /*Added by Amr - BugID_4720*/
+ struct mutex txq_add_to_head_cs;
+ spinlock_t txq_spinlock;
+
+ struct mutex rxq_cs;
+ struct mutex hif_cs;
+
+ //struct mutex txq_event;
+ struct semaphore rxq_event;
+ struct semaphore cfg_event;
+ struct semaphore sync_event;
+
+ struct semaphore txq_event;
+ //struct completion txq_event;
+
+#if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
+ struct work_struct rx_work_queue;
+#elif (RX_BH_TYPE == RX_BH_KTHREAD)
+ struct task_struct* rx_bh_thread;
+ struct semaphore rx_sem;
+#endif
+
+
+
+ struct semaphore rxq_thread_started;
+ struct semaphore txq_thread_started;
+
+ struct task_struct* rxq_thread;
+ struct task_struct* txq_thread;
+
+ unsigned char eth_src_address[NUM_CONCURRENT_IFC][6];
+ //unsigned char eth_dst_address[6];
+
+ const struct firmware* nmc_firmware; /* Bug 4703 */
+
+ struct net_device* real_ndev;
+#ifdef NMI_SDIO
+ int already_claim;
+ struct sdio_func* nmc_sdio_func;
+#else
+ struct spi_device* nmc_spidev;
+#endif
+
+} linux_wlan_t;
+
+typedef struct
+{
+ uint8_t u8IfIdx;
+ NMI_Uint8 iftype;
+ int monitor_flag;
+ int mac_opened;
+ #ifdef NMI_P2P
+ struct_frame_reg g_struct_frame_reg[num_reg_frame];
+ #endif
+struct net_device* nmc_netdev;
+struct net_device_stats netstats;
+
+}perInterface_wlan_t;
+
+struct NMI_WFI_mon_priv
+{
+ struct net_device* real_ndev;
+};
+extern struct net_device *NMI_WFI_devs[];
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/init_deinit_test.sh b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/init_deinit_test.sh
new file mode 100755
index 00000000..31bcc7a2
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/init_deinit_test.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+num_init_iterations=0
+echo "* Starting Init/Deinit Test *"
+while [ "$num_init_iterations" -lt "20" ]
+do
+echo "*****************************************"
+echo "* initialization trial no. $((num_init_iterations+1)) *"
+echo "*****************************************"
+echo "Bringing wlan0 down"
+ret_cfg_iface=$(adb shell ifconfig wlan0 down)
+ret_cfg_iface_err=$(echo "$ret_cfg_iface" | grep 'error')
+echo "$ret_cfg_iface_err"
+if [ -n "${ret_cfg_iface_err}" ]; then
+ echo "failed in ifconfig wlan1 down"
+ echo "..Initialization failed.."
+ exit
+fi
+sleep 1
+echo "Bringing wlan0 up"
+ret_cfg_iface=$(adb shell ifconfig wlan0 up)
+ret_cfg_iface_err=$(echo "$ret_cfg_iface" | grep 'error')
+echo "$ret_cfg_iface_err"
+if [ -n "${ret_cfg_iface_err}" ]; then
+ echo "failed in ifconfig wlan1 up"
+ echo "..Initialization failed.."
+ exit
+fi
+sleep 1
+echo "Disabling Wifi"
+adb shell svc wifi disable
+sleep 5
+echo "Enabling Wifi"
+adb shell svc wifi enable
+sleep 10
+cli_status=$(adb shell wpa_cli status)
+echo cli_status
+cli_status_check=$(echo "$cli_status" | grep ^wpa_state)
+
+if [ -z "${cli_status_check}" ]; then
+ echo "failed in wpa_cli status"
+ echo "..Initialization failed.."
+ exit
+fi
+echo "succeeded"
+num_init_iterations=$((num_init_iterations+1))
+adb shell ping -i.4 -c10 192.168.11.1
+#adb shell ping -i.4 -c10 192.168.1.1
+
+done
+echo "num of succeded init/deinit trials $num_init_iterations"
+echo "* End of Init/Deinit Test *"
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_load b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_load
new file mode 100755
index 00000000..a4e42aa6
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_load
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+export PATH=/sbin:/bin
+# Use a pathname, as new modutils don't look in the current dir by default
+#modprobe cfg80211
+insmod /lib/modules/$(uname -r)/kernel/net/wireless/cfg80211.ko
+insmod ./binary/linux/x86/nmi_wifi.ko $*
+
+ifconfig wlan0 local0
+ifconfig wlan1 local1
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_unload b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_unload
new file mode 100755
index 00000000..134c9352
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/nmi_wfi_unload
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+/sbin/ifconfig wlan0 down
+/sbin/ifconfig wlan1 down
+/sbin/rmmod nmi_wifi
+rmmod cfg80211
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_eval.sh b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_eval.sh
new file mode 100755
index 00000000..f9717eb4
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_eval.sh
@@ -0,0 +1,7 @@
+adb shell rm /system/etc/firmware/wifi_firmware.bin
+adb push ../../core/wifi_v111/ASIC_A0/wifi_firmware.bin /system/etc/firmware/wifi_firmware.bin
+adb push ../../core/wifi_v111/ASIC_A0_AP/wifi_firmware_ap.bin /system/etc/firmware/wifi_firmware_ap.bin
+adb push ../../core/wifi_v111/ASIC_A0/wifi_firmware_p2p_concurrency.bin /system/etc/firmware/wifi_firmware_p2p_concurrency.bin
+adb shell rm /data/nmi_wifi.ko
+adb push binary/linux/ARM-3.0/nmi_wifi.ko /data/nmi_wifi.ko
+adb push ./ap_soft.conf /data/misc/wifi/hostapd.conf
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_fpga.sh b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_fpga.sh
new file mode 100755
index 00000000..d8a1a897
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/panda_run_fpga.sh
@@ -0,0 +1,4 @@
+adb push ../../core/wifi_v111/FPGA_485t/wifi_firmware.bin /system/etc/firmware/wifi_firmware.bin
+adb push binary/linux/ARM-3.0/nmi_wifi.ko /sdcard/nmi_wifi.ko
+#adb push ../../../../../AdelShare/android4.0/softap.conf /data/misc/wifi/softap.conf
+adb shell insmod /sdcard/nmi_wifi.ko
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_CfgOperations.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_CfgOperations.c
new file mode 100755
index 00000000..25a6a485
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_CfgOperations.c
@@ -0,0 +1,4503 @@
+/*!
+* @file NMI_WFI_CfgOpertaions.c
+* @brief CFG80211 Function Implementation functionality
+* @author aabouzaeid
+* mabubakr
+* mdaftedar
+* zsalah
+* @sa NMI_WFI_CfgOpertaions.h top level OS wrapper file
+* @date 31 Aug 2010
+* @version 1.0
+*/
+
+#include "linux/include/NMI_WFI_CfgOperations.h"
+#include "nmi_wlan.c"
+#include "linux_wlan_sdio.h" //tony : for set_wiphy_dev()
+
+
+#define IS_MANAGMEMENT 0x100
+#define IS_MANAGMEMENT_CALLBACK 0x080
+#define IS_MGMT_STATUS_SUCCES 0x040
+#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
+
+extern void linux_wlan_free(void* vp);
+extern int linux_wlan_get_firmware(perInterface_wlan_t* p_nic);
+extern void linux_wlan_unlock(void* vp);
+extern NMI_Uint16 Set_machw_change_vir_if(NMI_Bool bValue);
+
+extern int mac_open(struct net_device *ndev);
+extern int mac_close(struct net_device *ndev);
+
+tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
+NMI_Uint32 u32LastScannedNtwrksCountShadow;
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+NMI_TimerHandle hDuringIpTimer;
+#endif
+NMI_TimerHandle hAgingTimer;
+static NMI_Uint8 op_ifcs=0;
+
+
+/*BugID_5137*/
+NMI_Uint8 g_nmc_initialized = 1;
+extern linux_wlan_t* g_linux_wlan;
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+extern NMI_Bool g_obtainingIP;
+#endif
+
+#define CHAN2G(_channel, _freq, _flags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_channel), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+/*Frequency range for channels*/
+static struct ieee80211_channel NMI_WFI_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+ CHAN2G(2, 2417, 0),
+ CHAN2G(3, 2422, 0),
+ CHAN2G(4, 2427, 0),
+ CHAN2G(5, 2432, 0),
+ CHAN2G(6, 2437, 0),
+ CHAN2G(7, 2442, 0),
+ CHAN2G(8, 2447, 0),
+ CHAN2G(9, 2452, 0),
+ CHAN2G(10, 2457, 0),
+ CHAN2G(11, 2462, 0),
+ CHAN2G(12, 2467, 0),
+ CHAN2G(13, 2472, 0),
+ CHAN2G(14, 2484, 0),
+};
+
+#define RATETAB_ENT(_rate, _hw_value, _flags) { \
+ .bitrate = (_rate), \
+ .hw_value = (_hw_value), \
+ .flags = (_flags), \
+}
+
+
+/* Table 6 in section 3.2.1.1 */
+static struct ieee80211_rate NMI_WFI_rates[] = {
+ RATETAB_ENT(10, 0, 0),
+ RATETAB_ENT(20, 1, 0),
+ RATETAB_ENT(55, 2, 0),
+ RATETAB_ENT(110, 3, 0),
+ RATETAB_ENT(60, 9, 0),
+ RATETAB_ENT(90, 6, 0),
+ RATETAB_ENT(120, 7, 0),
+ RATETAB_ENT(180, 8, 0),
+ RATETAB_ENT(240, 9, 0),
+ RATETAB_ENT(360, 10, 0),
+ RATETAB_ENT(480, 11, 0),
+ RATETAB_ENT(540, 12, 0),
+};
+
+#ifdef NMI_P2P
+struct p2p_mgmt_data{
+ int size;
+ u8* buff;
+};
+
+/*Global variable used to state the current connected STA channel*/
+NMI_Uint8 u8WLANChannel = DEFAULT_CHANNEL ;
+
+NMI_Uint8 u8P2P_oui[] ={0x50,0x6f,0x9A,0x09};
+NMI_Uint8 u8P2Plocalrandom=0x01;
+NMI_Uint8 u8P2Precvrandom=0x00;
+NMI_Uint8 u8P2P_vendorspec[]={0xdd,0x05,0x00,0x08,0x40,0x03};
+NMI_Bool bNmi_ie=NMI_FALSE;
+#endif
+
+static struct ieee80211_supported_band NMI_WFI_band_2ghz = {
+ .channels = NMI_WFI_2ghz_channels,
+ .n_channels = ARRAY_SIZE(NMI_WFI_2ghz_channels),
+ .bitrates = NMI_WFI_rates,
+ .n_bitrates = ARRAY_SIZE(NMI_WFI_rates),
+};
+
+
+/*BugID_5137*/
+struct add_key_params
+{
+ u8 key_idx;
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ bool pairwise;
+ #endif
+ u8* mac_addr;
+};
+struct add_key_params g_add_gtk_key_params;
+struct nmi_wfi_key g_key_gtk_params;
+struct add_key_params g_add_ptk_key_params;
+struct nmi_wfi_key g_key_ptk_params;
+struct nmi_wfi_wep_key g_key_wep_params;
+NMI_Uint8 g_flushing_in_progress = 0;
+NMI_Bool g_ptk_keys_saved = NMI_FALSE;
+NMI_Bool g_gtk_keys_saved = NMI_FALSE;
+NMI_Bool g_wep_keys_saved = NMI_FALSE;
+
+
+#define AGING_TIME 9*1000
+#define duringIP_TIME 15000
+
+void clear_shadow_scan(void* pUserVoid){
+ struct NMI_WFI_priv* priv;
+ int i;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ for(i = 0; i < u32LastScannedNtwrksCountShadow; i++){
+ if(astrLastScannedNtwrksShadow[u32LastScannedNtwrksCountShadow].pu8IEs != NULL)
+ NMI_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
+
+ host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
+ }
+ u32LastScannedNtwrksCountShadow = 0;
+
+ if(op_ifcs==0)
+ {
+ NMI_TimerDestroy(&hAgingTimer,NMI_NULL);
+ printk("destroy aging timer\n");
+ }
+
+}
+
+uint32_t get_rssi_avg(tstrNetworkInfo* pstrNetworkInfo)
+{
+ uint8_t i;
+ int rssi_v = 0;
+ uint8_t num_rssi = (pstrNetworkInfo->strRssi.u8Full)?NUM_RSSI:(pstrNetworkInfo->strRssi.u8Index);
+
+ for(i=0;i<num_rssi;i++)
+ rssi_v+=pstrNetworkInfo->strRssi.as8RSSI[i];
+
+ rssi_v /= num_rssi;
+ return rssi_v;
+}
+void refresh_scan(void* pUserVoid,uint8_t all,NMI_Bool bDirectScan){
+ struct NMI_WFI_priv* priv;
+ struct wiphy* wiphy;
+ struct cfg80211_bss* bss = NULL;
+ int i;
+ int rssi = 0;
+
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+ wiphy = priv->dev->ieee80211_ptr->wiphy;
+
+ for(i = 0; i < u32LastScannedNtwrksCountShadow; i++)
+ {
+ tstrNetworkInfo* pstrNetworkInfo;
+ pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
+
+
+ if((!pstrNetworkInfo->u8Found) || all){
+ NMI_Sint32 s32Freq;
+ struct ieee80211_channel *channel;
+
+ if(pstrNetworkInfo != NMI_NULL)
+ {
+
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
+ s32Freq = ieee80211_channel_to_frequency((NMI_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
+ #else
+ s32Freq = ieee80211_channel_to_frequency((NMI_Sint32)pstrNetworkInfo->u8channel);
+ #endif
+
+ channel = ieee80211_get_channel(wiphy, s32Freq);
+
+ rssi = get_rssi_avg(pstrNetworkInfo);
+ if(NMI_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan)
+ {
+ bss = cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
+ pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs,
+ (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)rssi) * 100), GFP_KERNEL);
+ cfg80211_put_bss(bss);
+ }
+ }
+
+ }
+ }
+
+}
+
+void reset_shadow_found(void* pUserVoid){
+ struct NMI_WFI_priv* priv;
+ int i;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+ for(i=0;i<u32LastScannedNtwrksCountShadow;i++){
+ astrLastScannedNtwrksShadow[i].u8Found = 0;
+
+ }
+}
+
+void update_scan_time(void* pUserVoid){
+ struct NMI_WFI_priv* priv;
+ int i;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+ for(i=0;i<u32LastScannedNtwrksCountShadow;i++){
+ astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
+ }
+}
+
+void remove_network_from_shadow(void* pUserVoid){
+ struct NMI_WFI_priv* priv;
+ unsigned long now = jiffies;
+ int i,j;
+
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ for(i=0;i<u32LastScannedNtwrksCountShadow;i++){
+ if(time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))){
+ PRINT_D(CFG80211_DBG,"Network expired in ScanShadow: %s \n",astrLastScannedNtwrksShadow[i].au8ssid);
+
+ if(astrLastScannedNtwrksShadow[i].pu8IEs != NULL)
+ NMI_FREE(astrLastScannedNtwrksShadow[i].pu8IEs);
+
+ host_int_freeJoinParams(astrLastScannedNtwrksShadow[i].pJoinParams);
+
+ for(j=i;(j<u32LastScannedNtwrksCountShadow-1);j++){
+ astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j+1];
+ }
+ u32LastScannedNtwrksCountShadow--;
+ }
+ }
+
+ PRINT_D(CFG80211_DBG,"Number of cached networks: %d\n",u32LastScannedNtwrksCountShadow);
+ if(u32LastScannedNtwrksCountShadow != 0)
+ NMI_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NMI_NULL);
+ else
+ PRINT_D(CFG80211_DBG,"No need to restart Aging timer\n");
+}
+
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+void clear_duringIP(void* pUserVoid)
+{
+ PRINT_D(GENERIC_DBG,"GO:IP Obtained , enable scan\n");
+ g_obtainingIP=NMI_FALSE;
+}
+#endif
+
+int8_t is_network_in_shadow(tstrNetworkInfo* pstrNetworkInfo,void* pUserVoid){
+ struct NMI_WFI_priv* priv;
+ int8_t state = -1;
+ int i;
+
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+ if(u32LastScannedNtwrksCountShadow== 0){
+ PRINT_D(CFG80211_DBG,"Starting Aging timer\n");
+ NMI_TimerStart(&(hAgingTimer), AGING_TIME, pUserVoid, NMI_NULL);
+ state = -1;
+ }else{
+ /* Linear search for now */
+ for(i=0;i<u32LastScannedNtwrksCountShadow;i++){
+ if(NMI_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
+ pstrNetworkInfo->au8bssid, 6) == 0){
+ state = i;
+ break;
+ }
+ }
+ }
+ return state;
+}
+
+void add_network_to_shadow(tstrNetworkInfo* pstrNetworkInfo,void* pUserVoid, void* pJoinParams){
+ struct NMI_WFI_priv* priv;
+ int8_t ap_found = is_network_in_shadow(pstrNetworkInfo,pUserVoid);
+ uint32_t ap_index = 0;
+ uint8_t rssi_index = 0;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ if(u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW){
+ PRINT_D(CFG80211_DBG,"Shadow network reached its maximum limit\n");
+ return;
+ }
+ if(ap_found == -1){
+ ap_index = u32LastScannedNtwrksCountShadow;
+ u32LastScannedNtwrksCountShadow++;
+
+ }else{
+ ap_index = ap_found;
+ }
+ rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
+ astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
+ if(rssi_index == NUM_RSSI)
+ {
+ rssi_index = 0;
+ astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
+ }
+ astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
+
+ astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
+ astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
+
+ astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
+ NMI_memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
+ pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
+
+ NMI_memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
+ pstrNetworkInfo->au8bssid, ETH_ALEN);
+
+ astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
+ astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
+ astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
+
+ astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
+ astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
+ if(ap_found != -1)
+ NMI_FREE(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
+ astrLastScannedNtwrksShadow[ap_index].pu8IEs =
+ (NMI_Uint8*)NMI_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated
+ by the NMI_WFI_CfgScan() function */
+ NMI_memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
+ pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
+
+ astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
+ astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
+ astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
+ if(ap_found != -1)
+ host_int_freeJoinParams(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
+ astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
+
+}
+
+
+/**
+* @brief CfgScanResult
+* @details Callback function which returns the scan results found
+*
+* @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
+* SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
+* tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
+* void* pUserVoid: Private structure associated with the wireless interface
+* @return NONE
+* @author mabubakr
+* @date
+* @version 1.0
+*/
+static void CfgScanResult(tenuScanEvent enuScanEvent, tstrNetworkInfo* pstrNetworkInfo, void* pUserVoid, void* pJoinParams)
+ {
+ struct NMI_WFI_priv* priv;
+ struct wiphy* wiphy;
+ NMI_Sint32 s32Freq;
+ struct ieee80211_channel *channel;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct cfg80211_bss* bss = NULL;
+
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+
+ if(priv->bCfgScanning == NMI_TRUE)
+ {
+
+
+ if(enuScanEvent == SCAN_EVENT_NETWORK_FOUND)
+ {
+
+ wiphy = priv->dev->ieee80211_ptr->wiphy;
+
+ NMI_NULLCHECK(s32Error, wiphy);
+
+ if(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
+ &&
+ ( (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100) < 0
+ ||
+ (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100) > 100)
+ )
+ {
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+
+
+ if(pstrNetworkInfo != NMI_NULL)
+ {
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
+ s32Freq = ieee80211_channel_to_frequency((NMI_Sint32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
+ #else
+ s32Freq = ieee80211_channel_to_frequency((NMI_Sint32)pstrNetworkInfo->u8channel);
+ #endif
+ channel = ieee80211_get_channel(wiphy, s32Freq);
+
+ NMI_NULLCHECK(s32Error, channel);
+
+ PRINT_INFO(CFG80211_DBG,"Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
+ "BeaconPeriod: %d \n",channel->center_freq, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100),
+ pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
+
+
+ if(pstrNetworkInfo->bNewNetwork == NMI_TRUE)
+ {
+ if(priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) //TODO: mostafa: to be replaced by
+ // max_scan_ssids
+ {
+ PRINT_D(CFG80211_DBG,"Network %s found\n",pstrNetworkInfo->au8ssid);
+
+
+ priv->u32RcvdChCount++;
+
+
+
+ if(pJoinParams == NULL){
+ printk(">> Something really bad happened\n");
+ }
+ add_network_to_shadow(pstrNetworkInfo,priv,pJoinParams);
+
+ /*P2P peers are sent to WPA supplicant and added to shadow table*/
+
+ if(!(NMI_memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) ))
+ {
+
+ bss = cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
+ pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs,
+ (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
+ cfg80211_put_bss(bss);
+ }
+
+
+ }
+ else
+ {
+ PRINT_ER("Discovered networks exceeded the max limit\n");
+ }
+ }
+ else
+ {
+ NMI_Uint32 i;
+ /* So this network is discovered before, we'll just update its RSSI */
+ for(i = 0; i < priv->u32RcvdChCount; i++)
+ {
+ if(NMI_memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0)
+ {
+ PRINT_D(CFG80211_DBG,"Update RSSI of %s \n",astrLastScannedNtwrksShadow[i].au8ssid);
+
+ astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
+ astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if(enuScanEvent == SCAN_EVENT_DONE)
+ {
+ PRINT_D(CFG80211_DBG,"Scan Done[%p] \n",priv->dev);
+
+ PRINT_D(CFG80211_DBG,"Refreshing Scan ... \n");
+ //refresh_scan(priv,0);
+ refresh_scan(priv,1,NMI_FALSE);
+
+ if(priv->u32RcvdChCount > 0)
+ {
+ PRINT_D(CFG80211_DBG,"%d Network(s) found \n", priv->u32RcvdChCount);
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"No networks found \n");
+ }
+
+ NMI_SemaphoreAcquire(&(priv->hSemScanReq), NULL);
+
+ if(priv->pstrScanReq != NMI_NULL)
+ {
+ cfg80211_scan_done(priv->pstrScanReq, NMI_FALSE);
+ priv->u32RcvdChCount = 0;
+ priv->bCfgScanning = NMI_FALSE;
+ priv->pstrScanReq = NMI_NULL;
+ }
+ NMI_SemaphoreRelease(&(priv->hSemScanReq), NULL);
+
+ }
+ /*Aborting any scan operation during mac close*/
+ else if(enuScanEvent == SCAN_EVENT_ABORTED)
+ {
+ NMI_SemaphoreAcquire(&(priv->hSemScanReq), NULL);
+
+ PRINT_D(CFG80211_DBG,"Scan Aborted \n");
+ if(priv->pstrScanReq != NMI_NULL)
+ {
+
+ update_scan_time(priv);
+ refresh_scan(priv,1,NMI_FALSE);
+
+ cfg80211_scan_done(priv->pstrScanReq,NMI_FALSE);
+ priv->bCfgScanning = NMI_FALSE;
+ priv->pstrScanReq = NMI_NULL;
+ }
+ NMI_SemaphoreRelease(&(priv->hSemScanReq), NULL);
+ }
+ }
+
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ }
+
+
+/**
+* @brief NMI_WFI_Set_PMKSA
+* @details Check if pmksa is cached and set it.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Set_PMKSA(NMI_Uint8 * bssid,struct NMI_WFI_priv* priv)
+{
+ NMI_Uint32 i;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+
+ for (i = 0; i < priv->pmkid_list.numpmkid; i++)
+ {
+
+ if (!NMI_memcmp(bssid,priv->pmkid_list.pmkidlist[i].bssid,
+ ETH_ALEN))
+ {
+ PRINT_D(CFG80211_DBG,"PMKID successful comparison");
+
+ /*If bssid is found, set the values*/
+ s32Error = host_int_set_pmkid_info(priv->hNMIWFIDrv,&priv->pmkid_list);
+
+ if(s32Error != NMI_SUCCESS)
+ PRINT_ER("Error in pmkid\n");
+
+ break;
+ }
+ }
+
+ return s32Error;
+
+
+}
+int linux_wlan_set_bssid(struct net_device * nmc_netdev,uint8_t * pBSSID);
+
+
+/**
+* @brief CfgConnectResult
+* @details
+* @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
+* connection response or disconnection notification.
+* tstrConnectInfo* pstrConnectInfo: COnnection information.
+* NMI_Uint8 u8MacStatus: Mac Status from firmware
+* tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
+* void* pUserVoid: Private data associated with wireless interface
+* @return NONE
+* @author mabubakr
+* @date 01 MAR 2012
+* @version 1.0
+*/
+ int connecting = 0;
+
+static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent,
+ tstrConnectInfo* pstrConnectInfo,
+ NMI_Uint8 u8MacStatus,
+ tstrDisconnectNotifInfo* pstrDisconnectNotifInfo,
+ void* pUserVoid)
+{
+ struct NMI_WFI_priv* priv;
+ struct net_device* dev;
+ NMI_Uint8 NullBssid[ETH_ALEN] = {0};
+ connecting = 0;
+ if(enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP)
+ {
+ /*Initialization*/
+ NMI_Uint16 u16ConnectStatus = WLAN_STATUS_SUCCESS;
+
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ dev = priv->dev;
+
+ u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
+
+ PRINT_D(CFG80211_DBG," Connection response received = %d\n",u8MacStatus);
+
+ if((u8MacStatus == MAC_DISCONNECTED) &&
+ (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE))
+ {
+ /* The case here is that our station was waiting for association response frame and has just received it containing status code
+ = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
+ u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ linux_wlan_set_bssid(priv->dev,NullBssid);
+
+ PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d \n",u16ConnectStatus,u8MacStatus);
+ }
+
+ if(u16ConnectStatus == WLAN_STATUS_SUCCESS)
+ {
+ NMI_Bool bNeedScanRefresh = NMI_FALSE;
+ NMI_Uint32 i;
+
+ PRINT_INFO(CFG80211_DBG,"Connection Successful:: BSSID: %x%x%x%x%x%x\n",pstrConnectInfo->au8bssid[0],
+ pstrConnectInfo->au8bssid[1],pstrConnectInfo->au8bssid[2],pstrConnectInfo->au8bssid[3],pstrConnectInfo->au8bssid[4],pstrConnectInfo->au8bssid[5]);
+ NMI_memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
+
+ //set bssid in frame filter
+ //linux_wlan_set_bssid(dev,pstrConnectInfo->au8bssid);
+
+ /* BugID_4209: if this network has expired in the scan results in the above nl80211 layer, refresh them here by calling
+ cfg80211_inform_bss() with the last Scan results before calling cfg80211_connect_result() to avoid
+ Linux kernel warning generated at the nl80211 layer */
+
+ for(i = 0; i < u32LastScannedNtwrksCountShadow; i++)
+ {
+ if(NMI_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
+ pstrConnectInfo->au8bssid, ETH_ALEN) == 0)
+ {
+ unsigned long now = jiffies;
+
+ if(time_after(now,
+ astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
+ {
+ bNeedScanRefresh = NMI_TRUE;
+ }
+
+ break;
+ }
+ }
+
+ if(bNeedScanRefresh == NMI_TRUE)
+ {
+ //RefreshScanResult(priv);
+ refresh_scan(priv, 1,NMI_FALSE);
+
+ }
+
+ }
+
+
+ PRINT_D(CFG80211_DBG,"Association request info elements length = %d\n", pstrConnectInfo->ReqIEsLen);
+
+ PRINT_D(CFG80211_DBG,"Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
+
+ cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
+ pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
+ pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
+ u16ConnectStatus, GFP_KERNEL); //TODO: mostafa: u16ConnectStatus to
+ // be replaced by pstrConnectInfo->u16ConnectStatus
+ }
+ else if(enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)
+ {
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+ dev = priv->dev;
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ g_obtainingIP=NMI_FALSE;
+ #endif
+ PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
+ pstrDisconnectNotifInfo->u16reason, priv->dev);
+ u8P2Plocalrandom=0x01;
+ u8P2Precvrandom=0x00;
+ bNmi_ie = NMI_FALSE;
+ NMI_memset(priv->au8AssociatedBss, 0, ETH_ALEN);
+ linux_wlan_set_bssid(priv->dev,NullBssid);
+ cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
+ pstrDisconnectNotifInfo->ie_len, GFP_KERNEL);
+
+ }
+
+}
+
+
+/**
+* @brief NMI_WFI_CfgSetChannel
+* @details Set channel for a given wireless interface. Some devices
+* may support multi-channel operation (by channel hopping) so cfg80211
+* doesn't verify much. Note, however, that the passed netdev may be
+* %NULL as well if the user requested changing the channel for the
+* device itself, or for a monitor interface.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
+/*
+* struct changed from v3.8.0
+* tony, sswd, NMI-KR, 2013-10-29
+* struct cfg80211_chan_def {
+ struct ieee80211_channel *chan;
+ enum nl80211_chan_width width;
+ u32 center_freq1;
+ u32 center_freq2;
+ };
+*/
+static int NMI_WFI_CfgSetChannel(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef)
+#else
+static int NMI_WFI_CfgSetChannel(struct wiphy *wiphy,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ struct net_device *netdev,
+ #endif
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type)
+#endif
+{
+
+ NMI_Uint32 channelnum = 0;
+ struct NMI_WFI_priv* priv;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ priv = wiphy_priv(wiphy);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) /* tony for v3.8.0 support */
+ channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
+ PRINT_D(CFG80211_DBG,"Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq );
+#else
+ channelnum = ieee80211_frequency_to_channel(channel->center_freq);
+ PRINT_D(CFG80211_DBG,"Setting channel %d with frequency %d\n", channelnum, channel->center_freq );
+#endif
+
+ priv->u8CurrChannel = channelnum;
+ s32Error = host_int_set_mac_chnl_num(priv->hNMIWFIDrv,channelnum);
+
+ if(s32Error != NMI_SUCCESS)
+ PRINT_ER("Error in setting channel %d\n", channelnum);
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_CfgScan
+* @details Request to do a scan. If returning zero, the scan request is given
+* the driver, and will be valid until passed to cfg80211_scan_done().
+* For scan results, call cfg80211_inform_bss(); you can call this outside
+* the scan/scan_done bracket too.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mabubakr
+* @date 01 MAR 2012
+* @version 1.0
+*/
+
+/*
+* kernel version 3.8.8 supported
+* tony, sswd, NMI-KR, 2013-10-29
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+static int NMI_WFI_CfgScan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+#else
+static int NMI_WFI_CfgScan(struct wiphy *wiphy,struct net_device *dev, struct cfg80211_scan_request *request)
+#endif
+{
+ struct NMI_WFI_priv* priv;
+ NMI_Uint32 i;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
+ tstrHiddenNetwork strHiddenNetwork;
+
+ priv = wiphy_priv(wiphy);
+
+ printk("Scan on netdev [%p] host if [%x]\n",dev, (NMI_Uint32)priv->hNMIWFIDrv);
+
+ /*if(connecting)
+ return -EBUSY; */
+
+ /*BugID_4800: if in AP mode, return.*/
+ /*This check is to handle the situation when user*/
+ /*requests "create group" during a running scan*/
+ //host_int_set_wfi_drv_handler(priv->hNMIWFIDrv);
+#if 0
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) /* tony for v3.8.0 support */
+ if(priv->dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP)
+ {
+ PRINT_D(GENERIC_DBG,"Required scan while in AP mode");
+ return s32Error;
+ }
+#else
+ if(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP)
+ {
+ PRINT_D(GENERIC_DBG,"Required scan while in AP mode");
+ s32Error = NMI_BUSY;
+ return s32Error;
+ }
+#endif
+#endif // end of if 0
+ priv->pstrScanReq = request;
+
+ priv->u32RcvdChCount = 0;
+
+ host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv);
+
+
+ reset_shadow_found(priv);
+
+ priv->bCfgScanning = NMI_TRUE;
+ priv->u8CurrChannel =-1;
+ if(request->n_channels <= MAX_NUM_SCANNED_NETWORKS) //TODO: mostafa: to be replaced by
+ // max_scan_ssids
+ {
+ for(i = 0; i < request->n_channels; i++)
+ {
+ au8ScanChanList[i] = (NMI_Uint8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+ PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,",i,au8ScanChanList[i]);
+ }
+
+ PRINT_D(CFG80211_DBG,"Requested num of scan channel %d\n",request->n_channels);
+ PRINT_D(CFG80211_DBG,"Scan Request IE len = %d\n",request->ie_len);
+
+ PRINT_D(CFG80211_DBG,"Number of SSIDs %d\n",request->n_ssids);
+
+ if(request->n_ssids >= 1)
+ {
+
+
+ strHiddenNetwork.pstrHiddenNetworkInfo = NMI_MALLOC(request->n_ssids * sizeof(tstrHiddenNetwork));
+ strHiddenNetwork.u8ssidnum = request->n_ssids;
+
+
+ /*BugID_4156*/
+ for(i=0;i<request->n_ssids;i++)
+ {
+
+ if(request->ssids[i].ssid != NULL && request->ssids[i].ssid_len!=0)
+ {
+ strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid= NMI_MALLOC( request->ssids[i].ssid_len);
+ NMI_memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid,request->ssids[i].ssid,request->ssids[i].ssid_len);
+ strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"Received one NULL SSID \n");
+ strHiddenNetwork.u8ssidnum-=1;
+ }
+ }
+ PRINT_D(CFG80211_DBG,"Trigger Scan Request \n");
+ s32Error = host_int_scan(priv->hNMIWFIDrv, USER_SCAN, ACTIVE_SCAN,
+ au8ScanChanList, request->n_channels,
+ (const NMI_Uint8*)request->ie, request->ie_len,
+ CfgScanResult, (void*)priv,&strHiddenNetwork);
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"Trigger Scan Request \n");
+ s32Error = host_int_scan(priv->hNMIWFIDrv, USER_SCAN, ACTIVE_SCAN,
+ au8ScanChanList, request->n_channels,
+ (const NMI_Uint8*)request->ie, request->ie_len,
+ CfgScanResult, (void*)priv,NULL);
+ }
+
+ }
+ else
+ {
+ PRINT_ER("Requested num of scanned channels is greater than the max, supported"
+ " channels \n");
+ }
+
+ if(s32Error != NMI_SUCCESS)
+ {
+ s32Error = -EBUSY;
+ PRINT_WRN(CFG80211_DBG,"Device is busy: Error(%d)\n",s32Error);
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_CfgConnect
+* @details Connect to the ESS with the specified parameters. When connected,
+* call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
+* If the connection fails for some reason, call cfg80211_connect_result()
+* with the status from the AP.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mabubakr
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_CfgConnect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint32 i;
+ //SECURITY_T tenuSecurity_t = NO_SECURITY;
+ NMI_Uint8 u8security = NO_ENCRYPT;
+ AUTHTYPE_T tenuAuth_type = ANY;
+ NMI_Char * pcgroup_encrypt_val;
+ NMI_Char * pccipher_group;
+ NMI_Char * pcwpa_version;
+
+ struct NMI_WFI_priv* priv;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ tstrNetworkInfo* pstrNetworkInfo = NULL;
+
+
+ connecting = 1;
+ priv = wiphy_priv(wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)(priv->hNMIWFIDrv);
+
+ host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv);
+
+ //host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv);
+ PRINT_D(CFG80211_DBG,"Connecting to SSID [%s] on netdev [%p] host if [%x]\n",sme->ssid,dev, (NMI_Uint32)priv->hNMIWFIDrv);
+ #ifdef NMI_P2P
+ if(!(NMI_strncmp(sme->ssid,"DIRECT-", 7)))
+ {
+ PRINT_D(CFG80211_DBG,"Connected to Direct network,OBSS disabled\n");
+ pstrWFIDrv->u8P2PConnect =1;
+ }
+ else
+ pstrWFIDrv->u8P2PConnect= 0;
+ #endif
+ PRINT_INFO(CFG80211_DBG,"Required SSID = %s\n , AuthType = %d \n", sme->ssid,sme->auth_type);
+
+ for(i = 0; i < u32LastScannedNtwrksCountShadow; i++)
+ {
+ if((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
+ NMI_memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
+ sme->ssid,
+ sme->ssid_len) == 0)
+ {
+ PRINT_INFO(CFG80211_DBG,"Network with required SSID is found %s\n", sme->ssid);
+ if(sme->bssid == NULL)
+ {
+ /* BSSID is not passed from the user, so decision of matching
+ * is done by SSID only */
+ PRINT_INFO(CFG80211_DBG,"BSSID is not passed from the user\n");
+ break;
+ }
+ else
+ {
+ /* BSSID is also passed from the user, so decision of matching
+ * should consider also this passed BSSID */
+ if(NMI_memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
+ sme->bssid,
+ ETH_ALEN) == 0)
+ {
+ PRINT_INFO(CFG80211_DBG,"BSSID is passed from the user and matched\n");
+ break;
+ }
+ }
+ }
+ }
+
+ if(i < u32LastScannedNtwrksCountShadow)
+ {
+ PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
+
+ pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
+
+ PRINT_INFO(CFG80211_DBG,"network BSSID to be associated: %x%x%x%x%x%x\n",
+ pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
+ pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
+ pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
+ }
+ else
+ {
+ s32Error = -ENOENT;
+ if(u32LastScannedNtwrksCountShadow == 0)
+ PRINT_D(CFG80211_DBG,"No Scan results yet\n");
+ else
+ PRINT_D(CFG80211_DBG,"Required bss not in scan results: Error(%d)\n",s32Error);
+
+ goto done;
+ }
+
+ priv->NMI_WFI_wep_default = 0;
+ NMI_memset(priv->NMI_WFI_wep_key, 0, sizeof(priv->NMI_WFI_wep_key));
+ NMI_memset(priv->NMI_WFI_wep_key_len, 0, sizeof(priv->NMI_WFI_wep_key_len));
+
+ PRINT_INFO(CFG80211_DBG,"sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
+ PRINT_INFO(CFG80211_DBG,"sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
+
+ PRINT_INFO(CFG80211_DBG,"sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
+
+ if(INFO)
+ {
+ for(i=0 ; i < sme->crypto.n_ciphers_pairwise ; i++)
+ NMI_PRINTF("sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
+ }
+
+ if(sme->crypto.cipher_group != NO_ENCRYPT)
+ {
+ /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
+ we will add to it the pairwise cipher suite(s) */
+ pcwpa_version = "Default";
+ printk(">> sme->crypto.wpa_versions: %x\n",sme->crypto.wpa_versions);
+ //case NL80211_WPA_VERSION_1:
+ if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40)
+ {
+ //printk("> WEP\n");
+ //tenuSecurity_t = WEP_40;
+ u8security = ENCRYPT_ENABLED | WEP;
+ pcgroup_encrypt_val = "WEP40";
+ pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
+ PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n",sme->key_idx);
+
+ if(INFO)
+ {
+ for(i=0;i<sme->key_len;i++)
+ NMI_PRINTF("WEP Key Value[%d] = %d\n", i, sme->key[i]);
+ }
+ priv->NMI_WFI_wep_default = sme->key_idx;
+ priv->NMI_WFI_wep_key_len[sme->key_idx] = sme->key_len;
+ NMI_memcpy(priv->NMI_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
+
+ /*BugID_5137*/
+ g_key_wep_params.key_len = sme->key_len;
+ g_key_wep_params.key = NMI_MALLOC(sme->key_len);
+ memcpy(g_key_wep_params.key, sme->key, sme->key_len);
+ g_key_wep_params.key_idx = sme->key_idx;
+ g_wep_keys_saved = NMI_TRUE;
+
+ host_int_set_WEPDefaultKeyID(priv->hNMIWFIDrv,sme->key_idx);
+ host_int_add_wep_key_bss_sta(priv->hNMIWFIDrv, sme->key,sme->key_len,sme->key_idx);
+ }
+ else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)
+ {
+ //printk("> WEP-WEP_EXTENDED\n");
+ //tenuSecurity_t = WEP_104;
+ u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
+ pcgroup_encrypt_val = "WEP104";
+ pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
+
+ priv->NMI_WFI_wep_default = sme->key_idx;
+ priv->NMI_WFI_wep_key_len[sme->key_idx] = sme->key_len;
+ NMI_memcpy(priv->NMI_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
+
+ /*BugID_5137*/
+ g_key_wep_params.key_len = sme->key_len;
+ g_key_wep_params.key = NMI_MALLOC(sme->key_len);
+ memcpy(g_key_wep_params.key, sme->key, sme->key_len);
+ g_key_wep_params.key_idx = sme->key_idx;
+ g_wep_keys_saved = NMI_TRUE;
+
+ host_int_set_WEPDefaultKeyID(priv->hNMIWFIDrv,sme->key_idx);
+ host_int_add_wep_key_bss_sta(priv->hNMIWFIDrv, sme->key,sme->key_len,sme->key_idx);
+ }
+ else if( sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+ {
+ //printk("> wpa_version: NL80211_WPA_VERSION_2\n");
+ //case NL80211_WPA_VERSION_2:
+ if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
+ {
+ //printk("> WPA2-TKIP\n");
+ //tenuSecurity_t = WPA2_TKIP;
+ u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
+ pcgroup_encrypt_val = "WPA2_TKIP";
+ pccipher_group = "TKIP";
+ }
+ else //TODO: mostafa: here we assume that any other encryption type is AES
+ {
+ //printk("> WPA2-AES\n");
+ //tenuSecurity_t = WPA2_AES;
+ u8security = ENCRYPT_ENABLED | WPA2 | AES;
+ pcgroup_encrypt_val = "WPA2_AES";
+ pccipher_group = "AES";
+ }
+ pcwpa_version = "WPA_VERSION_2";
+ }
+ else if( sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+ {
+ //printk("> wpa_version: NL80211_WPA_VERSION_1\n");
+ if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
+ {
+ //printk("> WPA-TKIP\n");
+ //tenuSecurity_t = WPA_TKIP;
+ u8security = ENCRYPT_ENABLED | WPA | TKIP;
+ pcgroup_encrypt_val = "WPA_TKIP";
+ pccipher_group = "TKIP";
+ }
+ else //TODO: mostafa: here we assume that any other encryption type is AES
+ {
+ //printk("> WPA-AES\n");
+ //tenuSecurity_t = WPA_AES;
+ u8security = ENCRYPT_ENABLED | WPA | AES;
+ pcgroup_encrypt_val = "WPA_AES";
+ pccipher_group = "AES";
+
+ }
+ pcwpa_version = "WPA_VERSION_1";
+
+ //break;
+ }
+ else
+ {
+ s32Error = -ENOTSUPP;
+ PRINT_ER("Not supported cipher: Error(%d)\n",s32Error);
+ //PRINT_ER("Cipher-Group: %x\n",sme->crypto.cipher_group);
+
+ goto done;
+ }
+
+ }
+
+ /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
+ add to it the pairwise cipher suite(s) */
+ if((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+ || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2))
+ {
+ for(i=0 ; i < sme->crypto.n_ciphers_pairwise ; i++)
+ {
+ if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
+ {
+ u8security = u8security | TKIP;
+ }
+ else //TODO: mostafa: here we assume that any other encryption type is AES
+ {
+ u8security = u8security | AES;
+ }
+ }
+ }
+
+ PRINT_D(CFG80211_DBG,"Adding key with cipher group = %x\n",sme->crypto.cipher_group);
+
+ PRINT_D(CFG80211_DBG, "Authentication Type = %d\n",sme->auth_type);
+ switch(sme->auth_type)
+ {
+ case NL80211_AUTHTYPE_OPEN_SYSTEM:
+ PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
+ tenuAuth_type = OPEN_SYSTEM;
+ break;
+ case NL80211_AUTHTYPE_SHARED_KEY:
+ tenuAuth_type = SHARED_KEY;
+ PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
+ break;
+ default:
+ PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n",sme->auth_type);
+ }
+
+
+ /* ai: key_mgmt: enterprise case */
+ if (sme->crypto.n_akm_suites)
+ {
+ switch (sme->crypto.akm_suites[0])
+ {
+ case WLAN_AKM_SUITE_8021X:
+ tenuAuth_type = IEEE8021;
+ break;
+ default:
+ //PRINT_D(CFG80211_DBG, "security unhandled [%x] \n",sme->crypto.akm_suites[0]);
+ break;
+ }
+ }
+
+
+ PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
+
+ PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
+ pcgroup_encrypt_val, pccipher_group,pcwpa_version);
+
+ /*Added by Amr - BugID_4793*/
+ if(priv->u8CurrChannel != pstrNetworkInfo->u8channel)
+ priv->u8CurrChannel = pstrNetworkInfo->u8channel;
+
+ if(!pstrWFIDrv->u8P2PConnect)
+ {
+ //NMI_PRINTF("STA CONNECTED CHANNEL %02x %02x\n",u8WLANChannel ,pstrNetworkInfo->u8channel);
+ u8WLANChannel = pstrNetworkInfo->u8channel;
+ //NMI_PRINTF("STA CONNECTED CHANNEL %02x %02x\n",u8WLANChannel,pstrNetworkInfo->u8channel);
+ }
+
+ linux_wlan_set_bssid(dev,pstrNetworkInfo->au8bssid);
+
+ s32Error = host_int_set_join_req(priv->hNMIWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
+ sme->ssid_len, sme->ie, sme->ie_len,
+ CfgConnectResult, (void*)priv, u8security,
+ tenuAuth_type, pstrNetworkInfo->u8channel,
+ pstrNetworkInfo->pJoinParams);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("host_int_set_join_req(): Error(%d) \n", s32Error);
+ s32Error = -ENOENT;
+ goto done;
+ }
+
+done:
+
+ return s32Error;
+}
+
+
+/**
+* @brief NMI_WFI_disconnect
+* @details Disconnect from the BSS/ESS.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_disconnect(struct wiphy *wiphy, struct net_device *dev,u16 reason_code)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ #ifdef NMI_P2P
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ #endif
+ uint8_t NullBssid[ETH_ALEN] = {0};
+ connecting = 0;
+
+
+ priv = wiphy_priv(wiphy);
+ #ifdef NMI_P2P
+ pstrWFIDrv=(tstrNMI_WFIDrv * )priv->hNMIWFIDrv;
+ #endif
+ linux_wlan_set_bssid(priv->dev,NullBssid);
+
+ PRINT_D(CFG80211_DBG,"Disconnecting with reason code(%d)\n", reason_code);
+
+ u8P2Plocalrandom=0x01;
+ u8P2Precvrandom=0x00;
+ bNmi_ie = NMI_FALSE;
+ #ifdef NMI_P2P
+ pstrWFIDrv->u64P2p_MgmtTimeout = 0;
+ #endif
+
+ s32Error = host_int_disconnect(priv->hNMIWFIDrv, reason_code);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
+ s32Error = -EINVAL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_add_key
+* @details Add a key with the given parameters. @mac_addr will be %NULL
+* when adding a group key.
+* @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_add_key(struct wiphy *wiphy, struct net_device *netdev,u8 key_index,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ bool pairwise,
+ #endif
+ const u8 *mac_addr,struct key_params *params)
+
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS,KeyLen = params->key_len;
+ NMI_Uint32 i;
+ struct NMI_WFI_priv* priv;
+ NMI_Uint8* pu8RxMic = NULL;
+ NMI_Uint8* pu8TxMic = NULL;
+ NMI_Uint8 u8mode = NO_ENCRYPT;
+ #ifdef NMI_AP_EXTERNAL_MLME
+ NMI_Uint8 u8gmode = NO_ENCRYPT;
+ NMI_Uint8 u8pmode = NO_ENCRYPT;
+ AUTHTYPE_T tenuAuth_type = ANY;
+ #endif
+
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(CFG80211_DBG,"Adding key with cipher suite = %x\n",params->cipher);
+
+ /*BugID_5137*/
+ PRINT_D(CFG80211_DBG,"%x %x %d\n",(NMI_Uint32)wiphy, (NMI_Uint32)netdev, key_index);
+
+ PRINT_D(CFG80211_DBG,"key %x %x %x\n",params->key[0],
+ params->key[1],
+ params->key[2]);
+
+
+ switch(params->cipher)
+ {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(priv->wdev->iftype == NL80211_IFTYPE_AP)
+ {
+
+ priv->NMI_WFI_wep_default = key_index;
+ priv->NMI_WFI_wep_key_len[key_index] = params->key_len;
+ NMI_memcpy(priv->NMI_WFI_wep_key[key_index], params->key, params->key_len);
+
+ PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n",key_index);
+ PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n",params->key_len);
+
+ for(i=0;i<params->key_len;i++)
+ PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
+
+ tenuAuth_type = OPEN_SYSTEM;
+
+ if(params->cipher == WLAN_CIPHER_SUITE_WEP40)
+ u8mode = ENCRYPT_ENABLED | WEP;
+ else
+ u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
+
+ host_int_add_wep_key_bss_ap(priv->hNMIWFIDrv,params->key,params->key_len,key_index,u8mode,tenuAuth_type);
+ break;
+ }
+ #endif
+ if(NMI_memcmp(params->key,priv->NMI_WFI_wep_key[key_index],params->key_len))
+ {
+ priv->NMI_WFI_wep_default = key_index;
+ priv->NMI_WFI_wep_key_len[key_index] = params->key_len;
+ NMI_memcpy(priv->NMI_WFI_wep_key[key_index], params->key, params->key_len);
+
+ PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n",key_index);
+ PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n",params->key_len);
+ if(INFO)
+ {
+ for(i=0;i<params->key_len;i++)
+ PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
+ }
+ host_int_add_wep_key_bss_sta(priv->hNMIWFIDrv,params->key,params->key_len,key_index);
+ }
+
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ case WLAN_CIPHER_SUITE_CCMP:
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO)
+ {
+
+ if(priv->nmi_gtk[key_index] == NULL)
+ {
+ priv->nmi_gtk[key_index] = (struct nmi_wfi_key *)NMI_MALLOC(sizeof(struct nmi_wfi_key));
+ priv->nmi_gtk[key_index]->key=NMI_NULL;
+ priv->nmi_gtk[key_index]->seq=NMI_NULL;
+
+ }
+ if(priv->nmi_ptk[key_index] == NULL)
+ {
+ priv->nmi_ptk[key_index] = (struct nmi_wfi_key *)NMI_MALLOC(sizeof(struct nmi_wfi_key));
+ priv->nmi_ptk[key_index]->key=NMI_NULL;
+ priv->nmi_ptk[key_index]->seq=NMI_NULL;
+ }
+
+
+
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ if (!pairwise)
+ #else
+ if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+ #endif
+ {
+ if(params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ u8gmode = ENCRYPT_ENABLED |WPA | TKIP;
+ else
+ u8gmode = ENCRYPT_ENABLED |WPA2 | AES;
+
+ priv->nmi_groupkey = u8gmode;
+
+ if(params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ {
+
+ pu8TxMic = params->key+24;
+ pu8RxMic = params->key+16;
+ KeyLen = params->key_len - 16;
+ }
+ /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
+ if(priv->nmi_gtk[key_index]->key)
+ NMI_FREE(priv->nmi_gtk[key_index]->key);
+
+ priv->nmi_gtk[key_index]->key = (NMI_Uint8 *)NMI_MALLOC(params->key_len);
+ NMI_memcpy(priv->nmi_gtk[key_index]->key,params->key,params->key_len);
+
+ /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
+ if(priv->nmi_gtk[key_index]->seq)
+ NMI_FREE(priv->nmi_gtk[key_index]->seq);
+
+ if((params->seq_len)>0)
+ {
+ priv->nmi_gtk[key_index]->seq = (NMI_Uint8 *)NMI_MALLOC(params->seq_len);
+ NMI_memcpy(priv->nmi_gtk[key_index]->seq,params->seq,params->seq_len);
+ }
+
+ priv->nmi_gtk[key_index]->cipher= params->cipher;
+ priv->nmi_gtk[key_index]->key_len=params->key_len;
+ priv->nmi_gtk[key_index]->seq_len=params->seq_len;
+
+ if(INFO)
+ {
+ for(i=0;i<params->key_len;i++)
+ PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
+ for(i=0;i<params->seq_len;i++)
+ PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
+ }
+
+
+ host_int_add_rx_gtk(priv->hNMIWFIDrv,params->key,KeyLen,
+ key_index,params->seq_len,params->seq,pu8RxMic,pu8TxMic,AP_MODE,u8gmode);
+
+ }
+ else
+ {
+ PRINT_INFO(CFG80211_DBG,"STA Address: %x%x%x%x%x\n",mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4]);
+
+ if(params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
+ else
+ u8pmode = priv->nmi_groupkey | AES;
+
+
+ if(params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ {
+
+ pu8TxMic = params->key+24;
+ pu8RxMic = params->key+16;
+ KeyLen = params->key_len - 16;
+ }
+
+ if(priv->nmi_ptk[key_index]->key)
+ NMI_FREE(priv->nmi_ptk[key_index]->key);
+
+ priv->nmi_ptk[key_index]->key = (NMI_Uint8 *)NMI_MALLOC(params->key_len);
+
+ if(priv->nmi_ptk[key_index]->seq)
+ NMI_FREE(priv->nmi_ptk[key_index]->seq);
+
+ if((params->seq_len)>0)
+ priv->nmi_ptk[key_index]->seq = (NMI_Uint8 *)NMI_MALLOC(params->seq_len);
+
+
+
+ if(INFO)
+ {
+ for(i=0;i<params->key_len;i++)
+ PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
+
+ for(i=0;i<params->seq_len;i++)
+ PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
+ }
+
+ NMI_memcpy(priv->nmi_ptk[key_index]->key,params->key,params->key_len);
+
+ if((params->seq_len)>0)
+ NMI_memcpy(priv->nmi_ptk[key_index]->seq,params->seq,params->seq_len);
+
+ priv->nmi_ptk[key_index]->cipher= params->cipher;
+ priv->nmi_ptk[key_index]->key_len=params->key_len;
+ priv->nmi_ptk[key_index]->seq_len=params->seq_len;
+
+ host_int_add_ptk(priv->hNMIWFIDrv,params->key,KeyLen,mac_addr,
+ pu8RxMic,pu8TxMic,AP_MODE,u8pmode,key_index);
+ }
+ break;
+ }
+ #endif
+
+ {
+ u8mode=0;
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ if (!pairwise)
+ #else
+ if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+ #endif
+ {
+ if(params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ {
+ //swap the tx mic by rx mic
+ pu8RxMic = params->key+24;
+ pu8TxMic = params->key+16;
+ KeyLen = params->key_len - 16;
+ }
+
+ /*BugID_5137*/
+ /*save keys only on interface 0 (wifi interface)*/
+ if(!g_gtk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].nmc_netdev)
+ {
+ g_add_gtk_key_params.key_idx = key_index;
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_gtk_key_params.pairwise = pairwise;
+ #endif
+ if(!mac_addr)
+ {
+ g_add_gtk_key_params.mac_addr = NULL;
+ }
+ else
+ {
+ g_add_gtk_key_params.mac_addr = NMI_MALLOC(ETH_ALEN);
+ memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
+ }
+ g_key_gtk_params.key_len = params->key_len;
+ g_key_gtk_params.seq_len = params->seq_len;
+ g_key_gtk_params.key = NMI_MALLOC(params->key_len);
+ memcpy(g_key_gtk_params.key, params->key, params->key_len);
+ if(params->seq_len > 0)
+ {
+ g_key_gtk_params.seq= NMI_MALLOC(params->seq_len);
+ memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
+ }
+ g_key_gtk_params.cipher = params->cipher;
+
+ PRINT_D(CFG80211_DBG,"key %x %x %x\n",g_key_gtk_params.key[0],
+ g_key_gtk_params.key[1],
+ g_key_gtk_params.key[2]);
+ g_gtk_keys_saved = NMI_TRUE;
+ }
+
+ host_int_add_rx_gtk(priv->hNMIWFIDrv,params->key,KeyLen,
+ key_index,params->seq_len,params->seq,pu8RxMic,pu8TxMic,STATION_MODE,u8mode);
+ //host_int_add_tx_gtk(priv->hNMIWFIDrv,params->key_len,params->key,key_index);
+ }
+ else
+ {
+ if(params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP)
+ {
+ //swap the tx mic by rx mic
+ pu8RxMic = params->key+24;
+ pu8TxMic = params->key+16;
+ KeyLen = params->key_len - 16;
+ }
+
+ /*BugID_5137*/
+ /*save keys only on interface 0 (wifi interface)*/
+ if(!g_ptk_keys_saved && netdev == g_linux_wlan->strInterfaceInfo[0].nmc_netdev)
+ {
+ g_add_ptk_key_params.key_idx = key_index;
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_ptk_key_params.pairwise = pairwise;
+ #endif
+ if(!mac_addr)
+ {
+ g_add_ptk_key_params.mac_addr = NULL;
+ }
+ else
+ {
+ g_add_ptk_key_params.mac_addr = NMI_MALLOC(ETH_ALEN);
+ memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
+ }
+ g_key_ptk_params.key_len = params->key_len;
+ g_key_ptk_params.seq_len = params->seq_len;
+ g_key_ptk_params.key = NMI_MALLOC(params->key_len);
+ memcpy(g_key_ptk_params.key, params->key, params->key_len);
+ if(params->seq_len > 0)
+ {
+ g_key_ptk_params.seq= NMI_MALLOC(params->seq_len);
+ memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
+ }
+ g_key_ptk_params.cipher = params->cipher;
+
+ PRINT_D(CFG80211_DBG,"key %x %x %x\n",g_key_ptk_params.key[0],
+ g_key_ptk_params.key[1],
+ g_key_ptk_params.key[2]);
+ g_ptk_keys_saved = NMI_TRUE;
+ }
+
+ host_int_add_ptk(priv->hNMIWFIDrv,params->key,KeyLen,mac_addr,
+ pu8RxMic,pu8TxMic,STATION_MODE,u8mode,key_index);
+ PRINT_D(CFG80211_DBG,"Adding pairwise key\n");
+ if(INFO)
+ {
+ for(i=0;i<params->key_len;i++)
+ PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
+ }
+ }
+ }
+ break;
+ default:
+ PRINT_ER("Not supported cipher: Error(%d)\n",s32Error);
+ s32Error = -ENOTSUPP;
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_del_key
+* @details Remove a key given the @mac_addr (%NULL for a group key)
+* and @key_index, return -ENOENT if the key doesn't exist.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_del_key(struct wiphy *wiphy, struct net_device *netdev,
+ u8 key_index,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ bool pairwise,
+ #endif
+ const u8 *mac_addr)
+{
+ struct NMI_WFI_priv* priv;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ priv = wiphy_priv(wiphy);
+
+ /*BugID_5137*/
+ /*delete saved keys, if any*/
+ if(netdev == g_linux_wlan->strInterfaceInfo[0].nmc_netdev)
+ {
+ g_ptk_keys_saved = NMI_FALSE;
+ g_gtk_keys_saved = NMI_FALSE;
+ g_wep_keys_saved = NMI_FALSE;
+
+ /*Delete saved WEP keys params, if any*/
+ if(g_key_wep_params.key != NULL)
+ {
+ NMI_FREE(g_key_wep_params.key);
+ g_key_wep_params.key = NULL;
+ }
+
+ /*freeing memory allocated by "nmi_gtk" and "nmi_ptk" in "NMI_WIFI_ADD_KEY"*/
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if((priv->nmi_gtk[key_index])!=NULL)
+ {
+
+ if(priv->nmi_gtk[key_index]->key!=NULL)
+ {
+
+ NMI_FREE(priv->nmi_gtk[key_index]->key);
+ priv->nmi_gtk[key_index]->key=NULL;
+ }
+ if(priv->nmi_gtk[key_index]->seq)
+ {
+
+ NMI_FREE(priv->nmi_gtk[key_index]->seq);
+ priv->nmi_gtk[key_index]->seq=NULL;
+ }
+
+ NMI_FREE(priv->nmi_gtk[key_index]);
+ priv->nmi_gtk[key_index]=NULL;
+
+ }
+
+ if((priv->nmi_ptk[key_index])!=NULL)
+ {
+
+ if(priv->nmi_ptk[key_index]->key)
+ {
+
+ NMI_FREE(priv->nmi_ptk[key_index]->key);
+ priv->nmi_ptk[key_index]->key=NULL;
+ }
+ if(priv->nmi_ptk[key_index]->seq)
+ {
+
+ NMI_FREE(priv->nmi_ptk[key_index]->seq);
+ priv->nmi_ptk[key_index]->seq=NULL;
+ }
+ NMI_FREE(priv->nmi_ptk[key_index]);
+ priv->nmi_ptk[key_index]=NULL;
+ }
+ #endif
+
+ /*Delete saved PTK and GTK keys params, if any*/
+ if(g_key_ptk_params.key != NULL)
+ {
+ NMI_FREE(g_key_ptk_params.key);
+ g_key_ptk_params.key = NULL;
+ }
+ if(g_key_ptk_params.seq != NULL)
+ {
+ NMI_FREE(g_key_ptk_params.seq);
+ g_key_ptk_params.seq = NULL;
+ }
+
+ if(g_key_gtk_params.key != NULL)
+ {
+ NMI_FREE(g_key_gtk_params.key);
+ g_key_gtk_params.key = NULL;
+ }
+ if(g_key_gtk_params.seq != NULL)
+ {
+ NMI_FREE(g_key_gtk_params.seq);
+ g_key_gtk_params.seq = NULL;
+ }
+
+ /*Reset NMI_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
+ Set_machw_change_vir_if(NMI_FALSE);
+ }
+
+ if(key_index >= 0 && key_index <=3)
+ {
+ NMI_memset(priv->NMI_WFI_wep_key[key_index], 0, priv->NMI_WFI_wep_key_len[key_index]);
+ priv->NMI_WFI_wep_key_len[key_index] = 0;
+
+ PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n",key_index);
+ host_int_remove_wep_key(priv->hNMIWFIDrv,key_index);
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
+ host_int_remove_key(priv->hNMIWFIDrv,mac_addr);
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_get_key
+* @details Get information about the key with the given parameters.
+* @mac_addr will be %NULL when requesting information for a group
+* key. All pointers given to the @callback function need not be valid
+* after it returns. This function should return an error if it is
+* not possible to retrieve the key, -ENOENT if it doesn't exist.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_get_key(struct wiphy *wiphy, struct net_device *netdev,u8 key_index,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ bool pairwise,
+ #endif
+ const u8 *mac_addr,void *cookie,void (*callback)(void* cookie, struct key_params*))
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ struct NMI_WFI_priv* priv;
+ struct key_params key_params;
+ NMI_Uint32 i;
+ priv= wiphy_priv(wiphy);
+
+
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ if (!pairwise)
+ #else
+ if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+ #endif
+ {
+ PRINT_D(CFG80211_DBG,"Getting group key idx: %x\n",key_index);
+
+ key_params.key=priv->nmi_gtk[key_index]->key;
+ key_params.cipher=priv->nmi_gtk[key_index]->cipher;
+ key_params.key_len=priv->nmi_gtk[key_index]->key_len;
+ key_params.seq=priv->nmi_gtk[key_index]->seq;
+ key_params.seq_len=priv->nmi_gtk[key_index]->seq_len;
+ if(INFO)
+ {
+ for(i=0;i<key_params.key_len;i++)
+ PRINT_INFO(CFG80211_DBG,"Retrieved key value %x\n",key_params.key[i]);
+ }
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"Getting pairwise key\n");
+
+ key_params.key=priv->nmi_ptk[key_index]->key;
+ key_params.cipher=priv->nmi_ptk[key_index]->cipher;
+ key_params.key_len=priv->nmi_ptk[key_index]->key_len;
+ key_params.seq=priv->nmi_ptk[key_index]->seq;
+ key_params.seq_len=priv->nmi_ptk[key_index]->seq_len;
+ }
+
+ callback(cookie,&key_params);
+
+ return s32Error;//priv->nmi_gtk->key_len ?0 : -ENOENT;
+}
+
+/**
+* @brief NMI_WFI_set_default_key
+* @details Set the default management frame key on an interface
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_default_key(struct wiphy *wiphy,struct net_device *netdev,u8 key_index
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)
+ ,bool unicast, bool multicast
+ #endif
+ )
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+
+
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(CFG80211_DBG,"Setting default key with idx = %d \n", key_index);
+
+ if(key_index!= priv->NMI_WFI_wep_default)
+ {
+
+ host_int_set_WEPDefaultKeyID(priv->hNMIWFIDrv,key_index);
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_dump_survey
+* @details Get site survey information
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_dump_survey(struct wiphy *wiphy, struct net_device *netdev,
+ int idx, struct survey_info *info)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+
+ if (idx != 0)
+ {
+ s32Error = -ENOENT;
+ PRINT_ER("Error Idx value doesn't equal zero: Error(%d)\n",s32Error);
+
+ }
+
+ return s32Error;
+}
+
+
+/**
+* @brief NMI_WFI_get_station
+* @details Get station information for the station identified by @mac
+* @param[in] NONE
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+
+extern uint32_t Statisitcs_totalAcks,Statisitcs_DroppedAcks;
+static int NMI_WFI_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_info *sinfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ perInterface_wlan_t* nic;
+ #ifdef NMI_AP_EXTERNAL_MLME
+ NMI_Uint32 i =0;
+ NMI_Uint32 associatedsta = 0;
+ NMI_Uint32 inactive_time=0;
+ #endif
+ priv = wiphy_priv(wiphy);
+ nic = netdev_priv(dev);
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(nic->iftype == AP_MODE)
+ {
+ PRINT_D(HOSTAPD_DBG,"Getting station parameters\n");
+
+ PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n",mac[0],mac[1],mac[2],mac[3],mac[4]);
+
+ for(i=0; i<NUM_STA_ASSOCIATED; i++)
+ {
+
+ if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN)))
+ {
+ associatedsta = i;
+ break;
+ }
+
+ }
+
+ if(associatedsta == -1)
+ {
+ s32Error = -ENOENT;
+ PRINT_ER("Station required is not associated : Error(%d)\n",s32Error);
+
+ return s32Error;
+ }
+
+ sinfo->filled |= STATION_INFO_INACTIVE_TIME;
+
+ host_int_get_inactive_time(priv->hNMIWFIDrv, mac,&(inactive_time));
+ sinfo->inactive_time = 1000 * inactive_time;
+ PRINT_D(CFG80211_DBG,"Inactive time %d\n",sinfo->inactive_time);
+
+ }
+ #endif
+
+ if(nic->iftype == STATION_MODE)
+ {
+ tstrStatistics strStatistics;
+ #if 0
+ NMI_Sint8 s8lnkspd = 0;
+ static NMI_Uint32 u32FirstLnkSpdCnt = 0;
+
+
+ sinfo->filled |= STATION_INFO_SIGNAL;
+
+ s32Error = host_int_get_rssi(priv->hNMIWFIDrv, &(sinfo->signal));
+ if(s32Error)
+ PRINT_ER("Failed to send get host channel param's message queue ");
+
+ PRINT_D(CFG80211_DBG,"Rssi value = %d %d,%d\n",sinfo->signal,Statisitcs_DroppedAcks,Statisitcs_totalAcks);
+
+ sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+ /* To get realistic Link Speed, let it fixed for first 10 times to give chance for Autorate to ramp up as traffic starts */
+
+ u32FirstLnkSpdCnt++;
+
+ if(u32FirstLnkSpdCnt > 10)
+ {
+ priv->gbAutoRateAdjusted = NMI_TRUE;
+ }
+
+ if(priv->gbAutoRateAdjusted == NMI_FALSE)
+ {
+ sinfo->txrate.legacy = 54 * 10;
+ }
+ else
+ {
+ s32Error = host_int_get_link_speed(priv->hNMIWFIDrv, &s8lnkspd);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send get host channel param's message queue ");
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"link_speed=%d\n", s8lnkspd);
+ sinfo->txrate.legacy = s8lnkspd * 10;
+ }
+ }
+ #else
+ host_int_get_statistics(priv->hNMIWFIDrv,&strStatistics);
+
+ /*
+ * tony: 2013-11-13
+ * tx_failed introduced more than
+ * kernel version 3.0.0
+ */
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS
+ | STATION_INFO_TX_FAILED | STATION_INFO_TX_BITRATE;
+ #else
+ sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS
+ | STATION_INFO_TX_BITRATE;
+ #endif
+
+ sinfo->signal = strStatistics.s8RSSI;
+ sinfo->rx_packets = strStatistics.u32RxCount;
+ sinfo->tx_packets = strStatistics.u32TxCount + strStatistics.u32TxFailureCount;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ sinfo->tx_failed = strStatistics.u32TxFailureCount;
+ #endif
+ sinfo->txrate.legacy = strStatistics.u8LinkSpeed*10;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ printk("*** stats[%d][%d][%d][%d][%d]\n",sinfo->signal,sinfo->rx_packets,sinfo->tx_packets,
+ sinfo->tx_failed,sinfo->txrate.legacy);
+ #else
+ printk("*** stats[%d][%d][%d][%d]\n",sinfo->signal,sinfo->rx_packets,sinfo->tx_packets,
+ sinfo->txrate.legacy);
+ #endif
+
+ #endif
+
+ }
+
+
+
+ return s32Error;
+}
+
+
+/**
+* @brief NMI_WFI_change_bss
+* @details Modify parameters for a given BSS.
+* @param[in]
+* -use_cts_prot: Whether to use CTS protection
+* (0 = no, 1 = yes, -1 = do not change)
+ * -use_short_preamble: Whether the use of short preambles is allowed
+ * (0 = no, 1 = yes, -1 = do not change)
+ * -use_short_slot_time: Whether the use of short slot time is allowed
+ * (0 = no, 1 = yes, -1 = do not change)
+ * -basic_rates: basic rates in IEEE 802.11 format
+ * (or NULL for no change)
+ * -basic_rates_len: number of basic rates
+ * -ap_isolate: do not forward packets between connected stations
+ * -ht_opmode: HT Operation mode
+ * (u16 = opmode, -1 = do not change)
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_change_bss(struct wiphy *wiphy, struct net_device *dev,
+ struct bss_parameters *params)
+{
+ PRINT_D(CFG80211_DBG,"Changing Bss parametrs\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_auth
+* @details Request to authenticate with the specified peer
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_auth(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_auth_request *req)
+{
+ PRINT_D(CFG80211_DBG,"In Authentication Function\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_assoc
+* @details Request to (re)associate with the specified peer
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_assoc(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_assoc_request *req)
+{
+ PRINT_D(CFG80211_DBG,"In Association Function\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_deauth
+* @details Request to deauthenticate from the specified peer
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_deauth(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_deauth_request *req,void *cookie)
+{
+ PRINT_D(CFG80211_DBG,"In De-authentication Function\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_disassoc
+* @details Request to disassociate from the specified peer
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_disassoc(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_disassoc_request *req,void *cookie)
+{
+ PRINT_D(CFG80211_DBG, "In Disassociation Function\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_set_wiphy_params
+* @details Notify that wiphy parameters have changed;
+* @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
+* have changed.
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrCfgParamVal pstrCfgParamVal;
+ struct NMI_WFI_priv* priv;
+
+ priv = wiphy_priv(wiphy);
+// priv = netdev_priv(priv->wdev->netdev);
+
+ pstrCfgParamVal.u32SetCfgFlag = 0;
+ PRINT_D(CFG80211_DBG,"Setting Wiphy params \n");
+
+ if(changed & WIPHY_PARAM_RETRY_SHORT)
+ {
+ PRINT_D(CFG80211_DBG,"Setting WIPHY_PARAM_RETRY_SHORT %d\n",
+ priv->dev->ieee80211_ptr->wiphy->retry_short);
+ pstrCfgParamVal.u32SetCfgFlag |= RETRY_SHORT;
+ pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
+ }
+ if(changed & WIPHY_PARAM_RETRY_LONG)
+ {
+
+ PRINT_D(CFG80211_DBG,"Setting WIPHY_PARAM_RETRY_LONG %d\n",priv->dev->ieee80211_ptr->wiphy->retry_long);
+ pstrCfgParamVal.u32SetCfgFlag |= RETRY_LONG;
+ pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
+
+ }
+ if(changed & WIPHY_PARAM_FRAG_THRESHOLD)
+ {
+ PRINT_D(CFG80211_DBG,"Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",priv->dev->ieee80211_ptr->wiphy->frag_threshold);
+ pstrCfgParamVal.u32SetCfgFlag |= FRAG_THRESHOLD;
+ pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
+
+ }
+
+ if(changed & WIPHY_PARAM_RTS_THRESHOLD)
+ {
+ PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",priv->dev->ieee80211_ptr->wiphy->rts_threshold);
+
+ pstrCfgParamVal.u32SetCfgFlag |= RTS_THRESHOLD;
+ pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
+
+ }
+
+ PRINT_D(CFG80211_DBG,"Setting CFG params in the host interface\n");
+ s32Error = hif_set_cfg(priv->hNMIWFIDrv,&pstrCfgParamVal);
+ if(s32Error)
+ PRINT_ER("Error in setting WIPHY PARAMS\n");
+
+
+ return s32Error;
+}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+/**
+* @brief NMI_WFI_set_bitrate_mask
+* @details set the bitrate mask configuration
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_bitrate_mask(struct wiphy *wiphy,
+ struct net_device *dev,const u8 *peer,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ //strCfgParamVal pstrCfgParamVal;
+ //struct NMI_WFI_priv* priv;
+
+ PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n");
+#if 0
+ priv = wiphy_priv(wiphy);
+ //priv = netdev_priv(priv->wdev->netdev);
+
+ pstrCfgParamVal.curr_tx_rate = mask->control[IEEE80211_BAND_2GHZ].legacy;
+
+ PRINT_D(CFG80211_DBG, "Tx rate = %d\n",pstrCfgParamVal.curr_tx_rate);
+ s32Error = hif_set_cfg(priv->hNMIWFIDrv,&pstrCfgParamVal);
+
+ if(s32Error)
+ PRINT_ER("Error in setting bitrate\n");
+#endif
+ return s32Error;
+
+}
+
+/**
+* @brief NMI_WFI_set_pmksa
+* @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
+* devices running firmwares capable of generating the (re) association
+* RSN IE. It allows for faster roaming between WPA2 BSSIDs.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmksa *pmksa)
+{
+ NMI_Uint32 i;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 flag = 0;
+
+ struct NMI_WFI_priv* priv = wiphy_priv(wiphy);
+
+ PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
+
+
+ for (i = 0; i < priv->pmkid_list.numpmkid; i++)
+ {
+ if (!NMI_memcmp(pmksa->bssid,priv->pmkid_list.pmkidlist[i].bssid,
+ ETH_ALEN))
+ {
+ /*If bssid already exists and pmkid value needs to reset*/
+ flag = PMKID_FOUND;
+ PRINT_D(CFG80211_DBG, "PMKID already exists\n");
+ break;
+ }
+ }
+ if (i < NMI_MAX_NUM_PMKIDS) {
+ PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
+ NMI_memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
+ ETH_ALEN);
+ NMI_memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
+ PMKID_LEN);
+ if(!(flag == PMKID_FOUND))
+ priv->pmkid_list.numpmkid++;
+ }
+ else
+ {
+ PRINT_ER("Invalid PMKID index\n");
+ s32Error = -EINVAL;
+ }
+
+ if(!s32Error)
+ {
+ PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
+ s32Error = host_int_set_pmkid_info(priv->hNMIWFIDrv, &priv->pmkid_list);
+ }
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_del_pmksa
+* @details Delete a cached PMKID.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmksa *pmksa)
+{
+
+ NMI_Uint32 i;
+ NMI_Uint8 flag = 0;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ struct NMI_WFI_priv* priv = wiphy_priv(wiphy);
+ //priv = netdev_priv(priv->wdev->netdev);
+
+ PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
+
+ for (i = 0; i < priv->pmkid_list.numpmkid; i++)
+ {
+ if (!NMI_memcmp(pmksa->bssid,priv->pmkid_list.pmkidlist[i].bssid,
+ ETH_ALEN))
+ {
+ /*If bssid is found, reset the values*/
+ PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
+ NMI_memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(tstrHostIFpmkid));
+ flag = PMKID_FOUND;
+ break;
+ }
+ }
+
+ if(i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0)
+ {
+ for (; i < (priv->pmkid_list.numpmkid- 1); i++) {
+ NMI_memcpy(priv->pmkid_list.pmkidlist[i].bssid,
+ priv->pmkid_list.pmkidlist[i+1].bssid,
+ ETH_ALEN);
+ NMI_memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
+ priv->pmkid_list.pmkidlist[i].pmkid,
+ PMKID_LEN);
+ }
+ priv->pmkid_list.numpmkid--;
+ }
+ else {
+ s32Error = -EINVAL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_flush_pmksa
+* @details Flush all cached PMKIDs.
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
+{
+ struct NMI_WFI_priv* priv = wiphy_priv(wiphy);
+ //priv = netdev_priv(priv->wdev->netdev);
+
+ PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
+
+ /*Get cashed Pmkids and set all with zeros*/
+ NMI_memset(&priv->pmkid_list, 0, sizeof(tstrHostIFpmkidAttr) );
+
+ return 0;
+}
+#endif
+
+#ifdef NMI_P2P
+
+/**
+* @brief NMI_WFI_CfgParseRxAction
+* @details Function parses the received frames and modifies the following attributes:
+* -GO Intent
+* -Channel list
+* -Operating Channel
+*
+* @param[in] u8* Buffer, u32 length
+* @return NONE.
+* @author mdaftedar
+* @date 12 DEC 2012
+* @version
+*/
+void NMI_WFI_CfgParseRxAction(NMI_Uint8 * buf,NMI_Uint32 len)
+{
+ NMI_Uint32 index=0;
+ NMI_Uint32 i=0,j=0;
+ while(index < len)
+ {
+ if(buf[index] == GO_INTENT_ATTR_ID)
+ {
+ buf[index+3] =(buf[index+3] & 0x01) | (0x00 << 1);
+ }
+
+ else if(buf[index] == CHANLIST_ATTR_ID)
+ {
+
+ for(i=index+3;i<((index+3)+buf[index+1]);i++)
+ {
+ if(buf[i] == 0x51)
+ {
+ for(j=i+2;j<((i+2)+buf[i+1]);j++)
+ {
+ buf[j] = u8WLANChannel;
+ }
+ break;
+ }
+
+ }
+ }
+ else if(buf[index] == OPERCHAN_ATTR_ID)
+ {
+ buf[index+6]=0x51;
+ buf[index+7]=u8WLANChannel;
+ }
+
+ index+=buf[index+1]+3; //ID,Length byte
+
+ }
+
+}
+
+/**
+* @brief NMI_WFI_CfgParseTxAction
+* @details Function parses the transmitted action frames and modifies the
+* GO Intent attribute
+* @param[in] u8* Buffer, u32 length
+* @return NONE.
+* @author mdaftedar
+* @date 12 DEC 2012
+* @version
+*/
+void NMI_WFI_CfgParseTxAction(NMI_Uint8 * buf,NMI_Uint32 len,NMI_Bool bOperChan)
+{
+ NMI_Uint32 index=0;
+ NMI_Uint32 i=0,j=0;
+
+ while(index < len)
+ {
+ if(buf[index] == GO_INTENT_ATTR_ID)
+ {
+ buf[index+3] =(buf[index+3] & 0x01) | (0x0f << 1);
+ break;
+ }
+
+ /*It's required to parse the operating channel and the channel only in the P2P_INVITE case*/
+ if(bOperChan)
+ {
+ if(buf[index] == CHANLIST_ATTR_ID)
+ {
+
+ for(i=index+3;i<((index+3)+buf[index+1]);i++)
+ {
+ if(buf[i] == 0x51)
+ {
+
+ for(j=i+2;j<((i+2)+buf[i+1]);j++)
+ {
+
+ buf[j] = u8WLANChannel;
+
+ }
+ break;
+ }
+
+ }
+ }
+ else if(buf[index] == OPERCHAN_ATTR_ID)
+ {
+
+ buf[index+6]=0x51;
+ buf[index+7]=u8WLANChannel;
+
+ }
+ }
+ index+=buf[index+1]+3; //ID,Length byte
+
+ }
+}
+/* @brief NMI_WFI_p2p_rx
+* @details
+* @param[in]
+
+* @return None
+* @author Mai Daftedar
+* @date 2 JUN 2013
+* @version 1.0
+*/
+
+void NMI_WFI_p2p_rx (struct net_device *dev,uint8_t *buff, uint32_t size)
+{
+
+ struct NMI_WFI_priv* priv;
+ NMI_Uint32 header,pkt_offset;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ NMI_Uint32 i=0,j=0;
+ priv= wiphy_priv(dev->ieee80211_ptr->wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+ //Get NMI header
+ memcpy(&header, (buff-HOST_HDR_OFFSET), HOST_HDR_OFFSET);
+
+
+ //The packet offset field conain info about what type of managment frame
+ // we are dealing with and ack status
+ pkt_offset = GET_PKT_OFFSET(header);
+ if(pkt_offset & IS_MANAGMEMENT_CALLBACK)
+ {
+ if(buff[0]==IEEE80211_STYPE_PROBE_RESP)
+ {
+ PRINT_D(GENERIC_DBG,"Probe response ACK\n");
+ cfg80211_mgmt_tx_status(dev,priv->u64tx_cookie,buff,size,true,GFP_KERNEL);
+ return;
+ }
+ else
+ {
+ if(pkt_offset & IS_MGMT_STATUS_SUCCES)
+ {
+ PRINT_D(GENERIC_DBG,"Success Ack - Action frame subtype: %x Dialog token: %d FS: %x %x\n",buff[30], buff[31], buff[21], buff[22]);
+ cfg80211_mgmt_tx_status(dev,priv->u64tx_cookie,buff,size,true,GFP_KERNEL);
+ }
+ else
+ {
+ PRINT_D(GENERIC_DBG,"Fail Ack - Action frame subtype: %x Dialog token: %d FS: %x %x\n",buff[30], buff[31], buff[21], buff[22]);
+ cfg80211_mgmt_tx_status(dev,priv->u64tx_cookie,buff,size,false,GFP_KERNEL);
+ }
+ }
+
+
+ }
+ else
+ {
+ if(buff[0] == ACTION_FRAME)
+ PRINT_D(GENERIC_DBG,"Rx Action Frame Type: %x\n", buff[30]);
+
+
+ if((buff[0] == ACTION_FRAME) && ( buff[30] == GO_NEG_REQ_ATTR_ID || buff[30] == GO_NEG_RSP_ATTR_ID|| buff[30] == P2P_INVITE_REQ || buff[30] == P2P_INVITE_RSP))
+ {
+ if(!bNmi_ie)
+ {
+ for(i=0;i<size;i++)
+ {
+ if ((buff[i]==0xdd) && (buff[i+1] == 0x05) &&
+ (buff[i+2] == 0x00) && (buff[i+3] == 0x08) &&
+ (buff[i+4] == 0x40) && (buff[i+5] == 0x03))
+ {
+ u8P2Precvrandom = buff[i+6];
+ bNmi_ie=NMI_TRUE;
+ PRINT_D(GENERIC_DBG,"NMI Vendor specific IE:%02x\n",u8P2Precvrandom);
+ break;
+ }
+ }
+ }
+
+ if(u8P2Plocalrandom > u8P2Precvrandom)
+ {
+ /*Search for the P2P public action frames*/
+ for(i=1;i<size;i++)
+ {
+ if(buff[i]==PUBLICACTION_CAT && buff[i+1]==PUBLICACTION_FRAME && !(memcmp(u8P2P_oui,&buff[i+2],4)))
+ {
+ if(buff[i+6] == GO_NEG_REQ_ATTR_ID || GO_NEG_RSP_ATTR_ID || buff[i+6] == P2P_INVITE_REQ || buff[i+6] == P2P_INVITE_RSP)
+ {
+ for(j=i+8;j<size;j++)
+ {
+ if(buff[j]== P2PELEM_ID && !(memcmp(u8P2P_oui,&buff[j+2],4)) )
+ {
+ NMI_WFI_CfgParseRxAction(&buff[j+6],size-(j+6));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ PRINT_D(GENERIC_DBG,"PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",u8P2Plocalrandom,u8P2Precvrandom);
+
+ }
+
+ if(priv->bCfgScanning == NMI_TRUE && jiffies >= pstrWFIDrv->u64P2p_MgmtTimeout)
+ {
+ PRINT_D(GENERIC_DBG,"Receiving action frames from wrong channels\n");
+ return;
+ }
+
+ PRINT_D(GENERIC_DBG,"Sending P2P to host\n");
+
+ if((buff[0] == ACTION_FRAME) && ( buff[30] == GO_NEG_REQ_ATTR_ID || buff[30] == GO_NEG_RSP_ATTR_ID) && ( bNmi_ie))
+ {
+ //extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ cfg80211_rx_mgmt(dev,priv->u32listen_freq, 0, buff,size-7,GFP_ATOMIC); // rachel
+ #else
+ cfg80211_rx_mgmt(dev,priv->u32listen_freq,buff,size-7,GFP_ATOMIC);
+ #endif
+ }
+ else
+ {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ cfg80211_rx_mgmt(dev,priv->u32listen_freq, 0, buff,size,GFP_ATOMIC); // rachel
+ #else
+ cfg80211_rx_mgmt(dev,priv->u32listen_freq,buff,size,GFP_ATOMIC);
+ #endif
+ }
+ }
+}
+/**
+* @brief NMI_WFI_mgmt_tx_complete
+* @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
+* @param[in] priv
+ transmitting status
+* @return None
+* @author Amr Abdelmoghny
+* @date 20 MAY 2013
+* @version 1.0
+*/
+static void NMI_WFI_mgmt_tx_complete(void* priv, int status)
+{
+ struct p2p_mgmt_data* pv_data = (struct p2p_mgmt_data*)priv;
+
+
+ kfree(pv_data->buff);
+ kfree(pv_data);
+}
+
+/**
+* @brief NMI_WFI_RemainOnChannelReady
+* @details Callback function, called from handle_remain_on_channel on being ready on channel
+* @param
+* @return none
+* @author Amr abdelmoghny
+* @date 9 JUNE 2013
+* @version
+*/
+
+static void NMI_WFI_RemainOnChannelReady(void* pUserVoid)
+{
+ struct NMI_WFI_priv* priv;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ PRINT_D(HOSTINF_DBG, "Remain on channel ready \n");
+
+ cfg80211_ready_on_channel(priv->dev,
+ priv->strRemainOnChanParams.u64ListenCookie,
+ priv->strRemainOnChanParams.pstrListenChan,
+ priv->strRemainOnChanParams.tenuChannelType,
+ priv->strRemainOnChanParams.u32ListenDuration,
+ GFP_KERNEL);
+}
+
+/**
+* @brief NMI_WFI_RemainOnChannelExpired
+* @details Callback function, called on expiration of remain-on-channel duration
+* @param
+* @return none
+* @author Amr abdelmoghny
+* @date 15 MAY 2013
+* @version
+*/
+
+static void NMI_WFI_RemainOnChannelExpired(void* pUserVoid)
+{
+ struct NMI_WFI_priv* priv;
+ priv = (struct NMI_WFI_priv*)pUserVoid;
+
+ PRINT_D(GENERIC_DBG, "Remain on channel expired \n");
+
+ /*Inform wpas of remain-on-channel expiration*/
+ cfg80211_remain_on_channel_expired(priv->dev,
+ priv->strRemainOnChanParams.u64ListenCookie,
+ priv->strRemainOnChanParams.pstrListenChan ,
+ priv->strRemainOnChanParams.tenuChannelType,
+ GFP_KERNEL);
+ priv->u8CurrChannel =-1;
+}
+
+
+/**
+* @brief NMI_WFI_remain_on_channel
+* @details Request the driver to remain awake on the specified
+* channel for the specified duration to complete an off-channel
+* operation (e.g., public action frame exchange). When the driver is
+* ready on the requested channel, it must indicate this with an event
+* notification by calling cfg80211_ready_on_channel().
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_remain_on_channel(struct wiphy *wiphy,
+ struct net_device *dev,struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type,
+ unsigned int duration,u64 *cookie)
+{
+ NMI_Sint32 freq;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(GENERIC_DBG, "Remaining on channel %d\n",chan->hw_value);
+
+ /*BugID_4800: if in AP mode, return.*/
+ /*This check is to handle the situation when user*/
+ /*requests "create group" during a running scan*/
+ if(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP)
+ {
+ PRINT_D(GENERIC_DBG,"Required remain-on-channel while in AP mode");
+ return s32Error;
+ }
+
+ if(priv->u8CurrChannel != chan->hw_value)
+ priv->u8CurrChannel = chan->hw_value;
+
+ /*Setting params needed by NMI_WFI_RemainOnChannelExpired()*/
+ priv->strRemainOnChanParams.pstrListenChan = chan;
+ priv->strRemainOnChanParams.u64ListenCookie = *cookie;
+ priv->strRemainOnChanParams.tenuChannelType = channel_type;
+
+ #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+ freq = ieee80211_channel_to_frequency((NMI_Sint32)chan->hw_value);
+ #else
+ freq = ieee80211_channel_to_frequency((NMI_Sint32)chan->hw_value, IEEE80211_BAND_2GHZ);
+ #endif
+ priv->u32listen_freq= freq;
+
+ s32Error = host_int_remain_on_channel(priv->hNMIWFIDrv, duration,chan->hw_value,NMI_WFI_RemainOnChannelExpired,NMI_WFI_RemainOnChannelReady,(void *)priv);
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_cancel_remain_on_channel
+* @details Cancel an on-going remain-on-channel operation.
+* This allows the operation to be terminated prior to timeout based on
+* the duration value.
+* @param[in] struct wiphy *wiphy,
+* @param[in] struct net_device *dev
+* @param[in] u64 cookie,
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
+ u64 cookie)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
+
+ s32Error = host_int_ListenStateExpired(priv->hNMIWFIDrv);
+ return 0;
+}
+/**
+* @brief NMI_WFI_add_nmivendorspec
+* @details Adding NMI information elemet to allow two NMI devices to
+ identify each other and connect
+* @param[in] NMI_Uint8 * buf
+* @return void
+* @author mdaftedar
+* @date 01 JAN 2014
+* @version 1.0
+*/
+void NMI_WFI_add_nmivendorspec(NMI_Uint8 * buff)
+{
+ memcpy(buff,u8P2P_vendorspec,sizeof(u8P2P_vendorspec));
+}
+/**
+* @brief NMI_WFI_mgmt_tx_frame
+* @details
+*
+* @param[in]
+* @return NONE.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version
+*/
+extern linux_wlan_t* g_linux_wlan;
+extern NMI_Bool bEnablePS;
+#if KERNEL_VERSION(3,1,0) > LINUX_VERSION_CODE
+
+ int NMI_WFI_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan, bool offchan,
+
+ enum nl80211_channel_type channel_type,
+
+ bool channel_type_valid, unsigned int wait,
+
+ const u8 *buf, size_t len, u64 *cookie)
+
+
+
+#else
+
+ int NMI_WFI_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
+
+ struct ieee80211_channel *chan, bool offchan,
+
+ enum nl80211_channel_type channel_type,
+
+ bool channel_type_valid, unsigned int wait,
+
+ const u8 *buf, size_t len, bool no_cck,
+
+ bool dont_wait_for_ack, u64 *cookie)
+
+#endif
+{
+ const struct ieee80211_mgmt *mgmt;
+ linux_wlan_t* nic;
+ struct p2p_mgmt_data *mgmt_tx;
+ struct NMI_WFI_priv* priv;
+ NMI_Uint16 fc;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ NMI_Uint32 i,j;
+
+ /*BugID_5213*/
+ /*Net length of mgmt_tx->buff (Frame passed from WPAS + Added attributes)*/
+ NMI_Uint32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
+
+ priv = wiphy_priv(wiphy);
+ nic =netdev_priv(dev);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+ *cookie = (unsigned long)buf;
+ priv->u64tx_cookie = *cookie;
+ mgmt = (const struct ieee80211_mgmt *) buf;
+ fc = mgmt->frame_control;
+ /*mgmt frame allocation*/
+ mgmt_tx = (struct p2p_mgmt_data*)NMI_MALLOC(sizeof(struct p2p_mgmt_data));
+ if(mgmt_tx == NULL){
+ PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
+ return NMI_FAIL;
+ }
+ mgmt_tx->buff= (char*)NMI_MALLOC(buf_len);
+ if(mgmt_tx->buff == NULL)
+ {
+ PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
+ return NMI_FAIL;
+ }
+ memcpy(mgmt_tx->buff,buf,len);
+ mgmt_tx->size=len;
+
+ /*send mgmt frame to firmware*/
+
+ //if(priv->u8CurrChannel != chan->hw_value)
+
+ priv->u8CurrChannel = chan->hw_value;
+
+ /*BugID_4847*/
+ /*Only set the channel, if not a negotiation confirmation frame
+ (If Negotiation confirmation frame, force it
+ to be transmitted on the same negotiation channel)*/
+ if(buf[0] != 0xd0 || buf[30] != 0x02)
+ {
+ PRINT_D(GENERIC_DBG,"Setting channel: %d\n",chan->hw_value);
+ host_int_set_mac_chnl_num(priv->hNMIWFIDrv, chan->hw_value);
+ }
+
+ if ( (buf[0] == ACTION_FRAME) && ( buf[30] == GO_NEG_REQ_ATTR_ID || buf[30] == GO_NEG_RSP_ATTR_ID || buf[30] == P2P_INVITE_REQ || buf[30] == P2P_INVITE_RSP))
+ {
+ if(u8P2Plocalrandom == 1 && u8P2Precvrandom<u8P2Plocalrandom)
+ {
+ get_random_bytes(&u8P2Plocalrandom, 1);
+ /*TODO:If zero?*/
+ }
+ if(u8P2Plocalrandom > u8P2Precvrandom)
+ {
+ PRINT_D(GENERIC_DBG,"LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n",u8P2Plocalrandom,u8P2Precvrandom);
+ for(i=1;i<len;i++)
+ {
+ /*Search for the P2P public action frames*/
+ if(buf[i]==PUBLICACTION_CAT && buf[i+1]==PUBLICACTION_FRAME && !(memcmp(u8P2P_oui,&buf[i+2],4)))
+ {
+ if(buf[i+6] == GO_NEG_REQ_ATTR_ID || GO_NEG_RSP_ATTR_ID || buf[i+6] == P2P_INVITE_REQ || buf[i+6] == P2P_INVITE_RSP)
+ {
+ for(j=i+8;j<len;j++)
+ {
+ if(buf[j]== P2PELEM_ID && !(memcmp(u8P2P_oui,&buf[j+2],4)) )
+ {
+ if(buf[30]==P2P_INVITE_REQ || buf[30]==P2P_INVITE_RSP)
+ NMI_WFI_CfgParseTxAction(&mgmt_tx->buff[j+6],len-(j+6),NMI_TRUE);
+ else
+ NMI_WFI_CfgParseTxAction(&mgmt_tx->buff[j+6],len-(j+6),NMI_FALSE);
+ break;
+ }
+ }
+ }
+ }
+ }
+ NMI_WFI_add_nmivendorspec(&mgmt_tx->buff[len]);
+ mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
+ mgmt_tx->size=buf_len;
+ }
+ else
+ PRINT_D(GENERIC_DBG,"PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",u8P2Plocalrandom,u8P2Precvrandom);
+ }
+ if(fc == IEEE80211_STYPE_ACTION)
+ {
+ PRINT_D(GENERIC_DBG,"TX: ACTION FRAME Type:%x : Chan:%d\n",buf[30], chan->hw_value);
+ pstrWFIDrv->u64P2p_MgmtTimeout = (jiffies + msecs_to_jiffies(wait));
+
+ PRINT_D(GENERIC_DBG,"Current Jiffies: %lu Timeout:%llu\n",jiffies,pstrWFIDrv->u64P2p_MgmtTimeout);
+ }
+ else if(fc == IEEE80211_STYPE_PROBE_RESP)
+ {
+ PRINT_D(GENERIC_DBG,"TX: Probe Response\n");
+ }
+
+ g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx,mgmt_tx->buff,mgmt_tx->size,NMI_WFI_mgmt_tx_complete);
+
+ return s32Error;
+}
+
+int NMI_WFI_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev,
+ u64 cookie)
+{
+ struct NMI_WFI_priv* priv;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ priv = wiphy_priv(wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+
+
+ PRINT_D(GENERIC_DBG,"Tx Cancel wait :%lu\n",jiffies);
+ pstrWFIDrv->u64P2p_MgmtTimeout = jiffies;
+
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_action
+* @details Transmit an action frame
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version 1.0
+* */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
+int NMI_WFI_action(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan,enum nl80211_channel_type channel_type,
+ const u8 *buf, size_t len, u64 *cookie)
+{
+ PRINT_D(HOSTAPD_DBG,"In action function\n");
+ return NMI_SUCCESS;
+}
+#endif
+#else
+
+/**
+* @brief NMI_WFI_frame_register
+* @details Notify driver that a management frame type was
+* registered. Note that this callback may not sleep, and cannot run
+* concurrently with itself.
+* @param[in]
+* @return NONE.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version
+*/
+void NMI_WFI_frame_register(struct wiphy *wiphy,struct net_device *dev,
+ u16 frame_type, bool reg)
+{
+
+ struct NMI_WFI_priv* priv;
+ perInterface_wlan_t* nic;
+
+
+ priv = wiphy_priv(wiphy);
+ nic = netdev_priv(priv->wdev->netdev);
+
+ /*If mac is closed, then return*/
+ /*if(!nic->nmc1000_initialized)
+ {
+ PRINT_D(GENERIC_DBG,"Return since mac is closed\n");
+ return;
+ }*/
+
+ /*BugID_5137*/
+ if(!frame_type)
+ return;
+
+ PRINT_D(GENERIC_DBG,"Frame registering Frame Type: %x: Boolean: %d\n",frame_type,reg);
+ host_int_frame_register(priv->hNMIWFIDrv,frame_type,reg);
+ switch(frame_type)
+ {
+ case PROBE_REQ:
+ {
+ nic->g_struct_frame_reg[0].frame_type =frame_type;
+ nic->g_struct_frame_reg[0].reg= reg;
+ }
+ break;
+
+ case ACTION:
+ {
+ nic->g_struct_frame_reg[1].frame_type =frame_type;
+ nic->g_struct_frame_reg[1].reg= reg;
+ }
+ break;
+
+ default:
+ {
+ break;
+ }
+
+ }
+
+}
+#endif
+#endif /*NMI_P2P*/
+
+/**
+* @brief NMI_WFI_set_cqm_rssi_config
+* @details Configure connection quality monitor RSSI threshold.
+* @param[in] struct wiphy *wiphy:
+* @param[in] struct net_device *dev:
+* @param[in] s32 rssi_thold:
+* @param[in] u32 rssi_hyst:
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_cqm_rssi_config(struct wiphy *wiphy,
+ struct net_device *dev, s32 rssi_thold, u32 rssi_hyst)
+{
+ PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
+ return 0;
+
+}
+/**
+* @brief NMI_WFI_dump_station
+* @details Configure connection quality monitor RSSI threshold.
+* @param[in] struct wiphy *wiphy:
+* @param[in] struct net_device *dev
+* @param[in] int idx
+* @param[in] u8 *mac
+* @param[in] struct station_info *sinfo
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_dump_station(struct wiphy *wiphy, struct net_device *dev,
+ int idx, u8 *mac, struct station_info *sinfo)
+{
+ struct NMI_WFI_priv* priv;
+ PRINT_D(CFG80211_DBG, "Dumping station information\n");
+
+ if (idx != 0)
+ return -ENOENT;
+
+ priv = wiphy_priv(wiphy);
+ //priv = netdev_priv(priv->wdev->netdev);
+
+ sinfo->filled |= STATION_INFO_SIGNAL ;
+
+ host_int_get_rssi(priv->hNMIWFIDrv, &(sinfo->signal));
+
+#if 0
+ sinfo->filled |= STATION_INFO_TX_BYTES |
+ STATION_INFO_TX_PACKETS |
+ STATION_INFO_RX_BYTES |
+ STATION_INFO_RX_PACKETS | STATION_INFO_SIGNAL | STATION_INFO_INACTIVE_TIME;
+
+ NMI_SemaphoreAcquire(&SemHandleUpdateStats,NULL);
+ sinfo->inactive_time = priv->netstats.rx_time > priv->netstats.tx_time ? jiffies_to_msecs(jiffies - priv->netstats.tx_time) : jiffies_to_msecs(jiffies - priv->netstats.rx_time);
+ sinfo->rx_bytes = priv->netstats.rx_bytes;
+ sinfo->tx_bytes = priv->netstats.tx_bytes;
+ sinfo->rx_packets = priv->netstats.rx_packets;
+ sinfo->tx_packets = priv->netstats.tx_packets;
+ NMI_SemaphoreRelease(&SemHandleUpdateStats,NULL);
+#endif
+ return 0;
+
+}
+
+
+/**
+* @brief NMI_WFI_set_power_mgmt
+* @details
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version 1.0NMI_WFI_set_cqmNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_config_rssi_config
+*/
+int NMI_WFI_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, int timeout)
+{
+ struct NMI_WFI_priv* priv;
+ PRINT_D(CFG80211_DBG," Power save Enabled= %d , TimeOut = %d\n",enabled,timeout);
+
+ if (wiphy == NMI_NULL)
+ return -ENOENT;
+
+ priv = wiphy_priv(wiphy);
+ if(priv->hNMIWFIDrv == NMI_NULL)
+ {
+ NMI_ERROR("Driver is NULL\n");
+ return -EIO;
+ }
+
+ if(bEnablePS == NMI_TRUE)
+ host_int_set_power_mgmt(priv->hNMIWFIDrv, enabled, timeout);
+
+
+ return NMI_SUCCESS;
+
+}
+#ifdef NMI_AP_EXTERNAL_MLME
+/**
+* @brief NMI_WFI_change_virt_intf
+* @details Change type/configuration of virtual interface,
+* keep the struct wireless_dev's iftype updated.
+* @param[in] NONE
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void nmc1000_wlan_deinit(linux_wlan_t *nic);
+int nmc1000_wlan_init(struct net_device *dev, perInterface_wlan_t* p_nic);
+
+static int NMI_WFI_change_virt_intf(struct wiphy *wiphy,struct net_device *dev,
+ enum nl80211_iftype type, u32 *flags,struct vif_params *params)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ //struct NMI_WFI_mon_priv* mon_priv;
+ perInterface_wlan_t* nic;
+ NMI_Uint8 interface_type;
+ NMI_Uint16 TID=0;
+ #ifdef NMI_P2P
+ NMI_Uint8 i;
+ #endif
+
+ nic = netdev_priv(dev);
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(HOSTAPD_DBG,"In Change virtual interface function\n");
+ PRINT_D(HOSTAPD_DBG,"Wireless interface name =%s\n", dev->name);
+ u8P2Plocalrandom=0x01;
+ u8P2Precvrandom=0x00;
+
+ bNmi_ie= NMI_FALSE;
+
+ /*BugID_5137*/
+ /*Set NMI_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
+ if(g_ptk_keys_saved && g_gtk_keys_saved)
+ {
+ Set_machw_change_vir_if(NMI_TRUE);
+ }
+
+ switch(type)
+ {
+ case NL80211_IFTYPE_STATION:
+ connecting = 0;
+ PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_STATION\n");
+ //linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+
+ dev->ieee80211_ptr->iftype = type;
+ priv->wdev->iftype = type;
+ nic->monitor_flag = 0;
+ nic->iftype = STATION_MODE;
+
+ #ifndef SIMULATION
+ #ifdef NMI_P2P
+ interface_type = nic->iftype;
+ nic->iftype = STATION_MODE;
+
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ // ensure that the message Q is empty
+ host_int_wait_msg_queue_idle();
+
+ /*BugID_5213*/
+ /*Eliminate host interface blocking state*/
+ linux_wlan_unlock((void *)&g_linux_wlan->cfg_event);
+
+ nmc1000_wlan_deinit(g_linux_wlan);
+ nmc1000_wlan_init(dev, nic);
+ g_nmc_initialized = 1;
+ nic->iftype = interface_type;
+
+ /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
+ host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
+ host_int_set_MacAddress((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+ host_int_set_operation_mode(priv->hNMIWFIDrv,STATION_MODE);
+
+ /*Add saved WEP keys, if any*/
+ if(g_wep_keys_saved)
+ {
+ host_int_set_WEPDefaultKeyID((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key_idx);
+ host_int_add_wep_key_bss_sta((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key,
+ g_key_wep_params.key_len,
+ g_key_wep_params.key_idx);
+ }
+
+ /*No matter the driver handler passed here, it will be overwriiten*/
+ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
+ host_int_flush_join_req(priv->hNMIWFIDrv);
+
+ /*Add saved PTK and GTK keys, if any*/
+ if(g_ptk_keys_saved && g_gtk_keys_saved)
+ {
+ PRINT_D(CFG80211_DBG,"ptk %x %x %x\n",g_key_ptk_params.key[0],
+ g_key_ptk_params.key[1],
+ g_key_ptk_params.key[2]);
+ PRINT_D(CFG80211_DBG,"gtk %x %x %x\n",g_key_gtk_params.key[0],
+ g_key_gtk_params.key[1],
+ g_key_gtk_params.key[2]);
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_ptk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_ptk_key_params.pairwise,
+ #endif
+ g_add_ptk_key_params.mac_addr,
+ (struct key_params *)(&g_key_ptk_params));
+
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_gtk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_gtk_key_params.pairwise,
+ #endif
+ g_add_gtk_key_params.mac_addr,
+ (struct key_params *)(&g_key_gtk_params));
+ }
+
+ /*BugID_4847: registered frames in firmware are now*/
+ /*lost due to mac close. So re-register those frames*/
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ for(i=0; i<num_reg_frame; i++)
+ {
+ PRINT_D(INIT_DBG,"Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ host_int_frame_register(priv->hNMIWFIDrv,
+ nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ }
+ }
+
+ bEnablePS = NMI_TRUE;
+ host_int_set_power_mgmt( priv->hNMIWFIDrv, 1, 0);
+ }
+ #endif
+ #endif
+ break;
+
+ case NL80211_IFTYPE_P2P_CLIENT:
+ bEnablePS = NMI_FALSE;
+ host_int_set_power_mgmt(priv->hNMIWFIDrv, 0, 0);
+ connecting = 0;
+ PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
+ //linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+
+ host_int_delBASession(priv->hNMIWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID, (void *)priv->hNMIWFIDrv);
+
+ dev->ieee80211_ptr->iftype = type;
+ priv->wdev->iftype = type;
+ nic->monitor_flag = 0;
+ nic->iftype = STATION_MODE;
+
+
+ #ifndef SIMULATION
+ #ifdef NMI_P2P
+
+ PRINT_D(HOSTAPD_DBG,"Downloading P2P_CONCURRENCY_FIRMWARE\n");
+ nic->iftype = CLIENT_MODE;
+
+
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ // ensure that the message Q is empty
+ host_int_wait_msg_queue_idle();
+
+ nmc1000_wlan_deinit(g_linux_wlan);
+ nmc1000_wlan_init(dev, nic);
+ nic->iftype = STATION_MODE;
+ g_nmc_initialized = 1;
+
+ host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
+ host_int_set_MacAddress((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+ host_int_set_operation_mode(priv->hNMIWFIDrv,STATION_MODE);
+
+ /*Add saved WEP keys, if any*/
+ if(g_wep_keys_saved)
+ {
+ host_int_set_WEPDefaultKeyID((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key_idx);
+ host_int_add_wep_key_bss_sta((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key,
+ g_key_wep_params.key_len,
+ g_key_wep_params.key_idx);
+ }
+
+ /*No matter the driver handler passed here, it will be overwriiten*/
+ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
+ host_int_flush_join_req(priv->hNMIWFIDrv);
+
+ /*Add saved PTK and GTK keys, if any*/
+ if(g_ptk_keys_saved && g_gtk_keys_saved)
+ {
+ PRINT_D(CFG80211_DBG,"ptk %x %x %x\n",g_key_ptk_params.key[0],
+ g_key_ptk_params.key[1],
+ g_key_ptk_params.key[2]);
+ PRINT_D(CFG80211_DBG,"gtk %x %x %x\n",g_key_gtk_params.key[0],
+ g_key_gtk_params.key[1],
+ g_key_gtk_params.key[2]);
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_ptk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_ptk_key_params.pairwise,
+ #endif
+ g_add_ptk_key_params.mac_addr,
+ (struct key_params *)(&g_key_ptk_params));
+
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_gtk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_gtk_key_params.pairwise,
+ #endif
+ g_add_gtk_key_params.mac_addr,
+ (struct key_params *)(&g_key_gtk_params));
+ }
+ /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
+ refresh_scan(priv,1,NMI_TRUE);
+ Set_machw_change_vir_if(NMI_FALSE);
+
+ /*BugID_4847: registered frames in firmware are now lost
+ due to mac close. So re-register those frames */
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ for(i=0; i<num_reg_frame; i++)
+ {
+ PRINT_D(INIT_DBG,"Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ host_int_frame_register(priv->hNMIWFIDrv,
+ nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ }
+ }
+ }
+ #endif
+ #endif
+ break;
+
+ case NL80211_IFTYPE_AP:
+ //connecting = 1;
+ bEnablePS = NMI_FALSE;
+ PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_AP %d\n", type);
+ //linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+ //mon_priv = netdev_priv(dev);
+ //mon_priv->real_ndev = dev;
+ dev->ieee80211_ptr->iftype = type;
+ priv->wdev->iftype = type;
+ nic->iftype = AP_MODE;
+ printk("(NMI_Uint32)priv->hNMIWFIDrv[%x]\n",(NMI_Uint32)priv->hNMIWFIDrv);
+
+ #ifndef SIMULATION
+ PRINT_D(HOSTAPD_DBG,"Downloading AP firmware\n");
+ linux_wlan_get_firmware(nic);
+ #ifdef NMI_P2P
+ /*If nmc is running, then close-open to actually get new firmware running (serves P2P)*/
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ nic->iftype = AP_MODE;
+ g_linux_wlan->nmc1000_initialized = 1;
+ mac_close(dev);
+ mac_open(dev);
+
+ //nmc1000_wlan_deinit(g_linux_wlan);
+ //nmc1000_wlan_init(dev,nic);
+ //repeat_power_cycle(nic);
+ //nic->iftype = STATION_MODE;
+
+ /*BugID_4847: registered frames in firmware are now lost
+ due to mac close. So re-register those frames */
+ for(i=0; i<num_reg_frame; i++)
+ {
+ PRINT_D(INIT_DBG,"Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ host_int_frame_register(priv->hNMIWFIDrv,
+ nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ }
+ }
+ #endif
+ #endif
+ break;
+
+ case NL80211_IFTYPE_P2P_GO:
+ PRINT_D(GENERIC_DBG,"start duringIP timer\n");
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ g_obtainingIP=NMI_TRUE;
+ NMI_TimerStart(&hDuringIpTimer, duringIP_TIME, NMI_NULL, NMI_NULL);
+ #endif
+ host_int_set_power_mgmt(priv->hNMIWFIDrv, 0, 0);
+ /*BugID_5222*/
+ /*Delete block ack has to be the latest config packet*/
+ /*sent before downloading new FW. This is because it blocks on*/
+ /*hWaitResponse semaphore, which allows previous config*/
+ /*packets to actually take action on old FW*/
+ host_int_delBASession(priv->hNMIWFIDrv, g_linux_wlan->strInterfaceInfo[0].aBSSID, TID, (void *)priv->hNMIWFIDrv);
+ bEnablePS = NMI_FALSE;
+ PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_GO\n");
+ //linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+ //mon_priv = netdev_priv(dev);
+ //mon_priv->real_ndev = dev;
+ dev->ieee80211_ptr->iftype = type;
+ priv->wdev->iftype = type;
+ nic->iftype = AP_MODE;
+ printk("(NMI_Uint32)priv->hNMIWFIDrv[%x]\n",(NMI_Uint32)priv->hNMIWFIDrv);
+ //host_int_set_operation_mode((NMI_Uint32)priv->hNMIWFIDrv,AP_MODE);
+
+ #ifndef SIMULATION
+ #ifdef NMI_P2P
+ PRINT_D(HOSTAPD_DBG,"Downloading P2P_CONCURRENCY_FIRMWARE\n");
+
+
+ #if 1
+ interface_type = nic->iftype;
+ nic->iftype = GO_MODE;
+
+ // ensure that the message Q is empty
+ host_int_wait_msg_queue_idle();
+
+ /*while(!g_hif_thread_idle)
+ {
+ PRINT_D(GENERIC_DBG, "Wait for host IF idle\n");
+ NMI_Sleep(10);
+ }*/
+ nmc1000_wlan_deinit(g_linux_wlan);
+ //repeat_power_cycle_partially(g_linux_wlan);
+ nmc1000_wlan_init(dev, nic);
+ g_nmc_initialized = 1;
+ nic->iftype = interface_type;
+
+ /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
+ host_int_set_wfi_drv_handler(g_linux_wlan->strInterfaceInfo[0].drvHandler);
+ host_int_set_MacAddress((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+ host_int_set_operation_mode(priv->hNMIWFIDrv,AP_MODE);
+
+ /*Add saved WEP keys, if any*/
+ if(g_wep_keys_saved)
+ {
+ host_int_set_WEPDefaultKeyID((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key_idx);
+ host_int_add_wep_key_bss_sta((NMI_WFIDrvHandle)(g_linux_wlan->strInterfaceInfo[0].drvHandler),
+ g_key_wep_params.key,
+ g_key_wep_params.key_len,
+ g_key_wep_params.key_idx);
+ }
+
+ /*No matter the driver handler passed here, it will be overwriiten*/
+ /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
+ host_int_flush_join_req(priv->hNMIWFIDrv);
+
+ /*Add saved PTK and GTK keys, if any*/
+ if(g_ptk_keys_saved && g_gtk_keys_saved)
+ {
+ PRINT_D(CFG80211_DBG,"ptk %x %x %x cipher %x\n",g_key_ptk_params.key[0],
+ g_key_ptk_params.key[1],
+ g_key_ptk_params.key[2],
+ g_key_ptk_params.cipher);
+ PRINT_D(CFG80211_DBG,"gtk %x %x %x cipher %x\n",g_key_gtk_params.key[0],
+ g_key_gtk_params.key[1],
+ g_key_gtk_params.key[2],
+ g_key_gtk_params.cipher);
+ #if 1
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_ptk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_ptk_key_params.pairwise,
+ #endif
+ g_add_ptk_key_params.mac_addr,
+ (struct key_params *)(&g_key_ptk_params));
+
+ NMI_WFI_add_key(g_linux_wlan->strInterfaceInfo[0].nmc_netdev->ieee80211_ptr->wiphy,
+ g_linux_wlan->strInterfaceInfo[0].nmc_netdev,
+ g_add_gtk_key_params.key_idx,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)
+ g_add_gtk_key_params.pairwise,
+ #endif
+ g_add_gtk_key_params.mac_addr,
+ (struct key_params *)(&g_key_gtk_params));
+ #endif
+ }
+ #endif
+
+ /*BugID_4847: registered frames in firmware are now*/
+ /*lost due to mac close. So re-register those frames*/
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+ for(i=0; i<num_reg_frame; i++)
+ {
+ PRINT_D(INIT_DBG,"Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ host_int_frame_register(priv->hNMIWFIDrv,
+ nic->g_struct_frame_reg[i].frame_type,
+ nic->g_struct_frame_reg[i].reg);
+ }
+ }
+ #endif
+ #endif
+ break;
+
+ default:
+ PRINT_ER("Unknown interface type= %d\n", type);
+ s32Error = -EINVAL;
+ return s32Error;
+ break;
+ }
+
+ return s32Error;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+/* (austin.2013-07-23)
+
+ To support revised cfg80211_ops
+
+ add_beacon --> start_ap
+ set_beacon --> change_beacon
+ del_beacon --> stop_ap
+
+ beacon_parameters --> cfg80211_ap_settings
+ cfg80211_beacon_data
+
+ applicable for linux kernel 3.4+
+*/
+
+/* cache of cfg80211_ap_settings later use in change_beacon api. */
+static struct cfg80211_ap_settings *_g_pApSettings = NULL;
+
+/**
+* @brief NMI_WFI_start_ap
+* @details Add a beacon with given parameters, @head, @interval
+* and @dtim_period will be valid, @tail is optional.
+* @param[in] wiphy
+* @param[in] dev The net device structure
+* @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
+* @return int : Return 0 on Success.
+* @author austin
+* @date 23 JUL 2013
+* @version 1.0
+*/
+static int NMI_WFI_start_ap(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ap_settings *settings)
+{
+ struct cfg80211_beacon_data* beacon = &(settings->beacon);
+ struct NMI_WFI_priv* priv;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ priv = wiphy_priv(wiphy);
+ PRINT_D(HOSTAPD_DBG,"Starting ap\n");
+
+ PRINT_D(HOSTAPD_DBG,"Interval = %d \n DTIM period = %d\n Head length = %d Tail length = %d\n",
+ settings->beacon_interval , settings->dtim_period, beacon->head_len, beacon->tail_len );
+
+ linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_add_beacon( priv->hNMIWFIDrv,
+ settings->beacon_interval,
+ settings->dtim_period,
+ beacon->head_len, (NMI_Uint8*)beacon->head,
+ beacon->tail_len, (NMI_Uint8*)beacon->tail);
+ #else
+ s32Error = host_add_beacon( priv->hNMIWFIDrv,
+ settings->beacon_interval,
+ settings->dtim_period,
+ beacon->head_len, (NMI_Uint8*)beacon->head,
+ beacon->tail_len, (NMI_Uint8*)beacon->tail);
+ #endif
+
+ _g_pApSettings = settings;
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_change_beacon
+* @details Add a beacon with given parameters, @head, @interval
+* and @dtim_period will be valid, @tail is optional.
+* @param[in] wiphy
+* @param[in] dev The net device structure
+* @param[in] beacon cfg80211_beacon_data for the beacon to be changed
+* @return int : Return 0 on Success.
+* @author austin
+* @date 23 JUL 2013
+* @version 1.0
+*/
+static int NMI_WFI_change_beacon(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_beacon_data *beacon)
+{
+ struct cfg80211_ap_settings *settings = _g_pApSettings;
+ struct NMI_WFI_priv* priv;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ priv = wiphy_priv(wiphy);
+ PRINT_D(HOSTAPD_DBG,"Setting beacon\n");
+
+ // should be call after start_ap.
+ if (!settings)
+ return NMI_INVALID_STATE;
+
+#ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_add_beacon( priv->hNMIWFIDrv,
+ settings->beacon_interval,
+ settings->dtim_period,
+ beacon->head_len, (NMI_Uint8*)beacon->head,
+ beacon->tail_len, (NMI_Uint8*)beacon->tail);
+#else
+ s32Error = host_add_beacon( priv->hNMIWFIDrv,
+ settings->beacon_interval,
+ settings->dtim_period,
+ beacon->head_len, (NMI_Uint8*)beacon->head,
+ beacon->tail_len, (NMI_Uint8*)beacon->tail);
+#endif
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_stop_ap
+* @details Remove beacon configuration and stop sending the beacon.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author austin
+* @date 23 JUL 2013
+* @version 1.0
+*/
+static int NMI_WFI_stop_ap(struct wiphy *wiphy, struct net_device *dev)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ NMI_Uint8 NullBssid[ETH_ALEN] = {0};
+
+
+ NMI_NULLCHECK(s32Error, wiphy);
+
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(HOSTAPD_DBG,"Deleting beacon\n");
+
+ /*BugID_5188*/
+ linux_wlan_set_bssid(dev, NullBssid);
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_del_beacon(priv->hNMIWFIDrv);
+ #else
+ s32Error = host_del_beacon(priv->hNMIWFIDrv);
+ #endif
+
+ _g_pApSettings = NULL; // better to reset primitive regardless of error.
+
+ NMI_ERRORCHECK(s32Error);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+#else /* here belows are original for < kernel 3.3 (austin.2013-07-23) */
+
+/**
+* @brief NMI_WFI_add_beacon
+* @details Add a beacon with given parameters, @head, @interval
+* and @dtim_period will be valid, @tail is optional.
+* @param[in] wiphy
+* @param[in] dev The net device structure
+* @param[in] info Parameters for the beacon to be added
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_add_beacon(struct wiphy *wiphy, struct net_device *dev,
+ struct beacon_parameters *info)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+
+
+
+ priv = wiphy_priv(wiphy);
+ PRINT_D(HOSTAPD_DBG,"Adding Beacon\n");
+
+ PRINT_D(HOSTAPD_DBG,"Interval = %d \n DTIM period = %d\n Head length = %d Tail length = %d\n",info->interval , info->dtim_period,info->head_len,info->tail_len );
+
+ linux_wlan_set_bssid(dev,g_linux_wlan->strInterfaceInfo[0].aSrcAddress);
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_add_beacon(priv->hNMIWFIDrv, info->interval,
+ info->dtim_period,
+ info->head_len, info->head,
+ info->tail_len, info->tail);
+
+ #else
+ s32Error = host_add_beacon(priv->hNMIWFIDrv, info->interval,
+ info->dtim_period,
+ info->head_len, info->head,
+ info->tail_len, info->tail);
+ #endif
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_set_beacon
+* @details Change the beacon parameters for an access point mode
+* interface. This should reject the call when no beacon has been
+* configured.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_set_beacon(struct wiphy *wiphy, struct net_device *dev,
+ struct beacon_parameters *info)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+
+ PRINT_D(HOSTAPD_DBG,"Setting beacon\n");
+
+ s32Error = NMI_WFI_add_beacon(wiphy, dev, info);
+
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_del_beacon
+* @details Remove beacon configuration and stop sending the beacon.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_del_beacon(struct wiphy *wiphy, struct net_device *dev)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ NMI_Uint8 NullBssid[ETH_ALEN] = {0};
+
+
+ NMI_NULLCHECK(s32Error, wiphy);
+
+ priv = wiphy_priv(wiphy);
+
+ PRINT_D(HOSTAPD_DBG,"Deleting beacon\n");
+
+ /*BugID_5188*/
+ linux_wlan_set_bssid(dev, NullBssid);
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_del_beacon(priv->hNMIWFIDrv);
+ #else
+ s32Error = host_del_beacon(priv->hNMIWFIDrv);
+ #endif
+
+ NMI_ERRORCHECK(s32Error);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+#endif /* linux kernel 3.4+ (austin.2013-07-23) */
+
+/**
+* @brief NMI_WFI_add_station
+* @details Add a new station.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_add_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_parameters *params)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ tstrNMI_AddStaParam strStaParams={{0}};
+ perInterface_wlan_t* nic;
+
+
+ NMI_NULLCHECK(s32Error, wiphy);
+
+ priv = wiphy_priv(wiphy);
+ nic = netdev_priv(dev);
+
+ if(nic->iftype == AP_MODE)
+ {
+ #ifndef NMI_FULLY_HOSTING_AP
+
+ NMI_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
+ NMI_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid],mac,ETH_ALEN);
+ strStaParams.u16AssocID = params->aid;
+ strStaParams.u8NumRates = params->supported_rates_len;
+ strStaParams.pu8Rates = params->supported_rates;
+
+ PRINT_D(CFG80211_DBG,"Adding station parameters %d\n",params->aid);
+
+ PRINT_D(CFG80211_DBG,"BSSID = %x%x%x%x%x%x\n",priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
+ priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
+ PRINT_D(HOSTAPD_DBG,"ASSOC ID = %d\n",strStaParams.u16AssocID);
+ PRINT_D(HOSTAPD_DBG,"Number of supported rates = %d\n",strStaParams.u8NumRates);
+
+ if(params->ht_capa == NMI_NULL)
+ {
+ strStaParams.bIsHTSupported = NMI_FALSE;
+ }
+ else
+ {
+ strStaParams.bIsHTSupported = NMI_TRUE;
+ strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
+ strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
+ NMI_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, NMI_SUPP_MCS_SET_SIZE);
+ strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
+ strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
+ strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
+ }
+
+ strStaParams.u16FlagsMask = params->sta_flags_mask;
+ strStaParams.u16FlagsSet = params->sta_flags_set;
+
+ PRINT_D(HOSTAPD_DBG,"IS HT supported = %d\n", strStaParams.bIsHTSupported);
+ PRINT_D(HOSTAPD_DBG,"Capability Info = %d\n", strStaParams.u16HTCapInfo);
+ PRINT_D(HOSTAPD_DBG,"AMPDU Params = %d\n",strStaParams.u8AmpduParams);
+ PRINT_D(HOSTAPD_DBG,"HT Extended params = %d\n",strStaParams.u16HTExtParams);
+ PRINT_D(HOSTAPD_DBG,"Tx Beamforming Cap = %d\n",strStaParams.u32TxBeamformingCap);
+ PRINT_D(HOSTAPD_DBG,"Antenna selection info = %d\n",strStaParams.u8ASELCap);
+ PRINT_D(HOSTAPD_DBG,"Flag Mask = %d\n",strStaParams.u16FlagsMask);
+ PRINT_D(HOSTAPD_DBG,"Flag Set = %d\n",strStaParams.u16FlagsSet);
+
+ s32Error = host_int_add_station(priv->hNMIWFIDrv, &strStaParams);
+ NMI_ERRORCHECK(s32Error);
+
+ #else
+ PRINT_D(CFG80211_DBG,"Adding station parameters %d\n",params->aid);
+ NMI_memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid],mac,ETH_ALEN);
+
+ PRINT_D(CFG80211_DBG,"BSSID = %x%x%x%x%x%x\n",priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3],priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
+ priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
+
+ NMI_AP_AddSta(mac, params);
+ NMI_ERRORCHECK(s32Error);
+ #endif //NMI_FULLY_HOSTING_AP
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_del_station
+* @details Remove a station; @mac may be NULL to remove all stations.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_del_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ perInterface_wlan_t* nic;
+
+
+ NMI_NULLCHECK(s32Error, wiphy);
+ /*BugID_4795: mac may be null pointer to indicate deleting all stations, so avoid null check*/
+ //NMI_NULLCHECK(s32Error, mac);
+
+ priv = wiphy_priv(wiphy);
+ nic = netdev_priv(dev);
+
+ if(nic->iftype == AP_MODE)
+ {
+ PRINT_D(HOSTAPD_DBG,"Deleting station\n");
+
+
+ if(mac == NMI_NULL)
+ PRINT_D(HOSTAPD_DBG,"All associated stations \n");
+ else
+ PRINT_D(HOSTAPD_DBG,"With mac address: %x%x%x%x%x%x\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ s32Error = host_int_del_station(priv->hNMIWFIDrv , mac);
+ #else
+ NMI_AP_RemoveSta(mac);
+ #endif //NMI_FULLY_HOSTING_AP
+ NMI_ERRORCHECK(s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_change_station
+* @details Modify a given station.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_change_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_parameters *params)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ struct NMI_WFI_priv* priv;
+ tstrNMI_AddStaParam strStaParams={{0}};
+ perInterface_wlan_t* nic;
+
+
+ PRINT_D(HOSTAPD_DBG,"Change station paramters\n");
+
+ NMI_NULLCHECK(s32Error, wiphy);
+
+ priv = wiphy_priv(wiphy);
+ nic = netdev_priv(dev);
+
+ if(nic->iftype == AP_MODE)
+ {
+ #ifndef NMI_FULLY_HOSTING_AP
+
+ NMI_memcpy(strStaParams.au8BSSID, mac, ETH_ALEN);
+ strStaParams.u16AssocID = params->aid;
+ strStaParams.u8NumRates = params->supported_rates_len;
+ strStaParams.pu8Rates = params->supported_rates;
+
+ PRINT_D(HOSTAPD_DBG,"BSSID = %x%x%x%x%x%x\n",strStaParams.au8BSSID[0],strStaParams.au8BSSID[1],strStaParams.au8BSSID[2],strStaParams.au8BSSID[3],strStaParams.au8BSSID[4],
+ strStaParams.au8BSSID[5]);
+ PRINT_D(HOSTAPD_DBG,"ASSOC ID = %d\n",strStaParams.u16AssocID);
+ PRINT_D(HOSTAPD_DBG,"Number of supported rates = %d\n",strStaParams.u8NumRates);
+
+ if(params->ht_capa == NMI_NULL)
+ {
+ strStaParams.bIsHTSupported = NMI_FALSE;
+ }
+ else
+ {
+ strStaParams.bIsHTSupported = NMI_TRUE;
+ strStaParams.u16HTCapInfo = params->ht_capa->cap_info;
+ strStaParams.u8AmpduParams = params->ht_capa->ampdu_params_info;
+ NMI_memcpy(strStaParams.au8SuppMCsSet, &params->ht_capa->mcs, NMI_SUPP_MCS_SET_SIZE);
+ strStaParams.u16HTExtParams = params->ht_capa->extended_ht_cap_info;
+ strStaParams.u32TxBeamformingCap = params->ht_capa->tx_BF_cap_info;
+ strStaParams.u8ASELCap = params->ht_capa->antenna_selection_info;
+
+ }
+
+ strStaParams.u16FlagsMask = params->sta_flags_mask;
+ strStaParams.u16FlagsSet = params->sta_flags_set;
+
+ PRINT_D(HOSTAPD_DBG,"IS HT supported = %d\n", strStaParams.bIsHTSupported);
+ PRINT_D(HOSTAPD_DBG,"Capability Info = %d\n", strStaParams.u16HTCapInfo);
+ PRINT_D(HOSTAPD_DBG,"AMPDU Params = %d\n",strStaParams.u8AmpduParams);
+ PRINT_D(HOSTAPD_DBG,"HT Extended params = %d\n",strStaParams.u16HTExtParams);
+ PRINT_D(HOSTAPD_DBG,"Tx Beamforming Cap = %d\n",strStaParams.u32TxBeamformingCap);
+ PRINT_D(HOSTAPD_DBG,"Antenna selection info = %d\n",strStaParams.u8ASELCap);
+ PRINT_D(HOSTAPD_DBG,"Flag Mask = %d\n",strStaParams.u16FlagsMask);
+ PRINT_D(HOSTAPD_DBG,"Flag Set = %d\n",strStaParams.u16FlagsSet);
+
+ s32Error = host_int_edit_station(priv->hNMIWFIDrv, &strStaParams);
+ NMI_ERRORCHECK(s32Error);
+
+ #else
+ NMI_AP_EditSta(mac, params);
+ NMI_ERRORCHECK(s32Error);
+ #endif //NMI_FULLY_HOSTING_AP
+
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+
+/**
+* @brief NMI_WFI_add_virt_intf
+* @details
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version 1.0
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) /* tony for v3.8 support */
+struct wireless_dev * NMI_WFI_add_virt_intf(struct wiphy *wiphy, const char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) /* tony for v3.6 support */
+struct wireless_dev * NMI_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+int NMI_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+#else
+struct net_device *NMI_WFI_add_virt_intf(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+#endif
+{
+ perInterface_wlan_t * nic;
+ struct NMI_WFI_priv* priv;
+ //struct NMI_WFI_mon_priv* mon_priv;
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ #endif
+ struct net_device * new_ifc = NULL;
+ priv = wiphy_priv(wiphy);
+
+
+
+ PRINT_D(HOSTAPD_DBG,"Adding monitor interface[%p]\n",priv->wdev->netdev);
+
+ nic = netdev_priv(priv->wdev->netdev);
+
+
+ if(type == NL80211_IFTYPE_MONITOR)
+ {
+ PRINT_D(HOSTAPD_DBG,"Monitor interface mode: Initializing mon interface virtual device driver\n");
+ PRINT_D(HOSTAPD_DBG,"Adding monitor interface[%p]\n",nic->nmc_netdev);
+ new_ifc = NMI_WFI_init_mon_interface(name,nic->nmc_netdev);
+ if(new_ifc != NULL)
+ {
+ PRINT_D(HOSTAPD_DBG,"Setting monitor flag in private structure\n");
+ #ifdef SIMULATION
+ priv = netdev_priv(priv->wdev->netdev);
+ priv->monitor_flag = 1;
+ #else
+ nic = netdev_priv(priv->wdev->netdev);
+ nic->monitor_flag = 1;
+ #endif
+ }
+ else
+ PRINT_ER("Error in initializing monitor interface\n ");
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) /* tony for v3.8 support */
+ //return priv->wdev;
+ return new_ifc; // rachel - have to check
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ return s32Error;
+#else
+ //return priv->wdev->netdev;
+ PRINT_D(HOSTAPD_DBG,"IFC[%p] created\n",new_ifc);
+ return new_ifc;
+#endif
+
+}
+
+/**
+* @brief NMI_WFI_del_virt_intf
+* @details
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 JUL 2012
+* @version 1.0
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+int NMI_WFI_del_virt_intf(struct wiphy *wiphy, struct wireless_dev *wdev) /* tony for v3.8 support */
+#else
+int NMI_WFI_del_virt_intf(struct wiphy *wiphy,struct net_device *dev)
+#endif
+{
+ PRINT_D(HOSTAPD_DBG,"Deleting virtual interface\n");
+ return NMI_SUCCESS;
+}
+
+
+
+#endif /*NMI_AP_EXTERNAL_MLME*/
+static struct cfg80211_ops NMI_WFI_cfg80211_ops = {
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+ /*
+ * replaced set_channel by set_monitor_channel
+ * from v3.6
+ * tony, 2013-10-29
+ */
+ .set_monitor_channel = NMI_WFI_CfgSetChannel,
+#else
+ .set_channel = NMI_WFI_CfgSetChannel,
+#endif
+ .scan = NMI_WFI_CfgScan,
+ .connect = NMI_WFI_CfgConnect,
+ .disconnect = NMI_WFI_disconnect,
+ .add_key = NMI_WFI_add_key,
+ .del_key = NMI_WFI_del_key,
+ .get_key = NMI_WFI_get_key,
+ .set_default_key = NMI_WFI_set_default_key,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ //.dump_survey = NMI_WFI_dump_survey,
+#endif
+ #ifdef NMI_AP_EXTERNAL_MLME
+ .add_virtual_intf = NMI_WFI_add_virt_intf,
+ .del_virtual_intf = NMI_WFI_del_virt_intf,
+ .change_virtual_intf = NMI_WFI_change_virt_intf,
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
+ .add_beacon = NMI_WFI_add_beacon,
+ .set_beacon = NMI_WFI_set_beacon,
+ .del_beacon = NMI_WFI_del_beacon,
+#else
+ /* supports kernel 3.4+ change. austin.2013-07-23 */
+ .start_ap = NMI_WFI_start_ap,
+ .change_beacon = NMI_WFI_change_beacon,
+ .stop_ap = NMI_WFI_stop_ap,
+#endif
+ .add_station = NMI_WFI_add_station,
+ .del_station = NMI_WFI_del_station,
+ .change_station = NMI_WFI_change_station,
+ #endif /* NMI_AP_EXTERNAL_MLME*/
+ #ifndef NMI_FULLY_HOSTING_AP
+ .get_station = NMI_WFI_get_station,
+ #endif
+ .dump_station = NMI_WFI_dump_station,
+ .change_bss = NMI_WFI_change_bss,
+ //.auth = NMI_WFI_auth,
+ //.assoc = NMI_WFI_assoc,
+ //.deauth = NMI_WFI_deauth,
+ //.disassoc = NMI_WFI_disassoc,
+ .set_wiphy_params = NMI_WFI_set_wiphy_params,
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ //.set_bitrate_mask = NMI_WFI_set_bitrate_mask,
+ .set_pmksa = NMI_WFI_set_pmksa,
+ .del_pmksa = NMI_WFI_del_pmksa,
+ .flush_pmksa = NMI_WFI_flush_pmksa,
+#ifdef NMI_P2P
+ .remain_on_channel = NMI_WFI_remain_on_channel,
+ .cancel_remain_on_channel = NMI_WFI_cancel_remain_on_channel,
+ .mgmt_tx_cancel_wait = NMI_WFI_mgmt_tx_cancel_wait,
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
+ .action = NMI_WFI_action,
+ #endif
+ #else
+ .mgmt_tx = NMI_WFI_mgmt_tx,
+ .mgmt_frame_register = NMI_WFI_frame_register,
+ #endif
+#endif
+ //.mgmt_tx_cancel_wait = NMI_WFI_mgmt_tx_cancel_wait,
+ .set_power_mgmt = NMI_WFI_set_power_mgmt,
+ .set_cqm_rssi_config = NMI_WFI_set_cqm_rssi_config,
+#endif
+
+};
+
+
+
+
+
+/**
+* @brief NMI_WFI_update_stats
+* @details Modify parameters for a given BSS.
+* @param[in]
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0NMI_WFI_set_cqmNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_configNMI_WFI_set_cqm_rssi_config_rssi_config
+*/
+int NMI_WFI_update_stats(struct wiphy *wiphy, u32 pktlen , u8 changed)
+{
+
+ struct NMI_WFI_priv *priv;
+
+ priv = wiphy_priv(wiphy);
+ //NMI_SemaphoreAcquire(&SemHandleUpdateStats,NULL);
+#if 1
+ switch(changed)
+ {
+
+ case NMI_WFI_RX_PKT:
+ {
+ //MI_PRINTF("In Rx Receive Packet\n");
+ priv->netstats.rx_packets++;
+ priv->netstats.rx_bytes += pktlen;
+ priv->netstats.rx_time = get_jiffies_64();
+ }
+ break;
+ case NMI_WFI_TX_PKT:
+ {
+ //NMI_PRINTF("In Tx Receive Packet\n");
+ priv->netstats.tx_packets++;
+ priv->netstats.tx_bytes += pktlen;
+ priv->netstats.tx_time = get_jiffies_64();
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ //NMI_SemaphoreRelease(&SemHandleUpdateStats,NULL);
+#endif
+ return 0;
+}
+/**
+* @brief NMI_WFI_InitPriv
+* @details Initialization of the net device, private data
+* @param[in] NONE
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_InitPriv(struct net_device *dev)
+{
+
+ struct NMI_WFI_priv *priv;
+ priv = netdev_priv(dev);
+
+ priv->netstats.rx_packets = 0;
+ priv->netstats.tx_packets = 0;
+ priv->netstats.rx_bytes = 0;
+ priv->netstats.rx_bytes = 0;
+ priv->netstats.rx_time = 0;
+ priv->netstats.tx_time = 0;
+
+
+}
+/**
+* @brief NMI_WFI_CfgAlloc
+* @details Allocation of the wireless device structure and assigning it
+* to the cfg80211 operations structure.
+* @param[in] NONE
+* @return wireless_dev : Returns pointer to wireless_dev structure.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+struct wireless_dev* NMI_WFI_CfgAlloc(void)
+{
+
+ struct wireless_dev *wdev;
+
+
+ PRINT_D(CFG80211_DBG,"Allocating wireless device\n");
+ /*Allocating the wireless device structure*/
+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+ if (!wdev)
+ {
+ PRINT_ER("Cannot allocate wireless device\n");
+ goto _fail_;
+ }
+
+ /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
+ wdev->wiphy = wiphy_new(&NMI_WFI_cfg80211_ops, sizeof(struct NMI_WFI_priv));
+ if (!wdev->wiphy)
+ {
+ PRINT_ER("Cannot allocate wiphy\n");
+ goto _fail_mem_;
+
+ }
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ //enable 802.11n HT
+ NMI_WFI_band_2ghz.ht_cap.ht_supported = 1;
+ NMI_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+ NMI_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
+ NMI_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
+ NMI_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+ #endif
+
+ /*wiphy bands*/
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ]= &NMI_WFI_band_2ghz;
+
+ return wdev;
+
+_fail_mem_:
+ kfree(wdev);
+_fail_:
+ return NULL;
+
+}
+/**
+* @brief NMI_WFI_WiphyRegister
+* @details Registering of the wiphy structure and interface modes
+* @param[in] NONE
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+struct wireless_dev* NMI_WFI_WiphyRegister(struct net_device *net)
+{
+ struct NMI_WFI_priv *priv;
+ struct wireless_dev *wdev;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ PRINT_D(CFG80211_DBG,"Registering wifi device\n");
+
+ wdev = NMI_WFI_CfgAlloc();
+ if(wdev == NULL){
+ PRINT_ER("CfgAlloc Failed\n");
+ return NULL;
+ }
+
+
+ /*Return hardware description structure (wiphy)'s priv*/
+ priv = wdev_priv(wdev);
+ NMI_SemaphoreCreate(&(priv->SemHandleUpdateStats),NULL);
+
+ /*Added by Amr - BugID_4793*/
+ priv->u8CurrChannel = -1;
+
+ /*Link the wiphy with wireless structure*/
+ priv->wdev = wdev;
+
+ /*Maximum number of probed ssid to be added by user for the scan request*/
+ wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ /*Maximum number of pmkids to be cashed*/
+ wdev->wiphy->max_num_pmkids = NMI_MAX_NUM_PMKIDS;
+ PRINT_INFO(CFG80211_DBG,"Max number of PMKIDs = %d\n",wdev->wiphy->max_num_pmkids);
+ #endif
+
+ wdev->wiphy->max_scan_ie_len = 1000;
+
+ /*signal strength in mBm (100*dBm) */
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ /*Set the availaible cipher suites*/
+ wdev->wiphy->cipher_suites = cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+ /*Setting default managment types: for register action frame: */
+ wdev->wiphy->mgmt_stypes = nmi_wfi_cfg80211_mgmt_types;
+#endif
+
+#ifdef NMI_P2P
+ wdev->wiphy->max_remain_on_channel_duration = 500;
+ /*Setting the wiphy interfcae mode and type before registering the wiphy*/
+ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
+
+ wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+#endif
+#else
+ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
+#endif
+ wdev->iftype = NL80211_IFTYPE_STATION;
+
+
+
+ PRINT_INFO(CFG80211_DBG,"Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
+ wdev->wiphy->max_scan_ssids,wdev->wiphy->max_scan_ie_len,wdev->wiphy->signal_type,
+ wdev->wiphy->interface_modes, wdev->iftype);
+
+ set_wiphy_dev(wdev->wiphy, &local_sdio_func->dev); //tony
+ /*Register wiphy structure*/
+ s32Error = wiphy_register(wdev->wiphy);
+ if (s32Error){
+ PRINT_ER("Cannot register wiphy device\n");
+ /*should define what action to be taken in such failure*/
+ }
+ else
+ {
+ PRINT_D(CFG80211_DBG,"Successful Registering\n");
+ }
+
+#if 0
+ /*wdev[i]->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP);
+ wdev[i]->iftype = NL80211_IFTYPE_AP;
+ */
+
+ /*Pointing the priv structure the netdev*/
+ priv= netdev_priv(net);
+
+ /*linking the wireless_dev structure with the netdevice*/
+ priv->dev->ieee80211_ptr = wdev;
+ priv->dev->ml_priv = priv;
+ wdev->netdev = priv->dev;
+#endif
+ priv->dev = net;
+#if 0
+ ret = host_int_init(&priv->hNMIWFIDrv);
+ if(ret)
+ {
+ NMI_PRINTF("Error Init Driver\n");
+ }
+#endif
+ return wdev;
+
+
+}
+/**
+* @brief NMI_WFI_WiphyFree
+* @details Freeing allocation of the wireless device structure
+* @param[in] NONE
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_InitHostInt(struct net_device *net)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ struct NMI_WFI_priv *priv;
+
+ tstrNMI_SemaphoreAttrs strSemaphoreAttrs;
+
+ printk("Host[%p][%p]\n",net,net->ieee80211_ptr);
+ priv = wdev_priv(net->ieee80211_ptr);
+ if(op_ifcs==0)
+ {
+ s32Error = NMI_TimerCreate(&(hAgingTimer), remove_network_from_shadow, NMI_NULL);
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ s32Error = NMI_TimerCreate(&(hDuringIpTimer), clear_duringIP, NMI_NULL);
+ #endif
+ }
+ op_ifcs++;
+ if(s32Error < 0){
+ PRINT_ER("Failed to creat refresh Timer\n");
+ return s32Error;
+ }
+
+ NMI_SemaphoreFillDefault(&strSemaphoreAttrs);
+
+ /////////////////////////////////////////
+ //strSemaphoreAttrs.u32InitCount = 0;
+
+
+ priv->gbAutoRateAdjusted = NMI_FALSE;
+
+
+ NMI_SemaphoreCreate(&(priv->hSemScanReq), &strSemaphoreAttrs);
+ s32Error = host_int_init(&priv->hNMIWFIDrv);
+ //s32Error = host_int_init(&priv->hNMIWFIDrv_2);
+ if(s32Error)
+ {
+ PRINT_ER("Error while initializing hostinterface\n");
+ }
+ return s32Error;
+}
+
+/**
+* @brief NMI_WFI_WiphyFree
+* @details Freeing allocation of the wireless device structure
+* @param[in] NONE
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_DeInitHostInt(struct net_device *net)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ struct NMI_WFI_priv *priv;
+ priv = wdev_priv(net->ieee80211_ptr);
+
+
+
+
+
+
+ NMI_SemaphoreDestroy(&(priv->hSemScanReq),NULL);
+
+ priv->gbAutoRateAdjusted = NMI_FALSE;
+
+
+
+ op_ifcs--;
+
+ s32Error = host_int_deinit(priv->hNMIWFIDrv);
+ //s32Error = host_int_deinit(priv->hNMIWFIDrv_2);
+
+ /* Clear the Shadow scan */
+ clear_shadow_scan(priv);
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ if(op_ifcs==0)
+ {
+ printk("destroy during ip\n");
+ NMI_TimerDestroy(&hDuringIpTimer,NMI_NULL);
+ }
+ #endif
+
+
+ if(s32Error)
+ {
+ PRINT_ER("Error while deintializing host interface\n");
+ }
+ return s32Error;
+}
+
+
+/**
+* @brief NMI_WFI_WiphyFree
+* @details Freeing allocation of the wireless device structure
+* @param[in] NONE
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_WiphyFree(struct net_device *net)
+{
+
+ PRINT_D(CFG80211_DBG,"Unregistering wiphy\n");
+
+ if(net == NULL){
+ PRINT_D(INIT_DBG,"net_device is NULL\n");
+ return;
+ }
+
+ if(net->ieee80211_ptr == NULL){
+ PRINT_D(INIT_DBG,"ieee80211_ptr is NULL\n");
+ return;
+ }
+
+ if(net->ieee80211_ptr->wiphy == NULL){
+ PRINT_D(INIT_DBG,"wiphy is NULL\n");
+ return;
+ }
+
+ wiphy_unregister(net->ieee80211_ptr->wiphy);
+
+ PRINT_D(INIT_DBG,"Freeing wiphy\n");
+ wiphy_free(net->ieee80211_ptr->wiphy);
+ kfree(net->ieee80211_ptr);
+
+}
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_NetDevice.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_NetDevice.c
new file mode 100755
index 00000000..41847cba
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/NMI_WFI_NetDevice.c
@@ -0,0 +1,969 @@
+/*!
+* @file NMI_WFI_NetDevice.c
+* @brief File Operations OS wrapper functionality
+* @author mdaftedar
+* @sa NMI_WFI_NetDevice.h
+* @date 01 MAR 2012
+* @version 1.0
+*/
+
+#ifdef SIMULATION
+
+#include "linux/include/NMI_WFI_CfgOperations.h"
+#include "host_interface.h"
+
+
+MODULE_AUTHOR("Mai Daftedar");
+MODULE_LICENSE("Dual BSD/GPL");
+
+
+struct net_device *NMI_WFI_devs[2];
+
+/*
+* Transmitter lockup simulation, normally disabled.
+*/
+static int lockup = 0;
+module_param(lockup, int, 0);
+
+static int timeout = NMI_WFI_TIMEOUT;
+module_param(timeout, int, 0);
+
+/*
+* Do we run in NAPI mode?
+*/
+static int use_napi = 0;
+module_param(use_napi, int, 0);
+
+
+/*
+* A structure representing an in-flight packet.
+*/
+struct NMI_WFI_packet {
+ struct NMI_WFI_packet *next;
+ struct net_device *dev;
+ int datalen;
+ u8 data[ETH_DATA_LEN];
+};
+
+
+
+int pool_size = 8;
+module_param(pool_size, int, 0);
+
+
+static void NMI_WFI_TxTimeout(struct net_device *dev);
+static void (*NMI_WFI_Interrupt)(int, void *, struct pt_regs *);
+
+/**
+* @brief NMI_WFI_SetupPool
+* @details Set up a device's packet pool.
+* @param[in] struct net_device *dev : Network Device Pointer
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+ void NMI_WFI_SetupPool(struct net_device *dev)
+ {
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ int i;
+ struct NMI_WFI_packet *pkt;
+
+ priv->ppool = NULL;
+ for (i = 0; i < pool_size; i++) {
+ pkt = kmalloc (sizeof (struct NMI_WFI_packet), GFP_KERNEL);
+ if (pkt == NULL) {
+ printk (KERN_NOTICE "Ran out of memory allocating packet pool\n");
+ return;
+ }
+ pkt->dev = dev;
+ pkt->next = priv->ppool;
+ priv->ppool = pkt;
+ }
+ }
+
+/**
+* @brief NMI_WFI_TearDownPool
+* @details Internal cleanup function that's called after the network device
+ driver is unregistered
+* @param[in] struct net_device *dev : Network Device Driver
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_TearDownPool(struct net_device *dev)
+ {
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ struct NMI_WFI_packet *pkt;
+
+ while ((pkt = priv->ppool)) {
+ priv->ppool = pkt->next;
+ kfree (pkt);
+ /* FIXME - in-flight packets ? */
+ }
+ }
+
+/**
+* @brief NMI_WFI_GetTxBuffer
+* @details Buffer/pool management
+* @param[in] net_device *dev : Network Device Driver Structure
+* @return struct NMI_WFI_packet
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+ struct NMI_WFI_packet *NMI_WFI_GetTxBuffer(struct net_device *dev)
+ {
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+ struct NMI_WFI_packet *pkt;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ pkt = priv->ppool;
+ priv->ppool = pkt->next;
+ if (priv->ppool == NULL) {
+ printk (KERN_INFO "Pool empty\n");
+ netif_stop_queue(dev);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return pkt;
+ }
+/**
+* @brief NMI_WFI_ReleaseBuffer
+* @details Buffer/pool management
+* @param[in] NMI_WFI_packet *pkt : Structure holding in-flight packet
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_ReleaseBuffer(struct NMI_WFI_packet *pkt)
+{
+ unsigned long flags;
+ struct NMI_WFI_priv *priv = netdev_priv(pkt->dev);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ pkt->next = priv->ppool;
+ priv->ppool = pkt;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ if (netif_queue_stopped(pkt->dev) && pkt->next == NULL)
+ netif_wake_queue(pkt->dev);
+}
+
+/**
+* @brief NMI_WFI_EnqueueBuf
+* @details Enqueuing packets in an RX buffer queue
+* @param[in] NMI_WFI_packet *pkt : Structure holding in-flight packet
+* @param[in] net_device *dev : Network Device Driver Structure
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_EnqueueBuf(struct net_device *dev, struct NMI_WFI_packet *pkt)
+{
+ unsigned long flags;
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ pkt->next = priv->rx_queue; /* FIXME - misorders packets */
+ priv->rx_queue = pkt;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+/**
+* @brief NMI_WFI_DequeueBuf
+* @details Dequeuing packets from the RX buffer queue
+* @param[in] net_device *dev : Network Device Driver Structure
+* @return NMI_WFI_packet *pkt : Structure holding in-flight pac
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+struct NMI_WFI_packet *NMI_WFI_DequeueBuf(struct net_device *dev)
+{
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ struct NMI_WFI_packet *pkt;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ pkt = priv->rx_queue;
+ if (pkt != NULL)
+ priv->rx_queue = pkt->next;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return pkt;
+ }
+/**
+* @brief NMI_WFI_RxInts
+* @details Enable and disable receive interrupts.
+* @param[in] net_device *dev : Network Device Driver Structure
+* @param[in] enable : Enable/Disable flag
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static void NMI_WFI_RxInts(struct net_device *dev, int enable)
+{
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ priv->rx_int_enabled = enable;
+}
+
+/**
+* @brief NMI_WFI_Open
+* @details Open Network Device Driver, called when the network
+ interface is opened. It starts the interface's transmit queue.
+* @param[in] net_device *dev : Network Device Driver Structure
+* @param[in] enable : Enable/Disable flag
+* @return int : Returns 0 upon success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Open(struct net_device *dev)
+{
+ /* request_region(), request_irq(), .... (like fops->open) */
+ /*
+ * Assign the hardware address of the board: use "\0SNULx", where
+ * x is 0 or 1. The first byte is '\0' to avoid being a multicast
+ * address (the first byte of multicast addrs is odd).
+ */
+ memcpy(dev->dev_addr, "\0WLAN0", ETH_ALEN);
+ if (dev == NMI_WFI_devs[1])
+ dev->dev_addr[ETH_ALEN-1]++; /* \0SNUL1 */
+
+ NMI_WFI_InitHostInt(dev);
+ netif_start_queue(dev);
+ return 0;
+}
+/**
+* @brief NMI_WFI_Release
+* @details Release Network Device Driver, called when the network
+ interface is stopped or brought down. This function marks
+ the network driver as not being able to transmit
+* @param[in] net_device *dev : Network Device Driver Structure
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Release(struct net_device *dev)
+{
+ /* release ports, irq and such -- like fops->close */
+
+ netif_stop_queue(dev); /* can't transmit any more */
+
+ return 0;
+ }
+/**
+* @brief NMI_WFI_Config
+* @details Configuration changes (passed on by ifconfig)
+* @param[in] net_device *dev : Network Device Driver Structure
+* @param[in] struct ifmap *map : Contains the ioctl implementation for the
+ network driver.
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Config(struct net_device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP) /* can't act on a running interface */
+ return -EBUSY;
+
+ /* Don't allow changing the I/O address */
+ if (map->base_addr != dev->base_addr) {
+ printk(KERN_WARNING "NMI_WFI: Can't change I/O address\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* Allow changing the IRQ */
+ if (map->irq != dev->irq) {
+ dev->irq = map->irq;
+ /* request_irq() is delayed to open-time */
+ }
+
+ /* ignore other fields */
+ return 0;
+}
+/**
+* @brief NMI_WFI_Rx
+* @details Receive a packet: retrieve, encapsulate and pass over to upper
+ levels
+* @param[in] net_device *dev : Network Device Driver Structure
+* @param[in] NMI_WFI_packet :
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_Rx(struct net_device *dev, struct NMI_WFI_packet *pkt)
+{
+ int i;
+ struct sk_buff *skb;
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ s8 rssi;
+ /*
+ * The packet has been retrieved from the transmission
+ * medium. Build an skb around it, so upper layers can handle it
+ */
+
+
+ skb = dev_alloc_skb(pkt->datalen + 2);
+ if (!skb) {
+ if (printk_ratelimit())
+ printk(KERN_NOTICE "NMI_WFI rx: low on mem - packet dropped\n");
+ priv->stats.rx_dropped++;
+ goto out;
+ }
+ skb_reserve(skb, 2); /* align IP on 16B boundary */
+ memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);
+
+ if(priv->monitor_flag)
+ {
+ PRINT_INFO(RX_DBG,"In monitor device name %s\n", dev->name);
+ priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy);
+ printk("VALUE PASSED IN OF HRWD %p\n", priv->hNMIWFIDrv);
+ // host_int_get_rssi(priv->hNMIWFIDrv, &(rssi));
+ // NMI_PRINTF("RSSI value is %d\n", rssi);
+ if(INFO)
+ {
+ for (i=14 ; i<skb->len; i++)
+ PRINT_INFO(RX_DBG,"RXdata[%d] %02x\n",i,skb->data[i]);
+ }
+ NMI_WFI_monitor_rx(dev, skb);
+ return;
+ }
+#if 0
+ NMI_PRINTF("In RX NORMAl Device name %s\n", dev->name);
+ /* Write metadata, and then pass to the receive level */
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
+ NMI_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy ,pkt->datalen,NMI_WFI_RX_PKT);
+ netif_rx(skb);
+#endif
+out:
+ return;
+}
+
+/**
+* @brief NMI_WFI_Poll
+* @details The poll implementation
+* @param[in] struct napi_struct *napi :
+* @param[in] int budget :
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static int NMI_WFI_Poll(struct napi_struct *napi, int budget)
+{
+ int npackets = 0;
+ struct sk_buff *skb;
+ struct NMI_WFI_priv *priv = container_of(napi, struct NMI_WFI_priv, napi);
+ struct net_device *dev = priv->dev;
+ struct NMI_WFI_packet *pkt;
+
+ while (npackets < budget && priv->rx_queue) {
+ pkt = NMI_WFI_DequeueBuf(dev);
+ skb = dev_alloc_skb(pkt->datalen + 2);
+ if (! skb) {
+ if (printk_ratelimit())
+ printk(KERN_NOTICE "NMI_WFI: packet dropped\n");
+ priv->stats.rx_dropped++;
+ NMI_WFI_ReleaseBuffer(pkt);
+ continue;
+ }
+ skb_reserve(skb, 2); /* align IP on 16B boundary */
+ memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
+ netif_receive_skb(skb);
+ /* Maintain stats */
+ npackets++;
+ NMI_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy,pkt->datalen,NMI_WFI_RX_PKT);
+ NMI_WFI_ReleaseBuffer(pkt);
+ }
+ /* If we processed all packets, we're done; tell the kernel and re-enable ints */
+ if (npackets < budget) {
+ napi_complete(napi);
+ NMI_WFI_RxInts(dev, 1);
+ }
+ return npackets;
+ }
+
+/**
+* @brief NMI_WFI_Poll
+* @details The typical interrupt entry point
+* @param[in] struct napi_struct *napi :
+* @param[in] int budget :
+* @return int : Return 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static void NMI_WFI_RegularInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int statusword;
+ struct NMI_WFI_priv *priv;
+ struct NMI_WFI_packet *pkt = NULL;
+ /*
+ * As usual, check the "device" pointer to be sure it is
+ * really interrupting.
+ * Then assign "struct device *dev"
+ */
+ struct net_device *dev = (struct net_device *)dev_id;
+ /* ... and check with hw if it's really ours */
+
+ /* paranoid */
+ if (!dev)
+ return;
+
+ /* Lock the device */
+ priv = netdev_priv(dev);
+ spin_lock(&priv->lock);
+
+ /* retrieve statusword: real netdevices use I/O instructions */
+ statusword = priv->status;
+ priv->status = 0;
+ if (statusword & NMI_WFI_RX_INTR) {
+ /* send it to NMI_WFI_rx for handling */
+ pkt = priv->rx_queue;
+ if (pkt) {
+ priv->rx_queue = pkt->next;
+ NMI_WFI_Rx(dev, pkt);
+ }
+ }
+ if (statusword & NMI_WFI_TX_INTR) {
+ /* a transmission is over: free the skb */
+ NMI_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy,priv->tx_packetlen,NMI_WFI_TX_PKT);
+ dev_kfree_skb(priv->skb);
+ }
+
+ /* Unlock the device and we are done */
+ spin_unlock(&priv->lock);
+ if (pkt) NMI_WFI_ReleaseBuffer(pkt); /* Do this outside the lock! */
+ return;
+}
+/**
+* @brief NMI_WFI_NapiInterrupt
+* @details A NAPI interrupt handler
+* @param[in] irq:
+* @param[in] dev_id:
+* @param[in] pt_regs:
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+static void NMI_WFI_NapiInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int statusword;
+ struct NMI_WFI_priv *priv;
+
+ /*
+ * As usual, check the "device" pointer for shared handlers.
+ * Then assign "struct device *dev"
+ */
+ struct net_device *dev = (struct net_device *)dev_id;
+ /* ... and check with hw if it's really ours */
+
+ /* paranoid */
+ if (!dev)
+ return;
+
+ /* Lock the device */
+ priv = netdev_priv(dev);
+ spin_lock(&priv->lock);
+
+ /* retrieve statusword: real netdevices use I/O instructions */
+ statusword = priv->status;
+ priv->status = 0;
+ if (statusword & NMI_WFI_RX_INTR) {
+ NMI_WFI_RxInts(dev, 0); /* Disable further interrupts */
+ napi_schedule(&priv->napi);
+ }
+ if (statusword & NMI_WFI_TX_INTR) {
+ /* a transmission is over: free the skb */
+
+ NMI_WFI_update_stats(priv->dev->ieee80211_ptr->wiphy,priv->tx_packetlen,NMI_WFI_TX_PKT);
+ dev_kfree_skb(priv->skb);
+ }
+
+ /* Unlock the device and we are done */
+ spin_unlock(&priv->lock);
+ return;
+}
+
+/**
+* @brief MI_WFI_HwTx
+* @details Transmit a packet (low level interface)
+* @param[in] buf:
+* @param[in] len:
+* @param[in] net_device *dev:
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+ void NMI_WFI_HwTx(char *buf, int len, struct net_device *dev)
+{
+ /*
+ * This function deals with hw details. This interface loops
+ * back the packet to the other NMI_WFI interface (if any).
+ * In other words, this function implements the NMI_WFI behaviour,
+ * while all other procedures are rather device-independent
+ */
+ struct iphdr *ih;
+ struct net_device *dest;
+ struct NMI_WFI_priv *priv;
+ u32 *saddr, *daddr;
+ struct NMI_WFI_packet *tx_buffer;
+
+
+ /* I am paranoid. Ain't I? */
+ if (len < sizeof(struct ethhdr) + sizeof(struct iphdr)) {
+ printk("NMI_WFI: Hmm... packet too short (%i octets)\n",
+ len);
+ return;
+ }
+
+ if (0) { /* enable this conditional to look at the data */
+ int i;
+ printk("len is %i",len);
+ for (i=14 ; i<len; i++)
+ printk("TXdata[%d] %02x\n",i,buf[i]&0xff);
+ // printk("\n");
+ }
+ /*
+ * Ethhdr is 14 bytes, but the kernel arranges for iphdr
+ * to be aligned (i.e., ethhdr is unaligned)
+ */
+ ih = (struct iphdr *)(buf+sizeof(struct ethhdr));
+ saddr = &ih->saddr;
+ daddr = &ih->daddr;
+
+ ((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */
+ ((u8 *)daddr)[2] ^= 1;
+
+ ih->check = 0; /* and rebuild the checksum (ip needs it) */
+ ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);
+
+
+ if (dev == NMI_WFI_devs[0])
+ PDEBUGG("%08x:%05i --> %08x:%05i\n",
+ ntohl(ih->saddr),ntohs(((struct tcphdr *)(ih+1))->source),
+ ntohl(ih->daddr),ntohs(((struct tcphdr *)(ih+1))->dest));
+ else
+ PDEBUGG("%08x:%05i <-- %08x:%05i\n",
+ ntohl(ih->daddr),ntohs(((struct tcphdr *)(ih+1))->dest),
+ ntohl(ih->saddr),ntohs(((struct tcphdr *)(ih+1))->source));
+
+ /*
+ * Ok, now the packet is ready for transmission: first simulate a
+ * receive interrupt on the twin device, then a
+ * transmission-done on the transmitting device
+ */
+ dest = NMI_WFI_devs[dev == NMI_WFI_devs[0] ? 1 : 0];
+ priv = netdev_priv(dest);
+
+ tx_buffer = NMI_WFI_GetTxBuffer(dev);
+ tx_buffer->datalen = len;
+ memcpy(tx_buffer->data, buf, len);
+ NMI_WFI_EnqueueBuf(dest, tx_buffer);
+ if (priv->rx_int_enabled) {
+ priv->status |= NMI_WFI_RX_INTR;
+ NMI_WFI_Interrupt(0, dest, NULL);
+ }
+
+ priv = netdev_priv(dev);
+ priv->tx_packetlen = len;
+ priv->tx_packetdata = buf;
+ priv->status |= NMI_WFI_TX_INTR;
+ if (lockup && ((priv->stats.tx_packets + 1) % lockup) == 0) {
+ /* Simulate a dropped transmit interrupt */
+ netif_stop_queue(dev);
+ PDEBUG("Simulate lockup at %ld, txp %ld\n", jiffies,
+ (unsigned long) priv->stats.tx_packets);
+ }
+ else
+ NMI_WFI_Interrupt(0, dev, NULL);
+
+}
+
+/**
+* @brief NMI_WFI_Tx
+* @details Transmit a packet (called by the kernel)
+* @param[in] sk_buff *skb:
+* @param[in] net_device *dev:
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Tx(struct sk_buff *skb, struct net_device *dev)
+{
+ int len;
+ char *data, shortpkt[ETH_ZLEN];
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+
+ // priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy);
+
+ // if(priv->monitor_flag)
+ // mac80211_hwsim_monitor_rx(skb);
+
+
+ data = skb->data;
+ len = skb->len;
+
+ if (len < ETH_ZLEN) {
+ memset(shortpkt, 0, ETH_ZLEN);
+ memcpy(shortpkt, skb->data, skb->len);
+ len = ETH_ZLEN;
+ data = shortpkt;
+ }
+ dev->trans_start = jiffies; /* save the timestamp */
+
+ /* Remember the skb, so we can free it at interrupt time */
+ priv->skb = skb;
+
+ /* actual deliver of data is device-specific, and not shown here */
+ NMI_WFI_HwTx(data, len, dev);
+
+ return 0; /* Our simple device can not fail */
+ }
+
+/**
+* @brief NMI_WFI_TxTimeout
+* @details Deal with a transmit timeout.
+* @param[in] net_device *dev:
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_TxTimeout(struct net_device *dev)
+{
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+
+ PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies,
+ jiffies - dev->trans_start);
+ /* Simulate a transmission interrupt to get things moving */
+ priv->status = NMI_WFI_TX_INTR;
+ NMI_WFI_Interrupt(0, dev, NULL);
+ priv->stats.tx_errors++;
+ netif_wake_queue(dev);
+ return;
+}
+
+/**
+* @brief NMI_WFI_Ioctl
+* @details Ioctl commands
+* @param[in] net_device *dev:
+* @param[in] ifreq *rq
+* @param[in] cmd:
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ PDEBUG("ioctl\n");
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_Stat
+* @details Return statistics to the caller
+* @param[in] net_device *dev:
+* @return NMI_WFI_Stats : Return net_device_stats stucture with the
+ network device driver private data contents.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+struct net_device_stats *NMI_WFI_Stats(struct net_device *dev)
+{
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ return &priv->stats;
+}
+
+/**
+* @brief NMI_WFI_RebuildHeader
+* @details This function is called to fill up an eth header, since arp is not
+* available on the interface
+* @param[in] sk_buff *skb:
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_RebuildHeader(struct sk_buff *skb)
+{
+ struct ethhdr *eth = (struct ethhdr *) skb->data;
+ struct net_device *dev = skb->dev;
+
+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+ memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
+ eth->h_dest[ETH_ALEN-1] ^= 0x01; /* dest is us xor 1 */
+ return 0;
+}
+/**
+* @brief NMI_WFI_RebuildHeader
+* @details This function is called to fill up an eth header, since arp is not
+* available on the interface
+* @param[in] sk_buff *skb:
+* @param[in] struct net_device *dev:
+* @param[in] unsigned short type:
+* @param[in] const void *saddr,
+* @param[in] const void *daddr:
+* @param[in] unsigned int len
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_Header(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type, const void *daddr, const void *saddr,
+ unsigned int len)
+{
+ struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);
+
+ eth->h_proto = htons(type);
+ memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len);
+ memcpy(eth->h_dest, daddr ? daddr : dev->dev_addr, dev->addr_len);
+ eth->h_dest[ETH_ALEN-1] ^= 0x01; /* dest is us xor 1 */
+ return (dev->hard_header_len);
+}
+
+/**
+* @brief NMI_WFI_ChangeMtu
+* @details The "change_mtu" method is usually not needed.
+* If you need it, it must be like this.
+* @param[in] net_device *dev : Network Device Driver Structure
+* @param[in] new_mtu :
+* @return int : Returns 0 on Success.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_ChangeMtu(struct net_device *dev, int new_mtu)
+{
+ unsigned long flags;
+ struct NMI_WFI_priv *priv = netdev_priv(dev);
+ spinlock_t *lock = &priv->lock;
+
+ /* check ranges */
+ if ((new_mtu < 68) || (new_mtu > 1500))
+ return -EINVAL;
+ /*
+ * Do anything you need, and the accept the value
+ */
+ spin_lock_irqsave(lock, flags);
+ dev->mtu = new_mtu;
+ spin_unlock_irqrestore(lock, flags);
+ return 0; /* success */
+}
+
+static const struct header_ops NMI_WFI_header_ops = {
+ .create = NMI_WFI_Header,
+ .rebuild = NMI_WFI_RebuildHeader,
+ .cache = NULL, /* disable caching */
+};
+
+
+static const struct net_device_ops NMI_WFI_netdev_ops = {
+ .ndo_open = NMI_WFI_Open,
+ .ndo_stop = NMI_WFI_Release,
+ .ndo_set_config = NMI_WFI_Config,
+ .ndo_start_xmit = NMI_WFI_Tx,
+ .ndo_do_ioctl = NMI_WFI_Ioctl,
+ .ndo_get_stats = NMI_WFI_Stats,
+ .ndo_change_mtu = NMI_WFI_ChangeMtu,
+ .ndo_tx_timeout = NMI_WFI_TxTimeout,
+ };
+
+/**
+* @brief NMI_WFI_Init
+* @details The init function (sometimes called probe).
+* It is invoked by register_netdev()
+* @param[in] net_device *dev:
+* @return NONE
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+void NMI_WFI_Init(struct net_device *dev)
+{
+ struct NMI_WFI_priv *priv;
+
+
+ /*
+ * Then, assign other fields in dev, using ether_setup() and some
+ * hand assignments
+ */
+ ether_setup(dev); /* assign some of the fields */
+ //1- Allocate space
+
+ dev->netdev_ops = &NMI_WFI_netdev_ops;
+ dev->header_ops = &NMI_WFI_header_ops;
+ dev->watchdog_timeo = timeout;
+ /* keep the default flags, just add NOARP */
+ dev->flags |= IFF_NOARP;
+ dev->features |= NETIF_F_NO_CSUM;
+ /*
+ * Then, initialize the priv field. This encloses the statistics
+ * and a few private fields.
+ */
+ priv = netdev_priv(dev);
+ memset(priv, 0, sizeof(struct NMI_WFI_priv));
+ priv->dev = dev;
+ netif_napi_add(dev, &priv->napi, NMI_WFI_Poll, 2);
+ /* The last parameter above is the NAPI "weight". */
+ spin_lock_init(&priv->lock);
+ NMI_WFI_RxInts(dev, 1); /* enable receive interrupts */
+ NMI_WFI_SetupPool(dev);
+ }
+
+/**
+* @brief NMI_WFI_Stat
+* @details Return statistics to the caller
+* @param[in] net_device *dev:
+* @return NMI_WFI_Stats : Return net_device_stats stucture with the
+ network device driver private data contents.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+
+void NMI_WFI_Cleanup(void)
+{
+ int i;
+ struct NMI_WFI_priv *priv[2];
+
+ /*if(hwsim_mon!=NULL)
+ {
+ printk("Freeing monitor interface\n");
+ unregister_netdev(hwsim_mon);
+ free_netdev(hwsim_mon);
+ }*/
+ for (i = 0; i < 2;i++)
+ {
+ priv[i] = netdev_priv(NMI_WFI_devs[i]);
+
+ if (NMI_WFI_devs[i])
+ {
+ NMI_PRINTF("Unregistering\n");
+ unregister_netdev(NMI_WFI_devs[i]);
+ NMI_WFI_TearDownPool(NMI_WFI_devs[i]);
+ free_netdev(NMI_WFI_devs[i]);
+ NMI_PRINTF("[NETDEV]Stopping interface\n");
+ NMI_WFI_DeInitHostInt(NMI_WFI_devs[i]);
+ NMI_WFI_WiphyFree(NMI_WFI_devs[i]);
+ }
+
+ }
+ //unregister_netdev(hwsim_mon);
+ NMI_WFI_deinit_mon_interface();
+ return;
+}
+
+
+void StartConfigSim(void);
+
+
+
+
+
+
+
+/**
+* @brief NMI_WFI_Stat
+* @details Return statistics to the caller
+* @param[in] net_device *dev:
+* @return NMI_WFI_Stats : Return net_device_stats stucture with the
+ network device driver private data contents.
+* @author mdaftedar
+* @date 01 MAR 2012
+* @version 1.0
+*/
+int NMI_WFI_InitModule(void)
+{
+
+ int result, i, ret = -ENOMEM;
+ struct NMI_WFI_priv *priv[2],*netpriv;
+ struct wireless_dev *wdev;
+ NMI_WFI_Interrupt = use_napi ? NMI_WFI_NapiInterrupt : NMI_WFI_RegularInterrupt;
+ char buf[IFNAMSIZ];
+
+ for (i = 0; i < 2; i++)
+ {
+
+ /* Allocate the net devices */
+ NMI_WFI_devs[i] = alloc_netdev(sizeof(struct NMI_WFI_priv), "wlan%d",
+ NMI_WFI_Init);
+ if(NMI_WFI_devs[i] == NULL)
+ goto out;
+ //priv[i] = netdev_priv(NMI_WFI_devs[i]);
+
+ wdev = NMI_WFI_WiphyRegister(NMI_WFI_devs[i]);
+ NMI_WFI_devs[i]->ieee80211_ptr = wdev;
+ netpriv = netdev_priv(NMI_WFI_devs[i]);
+ netpriv->dev->ieee80211_ptr = wdev;
+ netpriv->dev->ml_priv = netpriv;
+ wdev->netdev = netpriv->dev;
+
+ /*Registering the net device*/
+ if ((result = register_netdev(NMI_WFI_devs[i])))
+ printk("NMI_WFI: error %i registering device \"%s\"\n",
+ result, NMI_WFI_devs[i]->name);
+ else
+ ret = 0;
+ }
+
+
+ /*init NMi driver */
+ priv[0] = netdev_priv(NMI_WFI_devs[0]);
+ priv[1] = netdev_priv(NMI_WFI_devs[1]);
+ //printk("Net dev handler in int %lu\n",&priv[0]->hNMIWFIDrv);
+
+ if(priv[1]->dev->ieee80211_ptr->wiphy->interface_modes && BIT(NL80211_IFTYPE_MONITOR) )
+ {
+ //snprintf(buf, IFNAMSIZ, "mon.%s", priv[1]->dev->name);
+ // printk("Initializing mon interface %s\n", buf);
+ // NMI_WFI_init_mon_interface();
+ // priv[1]->monitor_flag = 1;
+
+ }
+ priv[0]->bCfgScanning = NMI_FALSE;
+ priv[0]->u32RcvdChCount = 0;
+
+ NMI_memset(priv[0]->au8AssociatedBss, 0xFF, ETH_ALEN);
+
+
+ //ret = host_int_init(&priv[0]->hNMIWFIDrv);
+ /*copy handle to the other driver*/
+ //priv[1]->hNMIWFIDrv = priv[0]->hNMIWFIDrv;
+ if(ret)
+ {
+ NMI_PRINTF("Error Init Driver\n");
+ }
+
+
+ out:
+ if (ret)
+ NMI_WFI_Cleanup();
+ return ret;
+
+
+}
+
+
+module_init(NMI_WFI_InitModule);
+module_exit(NMI_WFI_Cleanup);
+
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_mon.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_mon.c
new file mode 100755
index 00000000..6a846d24
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_mon.c
@@ -0,0 +1,693 @@
+/*!
+* @file linux_mon.c
+* @brief File Operations OS wrapper functionality
+* @author mdaftedar
+* @sa NMI_WFI_NetDevice.h
+* @date 01 MAR 2012
+* @version 1.0
+*/
+
+#ifndef SIMULATION
+#include "NMI_WFI_CfgOperations.h"
+#include "linux_wlan_common.h"
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+#endif
+#ifdef NMI_FULLY_HOSTING_AP
+#include "NMI_host_AP.h"
+#endif
+#ifdef NMI_AP_EXTERNAL_MLME
+#ifdef SIMULATION
+#include "NMI_WFI_CfgOperations.h"
+#endif
+struct nmi_wfi_radiotap_hdr {
+ struct ieee80211_radiotap_header hdr;
+ u8 rate;
+ // u32 channel;
+}__attribute__((packed));
+struct nmi_wfi_radiotap_cb_hdr {
+ struct ieee80211_radiotap_header hdr;
+ u8 rate;
+ u8 dump;
+ u16 tx_flags;
+ // u32 channel;
+}__attribute__((packed));
+
+extern linux_wlan_t* g_linux_wlan;
+
+static struct net_device *nmi_wfi_mon = NULL; /* global monitor netdev */
+
+#ifdef SIMULATION
+extern int NMI_WFI_Tx(struct sk_buff *skb, struct net_device *dev);
+#elif USE_WIRELESS
+extern int mac_xmit(struct sk_buff *skb, struct net_device *dev);
+#endif
+
+
+NMI_Uint8 srcAdd[6];
+NMI_Uint8 bssid[6];
+NMI_Uint8 broadcast[] = {0xff,0xff,0xff,0xff,0xff,0xff};
+/**
+* @brief NMI_WFI_monitor_rx
+* @details
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 12 JUL 2012
+* @version 1.0
+*/
+
+#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
+#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/
+#define IS_MANAGMEMENT 0x100
+#define IS_MANAGMEMENT_CALLBACK 0x080
+#define IS_MGMT_STATUS_SUCCES 0x040
+#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
+
+void NMI_WFI_monitor_rx(uint8_t *buff, uint32_t size)
+{
+ uint32_t header,pkt_offset;
+ struct sk_buff *skb = NULL;
+ struct nmi_wfi_radiotap_hdr *hdr;
+ struct nmi_wfi_radiotap_cb_hdr *cb_hdr;
+
+ PRINT_INFO(HOSTAPD_DBG,"In monitor interface receive function\n");
+
+ // struct NMI_WFI_priv *priv = netdev_priv(dev);
+
+ // priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy);
+
+ /* Bug 4601 */
+ if(nmi_wfi_mon == NULL)
+ return;
+
+ if (!netif_running(nmi_wfi_mon))
+ {
+ PRINT_INFO(HOSTAPD_DBG,"Monitor interface already RUNNING\n");
+ return;
+ }
+
+ //Get NMI header
+ memcpy(&header, (buff-HOST_HDR_OFFSET), HOST_HDR_OFFSET);
+
+ //The packet offset field conain info about what type of managment frame
+ // we are dealing with and ack status
+ pkt_offset = GET_PKT_OFFSET(header);
+
+ if(pkt_offset & IS_MANAGMEMENT_CALLBACK)
+ {
+
+ // hostapd callback mgmt frame
+
+ //if(INFO || buff[0] == 0x10 || buff[0] == 0xb0)
+ //PRINT_D(HOSTAPD_DBG,"In monitor interface callback receive function\n");
+
+
+ skb = dev_alloc_skb(size+sizeof(struct nmi_wfi_radiotap_cb_hdr));
+ if(skb == NULL)
+ {
+ PRINT_INFO(HOSTAPD_DBG,"Monitor if : No memory to allocate skb");
+ return;
+ }
+
+ memcpy(skb_put(skb,size),buff, size);
+
+ cb_hdr = (struct nmi_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr));
+ memset(cb_hdr, 0, sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION;
+
+ cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_present = cpu_to_le32(
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+
+ cb_hdr->rate = 5;//txrate->bitrate / 5;
+
+ if(pkt_offset & IS_MGMT_STATUS_SUCCES)
+ {
+ //success
+ cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS;
+ }
+ else
+ {
+ cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL;
+ }
+
+ }
+ else
+ {
+
+ // normal mgmt frame
+
+ //if(INFO || buff[0] == 0x00 || buff[0] == 0xb0)
+ // {
+ //PRINT_D(HOSTAPD_DBG,"In monitor interface receive function , length = %d\n",size);
+ //for(i=0;i<size;i++)
+ //PRINT_D(HOSTAPD_DBG,"Mon RxData[%d] = %02x\n",i,buff[i]);
+ // }
+
+
+ skb = dev_alloc_skb(size+sizeof(struct nmi_wfi_radiotap_hdr));
+
+ if(skb == NULL)
+ {
+ PRINT_INFO(HOSTAPD_DBG,"Monitor if : No memory to allocate skb");
+ return;
+ }
+
+ //skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC);
+ //if (skb == NULL)
+ // return;
+
+ memcpy(skb_put(skb,size),buff, size);
+ //printk("--radiotap header--\n",sizeof(*hdr));
+ hdr = (struct nmi_wfi_radiotap_hdr *) skb_push(skb, sizeof(*hdr));
+ memset(hdr, 0, sizeof(struct nmi_wfi_radiotap_hdr));
+ hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION;
+ //hdr->hdr.it_pad = 0;
+ hdr->hdr.it_len = cpu_to_le16(sizeof(struct nmi_wfi_radiotap_hdr));
+ PRINT_INFO(HOSTAPD_DBG,"Radiotap len %d\n", hdr->hdr.it_len);
+ hdr->hdr.it_present = cpu_to_le32
+ (1 << IEEE80211_RADIOTAP_RATE); //|
+ //(1 << IEEE80211_RADIOTAP_CHANNEL));
+ PRINT_INFO(HOSTAPD_DBG,"Presentflags %d\n", hdr->hdr.it_present);
+ hdr->rate = 5;//txrate->bitrate / 5;
+
+ }
+
+/* if(INFO || if(skb->data[9] == 0x00 || skb->data[9] == 0xb0))
+ {
+ for(i=0;i<skb->len;i++)
+ PRINT_INFO(HOSTAPD_DBG,"Mon RxData[%d] = %02x\n",i,skb->data[i]);
+ }*/
+
+
+ skb->dev = nmi_wfi_mon;
+ skb_set_mac_header(skb, 0);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ memset(skb->cb, 0, sizeof(skb->cb));
+
+ netif_rx(skb);
+
+
+}
+
+struct tx_complete_mon_data{
+ int size;
+ void* buff;
+};
+
+static void mgmt_tx_complete(void* priv, int status){
+
+ //struct sk_buff *skb2;
+ //struct nmi_wfi_radiotap_cb_hdr *cb_hdr;
+
+ struct tx_complete_mon_data* pv_data = (struct tx_complete_mon_data*)priv;
+ NMI_Uint8 * buf= pv_data->buff;
+
+
+
+ if(status == 1){
+ if(INFO || buf[0] == 0x10 || buf[0] == 0xb0)
+ PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",pv_data->size,pv_data->buff);
+ }else{
+ PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",pv_data->size,pv_data->buff);
+ }
+
+
+/* //(skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 )
+ {
+ skb2 = dev_alloc_skb(pv_data->size+sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ memcpy(skb_put(skb2,pv_data->size),pv_data->buff, pv_data->size);
+
+ cb_hdr = (struct nmi_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr));
+ memset(cb_hdr, 0, sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION;
+
+ cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_present = cpu_to_le32(
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+
+ cb_hdr->rate = 5;//txrate->bitrate / 5;
+ cb_hdr->tx_flags = 0x0004;
+
+ skb2->dev = nmi_wfi_mon;
+ skb_set_mac_header(skb2, 0);
+ skb2->ip_summed = CHECKSUM_UNNECESSARY;
+ skb2->pkt_type = PACKET_OTHERHOST;
+ skb2->protocol = htons(ETH_P_802_2);
+ memset(skb2->cb, 0, sizeof(skb2->cb));
+
+ netif_rx(skb2);
+ }*/
+
+ /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */
+ #ifndef NMI_FULLY_HOSTING_AP
+ kfree(pv_data->buff);
+
+ kfree(pv_data);
+ #endif
+}
+static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len)
+{
+ linux_wlan_t* nic;
+ struct tx_complete_mon_data *mgmt_tx =NULL;
+
+ if(dev == NULL)
+ {
+ PRINT_D(HOSTAPD_DBG,"ERROR: dev == NULL\n");
+ return NMI_FAIL;
+ }
+ nic =netdev_priv(dev);
+
+ //NMI_PRINTF("--IN mon_mgmt_tx--\n");
+ netif_stop_queue(dev);
+ mgmt_tx = (struct tx_complete_mon_data*)kmalloc(sizeof(struct tx_complete_mon_data),GFP_ATOMIC);
+ if(mgmt_tx == NULL){
+ PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
+ return NMI_FAIL;
+ }
+
+ #ifdef NMI_FULLY_HOSTING_AP
+ // add space for the pointer to tx_complete_mon_data
+ len+=sizeof(struct tx_complete_mon_data*);
+ #endif
+
+ mgmt_tx->buff= (char*)kmalloc(len,GFP_ATOMIC);
+ if(mgmt_tx->buff == NULL)
+ {
+ PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
+ return NMI_FAIL;
+
+ }
+
+ mgmt_tx->size=len;
+
+ #ifndef NMI_FULLY_HOSTING_AP
+ memcpy(mgmt_tx->buff,buf,len);
+ #else
+ //printk("sizeof(struct tx_complete_mon_data*) = %d\n",sizeof(struct tx_complete_mon_data*));
+ //printk("len = %d, mgmt_tx=%x\n",len,mgmt_tx);
+ memcpy(mgmt_tx->buff,buf,len-sizeof(struct tx_complete_mon_data*));
+ memcpy((mgmt_tx->buff)+(len-sizeof(struct tx_complete_mon_data*)),&mgmt_tx,sizeof(struct tx_complete_mon_data*));
+
+ // filter data frames to handle it's PS
+ if(filter_monitor_data_frames((mgmt_tx->buff),len)== NMI_TRUE)
+ {
+ return;
+ }
+
+ #endif //NMI_FULLY_HOSTING_AP
+
+ //printk("--IN mon_mgmt_tx: Sending MGMT Pkt to tx queue--\n");
+ g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx,mgmt_tx->buff,mgmt_tx->size,mgmt_tx_complete);
+
+ netif_wake_queue(dev);
+ return 0;
+}
+
+/**
+* @brief NMI_WFI_mon_xmit
+* @details
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 12 JUL 2012
+* @version 1.0
+*/
+static netdev_tx_t NMI_WFI_mon_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct ieee80211_radiotap_header *rtap_hdr;
+ NMI_Uint32 rtap_len,i,ret=0;
+ struct NMI_WFI_mon_priv *mon_priv ;
+
+ struct sk_buff *skb2;
+ struct nmi_wfi_radiotap_cb_hdr *cb_hdr;
+
+ //PRINT_D(HOSTAPD_DBG,"Monitor xmit function b4\n");
+ /* Bug 4601 */
+ if(nmi_wfi_mon == NULL)
+ return NMI_FAIL;
+
+ //if(skb->data[3] == 0x10 || skb->data[3] == 0xb0)
+ //PRINT_D(HOSTAPD_DBG,"Monitor xmit function\n");
+
+
+
+ mon_priv = netdev_priv(nmi_wfi_mon);
+
+ if(mon_priv== NULL)
+ {
+ PRINT_ER("Monitor interface private structure is NULL\n");
+ return NMI_FAIL;
+ }
+
+ rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
+
+ rtap_len = ieee80211_get_radiotap_len(skb->data);
+ if (skb->len < rtap_len)
+ {
+ PRINT_ER("Error in radiotap header\n");
+ return -1;
+ }
+ /* skip the radiotap header */
+ PRINT_INFO(HOSTAPD_DBG,"Radiotap len: %d\n", rtap_len);
+ //if(INFO)
+
+ if(INFO)
+ {
+ for(i=0; i<rtap_len ; i++)
+ PRINT_INFO(HOSTAPD_DBG,"Radiotap_hdr[%d] %02x\n",i,skb->data[i]);
+ }
+ /* Skip the ratio tap header */
+ skb_pull(skb, rtap_len);
+
+ if( skb->data[0] == 0xc0 &&(!(memcmp(broadcast, &skb->data[4],6) )) )
+ {
+ skb2 = dev_alloc_skb(skb->len+sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ memcpy(skb_put(skb2,skb->len),skb->data, skb->len);
+
+ cb_hdr = (struct nmi_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr));
+ memset(cb_hdr, 0, sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION;
+
+ cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_present = cpu_to_le32(
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+
+ cb_hdr->rate = 5;//txrate->bitrate / 5;
+ cb_hdr->tx_flags = 0x0004;
+
+ skb2->dev = nmi_wfi_mon;
+ skb_set_mac_header(skb2, 0);
+ skb2->ip_summed = CHECKSUM_UNNECESSARY;
+ skb2->pkt_type = PACKET_OTHERHOST;
+ skb2->protocol = htons(ETH_P_802_2);
+ memset(skb2->cb, 0, sizeof(skb2->cb));
+
+ netif_rx(skb2);
+
+ return 0;
+ }
+ skb->dev = mon_priv->real_ndev;
+
+ PRINT_INFO(HOSTAPD_DBG,"Skipping the radiotap header\n");
+
+
+
+ /* actual deliver of data is device-specific, and not shown here */
+ PRINT_INFO(HOSTAPD_DBG,"SKB netdevice name = %s\n", skb->dev->name);
+ PRINT_INFO(HOSTAPD_DBG,"MONITOR real dev name = %s\n", mon_priv->real_ndev->name);
+
+ #ifdef SIMULATION
+ ret = NMI_WFI_Tx(skb,mon_priv->real_ndev);
+ #elif USE_WIRELESS
+ //Identify if Ethernet or MAC header (data or mgmt)
+ memcpy(srcAdd,& skb->data[11],6);
+ //NMI_PRINTF("SRC/BSSID\n");
+ memcpy(bssid, &skb->data[17],6);
+ //if source address and bssid fields are equal>>Mac header
+ /*send it to mgmt frames handler */
+ if(!(memcmp(srcAdd,bssid,6)))
+ {
+ //NMI_PRINTF("--MGMT PKT in mon_xmit--\n");
+ mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len);
+ dev_kfree_skb(skb);
+ }
+ else
+ ret = mac_xmit(skb,mon_priv->real_ndev);
+ #endif
+
+ //return NETDEV_TX_OK;
+ return ret;
+}
+
+static const struct net_device_ops nmi_wfi_netdev_ops = {
+ .ndo_start_xmit = NMI_WFI_mon_xmit,
+
+};
+
+#ifdef NMI_FULLY_HOSTING_AP
+/*
+* @brief NMI_mgm_HOSTAPD_ACK
+* @details report the status of transmitted mgmt frames to HOSTAPD
+* @param[in] priv : pointer to tx_complete_mon_data struct
+* bStatus : status of transmission
+* @author Abd Al-Rahman Diab
+* @date 9 May 2013
+* @version 1.0
+*/
+void NMI_mgm_HOSTAPD_ACK(void* priv, NMI_Bool bStatus)
+{
+ struct sk_buff *skb;
+ struct nmi_wfi_radiotap_cb_hdr *cb_hdr;
+
+ struct tx_complete_mon_data* pv_data = (struct tx_complete_mon_data*)priv;
+ NMI_Uint8 * buf= pv_data->buff;
+
+ // len of the original frame without the added pointer at the tail
+ NMI_Uint16 u16len = (pv_data->size) - sizeof(struct tx_complete_mon_data*);
+
+
+ /*if(bStatus == 1){
+ if(INFO || buf[0] == 0x10 || buf[0] == 0xb0)
+ PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",u16len,pv_data->buff);
+ }else{
+ PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",u16len,pv_data->buff);
+ }
+ */
+
+ //(skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 )
+ {
+ skb = dev_alloc_skb(u16len+sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ memcpy(skb_put(skb,u16len),pv_data->buff, u16len);
+
+ cb_hdr = (struct nmi_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr));
+ memset(cb_hdr, 0, sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION;
+
+ cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct nmi_wfi_radiotap_cb_hdr));
+
+ cb_hdr->hdr.it_present = cpu_to_le32(
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+
+ cb_hdr->rate = 5;//txrate->bitrate / 5;
+
+
+ if(NMI_TRUE == bStatus)
+ {
+ //success
+ cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS;
+ }
+ else
+ {
+ cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL;
+ }
+
+ skb->dev = nmi_wfi_mon;
+ skb_set_mac_header(skb, 0);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ memset(skb->cb, 0, sizeof(skb->cb));
+
+ netif_rx(skb);
+ }
+
+ /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */
+ kfree(pv_data->buff);
+
+ kfree(pv_data);
+
+}
+#endif //NMI_FULLY_HOSTING_AP
+
+/**
+* @brief NMI_WFI_mon_setup
+* @details
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 12 JUL 2012
+* @version 1.0
+*/
+static void NMI_WFI_mon_setup(struct net_device *dev)
+{
+
+ dev->netdev_ops = &nmi_wfi_netdev_ops;
+ // dev->destructor = free_netdev;
+ PRINT_INFO(CORECONFIG_DBG,"In Ethernet setup function\n");
+ ether_setup(dev);
+ dev->tx_queue_len = 0;
+ dev->type = ARPHRD_IEEE80211_RADIOTAP;
+ memset(dev->dev_addr, 0, ETH_ALEN);
+
+ #ifdef USE_WIRELESS
+ {
+ // u8 * mac_add;
+ unsigned char mac_add[] = {0x00,0x50,0xc2,0x5e,0x10,0x8f};
+ // priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy);
+ // mac_add = (NMI_Uint8*)NMI_MALLOC(ETH_ALEN);
+ //status = host_int_get_MacAddress(priv->hNMIWFIDrv,mac_add);
+ //mac_add[ETH_ALEN-1]+=1;
+ memcpy(dev->dev_addr, mac_add, ETH_ALEN);
+ }
+ #else
+ dev->dev_addr[0] = 0x12;
+ #endif
+
+}
+
+/**
+* @brief NMI_WFI_init_mon_interface
+* @details
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 12 JUL 2012
+* @version 1.0
+*/
+struct net_device * NMI_WFI_init_mon_interface(char *name , struct net_device *real_dev )
+ {
+
+
+ NMI_Uint32 ret = NMI_SUCCESS;
+ struct NMI_WFI_mon_priv *priv ;
+
+ /*If monitor interface is already initialized, return it*/
+ if (nmi_wfi_mon)
+ {
+ return nmi_wfi_mon;
+ }
+#if 0
+ nmi_wfi_mon = alloc_netdev(sizeof(struct NMI_WFI_mon_priv), name, NMI_WFI_mon_setup);
+ if (nmi_wfi_mon == NULL)
+ {
+ PRINT_ER("Failed to allocate netdevice\n");
+ goto failed;
+ }
+
+ //rtnl_lock();
+ PRINT_INFO(HOSTAPD_DBG,"Monitor interface name %s\n", nmi_wfi_mon->name);
+
+
+ ret = dev_alloc_name(nmi_wfi_mon, nmi_wfi_mon->name);
+ if (ret < 0)
+ goto failed_mon;
+
+
+ priv = netdev_priv(nmi_wfi_mon);
+ if(priv== NULL)
+ {
+ PRINT_ER("private structure is NULL\n");
+ return NMI_FAIL;
+ }
+
+ priv->real_ndev = real_dev;
+
+
+ ret = register_netdevice(nmi_wfi_mon);
+
+
+ if (ret < 0)
+ {
+ PRINT_ER("Failed to register netdevice\n");
+ goto failed_mon;
+ }
+
+
+ return NMI_SUCCESS;
+ // rtnl_unlock();
+
+ failed:
+ return ret;
+
+ failed_mon:
+ //rtnl_unlock();
+ free_netdev(nmi_wfi_mon);
+ return ret;
+#endif
+
+ nmi_wfi_mon = alloc_etherdev(sizeof(struct NMI_WFI_mon_priv));
+ if (!nmi_wfi_mon) {
+ PRINT_ER("failed to allocate memory\n");
+ return NULL;
+
+ }
+
+ nmi_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP;
+ strncpy(nmi_wfi_mon->name, name, IFNAMSIZ);
+ nmi_wfi_mon->name[IFNAMSIZ - 1] = 0;
+ nmi_wfi_mon->netdev_ops = &nmi_wfi_netdev_ops;
+
+ ret = register_netdevice(nmi_wfi_mon);
+ if (ret) {
+ PRINT_ER(" register_netdevice failed (%d)\n", ret);
+ return NULL;
+ }
+ priv = netdev_priv(nmi_wfi_mon);
+ if(priv== NULL)
+ {
+ PRINT_ER("private structure is NULL\n");
+ return NULL;
+ }
+
+ priv->real_ndev = real_dev;
+
+ return nmi_wfi_mon;
+}
+
+/**
+* @brief NMI_WFI_deinit_mon_interface
+* @details
+* @param[in]
+* @return int : Return 0 on Success
+* @author mdaftedar
+* @date 12 JUL 2012
+* @version 1.0
+*/
+int NMI_WFI_deinit_mon_interface()
+{
+ bool rollback_lock = false;
+
+ if(nmi_wfi_mon != NULL)
+ {
+ PRINT_D(HOSTAPD_DBG,"In Deinit monitor interface\n");
+ PRINT_D(HOSTAPD_DBG,"RTNL is being locked\n");
+ if (rtnl_is_locked())
+ {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ PRINT_D(HOSTAPD_DBG,"Unregister netdev\n");
+ unregister_netdev(nmi_wfi_mon);
+ //NMI_PRINTF("Free Netdev\n");
+ //free_netdev(nmi_wfi_mon);
+
+ if (rollback_lock)
+ {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+ nmi_wfi_mon = NULL;
+ }
+ return NMI_SUCCESS;
+
+}
+#endif // NMI_AP_EXTERNAL_MLME
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan.c
new file mode 100755
index 00000000..a00a4247
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan.c
@@ -0,0 +1,3332 @@
+#ifndef SIMULATION
+#include "NMI_WFI_CfgOperations.h"
+#include "linux_wlan_common.h"
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+#ifdef USE_WIRELESS
+#include "NMI_WFI_CfgOperations.h"
+#endif
+
+#include "linux_wlan_common.h"
+
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#ifndef PLAT_ALLWINNER_A10 // tony
+#include <asm/gpio.h>
+#endif
+#include <linux/kthread.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+#include <linux/inetdevice.h>
+#endif
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+
+#include <linux/version.h>
+#include <linux/semaphore.h>
+
+#ifdef NMI_SDIO
+#include "linux_wlan_sdio.h"
+#else
+#include "linux_wlan_spi.h"
+#endif
+
+#ifdef NMI_FULLY_HOSTING_AP
+#include "NMI_host_AP.h"
+#endif
+
+#include "svnrevision.h"
+#ifdef FW_VERSION_VERIFICATION
+#include "verify_fw_version.c"
+#endif
+
+#ifdef STATIC_MACADDRESS//brandy_0724 [[
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+struct task_struct* nmi_mac_thread;
+unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2};
+#endif //brandy_0724 ]]
+
+#if defined(PLAT_AML8726_M3)
+ #include <mach/gpio.h>
+ #include <mach/gpio_data.h>
+ #include <mach/pinmux.h>
+
+ extern void extern_wifi_set_enable(int is_on);
+ extern void sdio_reinit(void);
+
+ #define _linux_wlan_device_power_on() extern_wifi_set_enable(1)
+ #define _linux_wlan_device_power_off() extern_wifi_set_enable(0)
+
+ #define _linux_wlan_device_detection() sdio_reinit()
+ #define _linux_wlan_device_removal() ;
+
+ static int _available_irq_ready = 0; //[[ johnny : because of dummy irq
+
+#elif defined(PLAT_ALLWINNER_A10)
+ extern void mmc_pm_power(int mode, int* updown);
+ extern void sunximmc_rescan_card(unsigned id, unsigned insert);
+ extern int mmc_pm_get_io_val(char* name);
+ extern int mmc_pm_gpio_ctrl(char* name, int level);
+
+ #define NMC1000_SDIO_CARD_ID 0
+ int nmc1000_power_val = 0;
+
+ #define _linux_wlan_device_power_on() { nmc1000_power_val = 1; mmc_pm_power(NMC1000_SDIO_CARD_ID,&nmc1000_power_val); }
+ #define _linux_wlan_device_power_off() { nmc1000_power_val = 0; mmc_pm_power(NMC1000_SDIO_CARD_ID,&nmc1000_power_val); }
+
+ #define _linux_wlan_device_detection() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,1)
+ #define _linux_wlan_device_removal() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,0)
+
+#elif defined(PLAT_ALLWINNER_A20)
+ extern void sw_mci_rescan_card(unsigned id, unsigned insert);
+ extern void wifi_pm_power(int on); // tony to keep allwinner's rule
+ #define NMC1000_SDIO_CARD_ID 3
+
+ #define _linux_wlan_device_power_on() wifi_pm_power(1)
+ #define _linux_wlan_device_power_off() wifi_pm_power(0)
+
+ #define _linux_wlan_device_detection() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,1)
+ #define _linux_wlan_device_removal() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,0)
+
+#elif defined(PLAT_ALLWINNER_A23)
+ extern void sunxi_mci_rescan_card(unsigned id, unsigned insert);
+ extern void wifi_pm_power(int on);
+ #define NMC1000_SDIO_CARD_ID 1
+
+ #define _linux_wlan_device_power_on() wifi_pm_power(1)
+ #define _linux_wlan_device_power_off() wifi_pm_power(0)
+
+ #define _linux_wlan_device_detection() sunxi_mci_rescan_card(NMC1000_SDIO_CARD_ID,1)
+ #define _linux_wlan_device_removal() sunxi_mci_rescan_card(NMC1000_SDIO_CARD_ID,0)
+
+#elif defined(PLAT_ALLWINNER_A31)
+ extern void sw_mci_rescan_card(unsigned id, unsigned insert);
+ extern void wifi_pm_power(int on);
+ #define NMC1000_SDIO_CARD_ID 1
+
+ #define _linux_wlan_device_power_on() wifi_pm_power(1)
+ #define _linux_wlan_device_power_off() wifi_pm_power(0)
+
+ #define _linux_wlan_device_detection() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,1)
+ #define _linux_wlan_device_removal() sw_mci_rescan_card(NMC1000_SDIO_CARD_ID,0)
+
+#elif defined(PLAT_WMS8304) // added by rachel
+ #include "nmi_custom_gpio.c"
+
+ #define _linux_wlan_device_power_on() NmiWifiCardPower(1)
+ #define _linux_wlan_device_power_off() NmiWifiCardPower(0)
+
+#elif defined(PLAT_WM8880)
+ #include "nmi_wm8880_gpio.c"
+
+ #include <linux/wireless.h> // simon, rachel
+ #include <mach/irqs.h>
+ #include <linux/mmc/sdio.h>
+ #include <mach/hardware.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+
+ /*simulate virtual sdio card insert and removal*/
+ extern void force_remove_sdio2(void);
+ extern void wmt_detect_sdio2(void);
+ int wmt_nmc1000_intr_num=15; //gpio 15
+
+ #define _linux_wlan_device_power_on() NmiWifiCardPower(1)
+ #define _linux_wlan_device_power_off() NmiWifiCardPower(0)
+
+ #define _linux_wlan_device_detection() wmt_detect_sdio2()
+ #define _linux_wlan_device_removal() force_remove_sdio2()
+
+#elif defined(PLAT_RKXXXX)
+extern int rk29sdk_wifi_power(int on);
+extern int rk29sdk_wifi_set_carddetect(int val);
+#define _linux_wlan_device_power_on() rk29sdk_wifi_power(1)
+#define _linux_wlan_device_power_off() rk29sdk_wifi_power(0)
+#define _linux_wlan_device_detection() rk29sdk_wifi_set_carddetect(1)
+#define _linux_wlan_device_removal() rk29sdk_wifi_set_carddetect(0)
+
+#elif defined(PLAT_CLM9722)
+#define _linux_wlan_device_power_on() {}
+#define _linux_wlan_device_power_off() {}
+
+#define _linux_wlan_device_detection() {}
+#define _linux_wlan_device_removal() {}
+
+#else
+ #define _linux_wlan_device_detection() {}
+ #define _linux_wlan_device_removal() {}
+ #define _linux_wlan_device_power_on() {}
+ #define _linux_wlan_device_power_off() {}
+
+#endif
+
+
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+extern NMI_Bool g_obtainingIP;
+#endif
+
+
+extern NMI_Uint16 Set_machw_change_vir_if(NMI_Bool bValue);
+extern void resolve_disconnect_aberration(void* drvHandler);
+extern NMI_Uint8 gau8MulticastMacAddrList[NMI_MULTICAST_TABLE_SIZE][ETH_ALEN];
+
+static int linux_wlan_device_power(int on_off)
+{
+ PRINT_D(INIT_DBG,"linux_wlan_device_power.. (%d)\n", on_off);
+
+ if ( on_off )
+ {
+ _linux_wlan_device_power_on();
+ }
+ else
+ {
+ _linux_wlan_device_power_off();
+ }
+
+ return 0;
+}
+
+static int linux_wlan_device_detection(int on_off)
+{
+ PRINT_D(INIT_DBG,"linux_wlan_device_detection.. (%d)\n", on_off);
+
+#ifdef NMI_SDIO
+ if ( on_off )
+ {
+ _linux_wlan_device_detection();
+ }
+ else
+ {
+ _linux_wlan_device_removal();
+ }
+#endif
+
+ return 0;
+}
+
+
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr);
+
+static struct notifier_block g_dev_notifier = {
+ .notifier_call = dev_state_ev_handler
+};
+#endif
+
+#define nmi_wlan_deinit(nic) if(&g_linux_wlan->oup != NULL) \
+ if(g_linux_wlan->oup.wlan_cleanup != NULL) \
+ g_linux_wlan->oup.wlan_cleanup()
+
+//[[ johnny : enable to selecte bin file on Makefile
+#ifndef STA_FIRMWARE
+#define STA_FIRMWARE "wifi_firmware.bin"
+#endif
+
+#ifndef AP_FIRMWARE
+#define AP_FIRMWARE "wifi_firmware_ap.bin"
+#endif
+
+#ifndef P2P_CONCURRENCY_FIRMWARE
+#define P2P_CONCURRENCY_FIRMWARE "wifi_firmware_p2p_concurrency.bin"
+#endif
+//]]
+
+// [[ added by tony
+typedef struct android_wifi_priv_cmd {
+ char *buf;
+ int used_len;
+ int total_len;
+} android_wifi_priv_cmd;
+// ]] for wpa supplicant iw
+
+
+#define IRQ_WAIT 1
+#define IRQ_NO_WAIT 0
+ /*
+ to sync between mac_close and module exit.
+ don't initialize or de-initialize from init/deinitlocks
+ to be initialized from module nmc_netdev_init and
+ deinitialized from mdoule_exit
+ */
+static struct semaphore close_exit_sync;
+unsigned int int_rcvdU;
+unsigned int int_rcvdB;
+unsigned int int_clrd;
+
+static int wlan_deinit_locks(linux_wlan_t* nic);
+static void wlan_deinitialize_threads(linux_wlan_t* nic);
+static void linux_wlan_lock(void* vp);
+void linux_wlan_unlock(void* vp);
+extern void NMI_WFI_monitor_rx(uint8_t *buff, uint32_t size);
+extern void NMI_WFI_p2p_rx(struct net_device *dev,uint8_t *buff, uint32_t size);
+
+
+static void* internal_alloc(uint32_t size, uint32_t flag);
+static void linux_wlan_tx_complete(void* priv, int status);
+void frmw_to_linux(uint8_t *buff, uint32_t size,uint32_t pkt_offset);
+static int mac_init_fn(struct net_device *ndev);
+int mac_xmit(struct sk_buff *skb, struct net_device *dev);
+int mac_open(struct net_device *ndev);
+int mac_close(struct net_device *ndev);
+static struct net_device_stats *mac_stats(struct net_device *dev);
+static int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd);
+static void nmi_set_multicast_list(struct net_device *dev);
+
+
+
+ /*
+ for now - in frmw_to_linux there should be private data to be passed to it
+ and this data should be pointer to net device
+ */
+linux_wlan_t* g_linux_wlan = NULL;
+nmi_wlan_oup_t* gpstrWlanOps;
+NMI_Bool bEnablePS = NMI_TRUE;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
+
+static const struct net_device_ops nmc_netdev_ops = {
+ .ndo_init = mac_init_fn,
+ .ndo_open = mac_open,
+ .ndo_stop = mac_close,
+ .ndo_start_xmit = mac_xmit,
+ .ndo_do_ioctl = mac_ioctl,
+ .ndo_get_stats = mac_stats,
+ .ndo_set_rx_mode = nmi_set_multicast_list,
+
+};
+#define nmc_set_netdev_ops(ndev) do { (ndev)->netdev_ops = &nmc_netdev_ops; } while(0)
+
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+
+static const struct net_device_ops nmc_netdev_ops = {
+ .ndo_init = mac_init_fn,
+ .ndo_open = mac_open,
+ .ndo_stop = mac_close,
+ .ndo_start_xmit = mac_xmit,
+ .ndo_do_ioctl = mac_ioctl,
+ .ndo_get_stats = mac_stats,
+ .ndo_set_multicast_list = nmi_set_multicast_list,
+
+};
+
+#define nmc_set_netdev_ops(ndev) do { (ndev)->netdev_ops = &nmc_netdev_ops; } while(0)
+
+#else
+
+static void nmc_set_netdev_ops(struct net_device *ndev)
+{
+
+ ndev->init = mac_init_fn;
+ ndev->open = mac_open;
+ ndev->stop = mac_close;
+ ndev->hard_start_xmit = mac_xmit;
+ ndev->do_ioctl = mac_ioctl;
+ ndev->get_stats = mac_stats;
+ ndev->set_multicast_list = nmi_set_multicast_list,
+}
+
+#endif
+#ifdef DEBUG_MODE
+
+extern volatile int timeNo;
+
+#define DEGUG_BUFFER_LENGTH 1000
+volatile int WatchDogdebuggerCounter=0;
+char DebugBuffer[DEGUG_BUFFER_LENGTH+20]={0};
+static char * ps8current=DebugBuffer;
+
+
+
+void printk_later(const char * format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ ps8current += vsprintf (ps8current,format, args);
+ va_end (args);
+ if((ps8current-DebugBuffer)>DEGUG_BUFFER_LENGTH)
+ {
+ ps8current=DebugBuffer;
+ }
+
+}
+
+
+void dump_logs()
+{
+ if(DebugBuffer[0])
+ {
+ DebugBuffer[DEGUG_BUFFER_LENGTH]=0;
+ printk("early printed\n");
+ printk(ps8current+1);
+ ps8current[1]=0;
+ printk("latest printed\n");
+ printk(DebugBuffer);
+ DebugBuffer[0]=0;
+ ps8current=DebugBuffer;
+ }
+}
+
+void Reset_WatchDogdebugger()
+{
+ WatchDogdebuggerCounter=0;
+}
+
+static int DebuggingThreadTask(void* vp)
+{
+ while(1){
+ while(!WatchDogdebuggerCounter)
+ {
+ printk("Debug Thread Running %d\n",timeNo);
+ WatchDogdebuggerCounter=1;
+ msleep(10000);
+ }
+ dump_logs();
+ WatchDogdebuggerCounter=0;
+ }
+}
+
+
+#endif
+
+
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr;
+ struct NMI_WFI_priv* priv;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ struct net_device * dev;
+ NMI_Uint8 *pIP_Add_buff;
+ NMI_Sint32 s32status = NMI_FAIL;
+ perInterface_wlan_t* nic;
+ NMI_Uint8 null_ip[4]={0};
+ char wlan_dev_name[5]="wlan0";
+
+ if(dev_iface == NULL)
+ {
+ NMI_PRINTF("dev_iface = NULL\n");
+ return NOTIFY_DONE;
+ }
+
+ dev = (struct net_device *)dev_iface->ifa_dev->dev;
+ priv= wiphy_priv(dev->ieee80211_ptr->wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+ nic = netdev_priv(dev);
+
+ printk("dev_state_ev_handler +++\n"); // tony
+
+ if( (memcmp(dev_iface->ifa_label , "wlan0", 5) ) &&( memcmp(dev_iface->ifa_label , "p2p0", 4) ) )
+ {
+ PRINT_D(GENERIC_DBG,"Interface is neither WLAN0 nor P2P0\n");
+ return NOTIFY_DONE;
+ }
+
+ if(pstrWFIDrv == NULL)
+ {
+ PRINT_ER("Driver handler = NULL !\n");
+ }
+
+ switch (event) {
+
+ case NETDEV_UP:
+ printk("dev_state_ev_handler event=NETDEV_UP %p\n",dev); // tony
+
+ printk("\n ============== IP Address Obtained ===============\n\n");
+
+
+ /*If we are in station mode or client mode*/
+ if(nic->iftype==STATION_MODE||nic->iftype==CLIENT_MODE)
+ {
+ g_obtainingIP=NMI_FALSE;
+ PRINT_D(GENERIC_DBG,"IP obtained , enable scan\n");
+ }
+
+
+
+ if(bEnablePS == NMI_TRUE)
+ host_int_set_power_mgmt((NMI_WFIDrvHandle)pstrWFIDrv, 1, 0);
+
+ PRINT_D(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label);
+
+ pIP_Add_buff = (char *) (&(dev_iface->ifa_address));
+ printk("IP add=%d:%d:%d:%d \n",pIP_Add_buff[0],pIP_Add_buff[1],pIP_Add_buff[2],pIP_Add_buff[3]);
+ s32status = host_int_setup_ipaddress((NMI_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
+
+ break;
+
+ case NETDEV_DOWN:
+ printk("dev_state_ev_handler event=NETDEV_DOWN %p\n",dev); // tony
+
+ printk("\n ============== IP Address Released ===============\n\n");
+ if(nic->iftype==STATION_MODE||nic->iftype==CLIENT_MODE)
+ {
+ g_obtainingIP=NMI_FALSE;
+ }
+
+ if(memcmp(dev_iface->ifa_label , wlan_dev_name, 5) == 0)
+ host_int_set_power_mgmt((NMI_WFIDrvHandle)pstrWFIDrv, 0, 0);
+
+ resolve_disconnect_aberration(pstrWFIDrv);
+
+
+ PRINT_D(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label);
+
+ pIP_Add_buff = null_ip;
+ printk("IP add=%d:%d:%d:%d \n",pIP_Add_buff[0],pIP_Add_buff[1],pIP_Add_buff[2],pIP_Add_buff[3]);
+ s32status = host_int_setup_ipaddress((NMI_WFIDrvHandle)pstrWFIDrv, pIP_Add_buff, nic->u8IfIdx);
+
+ break;
+
+ default:
+ printk("dev_state_ev_handler event=default\n"); // tony
+ PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event);
+
+ break;
+ }
+
+ return NOTIFY_DONE;
+
+}
+#endif
+
+/*
+ * Interrupt initialization and handling functions
+ */
+
+void linux_wlan_enable_irq(void){
+
+#if (RX_BH_TYPE != RX_BH_THREADED_IRQ)
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ PRINT_D(INT_DBG,"Enabling IRQ ...\n");
+
+ #if defined(PLAT_WMS8304) // added by rachel
+ //enable_irq(nic->dev_irq_num);
+ /*clean corresponding int status bit, or it will generate int continuously for ever*/
+ gpio_clean_irq_status_any(&gpio_irq_ctrl);
+
+ enable_irq(g_linux_wlan->dev_irq_num);
+
+ /*we should reopen this gpio pin int in order to capture the future/comming interruption*/
+ enable_gpio_int_any(&gpio_irq_ctrl, INT_EN);
+ #elif defined(PLAT_WM8880)
+
+ wmt_gpio_ack_irq(wmt_nmc1000_intr_num);
+ wmt_gpio_unmask_irq(wmt_nmc1000_intr_num);
+
+ #else
+ enable_irq(g_linux_wlan->dev_irq_num);
+ #endif
+
+#endif
+#endif
+}
+
+void linux_wlan_disable_irq(int wait){
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ if(wait) {
+ PRINT_D(INT_DBG,"Disabling IRQ ...\n");
+ #if defined(PLAT_WM8880)
+ wmt_gpio_mask_irq(wmt_nmc1000_intr_num);
+ #else
+ disable_irq(g_linux_wlan->dev_irq_num);
+ #endif
+ } else {
+ PRINT_D(INT_DBG,"Disabling IRQ ...\n");
+ #if defined(PLAT_WM8880)
+ wmt_gpio_mask_irq(wmt_nmc1000_intr_num);
+ #else
+ disable_irq_nosync(g_linux_wlan->dev_irq_num);
+ #endif
+ }
+#endif
+}
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+static irqreturn_t isr_uh_routine(int irq, void* user_data){
+
+#if defined(PLAT_WMS8304)
+ int pin_state;
+ //printk("isr_uh_routine\n");
+ /*if this gpio pin int is not enable or int status bit is not toggled, it is not our interruption*/
+ if(!gpio_irq_isEnable_any(&gpio_irq_ctrl) || !gpio_irq_state_any(&gpio_irq_ctrl))
+ return IRQ_NONE;
+
+ /*be here, be sure that this int is myself, but we should disable int before handler this interruption*/
+ enable_gpio_int_any(&gpio_irq_ctrl, INT_DIS);
+
+ /*get value on gpin int pin*/
+ pin_state = gpio_get_value_any(&gpio_irq_ctrl);
+
+ if(pin_state == 0) {
+ //printk("wlan int\n");
+ //dont_deinit_irq = 0;
+ }
+ else
+ {
+ //printk("this is fake interruption!!\n");
+ enable_gpio_int_any(&gpio_irq_ctrl, INT_EN);
+ return IRQ_HANDLED;
+ }
+#elif defined(PLAT_WM8880)
+
+ if(!is_gpio_irqenable(wmt_nmc1000_intr_num) || !gpio_irqstatus(wmt_nmc1000_intr_num))
+ return IRQ_NONE;
+
+ wmt_gpio_mask_irq(wmt_nmc1000_intr_num);
+
+#endif
+
+ int_rcvdU++;
+ PRINT_D(INT_DBG,"Interrupt received UH\n");
+#if (RX_BH_TYPE != RX_BH_THREADED_IRQ)
+ linux_wlan_disable_irq(IRQ_NO_WAIT);
+#endif
+
+#if defined(PLAT_AML8726_M3)//[[ johnny : because of dummy irq
+ if ( _available_irq_ready == 0 )
+ {
+ linux_wlan_enable_irq();
+ PRINT_D(GENERIC_DBG,"johnny test : recevied dummy irq\n");
+ return IRQ_HANDLED;
+ }
+#endif//]]
+
+ /*While mac is closing cacncel the handling of any interrupts received*/
+ if(g_linux_wlan->close)
+ {
+ PRINT_ER("Driver is CLOSING: Can't handle UH interrupt\n");
+ #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+ return IRQ_HANDLED;
+ #else
+ return IRQ_NONE;
+ #endif
+
+ }
+#if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
+ schedule_work(&g_linux_wlan->rx_work_queue);
+ return IRQ_HANDLED;
+#elif (RX_BH_TYPE == RX_BH_KTHREAD)
+ linux_wlan_unlock(&g_linux_wlan->rx_sem);
+ return IRQ_HANDLED;
+#elif (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+ return IRQ_WAKE_THREAD;
+#endif
+
+}
+#endif
+
+#if (RX_BH_TYPE == RX_BH_WORK_QUEUE || RX_BH_TYPE == RX_BH_THREADED_IRQ)
+
+#if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+irqreturn_t isr_bh_routine(int irq, void *userdata){
+ linux_wlan_t* nic;
+ nic = (linux_wlan_t*)userdata;
+#else
+static void isr_bh_routine(struct work_struct *work){
+ perInterface_wlan_t* nic;
+ nic = (perInterface_wlan_t*)container_of(work,linux_wlan_t,rx_work_queue);
+#endif
+
+ /*While mac is closing cacncel the handling of any interrupts received*/
+ if(g_linux_wlan->close)
+ {
+ PRINT_ER("Driver is CLOSING: Can't handle BH interrupt\n");
+ #if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+ return IRQ_HANDLED;
+ #else
+ return;
+ #endif
+
+
+
+ }
+
+ int_rcvdB++;
+ PRINT_D(INT_DBG,"Interrupt received BH\n");
+ if(g_linux_wlan->oup.wlan_handle_rx_isr != 0){
+ g_linux_wlan->oup.wlan_handle_rx_isr();
+ }else{
+ PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n");
+ }
+
+
+#if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+ return IRQ_HANDLED;
+#endif
+}
+#elif (RX_BH_TYPE == RX_BH_KTHREAD)
+static int isr_bh_routine(void *vp)
+{
+ linux_wlan_t* nic;
+
+ nic = (linux_wlan_t*)vp;
+
+ while(1) {
+ linux_wlan_lock(&nic->rx_sem);
+ if (g_linux_wlan->close){
+
+ while(!kthread_should_stop())
+ schedule();
+
+ break;
+ }
+ int_rcvdB++;
+ PRINT_D(INT_DBG,"Interrupt received BH\n");
+ if(g_linux_wlan->oup.wlan_handle_rx_isr != 0){
+ g_linux_wlan->oup.wlan_handle_rx_isr();
+ } else{
+ PRINT_ER("wlan_handle_rx_isr() hasn't been initialized\n");
+ }
+ }
+
+ return 0;
+}
+#endif
+
+
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+static int init_irq(linux_wlan_t* p_nic){
+ int ret = 0;
+ linux_wlan_t *nic = p_nic;
+
+#if defined(PLAT_AML8726_M3) //johnny add
+ nic->dev_irq_num = INT_GPIO_4; // <== skyworth //'100' value for onda vi30 platform
+
+ ret = request_irq(nic->dev_irq_num, isr_uh_routine, IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
+ "NMC_IRQ", nic);
+
+ if (ret < 0) {
+ PRINT_ER("Failed to request IRQ for GPIO: %d\n",nic->dev_irq_num);
+ }
+
+#elif defined (PLAT_WMS8304) //simon
+ //system("rmmod /system/modules/3.0.8-default/kpad.ko");
+ irq_gpio_init();
+ nic->dev_irq_num = IRQ_GPIO; //(5) gpio_irq_ctrl;
+ printk("%s\n",__FUNCTION__);
+ ret = request_irq(nic->dev_irq_num, isr_uh_routine, IRQF_SHARED,
+ "NMC_IRQ", nic);
+
+ if (ret < 0) {
+ PRINT_ER("Failed to request IRQ for GPIO: %d\n",nic->dev_irq_num);
+ }
+
+ enable_gpio_int_any(&gpio_irq_ctrl,INT_EN);
+
+#elif defined(PLAT_WM8880)
+
+ printk("%s\n",__FUNCTION__);
+ wmt_gpio_setpull(wmt_nmc1000_intr_num,WMT_GPIO_PULL_UP);
+ wmt_gpio_mask_irq(wmt_nmc1000_intr_num);
+ wmt_gpio_ack_irq(wmt_nmc1000_intr_num);
+
+
+ nic->dev_irq_num = IRQ_GPIO;
+ ret = request_irq(nic->dev_irq_num, isr_uh_routine, IRQF_SHARED,
+ "NMC_IRQ", nic);
+
+ if (ret < 0) {
+ PRINT_ER("Failed to request IRQ for GPIO: %d\n",nic->dev_irq_num);
+ }
+
+ /*clear int status register before enable this int pin*/
+ wmt_gpio_ack_irq(wmt_nmc1000_intr_num);
+ /*enable this int pin*/
+ wmt_gpio_unmask_irq(wmt_nmc1000_intr_num);
+
+#elif defined (PLAT_RKXXXX)
+ if ((gpio_request(GPIO_NUM, "NMC_INTR") == 0) &&
+ (gpio_direction_input(GPIO_NUM) == 0)) {
+
+ nic->dev_irq_num = gpio_to_irq(GPIO_NUM);
+ ret = request_irq(nic->dev_irq_num, isr_uh_routine, IRQF_TRIGGER_LOW,
+ "NMC_IRQ", nic);
+ PRINT_ER("********%s() IRQ_GPIO, %s\n", __func__, __DATE__);
+ if (ret < 0) {
+ PRINT_ER("Failed to request IRQ for GPIO: %d\n",nic->dev_irq_num);
+ }
+
+ } else {
+ ret = -1;
+ PRINT_ER("could not obtain gpio for NMC_INTR\n");
+ }
+
+
+#else
+ /*initialize GPIO and register IRQ num*/
+ /*GPIO request*/
+ if ((gpio_request(GPIO_NUM, "NMC_INTR") == 0) &&
+ (gpio_direction_input(GPIO_NUM) == 0)) {
+#if defined (NM73131_0_BOARD)
+ g_linux_wlan->dev_irq_num = IRQ_NMC1000;
+#else
+ gpio_export(GPIO_NUM, 1);
+ nic->dev_irq_num = OMAP_GPIO_IRQ(GPIO_NUM);
+ irq_set_irq_type(nic->dev_irq_num, IRQ_TYPE_LEVEL_LOW);
+#endif
+ } else {
+ ret = -1;
+ PRINT_ER("could not obtain gpio for NMC_INTR\n");
+ }
+
+
+#if (RX_BH_TYPE == RX_BH_THREADED_IRQ)
+ if( (ret != -1) && ( request_threaded_irq(g_linux_wlan->dev_irq_num, isr_uh_routine, isr_bh_routine,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT, /*Without IRQF_ONESHOT the uh will remain kicked in and dont gave a chance to bh*/
+ "NMC_IRQ", nic))<0){
+
+#else
+ /*Request IRQ*/
+ if( (ret != -1) && (request_irq(nic->dev_irq_num, isr_uh_routine,
+ IRQF_TRIGGER_LOW, "NMC_IRQ", nic) < 0)){
+
+#endif
+ PRINT_ER("Failed to request IRQ for GPIO: %d\n",GPIO_NUM);
+ ret = -1;
+ }else{
+
+ PRINT_D(INIT_DBG,"IRQ request succeeded IRQ-NUM= %d on GPIO: %d\n",
+ g_linux_wlan->dev_irq_num,GPIO_NUM);
+ }
+
+#endif
+
+ return ret;
+}
+#endif
+
+static void deinit_irq(linux_wlan_t* nic){
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ /* Deintialize IRQ */
+ if(&g_linux_wlan->dev_irq_num != 0){
+ free_irq(g_linux_wlan->dev_irq_num, g_linux_wlan);
+ #if defined(PLAT_AML8726_M3) //johnny
+
+ #elif defined (PLAT_WMS8304)
+ irq_gpio_deinit();
+
+ #elif defined(PLAT_WM8880)
+ /* austin-0720: johnny, let me know why this is empty */
+ #else
+ gpio_free(GPIO_NUM);
+ #endif
+ }
+#endif
+}
+
+
+/*
+ OS functions
+*/
+static void linux_wlan_msleep(uint32_t msc){
+ if(msc <= 4000000)
+ {
+ NMI_Uint32 u32Temp = msc * 1000;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
+ usleep_range(u32Temp, u32Temp);
+#else
+ /* This is delay not sleep !!!, has to be changed*/
+ msleep(msc);
+#endif
+ }
+ else
+ {
+ msleep(msc);
+ }
+}
+
+static void linux_wlan_atomic_msleep(uint32_t msc){
+ mdelay(msc);
+}
+static void linux_wlan_dbg(uint8_t *buff){
+ printk(buff);
+#if defined (NMC_DEBUGFS)
+ kmsgdump_write(buff);
+#endif
+}
+
+static void* linux_wlan_malloc_atomic(uint32_t sz){
+ char* pntr = NULL;
+ pntr = (char*)kmalloc(sz,GFP_ATOMIC );
+ PRINT_D(MEM_DBG,"Allocating %d bytes at address %p\n",sz,pntr);
+ return ((void*)pntr);
+
+}
+static void* linux_wlan_malloc(uint32_t sz){
+ char* pntr = NULL;
+ pntr = (char*)kmalloc(sz,GFP_KERNEL );
+ PRINT_D(MEM_DBG,"Allocating %d bytes at address %p\n",sz,pntr);
+ return ((void*)pntr);
+}
+
+void linux_wlan_free(void* vp){
+ if(vp != NULL){
+ PRINT_D(MEM_DBG,"Freeing %p\n",vp);
+ kfree(vp);
+ }
+}
+
+
+static void* internal_alloc(uint32_t size, uint32_t flag){
+ char* pntr = NULL;
+ pntr = (char*)kmalloc(size,flag);
+ PRINT_D(MEM_DBG,"Allocating %d bytes at address %p\n",size,pntr);
+ return ((void*)pntr);
+}
+
+
+static void linux_wlan_init_lock(char* lockName, void* plock,int count)
+{
+ sema_init((struct semaphore*)plock,count);
+ PRINT_D(LOCK_DBG,"Initializing [%s][%p]\n",lockName,plock);
+
+}
+
+static void linux_wlan_deinit_lock(void* plock)
+{
+ //mutex_destroy((struct mutex*)plock);
+}
+
+static void linux_wlan_lock(void* vp)
+{
+ PRINT_D(LOCK_DBG,"Locking %p\n",vp);
+ if(vp != NULL)
+ {
+ down((struct semaphore*)vp);
+ }
+ else
+ {
+ PRINT_ER("Failed, mutex is NULL\n");
+ }
+}
+
+static int linux_wlan_lock_timeout(void* vp,NMI_Uint32 timeout)
+{
+ int error = -1;
+ PRINT_D(LOCK_DBG,"Locking %p\n",vp);
+ if(vp != NULL)
+ {
+ error = down_timeout((struct semaphore*)vp, msecs_to_jiffies(timeout));
+ }
+ else
+ {
+ PRINT_ER("Failed, mutex is NULL\n");
+ }
+ return error;
+}
+
+void linux_wlan_unlock(void* vp)
+{
+ PRINT_D(LOCK_DBG,"Unlocking %p\n",vp);
+ if(vp != NULL)
+ {
+ up((struct semaphore*)vp);
+ }
+ else
+ {
+ PRINT_ER("Failed, mutex is NULL\n");
+ }
+}
+
+
+static void linux_wlan_init_mutex(char* lockName, void* plock,int count)
+{
+ mutex_init((struct mutex*)plock);
+ PRINT_D(LOCK_DBG,"Initializing mutex [%s][%p]\n",lockName,plock);
+
+}
+
+static void linux_wlan_deinit_mutex(void* plock)
+{
+ mutex_destroy((struct mutex*)plock);
+}
+
+static void linux_wlan_lock_mutex(void* vp)
+{
+ PRINT_D(LOCK_DBG,"Locking mutex %p\n",vp);
+ if(vp != NULL)
+ {
+ /*
+ if(mutex_is_locked((struct mutex*)vp))
+ {
+ //PRINT_ER("Mutex already locked - %p \n",vp);
+ }
+*/
+ mutex_lock((struct mutex*)vp);
+
+ }else
+ {
+ PRINT_ER("Failed, mutex is NULL\n");
+ }
+}
+
+static void linux_wlan_unlock_mutex(void* vp){
+ PRINT_D(LOCK_DBG,"Unlocking mutex %p\n",vp);
+ if(vp != NULL){
+
+ if(mutex_is_locked((struct mutex*)vp)){
+ mutex_unlock((struct mutex*)vp);
+ }else{
+ //PRINT_ER("Mutex already unlocked - %p\n",vp);
+ }
+
+ }else{
+ PRINT_ER("Failed, mutex is NULL\n");
+ }
+}
+
+
+/*Added by Amr - BugID_4720*/
+static void linux_wlan_init_spin_lock(char* lockName, void* plock,int count)
+{
+ spin_lock_init((spinlock_t*)plock);
+ PRINT_D(SPIN_DEBUG,"Initializing mutex [%s][%p]\n",lockName,plock);
+
+}
+
+static void linux_wlan_deinit_spin_lock(void* plock)
+{
+
+}
+static void linux_wlan_spin_lock(void* vp, unsigned long *flags){
+ unsigned long lflags;
+ PRINT_D(SPIN_DEBUG,"Lock spin %p\n",vp);
+ if(vp != NULL){
+ spin_lock_irqsave((spinlock_t*)vp, lflags);
+ *flags = lflags;
+ }
+ else{
+ PRINT_ER("Failed, spin lock is NULL\n");
+ }
+}
+static void linux_wlan_spin_unlock(void* vp, unsigned long *flags){
+ unsigned long lflags= *flags;
+ PRINT_D(SPIN_DEBUG,"Unlock spin %p\n",vp);
+ if(vp != NULL){
+ spin_unlock_irqrestore((spinlock_t*)vp, lflags);
+ *flags = lflags;
+ }
+ else{
+ PRINT_ER("Failed, spin lock is NULL\n");
+ }
+}
+
+static void linux_wlan_mac_indicate(int flag){
+ /*I have to do it that way becuase there is no mean to encapsulate device pointer
+ as a parameter
+ */
+ linux_wlan_t *pd = g_linux_wlan;
+ int status;
+
+ if (flag == NMI_MAC_INDICATE_STATUS) {
+ pd->oup.wlan_cfg_get_value(WID_STATUS, (unsigned char*)&status, 4);
+ if (pd->mac_status == NMI_MAC_STATUS_INIT) {
+ pd->mac_status = status;
+ linux_wlan_unlock(&pd->sync_event);
+ } else {
+ pd->mac_status = status;
+ }
+
+ if (pd->mac_status == NMI_MAC_STATUS_CONNECT) { /* Connect */
+#if 0
+ /**
+ get the mac and bssid address
+ **/
+ PRINT_D(RX_DBG,"Calling cfg_get to get MAC_ADDR\n");
+ pd->oup.wlan_cfg_get(1, WID_MAC_ADDR, 0);
+ PRINT_D(RX_DBG,"Calling cfg_get to get BSSID\n");
+ pd->oup.wlan_cfg_get(0, WID_BSSID, 1);
+
+ /**
+ get the value
+ **/
+ pd->oup.wlan_cfg_get_value(WID_MAC_ADDR, pd->eth_src_address, 6);
+ pd->oup.wlan_cfg_get_value(WID_BSSID, pd->eth_dst_address, 6);
+
+ PRINT_D(GENERIC_DBG,"Source Address = %s",pd->eth_src_address);
+ PRINT_D(GENERIC_DBG,"Destiation Address = %s",pd->eth_dst_address);
+
+ /**
+ launch ndis
+ **/
+#endif
+ }
+
+ } else if (flag == NMI_MAC_INDICATE_SCAN) {
+ PRINT_D(GENERIC_DBG,"Scanning ...\n");
+
+ }
+
+}
+
+struct net_device * GetIfHandler(uint8_t* pMacHeader)
+{
+ uint8_t *Bssid,*Bssid1;
+ int i =0;
+
+ //frmds = ((pMacHeader[1] & 0x02) >> 1);
+ //if(frmds)
+ {
+ Bssid = pMacHeader+10;
+ Bssid1 = pMacHeader+4;
+ }
+ #if 0
+ else
+ {
+ Bssid = pMacHeader+4;
+ DstAddress = pMacHeader+16;
+ }
+ #endif
+
+ for(i=0;i<g_linux_wlan->u8NoIfcs;i++)
+ {
+ if(!memcmp(Bssid1,g_linux_wlan->strInterfaceInfo[i].aBSSID,ETH_ALEN) ||
+ !memcmp(Bssid,g_linux_wlan->strInterfaceInfo[i].aBSSID,ETH_ALEN))
+ {
+ //printk("Ctx [%x]\n",g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ return g_linux_wlan->strInterfaceInfo[i].nmc_netdev;
+ }
+ }
+ printk("Invalide handle\n");
+ for(i=0;i<25;i++)
+ {
+ printk("%02x ",pMacHeader[i]);
+ }
+ Bssid = pMacHeader+18;
+ Bssid1 = pMacHeader+12;
+ for(i=0;i<g_linux_wlan->u8NoIfcs;i++)
+ {
+ if(!memcmp(Bssid1,g_linux_wlan->strInterfaceInfo[i].aBSSID,ETH_ALEN) ||
+ !memcmp(Bssid,g_linux_wlan->strInterfaceInfo[i].aBSSID,ETH_ALEN))
+ {
+ printk("Ctx [%p]\n",g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ return g_linux_wlan->strInterfaceInfo[i].nmc_netdev;
+ }
+ }
+ printk("\n");
+ return NULL;
+}
+
+int linux_wlan_set_bssid(struct net_device * nmc_netdev,uint8_t * pBSSID)
+{
+ int i = 0;
+ int ret = -1;
+ printk("set bssid on[%p]\n",nmc_netdev);
+ for(i=0;i<g_linux_wlan->u8NoIfcs;i++)
+ {
+ if(g_linux_wlan->strInterfaceInfo[i].nmc_netdev == nmc_netdev)
+ {
+ printk("set bssid [%x][%x][%x]\n",pBSSID[0],pBSSID[1],pBSSID[2]);
+ memcpy(g_linux_wlan->strInterfaceInfo[i].aBSSID,pBSSID,6);
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+/*BugID_5213*/
+/*Function to get number of connected interfaces*/
+int linux_wlan_get_num_conn_ifcs(void)
+{
+ uint8_t i = 0;
+ uint8_t null_bssid[6] = {0};
+ uint8_t ret_val = 0;
+
+ for(i=0; i<g_linux_wlan->u8NoIfcs; i++)
+ {
+ if(memcmp(g_linux_wlan->strInterfaceInfo[i].aBSSID, null_bssid, 6))
+ {
+ ret_val++;
+ }
+ }
+ return ret_val;
+}
+
+static int linux_wlan_rxq_task(void* vp){
+
+ /* inform nmc1000_wlan_init that RXQ task is started. */
+ linux_wlan_unlock(&g_linux_wlan->rxq_thread_started);
+ while(1) {
+ linux_wlan_lock(&g_linux_wlan->rxq_event);
+ //wait_for_completion(&g_linux_wlan->rxq_event);
+
+ if (g_linux_wlan->close){
+ /*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */
+ linux_wlan_unlock(&g_linux_wlan->rxq_thread_started);
+
+ while(!kthread_should_stop())
+ schedule();
+
+ PRINT_D(RX_DBG," RX thread stopped\n");
+ break;
+ }
+ PRINT_D(RX_DBG,"Calling wlan_handle_rx_que()\n");
+
+ g_linux_wlan->oup.wlan_handle_rx_que();
+ }
+ return 0;
+}
+
+#define USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
+
+static int linux_wlan_txq_task(void* vp)
+{
+ int ret,txq_count;
+
+#if defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
+#define TX_BACKOFF_WEIGHT_INCR_STEP (1)
+#define TX_BACKOFF_WEIGHT_DECR_STEP (1)
+#define TX_BACKOFF_WEIGHT_MAX (7)
+#define TX_BACKOFF_WEIGHT_MIN (0)
+#define TX_BACKOFF_WEIGHT_UNIT_MS (10)
+ int backoff_weight = TX_BACKOFF_WEIGHT_MIN;
+ signed long timeout;
+#endif
+
+ /* inform nmc1000_wlan_init that TXQ task is started. */
+ linux_wlan_unlock(&g_linux_wlan->txq_thread_started);
+ while(1) {
+
+ PRINT_D(TX_DBG,"txq_task Taking a nap :)\n");
+ linux_wlan_lock(&g_linux_wlan->txq_event);
+ //wait_for_completion(&pd->txq_event);
+ PRINT_D(TX_DBG,"txq_task Who waked me up :$\n");
+
+ if (g_linux_wlan->close){
+ /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */
+ linux_wlan_unlock(&g_linux_wlan->txq_thread_started);
+
+ while(!kthread_should_stop())
+ schedule();
+
+ PRINT_D(TX_DBG,"TX thread stopped\n");
+ break;
+ }
+ PRINT_D(TX_DBG,"txq_task handle the sending packet and let me go to sleep.\n");
+#if !defined USE_TX_BACKOFF_DELAY_IF_NO_BUFFERS
+ g_linux_wlan->oup.wlan_handle_tx_que();
+#else
+ do {
+ ret = g_linux_wlan->oup.wlan_handle_tx_que(&txq_count);
+ if(txq_count < FLOW_CONTROL_LOWER_THRESHOLD/* && netif_queue_stopped(pd->nmc_netdev)*/)
+ {
+ PRINT_D(TX_DBG,"Waking up queue\n");
+ //netif_wake_queue(pd->nmc_netdev);
+ if(netif_queue_stopped(g_linux_wlan->strInterfaceInfo[0].nmc_netdev))
+ netif_wake_queue(g_linux_wlan->strInterfaceInfo[0].nmc_netdev);
+ if(netif_queue_stopped(g_linux_wlan->strInterfaceInfo[1].nmc_netdev))
+ netif_wake_queue(g_linux_wlan->strInterfaceInfo[1].nmc_netdev);
+ }
+
+ if(ret == NMI_TX_ERR_NO_BUF) { /* failed to allocate buffers in chip. */
+ timeout = msecs_to_jiffies(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
+ do {
+ /* Back off from sending packets for some time. */
+ /* schedule_timeout will allow RX task to run and free buffers.*/
+ //set_current_state(TASK_UNINTERRUPTIBLE);
+ //timeout = schedule_timeout(timeout);
+ msleep(TX_BACKOFF_WEIGHT_UNIT_MS << backoff_weight);
+ } while(/*timeout*/0);
+ backoff_weight += TX_BACKOFF_WEIGHT_INCR_STEP;
+ if(backoff_weight > TX_BACKOFF_WEIGHT_MAX) {
+ backoff_weight = TX_BACKOFF_WEIGHT_MAX;
+ }
+ } else {
+ if(backoff_weight > TX_BACKOFF_WEIGHT_MIN) {
+ backoff_weight -= TX_BACKOFF_WEIGHT_DECR_STEP;
+ if(backoff_weight < TX_BACKOFF_WEIGHT_MIN) {
+ backoff_weight = TX_BACKOFF_WEIGHT_MIN;
+ }
+ }
+ }
+ /*TODO: drop packets after a certain time/number of retry count. */
+ } while(ret == NMI_TX_ERR_NO_BUF&&!g_linux_wlan->close); /* retry sending packets if no more buffers in chip. */
+#endif
+ }
+ return 0;
+}
+
+static void linux_wlan_rx_complete(void){
+ PRINT_D(RX_DBG,"RX completed\n");
+}
+
+int linux_wlan_get_firmware(perInterface_wlan_t* p_nic){
+
+ perInterface_wlan_t* nic = p_nic;
+ int ret = 0;
+ const struct firmware* nmc_firmware;
+ char *firmware;
+
+
+ if(nic->iftype == AP_MODE)
+ firmware = AP_FIRMWARE;
+ else if(nic->iftype == STATION_MODE)
+ firmware = STA_FIRMWARE;
+
+ /*BugID_5137*/
+ else
+ {
+ PRINT_D(GENERIC_DBG,"Get P2P_CONCURRENCY_FIRMWARE\n");
+ firmware = P2P_CONCURRENCY_FIRMWARE;
+ }
+
+
+
+ if(nic == NULL){
+ PRINT_ER("NIC is NULL\n");
+ goto _fail_;
+ }
+
+ if(&nic->nmc_netdev->dev == NULL){
+ PRINT_ER("&nic->nmc_netdev->dev is NULL\n");
+ goto _fail_;
+ }
+
+
+ /* the firmare should be located in /lib/firmware in
+ root file system with the name specified above */
+
+#ifdef NMI_SDIO
+ if( request_firmware(&nmc_firmware,firmware, &g_linux_wlan->nmc_sdio_func->dev) != 0){
+ PRINT_ER("%s - firmare not available\n",firmware);
+ ret = -1;
+ goto _fail_;
+ }
+#else
+ if( request_firmware(&nmc_firmware,firmware, &g_linux_wlan->nmc_spidev->dev) != 0){
+ PRINT_ER("%s - firmare not available\n",firmware);
+ ret = -1;
+ goto _fail_;
+ }
+#endif
+ g_linux_wlan->nmc_firmware = nmc_firmware; /* Bug 4703 */
+
+_fail_:
+
+ return ret;
+
+}
+
+#ifdef COMPLEMENT_BOOT
+int repeat_power_cycle(perInterface_wlan_t* nic);
+#endif
+
+static int linux_wlan_start_firmware(perInterface_wlan_t* nic){
+
+ static int timeout = 5;
+ int ret = 0;
+ /* start firmware */
+ PRINT_D(INIT_DBG,"Starting Firmware ...\n");
+ ret = g_linux_wlan->oup.wlan_start();
+ if(ret < 0){
+ PRINT_ER("Failed to start Firmware\n");
+ goto _fail_;
+ }
+#if defined(PLAT_AML8726_M3)//[[ johnny : because of dummy irq
+ _available_irq_ready = 1;
+#endif
+
+ /* wait for mac ready */
+ PRINT_D(INIT_DBG,"Waiting for Firmware to get ready ...\n");
+ if( (ret = linux_wlan_lock_timeout(&g_linux_wlan->sync_event,5000)) )
+ {
+#ifdef COMPLEMENT_BOOT
+ #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
+
+ if(timeout--)
+ {
+ printk("repeat power cycle[%d]",timeout);
+ ret = repeat_power_cycle(nic);
+ }
+ else
+ {
+ timeout = 5;
+ ret = -1;
+ goto _fail_;
+ }
+ #endif
+#endif
+ PRINT_D(INIT_DBG,"Firmware start timed out");
+ goto _fail_;
+ }
+ /*
+ TODO: Driver shouoldn't wait forever for firmware to get started -
+ in case of timeout this should be handled properly
+ */
+ PRINT_D(INIT_DBG,"Firmware successfully started\n");
+
+_fail_:
+ return ret;
+}
+static int linux_wlan_firmware_download(linux_wlan_t* p_nic){
+
+ int ret = 0;
+
+ if(g_linux_wlan->nmc_firmware == NULL){
+ PRINT_ER("Firmware buffer is NULL\n");
+ ret = -ENOBUFS;
+ goto _FAIL_;
+ }
+ /**
+ do the firmware download
+ **/
+ PRINT_D(INIT_DBG,"Downloading Firmware ...\n");
+ ret = g_linux_wlan->oup.wlan_firmware_download(g_linux_wlan->nmc_firmware->data, g_linux_wlan->nmc_firmware->size);
+ if(ret < 0){
+ goto _FAIL_;
+ }
+
+ /* Freeing FW buffer */
+ PRINT_D(INIT_DBG,"Freeing FW buffer ...\n");
+ PRINT_D(GENERIC_DBG,"Releasing firmware\n");
+ release_firmware(g_linux_wlan->nmc_firmware);
+ g_linux_wlan->nmc_firmware = NULL;
+
+ PRINT_D(INIT_DBG,"Download Succeeded \n");
+
+_FAIL_:
+ return ret;
+}
+
+
+/* startup configuration - could be changed later using iconfig*/
+static int linux_wlan_init_test_config(struct net_device *dev, linux_wlan_t* p_nic){
+
+ unsigned char c_val[64];
+ #ifndef STATIC_MACADDRESS
+ unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xff};
+ #endif
+ unsigned int chipid = 0;
+
+ /*BugID_5077*/
+ struct NMI_WFI_priv *priv;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+
+ PRINT_D(TX_DBG,"Start configuring Firmware\n");
+ #ifndef STATIC_MACADDRESS
+ //get_random_bytes(&mac_add[5], 1);
+ #endif
+ priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+ PRINT_D(GENERIC_DBG, "Host = %x\n",(NMI_Uint32)pstrWFIDrv);
+
+ printk("MAC address is : %02x-%02x-%02x-%02x-%02x-%02x\n", mac_add[0],mac_add[1],mac_add[2],mac_add[3],mac_add[4],mac_add[5]);
+ chipid = nmi_get_chipid(0);
+
+
+ if(g_linux_wlan->oup.wlan_cfg_set == NULL)
+ {
+ printk("Null p[ointer\n");
+ goto _fail_;
+ }
+
+ *(int*)c_val = (NMI_Uint32)pstrWFIDrv;
+
+ if (!g_linux_wlan->oup.wlan_cfg_set(1, WID_SET_DRV_HANDLER, c_val, 4, 0,0))
+ goto _fail_;
+
+ /*to tell fw that we are going to use PC test - NMI specific*/
+ c_val[0] = 0;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PC_TEST_MODE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = INFRASTRUCTURE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0,0))
+ goto _fail_;
+
+
+ //c_val[0] = RATE_AUTO; /* bug 4275: Enable autorate and limit it to 24Mbps */
+ c_val[0] = RATE_AUTO;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = G_MIXED_11B_2_MODE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 1;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = G_SHORT_PREAMBLE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = AUTO_PROT;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0,0))
+ goto _fail_;
+
+#ifdef SWITCH_LOG_TERMINAL
+ c_val[0] = AUTO_PROT;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0,0))
+ goto _fail_;
+#endif
+
+ c_val[0] = ACTIVE_SCAN;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = SITE_SURVEY_OFF;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0,0))
+ goto _fail_;
+
+ *((int *)c_val) = 0xffff; /* Never use RTS-CTS */
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0,0))
+ goto _fail_;
+
+ *((int *)c_val) = 2346;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 0,0))
+ goto _fail_;
+
+ /* SSID */
+ /* -------------------------------------------------------------- */
+ /* Configuration : String with length less than 32 bytes */
+ /* Values to set : Any string with length less than 32 bytes */
+ /* ( In BSS Station Set SSID to "" (null string) */
+ /* to enable Broadcast SSID suppport ) */
+ /* -------------------------------------------------------------- */
+#ifndef USE_WIRELESS
+ strcpy(c_val, "nwifi");
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val)+1), 0,0))
+ goto _fail_;
+#endif
+
+ c_val[0] = 0;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 1;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = NO_POWERSAVE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = NO_ENCRYPT; //NO_ENCRYPT, 0x79
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = OPEN_SYSTEM;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 0,0))
+ goto _fail_;
+
+ /* WEP/802 11I Configuration */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : WEP Key */
+ /* Values (0x) : 5 byte for WEP40 and 13 bytes for WEP104 */
+ /* In case more than 5 bytes are passed on for WEP 40 */
+ /* only first 5 bytes will be used as the key */
+ /* ------------------------------------------------------------------ */
+
+ strcpy(c_val, "123456790abcdef1234567890");
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val)+1), 0,0))
+ goto _fail_;
+
+ /* WEP/802 11I Configuration */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : AES/TKIP WPA/RSNA Pre-Shared Key */
+ /* Values to set : Any string with length greater than equal to 8 bytes */
+ /* and less than 64 bytes */
+ /* ------------------------------------------------------------------ */
+ strcpy(c_val, "12345678");
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 0,0))
+ goto _fail_;
+
+ /* IEEE802.1X Key Configuration */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Radius Server Access Secret Key */
+ /* Values to set : Any string with length greater than equal to 8 bytes */
+ /* and less than 65 bytes */
+ /* ------------------------------------------------------------------ */
+ strcpy(c_val, "password");
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val)+1), 0,0))
+ goto _fail_;
+
+ /* IEEE802.1X Server Address Configuration */
+ /* ------------------------------------------------------------------ */
+ /* Configuration : Radius Server IP Address */
+ /* Values to set : Any valid IP Address */
+ /* ------------------------------------------------------------------ */
+ c_val[0] = 192;
+ c_val[1] = 168;
+ c_val[2] = 1;
+ c_val[3] = 112;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0,0))
+ goto _fail_;
+
+ c_val[0] = 3;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 3;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = NORMAL_ACK;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 0;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 48;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 28;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0,0))
+ goto _fail_;
+
+ /* Beacon Interval */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Sets the beacon interval value */
+ /* Values to set : Any 16-bit value */
+ /* -------------------------------------------------------------------- */
+
+ *((int *)c_val) = 100;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0,0))
+ goto _fail_;
+
+ c_val[0] = REKEY_DISABLE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 0,0))
+ goto _fail_;
+
+ /* Rekey Time (s) (Used only when the Rekey policy is 2 or 4) */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Sets the Rekey Time (s) */
+ /* Values to set : 32-bit value */
+ /* -------------------------------------------------------------------- */
+ *((int *)c_val) = 84600;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 0,0))
+ goto _fail_;
+
+ /* Rekey Packet Count (in 1000s; used when Rekey Policy is 3) */
+ /* -------------------------------------------------------------------- */
+ /* Configuration : Sets Rekey Group Packet count */
+ /* Values to set : 32-bit Value */
+ /* -------------------------------------------------------------------- */
+ *((int *)c_val) = 500;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0,0))
+ goto _fail_;
+
+ c_val[0] = 1;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = G_SELF_CTS_PROT;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0,0))
+ goto _fail_;
+
+ if((chipid & 0xfff) > 0xd0)
+ c_val[0] = 1; /* Enable N */
+ else
+ c_val[0] = 0; /* Disable N */
+
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = HT_MIXED_MODE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 1; /* TXOP Prot disable in N mode: No RTS-CTS on TX A-MPDUs to save air-time. */
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0,0))
+ goto _fail_;
+
+ memcpy(c_val, mac_add, 6);
+
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0,0))
+ goto _fail_;
+
+ /**
+ AP only
+ **/
+ c_val[0] = DETECT_PROTECT_REPORT;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = RTS_CTS_NONHT_PROT;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 0;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = MIMO_MODE;
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0,0))
+ goto _fail_;
+
+
+ if(nmi_get_chipid(NMI_FALSE) >= 0x1002a0)
+ c_val[0] = 7; /* Limit TX rate below MCS-7 for NMC1000F0. Should be changed in to 7 in NMC1002. */
+ else
+ c_val[0] = 6;
+
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0,0))
+ goto _fail_;
+
+ c_val[0] = 1; /* Enable N with immediate block ack. */
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 0,0))
+ goto _fail_;
+
+ /*Adde by Amr - BugID 4707*/
+ /*A mandatory restart mac has to be done initially.*/
+ /*So wid reset is sent with startup configrations*/
+
+ c_val[0] = 1;
+
+ if (!g_linux_wlan->oup.wlan_cfg_set(0, WID_RESET, c_val, 1, 1,(NMI_Uint32)pstrWFIDrv))
+ goto _fail_;
+
+
+ return 0;
+
+_fail_:
+ return -1;
+}
+
+
+/**************************/
+void nmc1000_wlan_deinit(linux_wlan_t *nic) {
+
+ if(g_linux_wlan->nmc1000_initialized)
+ {
+
+ PRINT_D(INIT_DBG,"Deinitializing nmc1000 ...\n");
+
+ if(nic == NULL){
+ PRINT_ER("nic is NULL\n");
+ return;
+ }
+
+#if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
+ // johnny : remove
+ PRINT_D(INIT_DBG,"skip nmi_bus_set_default_speed\n");
+#else
+ nmi_bus_set_default_speed();
+#endif
+
+ PRINT_D(INIT_DBG,"Disabling IRQ\n");
+ #if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ linux_wlan_disable_irq(IRQ_WAIT);
+ #else
+ #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
+
+ #else
+ linux_wlan_lock_mutex((void*)&g_linux_wlan->hif_cs);
+ disable_sdio_interrupt();
+ linux_wlan_unlock_mutex((void*)&g_linux_wlan->hif_cs);
+ #endif
+ #endif
+
+
+ /* not sure if the following unlocks are needed or not*/
+ if(&g_linux_wlan->rxq_event != NULL){
+ linux_wlan_unlock(&g_linux_wlan->rxq_event);
+ }
+
+ if(&g_linux_wlan->txq_event != NULL){
+ linux_wlan_unlock(&g_linux_wlan->txq_event);
+ }
+
+
+ #if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
+ /*Removing the work struct from the linux kernel workqueue*/
+ if(&g_linux_wlan->rx_work_queue != NULL)
+ flush_work(&g_linux_wlan->rx_work_queue);
+
+ #elif (RX_BH_TYPE == RX_BH_KTHREAD)
+ //if(&nic->rx_sem != NULL)
+ //linux_wlan_unlock(&nic->rx_sem);
+ #endif
+
+ PRINT_D(INIT_DBG,"Deinitializing Threads\n");
+ wlan_deinitialize_threads(nic);
+
+ PRINT_D(INIT_DBG,"Deinitializing IRQ\n");
+ deinit_irq(g_linux_wlan);
+
+
+ if(&g_linux_wlan->oup != NULL){
+ if(g_linux_wlan->oup.wlan_stop != NULL)
+ g_linux_wlan->oup.wlan_stop();
+ }
+
+ PRINT_D(INIT_DBG,"Deinitializing NMI Wlan\n");
+ nmi_wlan_deinit(nic);
+#if (defined NMI_SDIO) && (!defined NMI_SDIO_IRQ_GPIO)
+ #if defined(PLAT_ALLWINNER_A20) || defined(PLAT_ALLWINNER_A23) || defined(PLAT_ALLWINNER_A31)
+ PRINT_D(INIT_DBG,"Disabling IRQ 2\n");
+
+ linux_wlan_lock_mutex((void*)&g_linux_wlan->hif_cs);
+ disable_sdio_interrupt();
+ linux_wlan_unlock_mutex((void*)&g_linux_wlan->hif_cs);
+ #endif
+#endif
+
+ /*De-Initialize locks*/
+ PRINT_D(INIT_DBG,"Deinitializing Locks\n");
+ wlan_deinit_locks(g_linux_wlan);
+
+ /* announce that nmc1000 is not initialized */
+ g_linux_wlan->nmc1000_initialized = 0;
+
+ PRINT_D(INIT_DBG,"nmc1000 deinitialization Done\n");
+
+ }else{
+ PRINT_D(INIT_DBG,"nmc1000 is not initialized\n");
+ }
+ return;
+}
+
+int wlan_init_locks(linux_wlan_t* p_nic){
+
+ PRINT_D(INIT_DBG,"Initializing Locks ...\n");
+
+ /*initialize mutexes*/
+ linux_wlan_init_mutex("hif_lock/hif_cs",&g_linux_wlan->hif_cs,1);
+ linux_wlan_init_mutex("rxq_lock/rxq_cs",&g_linux_wlan->rxq_cs,1);
+ linux_wlan_init_mutex("txq_lock/txq_cs",&g_linux_wlan->txq_cs,1);
+
+ /*Added by Amr - BugID_4720*/
+ linux_wlan_init_spin_lock("txq_spin_lock/txq_cs",&g_linux_wlan->txq_spinlock,1);
+
+ /*Added by Amr - BugID_4720*/
+ linux_wlan_init_lock("txq_add_to_head_lock/txq_cs",&g_linux_wlan->txq_add_to_head_cs,1);
+
+ linux_wlan_init_lock("txq_wait/txq_event",&g_linux_wlan->txq_event,0);
+ linux_wlan_init_lock("rxq_wait/rxq_event",&g_linux_wlan->rxq_event,0);
+
+ linux_wlan_init_lock("cfg_wait/cfg_event",&g_linux_wlan->cfg_event,0);
+ linux_wlan_init_lock("sync_event",&g_linux_wlan->sync_event,0);
+
+ linux_wlan_init_lock("rxq_lock/rxq_started",&g_linux_wlan->rxq_thread_started,0);
+ linux_wlan_init_lock("rxq_lock/txq_started",&g_linux_wlan->txq_thread_started,0);
+
+ #if (RX_BH_TYPE == RX_BH_KTHREAD)
+ linux_wlan_init_lock("BH_SEM", &g_linux_wlan->rx_sem, 0);
+ #endif
+
+ return 0;
+}
+
+static int wlan_deinit_locks(linux_wlan_t* nic){
+ PRINT_D(INIT_DBG,"De-Initializing Locks\n");
+
+ if(&g_linux_wlan->hif_cs != NULL)
+ linux_wlan_deinit_mutex(&g_linux_wlan->hif_cs);
+
+ if(&g_linux_wlan->rxq_cs != NULL)
+ linux_wlan_deinit_mutex(&g_linux_wlan->rxq_cs);
+
+ if(&g_linux_wlan->txq_cs != NULL)
+ linux_wlan_deinit_mutex(&g_linux_wlan->txq_cs);
+
+ /*Added by Amr - BugID_4720*/
+ if(&g_linux_wlan->txq_spinlock!= NULL)
+ linux_wlan_deinit_spin_lock(&g_linux_wlan->txq_spinlock);
+
+ if(&g_linux_wlan->rxq_event != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->rxq_event);
+
+ if(&g_linux_wlan->txq_event != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->txq_event);
+
+ /*Added by Amr - BugID_4720*/
+ if(&g_linux_wlan->txq_add_to_head_cs!= NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->txq_add_to_head_cs);
+
+ if(&g_linux_wlan->rxq_thread_started != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->rxq_thread_started);
+
+ if(&g_linux_wlan->txq_thread_started != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->txq_thread_started);
+
+ if(&g_linux_wlan->cfg_event != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->cfg_event);
+
+ if(&g_linux_wlan->sync_event != NULL)
+ linux_wlan_deinit_lock(&g_linux_wlan->sync_event);
+
+ return 0;
+}
+void linux_to_wlan(nmi_wlan_inp_t* nwi,linux_wlan_t* nic){
+
+ PRINT_D(INIT_DBG,"Linux to Wlan services ...\n");
+
+ nwi->os_context.hif_critical_section = (void *)&g_linux_wlan->hif_cs;
+ nwi->os_context.os_private = (void *)nic;
+ nwi->os_context.tx_buffer_size = LINUX_TX_SIZE;
+ nwi->os_context.txq_critical_section = (void *)&g_linux_wlan->txq_cs;
+
+ /*Added by Amr - BugID_4720*/
+ nwi->os_context.txq_add_to_head_critical_section=(void *)&g_linux_wlan->txq_add_to_head_cs;
+
+ /*Added by Amr - BugID_4720*/
+ nwi->os_context.txq_spin_lock = (void *)&g_linux_wlan->txq_spinlock;
+
+ nwi->os_context.txq_wait_event = (void *)&g_linux_wlan->txq_event;
+
+#if defined (MEMORY_STATIC)
+ nwi->os_context.rx_buffer_size = LINUX_RX_SIZE;
+#endif
+ nwi->os_context.rxq_critical_section = (void *)&g_linux_wlan->rxq_cs;
+ nwi->os_context.rxq_wait_event = (void *)&g_linux_wlan->rxq_event;
+ nwi->os_context.cfg_wait_event = (void *)&g_linux_wlan->cfg_event;
+
+ nwi->os_func.os_sleep = linux_wlan_msleep;
+ nwi->os_func.os_atomic_sleep = linux_wlan_atomic_msleep;
+ nwi->os_func.os_debug = linux_wlan_dbg;
+ nwi->os_func.os_malloc = linux_wlan_malloc;
+ nwi->os_func.os_malloc_atomic = linux_wlan_malloc_atomic;
+ nwi->os_func.os_free = linux_wlan_free;
+ nwi->os_func.os_lock = linux_wlan_lock;
+ nwi->os_func.os_unlock = linux_wlan_unlock;
+ nwi->os_func.os_wait = linux_wlan_lock_timeout;
+ nwi->os_func.os_signal = linux_wlan_unlock;
+ nwi->os_func.os_enter_cs = linux_wlan_lock_mutex;
+ nwi->os_func.os_leave_cs = linux_wlan_unlock_mutex;
+
+ /*Added by Amr - BugID_4720*/
+ nwi->os_func.os_spin_lock = linux_wlan_spin_lock;
+ nwi->os_func.os_spin_unlock = linux_wlan_spin_unlock;
+
+#ifdef NMI_SDIO
+ nwi->io_func.io_type = HIF_SDIO;
+ nwi->io_func.io_init = linux_sdio_init;
+ nwi->io_func.io_deinit = linux_sdio_deinit;
+ nwi->io_func.u.sdio.sdio_cmd52 = linux_sdio_cmd52;
+ nwi->io_func.u.sdio.sdio_cmd53 = linux_sdio_cmd53;
+ nwi->io_func.u.sdio.sdio_set_max_speed = linux_sdio_set_max_speed;
+ nwi->io_func.u.sdio.sdio_set_default_speed = linux_sdio_set_default_speed;
+#else
+ nwi->io_func.io_type = HIF_SPI;
+ nwi->io_func.io_init = linux_spi_init;
+ nwi->io_func.io_deinit = linux_spi_deinit;
+ nwi->io_func.u.spi.spi_tx = linux_spi_write;
+ nwi->io_func.u.spi.spi_rx = linux_spi_read;
+ nwi->io_func.u.spi.spi_trx = linux_spi_write_read;
+ nwi->io_func.u.spi.spi_max_speed = linux_spi_set_max_speed;
+#endif
+
+ /*for now - to be revised*/
+ #ifdef NMI_FULLY_HOSTING_AP
+ /* incase of Fully hosted AP, all non cfg pkts are processed here*/
+ nwi->net_func.rx_indicate = NMI_Process_rx_frame;
+ #else
+ nwi->net_func.rx_indicate = frmw_to_linux;
+ #endif
+ nwi->net_func.rx_complete = linux_wlan_rx_complete;
+ nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate;
+}
+
+int wlan_initialize_threads(perInterface_wlan_t* nic){
+
+ int ret = 0;
+ PRINT_D(INIT_DBG,"Initializing Threads ...\n");
+
+#if (RX_BH_TYPE == RX_BH_WORK_QUEUE)
+ /*Initialize rx work queue task*/
+ INIT_WORK(&g_linux_wlan->rx_work_queue, isr_bh_routine);
+#elif (RX_BH_TYPE == RX_BH_KTHREAD)
+ PRINT_D(INIT_DBG,"Creating kthread for Rxq BH\n");
+ g_linux_wlan->rx_bh_thread = kthread_run(isr_bh_routine,(void*)g_linux_wlan,"K_RXQ_BH");
+ if(g_linux_wlan->rx_bh_thread == 0){
+ PRINT_ER("couldn't create RX BH thread\n");
+ ret = -ENOBUFS;
+ goto _fail_;
+ }
+#endif
+
+ /* create rx task */
+ PRINT_D(INIT_DBG,"Creating kthread for reception\n");
+ g_linux_wlan->rxq_thread = kthread_run(linux_wlan_rxq_task,(void*)g_linux_wlan,"K_RXQ_TASK");
+ if(g_linux_wlan->rxq_thread == 0){
+ PRINT_ER("couldn't create RXQ thread\n");
+ ret = -ENOBUFS;
+ goto _fail_1;
+ }
+
+ /* wait for RXQ task to start. */
+ linux_wlan_lock(&g_linux_wlan->rxq_thread_started);
+
+ /* create tx task */
+ PRINT_D(INIT_DBG,"Creating kthread for transmission\n");
+ g_linux_wlan->txq_thread = kthread_run(linux_wlan_txq_task,(void*)g_linux_wlan,"K_TXQ_TASK");
+ if(g_linux_wlan->txq_thread == 0){
+ PRINT_ER("couldn't create TXQ thread\n");
+ ret = -ENOBUFS;
+ goto _fail_2;
+ }
+#ifdef DEBUG_MODE
+ PRINT_D(INIT_DBG,"Creating kthread for Debugging\n");
+ g_linux_wlan->txq_thread = kthread_run(DebuggingThreadTask,(void*)g_linux_wlan,"DebugThread");
+ if(g_linux_wlan->txq_thread == 0){
+ PRINT_ER("couldn't create TXQ thread\n");
+ ret = -ENOBUFS;
+ goto _fail_2;
+ }
+#endif
+ /* wait for TXQ task to start. */
+ linux_wlan_lock(&g_linux_wlan->txq_thread_started);
+
+ return 0;
+
+ _fail_2:
+ /*De-Initialize 2nd thread*/
+ g_linux_wlan->close = 1;
+ linux_wlan_unlock(&g_linux_wlan->rxq_event);
+ kthread_stop(g_linux_wlan->rxq_thread);
+
+ _fail_1:
+ #if(RX_BH_TYPE == RX_BH_KTHREAD)
+ /*De-Initialize 1st thread*/
+ g_linux_wlan->close = 1;
+ linux_wlan_unlock(&g_linux_wlan->rx_sem);
+ kthread_stop(g_linux_wlan->rx_bh_thread);
+ _fail_:
+ #endif
+ g_linux_wlan->close = 0;
+ return ret;
+}
+
+static void wlan_deinitialize_threads(linux_wlan_t* nic){
+
+ g_linux_wlan->close = 1;
+ PRINT_D(INIT_DBG,"Deinitializing Threads\n");
+ if(&g_linux_wlan->rxq_event != NULL)
+ linux_wlan_unlock(&g_linux_wlan->rxq_event);
+
+
+ if(g_linux_wlan->rxq_thread != NULL){
+ kthread_stop(g_linux_wlan->rxq_thread);
+ g_linux_wlan->rxq_thread = NULL;
+ }
+
+
+ if(&g_linux_wlan->txq_event != NULL)
+ linux_wlan_unlock(&g_linux_wlan->txq_event);
+
+
+ if(g_linux_wlan->txq_thread != NULL){
+ kthread_stop(g_linux_wlan->txq_thread);
+ g_linux_wlan->txq_thread = NULL;
+ }
+
+ #if(RX_BH_TYPE == RX_BH_KTHREAD)
+ if(&g_linux_wlan->rx_sem != NULL)
+ linux_wlan_unlock(&g_linux_wlan->rx_sem);
+
+ if(g_linux_wlan->rx_bh_thread != NULL){
+ kthread_stop(g_linux_wlan->rx_bh_thread);
+ g_linux_wlan->rx_bh_thread= NULL;
+ }
+ #endif
+}
+
+#ifdef STATIC_MACADDRESS
+static int linux_wlan_read_mac_addr(void* vp)
+{
+ int ret = 0;
+ struct file *fp = (struct file *)-ENOENT;
+ mm_segment_t old_fs;
+ loff_t pos = 0;
+
+ /* change to KERNEL_DS address limit */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ do {
+#if defined(PLAT_CLM9722) // rachel
+ fp = filp_open("/etc/wlan", O_WRONLY, 0640);
+#else
+ fp = filp_open("/data/wlan", O_WRONLY, 0640);
+#endif
+ if (!fp) {
+ ret = -1;
+ goto exit;
+ }
+
+ /*No such file or directory */
+ if (IS_ERR(fp) || !fp->f_op) {
+ get_random_bytes(&mac_add[3], 3);
+
+ /* open file to write */
+#if defined(PLAT_CLM9722) // rachel
+ fp = filp_open("/etc/wlan", O_WRONLY|O_CREAT, 0640);
+#else
+ fp = filp_open("/data/wlan", O_WRONLY|O_CREAT, 0640);
+#endif
+ if (!fp) {
+ ret = -1;
+ goto exit;
+ }
+
+ /* Write buf to file */
+ fp->f_op->write(fp, mac_add, 6, &pos);
+
+ }else{
+ /* read file to buf */
+ fp->f_op->read(fp, mac_add, 6, &pos);
+ }
+ }while(0);
+
+exit:
+ if (fp) {
+ filp_close(fp,NULL);
+ }
+
+ set_fs(old_fs);
+
+ return ret;
+}
+#endif
+
+#ifdef COMPLEMENT_BOOT
+
+extern volatile int probe;
+extern uint8_t core_11b_ready(void);
+
+#define READY_CHECK_THRESHOLD 10
+
+uint8_t nmc1000_prepare_11b_core(nmi_wlan_inp_t *nwi, nmi_wlan_oup_t *nwo,linux_wlan_t * nic)
+{
+ uint8_t trials = 0;
+ while((core_11b_ready() && (READY_CHECK_THRESHOLD > (trials++))))
+ {
+ PRINT_D(INIT_DBG,"11b core not ready yet: %u\n",trials);
+ nmi_wlan_deinit(nic);
+ sdio_unregister_driver(&nmc_bus);
+
+ linux_wlan_device_detection(0);
+ linux_wlan_device_power(0);
+
+ mdelay(100);
+
+ linux_wlan_device_power(1);
+ linux_wlan_device_detection(1);
+
+ sdio_register_driver(&nmc_bus);
+
+ while(!probe)
+ {
+ msleep(100);
+ }
+ probe = 0;
+ g_linux_wlan->nmc_sdio_func= local_sdio_func;
+ linux_to_wlan(nwi,nic);
+ nmi_wlan_init(nwi, nwo);
+ }
+
+ if(READY_CHECK_THRESHOLD <= trials)
+ return 1;
+ else
+ return 0;
+
+}
+
+int repeat_power_cycle(perInterface_wlan_t* nic)
+{
+ int ret = 0;
+ nmi_wlan_inp_t nwi;
+ nmi_wlan_oup_t nwo;
+ sdio_unregister_driver(&nmc_bus);
+
+ linux_wlan_device_detection(0);
+ linux_wlan_device_power(0);
+ msleep(100);
+ linux_wlan_device_power(1);
+ msleep(80);
+ linux_wlan_device_detection(1);
+ msleep(20);
+
+ sdio_register_driver(&nmc_bus);
+
+ //msleep(1000);
+ while(!probe)
+ {
+ msleep(100);
+ }
+ probe = 0;
+ g_linux_wlan->nmc_sdio_func= local_sdio_func;
+ linux_to_wlan(&nwi,g_linux_wlan);
+ ret = nmi_wlan_init(&nwi, &nwo);
+
+ g_linux_wlan->mac_status = NMI_MAC_STATUS_INIT;
+ #if (defined NMI_SDIO) && (!defined NMI_SDIO_IRQ_GPIO)
+ enable_sdio_interrupt();
+ #endif
+
+ if(linux_wlan_get_firmware(nic))
+ {
+ PRINT_ER("Can't get firmware \n");
+ ret = -1;
+ goto __fail__;
+ }
+
+ /*Download firmware*/
+ ret = linux_wlan_firmware_download(g_linux_wlan);
+ if(ret < 0)
+ {
+ PRINT_ER("Failed to download firmware\n");
+ goto __fail__;
+ }
+ /* Start firmware*/
+ ret = linux_wlan_start_firmware(nic);
+ if(ret < 0){
+ PRINT_ER("Failed to start firmware\n");
+ }
+ __fail__:
+ return ret;
+}
+#endif
+
+int nmc1000_wlan_init(struct net_device *dev,perInterface_wlan_t* p_nic)
+{
+ nmi_wlan_inp_t nwi;
+ nmi_wlan_oup_t nwo;
+ perInterface_wlan_t* nic = p_nic;
+ int ret = 0;
+
+ if(!g_linux_wlan->nmc1000_initialized){
+ g_linux_wlan->mac_status = NMI_MAC_STATUS_INIT;
+ g_linux_wlan->close = 0;
+ g_linux_wlan->nmc1000_initialized = 0;
+#if defined(PLAT_AML8726_M3)
+ _available_irq_ready = 0;
+#endif
+ wlan_init_locks(g_linux_wlan);
+
+#ifdef STATIC_MACADDRESS
+ nmi_mac_thread = kthread_run(linux_wlan_read_mac_addr,NULL,"nmi_mac_thread");
+ if(nmi_mac_thread < 0){
+ PRINT_ER("couldn't create Mac addr thread\n");
+ }
+#endif
+
+ linux_to_wlan(&nwi,g_linux_wlan);
+
+ ret = nmi_wlan_init(&nwi, &nwo);
+ if (ret < 0) {
+ PRINT_ER("Initializing NMI_Wlan FAILED\n");
+ goto _fail_locks_;
+ }
+ memcpy(&g_linux_wlan->oup, &nwo, sizeof(nmi_wlan_oup_t));
+
+ /*Save the oup structre into global pointer*/
+ gpstrWlanOps = &g_linux_wlan->oup;
+
+
+ ret = wlan_initialize_threads(nic);
+ if (ret < 0) {
+ PRINT_ER("Initializing Threads FAILED\n");
+ goto _fail_nmi_wlan_;
+ }
+
+#if (defined NMI_SDIO) && (defined COMPLEMENT_BOOT)
+ if(nmc1000_prepare_11b_core(&nwi,&nwo,g_linux_wlan)){
+ PRINT_ER("11b Core is not ready\n");
+ goto _fail_threads_;
+ }
+#endif
+
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ if(init_irq(g_linux_wlan)){
+ PRINT_ER("couldn't initialize IRQ\n");
+ ret = -EIO;
+ goto _fail_threads_;
+ }
+#endif
+
+#if (defined NMI_SDIO) && (!defined NMI_SDIO_IRQ_GPIO)
+ enable_sdio_interrupt();
+#endif
+
+ if(linux_wlan_get_firmware(nic)){
+ PRINT_ER("Can't get firmware \n");
+ goto _fail_threads_;
+ }
+
+//[[ johnny
+#ifdef FW_VERSION_VERIFICATION
+ if ( check_firmware_version( nic->iftype,
+ __DRIVER_VERSION__,
+ g_linux_wlan->nmc_firmware? g_linux_wlan->nmc_firmware->size:0 )
+ != 0 )
+ goto _fail_threads_;
+#endif
+//]]
+
+ /*Download firmware*/
+ ret = linux_wlan_firmware_download(g_linux_wlan);
+ if(ret < 0){
+ PRINT_ER("Failed to download firmware\n");
+ goto _fail_threads_;
+ }
+
+ /* Start firmware*/
+ ret = linux_wlan_start_firmware(nic);
+ if(ret < 0){
+ PRINT_ER("Failed to start firmware\n");
+ goto _fail_threads_;
+ }
+
+ nmi_bus_set_max_speed();
+
+ if (g_linux_wlan->oup.wlan_cfg_get(1, WID_FIRMWARE_VERSION, 1,0))
+ {
+ int size;
+ char Firmware_ver[20];
+ size = g_linux_wlan->oup.wlan_cfg_get_value(
+ WID_FIRMWARE_VERSION,
+ Firmware_ver,sizeof(Firmware_ver));
+ Firmware_ver[size] = '\0';
+ printk("***** Firmware Ver = %s *******\n",Firmware_ver);
+ }
+ /* Initialize firmware with default configuration */
+ ret = linux_wlan_init_test_config(dev, g_linux_wlan);
+
+ if(ret < 0){
+ PRINT_ER("Failed to configure firmware\n");
+ goto _fail_threads_;
+ }
+
+ g_linux_wlan->nmc1000_initialized = 1;
+ return 0; /*success*/
+
+_fail_threads_:
+ wlan_deinitialize_threads(g_linux_wlan);
+
+#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO)
+ deinit_irq(g_linux_wlan);
+
+#endif
+_fail_nmi_wlan_:
+ nmi_wlan_deinit(g_linux_wlan);
+_fail_locks_:
+ wlan_deinit_locks(g_linux_wlan);
+ PRINT_ER("WLAN Iinitialization FAILED\n");
+ }else{
+ PRINT_D(INIT_DBG,"nmc1000 already initialized\n");
+ }
+ return ret;
+}
+
+
+/*
+ - this function will be called automatically by OS when module inserted.
+*/
+
+#if !defined (NM73131_0_BOARD)
+int mac_init_fn(struct net_device *ndev){
+
+ /*Why we do this !!!*/
+ netif_start_queue(ndev); //ma
+ netif_stop_queue(ndev); //ma
+
+ return 0;
+}
+#else
+int mac_init_fn(struct net_device *ndev){
+
+ unsigned char mac_add[] = {0x00,0x50,0xc2,0x5e,0x10,0x00};
+ /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
+ memcpy(ndev->dev_addr, mac_add, 6);
+
+ if(!is_valid_ether_addr(ndev->dev_addr)){
+ PRINT_ER("Error: Wrong MAC address\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+
+void NMI_WFI_frame_register(struct wiphy *wiphy,struct net_device *dev,
+ u16 frame_type, bool reg);
+
+/* This fn is called, when this device is setup using ifconfig */
+#if !defined (NM73131_0_BOARD)
+int mac_open(struct net_device *ndev){
+ perInterface_wlan_t* nic;
+ /*BugID_5213*/
+ /*No need for setting mac address here anymore,*/
+ /*Just set it in init_test_config()*/
+ unsigned char mac_add[ETH_ALEN] ={0};
+ int status;
+ int ret = 0;
+ int i = 0;
+ struct NMI_WFI_priv* priv;
+
+ printk("MAC OPEN[%p]\n",ndev);
+
+
+
+ nic = netdev_priv(ndev);
+ priv = wiphy_priv(nic->nmc_netdev->ieee80211_ptr->wiphy);
+ //if (once == 1) return 0;
+ //linux_wlan_lock(&close_exit_sync);
+
+ #ifdef USE_WIRELESS
+ ret = NMI_WFI_InitHostInt(ndev);
+ if(ret < 0)
+ {
+ PRINT_ER("Failed to initialize host interface\n");
+
+ return ret;
+ }
+ #endif
+
+ /*initialize platform*/
+ printk("*** re-init ***\n");
+ ret = nmc1000_wlan_init(ndev, nic);
+ if(ret < 0)
+ {
+ PRINT_ER("Failed to initialize nmc1000\n");
+ NMI_WFI_DeInitHostInt(ndev);
+ //linux_wlan_unlock(&close_exit_sync);
+ return ret;
+ }
+ Set_machw_change_vir_if(NMI_FALSE);
+
+ //else
+ //{
+ /*BugID_5077*/
+ /*host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv);
+ host_int_set_MacAddress(priv->hNMIWFIDrv, mac_add);
+
+ g_linux_wlan->nmc1000_initialized = 1;
+ once++;
+ }*/
+
+
+
+ status = host_int_get_MacAddress(priv->hNMIWFIDrv, mac_add);
+ PRINT_D(GENERIC_DBG, "Mac address: %x:%x:%x:%x:%x:%x\n", mac_add[0], mac_add[1], mac_add[2],
+ mac_add[3], mac_add[4], mac_add[5]);
+
+ //loop through the NUM of supported devices and set the MAC address
+ for(i=0;i<g_linux_wlan->u8NoIfcs;i++)
+ {
+ if(ndev == g_linux_wlan->strInterfaceInfo[i].nmc_netdev)
+ {
+ memcpy(g_linux_wlan->strInterfaceInfo[i].aSrcAddress, mac_add, ETH_ALEN);
+ //linux_wlan_set_bssid(ndev,g_linux_wlan->strInterfaceInfo[i].aSrcAddress);
+ g_linux_wlan->strInterfaceInfo[i].drvHandler = (NMI_Uint32)priv->hNMIWFIDrv;
+ //change the MSB
+ //nic->strInterfaceInfo[i].aSrcAddress[0] = nic->strInterfaceInfo[i].aSrcAddress[0] + i*2;
+ break;
+ }
+ }
+
+ /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/
+ memcpy(ndev->dev_addr, g_linux_wlan->strInterfaceInfo[i].aSrcAddress, ETH_ALEN);
+
+ if(!is_valid_ether_addr(ndev->dev_addr)){
+ PRINT_ER("Error: Wrong MAC address\n");
+ //linux_wlan_unlock(&close_exit_sync);
+ return -EINVAL;
+ }
+ /* Start the network interface queue for this device */
+ PRINT_D(INIT_DBG,"Starting netifQ\n");
+ //netif_start_queue(ndev); ma
+ //enable interrupts
+ //enable_irq(g_linux_wlan->dev_irq_num);
+ //if(!once)
+ //host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv);
+ //host_int_set_wfi_drv_handler((NMI_Uint32)priv->hNMIWFIDrv_2);
+
+ NMI_WFI_frame_register(nic->nmc_netdev->ieee80211_ptr->wiphy,nic->nmc_netdev,
+ nic->g_struct_frame_reg[0].frame_type,nic->g_struct_frame_reg[0].reg);
+
+ NMI_WFI_frame_register(nic->nmc_netdev->ieee80211_ptr->wiphy,nic->nmc_netdev,
+ nic->g_struct_frame_reg[1].frame_type,nic->g_struct_frame_reg[1].reg);
+ netif_wake_queue(ndev);
+
+ //linux_wlan_lock(&close_exit_sync);
+ g_linux_wlan->open_ifcs++;
+ nic->mac_opened=1;
+ return 0;
+}
+#else
+int mac_open(struct net_device *ndev)
+{
+
+ linux_wlan_t* nic;
+ nic = netdev_priv(ndev);
+
+ /*initialize platform*/
+ if(nmc1000_wlan_init(nic)){
+ PRINT_ER("Failed to initialize platform\n");
+ return 1;
+ }
+ /* Start the network interface queue for this device */
+ PRINT_D(INIT_DBG,"Starting netifQ\n");
+ netif_start_queue(ndev);
+// linux_wlan_lock(&close_exit_sync);
+ return 0;
+}
+#endif
+
+struct net_device_stats *mac_stats(struct net_device *dev)
+{
+ perInterface_wlan_t* nic= netdev_priv(dev);
+
+
+ return &nic->netstats;
+}
+
+// Setup the multicast filter
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
+static void nmi_set_multicast_list(struct net_device *dev)
+{
+
+ struct netdev_hw_addr *ha;
+ struct NMI_WFI_priv* priv;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ int i=0;
+ priv= wiphy_priv(dev->ieee80211_ptr->wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+
+
+ if (!dev)
+ return;
+
+ PRINT_D(INIT_DBG,"Setting Multicast List with count = %d. \n",dev->mc.count);
+
+ if (dev->flags & IFF_PROMISC)
+ {
+ /* Normally, we should configure the chip to retrive all packets
+ * but we don't wanna support this right now */
+ // TODO: add promiscuous mode support
+ PRINT_D(INIT_DBG,"Set promiscuous mode ON, retrive all packets \n");
+ return;
+ }
+
+ /* If there's more addresses than we handle, get all multicast
+ packets and sort them out in software. */
+ if ( (dev->flags & IFF_ALLMULTI) ||(dev->mc.count) > NMI_MULTICAST_TABLE_SIZE)
+ {
+ PRINT_D(INIT_DBG,"Disable multicast filter, retrive all multicast packets\n");
+ // get all multicast packets
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)pstrWFIDrv, NMI_FALSE, 0);
+ return;
+ }
+
+ /* No multicast? Just get our own stuff */
+ if ((dev->mc.count) == 0)
+ {
+ PRINT_D(INIT_DBG,"Enable multicast filter, retrive directed packets only.\n");
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)pstrWFIDrv, NMI_TRUE, 0);
+ return;
+ }
+
+ /* Store all of the multicast addresses in the hardware filter */
+ netdev_for_each_mc_addr(ha, dev)
+ {
+ NMI_memcpy(gau8MulticastMacAddrList[i], ha->addr, ETH_ALEN);
+ PRINT_D(INIT_DBG,"Entry[%d]: %x:%x:%x:%x:%x:%x\n",i,
+ gau8MulticastMacAddrList[i][0], gau8MulticastMacAddrList[i][1], gau8MulticastMacAddrList[i][2], gau8MulticastMacAddrList[i][3], gau8MulticastMacAddrList[i][4], gau8MulticastMacAddrList[i][5]);
+ i++;
+ }
+
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)pstrWFIDrv, NMI_TRUE, (dev->mc.count));
+
+ return;
+
+}
+
+#else
+
+static void nmi_set_multicast_list(struct net_device *dev)
+{
+ // BIG Warning, Beware : Uncompiled, untested...
+ struct dev_mc_list *mc_ptr;
+ int i=0;
+
+ if (!dev)
+ return;
+
+ PRINT_D(INIT_DBG,"Setting Multicast List. \n");
+ printk("dev->mc_count = %d\n",dev->mc_count);
+
+ if (dev->flags & IFF_PROMISC)
+ {
+ /* Normally, we should configure the chip to retrive all packets
+ * but we don't wanna support this right now */
+ // TODO: add promiscuous mode support
+ PRINT_D(INIT_DBG,"Set promiscuous mode ON, retrive all packets \n");
+ return;
+ }
+
+ /* If there's more addresses than we handle, get all multicast
+ packets and sort them out in software. */
+ if ( (dev->flags & IFF_ALLMULTI) ||( dev->mc_count > NMI_MULTICAST_TABLE_SIZE) )
+ {
+ PRINT_D(INIT_DBG,"Disable multicast filter, retrive all multicast packets\n");
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)gWFiDrvHandle, NMI_FALSE, 0);
+ return;
+ }
+
+ /* No multicast? Just get our own stuff */
+ if (dev->mc_count == 0)
+ {
+ PRINT_D(INIT_DBG,"Enable multicast filter, retrive directed packets only.\n");
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)gWFiDrvHandle, NMI_TRUE, 0);
+ return;
+ }
+
+ /* Store all of the multicast addresses in the hardware filter */
+
+ for (mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next , i++)
+ {
+ NMI_memcpy(gau8MulticastMacAddrList[i], mc_ptr->dmi_addr, ETH_ALEN)
+ i++;
+ }
+
+ host_int_setup_multicast_filter((NMI_WFIDrvHandle)gWFiDrvHandle, NMI_TRUE, (dev->mc_count));
+
+}
+#endif
+
+static void linux_wlan_tx_complete(void* priv, int status){
+
+ struct tx_complete_data* pv_data = (struct tx_complete_data*)priv;
+ if(status == 1){
+ PRINT_D(TX_DBG,"Packet sent successfully - Size = %d - Address = %p - SKB = %p\n",pv_data->size,pv_data->buff, pv_data->skb);
+ } else {
+ PRINT_D(TX_DBG,"Couldn't send packet - Size = %d - Address = %p - SKB = %p\n",pv_data->size,pv_data->buff, pv_data->skb);
+ }
+ /* Free the SK Buffer, its work is done */
+ dev_kfree_skb(pv_data->skb);
+ linux_wlan_free(pv_data);
+}
+
+int mac_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ perInterface_wlan_t* nic;
+ struct tx_complete_data* tx_data = NULL;
+ int QueueCount;
+ //char* saddr,*daddr,*pu8UdpBuffer;
+ char *pu8UdpBuffer;
+ struct iphdr *ih;
+ struct ethhdr * eth_h;
+// struct ethhdr *eth;
+// char* ethsaddr,*ethdaddr;
+// int i;
+ //char* TestBuff;
+ //printk("mac xmit on [%x]\n",ndev);
+ PRINT_D(INT_DBG,"\n========\n IntUH: %d - IntBH: %d - IntCld: %d \n========\n",int_rcvdU,int_rcvdB,int_clrd);
+ nic = netdev_priv(ndev);
+
+ PRINT_D(TX_DBG,"Sending packet just received from TCP/IP\n");
+
+ /* Stop the network interface queue */
+ // netif_stop_queue(ndev);
+
+ if(skb->dev != ndev){
+ PRINT_ER("Packet not destined to this device\n");
+ return 0;
+ }
+
+ /* allocate memory for the frame - there is no need to allocate the fixed packet size 1496.
+ * just allocat memory with the length of the packet received - also don't put any constraint
+ * on the size of the packet to be received because this restriction is already handled inside firmware.
+ */
+/*
+ if(skb->len > 1496){
+ PRINT_ER("Unable to handle this large packet - Size = %d\n",skb->len);
+ }
+
+*/
+
+ tx_data = (struct tx_complete_data*)internal_alloc(sizeof(struct tx_complete_data),GFP_ATOMIC);
+ if(tx_data == NULL){
+ PRINT_ER("Failed to allocate memory for tx_data structure\n");
+ dev_kfree_skb(skb);
+ netif_wake_queue(ndev);
+ return 0;
+ }
+
+ tx_data->buff = skb->data;
+ tx_data->size = skb->len;
+ tx_data->skb = skb;
+
+ eth_h = (struct ethhdr *)(skb->data);
+ if(eth_h->h_proto == 0x8e88)
+ {
+ printk("EAPOL transmitted\n");
+ }
+
+ /*get source and dest ip addresses*/
+ ih = (struct iphdr *)(skb->data+sizeof(struct ethhdr));
+ //saddr = &ih->saddr;
+ //daddr = &ih->daddr;
+ //NMI_PRINTF("Source IP = %d:%d:%d:%d \n",saddr[0],saddr[1],
+ // saddr[2],saddr[3]);
+// NMI_PRINTF("Dest IP = %d:%d:%d:%d \n",daddr[0],daddr[1],
+ // daddr[2],daddr[3]);
+
+ pu8UdpBuffer = (char*)ih + sizeof(struct iphdr);
+ if((pu8UdpBuffer[1] == 68 && pu8UdpBuffer[3] == 67)||(pu8UdpBuffer[1] == 67 && pu8UdpBuffer[3] == 68))
+ {
+ PRINT_D(GENERIC_DBG,"DHCP Message transmitted, type:%x %x %x\n",pu8UdpBuffer[248],pu8UdpBuffer[249],pu8UdpBuffer[250] );
+
+ }
+ PRINT_D(TX_DBG,"Sending packet - Size = %d - Address = %p - SKB = %p\n",tx_data->size,tx_data->buff,tx_data->skb);
+
+ /*eth = (struct ethhdr *)(skb->data);
+
+ ethsaddr = &eth->h_source;
+ ethdaddr = &eth->h_dest;
+
+ NMI_PRINTF("Source MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x \n",ethsaddr[0],ethsaddr[1],
+ ethsaddr[2],ethsaddr[3],ethsaddr[4],ethsaddr[5]);
+ NMI_PRINTF("Dest MAC = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x \n",ethdaddr[0],ethdaddr[1],
+ ethdaddr[2],ethdaddr[3],ethdaddr[4],ethdaddr[5]);*/
+
+ //NMI_PRINTF("sending pkt \n");
+
+ // NMI_PRINTF("skb->data[12] = %2x, skb->data[13] = %2x \n");
+ /*TestBuff = (char*)(skb->data + sizeof(struct ethhdr));
+
+ for(i = 0; i < 30; i++)
+ {
+ if(i < skb->len)
+ {
+ NMI_PRINTF("TestBuff[%d] = %2x \n", i, TestBuff[i]);
+ }
+ }*/
+
+ /* Send packet to MAC HW - for now the tx_complete function will be just status
+ * indicator. still not sure if I need to suspend host transmission till the tx_complete
+ * function called or not?
+ * allocated buffer will be freed in tx_complete function.
+ */
+ PRINT_D(TX_DBG,"Adding tx packet to TX Queue\n");
+ nic->netstats.tx_packets++;
+ nic->netstats.tx_bytes+=tx_data->size;
+ tx_data->pBssid = g_linux_wlan->strInterfaceInfo[nic->u8IfIdx].aBSSID;
+ #ifndef NMI_FULLY_HOSTING_AP
+ QueueCount = g_linux_wlan->oup.wlan_add_to_tx_que((void*)tx_data,
+ tx_data->buff,
+ tx_data->size,
+ linux_wlan_tx_complete);
+ #else
+ QueueCount = NMI_Xmit_data((void*)tx_data, HOST_TO_WLAN);
+ #endif //NMI_FULLY_HOSTING_AP
+
+
+ if(QueueCount > FLOW_CONTROL_UPPER_THRESHOLD)
+ {
+ // printk("Stopping queue\n");
+ //netif_stop_queue(ndev);
+ netif_stop_queue(g_linux_wlan->strInterfaceInfo[0].nmc_netdev);
+ netif_stop_queue(g_linux_wlan->strInterfaceInfo[1].nmc_netdev);
+
+ }
+
+
+ /* Wake up the network interface queue */
+ //netif_wake_queue(ndev);
+
+
+ return 0;
+}
+
+
+int mac_close(struct net_device *ndev)
+{
+ struct NMI_WFI_priv* priv;
+ perInterface_wlan_t* nic;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+
+ nic = netdev_priv(ndev);
+
+ priv = wiphy_priv(nic->nmc_netdev->ieee80211_ptr->wiphy);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)priv->hNMIWFIDrv;
+
+
+
+ PRINT_D(GENERIC_DBG,"Mac close\n");
+ if((g_linux_wlan->open_ifcs)>0)
+ {
+ g_linux_wlan->open_ifcs--;
+ }
+ else
+ {
+ printk("ERROR: MAC close called while number of opened interfaces is zero\n");
+ return 0;
+ }
+
+
+
+
+ //int i = 0;
+/* for(i=0;i<g_linux_wlan->u8NoIfcs;i++)
+ {
+ if(g_linux_wlan->strInterfaceInfo[i].nmc_netdev != NULL)
+ {
+ // Stop the network interface queue
+ netif_stop_queue(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+
+#ifdef USE_WIRELESS
+ NMI_WFI_DeInitHostInt(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+#endif
+ }
+
+ }*/
+ if(nic->nmc_netdev != NULL)
+ {
+ // Stop the network interface queue
+ netif_stop_queue(nic->nmc_netdev);
+
+#ifdef USE_WIRELESS
+ NMI_WFI_DeInitHostInt(nic->nmc_netdev);
+#endif
+ }
+
+
+
+ if(g_linux_wlan->open_ifcs==0)
+ {
+ PRINT_D(GENERIC_DBG,"Deinitializing nmc1000\n");
+ g_linux_wlan->close = 1;
+ nmc1000_wlan_deinit(g_linux_wlan);
+ #ifdef USE_WIRELESS
+ #ifdef NMI_AP_EXTERNAL_MLME
+ NMI_WFI_deinit_mon_interface();
+ #endif
+ #endif
+ }
+
+ linux_wlan_unlock(&close_exit_sync);
+ nic->mac_opened=0;
+
+ return 0;
+}
+
+
+int mac_ioctl(struct net_device *ndev, struct ifreq *req, int cmd){
+
+ NMI_Uint8 *buff= NULL;
+ NMI_Sint8 rssi;
+ NMI_Uint32 size=0,length=0;
+ perInterface_wlan_t* nic;
+ struct NMI_WFI_priv* priv;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+
+
+ //struct iwreq *wrq = (struct iwreq *) req; // tony moved to case SIOCSIWPRIV
+ #ifdef USE_WIRELESS
+ nic = netdev_priv(ndev);
+
+ if(!g_linux_wlan->nmc1000_initialized)
+ return 0;
+
+ #endif
+
+ switch(cmd){
+ // [[ added by tony for SIOCDEVPRIVATE
+ case SIOCDEVPRIVATE+1:
+ {
+ android_wifi_priv_cmd priv_cmd;
+
+ PRINT_INFO(GENERIC_DBG, "in SIOCDEVPRIVATE+1\n");
+
+ if (copy_from_user(&priv_cmd, req->ifr_data, sizeof(android_wifi_priv_cmd))) {
+ s32Error = -EFAULT;
+ goto done;
+ }
+
+ buff = kmalloc(priv_cmd.total_len, GFP_KERNEL);
+ if (!buff)
+ {
+ s32Error = -ENOMEM;
+ goto done;
+ }
+
+ if (copy_from_user(buff, priv_cmd.buf, priv_cmd.total_len)) {
+ s32Error = -EFAULT;
+ goto done;
+ }
+
+ PRINT_INFO(GENERIC_DBG, "%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, buff, req->ifr_name);
+
+ if (strnicmp(buff, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, SCAN-ACTIVE command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "SCAN-PASSIVE", strlen("SCAN-PASSIVE")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, SCAN-PASSIVE command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "RXFILTER-START", strlen("RXFILTER-START")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-START command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "RXFILTER-STOP", strlen("RXFILTER-STOP")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-STOP command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "RXFILTER-ADD", strlen("RXFILTER-ADD")) == 0) {
+ int filter_num = *(buff + strlen("RXFILTER-ADD") + 1) - '0';
+ PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-ADD command, filter_num=%d\n", __FUNCTION__, filter_num);
+ }else if (strnicmp(buff, "RXFILTER-REMOVE", strlen("RXFILTER-REMOVE")) == 0) {
+ int filter_num = *(buff + strlen("RXFILTER-REMOVE") + 1) - '0';
+ PRINT_INFO(GENERIC_DBG, "%s, RXFILTER-REMOVE command, filter_num=%d\n", __FUNCTION__, filter_num);
+ }else if (strnicmp(buff, "BTCOEXSCAN-START", strlen("BTCOEXSCAN-START")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-START command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "BTCOEXSCAN-STOP", strlen("BTCOEXSCAN-STOP")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, BTCOEXSCAN-STOP command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, BTCOEXMODE command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "SETBAND", strlen("SETBAND")) == 0) {
+ uint band = *(buff + strlen("SETBAND") + 1) - '0';
+ PRINT_INFO(GENERIC_DBG, "%s, SETBAND command, band=%d\n", __FUNCTION__, band);
+ }else if (strnicmp(buff, "GETBAND", strlen("GETBAND")) == 0) {
+ PRINT_INFO(GENERIC_DBG, "%s, GETBAND command\n", __FUNCTION__);
+ }else if (strnicmp(buff, "COUNTRY", strlen("COUNTRY")) == 0) {
+ char *country_code = buff + strlen("COUNTRY") + 1;
+ PRINT_INFO(GENERIC_DBG, "%s, COUNTRY command, country_code=%s\n", __FUNCTION__, country_code);
+ }else {
+ PRINT_INFO(GENERIC_DBG, "%s, Unknown command\n", __FUNCTION__);
+ }
+ }break;
+ // ]] 2013-06-24
+ case SIOCSIWPRIV:
+ {
+ struct iwreq *wrq = (struct iwreq *) req; // added by tony
+
+ size = wrq->u.data.length;
+
+ if (size&& wrq->u.data.pointer)
+ {
+ buff = kmalloc(size, GFP_KERNEL);
+ if (!buff)
+ {
+ s32Error = -ENOMEM;
+ goto done;
+ }
+
+ if (copy_from_user
+ (buff, wrq->u.data.pointer,
+ wrq->u.data.length))
+ {
+ s32Error = -EFAULT;
+ goto done;
+ }
+
+ if(strnicmp(buff,"RSSI",length) == 0)
+ {
+
+ #ifdef USE_WIRELESS
+ priv = wiphy_priv(nic->nmc_netdev->ieee80211_ptr->wiphy);
+ s32Error = host_int_get_rssi(priv->hNMIWFIDrv, &(rssi));
+ if(s32Error)
+ PRINT_ER("Failed to send get rssi param's message queue ");
+ #endif
+ PRINT_INFO(GENERIC_DBG,"RSSI :%d\n",rssi);
+
+ /*Rounding up the rssi negative value*/
+ rssi+=5;
+
+ snprintf(buff, size, "rssi %d", rssi);
+
+ if (copy_to_user(wrq->u.data.pointer, buff, size)) {
+ PRINT_ER("%s: failed to copy data to user buffer\n", __FUNCTION__);
+ s32Error = -EFAULT;
+ goto done;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ PRINT_INFO(GENERIC_DBG,"Command - %d - has been received\n",cmd);
+ s32Error = -EOPNOTSUPP;
+ goto done;
+ }
+ }
+
+done:
+
+ if(buff != NULL)
+ {
+ kfree(buff);
+ }
+
+ return s32Error;
+}
+
+void frmw_to_linux(uint8_t *buff, uint32_t size,uint32_t pkt_offset){
+
+ unsigned int frame_len = 0;
+ int stats;
+ unsigned char* buff_to_send = NULL;
+ struct sk_buff *skb;
+ //char *saddr,*daddr;
+ char*pu8UdpBuffer;
+ struct iphdr *ih;
+ struct net_device* nmc_netdev;
+ perInterface_wlan_t *nic;
+// static int once = 1;
+// int i;
+ nmc_netdev = GetIfHandler(buff);
+ if(nmc_netdev == NULL)
+ return;
+ buff += pkt_offset;
+ //AdjustDstAddr(nmc_netdev,buff);
+
+ nic = netdev_priv(nmc_netdev);
+
+ if(size > 0){
+
+ frame_len = size;
+ buff_to_send = buff;
+
+
+ /* Need to send the packet up to the host, allocate a skb buffer */
+ skb = dev_alloc_skb(frame_len);
+ if(skb == NULL){
+ PRINT_ER("Low memory - packet droped\n");
+ return;
+ }
+
+ skb_reserve(skb, (unsigned int)skb->data & 0x3);
+
+ if(g_linux_wlan == NULL || nmc_netdev == NULL){
+ PRINT_ER("nmc_netdev in g_linux_wlan is NULL");
+ }
+ skb->dev = nmc_netdev;
+
+ if(skb->dev == NULL){
+ PRINT_ER("skb->dev is NULL\n");
+ }
+
+ /*
+ for(i=0;i<40;i++)
+ {
+ if(i<frame_len)
+ NMI_PRINTF("buff_to_send[%d]=%2x\n",i,buff_to_send[i]);
+
+ }*/
+
+ //skb_put(skb, frame_len);
+ memcpy(skb_put(skb, frame_len),buff_to_send, frame_len);
+
+ //NMI_PRINTF("After MEM_CPY\n");
+
+ //nic = netdev_priv(nmc_netdev);
+
+#ifdef USE_WIRELESS
+ /* if(nic->monitor_flag)
+ {
+ NMI_WFI_monitor_rx(nic->nmc_netdev,skb);
+ return;
+ }*/
+#endif
+ skb->protocol = eth_type_trans(skb, nmc_netdev);
+ /*get source and dest ip addresses*/
+ ih = (struct iphdr *)(skb->data+sizeof(struct ethhdr));
+ //saddr = &ih->saddr;
+ //daddr = &ih->daddr;
+ //NMI_PRINTF("[REC]Source IP = %.2x:%.2x:%.2x:%.2x",saddr[0],saddr[1],
+ //saddr[2],saddr[3]);
+ //NMI_PRINTF("[REC]Dest IP = %.2x:%.2x:%.2x:%.2x",daddr[0],daddr[1],
+ // daddr[2],daddr[3]);
+ //NMI_PRINTF("Protocol = %4x\n",skb->protocol);
+ pu8UdpBuffer = (char*)ih + sizeof(struct iphdr);
+ //printk("Port No = %d,%d\n",pu8UdpBuffer[1],pu8UdpBuffer[3]);
+ if(buff_to_send[35] == 67 && buff_to_send[37] == 68)
+ {
+ PRINT_D(RX_DBG,"DHCP Message received\n");
+ }
+
+ /* Send the packet to the stack by giving it to the bridge */
+ nic->netstats.rx_packets++;
+ nic->netstats.rx_bytes+=frame_len;
+ stats = netif_rx(skb);
+ //printk("netif_rx ret value is: %d\n",stats);
+ PRINT_D(RX_DBG,"netif_rx ret value is: %d\n",stats);
+ }else{
+ PRINT_ER("Discard sending packet with len = %d\n",size);
+ }
+}
+
+void NMI_WFI_mgmt_rx(uint8_t *buff, uint32_t size)
+{
+ int i = 0;
+ perInterface_wlan_t* nic;
+ //struct net_device* nmc_netdev = GetIfHandler(buff);
+ for(i = 0;i< g_linux_wlan->u8NoIfcs;i++)
+ {
+ nic = netdev_priv(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ if(nic->monitor_flag)
+ NMI_WFI_monitor_rx(buff,size);
+
+ #ifdef NMI_P2P
+ if( (buff[0]== nic->g_struct_frame_reg[0].frame_type && nic->g_struct_frame_reg[0].reg) ||
+ (buff[0]== nic->g_struct_frame_reg[1].frame_type && nic->g_struct_frame_reg[1].reg) )
+ {
+ NMI_WFI_p2p_rx(g_linux_wlan->strInterfaceInfo[i].nmc_netdev,buff,size);
+ }
+ #endif
+ }
+
+}
+int nmc_netdev_init(void){
+
+ int i;
+ perInterface_wlan_t* nic;
+ struct net_device* ndev;
+
+ linux_wlan_init_lock("close_exit_sync",&close_exit_sync,0);
+
+ /*create the common structure*/
+ g_linux_wlan=(linux_wlan_t*)NMI_MALLOC(sizeof(linux_wlan_t));
+ memset(g_linux_wlan,0,sizeof(linux_wlan_t));
+
+ /*Reset interrupt count debug*/
+ int_rcvdU= 0;
+ int_rcvdB= 0;
+ int_clrd = 0;
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ register_inetaddr_notifier(&g_dev_notifier);
+ #endif
+
+ for(i=0;i<NUM_CONCURRENT_IFC;i++)
+ {
+ /*allocate first ethernet device with perinterface_wlan_t as its private data*/
+ if(! (ndev = alloc_etherdev(sizeof(perInterface_wlan_t)))){
+ PRINT_ER("Failed to allocate ethernet dev\n");
+ return -1;
+ }
+
+ nic = netdev_priv(ndev);
+ memset(nic,sizeof(perInterface_wlan_t),0);
+
+
+
+ /*Name the Devices*/
+
+ if(i==0)
+ {
+ #if defined(NM73131) // tony, 2012-09-20
+ strcpy(ndev->name,"nmc_eth%d");
+ #elif defined(PLAT_CLM9722) // rachel
+ strcpy(ndev->name,"eth%d");
+ #else //PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_ALLWINNER_A31, PLAT_AML8726_M3 or PLAT_WMS8304
+ strcpy(ndev->name,"wlan%d");
+ #endif
+ }
+ else
+ strcpy(ndev->name,"p2p%d");
+
+ nic->u8IfIdx = g_linux_wlan->u8NoIfcs;
+ nic->nmc_netdev = ndev;
+ g_linux_wlan->strInterfaceInfo[g_linux_wlan->u8NoIfcs].nmc_netdev = ndev;
+ g_linux_wlan->u8NoIfcs++;
+ nmc_set_netdev_ops(ndev);
+
+ #ifdef USE_WIRELESS
+ {
+ struct wireless_dev *wdev;
+ /*Register WiFi*/
+ wdev = NMI_WFI_WiphyRegister(ndev);
+
+ /* set netdev, tony */
+ SET_NETDEV_DEV(ndev, &local_sdio_func->dev);
+
+ if(wdev == NULL){
+ PRINT_ER("Can't register NMI Wiphy\n");
+ return -1;
+ }
+
+ /*linking the wireless_dev structure with the netdevice*/
+ nic->nmc_netdev->ieee80211_ptr = wdev;
+ nic->nmc_netdev->ml_priv = nic;
+ wdev->netdev = nic->nmc_netdev;
+ nic->netstats.rx_packets=0;
+ nic->netstats.tx_packets=0;
+ nic->netstats.rx_bytes=0;
+ nic->netstats.tx_bytes=0;
+
+ }
+ #endif
+
+
+ if(register_netdev(ndev)){
+ PRINT_ER("Device couldn't be registered - %s\n", ndev->name);
+ return -1; /* ERROR */
+ }
+
+ nic->iftype = STATION_MODE;
+ nic->mac_opened=0;
+
+ }
+
+ #ifndef NMI_SDIO
+ if(!linux_spi_init(&g_linux_wlan->nmc_spidev)){
+ PRINT_ER("Can't initialize SPI \n");
+ return -1; /* ERROR */
+ }
+ g_linux_wlan->nmc_spidev = nmc_spi_dev;
+ #else
+ g_linux_wlan->nmc_sdio_func= local_sdio_func;
+ #endif
+
+ return 0;
+}
+
+
+/*The 1st function called after module inserted*/
+static int __init init_nmc_driver(void){
+
+
+#if defined (NMC_DEBUGFS)
+ if(nmc_debugfs_init() < 0) {
+ NMI_PRINTF("fail to create debugfs for nmc driver\n");
+ return -1;
+ }
+#endif
+
+ printk("IN INIT FUNCTION\n");
+ printk("*** NMC1000 driver VERSION=[%s] REVISON=[%s] FW_VER=[%s] ***\n", __DRIVER_VERSION__, SVNREV, STA_FIRMWARE);
+
+ linux_wlan_device_power(1);
+ msleep(100);
+ linux_wlan_device_detection(1);
+
+#ifdef NMI_SDIO
+ {
+ int ret;
+
+ ret = sdio_register_driver(&nmc_bus);
+ if (ret < 0) {
+ printk("init_nmc_driver: Failed register sdio driver\n");
+ }
+
+ return ret;
+ }
+#else
+ PRINT_D(INIT_DBG,"Initializing netdev\n");
+ if(nmc_netdev_init()){
+ PRINT_ER("Couldn't initialize netdev\n");
+ }
+
+ PRINT_D(INIT_DBG,"Device has been initialized successfully\n");
+ return 0;
+#endif
+}
+late_initcall(init_nmc_driver);
+
+static void __exit exit_nmc_driver(void)
+{
+ int i = 0;
+ perInterface_wlan_t* nic[NUM_CONCURRENT_IFC];
+ #define CLOSE_TIMEOUT 12*1000
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ unregister_inetaddr_notifier(&g_dev_notifier);
+ #endif
+
+ for(i=0;i<NUM_CONCURRENT_IFC;i++)
+ {
+ nic[i]=netdev_priv(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ }
+
+
+
+ if((g_linux_wlan != NULL) &&g_linux_wlan->nmc_firmware != NULL)
+ {
+ release_firmware(g_linux_wlan->nmc_firmware);
+ g_linux_wlan->nmc_firmware = NULL;
+ }
+
+
+ if( (g_linux_wlan != NULL) &&( ((g_linux_wlan->strInterfaceInfo[0].nmc_netdev) != NULL)
+ || ((g_linux_wlan->strInterfaceInfo[1].nmc_netdev) != NULL)))
+
+ {
+ PRINT_D(INIT_DBG,"Waiting for mac_close ....\n");
+
+ if(linux_wlan_lock_timeout(&close_exit_sync, CLOSE_TIMEOUT) < 0)
+ PRINT_D(INIT_DBG,"Closed TimedOUT\n");
+ else
+ PRINT_D(INIT_DBG,"mac_closed\n");
+
+
+
+
+ for(i=0;i<NUM_CONCURRENT_IFC;i++)
+ {
+
+ if(g_linux_wlan->strInterfaceInfo[i].nmc_netdev != NULL)
+ {
+ if(nic[i]->mac_opened)
+
+ {
+ mac_close(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ }
+
+ PRINT_D(INIT_DBG,"Unregistering netdev %p \n",g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ unregister_netdev(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+
+
+ #ifdef USE_WIRELESS
+ PRINT_D(INIT_DBG,"Freeing Wiphy...\n");
+ NMI_WFI_WiphyFree(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ #endif
+
+ PRINT_D(INIT_DBG,"Freeing netdev...\n");
+ free_netdev(g_linux_wlan->strInterfaceInfo[i].nmc_netdev);
+ }
+
+ }
+ }
+
+#ifdef USE_WIRELESS
+#ifdef NMI_AP_EXTERNAL_MLME
+ // Bug 4600 : NMI_WFI_deinit_mon_interface was already called at mac_close
+ //NMI_WFI_deinit_mon_interface();
+#endif
+#endif
+
+if(g_linux_wlan->open_ifcs==0)
+{
+ #ifndef NMI_SDIO
+ PRINT_D(INIT_DBG,"SPI unregsiter...\n");
+ spi_unregister_driver(&nmc_bus);
+ #else
+ PRINT_D(INIT_DBG,"SDIO unregsiter...\n");
+ sdio_unregister_driver(&nmc_bus);
+ #endif
+
+ linux_wlan_deinit_lock(&close_exit_sync);
+ NMI_FREE(g_linux_wlan);
+ g_linux_wlan = NULL;
+
+ PRINT_D(INIT_DBG,"Module_exit Done.\n");
+
+#if defined (NMC_DEBUGFS)
+ nmc_debugfs_remove();
+#endif
+
+ linux_wlan_device_detection(0);
+ linux_wlan_device_power(0);
+}
+}
+module_exit(exit_nmc_driver);
+
+MODULE_LICENSE("GPL");
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.c
new file mode 100755
index 00000000..08865acf
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.c
@@ -0,0 +1,277 @@
+#include "NMI_WFI_NetDevice.h"
+
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/host.h>
+
+
+
+#if defined (NM73131_0_BOARD)
+#define SDIO_MODALIAS "nmi_sdio"
+#else
+#define SDIO_MODALIAS "nmc1000_sdio"
+#endif
+
+#ifdef NMC_ASIC_A0
+#if defined (NM73131_0_BOARD)
+ #define MAX_SPEED 50000000
+#elif defined (PLAT_ALLWINNER_A10)
+ #define MAX_SPEED 50000000/*15000000*/
+#elif defined (PLAT_ALLWINNER_A20)
+ #define MAX_SPEED 45000000 //40000000 //50000000
+#elif defined (PLAT_ALLWINNER_A23)
+ #define MAX_SPEED 45000000
+#elif defined (PLAT_ALLWINNER_A31)
+ #define MAX_SPEED 45000000
+#elif defined (PLAT_PANDA_ES_OMAP4460)
+ #define MAX_SPEED 25000000 //johnny change
+#elif defined(PLAT_WM8880)
+ #define MAX_SPEED /*20000000*/50000000 /* tony increased to 50000000 */
+#elif defined (PLAT_UBUNTU_X86) // tony
+ #define MAX_SPEED 25000000
+#elif defined (PLAT_RKXXXX)
+#define MAX_SPEED 50000000
+#else
+#define MAX_SPEED 50000000
+#endif
+#else /* NMC_ASIC_A0 */
+/* Limit clk to 6MHz on FPGA. */
+#define MAX_SPEED 6000000
+#endif /* NMC_ASIC_A0 */
+
+
+struct sdio_func* local_sdio_func = NULL;
+extern linux_wlan_t* g_linux_wlan;
+extern int nmc_netdev_init(void);
+extern int sdio_clear_int(void);
+extern void nmi_handle_isr(void);
+
+static unsigned int sdio_default_speed=0;
+
+#define SDIO_VENDOR_ID_NMI 0x0296
+#define SDIO_DEVICE_ID_NMI 0x5347
+
+static const struct sdio_device_id nmi_sdio_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_NMI,SDIO_DEVICE_ID_NMI) },
+};
+
+
+static void nmi_sdio_interrupt(struct sdio_func *func)
+{
+#ifndef NMI_SDIO_IRQ_GPIO
+ sdio_release_host(func);
+ nmi_handle_isr();
+ sdio_claim_host(func);
+#endif
+}
+
+
+int linux_sdio_cmd52(sdio_cmd52_t *cmd){
+ struct sdio_func *func = g_linux_wlan->nmc_sdio_func;
+ int ret;
+ u8 data;
+
+ sdio_claim_host(func);
+
+ func->num = cmd->function;
+ if (cmd->read_write) { /* write */
+ if (cmd->raw) {
+ sdio_writeb(func, cmd->data, cmd->address, &ret);
+ data = sdio_readb(func, cmd->address, &ret);
+ cmd->data = data;
+ } else {
+ sdio_writeb(func, cmd->data, cmd->address, &ret);
+ }
+ } else { /* read */
+ data = sdio_readb(func, cmd->address, &ret);
+ cmd->data = data;
+ }
+
+ sdio_release_host(func);
+
+ if (ret < 0) {
+ printk("nmi_sdio_cmd52..failed, err(%d)\n", ret);
+ return 0;
+ }
+ return 1;
+}
+
+
+ int linux_sdio_cmd53(sdio_cmd53_t *cmd){
+ struct sdio_func *func = g_linux_wlan->nmc_sdio_func;
+ int size, ret;
+
+ sdio_claim_host(func);
+
+ func->num = cmd->function;
+ func->cur_blksize = cmd->block_size;
+ if (cmd->block_mode)
+ size = cmd->count * cmd->block_size;
+ else
+ size = cmd->count;
+
+ if (cmd->read_write) { /* write */
+ ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size);
+ } else { /* read */
+ ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size);
+ }
+
+ sdio_release_host(func);
+
+
+ if (ret < 0) {
+ printk("nmi_sdio_cmd53..failed, err(%d)\n", ret);
+ return 0;
+ }
+
+ return 1;
+}
+
+volatile int probe = 0; //COMPLEMENT_BOOT
+extern void set_wifi_name(char * name);
+
+static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id){
+ printk("probe function\n");
+
+#ifdef COMPLEMENT_BOOT
+ if(local_sdio_func != NULL)
+ {
+ local_sdio_func = func;
+ probe = 1;
+ PRINT_D(INIT_DBG,"local_sdio_func isn't NULL\n");
+ return 0;
+ }
+#endif
+ PRINT_D(INIT_DBG,"Initializing netdev\n");
+ local_sdio_func = func;
+ if(nmc_netdev_init()){
+ PRINT_ER("Couldn't initialize netdev\n");
+ return -1;
+ }
+ //added by rubbitxiao
+ set_wifi_name("nmc1000_android4.4.ko");
+
+ return 0;
+}
+
+static void linux_sdio_remove(struct sdio_func *func)
+{
+ /**
+ TODO
+ **/
+
+}
+
+struct sdio_driver nmc_bus = {
+ .name = SDIO_MODALIAS,
+ .id_table = nmi_sdio_ids,
+ .probe = linux_sdio_probe,
+ .remove = linux_sdio_remove,
+};
+
+void enable_sdio_interrupt(void){
+ int ret;
+
+#ifndef NMI_SDIO_IRQ_GPIO
+
+ sdio_claim_host(local_sdio_func);
+ ret = sdio_claim_irq(local_sdio_func, nmi_sdio_interrupt);
+ sdio_release_host(local_sdio_func);
+
+ if (ret < 0) {
+ PRINT_ER("can't claim sdio_irq, err(%d)\n", ret);
+ }
+#endif
+}
+
+void disable_sdio_interrupt(void){
+
+#ifndef NMI_SDIO_IRQ_GPIO
+ int ret;
+
+ PRINT_D(INIT_DBG,"disable_sdio_interrupt IN\n");
+
+ sdio_claim_host(local_sdio_func);
+ ret = sdio_release_irq(local_sdio_func);
+ if (ret < 0) {
+ PRINT_ER("can't release sdio_irq, err(%d)\n", ret);
+ }
+ sdio_release_host(local_sdio_func);
+
+ PRINT_D(INIT_DBG,"disable_sdio_interrupt OUT\n");
+#endif
+}
+
+static int linux_sdio_set_speed(int speed)
+{
+#if defined(PLAT_AML8726_M3)
+
+#else
+ struct mmc_ios ios;
+ sdio_claim_host(local_sdio_func);
+
+ memcpy((void *)&ios,(void *)&local_sdio_func->card->host->ios,sizeof(struct mmc_ios));
+ local_sdio_func->card->host->ios.clock = speed;
+ ios.clock = speed;
+ local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host,&ios);
+ sdio_release_host(local_sdio_func);
+ PRINT_ER("@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed);
+#endif
+ return 1;
+}
+
+static int linux_sdio_get_speed(void)
+{
+ return local_sdio_func->card->host->ios.clock;
+}
+
+int linux_sdio_init(void* pv){
+
+#if defined(PLAT_AML8726_M3)
+//[[ rachel - copy from v.3.0 (by johnny)
+ #ifdef NMC1000_SINGLE_TRANSFER
+ #define NMI_SDIO_BLOCK_SIZE 256
+ #else
+ #define NMI_SDIO_BLOCK_SIZE 512
+ #endif
+
+ int err;
+
+ sdio_claim_host(local_sdio_func);
+
+ printk("johnny linux_sdio_init %d\n", local_sdio_func->num );
+
+ local_sdio_func->num = 0;
+ sdio_set_block_size(local_sdio_func, NMI_SDIO_BLOCK_SIZE);
+
+ local_sdio_func->num = 1;
+ sdio_enable_func(local_sdio_func);
+ sdio_set_block_size(local_sdio_func, NMI_SDIO_BLOCK_SIZE);
+
+ sdio_release_host(local_sdio_func);
+
+ printk("johnny linux_sdio_init\n");
+#endif
+
+ sdio_default_speed = linux_sdio_get_speed();
+ return 1;
+}
+
+void linux_sdio_deinit(void *pv){
+ sdio_unregister_driver(&nmc_bus);
+}
+
+int linux_sdio_set_max_speed(void)
+{
+ return linux_sdio_set_speed(MAX_SPEED);
+}
+
+int linux_sdio_set_default_speed(void)
+{
+ return linux_sdio_set_speed(sdio_default_speed);
+}
+
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.h
new file mode 100755
index 00000000..68b3da25
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_sdio.h
@@ -0,0 +1,14 @@
+extern struct sdio_func *local_sdio_func;
+extern struct sdio_driver nmc_bus;
+
+#include <linux/mmc/sdio_func.h>
+
+int linux_sdio_init(void*);
+void linux_sdio_deinit(void*);
+int linux_sdio_cmd52(sdio_cmd52_t *cmd);
+int linux_sdio_cmd53(sdio_cmd53_t *cmd);
+void enable_sdio_interrupt(void);
+void disable_sdio_interrupt(void);
+int linux_sdio_set_max_speed(void);
+int linux_sdio_set_default_speed(void);
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.c
new file mode 100755
index 00000000..a6682b47
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.c
@@ -0,0 +1,489 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <asm/uaccess.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+
+#include "linux_wlan_common.h"
+
+#define USE_SPI_DMA 0 //johnny add
+
+#ifdef NMC_ASIC_A0
+#if defined(PLAT_PANDA_ES_OMAP4460)
+#define MIN_SPEED 12000000
+#define MAX_SPEED 24000000
+#elif defined(PLAT_WMS8304)
+#define MIN_SPEED 12000000
+#define MAX_SPEED 24000000 //4000000
+#else
+#define MIN_SPEED 24000000
+#define MAX_SPEED 48000000
+#endif
+#else /* NMC_ASIC_A0 */
+/* Limit clk to 6MHz on FPGA. */
+#define MIN_SPEED 6000000
+#define MAX_SPEED 6000000
+#endif /* NMC_ASIC_A0 */
+
+static uint32_t SPEED = MIN_SPEED;
+
+struct spi_device* nmc_spi_dev;
+void linux_spi_deinit(void* vp);
+
+static int __init nmc_bus_probe(struct spi_device* spi){
+
+ PRINT_D(BUS_DBG,"spiModalias: %s\n",spi->modalias);
+ PRINT_D(BUS_DBG,"spiMax-Speed: %d\n",spi->max_speed_hz);
+ nmc_spi_dev = spi;
+
+ return 0;
+}
+
+static int __devexit nmc_bus_remove(struct spi_device* spi){
+
+ //linux_spi_deinit(NULL);
+
+ return 0;
+}
+
+
+struct spi_driver nmc_bus __refdata = {
+ .driver = {
+ .name = MODALIAS,
+ },
+ .probe = nmc_bus_probe,
+ .remove = __devexit_p(nmc_bus_remove),
+};
+
+
+void linux_spi_deinit(void* vp){
+
+ spi_unregister_driver(&nmc_bus);
+
+ SPEED = MIN_SPEED;
+ PRINT_ER("@@@@@@@@@@@@ restore SPI speed to %d @@@@@@@@@\n", SPEED);
+
+}
+
+
+
+int linux_spi_init(void* vp){
+ int ret = 1;
+ static int called = 0;
+
+
+ if(called == 0){
+ called++;
+ if(&nmc_bus == NULL){
+ PRINT_ER("nmc_bus address is NULL\n");
+ }
+ ret = spi_register_driver(&nmc_bus);
+ }
+
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+}
+
+#if defined(PLAT_WMS8304) // rachel
+#define TXRX_PHASE_SIZE (4096)
+#endif
+
+#if defined (NM73131_0_BOARD)
+
+int linux_spi_write(uint8_t* b, uint32_t len){
+
+ int ret;
+
+ if(len > 0 && b != NULL) {
+ struct spi_message msg;
+ PRINT_D(BUS_DBG,"Request writing %d bytes\n",len);
+ struct spi_transfer tr = {
+ .tx_buf = b,
+ .len = len,
+ .speed_hz = SPEED,
+ .delay_usecs = 0,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&tr,&msg);
+ ret = spi_sync(nmc_spi_dev,&msg);
+ if(ret < 0){
+ PRINT_ER( "SPI transaction failed\n");
+ }
+
+ } else{
+ PRINT_ER("can't write data with the following length: %d\n",len);
+ PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n",len);
+ ret = -1;
+ }
+
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+
+ return ret;
+}
+
+#elif defined(TXRX_PHASE_SIZE)
+
+int linux_spi_write(uint8_t* b, uint32_t len){
+ int ret;
+ if(len > 0 && b != NULL) {
+ int i = 0;
+ int blk = len/TXRX_PHASE_SIZE;
+ int remainder = len%TXRX_PHASE_SIZE;
+
+ char *r_buffer = (char*) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
+ if(! r_buffer){
+ PRINT_ER("Failed to allocate memory for r_buffer\n");
+ }
+
+ if(blk)
+ {
+ while(i<blk)
+ {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ .tx_buf = b + (i*TXRX_PHASE_SIZE),
+ //.rx_buf = NULL,
+ .len = TXRX_PHASE_SIZE,
+ .speed_hz = SPEED,
+ .bits_per_word = 8,
+ .delay_usecs = 0,
+ };
+ /*
+ char *r_buffer = (char*) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
+ if(! r_buffer){
+ PRINT_ER("Failed to allocate memory for r_buffer\n");
+ }
+ */
+ tr.rx_buf = r_buffer;
+
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+
+ spi_message_add_tail(&tr, &msg);
+ ret = spi_sync(nmc_spi_dev, &msg);
+ if(ret < 0) {
+ PRINT_ER( "SPI transaction failed\n");
+ }
+ //i += MJ_WRITE_SIZE;
+ i++;
+
+ }
+ }
+ if(remainder)
+ {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ .tx_buf = b + (blk*TXRX_PHASE_SIZE),
+ //.rx_buf = NULL,
+ .len = remainder,
+ .speed_hz = SPEED,
+ .bits_per_word = 8,
+ .delay_usecs = 0,
+ };
+ /*
+ char *r_buffer = (char*) kzalloc(remainder, GFP_KERNEL);
+ if(! r_buffer){
+ PRINT_ER("Failed to allocate memory for r_buffer\n");
+ }
+ */
+ tr.rx_buf = r_buffer;
+
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+
+ spi_message_add_tail(&tr, &msg);
+ ret = spi_sync(nmc_spi_dev, &msg);
+ if(ret < 0) {
+ PRINT_ER( "SPI transaction failed\n");
+ }
+ }
+ if(r_buffer)
+ kfree(r_buffer);
+ } else {
+ PRINT_ER("can't write data with the following length: %d\n",len);
+ PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n",len);
+ ret = -1;
+ }
+
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+
+}
+
+#else
+int linux_spi_write(uint8_t* b, uint32_t len){
+
+ int ret;
+ struct spi_message msg;
+
+ if(len > 0 && b != NULL){
+ struct spi_transfer tr = {
+ .tx_buf = b,
+ //.rx_buf = r_buffer,
+ .len = len,
+ .speed_hz = SPEED,
+ .delay_usecs = 0,
+ };
+ char *r_buffer = (char*) kzalloc(len, GFP_KERNEL);
+ if(! r_buffer){
+ PRINT_ER("Failed to allocate memory for r_buffer\n");
+ }
+ tr.rx_buf = r_buffer;
+ PRINT_D(BUS_DBG,"Request writing %d bytes\n",len);
+
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+//[[johnny add
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+//]]
+ spi_message_add_tail(&tr,&msg);
+
+ ret = spi_sync(nmc_spi_dev,&msg);
+ if(ret < 0){
+ PRINT_ER( "SPI transaction failed\n");
+ }
+
+ kfree(r_buffer);
+ }else{
+ PRINT_ER("can't write data with the following length: %d\n",len);
+ PRINT_ER("FAILED due to NULL buffer or ZERO length check the following length: %d\n",len);
+ ret = -1;
+ }
+
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+
+ return ret;
+}
+
+#endif
+
+#if defined (NM73131_0_BOARD)
+
+int linux_spi_read(unsigned char*rb, unsigned long rlen){
+
+ int ret;
+
+ if(rlen > 0) {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ .rx_buf = rb,
+ .len = rlen,
+ .speed_hz = SPEED,
+ .delay_usecs = 0,
+
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&tr,&msg);
+ ret = spi_sync(nmc_spi_dev,&msg);
+ if(ret < 0){
+ PRINT_ER("SPI transaction failed\n");
+ }
+ }else{
+ PRINT_ER("can't read data with the following length: %ld\n",rlen);
+ ret = -1;
+ }
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+}
+
+#elif defined(TXRX_PHASE_SIZE)
+
+int linux_spi_read(unsigned char*rb, unsigned long rlen){
+ int ret;
+
+ if(rlen > 0) {
+ int i =0;
+
+ int blk = rlen/TXRX_PHASE_SIZE;
+ int remainder = rlen%TXRX_PHASE_SIZE;
+
+ char *t_buffer = (char*) kzalloc(TXRX_PHASE_SIZE, GFP_KERNEL);
+ if(! t_buffer){
+ PRINT_ER("Failed to allocate memory for t_buffer\n");
+ }
+
+ if(blk)
+ {
+ //printk(" read blk %d cnt\n", blk);
+ while(i<blk)
+ {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ //.tx_buf = NULL,
+ .rx_buf = rb + (i*TXRX_PHASE_SIZE),
+ .len = TXRX_PHASE_SIZE,
+ .speed_hz = SPEED,
+ .bits_per_word = 8,
+ .delay_usecs = 0,
+ };
+ tr.tx_buf = t_buffer;
+
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+
+ spi_message_add_tail(&tr, &msg);
+ ret = spi_sync(nmc_spi_dev, &msg);
+ if(ret < 0) {
+ PRINT_ER( "SPI transaction failed\n");
+ }
+ i ++;
+ }
+ }
+ if(remainder)
+ {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ //.tx_buf = NULL,
+ .rx_buf = rb + (blk*TXRX_PHASE_SIZE),
+ .len = remainder,
+ .speed_hz = SPEED,
+ .bits_per_word = 8,
+ .delay_usecs = 0,
+ };
+ /*
+ char *t_buffer = (char*) kzalloc(remainder, GFP_KERNEL);
+ if(! t_buffer){
+ PRINT_ER("Failed to allocate memory for t_buffer\n");
+ }
+ */
+ tr.tx_buf = t_buffer;
+
+ //printk(" read remain, %d bytes\n", remainder);
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+
+ spi_message_add_tail(&tr, &msg);
+ ret = spi_sync(nmc_spi_dev, &msg);
+ if(ret < 0) {
+ PRINT_ER( "SPI transaction failed\n");
+ }
+ }
+
+ if(t_buffer)
+ kfree(t_buffer);
+ }else {
+ PRINT_ER("can't read data with the following length: %ld\n",rlen);
+ ret = -1;
+ }
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+}
+
+#else
+int linux_spi_read(unsigned char*rb, unsigned long rlen){
+
+ int ret;
+
+ if(rlen > 0){
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ // .tx_buf = t_buffer,
+ .rx_buf = rb,
+ .len = rlen,
+ .speed_hz = SPEED,
+ .delay_usecs = 0,
+
+ };
+ char *t_buffer = (char*) kzalloc(rlen, GFP_KERNEL);
+ if(! t_buffer){
+ PRINT_ER("Failed to allocate memory for t_buffer\n");
+ }
+ tr.tx_buf = t_buffer;
+
+ memset(&msg, 0, sizeof(msg));
+ spi_message_init(&msg);
+//[[ johnny add
+ msg.spi = nmc_spi_dev;
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel
+//]]
+ spi_message_add_tail(&tr,&msg);
+
+ ret = spi_sync(nmc_spi_dev,&msg);
+ if(ret < 0){
+ PRINT_ER("SPI transaction failed\n");
+ }
+ kfree(t_buffer);
+ }else{
+ PRINT_ER("can't read data with the following length: %ld\n",rlen);
+ ret = -1;
+ }
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+}
+
+#endif
+
+int linux_spi_write_read(unsigned char*wb, unsigned char*rb, unsigned int rlen)
+{
+
+ int ret;
+
+ if(rlen > 0) {
+ struct spi_message msg;
+ struct spi_transfer tr = {
+ .rx_buf = rb,
+ .tx_buf = wb,
+ .len = rlen,
+ .speed_hz = SPEED,
+ .bits_per_word = 8,
+ .delay_usecs = 0,
+
+ };
+
+ memset(&msg, 0, sizeof(msg)); // rachel
+ spi_message_init(&msg);
+ msg.spi = nmc_spi_dev; // rachel
+ msg.is_dma_mapped = USE_SPI_DMA; // rachel for DMA
+
+ spi_message_add_tail(&tr,&msg);
+ ret = spi_sync(nmc_spi_dev,&msg);
+ if(ret < 0){
+ PRINT_ER("SPI transaction failed\n");
+ }
+ }else{
+ PRINT_ER("can't read data with the following length: %d\n",rlen);
+ ret = -1;
+ }
+ /* change return value to match NMI interface */
+ (ret<0)? (ret = 0):(ret = 1);
+
+ return ret;
+}
+
+int linux_spi_set_max_speed(void)
+{
+ SPEED = MAX_SPEED;
+
+ PRINT_ER("@@@@@@@@@@@@ change SPI speed to %d @@@@@@@@@\n", SPEED);
+ return 1;
+}
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.h
new file mode 100755
index 00000000..6f5eb1ae
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/linux_wlan_spi.h
@@ -0,0 +1,14 @@
+#ifndef LINUX_WLAN_SPI_H
+#define LINUX_WLAN_SPI_H
+
+#include <linux/spi/spi.h>
+extern struct spi_device* nmc_spi_dev;
+extern struct spi_driver nmc_bus;
+
+int linux_spi_init(void* vp);
+void linux_spi_deinit(void* vp);
+int linux_spi_write(uint8_t* b, uint32_t len);
+int linux_spi_read(uint8_t *rb, uint32_t rlen);
+int linux_spi_write_read(unsigned char*wb, unsigned char*rb, unsigned int rlen);
+int linux_spi_set_max_speed(void);
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_custom_gpio.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_custom_gpio.c
new file mode 100755
index 00000000..bd592f3f
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_custom_gpio.c
@@ -0,0 +1,169 @@
+/*
+
+* $Id: nmi_custom_gpio.c, Exp $
+*/
+//#include <linux/mmc/core.h>
+//#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+//#include <linux/mmc/sdio_func.h>
+//#include <linux/mmc/sdio_ids.h>
+//#include <linux/mmc/sdio.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+//via
+#include <mach/gpio_customize_ease.h>
+//johnny add
+#include <mach/hardware.h>
+#include <mach/wmt_gpio.h>
+
+
+
+//static struct mmc_host *mmc_host = NULL;
+
+static GPIO_CTRL gpio_pmu_ctrl;
+static GPIO_CTRL gpio_reset_ctrl;
+static GPIO_CTRL gpio_wake_ctrl;
+GPIO_CTRL gpio_irq_ctrl;
+
+//extern void sdhci_bus_scan(void);
+
+//extern int sprd_3rdparty_gpio_wifi_reset;
+//extern int sprd_3rdparty_gpio_wifi_pwd;
+//extern int sprd_3rdparty_gpio_wifi_wake;
+//extern int sprd_3rdparty_gpio_wifi_irq;
+/*
+int sprd_3rdparty_gpio_wifi_reset = 255;
+int sprd_3rdparty_gpio_wifi_pwd = 255;
+int sprd_3rdparty_gpio_wifi_wake = 255;
+int sprd_3rdparty_gpio_wifi_irq =255;
+*/
+
+void Rubbit_Chk_gpio_irq(int value)
+{
+ printk("[%d] gpio_irq_ctrl.gpio_int_ctl:%x\n",value, REG8_VAL(gpio_irq_ctrl.gpio_int_ctl.address));
+ printk("[%d] gpio_irq_ctrl.gpio_int_status:%x\n",value, REG8_VAL(gpio_irq_ctrl.gpio_int_status.address));
+ printk("[%d] gpio_get_value_any: 0x%x\n", value, gpio_get_value_any(&gpio_irq_ctrl));
+}
+
+void irq_gpio_init(void)
+{
+ //if(!gpio_irq_isEnable_any(&gpio_irq_ctrl) || !gpio_irq_state_any(&gpio_irq_ctrl))
+
+#if 1
+ printk("[MMM] irq is Enable (%d), irq state (%d)\n"
+ , gpio_irq_isEnable_any(&gpio_irq_ctrl)
+ , gpio_irq_state_any(&gpio_irq_ctrl));
+
+#endif
+
+
+ {
+ /*init gpio interruption pin: input, low trigger, pull up, disable int*/
+ gpio_enable_any(&gpio_irq_ctrl, INPUT);
+ set_gpio_irq_triger_mode_any(&gpio_irq_ctrl, IRQ_LOW);
+ gpio_pull_enable_any(&gpio_irq_ctrl,PULL_UP);
+
+ gpio_clean_irq_status_any(&gpio_irq_ctrl);
+
+ enable_gpio_int_any(&gpio_irq_ctrl,INT_DIS);
+ }
+
+}
+
+void irq_gpio_deinit(void)
+{
+ //disable_irq_wake();
+ printk("[MMM] IRQ GPIO DEINIT, called [2] ~~~~~~~~~~~~~~~~~~~\n");
+ Rubbit_Chk_gpio_irq(3);
+ /* below: no interrupt @ 2nd time
+ gpio_enable_any(&gpio_irq_ctrl, INPUT);
+ gpio_pull_enable_any(&gpio_irq_ctrl, PULL_DOWN);
+ */
+
+ // below not working (no interrupt @ 2nd time)
+ //gpio_disable_any(&gpio_irq_ctrl);
+}
+
+
+
+void wifi_gpio_reset(int high_or_low)
+{
+ printk("%s======hi= %d\n",__FUNCTION__,high_or_low);
+/*
+ if(sprd_3rdparty_gpio_wifi_reset > 0)
+ {printk("wifi reset gpio = %d\n", sprd_3rdparty_gpio_wifi_reset);
+ gpio_direction_output(sprd_3rdparty_gpio_wifi_reset, high_or_low);
+ gpio_set_value(sprd_3rdparty_gpio_wifi_reset,high_or_low);
+ }
+ */
+
+ gpio_enable_any(&gpio_reset_ctrl, OUTPUT);
+ gpio_set_value_any(&gpio_reset_ctrl,high_or_low);
+
+}
+static void wifi_card_set_gpios(int high_or_low)
+{
+/*
+ printk("%s**********hi=%d\n",__FUNCTION__,high_or_low);
+ if(sprd_3rdparty_gpio_wifi_reset > 0)
+ {printk("wifi reset gpio = %d\n", sprd_3rdparty_gpio_wifi_reset);
+ gpio_direction_output(sprd_3rdparty_gpio_wifi_reset, high_or_low);
+ gpio_set_value(sprd_3rdparty_gpio_wifi_reset,high_or_low);
+ }
+
+ if(sprd_3rdparty_gpio_wifi_pwd > 0)
+ {printk("wifi pwd gpio = %d\n",sprd_3rdparty_gpio_wifi_pwd);
+ gpio_direction_output(sprd_3rdparty_gpio_wifi_pwd,high_or_low);
+ gpio_set_value(sprd_3rdparty_gpio_wifi_pwd,high_or_low);
+ }
+ if(sprd_3rdparty_gpio_wifi_wake > 0)
+ { printk("wifi wake gpio = %d\n",sprd_3rdparty_gpio_wifi_wake);
+ gpio_direction_output(sprd_3rdparty_gpio_wifi_wake,high_or_low);
+ gpio_set_value(sprd_3rdparty_gpio_wifi_wake,high_or_low);
+ }*/
+
+ parse_gpio_ctrl_string("e3:4:5a:9a:da:49a:4da", &gpio_pmu_ctrl, "wmt.nmc.pmu");//kpadcolu0 pmu enable
+ parse_gpio_ctrl_string("e3:5:5a:9a:da:49a:4da", &gpio_reset_ctrl, "wmt.nmc.reset");//kpadcolu1 reset
+ parse_gpio_ctrl_string("e3:6:5a:9a:da:49a:4da", &gpio_wake_ctrl, "wmt.nmc.wake");//kpadcolu2 wakeup
+ parse_gpio_ctrl_string("df:6:40:80:00:306:360:480:4c0", &gpio_irq_ctrl, "wmt.nmc.irq");//irq gpio6
+ gpio_irq_ctrl.gpio_input_data.address = 0xfe110000;
+ printk("=====================\n");
+ printf_gpio_ctrl(&gpio_pmu_ctrl);
+ printf_gpio_ctrl(&gpio_reset_ctrl);
+ printf_gpio_ctrl(&gpio_wake_ctrl);
+ printf_gpio_ctrl(&gpio_irq_ctrl);
+ printk("=====================high_or_low:%x \n",high_or_low);
+
+ gpio_enable_any(&gpio_pmu_ctrl, OUTPUT);
+ gpio_set_value_any(&gpio_pmu_ctrl,high_or_low);
+
+ gpio_enable_any(&gpio_wake_ctrl, OUTPUT);
+ gpio_set_value_any(&gpio_wake_ctrl,high_or_low);
+
+ gpio_enable_any(&gpio_reset_ctrl, OUTPUT);//enable output
+ gpio_set_value_any(&gpio_reset_ctrl,high_or_low);//output hign
+
+ //gpio_enable_any(&gpio_irq_ctrl, OUTPUT);
+ //gpio_set_value_any(&gpio_irq_ctrl,high_or_low);
+
+}
+
+
+/* Customer function to control hw specific wlan gpios */
+void NmiWifiCardPower(int power)
+{
+ printk("%s, power=%d\n", __FUNCTION__, power);
+
+ wifi_card_set_gpios (power);
+ if(power){
+ wifi_gpio_reset(0);
+ msleep(100);
+ wifi_gpio_reset(1);
+ msleep(100);
+ }else{
+ wifi_gpio_reset(0);
+ }
+}
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_debugfs.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_debugfs.c
new file mode 100755
index 00000000..b11572f4
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_debugfs.c
@@ -0,0 +1,264 @@
+/*
+* NewportMedia WiFi chipset driver test tools - nmi-debug
+* Copyright (c) 2012 NewportMedia Inc.
+* Author: SSW <sswd@nmisemic.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+
+#if defined(NMC_DEBUGFS)
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include "nmi_queue.h"
+#include "nmi_wlan_if.h"
+
+
+static struct dentry *nmc_dir;
+
+/*
+--------------------------------------------------------------------------------
+*/
+
+// [[ linux_wlan_common.h
+#define DBG_REGION_ALL (GENERIC_DBG | HOSTAPD_DBG | HOSTINF_DBG | CORECONFIG_DBG | CFG80211_DBG | INT_DBG | TX_DBG | RX_DBG | LOCK_DBG | INIT_DBG | BUS_DBG | MEM_DBG)
+
+#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR)
+
+atomic_t REGION = ATOMIC_INIT(INIT_DBG | GENERIC_DBG | CFG80211_DBG);
+
+// [[ debug level: DEBUG, INFO, WRN, added by tony 2012-01-09
+atomic_t DEBUG_LEVEL = ATOMIC_INIT(DEBUG | ERR); // if DEBUG_LEVEL is zero, silent, if DEBUG_LEVEL is 0xFFFFFFFF, verbose
+// ]]
+
+// debug_kmsg
+queue g_dumpqueue = {NULL, };
+#define DUMP_QUEUE_MAX (8*1024)
+DECLARE_WAIT_QUEUE_HEAD(nmc_msgdump_waitqueue);
+
+
+/*
+--------------------------------------------------------------------------------
+*/
+static int nmc_debug_level_open(struct inode *inode, struct file *file)
+{
+ /*DEBUG_LEVEL = *((unsigned int *)inode->i_private);*/
+ printk("nmc_debug_level_open: current debug-level=%x\n", atomic_read(&DEBUG_LEVEL));
+ return 0;
+}
+
+static int nmc_debug_region_open(struct inode *inode, struct file *file)
+{
+ /*REGION = *((unsigned int *)inode->i_private);*/
+ printk("nmc_debug_region_open: current debug-region=%x\n", atomic_read(&REGION));
+ return 0;
+}
+
+static int nmc_debug_dump_open(struct inode *inode, struct file *file)
+{
+ printk("nmc_debug_dump_open\n");
+ return 0;
+}
+
+static ssize_t nmc_debug_level_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+ if(copy_to_user(buf, (const void*)(&atomic_read(&DEBUG_LEVEL)), sizeof(unsigned int))) {
+ return -EFAULT;
+ }
+
+ return sizeof(unsigned int);
+}
+
+static ssize_t nmc_debug_level_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+ unsigned int flag = 0;
+
+ if(copy_from_user(&flag, buf, sizeof(unsigned int))) {
+ return -EFAULT;
+ }
+
+ if(flag > DBG_LEVEL_ALL) {
+ printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&DEBUG_LEVEL));
+ return -EFAULT;
+ }
+
+ atomic_set(&DEBUG_LEVEL, (int)flag);
+ printk("new debug-level is %x\n", atomic_read(&DEBUG_LEVEL));
+
+ return sizeof(unsigned int);
+}
+
+static ssize_t nmc_debug_region_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+ if(copy_to_user(buf, (const void*)(&atomic_read(&REGION)), sizeof(unsigned int))) {
+ return -EFAULT;
+ }
+
+ return sizeof(unsigned int);
+}
+
+static ssize_t nmc_debug_region_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+ uint32_t flag = 0;
+
+ if(copy_from_user(&flag, buf, sizeof(unsigned int))) {
+ return -EFAULT;
+ }
+
+ if(flag > DBG_REGION_ALL) {
+ printk("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", __func__, flag, atomic_read(&REGION));
+ return -EFAULT;
+ }
+
+ atomic_set(&REGION, (int)flag);
+ printk("new debug-region is %x\n", atomic_read(&REGION));
+
+ return sizeof(unsigned int);
+}
+
+void kmsgdump_write(char *fmt, ...)
+{
+ char buf[256] = {0,};
+ va_list args;
+ int len;
+
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
+
+ if((len>=256) || (len<0))
+ buf[256-1] = '\n';
+
+#if !defined (NM73131_0_BOARD)
+//#define LOG_TIME_STAMP //NM73131 is not support : rachel check required
+#endif
+
+#ifdef LOG_TIME_STAMP
+ {
+ char buf_t[30] = {0,};
+ unsigned long rem_nsec;
+ u64 ts = local_clock();
+
+ rem_nsec = do_div(ts, 1000000000);
+ sprintf(buf_t, "[%5lu.%06lu] ", (unsigned long)ts, rem_nsec / 1000);
+
+ queue_write(&g_dumpqueue, (void*)buf_t, strlen(buf_t));
+ }
+#endif
+
+ queue_write(&g_dumpqueue, (void*)buf, strlen(buf));
+ wake_up(&nmc_msgdump_waitqueue);
+
+}
+
+static ssize_t kmsgdump_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+ int read_size = 0;
+ int buf_size = queue_data_size(&g_dumpqueue);
+
+ if(buf_size > 0)
+ {
+ unsigned char *text = kmalloc(buf_size, GFP_KERNEL);
+ read_size = queue_read(&g_dumpqueue, (void*)text, (int)buf_size);
+ if(copy_to_user(buf, text, read_size)) {
+ kfree(text);
+ return -EFAULT;
+ }
+ kfree(text);
+ return read_size;
+ }
+ // return -EAGAIN;
+ return 0;
+}
+
+static unsigned int kmsgdump_poll(struct file *file, poll_table *wait)
+{
+ if(queue_data_size(&g_dumpqueue))
+ return POLLIN | POLLRDNORM;
+ poll_wait(file, &nmc_msgdump_waitqueue, wait);
+ if(queue_data_size(&g_dumpqueue))
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+
+/*
+--------------------------------------------------------------------------------
+*/
+
+#define FOPS(_open, _read, _write, _poll) { \
+ .owner = THIS_MODULE, \
+ .open = (_open), \
+ .read = (_read), \
+ .write = (_write), \
+ .poll = (_poll), \
+}
+
+struct nmc_debugfs_info_t {
+ const char *name;
+ int perm;
+ unsigned int data;
+ struct file_operations fops;
+};
+
+static struct nmc_debugfs_info_t debugfs_info[] = {
+ { "nmc_debug_level", 0666, (DEBUG | ERR), FOPS(nmc_debug_level_open, nmc_debug_level_read, nmc_debug_level_write,NULL), },
+ { "nmc_debug_region", 0666, (INIT_DBG | GENERIC_DBG | CFG80211_DBG), FOPS(nmc_debug_region_open, nmc_debug_region_read, nmc_debug_region_write, NULL), },
+ { "nmc_debug_dump", 0666, 0, FOPS(nmc_debug_dump_open, kmsgdump_read, NULL, kmsgdump_poll), },
+};
+
+int nmc_debugfs_init(void)
+{
+ int i;
+
+ struct dentry *debugfs_files;
+ struct nmc_debugfs_info_t *info;
+
+ nmc_dir = debugfs_create_dir("nmi_wifi", NULL);
+ if(nmc_dir == ERR_PTR(-ENODEV)) {
+ /* it's not error. the debugfs is just not being enabled. */
+ printk("ERR, kernel has built without debugfs support\n");
+ return 0;
+ }
+
+ if(!nmc_dir) {
+ printk("ERR, debugfs create dir\n");
+ return -1;
+ }
+
+ for(i=0; i<ARRAY_SIZE(debugfs_info) ; i++)
+ {
+ info = &debugfs_info[i];
+ printk("create the debugfs file, %s\n", info->name);
+ debugfs_files = debugfs_create_file(info->name,
+ info->perm,
+ nmc_dir,
+ &info->data,
+ &info->fops);
+
+ if(!debugfs_files) {
+ printk("fail to create the debugfs file, %s\n", info->name);
+ debugfs_remove_recursive(nmc_dir);
+ return -1;
+ }
+ }
+
+ queue_init(&g_dumpqueue, DUMP_QUEUE_MAX);
+
+ return 0;
+}
+
+void nmc_debugfs_remove(void)
+{
+ queue_deinit(&g_dumpqueue);
+
+ debugfs_remove_recursive(nmc_dir);
+}
+
+#endif
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.c
new file mode 100755
index 00000000..3b46fb43
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.c
@@ -0,0 +1,235 @@
+/*
+ Copyright (c) Newport Media Inc. All rights reserved.
+ Copyright (c) WRG Inc. All rights reserved.
+
+ Use of this sample source code is subject to the terms of the Newport Media Inc.
+ license agreement under which you licensed this sample source code. If you did not
+ accept the terms of the license agreement, you are not authorized to use this
+ sample source code. For the terms of the license, please see the license agreement
+ between you and Newport Media Inc.
+ THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
+*/
+/**
+ @file queue.c
+ @description generic QUEUE object with auto drop.
+ @author Austin Shin (austin.shin@wrg.co.kr)
+ @date 2009-02-17
+*/
+
+//#include <stdio.h>
+//#include <stdlib.h>
+//#include <string.h>
+//#include <android/log.h> //added
+
+#include "nmi_queue.h"
+
+#ifdef _MSC_VER
+#define inline __inline
+#endif
+
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+static spinlock_t g_lock;
+
+/* read write option */
+#define OPTION_PARTIAL_READ // enable partial read
+//#define OPTION_PARTIAL_WRITE // enable partial write
+#define OPTION_AUTO_DROP // force write with auto dropping.
+
+
+/* debugging */
+#define ASSERT(x)
+//#define ASSERT(x) (!(x)) ? assert(x);
+
+static inline int __align(int v, unsigned int n)
+{
+ return (v + (n-1)) & ~(n-1);
+}
+
+int queue_init(queue* p, int len)
+{
+ ASSERT(p);
+ ASSERT(p->buffer);
+ ASSERT(len > 0);
+
+ spin_lock_init(&g_lock);
+
+ //p->buffer = malloc(len);
+ p->buffer = kmalloc(len, GFP_KERNEL);
+
+ if ( p->buffer == NULL )
+ {
+ return 0;
+ }
+
+ p->size = len;
+
+ queue_reset(p);
+
+ return len;
+}
+
+int queue_deinit(queue* p)
+{
+ if( p->buffer == NULL )
+ return -1;
+
+ queue_reset(p);
+
+ kfree(p->buffer); p->buffer = NULL;
+
+ return 0;
+}
+
+int queue_reset(queue* p)
+{
+ ASSERT(p);
+ ASSERT(p->buffer);
+ ASSERT(p->size > 0);
+
+ if(p->buffer == NULL)
+ return 0;
+
+ spin_lock(&g_lock);
+
+ memset(p->buffer, 0, p->size);
+ p->wr = 0;
+ p->rd = 0;
+
+ spin_unlock(&g_lock);
+
+ return 0;
+}
+
+int queue_data_size(queue* p)
+{
+ ASSERT(p);
+
+ if(p->wr >= p->rd)
+ return (p->wr - p->rd);
+ else
+ return (p->wr + (p->size - p->rd));
+}
+
+int queue_free_size(queue* p)
+{
+ ASSERT(p);
+
+ return p->size - queue_data_size(p);
+}
+
+int queue_drop(queue* p, int len)
+{
+ ASSERT(p);
+ ASSERT(len < p->size);
+
+ if(p->rd + len < p->size)
+ {
+ p->rd += len;
+ }
+ else
+ {
+ p->rd = p->rd + len - p->size;
+ }
+
+ return len;
+}
+
+int queue_write(queue* p, void* data, int len)
+{
+ int freesize;
+
+ ASSERT(p);
+ ASSERT(data);
+ ASSERT(len < p->size);
+
+ if(p->buffer == NULL)
+ return 0;
+
+ spin_lock(&g_lock);
+
+ freesize = queue_free_size(p);
+
+ if(len > freesize)
+ {
+#if defined(OPTION_PARTIAL_WRITE)
+ len = freesize;
+#elif defined(OPTION_AUTO_DROP)
+ queue_drop(p, __align(len - freesize, 1)+1);
+#else
+ spin_unlock(&g_lock);
+ return 0;
+#endif
+ }
+
+ if(p->wr + len < p->size)
+ {
+ memcpy(p->buffer + p->wr, data, len);
+ p->wr += len;
+ }
+ else
+ {
+ int part1 = p->size - p->wr;
+ int part2 = len - part1;
+
+ memcpy(p->buffer + p->wr, data, part1);
+ memcpy(p->buffer, (char*)(data) + part1, part2);
+ p->wr = part2;
+
+ }
+
+ spin_unlock(&g_lock);
+
+ return len;
+}
+
+
+int queue_read(queue* p, void* data, int len)
+{
+ int datasize;
+
+ ASSERT(p);
+ ASSERT(data);
+ ASSERT(len < p->size);
+
+ if(p->buffer == NULL)
+ return 0;
+
+ spin_lock(&g_lock);
+
+ datasize = queue_data_size(p);
+
+ if (len > datasize)
+ {
+ //printk("queue underrun\n");
+#if defined(OPTION_PARTIAL_READ)
+ len = datasize;
+#else
+ spin_unlock(&g_lock);
+
+ return 0;
+#endif
+ }
+
+ if(p->rd + len < p->size)
+ {
+ memcpy(data, p->buffer + p->rd, len);
+ p->rd += len;
+ }
+ else
+ {
+ int part1 = p->size - p->rd;
+ int part2 = len - part1;
+
+ memcpy(data, p->buffer + p->rd, part1);
+ memcpy((char*)(data) + part1, p->buffer, part2);
+ p->rd = part2;
+ }
+
+ spin_unlock(&g_lock);
+
+ return len;
+}
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.h b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.h
new file mode 100755
index 00000000..cdfc8fbe
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_queue.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (c) Newport Media Inc. All rights reserved.
+ Copyright (c) WRG Inc. All rights reserved.
+
+ Use of this sample source code is subject to the terms of the Newport Media Inc.
+ license agreement under which you licensed this sample source code. If you did not
+ accept the terms of the license agreement, you are not authorized to use this
+ sample source code. For the terms of the license, please see the license agreement
+ between you and Newport Media Inc.
+ THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
+*/
+/**
+ @file queue.h
+ @description generic QUEUE object with auto drop.
+ @author Austin Shin (austin.shin@wrg.co.kr)
+ @date 2009-02-17
+*/
+
+#ifndef _QUEUE_H_
+#define _QUEUE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 1
+#define QUE_BUFFER_MAX_SIZE ((188*16*5)+1) //(188*16*8)//(188*30*4)//8192
+#else
+#define QUE_BUFFER_MAX_SIZE (188*30*8)//(188*30*4)
+#endif
+
+typedef struct _queue
+{
+ char* buffer; // data buffer
+ int size; // buffer size
+ int rd, wr; // r/w offset.
+} queue;
+
+
+int queue_init(queue* p, int len);
+int queue_deinit(queue* p);
+int queue_reset(queue* p);
+int queue_data_size(queue* p);
+int queue_free_size(queue* p);
+int queue_write(queue* p, void* data, int len);
+int queue_read(queue* p, void* data, int len);
+int queue_drop(queue* p, int len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _QUEUE_H_
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_wm8880_gpio.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_wm8880_gpio.c
new file mode 100755
index 00000000..a0155f55
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/linux/source/nmi_wm8880_gpio.c
@@ -0,0 +1,87 @@
+/*
+
+* $Id: nmi_custom_gpio.c, Exp $
+*/
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+
+#include <mach/gpio_customize_ease.h>
+#include <mach/hardware.h>
+#include <mach/wmt_gpio.h>
+
+#include <linux/gpio.h>
+#include <mach/wmt_iomux.h>
+
+
+static int gpio_chipen_ctrl = -1;
+static int gpio_reset_ctrl = -1;
+
+
+static void wifi_gpio_reset(int high_or_low)
+{
+ printk("%s======hi= %d\n",__FUNCTION__,high_or_low);
+
+ gpio_direction_output(gpio_reset_ctrl, high_or_low);
+}
+
+static void wifi_card_init_gpios(void)
+{
+ int ret;
+
+ gpio_chipen_ctrl = WMT_PIN_GP62_SUSGPIO1; // ??? simon
+ gpio_reset_ctrl = WMT_PIN_GP1_GPIO14;
+
+ ret = gpio_request(gpio_chipen_ctrl, "nmc1000 chipen pin");
+ if (ret < 0) {
+ printk("reques gpio:%x failed!!! for nmc1000\n", gpio_chipen_ctrl);
+ return ;
+ } else {
+ printk("request gpio:%d for nmc1000 success!!!\n", gpio_chipen_ctrl);
+ }
+ gpio_direction_output(gpio_chipen_ctrl, 0);
+
+ ret = gpio_request(gpio_reset_ctrl, "nmc1000 reset pin");
+ if (ret < 0) {
+ printk("reques gpio:%x failed!!! for nmc1000\n", gpio_reset_ctrl);
+ return ;
+ } else {
+ printk("request gpio:%d for nmc1000 success!!!\n", gpio_reset_ctrl);
+ }
+ gpio_direction_output(gpio_reset_ctrl, 0);
+}
+
+static void wifi_card_release_gpios(void)
+{
+ gpio_free(gpio_chipen_ctrl);
+ gpio_free(gpio_reset_ctrl);
+}
+
+static void wifi_card_chipen_gpios(int high_or_low)
+{
+ gpio_direction_output(gpio_chipen_ctrl, high_or_low);
+}
+
+/* Customer function to control hw specific wlan gpios */
+void NmiWifiCardPower(int power)
+{
+ printk("%s, power=%d\n", __FUNCTION__, power);
+
+ if(power){
+ wifi_card_init_gpios();
+ wifi_gpio_reset(0);
+ wifi_card_chipen_gpios (power);
+ msleep(35);
+ wifi_gpio_reset(1);
+ msleep(20);
+ }else{
+ wifi_gpio_reset(0);
+ msleep(10);
+ wifi_card_chipen_gpios (power);
+ msleep(10);
+ wifi_card_release_gpios();
+ }
+}
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_driver_interface/host_interface.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_driver_interface/host_interface.c
new file mode 100755
index 00000000..166edb56
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_driver_interface/host_interface.c
@@ -0,0 +1,8371 @@
+#include "host_interface.h"
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+#include "itypes.h"
+#include "CoreConfigurator.h"
+
+extern NMI_Sint32 TransportInit(void);
+extern NMI_Sint32 TransportDeInit(void);
+extern NMI_Uint8 connecting;
+
+extern NMI_Bool bEnablePS;
+/*BugID_5137*/
+extern NMI_Uint8 g_nmc_initialized;
+/*****************************************************************************/
+/* Macros */
+/*****************************************************************************/
+
+/* Message types of the Host IF Message Queue*/
+#define HOST_IF_MSG_SCAN ((NMI_Uint16)0)
+#define HOST_IF_MSG_CONNECT ((NMI_Uint16)1)
+#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO ((NMI_Uint16)2)
+#define HOST_IF_MSG_KEY ((NMI_Uint16)3)
+#define HOST_IF_MSG_RCVD_NTWRK_INFO ((NMI_Uint16)4)
+#define HOST_IF_MSG_RCVD_SCAN_COMPLETE ((NMI_Uint16)5)
+#define HOST_IF_MSG_CFG_PARAMS ((NMI_Uint16)6)
+#define HOST_IF_MSG_SET_CHANNEL ((NMI_Uint16)7)
+#define HOST_IF_MSG_DISCONNECT ((NMI_Uint16)8)
+#define HOST_IF_MSG_GET_RSSI ((NMI_Uint16)9)
+#define HOST_IF_MSG_GET_CHNL ((NMI_Uint16)10)
+#define HOST_IF_MSG_ADD_BEACON ((NMI_Uint16)11)
+#define HOST_IF_MSG_DEL_BEACON ((NMI_Uint16)12)
+#define HOST_IF_MSG_ADD_STATION ((NMI_Uint16)13)
+#define HOST_IF_MSG_DEL_STATION ((NMI_Uint16)14)
+#define HOST_IF_MSG_EDIT_STATION ((NMI_Uint16)15)
+#define HOST_IF_MSG_SCAN_TIMER_FIRED ((NMI_Uint16)16)
+#define HOST_IF_MSG_CONNECT_TIMER_FIRED ((NMI_Uint16)17)
+#define HOST_IF_MSG_POWER_MGMT ((NMI_Uint16)18)
+#define HOST_IF_MSG_GET_INACTIVETIME ((NMI_Uint16)19)
+#define HOST_IF_MSG_REMAIN_ON_CHAN ((NMI_Uint16)20)
+#define HOST_IF_MSG_REGISTER_FRAME ((NMI_Uint16)21)
+#define HOST_IF_MSG_LISTEN_TIMER_FIRED ((NMI_Uint16)22)
+#define HOST_IF_MSG_GET_LINKSPEED ((NMI_Uint16)23)
+#define HOST_IF_MSG_SET_WFIDRV_HANDLER ((NMI_Uint16)24)
+#define HOST_IF_MSG_SET_MAC_ADDRESS ((NMI_Uint16)25)
+#define HOST_IF_MSG_GET_MAC_ADDRESS ((NMI_Uint16)26)
+#define HOST_IF_MSG_SET_OPERATION_MODE ((NMI_Uint16)27)
+#define HOST_IF_MSG_SET_IPADDRESS ((NMI_Uint16)28)
+#define HOST_IF_MSG_GET_IPADDRESS ((NMI_Uint16)29)
+#define HOST_IF_MSG_FLUSH_CONNECT ((NMI_Uint16)30)
+#define HOST_IF_MSG_GET_STATISTICS ((NMI_Uint16)31)
+#define HOST_IF_MSG_SET_MULTICAST_FILTER ((NMI_Uint16)32)
+#define HOST_IF_MSG_ADD_BA_SESSION ((NMI_Uint16)33)
+#define HOST_IF_MSG_DEL_BA_SESSION ((NMI_Uint16)34)
+#define HOST_IF_MSG_Q_IDLE ((NMI_Uint16)35)
+
+#define HOST_IF_MSG_EXIT ((NMI_Uint16)100)
+
+#define HOST_IF_SCAN_TIMEOUT 4000
+#define HOST_IF_CONNECT_TIMEOUT 9500
+
+#define BA_SESSION_DEFAULT_BUFFER_SIZE 16
+#define BA_SESSION_DEFAULT_TIMEOUT 1000
+#define BLOCK_ACK_REQ_SIZE 0x14
+/*****************************************************************************/
+/* Type Definitions */
+/*****************************************************************************/
+
+/*!
+* @struct tstrHostIFCfgParamAttr
+* @brief Structure to hold Host IF CFG Params Attributes
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 02 April 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFCfgParamAttr
+{
+ tstrCfgParamVal pstrCfgParamVal;
+
+}tstrHostIFCfgParamAttr;
+
+/*!
+* @struct tstrHostIFwpaAttr
+* @brief Structure to hold Host IF Scan Attributes
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFwpaAttr
+{
+ NMI_Uint8* pu8key;
+ const NMI_Uint8* pu8macaddr;
+ NMI_Uint8* pu8seq;
+ NMI_Uint8 u8seqlen;
+ NMI_Uint8 u8keyidx;
+ NMI_Uint8 u8Keylen;
+ NMI_Uint8 u8Ciphermode;
+} tstrHostIFwpaAttr;
+
+
+/*!
+* @struct tstrHostIFwepAttr
+* @brief Structure to hold Host IF Scan Attributes
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFwepAttr
+{
+ NMI_Uint8* pu8WepKey;
+ NMI_Uint8 u8WepKeylen;
+ NMI_Uint8 u8Wepidx;
+ NMI_Uint8 u8mode;
+ AUTHTYPE_T tenuAuth_type;
+
+} tstrHostIFwepAttr;
+
+/*!
+* @struct tuniHostIFkeyAttr
+* @brief Structure to hold Host IF Scan Attributes
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef union _tuniHostIFkeyAttr
+{
+ tstrHostIFwepAttr strHostIFwepAttr;
+ tstrHostIFwpaAttr strHostIFwpaAttr;
+ tstrHostIFpmkidAttr strHostIFpmkidAttr;
+} tuniHostIFkeyAttr;
+
+/*!
+* @struct tstrHostIFkeyAttr
+* @brief Structure to hold Host IF Scan Attributes
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFkeyAttr
+{
+ tenuKeyType enuKeyType;
+ NMI_Uint8 u8KeyAction;
+ tuniHostIFkeyAttr uniHostIFkeyAttr;
+} tstrHostIFkeyAttr;
+
+
+
+
+/*!
+* @struct tstrHostIFscanAttr
+* @brief Structure to hold Host IF Scan Attributes
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFscanAttr
+{
+ NMI_Uint8 u8ScanSource;
+ NMI_Uint8 u8ScanType;
+ NMI_Uint8* pu8ChnlFreqList;
+ NMI_Uint8 u8ChnlListLen;
+ NMI_Uint8* pu8IEs;
+ size_t IEsLen;
+ tNMIpfScanResult pfScanResult;
+ void* pvUserArg;
+ /*BugID_4189*/
+ tstrHiddenNetwork strHiddenNetwork;
+
+} tstrHostIFscanAttr;
+
+/*!
+* @struct tstrHostIFconnectAttr
+* @brief Structure to hold Host IF Connect Attributes
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFconnectAttr
+{
+ NMI_Uint8* pu8bssid;
+ NMI_Uint8* pu8ssid;
+ size_t ssidLen;
+ NMI_Uint8* pu8IEs;
+ size_t IEsLen;
+ NMI_Uint8 u8security;
+ tNMIpfConnectResult pfConnectResult;
+ void* pvUserArg;
+ AUTHTYPE_T tenuAuth_type;
+ NMI_Uint8 u8channel;
+ void* pJoinParams;
+} tstrHostIFconnectAttr;
+
+/*!
+* @struct tstrRcvdGnrlAsyncInfo
+* @brief Structure to hold Received General Asynchronous info
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrRcvdGnrlAsyncInfo
+{
+ NMI_Uint8* pu8Buffer;
+ NMI_Uint32 u32Length;
+} tstrRcvdGnrlAsyncInfo;
+
+/*!
+* @struct tstrHostIFSetChan
+* @brief Set Channel message body
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFSetChan
+{
+ NMI_Uint8 u8SetChan;
+} tstrHostIFSetChan;
+
+/*!
+* @struct tstrHostIFSetChan
+* @brief Get Channel message body
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 01 Jule 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFGetChan
+{
+ NMI_Uint8 u8GetChan;
+} tstrHostIFGetChan;
+
+/*bug3819: Add Scan acomplete notification to host*/
+/*!
+* @struct tstrScanComplete
+* @brief hold received Async. Scan Complete message body
+* @details
+* @todo
+* @sa
+* @author zsalah
+* @date 25 March 2012
+* @version 1.0
+*/
+/*typedef struct _tstrScanComplete
+{
+ NMI_Uint8* pu8Buffer;
+ NMI_Uint32 u32Length;
+} tstrScanComplete;*/
+
+/*!
+* @struct tstrHostIFSetBeacon
+* @brief Set Beacon message body
+* @details
+* @todo
+* @sa
+* @author Adham Abozaeid
+* @date 10 July 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFSetBeacon
+{
+ NMI_Uint32 u32Interval; /*!< Beacon Interval. Period between two successive beacons on air */
+ NMI_Uint32 u32DTIMPeriod; /*!< DTIM Period. Indicates how many Beacon frames
+ (including the current frame) appear before the next DTIM */
+ NMI_Uint32 u32HeadLen; /*!< Length of the head buffer in bytes */
+ NMI_Uint8* pu8Head; /*!< Pointer to the beacon's head buffer. Beacon's head is the part
+ from the beacon's start till the TIM element, NOT including the TIM */
+ NMI_Uint32 u32TailLen; /*!< Length of the tail buffer in bytes */
+ NMI_Uint8* pu8Tail; /*!< Pointer to the beacon's tail buffer. Beacon's tail starts just
+ after the TIM inormation element */
+ }tstrHostIFSetBeacon;
+
+
+
+/*!
+* @struct tstrHostIFDelBeacon
+* @brief Del Beacon message body
+* @details
+* @todo
+* @sa
+* @author Adham Abozaeid
+* @date 15 July 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFDelBeacon
+{
+ NMI_Uint8 u8dummy;
+ }tstrHostIFDelBeacon;
+
+/*!
+* @struct tstrHostIFSetMulti
+* @brief set Multicast filter Address
+* @details
+* @todo
+* @sa
+* @author Abdelrahman Sobhy
+* @date 30 August 2013
+* @version 1.0 Description
+*/
+
+typedef struct
+{
+ NMI_Bool bIsEnabled;
+ NMI_Uint32 u32count;
+}tstrHostIFSetMulti;
+
+/*!
+* @struct tstrHostIFDelSta
+* @brief Delete station message body
+* @details
+* @todo
+* @sa
+* @author Adham Abozaeid
+* @date 15 July 2012
+* @version 1.0 Description
+*/
+
+typedef struct
+{
+ NMI_Uint8 au8MacAddr[ETH_ALEN];
+}tstrHostIFDelSta;
+
+/*!
+* @struct tstrTimerCb
+* @brief Timer callback message body
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrTimerCb
+{
+ void* pvUsrArg; /*!< Private data passed at timer start */
+} tstrTimerCb;
+
+/*!
+* @struct tstrHostIfPowerMgmtParam
+* @brief Power management message body
+* @details
+* @todo
+* @sa
+* @author Adham Abozaeid
+* @date 24 November 2012
+* @version 1.0
+*/
+typedef struct
+{
+
+ NMI_Bool bIsEnabled;
+ NMI_Uint32 u32Timeout;
+}tstrHostIfPowerMgmtParam;
+
+/*!
+* @struct tstrHostIFSetIPAddr
+* @brief set IP Address message body
+* @details
+* @todo
+* @sa
+* @author Abdelrahman Sobhy
+* @date 30 August 2013
+* @version 1.0 Description
+*/
+
+typedef struct
+{
+ NMI_Uint8* au8IPAddr;
+ NMI_Uint8 idx;
+}tstrHostIFSetIPAddr;
+
+/*!
+* @struct tstrHostIfStaInactiveT
+* @brief Get station message body
+* @details
+* @todo
+* @sa
+* @author Mai Daftedar
+* @date 16 April 2013
+* @version 1.0
+*/
+typedef struct
+{
+ NMI_Uint8 mac[6];
+
+}tstrHostIfStaInactiveT;
+/**/
+/*!
+* @union tuniHostIFmsgBody
+* @brief Message body for the Host Interface message_q
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef union _tuniHostIFmsgBody
+{
+ tstrHostIFscanAttr strHostIFscanAttr; /*!< Host IF Scan Request Attributes message body */
+ tstrHostIFconnectAttr strHostIFconnectAttr; /*!< Host IF Connect Request Attributes message body */
+ tstrRcvdNetworkInfo strRcvdNetworkInfo; /*!< Received Asynchronous Network Info message body */
+ tstrRcvdGnrlAsyncInfo strRcvdGnrlAsyncInfo; /*!< Received General Asynchronous Info message body */
+ tstrHostIFkeyAttr strHostIFkeyAttr; /*!<>*/
+ tstrHostIFCfgParamAttr strHostIFCfgParamAttr; /*! <CFG Parameter message Body> */
+ tstrHostIFSetChan strHostIFSetChan;
+ tstrHostIFGetChan strHostIFGetChan;
+ tstrHostIFSetBeacon strHostIFSetBeacon; /*!< Set beacon message body */
+ tstrHostIFDelBeacon strHostIFDelBeacon; /*!< Del beacon message body */
+ tstrNMI_AddStaParam strAddStaParam; /*!< Add station message body */
+ tstrHostIFDelSta strDelStaParam; /*!< Del Station message body */
+ tstrNMI_AddStaParam strEditStaParam; /*!< Edit station message body */
+ //tstrScanComplete strScanComplete; /*Received Async. Scan Complete message body*/
+ tstrTimerCb strTimerCb; /*!< Timer callback message body */
+ tstrHostIfPowerMgmtParam strPowerMgmtparam; /*!< Power Management message body */
+ tstrHostIfStaInactiveT strHostIfStaInactiveT;
+ tstrHostIFSetIPAddr strHostIfSetIP;
+ tstrHostIfSetDrvHandler strHostIfSetDrvHandler;
+ tstrHostIFSetMulti strHostIfSetMulti;
+ tstrHostIfSetOperationMode strHostIfSetOperationMode;
+ tstrHostIfSetMacAddress strHostIfSetMacAddress;
+ tstrHostIfGetMacAddress strHostIfGetMacAddress;
+ tstrHostIfBASessionInfo strHostIfBASessionInfo;
+ #ifdef NMI_P2P
+ tstrHostIfRemainOnChan strHostIfRemainOnChan;
+ tstrHostIfRegisterFrame strHostIfRegisterFrame;
+ #endif
+ NMI_Char * pUserData;
+
+} tuniHostIFmsgBody;
+
+/*!
+* @struct tstrHostIFmsg
+* @brief Host Interface message
+* @details
+* @todo
+* @sa
+* @author Mostafa Abu Bakr
+* @date 25 March 2012
+* @version 1.0
+*/
+typedef struct _tstrHostIFmsg
+{
+ NMI_Uint16 u16MsgId; /*!< Message ID */
+ tuniHostIFmsgBody uniHostIFmsgBody; /*!< Message body */
+ void * drvHandler;
+}tstrHostIFmsg;
+
+#ifdef CONNECT_DIRECT
+typedef struct _tstrWidJoinReqExt
+{
+ NMI_Char SSID[MAX_SSID_LEN];
+ NMI_Uint8 u8channel;
+ NMI_Uint8 BSSID[6];
+}tstrWidJoinReqExt;
+#endif
+
+/*Bug4218: Parsing Join Param*/
+#ifdef NMI_PARSE_SCAN_IN_HOST
+/*Struct containg joinParam of each AP*/
+typedef struct _tstrJoinBssParam
+{
+ BSSTYPE_T bss_type;
+ NMI_Uint8 dtim_period;
+ NMI_Uint16 beacon_period;
+ NMI_Uint16 cap_info;
+ NMI_Uint8 au8bssid[6];
+ NMI_Char ssid[MAX_SSID_LEN];
+ NMI_Uint8 ssidLen;
+ NMI_Uint8 supp_rates[MAX_RATES_SUPPORTED + 1];
+ NMI_Uint8 ht_capable;
+ NMI_Uint8 wmm_cap;
+ NMI_Uint8 uapsd_cap;
+ NMI_Bool rsn_found;
+ NMI_Uint8 rsn_grp_policy;
+ NMI_Uint8 mode_802_11i;
+ NMI_Uint8 rsn_pcip_policy[3];
+ NMI_Uint8 rsn_auth_policy[3];
+ NMI_Uint8 rsn_cap[2];
+ struct _tstrJoinParam* nextJoinBss;
+ #ifdef NMI_P2P
+ NMI_Uint32 tsf;
+ NMI_Uint8 u8NoaEnbaled;
+ NMI_Uint8 u8OppEnable;
+ NMI_Uint8 u8CtWindow;
+ NMI_Uint8 u8Count;
+ NMI_Uint8 u8Index;
+ NMI_Uint8 au8Duration[4];
+ NMI_Uint8 au8Interval[4];
+ NMI_Uint8 au8StartTime[4];
+ #endif
+}tstrJoinBssParam;
+/*Bug4218: Parsing Join Param*/
+/*a linked list table containing needed join parameters entries for each AP found in most recent scan*/
+typedef struct _tstrBssTable
+{
+ NMI_Uint8 u8noBssEntries;
+ tstrJoinBssParam* head;
+ tstrJoinBssParam* tail;
+}tstrBssTable;
+#endif /*NMI_PARSE_SCAN_IN_HOST*/
+
+typedef enum
+{
+ SCAN_TIMER = 0,
+ CONNECT_TIMER = 1,
+ SCAN_CONNECT_TIMER_FORCE_32BIT = 0xFFFFFFFF
+}tenuScanConnTimer;
+
+/*****************************************************************************/
+/* */
+/* Global Variabls */
+/* */
+/*****************************************************************************/
+
+
+tstrNMI_WFIDrv* terminated_handle=NMI_NULL;
+tstrNMI_WFIDrv* gWFiDrvHandle = NMI_NULL;
+#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+NMI_Bool g_obtainingIP=NMI_FALSE;
+#endif
+
+static NMI_ThreadHandle HostIFthreadHandler;
+static NMI_MsgQueueHandle gMsgQHostIF;
+static NMI_SemaphoreHandle hSemHostIFthrdEnd;
+
+NMI_SemaphoreHandle hSemDeinitDrvHandle;
+static NMI_SemaphoreHandle hWaitResponse;
+
+
+NMI_Uint8 gau8MulticastMacAddrList[NMI_MULTICAST_TABLE_SIZE][ETH_ALEN] = {{0}};
+
+#ifndef CONNECT_DIRECT
+static NMI_Uint8 gapu8RcvdSurveyResults[2][MAX_SURVEY_RESULT_FRAG_SIZE];
+#endif
+
+static NMI_Uint8 gapu8RcvdAssocResp[MAX_ASSOC_RESP_FRAME_SIZE];
+
+NMI_Bool gbScanWhileConnected = NMI_FALSE;
+
+static NMI_Sint8 gs8Rssi = 0;
+static NMI_Sint8 gs8lnkspd = 0;
+static NMI_Uint8 gu8Chnl = 0;
+static NMI_Uint8 gs8SetIP[2][4] = {{0}};
+static NMI_Uint8 gs8GetIP[2][4] = {{0}};
+#ifdef NMI_AP_EXTERNAL_MLME
+static NMI_Uint32 gu32InactiveTime = 0;
+static NMI_Uint8 gu8DelBcn = 0;
+#endif
+#ifndef SIMULATION
+static NMI_Uint32 gu32WidConnRstHack = 0;
+#endif
+
+/*BugID_5137*/
+NMI_Uint8* gu8FlushedJoinReq = NULL;
+NMI_Uint8* gu8FlushedInfoElemAsoc = NULL;
+NMI_Uint8 gu8Flushed11iMode;
+NMI_Uint8 gu8FlushedAuthType;
+NMI_Uint32 gu32FlushedJoinReqSize;
+NMI_Uint32 gu32FlushedInfoElemAsocSize;
+NMI_Uint32 gu8FlushedJoinReqDrvHandler = 0;
+#define REAL_JOIN_REQ 0
+#define FLUSHED_JOIN_REQ 1
+#define FLUSHED_BYTE_POS 79 //Position the byte indicating flushing in the flushed request
+
+/*Bug4218: Parsing Join Param*/
+#ifdef NMI_PARSE_SCAN_IN_HOST
+/*Bug4218: Parsing Join Param*/
+static void* host_int_ParseJoinBssParam(tstrNetworkInfo* ptstrNetworkInfo);
+#endif /*NMI_PARSE_SCAN_IN_HOST*/
+
+extern void chip_sleep_manually(NMI_Uint32 u32SleepTime);
+extern int linux_wlan_get_num_conn_ifcs(void);
+
+/**
+* @brief Handle_SetChannel
+* @details Sending config packet to firmware to set channel
+* @param[in] tstrHostIFSetChan* pstrHostIFSetChan
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_SetChannel(void * drvHandler,tstrHostIFSetChan* pstrHostIFSetChan)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_CURRENT_CHANNEL;
+ strWID.enuWIDtype= WID_CHAR;
+ strWID.ps8WidVal = (NMI_Char*)&(pstrHostIFSetChan->u8SetChan);
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ PRINT_D(HOSTINF_DBG,"Setting channel\n");
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to set channel\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+/**
+* @brief Handle_SetWfiDrvHandler
+* @details Sending config packet to firmware to set driver handler
+* @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_SetWfiDrvHandler(tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)((pstrHostIfSetDrvHandler->u32Address));
+
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_SET_DRV_HANDLER;
+ strWID.enuWIDtype= WID_INT;
+ strWID.ps8WidVal = (NMI_Sint8*)&(pstrHostIfSetDrvHandler->u32Address);
+ strWID.s32ValueSize = sizeof(NMI_Uint32);
+
+ /*Sending Cfg*/
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+
+ if((pstrHostIfSetDrvHandler->u32Address)==(NMI_Uint32)NULL)
+{
+ NMI_SemaphoreRelease(&hSemDeinitDrvHandle, NMI_NULL);
+}
+
+
+ if(s32Error)
+ {
+ PRINT_ER("Failed to set driver handler\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_SetWfiAPDrvHandler
+* @details Sending config packet to firmware to set driver handler
+* @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_SetOperationMode(void * drvHandler, tstrHostIfSetOperationMode* pstrHostIfSetOperationMode)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_SET_OPERATION_MODE;
+ strWID.enuWIDtype= WID_INT;
+ strWID.ps8WidVal = (NMI_Sint8*)&(pstrHostIfSetOperationMode->u32Mode);
+ strWID.s32ValueSize = sizeof(NMI_Uint32);
+
+ /*Sending Cfg*/
+ printk("(NMI_Uint32)pstrWFIDrv= %x \n",(NMI_Uint32)pstrWFIDrv);
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+
+ if((pstrHostIfSetOperationMode->u32Mode)==(NMI_Uint32)NULL)
+{
+ NMI_SemaphoreRelease(&hSemDeinitDrvHandle, NMI_NULL);
+}
+
+
+ if(s32Error)
+ {
+ PRINT_ER("Failed to set driver handler\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_set_IPAddress
+* @details Setting IP address params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8IPAddr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 Handle_set_IPAddress(void * drvHandler, NMI_Uint8* pu8IPAddr, NMI_Uint8 idx)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ char firmwareIPAddress[4] ={0};
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ if(pu8IPAddr[0] <192)
+ pu8IPAddr[0]=0;
+
+ printk("Indx = %d, Handling set IP = %d.%d.%d.%d \n",idx, pu8IPAddr[0],pu8IPAddr[1],pu8IPAddr[2],pu8IPAddr[3]);
+
+ NMI_memcpy(gs8SetIP[idx],pu8IPAddr,IP_ALEN);
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_IP_ADDRESS;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Uint8*)pu8IPAddr;
+ strWID.s32ValueSize = IP_ALEN;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE, (NMI_Uint32)pstrWFIDrv);
+
+
+
+ host_int_get_ipaddress((NMI_WFIDrvHandle)drvHandler, firmwareIPAddress, idx);
+
+ if(s32Error)
+ {
+ PRINT_D(HOSTINF_DBG,"Failed to set IP address\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ PRINT_INFO(HOSTINF_DBG,"IP address set\n");
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+
+/**
+* @brief Handle_get_IPAddress
+* @details Setting IP address params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8IPAddr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 Handle_get_IPAddress(void * drvHandler, NMI_Uint8* pu8IPAddr, NMI_Uint8 idx)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_IP_ADDRESS;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Uint8*)NMI_MALLOC(IP_ALEN);
+ strWID.s32ValueSize = IP_ALEN;
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE, (NMI_Uint32)pstrWFIDrv);
+
+ printk("%d.%d.%d.%d\n",(NMI_Uint8)(strWID.ps8WidVal[0]),(NMI_Uint8)(strWID.ps8WidVal[1]),(NMI_Uint8)(strWID.ps8WidVal[2]),(NMI_Uint8)(strWID.ps8WidVal[3]));
+
+ NMI_memcpy(gs8GetIP[idx],strWID.ps8WidVal,IP_ALEN);
+
+ /*get the value by searching the local copy*/
+ NMI_FREE(strWID.ps8WidVal);
+
+ if(NMI_memcmp(gs8GetIP[idx], gs8SetIP[idx], IP_ALEN) != 0)
+ host_int_setup_ipaddress((NMI_WFIDrvHandle)pstrWFIDrv, gs8SetIP[idx],idx);
+
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Failed to get IP address\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ printk("IP address retrieved:: u8IfIdx = %d \n",idx);
+ printk("%d.%d.%d.%d\n",gs8GetIP[idx][0],gs8GetIP[idx][1],gs8GetIP[idx][2],gs8GetIP[idx][3]);
+
+ PRINT_INFO(HOSTINF_DBG,"\n");
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+
+/*BugId_5077*/
+/**
+* @brief Handle_SetMacAddress
+* @details Setting mac address
+* @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
+* @return Error code.
+* @author Amr Abdel-Moghny
+* @date November 2013
+* @version 7.0
+*/
+static NMI_Sint32 Handle_SetMacAddress(void * drvHandler, tstrHostIfSetMacAddress* pstrHostIfSetMacAddress)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ NMI_Uint8 *mac_buf = (NMI_Uint8*)NMI_MALLOC(ETH_ALEN);
+ if(mac_buf == NULL)
+ {
+ PRINT_ER("No buffer to send mac address\n");
+ return NMI_FAIL;
+ }
+ NMI_memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN);
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_MAC_ADDR;
+ strWID.enuWIDtype= WID_STR;
+ strWID.ps8WidVal = mac_buf;
+ strWID.s32ValueSize = ETH_ALEN;
+PRINT_D(GENERIC_DBG,"mac addr = :%x:%x:%x:%x:%x:%x\n",strWID.ps8WidVal[0], strWID.ps8WidVal[1], strWID.ps8WidVal[2], strWID.ps8WidVal[3], strWID.ps8WidVal[4], strWID.ps8WidVal[5]);
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to set mac address\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ NMI_FREE(mac_buf);
+ return s32Error;
+}
+
+
+/*BugID_5213*/
+/**
+* @brief Handle_GetMacAddress
+* @details Getting mac address
+* @param[in] void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
+* @return Error code.
+* @author Amr Abdel-Moghny
+* @date JAN 2013
+* @version 8.0
+*/
+static NMI_Sint32 Handle_GetMacAddress(void * drvHandler, tstrHostIfGetMacAddress* pstrHostIfGetMacAddress)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_MAC_ADDR;
+ strWID.enuWIDtype= WID_STR;
+ strWID.ps8WidVal = pstrHostIfGetMacAddress->u8MacAddress;
+ strWID.s32ValueSize = ETH_ALEN;
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)drvHandler);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to get mac address\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ NMI_SemaphoreRelease(&hWaitResponse, NULL);
+
+ return s32Error;
+}
+
+
+/**
+* @brief Handle_CfgParam
+* @details Sending config packet to firmware to set CFG params
+* @param[in] tstrHostIFCfgParamAttr* strHostIFCfgParamAttr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_CfgParam(void * drvHandler,tstrHostIFCfgParamAttr* strHostIFCfgParamAttr)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWIDList[32];
+ NMI_Uint8 u8WidCnt= 0;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+
+
+ PRINT_D(HOSTINF_DBG,"Setting CFG params\n");
+
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BSS_TYPE)
+ {
+ /*----------------------------------------------------------*/
+ /*Input Value: INFRASTRUCTURE = 1, */
+ /* INDEPENDENT= 2, */
+ /* ANY_BSS= 3 */
+ /*----------------------------------------------------------*/
+ //validate input then copy>> need to check value 4 and 5
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.bss_type<6)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_BSS_TYPE;
+ strWIDList[u8WidCnt].ps8WidVal =(NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.bss_type;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.bss_type = (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.bss_type;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTH_TYPE)
+ {
+ /*------------------------------------------------------*/
+ /*Input Values: OPEN_SYSTEM = 0, */
+ /* SHARED_KEY = 1, */
+ /* ANY = 2 */
+ /*------------------------------------------------------*/
+ /*validate Possible values*/
+ if((strHostIFCfgParamAttr->pstrCfgParamVal.auth_type)==1 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type)==2 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type)==5)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TYPE;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_type;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.auth_type= (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.auth_type;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTHEN_TIMEOUT)
+ {
+ //range is 1 to 65535.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout>0 && strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TIMEOUT;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & POWER_MANAGEMENT)
+ {
+ /*-----------------------------------------------------------*/
+ /*Input Values: NO_POWERSAVE = 0, */
+ /* MIN_FAST_PS = 1, */
+ /* MAX_FAST_PS = 2, */
+ /* MIN_PSPOLL_PS = 3, */
+ /* MAX_PSPOLL_PS = 4 */
+ /*----------------------------------------------------------*/
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode<5)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_POWER_MANAGEMENT;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.power_mgmt_mode = (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_SHORT)
+ {
+ //range from 1 to 256
+ if((strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit>0) && (strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit<256))
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_SHORT_RETRY_LIMIT;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_LONG)
+ {
+ //range from 1 to 256
+ if((strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit>0) && (strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit<256))
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_LONG_RETRY_LIMIT;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit;
+
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & FRAG_THRESHOLD)
+ {
+
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold>255 && strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold<7937)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_FRAG_THRESHOLD;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RTS_THRESHOLD)
+ {
+ //range 256 to 65535
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold >255 && strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_RTS_THRESHOLD;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PREAMBLE)
+ {
+ /*-----------------------------------------------------*/
+ /*Input Values: Short= 0, */
+ /* Long= 1, */
+ /* Auto= 2 */
+ /*------------------------------------------------------*/
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type< 3)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_PREAMBLE;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.preamble_type = strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SHORT_SLOT_ALLOWED )
+ {
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed<2)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_SHORT_SLOT_ALLOWED;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.short_slot_allowed = (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & TXOP_PROT_DISABLE)
+ {
+ /*Description: used to Disable RTS-CTS protection for TXOP burst*/
+ /*transmission when the acknowledgement policy is No-Ack or Block-Ack */
+ /* this information is useful for external supplicant */
+ /*Input Values: 1 for enable and 0 for disable. */
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled<2)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_11N_TXOP_PROT_DISABLE;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.txop_prot_disabled = (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BEACON_INTERVAL)
+ {
+ //range is 1 to 65535.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval>0 && strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_BEACON_INTERVAL;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & DTIM_PERIOD)
+ {
+ //range is 1 to 255.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period>0 && strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period<256)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_DTIM_PERIOD;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.dtim_period = strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY)
+ {
+ /*----------------------------------------------------------------------*/
+ /*Input Values: SITE_SURVEY_1CH = 0, i.e.: currently set channel */
+ /* SITE_SURVEY_ALL_CH = 1, */
+ /* SITE_SURVEY_OFF = 2 */
+ /*----------------------------------------------------------------------*/
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled<3)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled;
+ strWIDList[u8WidCnt].enuWIDtype= WID_CHAR;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Char);
+ pstrWFIDrv->strCfgValues.site_survey_enabled = (NMI_Uint8)strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY_SCAN_TIME)
+ {
+ //range is 1 to 65535.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time>0 && strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY_SCAN_TIME;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & ACTIVE_SCANTIME)
+ {
+ //range is 1 to 65535.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time>0 && strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_ACTIVE_SCAN_TIME;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PASSIVE_SCANTIME)
+ {
+ //range is 1 to 65535.
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time>0 && strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time<65536)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_PASSIVE_SCAN_TIME;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ if(strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & CURRENT_TX_RATE)
+ {
+ CURRENT_TX_RATE_T curr_tx_rate = strHostIFCfgParamAttr->pstrCfgParamVal.curr_tx_rate;
+ /*----------------------------------------------------------------------*/
+ /*Rates: 1 2 5.5 11 6 9 12 18 24 36 48 54 Auto */
+ /*InputValues: 1 2 3 4 5 6 7 8 9 10 11 12 0 */
+ /*----------------------------------------------------------------------*/
+ //validate rate
+ if(curr_tx_rate==AUTORATE ||curr_tx_rate==MBPS_1
+ ||curr_tx_rate==MBPS_2 || curr_tx_rate==MBPS_5_5
+ ||curr_tx_rate== MBPS_11 ||curr_tx_rate==MBPS_6
+ ||curr_tx_rate==MBPS_9 || curr_tx_rate==MBPS_12
+ ||curr_tx_rate== MBPS_18|| curr_tx_rate==MBPS_24
+ ||curr_tx_rate==MBPS_36 ||curr_tx_rate==MBPS_48 || curr_tx_rate==MBPS_54)
+ {
+ strWIDList[u8WidCnt].u16WIDid = WID_CURRENT_TX_RATE;
+ strWIDList[u8WidCnt].ps8WidVal = (NMI_Sint8*)&curr_tx_rate;
+ strWIDList[u8WidCnt].enuWIDtype= WID_SHORT;
+ strWIDList[u8WidCnt].s32ValueSize = sizeof(NMI_Uint16);
+ pstrWFIDrv->strCfgValues.curr_tx_rate = (NMI_Uint8)curr_tx_rate;
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ u8WidCnt++;
+ }
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, u8WidCnt, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+
+ if(s32Error)
+ {
+ PRINT_ER("Error in setting CFG params\n");
+
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL);
+ return s32Error;
+}
+
+
+/**
+* @brief Handle_wait_msg_q_empty
+* @details this should be the last msg and then the msg Q becomes idle
+* @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_wait_msg_q_empty(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ g_nmc_initialized = 0;
+ NMI_SemaphoreRelease(&hWaitResponse, NULL);
+ return s32Error;
+}
+
+/**
+* @brief Handle_Scan
+* @details Sending config packet to firmware to set the scan params
+* @param[in] tstrHostIFscanAttr* pstrHostIFscanAttr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_Scan(void * drvHandler,tstrHostIFscanAttr* pstrHostIFscanAttr)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWIDList[5];
+ NMI_Uint32 u32WidsCount = 0;
+ NMI_Uint32 i;
+ NMI_Uint8* pu8Buffer;
+ NMI_Uint8 valuesize=0;
+ NMI_Uint8* pu8HdnNtwrksWidVal = NULL;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+
+ PRINT_D(HOSTINF_DBG,"Setting SCAN params\n");
+ PRINT_D(HOSTINF_DBG,"Scanning: In [%d] state \n", pstrWFIDrv->enuHostIFstate);
+
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult;
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg;
+
+ #ifdef NMI_P2P
+ #if 0
+ if(pstrWFIDrv->enuHostIFstate== HOST_IF_P2P_LISTEN || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED && pstrWFIDrv->u8P2PConnect))
+ {
+ PRINT_INFO(GENERIC_DBG,"Busy: State: %d\n",pstrWFIDrv->enuHostIFstate);
+ PRINT_INFO(GENERIC_DBG,"Current Jiffies: %lu Timeout:%llu\n",jiffies,pstrWFIDrv->u64P2p_MgmtTimeout);
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+ }
+ #endif
+ #endif
+
+ if((pstrWFIDrv->enuHostIFstate >= HOST_IF_SCANNING) && (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTED))
+ {
+ /* here we either in HOST_IF_SCANNING, HOST_IF_WAITING_CONN_REQ or HOST_IF_WAITING_CONN_RESP */
+ PRINT_D(GENERIC_DBG,"Don't scan we are already in [%d] state\n",pstrWFIDrv->enuHostIFstate);
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+ }
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ if(g_obtainingIP||connecting)
+ {
+ PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+ }
+ #endif
+
+ PRINT_D(HOSTINF_DBG,"Setting SCAN params\n");
+
+
+ pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount = 0;
+
+ /*BugID_4189*/
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_SSID_PROBE_REQ;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+
+ for(i=0;i<pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum;i++)
+ {
+ valuesize+=((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen)+1);
+ }
+ pu8HdnNtwrksWidVal = NMI_MALLOC(valuesize+1);
+ strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal;
+ if(strWIDList[u32WidsCount].ps8WidVal != NMI_NULL)
+ {
+ pu8Buffer = strWIDList[u32WidsCount].ps8WidVal;
+
+ *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum;
+
+ PRINT_D(HOSTINF_DBG,"In Handle_ProbeRequest number of ssid %d\n",pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum);
+
+ for(i=0;i<pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum;i++)
+ {
+ *pu8Buffer++=pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen;
+ NMI_memcpy(pu8Buffer, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen);
+ pu8Buffer+=pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen;
+ }
+
+
+
+ strWIDList[u32WidsCount].s32ValueSize = (NMI_Sint32)(valuesize+1);
+ u32WidsCount++;
+ }
+
+ /*filling cfg param array*/
+
+ //if((pstrHostIFscanAttr->pu8IEs != NULL) && (pstrHostIFscanAttr->IEsLen != 0))
+ {
+ /* IEs to be inserted in Probe Request */
+ strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_PROBE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
+ strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8IEs;
+ strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->IEsLen;
+ u32WidsCount++;
+ }
+
+ /*Scan Type*/
+ strWIDList[u32WidsCount].u16WIDid = WID_SCAN_TYPE;
+ strWIDList[u32WidsCount].enuWIDtype= WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrHostIFscanAttr->u8ScanType));
+ u32WidsCount++;
+
+ /*list of channels to be scanned*/
+ strWIDList[u32WidsCount].u16WIDid = WID_SCAN_CHANNEL_LIST;
+ strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
+
+ /* Bug 4648: Convert channel numbers to start from 0 not 1. */
+ if(pstrHostIFscanAttr->pu8ChnlFreqList != NULL && pstrHostIFscanAttr->u8ChnlListLen > 0)
+ {
+ int i;
+
+ for(i=0; i<pstrHostIFscanAttr->u8ChnlListLen; i++)
+ {
+ if(pstrHostIFscanAttr->pu8ChnlFreqList[i] > 0) {
+ pstrHostIFscanAttr->pu8ChnlFreqList[i] = pstrHostIFscanAttr->pu8ChnlFreqList[i] - 1;
+ }
+ }
+ }
+
+ strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8ChnlFreqList;
+ strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->u8ChnlListLen;
+ u32WidsCount++;
+
+ /*Scan Request*/
+ strWIDList[u32WidsCount].u16WIDid = WID_START_SCAN_REQ;
+ strWIDList[u32WidsCount].enuWIDtype= WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal=(NMI_Sint8*)(&(pstrHostIFscanAttr->u8ScanSource));
+ u32WidsCount++;
+
+ /*keep the state as is , no need to change it*/
+ //gWFiDrvHandle->enuHostIFstate = HOST_IF_SCANNING;
+
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)
+ {
+ gbScanWhileConnected = NMI_TRUE;
+ }
+ else if(pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE)
+ {
+ gbScanWhileConnected = NMI_FALSE;
+ }
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send scan paramters config packet\n");
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ else
+ {
+ PRINT_D(HOSTINF_DBG,"Successfully sent SCAN params config packet\n");
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ NMI_TimerStop(&(pstrWFIDrv->hScanTimer), NMI_NULL);
+ /*if there is an ongoing scan request*/
+ Handle_ScanDone(drvHandler,SCAN_EVENT_ABORTED);
+ }
+
+ /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */
+ if(pstrHostIFscanAttr->pu8ChnlFreqList != NULL)
+ {
+ NMI_FREE(pstrHostIFscanAttr->pu8ChnlFreqList);
+ pstrHostIFscanAttr->pu8ChnlFreqList = NULL;
+ }
+
+ /* Deallocate pstrHostIFscanAttr->pu8IEs which was previously allocated by the sending thread */
+ if(pstrHostIFscanAttr->pu8IEs != NULL)
+ {
+ NMI_FREE(pstrHostIFscanAttr->pu8IEs);
+ pstrHostIFscanAttr->pu8IEs = NULL;
+ }
+ if(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo != NULL)
+ {
+ NMI_FREE(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo);
+ pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo = NULL;
+ }
+
+ /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */
+ if(pstrHostIFscanAttr->pu8ChnlFreqList != NULL)
+ {
+ NMI_FREE(pstrHostIFscanAttr->pu8ChnlFreqList);
+ pstrHostIFscanAttr->pu8ChnlFreqList = NULL;
+ }
+
+ if(pu8HdnNtwrksWidVal != NULL)
+ {
+ NMI_FREE(pu8HdnNtwrksWidVal);
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_ScanDone
+* @details Call scan notification callback function
+* @param[in] NONE
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_ScanDone(void* drvHandler,tenuScanEvent enuEvent)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ NMI_Uint8 u8abort_running_scan;
+ tstrWID strWID;
+
+
+ PRINT_D(HOSTINF_DBG,"in Handle_ScanDone()\n");
+
+ /*BugID_4978*/
+ /*Ask FW to abort the running scan, if any*/
+ if(enuEvent == SCAN_EVENT_ABORTED)
+ {
+ PRINT_D(GENERIC_DBG,"Abort running scan\n");
+ u8abort_running_scan = 1;
+ strWID.u16WIDid = (NMI_Uint16)WID_ABORT_RUNNING_SCAN;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&u8abort_running_scan;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Failed to set abort running scan\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ }
+
+ /*if there is an ongoing scan request*/
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult(enuEvent, NMI_NULL,
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid,NULL);
+ /*delete current scan request*/
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult= NULL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_Connect
+* @details Sending config packet to firmware to starting connection
+* @param[in] tstrHostIFconnectAttr* pstrHostIFconnectAttr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Uint8 u8ConnectedSSID[6]={0};
+static NMI_Sint32 Handle_Connect(void * drvHandler,tstrHostIFconnectAttr* pstrHostIFconnectAttr)
+{ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWIDList[8];
+ NMI_Uint32 u32WidsCount = 0,dummyval = 0;
+ //char passphrase[] = "12345678";
+ #ifndef CONNECT_DIRECT
+ NMI_Sint32 s32Err = NMI_SUCCESS;
+ NMI_Uint32 i;
+ NMI_Uint8 u8bssDscListIndex;
+ wid_site_survey_reslts_s* pstrSurveyResults = NMI_NULL;
+ #else
+ NMI_Uint8* pu8CurrByte = NMI_NULL;
+ /*Bug4218: Parsing Join Param*/
+ #ifdef NMI_PARSE_SCAN_IN_HOST
+ tstrJoinBssParam* ptstrJoinBssParam;
+ #endif/*NMI_PARSE_SCAN_IN_HOST*/
+
+ #endif
+
+ PRINT_D(GENERIC_DBG,"Handling connect request\n");
+
+ #ifndef CONNECT_DIRECT
+ NMI_memset(gapu8RcvdSurveyResults[0], 0, MAX_SURVEY_RESULT_FRAG_SIZE);
+ NMI_memset(gapu8RcvdSurveyResults[1], 0, MAX_SURVEY_RESULT_FRAG_SIZE);
+
+
+ PRINT_D(HOSTINF_DBG,"Getting site survey results\n");
+ s32Err = host_int_get_site_survey_results((NMI_WFIDrvHandle)pstrWFIDrv,
+ gapu8RcvdSurveyResults,
+ MAX_SURVEY_RESULT_FRAG_SIZE);
+ if(s32Err)
+ {
+ PRINT_ER("Failed to get site survey results\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+
+ }
+ s32Err = ParseSurveyResults(gapu8RcvdSurveyResults, &pstrSurveyResults,
+ &pstrWFIDrv->u32SurveyResultsCount);
+
+
+ if(s32Err == NMI_SUCCESS)
+ {
+ /* use the parsed info in pstrSurveyResults, then deallocate it */
+ PRINT_D(HOSTINF_DBG,"Copying site survey results in global structure, then deallocate\n");
+ for(i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++)
+ {
+ NMI_memcpy(&pstrWFIDrv->astrSurveyResults[i], &pstrSurveyResults[i],
+ sizeof(wid_site_survey_reslts_s));
+ }
+
+ DeallocateSurveyResults(pstrSurveyResults);
+ }
+ else
+ {
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ PRINT_ER("ParseSurveyResults() Error(%d) \n", s32Err);
+ }
+
+
+ for(i = 0; i < pstrWFIDrv->u32SurveyResultsCount; i++)
+ {
+ if(NMI_memcmp(pstrWFIDrv->astrSurveyResults[i].SSID,
+ pstrHostIFconnectAttr->pu8ssid,
+ pstrHostIFconnectAttr->ssidLen) == 0)
+ {
+ PRINT_INFO(HOSTINF_DBG,"Network with required SSID is found %s\n",pstrHostIFconnectAttr->pu8ssid);
+ if(pstrHostIFconnectAttr->pu8bssid == NULL)
+ {
+ /* BSSID is not passed from the user, so decision of matching
+ * is done by SSID only */
+ PRINT_INFO(HOSTINF_DBG,"BSSID is not passed from the user\n");
+ break;
+ }
+ else
+ {
+ /* BSSID is also passed from the user, so decision of matching
+ * should consider also this passed BSSID */
+
+ if(NMI_memcmp(pstrWFIDrv->astrSurveyResults[i].BSSID,
+ pstrHostIFconnectAttr->pu8bssid,
+ 6) == 0)
+ {
+ PRINT_INFO(HOSTINF_DBG,"BSSID is passed from the user and matched\n");
+ break;
+ }
+ }
+ }
+ }
+
+ if(i < pstrWFIDrv->u32SurveyResultsCount)
+ {
+ u8bssDscListIndex = i;
+
+ PRINT_INFO(HOSTINF_DBG,"Connecting to network of Bss Idx %d and SSID %s and channel %d \n",
+ u8bssDscListIndex, pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].SSID,
+ pstrWFIDrv->astrSurveyResults[u8bssDscListIndex].Channel);
+
+ PRINT_INFO(HOSTINF_DBG,"Saving connection parameters in global structure\n");
+
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = (NMI_Uint8*)NMI_MALLOC(6);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen;
+ if(pstrHostIFconnectAttr->pu8ssid != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->ssidLen+1);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid,
+ pstrHostIFconnectAttr->ssidLen);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0';
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen;
+ if(pstrHostIFconnectAttr->pu8IEs != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->IEsLen);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs,
+ pstrHostIFconnectAttr->IEsLen);
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.u8security= pstrHostIFconnectAttr->u8security;
+ pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type= pstrHostIFconnectAttr->tenuAuth_type;
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult;
+ pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg;
+
+
+ //if((gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) &&
+ // (gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen != 0))
+ {
+ /* IEs to be inserted in Association Request */
+ strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
+ strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs;
+ strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen;
+ u32WidsCount++;
+ }
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrWFIDrv->strNMI_UsrConnReq.u8security));
+ u32WidsCount++;
+
+ PRINT_INFO(HOSTINF_DBG,"Encrypt Mode = %x\n",pstrWFIDrv->strNMI_UsrConnReq.u8security);
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_AUTH_TYPE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type);
+ u32WidsCount++;
+
+ PRINT_INFO(HOSTINF_DBG,"Authentication Type = %x\n",pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type);
+ /*
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_11I_PSK;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(passphrase);
+ u32WidsCount++;
+ */
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_JOIN_REQ;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)&u8bssDscListIndex;
+ u32WidsCount++;
+
+ #ifndef SIMULATION
+ /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the
+ firmware at chip reset when processing the WIDs of the Connect Request.
+ (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */
+ ////////////////////////
+ gu32WidConnRstHack = 0;
+ ////////////////////////
+ #endif
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Handle_Connect()] failed to send config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
+ }
+
+ }
+ else
+ {
+ PRINT_ER("Required BSSID not found\n");
+ NMI_ERRORREPORT(s32Error,NMI_NOT_FOUND);
+ }
+
+ #else
+
+ PRINT_INFO(HOSTINF_DBG,"Saving connection parameters in global structure\n");
+
+ /*Bug4218: Parsing Join Param*/
+ #ifdef NMI_PARSE_SCAN_IN_HOST
+ ptstrJoinBssParam = (tstrJoinBssParam*)pstrHostIFconnectAttr->pJoinParams;
+ if(ptstrJoinBssParam==NULL)
+ {
+ PRINT_ER("Required BSSID not found\n");
+ NMI_ERRORREPORT(s32Error,NMI_NOT_FOUND);
+ }
+ #endif /*NMI_PARSE_SCAN_IN_HOST*/
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTING;
+
+#if 0
+ // if we try to connect to an already connected AP then discard the request
+ PRINT_D(GENERIC_DBG,"Bssid = %x:%x:%x:%x:%x:%x\n",(pstrHostIFconnectAttr->pu8bssid[0]),(pstrHostIFconnectAttr->pu8bssid[1]),(pstrHostIFconnectAttr->pu8bssid[2]),(pstrHostIFconnectAttr->pu8bssid[3]),(pstrHostIFconnectAttr->pu8bssid[4]),(pstrHostIFconnectAttr->pu8bssid[5]));
+ PRINT_D(GENERIC_DBG,"bssid = %x:%x:%x:%x:%x:%x\n",(u8ConnectedSSID[0]),(u8ConnectedSSID[1]),(u8ConnectedSSID[2]),(u8ConnectedSSID[3]),(u8ConnectedSSID[4]),(u8ConnectedSSID[5]));
+ if(NMI_memcmp(pstrHostIFconnectAttr->pu8bssid,&u8ConnectedSSID,ETH_ALEN) == 0)
+ {
+ PRINT_ER("Discard connect request\n");
+ s32Error=NMI_FAIL;
+ return s32Error;
+ }
+#endif
+
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = (NMI_Uint8*)NMI_MALLOC(6);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen;
+ if(pstrHostIFconnectAttr->pu8ssid != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->ssidLen+1);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid,
+ pstrHostIFconnectAttr->ssidLen);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0';
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen;
+ if(pstrHostIFconnectAttr->pu8IEs != NULL)
+ {
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->IEsLen);
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs,
+ pstrHostIFconnectAttr->IEsLen);
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.u8security= pstrHostIFconnectAttr->u8security;
+ pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type= pstrHostIFconnectAttr->tenuAuth_type;
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult;
+ pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(dummyval));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(dummyval));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(dummyval));
+ u32WidsCount++;
+
+ //if((gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) &&
+ // (gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen != 0))
+ {
+ /* IEs to be inserted in Association Request */
+ strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
+ strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs;
+ strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen;
+ u32WidsCount++;
+
+ /*BugID_5137*/
+ if(NMI_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid,7))
+ {
+
+ gu32FlushedInfoElemAsocSize = pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen;
+ gu8FlushedInfoElemAsoc = NMI_MALLOC(gu32FlushedInfoElemAsocSize);
+ memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs,
+ gu32FlushedInfoElemAsocSize);
+ }
+ }
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrWFIDrv->strNMI_UsrConnReq.u8security));
+ u32WidsCount++;
+
+ /*BugID_5137*/
+ if(NMI_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid,7))
+ gu8Flushed11iMode = pstrWFIDrv->strNMI_UsrConnReq.u8security;
+
+ PRINT_INFO(HOSTINF_DBG,"Encrypt Mode = %x\n",pstrWFIDrv->strNMI_UsrConnReq.u8security);
+
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_AUTH_TYPE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type);
+ u32WidsCount++;
+
+ /*BugID_5137*/
+ if(NMI_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid,7))
+ gu8FlushedAuthType = (NMI_Uint8)pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type;
+
+ PRINT_INFO(HOSTINF_DBG,"Authentication Type = %x\n",pstrWFIDrv->strNMI_UsrConnReq.tenuAuth_type);
+ /*
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_11I_PSK;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(passphrase);
+ u32WidsCount++;
+ */
+
+ PRINT_D(HOSTINF_DBG,"Connecting to network of SSID %s on channel %d\n",
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->u8channel);
+
+
+#ifndef NMI_PARSE_SCAN_IN_HOST
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_JOIN_REQ_EXTENDED;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+ strWIDList[u32WidsCount].s32ValueSize = MAX_SSID_LEN+7;
+ strWIDList[u32WidsCount].ps8WidVal = NMI_MALLOC(strWIDList[u32WidsCount].s32ValueSize);
+
+ if(strWIDList[u32WidsCount].ps8WidVal == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
+
+ if(pstrHostIFconnectAttr->pu8ssid != NULL)
+ {
+ NMI_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen);
+ pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0';
+ }
+ pu8CurrByte += MAX_SSID_LEN;
+ if((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14))
+ {
+ *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel;
+ }
+ else
+ {
+ PRINT_ER("Channel out of range\n");
+ *(pu8CurrByte++) = 0xFF;
+ }
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+ pu8CurrByte += 6;
+
+ /* keep the buffer at the start of the allocated pointer to use it with the free*/
+ pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal ;
+
+ #else
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_JOIN_REQ_EXTENDED;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+
+ /*Sending NoA attributes during connection*/
+ strWIDList[u32WidsCount].s32ValueSize = 112;//79;
+ strWIDList[u32WidsCount].ps8WidVal = NMI_MALLOC(strWIDList[u32WidsCount].s32ValueSize);
+
+ /*BugID_5137*/
+ if(NMI_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid,7))
+ {
+ gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize;
+ gu8FlushedJoinReq = NMI_MALLOC(gu32FlushedJoinReqSize);
+ }
+ if(strWIDList[u32WidsCount].ps8WidVal == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
+
+
+ if(pstrHostIFconnectAttr->pu8ssid != NULL)
+ {
+ NMI_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen);
+ pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0';
+ }
+ pu8CurrByte += MAX_SSID_LEN;
+
+ /* BSS type*/
+ *(pu8CurrByte++) = INFRASTRUCTURE;
+ /* Channel*/
+ if((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14))
+ {
+ *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel;
+ }
+ else
+ {
+ PRINT_ER("Channel out of range\n");
+ *(pu8CurrByte++) = 0xFF;
+ }
+ /* Cap Info*/
+ *(pu8CurrByte++) = ( ptstrJoinBssParam->cap_info) & 0xFF;
+ *(pu8CurrByte++) = (( ptstrJoinBssParam->cap_info) >>8) & 0xFF;
+ PRINT_D(HOSTINF_DBG,"* Cap Info %0x*\n",(*(pu8CurrByte-2) | ((*(pu8CurrByte-1))<<8)) );
+
+ /* sa*/
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+ pu8CurrByte += 6;
+
+ /* bssid*/
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+ pu8CurrByte += 6;
+
+ /* Beacon Period*/
+ *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
+ *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >>8) & 0xFF;
+ PRINT_D(HOSTINF_DBG,"* Beacon Period %d*\n",(*(pu8CurrByte-2) | ((*(pu8CurrByte-1))<<8) ));
+ /* DTIM Period*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
+ PRINT_D(HOSTINF_DBG,"* DTIM Period %d*\n",(*(pu8CurrByte-1)));
+ /* Supported rates*/
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED+1);
+ pu8CurrByte += (MAX_RATES_SUPPORTED+1);
+
+ /* wmm cap*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
+ PRINT_D(HOSTINF_DBG,"* wmm cap%d*\n",(*(pu8CurrByte-1)));
+ /* uapsd cap*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
+
+ /* ht cap*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
+ //copy this information to the user request
+ pstrWFIDrv->strNMI_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable;
+
+ /* rsn found*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
+ PRINT_D(HOSTINF_DBG,"* rsn found %d*\n",*(pu8CurrByte-1));
+ /* rsn group policy*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
+ PRINT_D(HOSTINF_DBG,"* rsn group policy %0x*\n",(*(pu8CurrByte-1)));
+ /* mode_802_11i*/
+ *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
+ PRINT_D(HOSTINF_DBG,"* mode_802_11i %d*\n",(*(pu8CurrByte-1)));
+ /* rsn pcip policy*/
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
+ pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
+
+ /* rsn auth policy*/
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
+ pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
+
+ /* rsn auth policy*/
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof( ptstrJoinBssParam->rsn_cap));
+ pu8CurrByte += sizeof( ptstrJoinBssParam->rsn_cap);
+
+ /*BugID_5137*/
+ *(pu8CurrByte++) = REAL_JOIN_REQ;
+
+ #ifdef NMI_P2P
+ *(pu8CurrByte++) = ptstrJoinBssParam->u8NoaEnbaled;
+ if(ptstrJoinBssParam->u8NoaEnbaled)
+ {
+ PRINT_D(HOSTINF_DBG,"NOA present\n");
+
+ *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
+ *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf)>>8) & 0xFF;
+ *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf)>>16) & 0xFF;
+ *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf)>>24) & 0xFF;
+
+ *(pu8CurrByte++) = ptstrJoinBssParam->u8Index;
+
+ *(pu8CurrByte++) =ptstrJoinBssParam->u8OppEnable;
+
+ if(ptstrJoinBssParam->u8OppEnable)
+ *(pu8CurrByte++) = ptstrJoinBssParam->u8CtWindow;
+
+ *(pu8CurrByte++) = ptstrJoinBssParam->u8Count;
+
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Duration, sizeof( ptstrJoinBssParam->au8Duration));
+
+ pu8CurrByte += sizeof( ptstrJoinBssParam->au8Duration);
+
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->au8Interval, sizeof( ptstrJoinBssParam->au8Interval));
+
+ pu8CurrByte += sizeof( ptstrJoinBssParam->au8Interval);
+
+ NMI_memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof( ptstrJoinBssParam->au8StartTime));
+
+ pu8CurrByte += sizeof( ptstrJoinBssParam->au8StartTime);
+
+ }
+ else
+ PRINT_D(HOSTINF_DBG,"NOA not present\n");
+ #endif
+
+
+ /* keep the buffer at the start of the allocated pointer to use it with the free*/
+ pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal ;
+
+
+ #endif /* #ifdef NMI_PARSE_SCAN_IN_HOST*/
+ u32WidsCount++;
+
+ #ifndef SIMULATION
+ /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the
+ firmware at chip reset when processing the WIDs of the Connect Request.
+ (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */
+ ////////////////////////
+ gu32WidConnRstHack = 0;
+ ////////////////////////
+ #endif
+
+ /*BugID_5137*/
+ if(NMI_memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid,7))
+ {
+ memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize);
+ gu8FlushedJoinReqDrvHandler = (NMI_Uint32)pstrWFIDrv;
+ }
+
+ PRINT_D(GENERIC_DBG,"send HOST_IF_WAITING_CONN_RESP\n");
+
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_memcpy(&u8ConnectedSSID,pstrHostIFconnectAttr->pu8bssid,ETH_ALEN);
+
+ PRINT_D(GENERIC_DBG,"save Bssid = %x:%x:%x:%x:%x:%x\n",(pstrHostIFconnectAttr->pu8bssid[0]),(pstrHostIFconnectAttr->pu8bssid[1]),(pstrHostIFconnectAttr->pu8bssid[2]),(pstrHostIFconnectAttr->pu8bssid[3]),(pstrHostIFconnectAttr->pu8bssid[4]),(pstrHostIFconnectAttr->pu8bssid[5]));
+ PRINT_D(GENERIC_DBG,"save bssid = %x:%x:%x:%x:%x:%x\n",(u8ConnectedSSID[0]),(u8ConnectedSSID[1]),(u8ConnectedSSID[2]),(u8ConnectedSSID[3]),(u8ConnectedSSID[4]),(u8ConnectedSSID[5]));
+ }
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Handle_Connect()] failed to send config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ PRINT_D(GENERIC_DBG,"set HOST_IF_WAITING_CONN_RESP\n");
+ pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
+ }
+ #endif
+
+ NMI_CATCH(s32Error)
+ {
+ tstrConnectInfo strConnectInfo;
+
+ NMI_TimerStop(&(pstrWFIDrv->hConnectTimer), NMI_NULL);
+
+ PRINT_D(HOSTINF_DBG,"could not start connecting to the required network\n");
+
+ NMI_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
+
+ if(pstrHostIFconnectAttr->pfConnectResult != NULL)
+ {
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
+ }
+
+ if(pstrHostIFconnectAttr->pu8IEs != NULL)
+ {
+ strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen;
+ strConnectInfo.pu8ReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->IEsLen);
+ NMI_memcpy(strConnectInfo.pu8ReqIEs,
+ pstrHostIFconnectAttr->pu8IEs,
+ pstrHostIFconnectAttr->IEsLen);
+ }
+
+ pstrHostIFconnectAttr->pfConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
+ &strConnectInfo,
+ MAC_DISCONNECTED,
+ NULL,
+ pstrHostIFconnectAttr->pvUserArg);
+ /*Change state to idle*/
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+ /* Deallocation */
+ if(strConnectInfo.pu8ReqIEs != NULL)
+ {
+ NMI_FREE(strConnectInfo.pu8ReqIEs);
+ strConnectInfo.pu8ReqIEs = NULL;
+ }
+
+ }
+ else
+ {
+ PRINT_ER("Connect callback function pointer is NULL \n");
+ }
+ }
+
+ PRINT_D(HOSTINF_DBG,"Deallocating connection parameters\n");
+ /* Deallocate pstrHostIFconnectAttr->pu8bssid which was prevoisuly allocated by the sending thread */
+ if(pstrHostIFconnectAttr->pu8bssid != NULL)
+ {
+ NMI_FREE(pstrHostIFconnectAttr->pu8bssid);
+ pstrHostIFconnectAttr->pu8bssid = NULL;
+ }
+
+ /* Deallocate pstrHostIFconnectAttr->pu8ssid which was prevoisuly allocated by the sending thread */
+ if(pstrHostIFconnectAttr->pu8ssid != NULL)
+ {
+ NMI_FREE(pstrHostIFconnectAttr->pu8ssid);
+ pstrHostIFconnectAttr->pu8ssid = NULL;
+ }
+
+ /* Deallocate pstrHostIFconnectAttr->pu8IEs which was prevoisuly allocated by the sending thread */
+ if(pstrHostIFconnectAttr->pu8IEs != NULL)
+ {
+ NMI_FREE(pstrHostIFconnectAttr->pu8IEs);
+ pstrHostIFconnectAttr->pu8IEs = NULL;
+ }
+
+ if(pu8CurrByte != NMI_NULL)
+ {
+ NMI_FREE(pu8CurrByte);
+ }
+ return s32Error;
+}
+
+/**
+* @brief Handle_FlushConnect
+* @details Sending config packet to firmware to flush an old connection
+ after switching FW from station one to hybrid one
+* @param[in] void * drvHandler
+* @return Error code.
+* @author Amr Abdel-Moghny
+* @date 19 DEC 2013
+* @version 8.0
+*/
+
+static NMI_Sint32 Handle_FlushConnect(void * drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWIDList[5];
+ NMI_Uint32 u32WidsCount = 0;
+ NMI_Uint8* pu8CurrByte = NMI_NULL;
+
+
+ /* IEs to be inserted in Association Request */
+ strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
+ strWIDList[u32WidsCount].ps8WidVal = gu8FlushedInfoElemAsoc;
+ strWIDList[u32WidsCount].s32ValueSize = gu32FlushedInfoElemAsocSize;
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(gu8Flushed11iMode));
+ u32WidsCount++;
+
+
+
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_AUTH_TYPE;
+ strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&gu8FlushedAuthType);
+ u32WidsCount++;
+
+
+ #ifdef NMI_PARSE_SCAN_IN_HOST
+ strWIDList[u32WidsCount].u16WIDid = (NMI_Uint16)WID_JOIN_REQ_EXTENDED;
+ strWIDList[u32WidsCount].enuWIDtype = WID_STR;
+ strWIDList[u32WidsCount].s32ValueSize = gu32FlushedJoinReqSize;
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)gu8FlushedJoinReq;
+ pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
+
+ pu8CurrByte += FLUSHED_BYTE_POS;
+ *(pu8CurrByte) = FLUSHED_JOIN_REQ;
+
+ u32WidsCount++;
+
+ #endif
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE, gu8FlushedJoinReqDrvHandler);
+ if(s32Error)
+ {
+ PRINT_ER("Handle_Flush_Connect()] failed to send config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_ConnectTimeout
+* @details Call connect notification callback function indicating connection failure
+* @param[in] NONE
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_ConnectTimeout(void* drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrConnectInfo strConnectInfo;
+ tstrWID strWID;
+ NMI_Uint16 u16DummyReasonCode = 0;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+
+ gbScanWhileConnected = NMI_FALSE;
+
+
+ NMI_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
+
+ /* First, we will notify the upper layer with the Connection failure {through the Connect Callback function},
+ then we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying
+ WID_DISCONNECT} */
+ if(pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult != NULL)
+ {
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ NMI_memcpy(strConnectInfo.au8bssid,
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid, 6);
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ strConnectInfo.ReqIEsLen = pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen;
+ strConnectInfo.pu8ReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen);
+ NMI_memcpy(strConnectInfo.pu8ReqIEs,
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs,
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen);
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
+ &strConnectInfo,
+ MAC_DISCONNECTED,
+ NULL,
+ pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid);
+
+ /* Deallocation of strConnectInfo.pu8ReqIEs */
+ if(strConnectInfo.pu8ReqIEs != NULL)
+ {
+ NMI_FREE(strConnectInfo.pu8ReqIEs);
+ strConnectInfo.pu8ReqIEs = NULL;
+ }
+ }
+ else
+ {
+ PRINT_ER("Connect callback function pointer is NULL \n");
+ }
+
+ /* Here we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying
+ WID_DISCONNECT} */
+ strWID.u16WIDid = (NMI_Uint16)WID_DISCONNECT;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&u16DummyReasonCode;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ PRINT_D(HOSTINF_DBG,"Sending disconnect request\n");
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send dissconect config packet\n");
+ }
+
+ /* Deallocation of the Saved Connect Request in the global Handle */
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = NULL;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = NULL;
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = NULL;
+ }
+
+ /*BugID_5213*/
+ /*Freeing flushed join request params on connect timeout*/
+ if(gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedJoinReq);
+ gu8FlushedJoinReq = NULL;
+ }
+ if(gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedInfoElemAsoc);
+ gu8FlushedInfoElemAsoc = NULL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_RcvdNtwrkInfo
+* @details Handling received network information
+* @param[in] tstrRcvdNetworkInfo* pstrRcvdNetworkInfo
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_RcvdNtwrkInfo(void* drvHandler,tstrRcvdNetworkInfo* pstrRcvdNetworkInfo)
+{
+ NMI_Uint32 i;
+ NMI_Bool bNewNtwrkFound;
+
+
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNetworkInfo * pstrNetworkInfo = NULL;
+ void* pJoinParams = NULL;
+
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+
+ bNewNtwrkFound = NMI_TRUE;
+ PRINT_INFO(HOSTINF_DBG,"Handling received network info\n");
+
+ /*if there is a an ongoing scan request*/
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ PRINT_D(HOSTINF_DBG,"State: Scanning, parsing network information received\n");
+ ParseNetworkInfo(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo);
+ if((pstrNetworkInfo == NULL)
+ ||(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult == NMI_NULL))
+ {
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ /* check whether this network is discovered before */
+ for(i = 0; i < pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount; i++)
+ {
+
+ if((pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) &&
+ (pstrNetworkInfo->au8bssid != NULL))
+ {
+ if(NMI_memcmp(pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[i].au8bssid,
+ pstrNetworkInfo->au8bssid, 6) == 0)
+ {
+ if(pstrNetworkInfo->s8rssi <= pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[i].s8rssi)
+ {
+ /*we have already found this network with better rssi, so keep the old cached one and don't
+ send anything to the upper layer */
+ PRINT_D(HOSTINF_DBG,"Network previously discovered\n");
+ goto done;
+ }
+ else
+ {
+ /* here the same already found network is found again but with a better rssi, so just update
+ the rssi for this cached network and send this updated network to the upper layer but
+ don't add a new record for it */
+ pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi;
+ bNewNtwrkFound = NMI_FALSE;
+ break;
+ }
+ }
+ }
+ }
+
+ if(bNewNtwrkFound == NMI_TRUE)
+ {
+ /* here it is confirmed that it is a new discovered network,
+ * so add its record then call the User CallBack function */
+
+ PRINT_D(HOSTINF_DBG,"New network found\n");
+
+ if(pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS)
+ {
+ pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
+
+ if((pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount].au8bssid != NULL)
+ && (pstrNetworkInfo->au8bssid != NULL))
+ {
+ NMI_memcpy(pstrWFIDrv->strNMI_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount].au8bssid,
+ pstrNetworkInfo->au8bssid, 6);
+
+ pstrWFIDrv->strNMI_UsrScanReq.u32RcvdChCount++;
+
+ pstrNetworkInfo->bNewNetwork = NMI_TRUE;
+ /*Bug4218: Parsing Join Param*/
+ //add new BSS to JoinBssTable
+ #ifdef NMI_PARSE_SCAN_IN_HOST
+ pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
+ #endif/*NMI_PARSE_SCAN_IN_HOST*/
+
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid,
+ pJoinParams);
+
+
+ }
+ }
+ else
+ {
+ PRINT_WRN(HOSTINF_DBG,"Discovered networks exceeded max. limit \n");
+ }
+ }
+ else
+ {
+ pstrNetworkInfo->bNewNetwork = NMI_FALSE;
+ /* just call the User CallBack function to send the same discovered network with its updated RSSI */
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid,NULL);
+ }
+ }
+
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+done:
+ /* Deallocate pstrRcvdNetworkInfo->pu8Buffer which was prevoisuly allocated by the sending thread */
+ if(pstrRcvdNetworkInfo->pu8Buffer != NULL)
+ {
+ NMI_FREE(pstrRcvdNetworkInfo->pu8Buffer);
+ pstrRcvdNetworkInfo->pu8Buffer = NULL;
+ }
+
+ /*free structure allocated*/
+ if(pstrNetworkInfo != NMI_NULL)
+ {
+ DeallocateNetworkInfo(pstrNetworkInfo);
+ pstrNetworkInfo = NMI_NULL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_RcvdGnrlAsyncInfo
+* @details Handling received asynchrous general network information
+* @param[in] tstrRcvdGnrlAsyncInfo* pstrRcvdGnrlAsyncInfo
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_RcvdGnrlAsyncInfo(void * drvHandler,tstrRcvdGnrlAsyncInfo* pstrRcvdGnrlAsyncInfo)
+{
+ //TODO: mostafa: till now, this function just handles only the received mac status msg,
+ // which carries only 1 WID which have WID ID = WID_STATUS
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 u8MsgType = 0;
+ NMI_Uint8 u8MsgID = 0;
+ NMI_Uint16 u16MsgLen = 0;
+ NMI_Uint16 u16WidID = (NMI_Uint16)WID_NIL;
+ NMI_Uint8 u8WidLen = 0;
+ NMI_Uint8 u8MacStatus;
+ NMI_Uint8 u8MacStatusReasonCode;
+ NMI_Uint8 u8MacStatusAdditionalInfo;
+ tstrConnectInfo strConnectInfo;
+ tstrDisconnectNotifInfo strDisconnectNotifInfo;
+ NMI_Sint32 s32Err = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+ PRINT_D(GENERIC_DBG,"Current State = %d,Received state = %d\n",pstrWFIDrv->enuHostIFstate,
+ pstrRcvdGnrlAsyncInfo->pu8Buffer[7]);
+
+ if((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) ||
+ (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) ||
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ if((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) ||
+ (pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult == NMI_NULL))
+ {
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ u8MsgType = pstrRcvdGnrlAsyncInfo->pu8Buffer[0];
+
+ /* Check whether the received message type is 'I' */
+ if('I' != u8MsgType)
+ {
+ PRINT_ER("Received Message format incorrect.\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ /* Extract message ID */
+ u8MsgID = pstrRcvdGnrlAsyncInfo->pu8Buffer[1];
+
+ /* Extract message Length */
+ u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[2], pstrRcvdGnrlAsyncInfo->pu8Buffer[3]);
+
+ /* Extract WID ID [expected to be = WID_STATUS] */
+ u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[4], pstrRcvdGnrlAsyncInfo->pu8Buffer[5]);
+
+ /* Extract WID Length [expected to be = 1] */
+ u8WidLen = pstrRcvdGnrlAsyncInfo->pu8Buffer[6];
+
+ /* get the WID value [expected to be one of two values: either MAC_CONNECTED = (1) or MAC_DISCONNECTED = (0)] */
+ u8MacStatus = pstrRcvdGnrlAsyncInfo->pu8Buffer[7];
+ u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->pu8Buffer[8];
+ u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->pu8Buffer[9];
+ printk("Recieved MAC status = %d with Reason = %d , Info = %d\n",u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP)
+ {
+ /* our station had sent Association Request frame, so here it will get the Association Response frame then parse it */
+ NMI_Uint32 u32RcvdAssocRespInfoLen;
+ tstrConnectRespInfo* pstrConnectRespInfo = NULL;
+
+ PRINT_D(HOSTINF_DBG,"Recieved MAC status = %d with Reason = %d , Code = %d\n",u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
+
+ NMI_memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
+
+ if(u8MacStatus == MAC_CONNECTED)
+ {
+ NMI_memset(gapu8RcvdAssocResp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
+
+ host_int_get_assoc_res_info((NMI_WFIDrvHandle)pstrWFIDrv,
+ gapu8RcvdAssocResp,
+ MAX_ASSOC_RESP_FRAME_SIZE,
+ &u32RcvdAssocRespInfoLen);
+
+ PRINT_INFO(HOSTINF_DBG,"Received association response with length = %d\n",u32RcvdAssocRespInfoLen);
+
+ if(u32RcvdAssocRespInfoLen != 0)
+ {
+
+ PRINT_D(HOSTINF_DBG,"Parsing association response\n");
+ s32Err = ParseAssocRespInfo(gapu8RcvdAssocResp, u32RcvdAssocRespInfoLen,
+ &pstrConnectRespInfo);
+ if(s32Err)
+ {
+ PRINT_ER("ParseAssocRespInfo() returned error %d \n", s32Err);
+ }
+ else
+ {
+ /* use the necessary parsed Info from the Received Association Response */
+ strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
+
+ if(strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)
+ {
+ PRINT_INFO(HOSTINF_DBG,"Association response received : Successful connection status\n");
+ if(pstrConnectRespInfo->pu8RespIEs != NULL)
+ {
+ strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
+
+
+ strConnectInfo.pu8RespIEs = (NMI_Uint8*)NMI_MALLOC(pstrConnectRespInfo->u16RespIEsLen);
+ NMI_memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
+ pstrConnectRespInfo->u16RespIEsLen);
+ }
+ }
+
+ /* deallocate the Assoc. Resp. parsed structure as it is not needed anymore */
+ if(pstrConnectRespInfo != NULL)
+ {
+ DeallocateAssocRespInfo(pstrConnectRespInfo);
+ pstrConnectRespInfo = NULL;
+ }
+ }
+ }
+ }
+
+ /* The station has just received mac status and it also received assoc. response which
+ it was waiting for.
+ So check first the matching between the received mac status and the received status code in Asoc Resp */
+ if((u8MacStatus == MAC_CONNECTED) &&
+ (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE))
+ {
+ NMI_ERROR("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE \n");
+ NMI_memset(u8ConnectedSSID,0,ETH_ALEN);
+
+ }
+ else if(u8MacStatus == MAC_DISCONNECTED)
+ {
+ NMI_ERROR("Received MAC status is MAC_DISCONNECTED\n");
+ NMI_memset(u8ConnectedSSID,0,ETH_ALEN);
+ }
+
+ //TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP
+ // through a structure of type tstrConnectRespInfo
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ PRINT_D(HOSTINF_DBG,"Retrieving actual BSSID from AP\n");
+ NMI_memcpy(strConnectInfo.au8bssid, pstrWFIDrv->strNMI_UsrConnReq.pu8bssid, 6);
+
+ if((u8MacStatus == MAC_CONNECTED) &&
+ (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE))
+
+
+ {
+ NMI_memcpy(pstrWFIDrv->au8AssociatedBSSID,
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid, ETH_ALEN);
+ }
+ }
+
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ strConnectInfo.ReqIEsLen = pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen;
+ strConnectInfo.pu8ReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen);
+ NMI_memcpy(strConnectInfo.pu8ReqIEs,
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs,
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen);
+ }
+
+
+ NMI_TimerStop(&(pstrWFIDrv->hConnectTimer), NMI_NULL);
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
+ &strConnectInfo,
+ u8MacStatus,
+ NULL,
+ pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid);
+
+
+ /* if received mac status is MAC_CONNECTED and
+ received status code in Asoc Resp is SUCCESSFUL_STATUSCODE, change state to CONNECTED
+ else change state to IDLE */
+ if((u8MacStatus == MAC_CONNECTED) &&
+ (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE))
+ {
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ host_int_set_power_mgmt((NMI_WFIDrvHandle)pstrWFIDrv, 0, 0);
+ #endif
+
+ PRINT_D(HOSTINF_DBG,"MAC status : CONNECTED and Connect Status : Successful\n");
+ pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTED;
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ PRINT_D(GENERIC_DBG,"during ip, scan disabled\n");
+ g_obtainingIP=NMI_TRUE;
+ #endif
+
+ #ifdef NMI_PARSE_SCAN_IN_HOST
+ //open a BA session if possible
+ //if(pstrWFIDrv->strNMI_UsrConnReq.IsHTCapable)
+
+ #endif
+
+ //host_int_addBASession(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid,0,
+ //BA_SESSION_DEFAULT_BUFFER_SIZE,BA_SESSION_DEFAULT_TIMEOUT);
+ }
+ else
+ {
+ PRINT_D(HOSTINF_DBG,"MAC status : %d and Connect Status : %d\n",u8MacStatus,strConnectInfo.u16ConnectStatus);
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+ gbScanWhileConnected = NMI_FALSE;
+ }
+
+ /* Deallocation */
+ if(strConnectInfo.pu8RespIEs != NULL)
+ {
+ NMI_FREE(strConnectInfo.pu8RespIEs);
+ strConnectInfo.pu8RespIEs = NULL;
+ }
+
+ if(strConnectInfo.pu8ReqIEs != NULL)
+ {
+ NMI_FREE(strConnectInfo.pu8ReqIEs);
+ strConnectInfo.pu8ReqIEs = NULL;
+ }
+
+
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = NULL;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = NULL;
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = NULL;
+ }
+
+ }
+ else if((u8MacStatus == MAC_DISCONNECTED) &&
+ (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED))
+ {
+ /* Disassociation or Deauthentication frame has been received */
+ PRINT_D(HOSTINF_DBG,"Received MAC_DISCONNECTED from the FW\n");
+
+ NMI_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
+
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ printk("\n\n<< Abort the running OBSS Scan >> \n\n");
+ NMI_TimerStop(&(pstrWFIDrv->hScanTimer), NMI_NULL);
+ Handle_ScanDone((void*)pstrWFIDrv,SCAN_EVENT_ABORTED);
+ }
+
+ strDisconnectNotifInfo.u16reason = 0;
+ strDisconnectNotifInfo.ie = NULL;
+ strDisconnectNotifInfo.ie_len = 0;
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult != NULL)
+ {
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ g_obtainingIP=NMI_FALSE;
+ host_int_set_power_mgmt((NMI_WFIDrvHandle)pstrWFIDrv, 0, 0);
+ #endif
+
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
+ NULL,
+ 0,
+ &strDisconnectNotifInfo,
+ pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid);
+
+ }
+
+ else
+ {
+ PRINT_ER("Connect result callback function is NULL \n");
+ }
+
+ NMI_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN);
+
+
+ /* Deallocation */
+
+ /* if Information Elements were retrieved from the Received deauth/disassoc frame, then they
+ should be deallocated here */
+ /*
+ if(strDisconnectNotifInfo.ie != NULL)
+ {
+ NMI_FREE(strDisconnectNotifInfo.ie);
+ strDisconnectNotifInfo.ie = NULL;
+ }
+ */
+
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = NULL;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = NULL;
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = NULL;
+ }
+
+ /*BugID_5213*/
+ /*Freeing flushed join request params on receiving*/
+ /*MAC_DISCONNECTED while connected*/
+ if(gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedJoinReq);
+ gu8FlushedJoinReq = NULL;
+ }
+ if(gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedInfoElemAsoc);
+ gu8FlushedInfoElemAsoc = NULL;
+ }
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+ gbScanWhileConnected = NMI_FALSE;
+
+ }else if((u8MacStatus == MAC_DISCONNECTED) &&
+ (pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult != NULL)){
+ PRINT_D(HOSTINF_DBG,"Received MAC_DISCONNECTED from the FW while scanning\n");
+ printk("\n\n<< Abort the running Scan >> \n\n");
+ /*Abort the running scan*/
+ NMI_TimerStop(&(pstrWFIDrv->hScanTimer), NMI_NULL);
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ Handle_ScanDone((void*)pstrWFIDrv,SCAN_EVENT_ABORTED);
+
+ }
+ }
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ /* Deallocate pstrRcvdGnrlAsyncInfo->pu8Buffer which was prevoisuly allocated by the sending thread */
+ if(pstrRcvdGnrlAsyncInfo->pu8Buffer != NULL)
+ {
+ NMI_FREE(pstrRcvdGnrlAsyncInfo->pu8Buffer);
+ pstrRcvdGnrlAsyncInfo->pu8Buffer = NULL;
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_Key
+* @details Sending config packet to firmware to set key
+* @param[in] tstrHostIFkeyAttr* pstrHostIFkeyAttr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static int Handle_Key(void * drvHandler,tstrHostIFkeyAttr* pstrHostIFkeyAttr)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ #ifdef NMI_AP_EXTERNAL_MLME
+ tstrWID strWIDList[5];
+ #endif
+ NMI_Uint8 i;
+ NMI_Uint8* pu8keybuf;
+ NMI_Sint8 s8idxarray[1];
+ NMI_Sint8 ret = 0;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ switch(pstrHostIFkeyAttr->enuKeyType)
+ {
+
+
+ case WEP:
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP)
+ {
+
+ PRINT_D(HOSTINF_DBG,"Handling WEP key\n");
+ PRINT_D(GENERIC_DBG,"ID Hostint is %d\n",(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
+ strWIDList[0].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[0].enuWIDtype = WID_CHAR;
+ strWIDList[0].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[0].ps8WidVal = (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8mode));
+
+ strWIDList[1].u16WIDid = WID_AUTH_TYPE;
+ strWIDList[1].enuWIDtype = WID_CHAR;
+ strWIDList[1].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[1].ps8WidVal= (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type));
+
+ strWIDList[2].u16WIDid = (NMI_Uint16)WID_KEY_ID;
+ strWIDList[2].enuWIDtype = WID_CHAR;
+
+ strWIDList[2].ps8WidVal = (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
+ strWIDList[2].s32ValueSize = sizeof(NMI_Char);
+
+
+pu8keybuf = (NMI_Uint8*)NMI_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
+
+
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send Key\n");
+ return -1;
+ }
+
+ NMI_memcpy(pu8keybuf,pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
+
+
+ NMI_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey);
+
+ strWIDList[3].u16WIDid = (NMI_Uint16)WID_WEP_KEY_VALUE;
+ strWIDList[3].enuWIDtype = WID_STR;
+ strWIDList[3].s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen;
+ strWIDList[3].ps8WidVal = (NMI_Sint8*)pu8keybuf;
+
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, 4, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ NMI_FREE(pu8keybuf);
+
+
+ }
+ #endif
+
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY)
+ {
+ PRINT_D(HOSTINF_DBG,"Handling WEP key\n");
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2);
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send Key\n");
+ return -1;
+ }
+ pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx;
+
+ NMI_memcpy(pu8keybuf+1, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, 1 );
+
+ NMI_memcpy(pu8keybuf+2,pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
+
+ NMI_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey);
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ADD_WEP_KEY;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Sint8*)pu8keybuf;
+ strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ NMI_FREE(pu8keybuf);
+ }
+ else if(pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY)
+ {
+
+ PRINT_D(HOSTINF_DBG,"Removing key\n");
+ strWID.u16WIDid = (NMI_Uint16)WID_REMOVE_WEP_KEY;
+ strWID.enuWIDtype = WID_STR;
+
+ s8idxarray[0] = (NMI_Sint8)pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx;
+ strWID.ps8WidVal = s8idxarray;
+ strWID.s32ValueSize = 1;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ }
+ else
+ {
+ strWID.u16WIDid = (NMI_Uint16)WID_KEY_ID;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ PRINT_D(HOSTINF_DBG,"Setting default key index\n");
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ }
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), NMI_NULL);
+ break;
+ case WPARxGtk:
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP)
+ {
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC(RX_MIC_KEY_MSG_LEN);
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send RxGTK Key\n");
+ ret = -1;
+ goto _WPARxGtk_end_case_;
+ }
+
+ NMI_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN);
+
+
+ /*|----------------------------------------------------------------------------|
+ |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key |
+ |------------|---------|-------|------------|---------------|----------------|
+ | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/
+
+
+
+ if(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq != NULL)
+ NMI_memcpy(pu8keybuf+6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8 );
+
+
+ NMI_memcpy(pu8keybuf+14,&pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1);
+
+ NMI_memcpy(pu8keybuf+15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
+
+ NMI_memcpy(pu8keybuf+16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
+ //pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = 0X51;
+ strWIDList[0].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[0].enuWIDtype = WID_CHAR;
+ strWIDList[0].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[0].ps8WidVal = (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode));
+
+ strWIDList[1].u16WIDid = (NMI_Uint16)WID_ADD_RX_GTK;
+ strWIDList[1].enuWIDtype = WID_STR;
+ strWIDList[1].ps8WidVal = (NMI_Sint8*)pu8keybuf;
+ strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN;
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ NMI_FREE(pu8keybuf);
+
+ ////////////////////////////
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), NMI_NULL);
+ ///////////////////////////
+ }
+
+ #endif
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY)
+ {
+ PRINT_D(HOSTINF_DBG,"Handling group key(Rx) function\n");
+
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC(RX_MIC_KEY_MSG_LEN);
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send RxGTK Key\n");
+ ret = -1;
+ goto _WPARxGtk_end_case_;
+ }
+
+ NMI_memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN);
+
+
+ /*|----------------------------------------------------------------------------|
+ |Sta Address | Key RSC | KeyID | Key Length | Temporal Key | Rx Michael Key |
+ |------------|---------|-------|------------|---------------|----------------|
+ | 6 bytes | 8 byte |1 byte | 1 byte | 16 bytes | 8 bytes |*/
+
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)
+ {
+ NMI_memcpy(pu8keybuf, pstrWFIDrv->au8AssociatedBSSID, ETH_ALEN);
+ }
+ else
+ {
+ PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED \n");
+ }
+
+ NMI_memcpy(pu8keybuf+6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8 );
+
+ NMI_memcpy(pu8keybuf+14,&pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1);
+
+ NMI_memcpy(pu8keybuf+15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
+ NMI_memcpy(pu8keybuf+16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ADD_RX_GTK;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Sint8*)pu8keybuf;
+ strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ NMI_FREE(pu8keybuf);
+
+ ////////////////////////////
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), NMI_NULL);
+ ///////////////////////////
+}
+_WPARxGtk_end_case_:
+ NMI_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key);
+ NMI_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq);
+ if(ret == -1)
+ return ret;
+
+ break;
+
+ case WPAPtk:
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP)
+ {
+
+
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC(PTK_KEY_MSG_LEN+1);
+
+
+
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send PTK Key\n");
+ ret = -1;
+ goto _WPAPtk_end_case_;
+
+ }
+
+ /*|-----------------------------------------------------------------------------|
+ |Station address | keyidx |Key Length |Temporal Key | Rx Michael Key |Tx Michael Key |
+ |----------------|------------ |--------------|----------------|---------------|
+ | 6 bytes | 1 byte | 1byte | 16 bytes | 8 bytes | 8 bytes |
+ |-----------------------------------------------------------------------------|*/
+
+ NMI_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6 ); /*1 bytes Key Length */
+
+ NMI_memcpy(pu8keybuf+6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1 );
+ NMI_memcpy(pu8keybuf+7, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1 );
+ /*16 byte TK*/
+ NMI_memcpy(pu8keybuf+8, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
+
+
+ strWIDList[0].u16WIDid = (NMI_Uint16)WID_11I_MODE;
+ strWIDList[0].enuWIDtype = WID_CHAR;
+ strWIDList[0].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[0].ps8WidVal = (NMI_Sint8*)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode));
+
+ strWIDList[1].u16WIDid = (NMI_Uint16)WID_ADD_PTK;
+ strWIDList[1].enuWIDtype = WID_STR;
+ strWIDList[1].ps8WidVal = (NMI_Sint8 *)pu8keybuf;
+ strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN+1;
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ NMI_FREE(pu8keybuf);
+
+ ////////////////////////////
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), NMI_NULL);
+ ///////////////////////////
+ }
+ #endif
+ if(pstrHostIFkeyAttr->u8KeyAction & ADDKEY)
+ {
+
+
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC(PTK_KEY_MSG_LEN);
+
+
+
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send PTK Key\n");
+ ret = -1;
+ goto _WPAPtk_end_case_;
+
+ }
+
+ /*|-----------------------------------------------------------------------------|
+ |Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key |
+ |----------------|------------|--------------|----------------|---------------|
+ | 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes |
+ |-----------------------------------------------------------------------------|*/
+
+ NMI_memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6 ); /*1 bytes Key Length */
+
+ NMI_memcpy(pu8keybuf+6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1 );
+ /*16 byte TK*/
+ NMI_memcpy(pu8keybuf+7, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ADD_PTK;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Sint8 *)pu8keybuf;
+ strWID.s32ValueSize = PTK_KEY_MSG_LEN;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ NMI_FREE(pu8keybuf);
+
+ ////////////////////////////
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestKeyBlock), NMI_NULL);
+ ///////////////////////////
+ }
+
+_WPAPtk_end_case_:
+ NMI_FREE(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key);
+ if(ret == -1)
+ return ret;
+
+ break;
+
+
+ case PMKSA:
+
+ PRINT_D(HOSTINF_DBG,"Handling PMKSA key\n");
+
+ pu8keybuf = (NMI_Uint8*)NMI_MALLOC( (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid*PMKSA_KEY_LEN) + 1);
+ if(pu8keybuf == NULL)
+ {
+ PRINT_ER("No buffer to send PMKSA Key\n");
+ return -1;
+ }
+
+ pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid;
+
+ for(i = 0 ; i< pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid;i++)
+ {
+
+ NMI_memcpy(pu8keybuf+((PMKSA_KEY_LEN * i)+1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, ETH_ALEN);
+ NMI_memcpy(pu8keybuf+((PMKSA_KEY_LEN * i)+ETH_ALEN+1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, PMKID_LEN);
+ }
+
+ strWID.u16WIDid = (NMI_Uint16)WID_PMKID_INFO;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Sint8*)pu8keybuf;
+ strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid*PMKSA_KEY_LEN) + 1;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ NMI_FREE(pu8keybuf);
+ break;
+ }
+
+ if(s32Error)
+ PRINT_ER("Failed to send key config packet\n");
+
+
+ return s32Error;
+}
+
+
+/**
+* @brief Handle_Disconnect
+* @details Sending config packet to firmware to disconnect
+* @param[in] NONE
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_Disconnect(void* drvHandler)
+{
+ tstrWID strWID;
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint16 u16DummyReasonCode = 0;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_DISCONNECT;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&u16DummyReasonCode;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+
+
+ PRINT_D(HOSTINF_DBG,"Sending disconnect request\n");
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ g_obtainingIP=NMI_FALSE;
+ host_int_set_power_mgmt((NMI_WFIDrvHandle)pstrWFIDrv, 0, 0);
+ #endif
+
+ NMI_memset(u8ConnectedSSID,0,ETH_ALEN);
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send dissconect config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+ else
+ {
+ tstrDisconnectNotifInfo strDisconnectNotifInfo;
+
+ NMI_memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
+
+ strDisconnectNotifInfo.u16reason = 0;
+ strDisconnectNotifInfo.ie = NULL;
+ strDisconnectNotifInfo.ie_len = 0;
+
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ NMI_TimerStop(&(pstrWFIDrv->hScanTimer), NMI_NULL);
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NMI_NULL,
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid,NULL);
+
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult= NMI_NULL;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult != NULL)
+ {
+
+ pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
+ 0, &strDisconnectNotifInfo,pstrWFIDrv->strNMI_UsrConnReq.u32UserConnectPvoid);
+ }
+ else
+ {
+ NMI_ERROR("strNMI_UsrConnReq.pfUserConnectResult = NULL \n");
+ }
+
+ gbScanWhileConnected = NMI_FALSE;
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+
+ NMI_memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN);
+
+
+ /* Deallocation */
+ pstrWFIDrv->strNMI_UsrConnReq.ssidLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ssid = NULL;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8bssid);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8bssid = NULL;
+ }
+
+ pstrWFIDrv->strNMI_UsrConnReq.ConnReqIEsLen = 0;
+ if(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs != NULL)
+ {
+ NMI_FREE(pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs);
+ pstrWFIDrv->strNMI_UsrConnReq.pu8ConnReqIEs = NULL;
+ }
+
+ /*BugID_5137*/
+ if(gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedJoinReq);
+ gu8FlushedJoinReq = NULL;
+ }
+ if(gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler==(NMI_Uint32)drvHandler)
+ {
+ NMI_FREE(gu8FlushedInfoElemAsoc);
+ gu8FlushedInfoElemAsoc = NULL;
+ }
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ ////////////////////////////
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemTestDisconnectBlock), NMI_NULL);
+ ///////////////////////////
+
+}
+
+
+void resolve_disconnect_aberration(void* drvHandler)
+{ tstrNMI_WFIDrv * pstrWFIDrv;
+
+ pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ if (pstrWFIDrv == NMI_NULL)
+ return;
+ if((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP)||(pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTING))
+ {
+ printk("\n\n<< correcting Supplicant state machine >>\n\n");
+ host_int_disconnect((NMI_WFIDrvHandle)pstrWFIDrv, 1);
+ }
+}
+static NMI_Sint32 Switch_Log_Terminal(void * drvHandler)
+{
+
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ static char dummy=9;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_LOGTerminal_Switch;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = &dummy;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+
+ if(s32Error)
+ {
+ PRINT_D(HOSTINF_DBG,"Failed to switch log terminal\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ PRINT_INFO(HOSTINF_DBG,"MAC address set :: \n");
+
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_GetChnl
+* @details Sending config packet to get channel
+* @param[in] NONE
+* @return NONE
+
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_GetChnl(void* drvHandler)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ strWID.u16WIDid = (NMI_Uint16)WID_CURRENT_CHANNEL;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8 *)&gu8Chnl;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ PRINT_D(HOSTINF_DBG,"Getting channel value\n");
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ /*get the value by searching the local copy*/
+ if(s32Error)
+ {
+ PRINT_ER("Failed to get channel number\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemGetCHNL), NMI_NULL);
+
+ return s32Error;
+
+
+
+}
+
+
+/**
+* @brief Handle_GetRssi
+* @details Sending config packet to get RSSI
+* @param[in] NONE
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_GetRssi(void* drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv* pstrWFIDrv=(tstrNMI_WFIDrv*)drvHandler;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_RSSI;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = &gs8Rssi;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ /*Sending Cfg*/
+ PRINT_D(HOSTINF_DBG,"Getting RSSI value\n");
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to get RSSI value\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemGetRSSI), NMI_NULL);
+
+
+}
+
+
+static void Handle_GetLinkspeed(void* drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv* pstrWFIDrv=(tstrNMI_WFIDrv*)drvHandler;
+
+ gs8lnkspd = 0;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_LINKSPEED;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = &gs8lnkspd;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+ /*Sending Cfg*/
+ PRINT_D(HOSTINF_DBG,"Getting LINKSPEED value\n");
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to get LINKSPEED value\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemGetLINKSPEED), NMI_NULL);
+
+
+}
+
+NMI_Sint32 Handle_GetStatistics(void * drvHandler,tstrStatistics* pstrStatistics)
+{
+ tstrWID strWIDList[5];
+ uint32_t u32WidsCount = 0,s32Error = 0;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_LINKSPEED;
+ strWIDList[u32WidsCount].enuWIDtype= WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrStatistics->u8LinkSpeed));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_RSSI;
+ strWIDList[u32WidsCount].enuWIDtype= WID_CHAR;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Char);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrStatistics->s8RSSI));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrStatistics->u32TxCount));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrStatistics->u32RxCount));
+ u32WidsCount++;
+
+ strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT;
+ strWIDList[u32WidsCount].enuWIDtype= WID_INT;
+ strWIDList[u32WidsCount].s32ValueSize = sizeof(NMI_Uint32);
+ strWIDList[u32WidsCount].ps8WidVal = (NMI_Sint8*)(&(pstrStatistics->u32TxFailureCount));
+ u32WidsCount++;
+
+ s32Error = SendConfigPkt(GET_CFG, strWIDList, u32WidsCount, NMI_FALSE,(NMI_Uint32)drvHandler);
+
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send scan paramters config packet\n");
+ //NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_SemaphoreRelease(&hWaitResponse, NULL);
+ return 0;
+
+}
+
+
+#ifdef NMI_AP_EXTERNAL_MLME
+
+
+/**
+* @brief Handle_Get_InActiveTime
+* @details Sending config packet to set mac adddress for station and
+ get inactive time
+* @param[in] NONE
+* @return NONE
+
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Sint32 Handle_Get_InActiveTime(void* drvHandler,tstrHostIfStaInactiveT* strHostIfStaInactiveT)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 *stamac;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_SET_STA_MAC_INACTIVE_TIME;
+ strWID.enuWIDtype = WID_STR;
+ strWID.s32ValueSize = ETH_ALEN;
+ strWID.ps8WidVal = (NMI_Uint8 *)NMI_MALLOC(strWID.s32ValueSize);
+
+
+ stamac = strWID.ps8WidVal;
+ NMI_memcpy(stamac,strHostIfStaInactiveT->mac, ETH_ALEN);
+
+
+ PRINT_D(CFG80211_DBG,"SETING STA inactive time\n");
+
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ /*get the value by searching the local copy*/
+ if(s32Error)
+ {
+ PRINT_ER("Failed to SET incative time\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_GET_INACTIVE_TIME;
+ strWID.enuWIDtype = WID_INT;
+ strWID.ps8WidVal = (NMI_Sint8*)&gu32InactiveTime;
+ strWID.s32ValueSize = sizeof(NMI_Uint32);
+
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ /*get the value by searching the local copy*/
+ if(s32Error)
+ {
+ PRINT_ER("Failed to get incative time\n");
+ NMI_ERRORREPORT(s32Error,NMI_FAIL);
+ }
+
+
+ PRINT_D(CFG80211_DBG,"Getting inactive time : %d\n",gu32InactiveTime);
+
+ NMI_SemaphoreRelease(&(pstrWFIDrv->hSemInactiveTime), NMI_NULL);
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+
+ return s32Error;
+
+
+
+}
+
+
+/**
+* @brief Handle_AddBeacon
+* @details Sending config packet to add beacon
+* @param[in] tstrHostIFSetBeacon* pstrSetBeaconParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_AddBeacon(void* drvHandler,tstrHostIFSetBeacon* pstrSetBeaconParam)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ PRINT_D(HOSTINF_DBG,"Adding BEACON\n");
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ADD_BEACON;
+ strWID.enuWIDtype = WID_BIN;
+ strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen+pstrSetBeaconParam->u32TailLen+16;
+ strWID.ps8WidVal = NMI_MALLOC(strWID.s32ValueSize);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+ *pu8CurrByte++ = (pstrSetBeaconParam->u32Interval & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 8) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 16) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 24) & 0xFF);
+
+ *pu8CurrByte++ = (pstrSetBeaconParam->u32DTIMPeriod & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 8) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 16) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 24) & 0xFF);
+
+ *pu8CurrByte++ = (pstrSetBeaconParam->u32HeadLen & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 8) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 16) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 24) & 0xFF);
+
+ memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Head, pstrSetBeaconParam->u32HeadLen);
+ pu8CurrByte += pstrSetBeaconParam->u32HeadLen;
+
+ *pu8CurrByte++ = (pstrSetBeaconParam->u32TailLen& 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 8) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 16) & 0xFF);
+ *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 24) & 0xFF);
+
+ /* Bug 4599 : if tail length = 0 skip copying */
+ if(pstrSetBeaconParam->pu8Tail > 0)
+ memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Tail, pstrSetBeaconParam->u32TailLen);
+ pu8CurrByte += pstrSetBeaconParam->u32TailLen;
+
+
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send add beacon config packet\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_FREE_IF_TRUE(strWID.ps8WidVal);
+ NMI_FREE_IF_TRUE(pstrSetBeaconParam->pu8Head);
+ NMI_FREE_IF_TRUE(pstrSetBeaconParam->pu8Tail);
+}
+
+
+/**
+* @brief Handle_AddBeacon
+* @details Sending config packet to delete beacon
+* @param[in] tstrHostIFDelBeacon* pstrDelBeacon
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_DelBeacon(void* drvHandler,tstrHostIFDelBeacon* pstrDelBeacon)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ strWID.u16WIDid = (NMI_Uint16)WID_DEL_BEACON;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+ strWID.ps8WidVal = &gu8DelBcn;
+
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+
+ PRINT_D(HOSTINF_DBG,"Deleting BEACON\n");
+ /* TODO: build del beacon message*/
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+
+ PRINT_ER("Failed to send delete beacon config packet\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+}
+
+
+/**
+* @brief NMI_HostIf_PackStaParam
+* @details Handling packing of the station params in a buffer
+* @param[in] NMI_Uint8* pu8Buffer, tstrNMI_AddStaParam* pstrStationParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Uint32 NMI_HostIf_PackStaParam(NMI_Uint8* pu8Buffer, tstrNMI_AddStaParam* pstrStationParam)
+{
+ NMI_Uint8* pu8CurrByte;
+
+ pu8CurrByte = pu8Buffer;
+
+ PRINT_D(HOSTINF_DBG,"Packing STA params\n");
+ NMI_memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
+ pu8CurrByte += ETH_ALEN;
+
+ *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
+
+ *pu8CurrByte++ = pstrStationParam->u8NumRates;
+ if(pstrStationParam->u8NumRates > 0)
+ {
+ NMI_memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
+ }
+ pu8CurrByte += pstrStationParam->u8NumRates;
+
+ *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
+ *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
+
+ *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
+ NMI_memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, NMI_SUPP_MCS_SET_SIZE);
+ pu8CurrByte += NMI_SUPP_MCS_SET_SIZE;
+
+ *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
+
+ *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
+
+ *pu8CurrByte++ = pstrStationParam->u8ASELCap;
+
+ *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >>8) & 0xFF;
+
+ *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
+ *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >>8) & 0xFF;
+
+ return pu8CurrByte - pu8Buffer;
+}
+
+/**
+* @brief Handle_AddStation
+* @details Sending config packet to add station
+* @param[in] tstrNMI_AddStaParam* pstrStationParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_AddStation(void* drvHandler,tstrNMI_AddStaParam* pstrStationParam)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ PRINT_D(HOSTINF_DBG,"Handling add station\n");
+ strWID.u16WIDid = (NMI_Uint16)WID_ADD_STA;
+ strWID.enuWIDtype = WID_BIN;
+ strWID.s32ValueSize =NMI_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
+
+ strWID.ps8WidVal = NMI_MALLOC(strWID.s32ValueSize);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+ pu8CurrByte += NMI_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error != NMI_SUCCESS)
+ {
+
+ PRINT_ER("Failed to send add station config packet\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_FREE_IF_TRUE(pstrStationParam->pu8Rates);
+ NMI_FREE_IF_TRUE(strWID.ps8WidVal);
+}
+
+
+/**
+* @brief Handle_DelStation
+* @details Sending config packet to delete station
+* @param[in] tstrHostIFDelSta* pstrDelStaParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_DelStation(void * drvHandler,tstrHostIFDelSta* pstrDelStaParam)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_REMOVE_STA;
+ strWID.enuWIDtype = WID_BIN;
+ strWID.s32ValueSize =ETH_ALEN;
+
+ PRINT_D(HOSTINF_DBG,"Handling delete station \n");
+
+ strWID.ps8WidVal = NMI_MALLOC(strWID.s32ValueSize);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+
+ NMI_memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+
+ PRINT_ER("Failed to send add station config packe\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_FREE_IF_TRUE(strWID.ps8WidVal);
+}
+
+
+/**
+* @brief Handle_EditStation
+* @details Sending config packet to edit station
+* @param[in] tstrNMI_AddStaParam* pstrStationParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_EditStation(void* drvHandler,tstrNMI_AddStaParam* pstrStationParam)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_EDIT_STA;
+ strWID.enuWIDtype = WID_BIN;
+ strWID.s32ValueSize =NMI_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
+
+ PRINT_D(HOSTINF_DBG,"Handling edit station\n");
+ strWID.ps8WidVal = NMI_MALLOC(strWID.s32ValueSize);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+ pu8CurrByte += NMI_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+
+ PRINT_ER("Failed to send edit station config packet\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_FREE_IF_TRUE(pstrStationParam->pu8Rates);
+ NMI_FREE_IF_TRUE(strWID.ps8WidVal);
+}
+#endif /*NMI_AP_EXTERNAL_MLME*/
+
+#ifdef NMI_P2P
+/**
+* @brief Handle_RemainOnChan
+* @details Sending config packet to edit station
+* @param[in] tstrNMI_AddStaParam* pstrStationParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static int Handle_RemainOnChan(void* drvHandler,tstrHostIfRemainOnChan* pstrHostIfRemainOnChan)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ NMI_Uint8 u8remain_on_chan_flag;
+ tstrWID strWIDList[2];
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+
+
+ /*If it's a pendig remain-on-channel, don't overwrite gWFiDrvHandle values (since incoming msg is garbbage)*/
+ if(!pstrWFIDrv->u8RemainOnChan_pendingreq)
+ {
+ pstrWFIDrv->strHostIfRemainOnChan.pVoid=pstrHostIfRemainOnChan->pVoid;
+ pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
+ pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady= pstrHostIfRemainOnChan->pRemainOnChanReady;
+ pstrWFIDrv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel;
+ }
+ else
+ {
+ /*Set the channel to use it as a wid val*/
+ pstrHostIfRemainOnChan->u16Channel = pstrWFIDrv->strHostIfRemainOnChan.u16Channel;
+ }
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED )
+ {
+ pstrWFIDrv->u8RemainOnChan_pendingreq = 1;
+ return NMI_BUSY;
+ }
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult!=NULL)
+ {
+ PRINT_INFO(GENERIC_DBG,"Required to remain on chan while scanning return\n");
+ /*Calling the CFG80211 scan done function with the abort flag set to true*/
+ pstrWFIDrv->u8RemainOnChan_pendingreq = 1;
+ //return NMI_BUSY;
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+ }
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP)
+ {
+ PRINT_INFO(GENERIC_DBG,"Required to remain on chan while connecting return\n");
+ /*Calling the CFG80211 scan done function with the abort flag set to true*/
+ //return NMI_BUSY;
+
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+
+ }
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+ if(g_obtainingIP||connecting)
+ {
+ PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
+ NMI_ERRORREPORT(s32Error, NMI_BUSY);
+ }
+ #endif
+
+ PRINT_D(GENERIC_DBG,"Setting channel :%d\n",pstrHostIfRemainOnChan->u16Channel);
+
+ /*prepare configuration packet*/
+ strWIDList[0].u16WIDid = (NMI_Uint16)WID_CURRENT_CHANNEL;
+ strWIDList[0].enuWIDtype= WID_CHAR;
+ strWIDList[0].ps8WidVal = (NMI_Sint8*)&(pstrHostIfRemainOnChan->u16Channel);
+ strWIDList[0].s32ValueSize = sizeof(NMI_Char);
+
+ u8remain_on_chan_flag = NMI_TRUE;
+
+ strWIDList[1].u16WIDid = (NMI_Uint16)WID_REMAIN_ON_CHAN;
+ strWIDList[1].enuWIDtype = WID_CHAR;
+ strWIDList[1].ps8WidVal = (NMI_Sint8*)&u8remain_on_chan_flag;
+ strWIDList[1].s32ValueSize = sizeof(NMI_Char);
+ /*NMI_Uint8 reset=1;
+ PRINT_D(GENERIC_DBG,"WID RESET \n");
+ strWIDList[1].u16WIDid = (NMI_Uint16)WID_RESET;
+ strWIDList[1].ps8WidVal = (NMI_Sint8*)&reset;
+ strWIDList[1].enuWIDtype = WID_CHAR;
+ strWIDList[1].s32ValueSize = sizeof(NMI_Char);*/
+
+ /*Sending Cfg*/
+
+ s32Error = SendConfigPkt(SET_CFG, strWIDList, 2, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Failed to set remain on channel\n");
+ }
+
+NMI_CATCH(-1)
+ {
+ pstrWFIDrv->enuHostIFstate= HOST_IF_P2P_LISTEN;
+ NMI_TimerStart(&(pstrWFIDrv->hRemainOnChannel), pstrHostIfRemainOnChan->u32duration, (void*)pstrWFIDrv, NMI_NULL);
+
+ /*Calling CFG ready_on_channel*/
+ if(pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady)
+ {
+ pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady(pstrWFIDrv->strHostIfRemainOnChan.pVoid);
+ }
+
+ if(pstrWFIDrv->u8RemainOnChan_pendingreq)
+ pstrWFIDrv->u8RemainOnChan_pendingreq = 0;
+ }
+
+
+ return s32Error;
+}
+
+/**
+* @brief Handle_RegisterFrame
+* @details
+* @param[in]
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static int Handle_RegisterFrame(void* drvHandler,tstrHostIfRegisterFrame* pstrHostIfRegisterFrame)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ PRINT_D(HOSTINF_DBG,"Handling frame register Flag : %d FrameType: %d\n",pstrHostIfRegisterFrame->bReg,pstrHostIfRegisterFrame->u16FrameType);
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_REGISTER_FRAME;
+ strWID.enuWIDtype= WID_STR;
+ strWID.ps8WidVal = NMI_MALLOC(sizeof(NMI_Uint16)+2);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+
+ *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
+ *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
+ NMI_memcpy(pu8CurrByte,&(pstrHostIfRegisterFrame->u16FrameType),sizeof(NMI_Uint16));
+
+
+ strWID.s32ValueSize = sizeof(NMI_Uint16)+2;
+
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to frame register config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+
+
+ NMI_CATCH(s32Error)
+ {
+ }
+
+ return s32Error;
+
+}
+
+/**
+* @brief Handle_ListenStateExpired
+* @details Handle of listen state expiration
+* @param[in] NONE
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static NMI_Uint32 Handle_ListenStateExpired(void *drvHandler,tstrHostIfRemainOnChan* pstrHostIfRemainOnChan)
+{
+ NMI_Uint8 u8remain_on_chan_flag;
+ tstrWID strWID;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *) drvHandler;
+
+ PRINT_D(HOSTINF_DBG,"CANCEL REMAIN ON CHAN\n");
+
+ u8remain_on_chan_flag = NMI_FALSE;
+ strWID.u16WIDid = (NMI_Uint16)WID_REMAIN_ON_CHAN;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&u8remain_on_chan_flag;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Failed to set remain on channel\n");
+ return s32Error;
+ }
+ if(pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired)
+ {
+ pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired(pstrWFIDrv->strHostIfRemainOnChan.pVoid);
+ }
+ pstrWFIDrv->enuHostIFstate= HOST_IF_IDLE;
+ return s32Error;
+}
+
+
+/**
+* @brief ListenTimerCB
+* @details Callback function of remain-on-channel timer
+* @param[in] NONE
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+static void ListenTimerCB(void* pvArg)
+{
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)pvArg;
+ /*Stopping remain-on-channel timer*/
+ NMI_TimerStop(&(pstrWFIDrv->hRemainOnChannel), NMI_NULL);
+
+ /* prepare the Timer Callback message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED;
+ strHostIFmsg.drvHandler=pstrWFIDrv;
+
+ /* send the message */
+ NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+}
+#endif
+
+
+/**
+* @brief Handle_EditStation
+* @details Sending config packet to edit station
+* @param[in] tstrNMI_AddStaParam* pstrStationParam
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void Handle_PowerManagement(void* drvHandler,tstrHostIfPowerMgmtParam* strPowerMgmtParam)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Sint8 s8PowerMode;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ strWID.u16WIDid = (NMI_Uint16)WID_POWER_MANAGEMENT;
+
+ if(strPowerMgmtParam->bIsEnabled == NMI_TRUE)
+ {
+ s8PowerMode = MIN_FAST_PS;
+ }
+ else
+ {
+ s8PowerMode = NO_POWERSAVE;
+ }
+ PRINT_D(HOSTINF_DBG,"Handling power mgmt to %d\n", s8PowerMode);
+ strWID.ps8WidVal = &s8PowerMode;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ PRINT_D(HOSTINF_DBG,"Handling Power Management\n");
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send power management config packet\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+}
+
+/**
+* @brief Handle_SetMulticastFilter
+* @details Set Multicast filter in firmware
+* @param[in] tstrHostIFSetMulti* strHostIfSetMulti
+* @return NONE
+* @author asobhy
+* @date
+* @version 1.0
+*/
+static void Handle_SetMulticastFilter(void * drvHandler,tstrHostIFSetMulti* strHostIfSetMulti)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ NMI_Uint8* pu8CurrByte;
+
+ PRINT_D(HOSTINF_DBG,"Setup Multicast Filter\n");
+
+ strWID.u16WIDid = (NMI_Uint16)WID_SETUP_MULTICAST_FILTER;
+ strWID.enuWIDtype = WID_BIN;
+ strWID.s32ValueSize = sizeof(tstrHostIFSetMulti) + ((strHostIfSetMulti->u32count) * ETH_ALEN) ;
+ strWID.ps8WidVal = NMI_MALLOC(strWID.s32ValueSize);
+ if(strWID.ps8WidVal == NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_NO_MEM);
+ }
+
+ pu8CurrByte = strWID.ps8WidVal;
+ *pu8CurrByte++ = (strHostIfSetMulti->bIsEnabled & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 8) & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 16) & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 24) & 0xFF);
+
+ *pu8CurrByte++ = (strHostIfSetMulti->u32count & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 8) & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 16) & 0xFF);
+ *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 24) & 0xFF);
+
+ if((strHostIfSetMulti->u32count) > 0)
+ memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN));
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE,(NMI_Uint32)drvHandler);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send setup multicast config packet\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ NMI_FREE_IF_TRUE(strWID.ps8WidVal);
+
+}
+
+
+/*BugID_5222*/
+/**
+* @brief Handle_AddBASession
+* @details Add block ack session
+* @param[in] tstrHostIFSetMulti* strHostIfSetMulti
+* @return NONE
+* @author Amr Abdel-Moghny
+* @date Feb. 2014
+* @version 9.0
+*/
+static NMI_Sint32 Handle_AddBASession(void * drvHandler, tstrHostIfBASessionInfo* strHostIfBASessionInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ int AddbaTimeout = 100;
+ char* ptr = NULL;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d \nBufferSize == %d \nSessionTimeOut = %d\n",
+ strHostIfBASessionInfo->au8Bssid[0],
+ strHostIfBASessionInfo->au8Bssid[1],
+ strHostIfBASessionInfo->au8Bssid[2],
+ strHostIfBASessionInfo->u16BufferSize,
+ strHostIfBASessionInfo->u16SessionTimeout,
+ strHostIfBASessionInfo->u8Ted);
+
+ strWID.u16WIDid = (NMI_Uint16)WID_11E_P_ACTION_REQ;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Uint8*)NMI_MALLOC(BLOCK_ACK_REQ_SIZE);
+ strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
+ ptr = strWID.ps8WidVal;
+ //*ptr++ = 0x14;
+ *ptr++ = 0x14;
+ *ptr++ = 0x3;
+ *ptr++ = 0x0;
+ NMI_memcpy(ptr,strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
+ ptr += ETH_ALEN;
+ *ptr++ = strHostIfBASessionInfo->u8Ted;
+ /* BA Policy*/
+ *ptr++ = 1;
+ /* Buffer size*/
+ *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
+ *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >>16) & 0xFF);
+ /* BA timeout*/
+ *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
+ *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >>16) & 0xFF);
+ /* ADDBA timeout*/
+ *ptr++ = (AddbaTimeout& 0xFF);
+ *ptr++ = ((AddbaTimeout>>16) & 0xFF);
+ /* Group Buffer Max Frames*/
+ *ptr++ = 8;
+ /* Group Buffer Timeout */
+ *ptr++ = 0;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_11E_P_ACTION_REQ;
+ strWID.enuWIDtype = WID_STR;
+ strWID.s32ValueSize = 15;
+ ptr = strWID.ps8WidVal;
+ //*ptr++ = 0x14;
+ *ptr++ = 15;
+ *ptr++ = 7;
+ *ptr++ = 0x2;
+ NMI_memcpy(ptr,strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
+ ptr += ETH_ALEN;
+ /* TID*/
+ *ptr++ = strHostIfBASessionInfo->u8Ted;
+ /* Max Num MSDU */
+ *ptr++ = 8;
+ /* BA timeout*/
+ *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
+ *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout>>16) & 0xFF);
+ /*Ack-Policy */
+ *ptr++ = 3;
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ if(strWID.ps8WidVal != NULL)
+ NMI_FREE(strWID.ps8WidVal);
+
+ return s32Error;
+
+}
+
+
+/*BugID_5222*/
+/**
+* @brief Handle_DelBASession
+* @details Delete block ack session
+* @param[in] tstrHostIFSetMulti* strHostIfSetMulti
+* @return NONE
+* @author Amr Abdel-Moghny
+* @date Feb. 2013
+* @version 9.0
+*/
+static NMI_Sint32 Handle_DelBASession(void * drvHandler, tstrHostIfBASessionInfo* strHostIfBASessionInfo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ char* ptr = NULL;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+ PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x \nTID=%d\n",
+ strHostIfBASessionInfo->au8Bssid[0],
+ strHostIfBASessionInfo->au8Bssid[1],
+ strHostIfBASessionInfo->au8Bssid[2],
+ strHostIfBASessionInfo->u8Ted);
+
+ strWID.u16WIDid = (NMI_Uint16)WID_11E_P_ACTION_REQ;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Uint8*)NMI_MALLOC(BLOCK_ACK_REQ_SIZE);
+ strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
+ ptr = strWID.ps8WidVal;
+ //*ptr++ = 0x14;
+ *ptr++ = 0x14;
+ *ptr++ = 0x3;
+ *ptr++ = 0x2;
+ NMI_memcpy(ptr,strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
+ ptr += ETH_ALEN;
+ *ptr++ = strHostIfBASessionInfo->u8Ted;
+ /* BA direction = recipent*/
+ *ptr++ = 0;
+ /* Delba Reason */
+ *ptr++ = 32; // Unspecific QOS reason
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
+
+
+ strWID.u16WIDid = (NMI_Uint16)WID_11E_P_ACTION_REQ;
+ strWID.enuWIDtype = WID_STR;
+ strWID.s32ValueSize = 15;
+ ptr = strWID.ps8WidVal;
+ //*ptr++ = 0x14;
+ *ptr++ = 15;
+ *ptr++ = 7;
+ *ptr++ = 0x3;
+ NMI_memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
+ ptr += ETH_ALEN;
+ /* TID*/
+ *ptr++ = strHostIfBASessionInfo->u8Ted;
+
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ if(strWID.ps8WidVal != NULL)
+ NMI_FREE(strWID.ps8WidVal);
+
+ /*BugID_5222*/
+ NMI_SemaphoreRelease(&hWaitResponse, NULL);
+
+ return s32Error;
+
+}
+
+
+/**
+* @brief hostIFthread
+* @details Main thread to handle message queue requests
+* @param[in] void* pvArg
+* @return NONE
+* @author
+* @date
+* @version 1.0
+*/
+static void hostIFthread(void* pvArg)
+{
+ NMI_Uint32 u32Ret;
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_WFIDrv * pstrWFIDrv ;
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ while(1)
+ {
+ NMI_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret, NMI_NULL);
+ pstrWFIDrv = (tstrNMI_WFIDrv *)strHostIFmsg.drvHandler;
+ if(strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT)
+ {
+ PRINT_D(GENERIC_DBG,"THREAD: Exiting HostIfThread\n");
+ break;
+ }
+
+
+ /*Re-Queue HIF message*/
+ if((!g_nmc_initialized))
+ {
+ PRINT_D(GENERIC_DBG, "--WAIT--");
+ NMI_Sleep(200);
+ NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ continue;
+ }
+
+ if(strHostIFmsg.u16MsgId == HOST_IF_MSG_CONNECT && pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult != NULL){
+ PRINT_D(HOSTINF_DBG,"Requeue connect request till scan done received\n");
+ NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ NMI_Sleep(2);
+ continue;
+ }
+
+ switch(strHostIFmsg.u16MsgId)
+ {
+ case HOST_IF_MSG_Q_IDLE:
+ {
+ Handle_wait_msg_q_empty();
+ break;
+ }
+ case HOST_IF_MSG_SCAN:
+ {
+ Handle_Scan(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr);
+ break;
+ }
+ case HOST_IF_MSG_CONNECT:
+ {
+ Handle_Connect(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr);
+ break;
+ }
+
+ /*BugID_5137*/
+ case HOST_IF_MSG_FLUSH_CONNECT:
+ {
+ Handle_FlushConnect(strHostIFmsg.drvHandler);
+ break;
+ }
+
+ case HOST_IF_MSG_RCVD_NTWRK_INFO:
+ {
+ Handle_RcvdNtwrkInfo(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo);
+ break;
+ }
+ case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
+ {
+ Handle_RcvdGnrlAsyncInfo(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo);
+ break;
+ }
+ case HOST_IF_MSG_KEY:
+ {
+ Handle_Key(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr);
+ break;
+ }
+ case HOST_IF_MSG_CFG_PARAMS:
+ {
+
+ Handle_CfgParam(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr);
+ break;
+ }
+ case HOST_IF_MSG_SET_CHANNEL:
+ {
+ Handle_SetChannel(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan);
+ break;
+ }
+ case HOST_IF_MSG_DISCONNECT:
+ {
+ Handle_Disconnect(strHostIFmsg.drvHandler);
+ break;
+ }
+ case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
+ {
+ NMI_TimerStop(&(pstrWFIDrv->hScanTimer), NMI_NULL);
+ PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
+
+ /*BugID_5213*/
+ /*Allow chip sleep, only if both interfaces are not connected*/
+ if(!linux_wlan_get_num_conn_ifcs())
+ {
+ chip_sleep_manually(INFINITE_SLEEP_TIME);
+ }
+
+ Handle_ScanDone(strHostIFmsg.drvHandler,SCAN_EVENT_DONE);
+
+ #ifdef NMI_P2P
+ if(pstrWFIDrv->u8RemainOnChan_pendingreq)
+ Handle_RemainOnChan(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan);
+ #endif
+
+ break;
+ }
+ case HOST_IF_MSG_GET_RSSI:
+ {
+ Handle_GetRssi(strHostIFmsg.drvHandler);
+ break;
+ }
+ case HOST_IF_MSG_GET_LINKSPEED:
+ {
+ Handle_GetLinkspeed(strHostIFmsg.drvHandler);
+ break;
+ }
+ case HOST_IF_MSG_GET_STATISTICS:
+ {
+ Handle_GetStatistics(strHostIFmsg.drvHandler,(tstrStatistics*)strHostIFmsg.uniHostIFmsgBody.pUserData);
+ break;
+ }
+ case HOST_IF_MSG_GET_CHNL:
+ {
+ Handle_GetChnl(strHostIFmsg.drvHandler);
+ break;
+ }
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ case HOST_IF_MSG_ADD_BEACON:
+ {
+ Handle_AddBeacon(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon);
+ break;
+ }
+ break;
+
+ case HOST_IF_MSG_DEL_BEACON:
+ {
+ Handle_DelBeacon(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIFDelBeacon);
+ break;
+ }
+ break;
+
+ case HOST_IF_MSG_ADD_STATION:
+ {
+ Handle_AddStation(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strAddStaParam);
+ break;
+ }
+
+ case HOST_IF_MSG_DEL_STATION:
+ {
+ Handle_DelStation(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strDelStaParam);
+ break;
+ }
+ case HOST_IF_MSG_EDIT_STATION:
+ {
+ Handle_EditStation(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strEditStaParam);
+ break;
+ }
+ case HOST_IF_MSG_GET_INACTIVETIME:
+ {
+ Handle_Get_InActiveTime(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT);
+ break;
+ }
+ #endif /*NMI_AP_EXTERNAL_MLME*/
+ case HOST_IF_MSG_SCAN_TIMER_FIRED:
+ {
+ NMI_PRINTF("Scan Timeout\n");
+
+ Handle_ScanDone(strHostIFmsg.drvHandler,SCAN_EVENT_ABORTED);
+
+
+
+ break;
+ }
+ case HOST_IF_MSG_CONNECT_TIMER_FIRED:
+ {
+ NMI_PRINTF("Connect Timeout \n");
+ Handle_ConnectTimeout(strHostIFmsg.drvHandler);
+ break;
+ }
+ case HOST_IF_MSG_POWER_MGMT:
+ {
+ Handle_PowerManagement(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam);
+ break;
+ }
+
+ case HOST_IF_MSG_SET_WFIDRV_HANDLER:
+ {
+
+ Handle_SetWfiDrvHandler(&strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler);
+
+
+ break;
+ }
+ case HOST_IF_MSG_SET_OPERATION_MODE:
+ {
+
+ Handle_SetOperationMode(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode);
+
+
+ break;
+ }
+
+ case HOST_IF_MSG_SET_IPADDRESS:
+ {
+ PRINT_D(HOSTINF_DBG,"HOST_IF_MSG_SET_IPADDRESS\n");
+ Handle_set_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx);
+ break;
+ }
+ case HOST_IF_MSG_GET_IPADDRESS:
+ {
+ PRINT_D(HOSTINF_DBG,"HOST_IF_MSG_SET_IPADDRESS\n");
+ Handle_get_IPAddress(strHostIFmsg.drvHandler, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr, strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx);
+ break;
+ }
+
+ /*BugID_5077*/
+ case HOST_IF_MSG_SET_MAC_ADDRESS:
+ {
+ Handle_SetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress);
+ break;
+ }
+
+ /*BugID_5213*/
+ case HOST_IF_MSG_GET_MAC_ADDRESS:
+ {
+ Handle_GetMacAddress(strHostIFmsg.drvHandler, &strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress);
+ break;
+ }
+
+ #ifdef NMI_P2P
+ case HOST_IF_MSG_REMAIN_ON_CHAN:
+ {
+ PRINT_D(HOSTINF_DBG,"HOST_IF_MSG_REMAIN_ON_CHAN\n");
+ Handle_RemainOnChan(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan);
+ break;
+ }
+ case HOST_IF_MSG_REGISTER_FRAME:
+ {
+ PRINT_D(HOSTINF_DBG,"HOST_IF_MSG_REGISTER_FRAME\n");
+ Handle_RegisterFrame(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame);
+ break;
+ }
+ case HOST_IF_MSG_LISTEN_TIMER_FIRED:
+ {
+ Handle_ListenStateExpired(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan);
+ break;
+ }
+ #endif
+ case HOST_IF_MSG_SET_MULTICAST_FILTER:
+ {
+ PRINT_D(HOSTINF_DBG,"HOST_IF_MSG_SET_MULTICAST_FILTER\n");
+ Handle_SetMulticastFilter(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti);
+ break;
+ }
+
+ /*BugID_5222*/
+ case HOST_IF_MSG_ADD_BA_SESSION:
+ {
+ Handle_AddBASession(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo);
+ break;
+ }
+ case HOST_IF_MSG_DEL_BA_SESSION:
+ {
+ Handle_DelBASession(strHostIFmsg.drvHandler,&strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo);
+ break;
+ }
+
+ default:
+ {
+ NMI_ERROR("[Host Interface] undefined Received Msg ID \n");
+ break;
+ }
+ }
+ }
+
+ PRINT_D(HOSTINF_DBG,"Releasing thread exit semaphore\n");
+ NMI_SemaphoreRelease(&hSemHostIFthrdEnd, NMI_NULL);
+ return;
+ //do_exit(error);
+ //PRINT_D(HOSTINF_DBG,"do_exit error code %d\n",error);
+
+}
+
+static void TimerCB_Scan(void* pvArg)
+{
+ tstrHostIFmsg strHostIFmsg;
+
+ /* prepare the Timer Callback message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.drvHandler=pvArg;
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED;
+
+ // send the message
+ NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+}
+
+static void TimerCB_Connect(void* pvArg)
+{
+ tstrHostIFmsg strHostIFmsg;
+
+ //prepare the Timer Callback message
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.drvHandler=pvArg;
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED;
+
+ /* send the message */
+ NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+}
+
+
+/**
+* @brief removes wpa/wpa2 keys
+* @details only in BSS STA mode if External Supplicant support is enabled.
+ removes all WPA/WPA2 station key entries from MAC hardware.
+* @param[in,out] handle to the wifi driver
+* @param[in] 6 bytes of Station Adress in the station entry table
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+//Check implementation in core adding 9 bytes to the input!
+NMI_Sint32 host_int_remove_key(NMI_WFIDrvHandle hWFIDrv,const NMI_Uint8* pu8StaAddress)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_REMOVE_KEY;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = (NMI_Sint8*)pu8StaAddress;
+ strWID.s32ValueSize = 6;
+
+ return s32Error;
+
+}
+
+/**
+* @brief removes WEP key
+* @details valid only in BSS STA mode if External Supplicant support is enabled.
+ remove a WEP key entry from MAC HW.
+ The BSS Station automatically finds the index of the entry using its
+ BSS ID and removes that entry from the MAC hardware.
+* @param[in,out] handle to the wifi driver
+* @param[in] 6 bytes of Station Adress in the station entry table
+* @return Error code indicating success/failure
+* @note NO need for the STA add since it is not used for processing
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_remove_wep_key(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8keyIdx)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the Remove Wep Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = REMOVEKEY;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Error in sending message queue : Request to remove WEP key \n");
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+
+/**
+* @brief sets WEP default key
+* @details Sets the index of the WEP encryption key in use,
+ in the key table
+* @param[in,out] handle to the wifi driver
+* @param[in] key index ( 0, 1, 2, 3)
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_WEPDefaultKeyID(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8Index)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = DEFAULTKEY;
+ strHostIFmsg.drvHandler= hWFIDrv;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Error in sending message queue : Default key index\n");
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief sets WEP deafault key
+* @details valid only in BSS STA mode if External Supplicant support is enabled.
+ sets WEP key entry into MAC hardware when it receives the
+ corresponding request from NDIS.
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing WEP Key in the following format
+ |---------------------------------------|
+ |Key ID Value | Key Length | Key |
+ |-------------|------------|------------|
+ | 1byte | 1byte | Key Length |
+ |---------------------------------------|
+
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_wep_key_bss_sta(NMI_WFIDrvHandle hWFIDrv, const NMI_Uint8* pu8WepKey, NMI_Uint8 u8WepKeylen, NMI_Uint8 u8Keyidx)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (NMI_Uint8*)NMI_MALLOC(u8WepKeylen);
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
+ pu8WepKey, u8WepKeylen);
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen);
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Error in sending message queue :WEP Key\n");
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+
+}
+
+#ifdef NMI_AP_EXTERNAL_MLME
+/**
+
+* @brief host_int_add_wep_key_bss_ap
+* @details valid only in BSS AP mode if External Supplicant support is enabled.
+ sets WEP key entry into MAC hardware when it receives the
+
+ corresponding request from NDIS.
+* @param[in,out] handle to the wifi driver
+
+
+* @return Error code indicating success/failure
+* @note
+* @author mdaftedar
+* @date 28 FEB 2013
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_wep_key_bss_ap(NMI_WFIDrvHandle hWFIDrv, const NMI_Uint8* pu8WepKey, NMI_Uint8 u8WepKeylen, NMI_Uint8 u8Keyidx,NMI_Uint8 u8mode, AUTHTYPE_T tenuAuth_type)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint8 i;
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ if(INFO)
+ {
+ for(i=0;i<u8WepKeylen;i++)
+ PRINT_INFO(HOSTAPD_DBG,"KEY is %x\n",pu8WepKey[i]);
+ }
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WEP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = (NMI_Uint8*)NMI_MALLOC((u8WepKeylen));
+
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
+ pu8WepKey, (u8WepKeylen));
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen);
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.u8mode = u8mode;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type;
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+
+ if(s32Error)
+ PRINT_ER("Error in sending message queue :WEP Key\n");
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+
+}
+#endif
+/**
+* @brief adds ptk Key
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing PTK Key in the following format
+|-----------------------------------------------------------------------------|
+|Station address | Key Length | Temporal Key | Rx Michael Key |Tx Michael Key |
+|----------------|------------|--------------|----------------|---------------|
+| 6 bytes | 1byte | 16 bytes | 8 bytes | 8 bytes |
+|-----------------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_ptk(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8Ptk,NMI_Uint8 u8PtkKeylen,
+ const NMI_Uint8* mac_addr,NMI_Uint8* pu8RxMic,NMI_Uint8* pu8TxMic,NMI_Uint8 mode,NMI_Uint8 u8Ciphermode,NMI_Uint8 u8Idx)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint8 u8KeyLen = u8PtkKeylen;
+ NMI_Uint32 i;
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ if(pu8RxMic != NULL)
+ {
+ u8KeyLen += RX_MIC_KEY_LEN;
+ }
+ if(pu8TxMic != NULL)
+ {
+ u8KeyLen += TX_MIC_KEY_LEN;
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPAPtk;
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(mode == AP_MODE)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8Idx;
+ }
+ #endif
+ if(mode == STATION_MODE)
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (NMI_Uint8*)NMI_MALLOC(u8PtkKeylen);
+
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pu8Ptk, u8PtkKeylen);
+
+ if(pu8RxMic != NULL)
+ {
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key+16,
+ pu8RxMic,RX_MIC_KEY_LEN);
+ if(INFO)
+ {
+ for(i=0;i<RX_MIC_KEY_LEN;i++)
+ PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
+ }
+ }
+ if(pu8TxMic != NULL)
+ {
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key+24,
+ pu8TxMic, TX_MIC_KEY_LEN);
+ if(INFO)
+ {
+ for(i=0;i<TX_MIC_KEY_LEN;i++)
+ PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
+ }
+ }
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr = mac_addr;
+ strHostIFmsg.drvHandler= hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+
+ if(s32Error)
+ PRINT_ER("Error in sending message queue: PTK Key\n");
+
+ ////////////////
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+ //NMI_Sleep(100);
+ /////////
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief adds Rx GTk Key
+* @details
+* @param[in,out] handle to the wifi driver
+* @param[in] pu8RxGtk : contains temporal key | Rx Mic | Tx Mic
+ u8GtkKeylen :The total key length
+
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_rx_gtk(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8RxGtk,NMI_Uint8 u8GtkKeylen,
+ NMI_Uint8 u8KeyIdx,NMI_Uint32 u32KeyRSClen, NMI_Uint8* KeyRSC,
+ NMI_Uint8* pu8RxMic,NMI_Uint8* pu8TxMic,NMI_Uint8 mode,NMI_Uint8 u8Ciphermode)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint8 u8KeyLen = u8GtkKeylen;
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ if(pu8RxMic != NULL)
+ {
+ u8KeyLen += RX_MIC_KEY_LEN;
+ }
+ if(pu8TxMic != NULL)
+ {
+ u8KeyLen += TX_MIC_KEY_LEN;
+ }
+ if(KeyRSC!= NULL)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = (NMI_Uint8*)NMI_MALLOC(u32KeyRSClen);
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq,
+ KeyRSC, u32KeyRSClen);
+ }
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPARxGtk;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+ #ifdef NMI_AP_EXTERNAL_MLME
+ if(mode == AP_MODE)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY_AP;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode;
+ }
+ #endif
+ if(mode == STATION_MODE)
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (NMI_Uint8*)NMI_MALLOC(u8KeyLen);
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pu8RxGtk, u8GtkKeylen);
+
+ if(pu8RxMic != NULL)
+ {
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key+16,
+ pu8RxMic,RX_MIC_KEY_LEN);
+
+ }
+ if(pu8TxMic != NULL)
+ {
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key+24,
+ pu8TxMic, TX_MIC_KEY_LEN);
+
+ }
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8KeyIdx;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.u8seqlen = u32KeyRSClen;
+
+
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ NMI_ERROR("Error in sending message queue: RX GTK\n");
+ ////////////////
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestKeyBlock),NULL);
+ //NMI_Sleep(100);
+ /////////
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+#if 0
+/**
+* @brief host_int_add_tx_gtk
+* @details adds Tx GTk Key
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing Tx GTK Key in the following format
+ |----------------------------------------------------|
+ | KeyID | Key Length | Temporal Key | Tx Michael Key |
+ |-------|------------|--------------|----------------|
+ |1 byte | 1 byte | 16 bytes | 8 bytes |
+ |----------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_tx_gtk(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8KeyLen,NMI_Uint8* pu8TxGtk,NMI_Uint8 u8KeyIdx)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = WPATxGtk;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.
+ uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = (NMI_Uint8*)NMI_MALLOC(u8KeyLen);
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
+ pu8TxGtk, u8KeyLen);
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ NMI_ERROR("Error in sending message queue: TX GTK\n");
+
+ ////////////////
+ NMI_SemaphoreAcquire(&hSemTestKeyBlock,NULL);
+ NMI_Sleep(100);
+ /////////
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+#endif
+/**
+* @brief host_int_set_pmkid_info
+* @details caches the pmkid valid only in BSS STA mode if External Supplicant
+ support is enabled. This Function sets the PMKID in firmware
+ when host drivr receives the corresponding request from NDIS.
+ The firmware then includes theset PMKID in the appropriate
+ management frames
+* @param[in,out] handle to the wifi driver
+* @param[in] message containing PMKID Info in the following format
+|-----------------------------------------------------------------|
+|NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] |
+|-----------|------------|----------|-------|----------|----------|
+| 1 | 6 | 16 | ... | 6 | 16 |
+|-----------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_pmkid_info(NMI_WFIDrvHandle hWFIDrv, tstrHostIFpmkidAttr* pu8PmkidInfoArray)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint32 i;
+
+
+ if(pstrWFIDrv == NMI_NULL )
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the Key Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_KEY;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.enuKeyType = PMKSA;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.u8KeyAction = ADDKEY;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ for(i = 0 ; i< pu8PmkidInfoArray->numpmkid;i++)
+ {
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, &pu8PmkidInfoArray->pmkidlist[i].bssid,
+ ETH_ALEN);
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, &pu8PmkidInfoArray->pmkidlist[i].pmkid,
+ PMKID_LEN);
+ }
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief gets the cached the pmkid info
+* @details valid only in BSS STA mode if External Supplicant
+ support is enabled. This Function sets the PMKID in firmware
+ when host drivr receives the corresponding request from NDIS.
+ The firmware then includes theset PMKID in the appropriate
+ management frames
+* @param[in,out] handle to the wifi driver,
+ message containing PMKID Info in the following format
+ |-----------------------------------------------------------------|
+ |NumEntries | BSSID[1] | PMKID[1] | ... | BSSID[K] | PMKID[K] |
+ |-----------|------------|----------|-------|----------|----------|
+ | 1 | 6 | 16 | ... | 6 | 16 |
+ |-----------------------------------------------------------------|
+* @param[in]
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_pmkid_info(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8PmkidInfoArray,
+ NMI_Uint32 u32PmkidInfoLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_PMKID_INFO;
+ strWID.enuWIDtype = WID_STR;
+ strWID.s32ValueSize = u32PmkidInfoLen;
+ strWID.ps8WidVal = pu8PmkidInfoArray;
+
+ return s32Error;
+}
+
+/**
+* @brief sets the pass phrase
+* @details AP/STA mode. This function gives the pass phrase used to
+ generate the Pre-Shared Key when WPA/WPA2 is enabled
+ The length of the field can vary from 8 to 64 bytes,
+ the lower layer should get the
+* @param[in,out] handle to the wifi driver,
+* @param[in] String containing PSK
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_RSNAConfigPSKPassPhrase(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8PassPhrase,
+ NMI_Uint8 u8Psklength)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ //NMI_Uint8 u8Psklength = NMI_strlen(pu8PassPhrase);
+ /*validating psk length*/
+ if((u8Psklength >7) && (u8Psklength<65))
+ {
+ strWID.u16WIDid = (NMI_Uint16)WID_11I_PSK;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = pu8PassPhrase;
+ strWID.s32ValueSize = u8Psklength;
+ }
+
+ return s32Error;
+}
+/**
+* @brief host_int_get_MacAddress
+* @details gets mac address
+* @param[in,out] handle to the wifi driver,
+
+* @return Error code indicating success/failure
+* @note
+* @author mdaftedar
+* @date 19 April 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_MacAddress(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8MacAddress)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /* prepare the Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_MAC_ADDRESS;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfGetMacAddress.u8MacAddress = pu8MacAddress;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error){
+ PRINT_ER("Failed to send get mac address\n");
+ return NMI_FAIL;
+ }
+
+ NMI_SemaphoreAcquire(&hWaitResponse, NULL);
+ return s32Error;
+}
+
+/**
+* @brief host_int_set_MacAddress
+* @details sets mac address
+* @param[in,out] handle to the wifi driver,
+
+* @return Error code indicating success/failure
+* @note
+* @author mabubakr
+* @date 16 July 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_MacAddress(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8MacAddress)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+ PRINT_D(GENERIC_DBG,"mac addr = %x:%x:%x\n",pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
+
+ /* prepare setting mac address message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MAC_ADDRESS;
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfSetMacAddress.u8MacAddress, pu8MacAddress, ETH_ALEN);
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send message queue: Set mac address\n");
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+
+}
+
+/**
+* @brief host_int_get_RSNAConfigPSKPassPhrase
+* @details gets the pass phrase:AP/STA mode. This function gets the pass phrase used to
+ generate the Pre-Shared Key when WPA/WPA2 is enabled
+ The length of the field can vary from 8 to 64 bytes,
+ the lower layer should get the
+* @param[in,out] handle to the wifi driver,
+ String containing PSK
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_RSNAConfigPSKPassPhrase(NMI_WFIDrvHandle hWFIDrv,
+ NMI_Uint8* pu8PassPhrase, NMI_Uint8 u8Psklength)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_11I_PSK;
+ strWID.enuWIDtype = WID_STR;
+ strWID.s32ValueSize = u8Psklength;
+ strWID.ps8WidVal = pu8PassPhrase;
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_get_site_survey_results
+* @details gets the site survey results
+* @param[in,out] handle to the wifi driver,
+ Message containing site survey results in the
+ following format
+|---------------------------------------------------|
+| MsgLength | fragNo. | MsgBodyLength | MsgBody |
+|-----------|-----------|---------------|-----------|
+| 1 | 1 | 1 | 1 |
+----------------------------------------- | ----------------
+ |
+ |---------------------------------------|
+ | Network1 | Netweork2 | ... | Network5 |
+ |---------------------------------------|
+ | 44 | 44 | ... | 44 |
+-------------------------- | ---------------------------------------
+ |
+|---------------------------------------------------------------------|
+| SSID | BSS Type | Channel | Security Status| BSSID | RSSI |Reserved |
+
+
+|------|----------|---------|----------------|-------|------|---------|
+| 33 | 1 | 1 | 1 | 6 | 1 | 1 |
+|---------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+#ifndef CONNECT_DIRECT
+NMI_Sint32 host_int_get_site_survey_results(NMI_WFIDrvHandle hWFIDrv,
+ NMI_Uint8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
+ NMI_Uint32 u32MaxSiteSrvyFragLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID astrWIDList[2];
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ astrWIDList[0].u16WIDid = (NMI_Uint16)WID_SITE_SURVEY_RESULTS;
+ astrWIDList[0].enuWIDtype = WID_STR;
+ astrWIDList[0].ps8WidVal = ppu8RcvdSiteSurveyResults[0];
+ astrWIDList[0].s32ValueSize = u32MaxSiteSrvyFragLen;
+
+ astrWIDList[1].u16WIDid = (NMI_Uint16)WID_SITE_SURVEY_RESULTS;
+ astrWIDList[1].enuWIDtype = WID_STR;
+ astrWIDList[1].ps8WidVal = ppu8RcvdSiteSurveyResults[1];
+ astrWIDList[1].s32ValueSize = u32MaxSiteSrvyFragLen;
+
+ s32Error = SendConfigPkt(GET_CFG, astrWIDList, 2, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+
+ /*get the value by searching the local copy*/
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send config packet to get survey results\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+#endif
+
+/**
+* @brief sets a start scan request
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Scan Source one of the following values
+ DEFAULT_SCAN 0
+ USER_SCAN BIT0
+ OBSS_PERIODIC_SCAN BIT1
+ OBSS_ONETIME_SCAN BIT2
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_start_scan_req(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 scanSource)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_START_SCAN_REQ;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&scanSource;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_get_start_scan_req
+* @details gets a start scan request
+* @param[in,out] handle to the wifi driver,
+* @param[in] Scan Source one of the following values
+ DEFAULT_SCAN 0
+ USER_SCAN BIT0
+ OBSS_PERIODIC_SCAN BIT1
+ OBSS_ONETIME_SCAN BIT2
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_get_start_scan_req(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8* pu8ScanSource)
+ {
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_START_SCAN_REQ;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)pu8ScanSource;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ return s32Error;
+ }
+
+/**
+* @brief host_int_set_join_req
+* @details sets a join request
+* @param[in,out] handle to the wifi driver,
+* @param[in] Index of the bss descriptor
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_join_req(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8bssid,
+ NMI_Uint8* pu8ssid, size_t ssidLen,
+ const NMI_Uint8* pu8IEs, size_t IEsLen,
+ tNMIpfConnectResult pfConnectResult, void* pvUserArg,
+ NMI_Uint8 u8security, AUTHTYPE_T tenuAuth_type,
+ NMI_Uint8 u8channel,
+ void* pJoinParams)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tenuScanConnTimer enuScanConnTimer;
+
+ if(pstrWFIDrv == NMI_NULL || pfConnectResult == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ if(hWFIDrv== NULL)
+ {
+ PRINT_ER("Driver not initialized: gWFiDrvHandle = NULL\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ if(pJoinParams == NULL){
+ PRINT_ER("Unable to Join - JoinParams is NULL\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+
+ }
+/*
+ if(gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount == 0)
+ {
+ PRINT_ER("No scan results exist: Scanning should be done\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+*/
+ /* prepare the Connect Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8security = u8security;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.tenuAuth_type = tenuAuth_type;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.u8channel = u8channel;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pfConnectResult = pfConnectResult;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pvUserArg = pvUserArg;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pJoinParams = pJoinParams;
+ strHostIFmsg.drvHandler= hWFIDrv;
+
+ if(pu8bssid != NULL)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid = (NMI_Uint8*)NMI_MALLOC(6); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8bssid,
+ pu8bssid, 6);
+ }
+
+ if(pu8ssid != NULL)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.ssidLen = ssidLen;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid = (NMI_Uint8*)NMI_MALLOC(ssidLen); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8ssid,
+
+ pu8ssid, ssidLen);
+ }
+
+ if(pu8IEs != NULL)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.IEsLen = IEsLen;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs = (NMI_Uint8*)NMI_MALLOC(IEsLen); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr.pu8IEs,
+ pu8IEs, IEsLen);
+ }
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send message queue: Set join request\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ enuScanConnTimer = CONNECT_TIMER;
+ NMI_TimerStart(&(pstrWFIDrv->hConnectTimer), HOST_IF_CONNECT_TIMEOUT,(void*) hWFIDrv, NMI_NULL);
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief Flush a join request parameters to FW, but actual connection
+* @details The function is called in situation where NMC is connected to AP and
+ required to switch to hybrid FW for P2P connection
+* @param[in] handle to the wifi driver,
+* @return Error code indicating success/failure
+* @note
+* @author Amr Abdel-Moghny
+* @date 19 DEC 2013
+* @version 8.0
+*/
+
+NMI_Sint32 host_int_flush_join_req(NMI_WFIDrvHandle hWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(!gu8FlushedJoinReq)
+ {
+ s32Error = NMI_FAIL;
+ return s32Error;
+ }
+
+
+ if(hWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_FLUSH_CONNECT;
+ strHostIFmsg.drvHandler= hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send message queue: Flush join request\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+
+/**
+* @brief host_int_disconnect
+* @details disconnects from the currently associated network
+* @param[in,out] handle to the wifi driver,
+* @param[in] Reason Code of the Disconnection
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_disconnect(NMI_WFIDrvHandle hWFIDrv, NMI_Uint16 u16ReasonCode)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ if(pstrWFIDrv == NULL)
+ {
+ PRINT_ER("gWFiDrvHandle = NULL\n");
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ /* prepare the Disconnect Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_DISCONNECT;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Failed to send message queue: disconnect\n");
+ ////////////////
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemTestDisconnectBlock),NULL);
+ /////////
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_disconnect_station
+* @details disconnects a sta
+* @param[in,out] handle to the wifi driver,
+* @param[in] Association Id of the station to be disconnected
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_disconnect_station(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 assoc_id)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_DISCONNECT;
+ strWID.enuWIDtype = WID_CHAR;
+ strWID.ps8WidVal = (NMI_Sint8*)&assoc_id;
+ strWID.s32ValueSize = sizeof(NMI_Char);
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_get_assoc_req_info
+* @details gets a Association request info
+* @param[in,out] handle to the wifi driver,
+ Message containg assoc. req info in the following format
+------------------------------------------------------------------------
+| Management Frame Format |
+|-------------------------------------------------------------------|
+|Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS |
+|-------------|--------|--|--|-----|----------------|----------|----|
+| 2 |2 |6 |6 |6 | 2 |0 - 2312 | 4 |
+|-------------------------------------------------------------------|
+| |
+| Association Request Frame - Frame Body |
+|-------------------------------------------------------------------|
+| Capability Information | Listen Interval | SSID | Supported Rates |
+|------------------------|-----------------|------|-----------------|
+| 2 | 2 | 2-34 | 3-10 |
+| ---------------------------------------------------------------------
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_get_assoc_req_info(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8AssocReqInfo,
+ NMI_Uint32 u32AssocReqInfoLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ASSOC_REQ_INFO;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = pu8AssocReqInfo;
+ strWID.s32ValueSize = u32AssocReqInfoLen;
+
+
+ return s32Error;
+}
+
+/**
+* @brief gets a Association Response info
+* @details
+* @param[in,out] handle to the wifi driver,
+ Message containg assoc. resp info
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_assoc_res_info(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8AssocRespInfo,
+ NMI_Uint32 u32MaxAssocRespInfoLen, NMI_Uint32* pu32RcvdAssocRespInfoLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ strWID.u16WIDid = (NMI_Uint16)WID_ASSOC_RES_INFO;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = pu8AssocRespInfo;
+ strWID.s32ValueSize = u32MaxAssocRespInfoLen;
+
+
+ /* Sending Configuration packet */
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send association response config packet\n");
+ *pu32RcvdAssocRespInfoLen = 0;
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ *pu32RcvdAssocRespInfoLen = strWID.s32ValueSize;
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+
+/**
+* @brief gets a Association Response info
+* @details Valid only in STA mode. This function gives the RSSI
+ values observed in all the channels at the time of scanning.
+ The length of the field is 1 greater that the total number of
+ channels supported. Byte 0 contains the number of channels while
+ each of Byte N contains the observed RSSI value for the channel index N.
+* @param[in,out] handle to the wifi driver,
+ array of scanned channels' RSSI
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_rx_power_level(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8RxPowerLevel,
+ NMI_Uint32 u32RxPowerLevelLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ strWID.u16WIDid = (NMI_Uint16)WID_RX_POWER_LEVEL;
+ strWID.enuWIDtype = WID_STR;
+ strWID.ps8WidVal = pu8RxPowerLevel;
+ strWID.s32ValueSize = u32RxPowerLevelLen;
+
+
+ return s32Error;
+}
+
+/**
+* @brief sets a channel
+* @details
+* @param[in,out] handle to the wifi driver,
+* @param[in] Index of the channel to be set
+|-------------------------------------------------------------------|
+| CHANNEL1 CHANNEL2 .... CHANNEL14 |
+| Input: 1 2 14 |
+|-------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_set_mac_chnl_num(NMI_WFIDrvHandle hWFIDrv,NMI_Uint8 u8ChNum)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the set channel message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_CHANNEL;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan.u8SetChan= u8ChNum;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+
+NMI_Sint32 host_int_wait_msg_queue_idle(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrHostIFmsg strHostIFmsg;
+
+ /* prepare the set driver handler message */
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_Q_IDLE;
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ // wait untill MSG Q is empty
+ NMI_SemaphoreAcquire(&hWaitResponse, NULL);
+
+ return s32Error;
+
+}
+
+NMI_Sint32 host_int_set_wfi_drv_handler(NMI_Uint32 u32address)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /* prepare the set driver handler message */
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_WFIDRV_HANDLER;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetDrvHandler.u32Address=u32address;
+ //strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+
+
+NMI_Sint32 host_int_set_operation_mode(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32mode)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /* prepare the set driver handler message */
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_OPERATION_MODE;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetOperationMode.u32Mode=u32mode;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief gets the current channel index
+* @details
+* @param[in,out] handle to the wifi driver,
+ current channel index
+|-----------------------------------------------------------------------|
+| CHANNEL1 CHANNEL2 .... CHANNEL14 |
+| Input: 1 2 14 |
+|-----------------------------------------------------------------------|
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_host_chnl_num(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8ChNo)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the Get Channel Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_CHNL;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Failed to send get host channel param's message queue ");
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemGetCHNL), NULL);
+ //gu8Chnl = 11;
+
+ *pu8ChNo = gu8Chnl;
+
+ NMI_CATCH(s32Error)
+ {}
+
+ return s32Error;
+
+
+}
+
+
+/**
+* @brief host_int_test_set_int_wid
+* @details Test function for setting wids
+* @param[in,out] NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32TestMemAddr
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_test_set_int_wid(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32TestMemAddr)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ /*prepare configuration packet*/
+ strWID.u16WIDid = (NMI_Uint16)WID_MEMORY_ADDRESS;
+ strWID.enuWIDtype = WID_INT;
+ strWID.ps8WidVal = (NMI_Char*)&u32TestMemAddr;
+ strWID.s32ValueSize = sizeof(NMI_Uint32);
+
+ /*Sending Cfg*/
+ s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ if(s32Error)
+ {
+ PRINT_ER("Test Function: Failed to set wid value\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ PRINT_D(HOSTINF_DBG,"Successfully set wid value\n");
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+
+#ifdef NMI_AP_EXTERNAL_MLME
+/**
+* @brief host_int_get_inactive_time
+* @details
+* @param[in,out] handle to the wifi driver,
+ current sta macaddress, inactive_time
+* @return
+* @note
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_inactive_time(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8 * mac,NMI_Uint32* pu32InactiveTime)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT.mac,
+ mac, ETH_ALEN);
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_INACTIVETIME;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ PRINT_ER("Failed to send get host channel param's message queue ");
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemInactiveTime), NULL);
+
+ *pu32InactiveTime = gu32InactiveTime;
+
+ NMI_CATCH(s32Error)
+ {}
+
+ return s32Error;
+}
+#endif
+/**
+* @brief host_int_test_get_int_wid
+* @details Test function for getting wids
+* @param[in,out] NMI_WFIDrvHandle hWFIDrv, NMI_Uint32* pu32TestMemAddr
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_test_get_int_wid(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32* pu32TestMemAddr)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrWID strWID;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+
+ strWID.u16WIDid = (NMI_Uint16)WID_MEMORY_ADDRESS;
+ strWID.enuWIDtype = WID_INT;
+ strWID.ps8WidVal = (NMI_Sint8*)pu32TestMemAddr;
+ strWID.s32ValueSize = sizeof(NMI_Uint32);
+
+ s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE,(NMI_Uint32)pstrWFIDrv);
+ /*get the value by searching the local copy*/
+ if(s32Error)
+ {
+ PRINT_ER("Test Function: Failed to get wid value\n");
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE);
+ }
+ else
+ {
+ PRINT_D(HOSTINF_DBG,"Successfully got wid value\n");
+
+ }
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+}
+
+
+/**
+* @brief host_int_get_rssi
+* @details gets the currently maintained RSSI value for the station.
+ The received signal strength value in dB.
+ The range of valid values is -128 to 0.
+* @param[in,out] handle to the wifi driver,
+ rssi value in dB
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_get_rssi(NMI_WFIDrvHandle hWFIDrv, NMI_Sint8* ps8Rssi)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_WFIDrv* pstrWFIDrv=(tstrNMI_WFIDrv*)hWFIDrv;
+
+
+ /* prepare the Get RSSI Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error){
+ PRINT_ER("Failed to send get host channel param's message queue ");
+ return NMI_FAIL;
+ }
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemGetRSSI), NULL);
+
+
+ if(ps8Rssi == NULL)
+ {
+ PRINT_ER("RSS pointer value is null");
+ return NMI_FAIL;
+ }
+
+
+ *ps8Rssi = gs8Rssi;
+
+
+ return s32Error;
+}
+
+NMI_Sint32 host_int_get_link_speed(NMI_WFIDrvHandle hWFIDrv, NMI_Sint8* ps8lnkspd)
+{
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrNMI_WFIDrv* pstrWFIDrv=(tstrNMI_WFIDrv*)hWFIDrv;
+
+
+
+ /* prepare the Get LINKSPEED Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_LINKSPEED;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error){
+ PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
+ return NMI_FAIL;
+ }
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->hSemGetLINKSPEED), NULL);
+
+
+ if(ps8lnkspd == NULL)
+ {
+ PRINT_ER("LINKSPEED pointer value is null");
+ return NMI_FAIL;
+ }
+
+
+ *ps8lnkspd = gs8lnkspd;
+
+
+ return s32Error;
+}
+
+NMI_Sint32 host_int_get_statistics(NMI_WFIDrvHandle hWFIDrv, tstrStatistics* pstrStatistics)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /* prepare the Get RSSI Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_STATISTICS;
+ strHostIFmsg.uniHostIFmsgBody.pUserData =(NMI_Char*)pstrStatistics;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error){
+ PRINT_ER("Failed to send get host channel param's message queue ");
+ return NMI_FAIL;
+ }
+
+ NMI_SemaphoreAcquire(&hWaitResponse, NULL);
+ return s32Error;
+}
+
+
+/**
+* @brief host_int_scan
+* @details scans a set of channels
+* @param[in,out] handle to the wifi driver,
+* @param[in] Scan source
+ Scan Type PASSIVE_SCAN = 0,
+ ACTIVE_SCAN = 1
+ Channels Array
+ Channels Array length
+ Scan Callback function
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 host_int_scan(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8 u8ScanSource,
+ NMI_Uint8 u8ScanType, NMI_Uint8* pu8ChnlFreqList,
+ NMI_Uint8 u8ChnlListLen, const NMI_Uint8* pu8IEs,
+ size_t IEsLen, tNMIpfScanResult ScanResult,
+ void* pvUserArg,tstrHiddenNetwork *pstrHiddenNetwork)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tenuScanConnTimer enuScanConnTimer;
+
+ if(pstrWFIDrv == NMI_NULL || ScanResult == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+
+ /* prepare the Scan Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN;
+
+ if(pstrHiddenNetwork != NULL)
+ {
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.strHiddenNetwork.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
+
+ }
+ else
+ NMI_PRINTF("pstrHiddenNetwork IS EQUAL TO NULL\n");
+
+ strHostIFmsg.drvHandler=hWFIDrv;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanSource = u8ScanSource;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ScanType = u8ScanType;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pfScanResult = ScanResult;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pvUserArg = pvUserArg;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.u8ChnlListLen = u8ChnlListLen;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList = (NMI_Uint8*)NMI_MALLOC(u8ChnlListLen); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8ChnlFreqList,
+ pu8ChnlFreqList, u8ChnlListLen);
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.IEsLen = IEsLen;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs = (NMI_Uint8*)NMI_MALLOC(IEsLen); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr.pu8IEs,
+ pu8IEs, IEsLen);
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Error in sending message queue scanning parameters: Error(%d)\n",s32Error);
+ NMI_ERRORREPORT(s32Error, NMI_FAIL);
+ }
+
+ enuScanConnTimer = SCAN_TIMER;
+ printk(">> Starting the SCAN timer\n");
+ NMI_TimerStart(&(pstrWFIDrv->hScanTimer), HOST_IF_SCAN_TIMEOUT,(void*) hWFIDrv, NMI_NULL);
+
+
+ NMI_CATCH(s32Error)
+ {
+
+ }
+ return s32Error;
+
+}
+/**
+* @brief hif_set_cfg
+* @details sets configuration wids values
+* @param[in,out] handle to the wifi driver,
+* @param[in] WID, WID value
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 hif_set_cfg(NMI_WFIDrvHandle hWFIDrv, tstrCfgParamVal * pstrCfgParamVal)
+{
+
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ tstrHostIFmsg strHostIFmsg;
+
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+ /* prepare the WiphyParams Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_CFG_PARAMS;
+ strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr.pstrCfgParamVal = *pstrCfgParamVal;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+
+ return s32Error;
+
+}
+
+
+/**
+* @brief hif_get_cfg
+* @details gets configuration wids values
+* @param[in,out] handle to the wifi driver,
+ WID value
+* @param[in] WID,
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+
+* @date 8 March 2012
+* @version 1.0
+*/
+NMI_Sint32 hif_get_cfg(NMI_WFIDrvHandle hWFIDrv,NMI_Uint16 u16WID,NMI_Uint16* pu16WID_Value)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n");
+ NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT);
+ }
+ PRINT_D(HOSTINF_DBG,"Getting configuration parameters\n");
+ switch(u16WID)
+ {
+
+ case WID_BSS_TYPE:
+ {
+
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.bss_type;
+
+ }
+ break;
+ case WID_AUTH_TYPE:
+ {
+
+ *pu16WID_Value =(NMI_Uint16)pstrWFIDrv->strCfgValues.auth_type;
+
+ }
+ break;
+ case WID_AUTH_TIMEOUT:
+ {
+
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.auth_timeout;
+
+ }
+ break;
+
+ case WID_POWER_MANAGEMENT:
+ {
+
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.power_mgmt_mode;
+ }
+ break;
+ case WID_SHORT_RETRY_LIMIT:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.short_retry_limit;
+ }
+ break;
+ case WID_LONG_RETRY_LIMIT:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.long_retry_limit;
+
+ }
+ break;
+ case WID_FRAG_THRESHOLD:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.frag_threshold;
+ }
+ break;
+ case WID_RTS_THRESHOLD:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.rts_threshold;
+ }
+ break;
+ case WID_PREAMBLE:
+ {
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.preamble_type;
+ }
+ break;
+ case WID_SHORT_SLOT_ALLOWED:
+ {
+ *pu16WID_Value =(NMI_Uint16) pstrWFIDrv->strCfgValues.short_slot_allowed;
+ }
+ break;
+ case WID_11N_TXOP_PROT_DISABLE:
+ {
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.txop_prot_disabled;
+ }
+ break;
+ case WID_BEACON_INTERVAL:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.beacon_interval;
+ }
+ break;
+ case WID_DTIM_PERIOD:
+ {
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.dtim_period;
+ }
+ break;
+ case WID_SITE_SURVEY:
+ {
+ *pu16WID_Value = (NMI_Uint16)pstrWFIDrv->strCfgValues.site_survey_enabled;
+ }
+ break;
+ case WID_SITE_SURVEY_SCAN_TIME:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.site_survey_scan_time;
+ }
+ break;
+
+ case WID_ACTIVE_SCAN_TIME:
+ {
+
+ *pu16WID_Value=pstrWFIDrv->strCfgValues.active_scan_time;
+ }
+ break;
+ case WID_PASSIVE_SCAN_TIME:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.passive_scan_time;
+
+ }
+ break;
+ case WID_CURRENT_TX_RATE:
+ {
+ *pu16WID_Value = pstrWFIDrv->strCfgValues.curr_tx_rate;
+ }
+ break;
+ default:
+ break;
+ }
+
+ NMI_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem), NULL);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+
+}
+
+/*****************************************************************************/
+/* Notification Functions */
+/*****************************************************************************/
+/**
+* @brief notifies host with join and leave requests
+* @details This function prepares an Information frame having the
+ information about a joining/leaving station.
+* @param[in,out] handle to the wifi driver,
+* @param[in] 6 byte Sta Adress
+ Join or leave flag:
+ Join = 1,
+ Leave =0
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+void host_int_send_join_leave_info_to_host
+ (NMI_Uint16 assocId, NMI_Uint8* stationAddr, NMI_Bool joining)
+{
+}
+/**
+* @brief notifies host with stations found in scan
+* @details sends the beacon/probe response from scan
+* @param[in,out] handle to the wifi driver,
+* @param[in] Sta Address,
+ Frame length,
+ Rssi of the Station found
+* @return Error code indicating success/failure
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+void GetPeriodicRSSI(void * pvArg)
+{
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)pvArg;
+ if(pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)
+ {
+
+ //printk("get peridoc rssi\n");
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /* prepare the Get RSSI Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI;
+ strHostIFmsg.drvHandler=pstrWFIDrv;
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Failed to send get host channel param's message queue ");
+ return;
+ }
+ }
+ NMI_TimerStart(&(pstrWFIDrv->hPeriodicRSSI),5000,(void*)pstrWFIDrv,NULL);
+}
+
+
+void host_int_send_network_info_to_host
+ (NMI_Uint8 *macStartAddress,NMI_Uint16 u16RxFrameLen, NMI_Sint8 s8Rssi)
+{
+}
+/**
+* @brief host_int_init
+* @details host interface initialization function
+* @param[in,out] handle to the wifi driver,
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+static NMI_Uint32 u32Intialized = 0;
+static NMI_Uint32 msgQ_created=0;
+static NMI_Uint32 clients_count=0;
+
+NMI_Sint32 host_int_init(NMI_WFIDrvHandle* phWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv;
+ tstrNMI_SemaphoreAttrs strSemaphoreAttrs;
+
+
+ /*if(u32Intialized == 1)
+ {
+ PRINT_D(HOSTINF_DBG,"Host interface is previously initialized\n");
+ *phWFIDrv = (NMI_WFIDrvHandle)gWFiDrvHandle; //Will be adjusted later for P2P
+ return 0;
+ } */
+ PRINT_D(HOSTINF_DBG,"Initializing host interface for client %d\n",clients_count+1);
+
+ gbScanWhileConnected = NMI_FALSE;
+
+ NMI_SemaphoreFillDefault(&strSemaphoreAttrs);
+
+
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&hWaitResponse, &strSemaphoreAttrs);
+
+
+
+ /*Allocate host interface private structure*/
+ pstrWFIDrv = (tstrNMI_WFIDrv*)NMI_MALLOC(sizeof(tstrNMI_WFIDrv));
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ //NMI_ERRORREPORT(s32Error,NMI_NO_MEM);
+ s32Error = NMI_NO_MEM;
+ PRINT_ER("Failed to allocate memory\n");
+ goto _fail_timer_2;
+ }
+ NMI_memset(pstrWFIDrv,0,sizeof(tstrNMI_WFIDrv));
+ /*return driver handle to user*/
+ *phWFIDrv = (NMI_WFIDrvHandle)pstrWFIDrv;
+ /*save into globl handle*/
+
+ #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP
+
+ g_obtainingIP=NMI_FALSE;
+ #endif
+
+ PRINT_D(HOSTINF_DBG,"Global handle pointer value=%x\n",(NMI_Uint32)pstrWFIDrv);
+ /////////////////////////////////////////
+ if(clients_count==0)
+ {
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&hSemHostIFthrdEnd, &strSemaphoreAttrs);
+
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&hSemDeinitDrvHandle, &strSemaphoreAttrs);
+ }
+
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemTestKeyBlock), &strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemTestDisconnectBlock), &strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemGetRSSI), &strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemGetLINKSPEED), &strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemGetCHNL), &strSemaphoreAttrs);
+ strSemaphoreAttrs.u32InitCount = 0;
+ NMI_SemaphoreCreate(&(pstrWFIDrv->hSemInactiveTime), &strSemaphoreAttrs);
+
+
+ /////////////////////////////////////////
+
+
+
+ PRINT_D(HOSTINF_DBG,"INIT: CLIENT COUNT %d\n",clients_count);
+
+ if(clients_count==0)
+ {
+
+ s32Error = NMI_MsgQueueCreate(&gMsgQHostIF, NMI_NULL);
+
+
+ if(s32Error < 0)
+ {
+ PRINT_ER("Failed to creat MQ\n");
+ goto _fail_;
+ }
+ msgQ_created=1;
+ s32Error = NMI_ThreadCreate(&HostIFthreadHandler,hostIFthread, NMI_NULL, NMI_NULL);
+ if(s32Error < 0)
+ {
+ PRINT_ER("Failed to creat Thread\n");
+ goto _fail_mq_;
+ }
+
+
+ }
+
+
+ s32Error = NMI_TimerCreate(&(pstrWFIDrv->hScanTimer), TimerCB_Scan, NMI_NULL);
+ if(s32Error < 0){
+ PRINT_ER("Failed to creat Timer\n");
+ goto _fail_thread_;
+ }
+
+ s32Error = NMI_TimerCreate(&(pstrWFIDrv->hConnectTimer), TimerCB_Connect, NMI_NULL);
+ if(s32Error < 0){
+ PRINT_ER("Failed to creat Timer\n");
+ goto _fail_timer_1;
+ }
+ s32Error = NMI_TimerCreate(&(pstrWFIDrv->hPeriodicRSSI),GetPeriodicRSSI, NMI_NULL);
+ if(s32Error < 0){
+ PRINT_ER("Failed to creat Timer\n");
+ goto _fail_timer_1;
+ }
+ NMI_TimerStart(&(pstrWFIDrv->hPeriodicRSSI),5000,(void*)pstrWFIDrv,NULL);
+
+ #ifdef NMI_P2P
+ /*Remain on channel timer*/
+ s32Error = NMI_TimerCreate(&(pstrWFIDrv->hRemainOnChannel),ListenTimerCB, NMI_NULL);
+ if(s32Error < 0){
+ PRINT_ER("Failed to creat Remain-on-channel Timer\n");
+ goto _fail_timer_3;
+ }
+ #endif
+
+ NMI_SemaphoreCreate(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+
+
+
+#ifdef SIMULATION
+ TransportInit();
+#endif
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+ //gWFiDrvHandle->bPendingConnRequest = NMI_FALSE;
+
+ /*Initialize CFG WIDS Defualt Values*/
+
+ pstrWFIDrv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
+ pstrWFIDrv->strCfgValues.scan_source = DEFAULT_SCAN;
+ pstrWFIDrv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
+ pstrWFIDrv->strCfgValues.passive_scan_time= PASSIVE_SCAN_TIME;
+ pstrWFIDrv->strCfgValues.curr_tx_rate = AUTORATE;
+
+
+ #ifdef NMI_P2P
+
+ pstrWFIDrv->u64P2p_MgmtTimeout = 0;
+
+ #endif
+
+ PRINT_INFO(HOSTINF_DBG,"Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n",
+
+ pstrWFIDrv->strCfgValues.site_survey_enabled,pstrWFIDrv->strCfgValues.scan_source,
+ pstrWFIDrv->strCfgValues.active_scan_time,pstrWFIDrv->strCfgValues.passive_scan_time,
+ pstrWFIDrv->strCfgValues.curr_tx_rate);
+
+
+ NMI_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+
+ /*TODO Code to setup simulation to be removed later*/
+ /*Intialize configurator module*/
+ s32Error = CoreConfiguratorInit();
+ if(s32Error < 0){
+ PRINT_ER("Failed to initialize core configurator\n");
+ goto _fail_mem_;
+ }
+
+#ifdef SIMULATION
+ /*Initialize Simulaor*/
+ CoreConfigSimulatorInit();
+#endif
+
+ u32Intialized = 1;
+ clients_count++;//increase number of created entities
+
+ return s32Error;
+
+
+_fail_mem_:
+ if(pstrWFIDrv != NMI_NULL)
+ NMI_FREE(pstrWFIDrv);
+#ifdef NMI_P2P
+_fail_timer_3:
+ NMI_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), NMI_NULL);
+#endif
+_fail_timer_2:
+ NMI_SemaphoreRelease(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+ NMI_TimerDestroy(&(pstrWFIDrv->hConnectTimer),NMI_NULL);
+_fail_timer_1:
+ NMI_TimerDestroy(&(pstrWFIDrv->hScanTimer),NMI_NULL);
+_fail_thread_:
+ NMI_ThreadDestroy(&HostIFthreadHandler, NMI_NULL);
+_fail_mq_:
+ NMI_MsgQueueDestroy(&gMsgQHostIF, NMI_NULL);
+_fail_:
+ return s32Error;
+
+
+}
+/**
+* @brief host_int_deinit
+* @details host interface initialization function
+* @param[in,out] handle to the wifi driver,
+* @note
+* @author zsalah
+* @date 8 March 2012
+* @version 1.0
+*/
+
+NMI_Sint32 host_int_deinit(NMI_WFIDrvHandle hWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+
+
+ /*obtain driver handle*/
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ /*if(u32Intialized == 0)
+ {
+ PRINT_ER("Host Interface is not initialized\n");
+ return 0;
+ }*/
+
+ terminated_handle=pstrWFIDrv;
+ PRINT_D( HOSTINF_DBG,"De-initializing host interface for client %d\n",clients_count);
+ host_int_set_wfi_drv_handler((NMI_Uint32)NMI_NULL);
+ NMI_SemaphoreAcquire(&hSemDeinitDrvHandle, NULL);
+
+ /*Calling the CFG80211 scan done function with the abort flag set to true*/
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NMI_NULL,
+ pstrWFIDrv->strNMI_UsrScanReq.u32UserScanPvoid,NULL);
+
+ pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult= NMI_NULL;
+ }
+ /*deinit configurator and simulator*/
+#ifdef SIMULATION
+ CoreConfigSimulatorDeInit();
+#endif
+ CoreConfiguratorDeInit();
+#ifdef SIMULATION
+ TransportDeInit();
+#endif
+
+ if(NMI_TimerDestroy(&(pstrWFIDrv->hScanTimer), NMI_NULL)){
+ printk(">> Scan timer is active \n");
+ //msleep(HOST_IF_SCAN_TIMEOUT+1000);
+ }
+
+ if(NMI_TimerDestroy(&(pstrWFIDrv->hConnectTimer), NMI_NULL)){
+ printk(">> Connect timer is active \n");
+ //msleep(HOST_IF_CONNECT_TIMEOUT+1000);
+ }
+
+
+ if(NMI_TimerDestroy(&(pstrWFIDrv->hPeriodicRSSI), NMI_NULL)){
+ printk(">> Connect timer is active \n");
+ //msleep(HOST_IF_CONNECT_TIMEOUT+1000);
+ }
+
+ #ifdef NMI_P2P
+ /*Destroy Remain-onchannel Timer*/
+ NMI_TimerDestroy(&(pstrWFIDrv->hRemainOnChannel), NMI_NULL);
+ #endif
+
+ pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
+
+ gbScanWhileConnected = NMI_FALSE;
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ if(clients_count==1)
+ {
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_EXIT;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error != NMI_SUCCESS)
+ {
+ PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n",s32Error);
+ }
+
+ NMI_SemaphoreAcquire(&hSemHostIFthrdEnd, NULL);
+
+
+ //PRINT_D(HOSTINF_DBG,"Thread Destroy %p\n",&HostIFthreadHandler);
+ //s32Error = NMI_ThreadDestroy(&HostIFthreadHandler, NMI_NULL);
+ //NMI_ERRORCHECK(s32Error);
+ }
+
+
+ /* Destroy the MSG Queue */
+ if(clients_count==1)
+ {
+ NMI_MsgQueueDestroy(&gMsgQHostIF, NMI_NULL);
+ msgQ_created=0;
+
+ }
+
+
+
+
+ /*Destroy Semaphores*/
+ if (clients_count==1)
+ {
+ NMI_SemaphoreDestroy(&hSemHostIFthrdEnd,NULL);
+ NMI_SemaphoreDestroy(&hSemDeinitDrvHandle,NULL);
+ }
+
+ NMI_SemaphoreDestroy(&(pstrWFIDrv ->hSemTestKeyBlock),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->hSemTestDisconnectBlock),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->hSemGetRSSI),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->hSemGetLINKSPEED),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->hSemGetCHNL),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->hSemInactiveTime),NULL);
+ NMI_SemaphoreDestroy(&hWaitResponse,NULL);
+
+ NMI_SemaphoreAcquire(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+ NMI_SemaphoreDestroy(&(pstrWFIDrv->gtOsCfgValuesSem),NULL);
+
+ /*Setting the gloabl driver handler with NULL*/
+ u32Intialized = 0;
+ //gWFiDrvHandle = NULL;
+ if(pstrWFIDrv != NMI_NULL)
+ {
+ NMI_FREE(pstrWFIDrv);
+ //pstrWFIDrv=NMI_NULL;
+
+ }
+
+ clients_count--;//Decrease number of created entities
+ terminated_handle=NMI_NULL;
+ return s32Error;
+}
+
+
+/**
+* @brief NetworkInfoReceived
+* @details function to to be called when network info packet is received
+* @param[in] pu8Buffer the received packet
+* @param[in] u32Length length of the received packet
+* @return none
+* @note
+* @author
+* @date 1 Mar 2012
+* @version 1.0
+*/
+void NetworkInfoReceived(NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint32 drvHandler;
+ tstrNMI_WFIDrv * pstrWFIDrv=NMI_NULL;
+
+ drvHandler=((pu8Buffer[u32Length-4])|(pu8Buffer[u32Length-3]<<8)|(pu8Buffer[u32Length-2]<<16)|(pu8Buffer[u32Length-1]<<24));
+ pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+
+
+ if(pstrWFIDrv== NMI_NULL||pstrWFIDrv==terminated_handle)
+ {
+ PRINT_ER("NetworkInfo received but driver not init[%x]\n",(NMI_Uint32)pstrWFIDrv);
+ return;
+ }
+
+ /* prepare the Asynchronous Network Info message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_NTWRK_INFO;
+ strHostIFmsg.drvHandler=pstrWFIDrv;
+
+ strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.u32Length = u32Length;
+ strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer = (NMI_Uint8*)NMI_MALLOC(u32Length); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo.pu8Buffer,
+ pu8Buffer, u32Length);
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n",s32Error);
+ }
+
+
+ return;
+}
+
+/**
+* @brief GnrlAsyncInfoReceived
+* @details function to be called when general Asynchronous info packet is received
+* @param[in] pu8Buffer the received packet
+* @param[in] u32Length length of the received packet
+* @return none
+* @note
+* @author
+* @date 15 Mar 2012
+* @version 1.0
+*/
+void GnrlAsyncInfoReceived(NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint32 drvHandler;
+ tstrNMI_WFIDrv * pstrWFIDrv=NMI_NULL;
+
+ drvHandler=((pu8Buffer[u32Length-4])|(pu8Buffer[u32Length-3]<<8)|(pu8Buffer[u32Length-2]<<16)|(pu8Buffer[u32Length-1]<<24));
+ pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+ PRINT_D(HOSTINF_DBG,"General asynchronous info packet received \n");
+
+
+ if(pstrWFIDrv== NULL||pstrWFIDrv==terminated_handle)
+ {
+ PRINT_ER("Wifi driver handler is equal to NULL\n");
+ return;
+ }
+
+ if(pstrWFIDrv->strNMI_UsrConnReq.pfUserConnectResult == NMI_NULL)
+ {
+ /* received mac status is not needed when there is no current Connect Request */
+ PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
+ return;
+ }
+
+ /* prepare the General Asynchronous Info message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
+ strHostIFmsg.drvHandler=pstrWFIDrv;
+
+
+ strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.u32Length = u32Length;
+ strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer = (NMI_Uint8*)NMI_MALLOC(u32Length); /* will be deallocated
+ by the receiving
+ thread */
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo.pu8Buffer,
+ pu8Buffer, u32Length);
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n",s32Error);
+ }
+
+ return;
+}
+
+/**
+* @brief host_int_ScanCompleteReceived
+* @details Setting scan complete received notifcation in message queue
+* @param[in] NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+void host_int_ScanCompleteReceived(NMI_Uint8* pu8Buffer, NMI_Uint32 u32Length)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrHostIFmsg strHostIFmsg;
+ NMI_Uint32 drvHandler;
+ tstrNMI_WFIDrv * pstrWFIDrv=NMI_NULL;
+ drvHandler=((pu8Buffer[u32Length-4])|(pu8Buffer[u32Length-3]<<8)|(pu8Buffer[u32Length-2]<<16)|(pu8Buffer[u32Length-1]<<24));
+ pstrWFIDrv = (tstrNMI_WFIDrv *)drvHandler;
+
+
+ PRINT_D(GENERIC_DBG,"Scan notification received %x\n", (NMI_Uint32)pstrWFIDrv);
+
+ if(pstrWFIDrv== NULL||pstrWFIDrv==terminated_handle)
+
+ {
+ return;
+ }
+
+ /*if there is an ongoing scan request*/
+ if(pstrWFIDrv->strNMI_UsrScanReq.pfUserScanResult)
+ {
+ /* prepare theScan Done message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
+ strHostIFmsg.drvHandler=pstrWFIDrv;
+
+
+ /* will be deallocated by the receiving thread */
+ /*no need to send message body*/
+
+ /*strHostIFmsg.uniHostIFmsgBody.strScanComplete.u32Length = u32Length;
+ strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer = (NMI_Uint8*)NMI_MALLOC(u32Length);
+ NMI_memcpy(strHostIFmsg.uniHostIFmsgBody.strScanComplete.pu8Buffer,
+ pu8Buffer, u32Length); */
+
+ /* send the message */
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n",s32Error);
+ }
+ }
+
+
+ return;
+
+}
+
+#ifdef NMI_P2P
+/**
+* @brief host_int_remain_on_channel
+* @details
+* @param[in] Handle to wifi driver
+ Duration to remain on channel
+ Channel to remain on
+ Pointer to fn to be called on receive frames in listen state
+ Pointer to remain-on-channel expired fn
+ Priv
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_remain_on_channel(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32duration, NMI_Uint16 chan,tNMIpfRemainOnChanExpired RemainOnChanExpired, tNMIpfRemainOnChanReady RemainOnChanReady,void* pvUserArg)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the remainonchan Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_REMAIN_ON_CHAN;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u16Channel= chan;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanExpired = RemainOnChanExpired;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanReady = RemainOnChanReady;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pVoid=pvUserArg;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32duration=u32duration;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_ListenStateExpired
+* @details
+* @param[in] Handle to wifi driver
+ Duration to remain on channel
+ Channel to remain on
+ Pointer to fn to be called on receive frames in listen state
+ Pointer to remain-on-channel expired fn
+ Priv
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_ListenStateExpired(NMI_WFIDrvHandle hWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /*Stopping remain-on-channel timer*/
+ NMI_TimerStop(&(pstrWFIDrv->hRemainOnChannel), NMI_NULL);
+
+ /* prepare the timer fire Message */
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_frame_register
+* @details
+* @param[in] Handle to wifi driver
+* @return Error code.
+* @author
+* @date
+* @version 1.0*/
+NMI_Sint32 host_int_frame_register(NMI_WFIDrvHandle hWFIDrv, NMI_Uint16 u16FrameType,NMI_Bool bReg)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_REGISTER_FRAME;
+ switch (u16FrameType)
+ {
+ case ACTION:
+ PRINT_D(HOSTINF_DBG,"ACTION\n");
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid=ACTION_FRM_IDX;
+ break;
+ case PROBE_REQ:
+ PRINT_D(HOSTINF_DBG,"PROBE REQ\n");
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u8Regid=PROBE_REQ_IDX;
+ break;
+ default:
+ PRINT_D(HOSTINF_DBG,"Not valid frame type\n");
+ break;
+ }
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.u16FrameType= u16FrameType;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfRegisterFrame.bReg= bReg;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+
+
+}
+#endif
+
+#ifdef NMI_AP_EXTERNAL_MLME
+/**
+* @brief host_int_add_beacon
+* @details Setting add beacon params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8Tail
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_beacon(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32Interval,
+ NMI_Uint32 u32DTIMPeriod,
+ NMI_Uint32 u32HeadLen, NMI_Uint8* pu8Head,
+ NMI_Uint32 u32TailLen, NMI_Uint8* pu8Tail)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIFSetBeacon* pstrSetBeaconParam = &strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ PRINT_D(HOSTINF_DBG,"Setting adding beacon message queue params\n");
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BEACON;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ pstrSetBeaconParam->u32Interval = u32Interval;
+ pstrSetBeaconParam->u32DTIMPeriod= u32DTIMPeriod;
+ pstrSetBeaconParam->u32HeadLen = u32HeadLen;
+ pstrSetBeaconParam->pu8Head = (NMI_Uint8*)NMI_MALLOC(u32HeadLen);
+ if(pstrSetBeaconParam->pu8Head == NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_NO_MEM);
+ }
+ NMI_memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen);
+ pstrSetBeaconParam->u32TailLen = u32TailLen;
+
+ /* Bug 4599 : if tail length = 0 skip allocating & copying */
+ if(u32TailLen > 0)
+ {
+ pstrSetBeaconParam->pu8Tail = (NMI_Uint8*)NMI_MALLOC(u32TailLen);
+ if(pstrSetBeaconParam->pu8Tail== NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_NO_MEM);
+ }
+ NMI_memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen);
+ }
+ else
+ {
+ pstrSetBeaconParam->pu8Tail=NULL;
+ }
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ if(pstrSetBeaconParam->pu8Head != NULL)
+ {
+ NMI_FREE(pstrSetBeaconParam->pu8Head);
+ }
+
+ if(pstrSetBeaconParam->pu8Tail != NULL)
+ {
+ NMI_FREE(pstrSetBeaconParam->pu8Tail);
+ }
+ }
+
+ return s32Error;
+
+}
+
+
+/**
+* @brief host_int_del_beacon
+* @details Setting add beacon params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_del_beacon(NMI_WFIDrvHandle hWFIDrv)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BEACON;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ PRINT_D(HOSTINF_DBG,"Setting deleting beacon message queue params\n");
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ NMI_ERRORCHECK(s32Error);
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+
+/**
+* @brief host_int_add_station
+* @details Setting add station params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_add_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_AddStaParam* pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam;
+
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ PRINT_D(HOSTINF_DBG,"Setting adding station message queue params\n");
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_STATION;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ NMI_memcpy(pstrAddStationMsg , pstrStaParams, sizeof(tstrNMI_AddStaParam));
+ if(pstrAddStationMsg->u8NumRates>0)
+ {
+ pstrAddStationMsg->pu8Rates = NMI_MALLOC(pstrAddStationMsg->u8NumRates);
+ NMI_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates);
+
+ NMI_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
+ }
+
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+/**
+* @brief host_int_del_station
+* @details Setting delete station params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8MacAddr
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_del_station(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* pu8MacAddr)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIFDelSta* pstrDelStationMsg = &strHostIFmsg.uniHostIFmsgBody.strDelStaParam;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ PRINT_D(HOSTINF_DBG,"Setting deleting station message queue params\n");
+
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_STATION;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ /*BugID_4795: Handling situation of deleting all stations*/
+ if(pu8MacAddr == NMI_NULL)
+ NMI_memset(pstrDelStationMsg->au8MacAddr, 255, ETH_ALEN);
+ else
+ NMI_memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN);
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+/**
+* @brief host_int_edit_station
+* @details Setting edit station params in message queue
+* @param[in] NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams
+* @return Error code.
+* @author
+* @date
+* @version 1.0
+*/
+NMI_Sint32 host_int_edit_station(NMI_WFIDrvHandle hWFIDrv, tstrNMI_AddStaParam* pstrStaParams)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrNMI_AddStaParam* pstrAddStationMsg = &strHostIFmsg.uniHostIFmsgBody.strAddStaParam;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ PRINT_D(HOSTINF_DBG,"Setting editing station message queue params\n");
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_EDIT_STATION;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ NMI_memcpy(pstrAddStationMsg , pstrStaParams, sizeof(tstrNMI_AddStaParam));
+ if(pstrAddStationMsg->u8NumRates>0)
+ {
+ pstrAddStationMsg->pu8Rates = NMI_MALLOC(pstrAddStationMsg->u8NumRates);
+ NMI_memcpy(pstrAddStationMsg->pu8Rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
+ NMI_NULLCHECK(s32Error, pstrAddStationMsg->pu8Rates);
+ }
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+#endif /*NMI_AP_EXTERNAL_MLME*/
+uint32_t nmi_get_chipid(uint8_t);
+
+NMI_Sint32 host_int_set_power_mgmt(NMI_WFIDrvHandle hWFIDrv, NMI_Bool bIsEnabled, NMI_Uint32 u32Timeout)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIfPowerMgmtParam* pstrPowerMgmtParam = &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam;
+
+ printk("\n\n>> Setting PS to %d << \n\n",bIsEnabled);
+
+ // Disable PS with muxed sdio for D0 for DMA version 2, cause it had a bug with DMA ver 2 with the interrupt registers that was fixed in F0
+#if (defined NMI_SDIO) && (!defined USE_DMA_VER_1) && (!defined NMI_SDIO_IRQ_GPIO)
+ if(nmi_get_chipid(NMI_FALSE) == 0x1000d0)
+ {
+ return s32Error;
+ }
+#endif
+
+ // F0 boards requires the 1.4 VCO supply. Otherwise, disable PS
+#ifndef VCO_14_SUPPLY
+ if(nmi_get_chipid(NMI_FALSE) < 0x1002a0)
+ {
+ return s32Error;
+ }
+#endif //VCO_14_SUPPLY
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ PRINT_D(HOSTINF_DBG,"Setting Power management message queue params\n");
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_POWER_MGMT;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ pstrPowerMgmtParam->bIsEnabled = bIsEnabled;
+ pstrPowerMgmtParam->u32Timeout = u32Timeout;
+
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+NMI_Sint32 host_int_setup_multicast_filter(NMI_WFIDrvHandle hWFIDrv, NMI_Bool bIsEnabled, NMI_Uint32 u32count)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIFSetMulti* pstrMulticastFilterParam = &strHostIFmsg.uniHostIFmsgBody.strHostIfSetMulti;
+
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ PRINT_D(HOSTINF_DBG,"Setting Multicast Filter params\n");
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_MULTICAST_FILTER;
+ strHostIFmsg.drvHandler=hWFIDrv;
+
+ pstrMulticastFilterParam->bIsEnabled = bIsEnabled;
+ pstrMulticastFilterParam->u32count = u32count;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+ }
+ return s32Error;
+}
+
+
+
+/*Bug4218: Parsing Join Param*/
+#ifdef NMI_PARSE_SCAN_IN_HOST
+
+/*Bug4218: Parsing Join Param*/
+/**
+* @brief host_int_ParseJoinBssParam
+* @details Parse Needed Join Parameters and save it in a new JoinBssParam entry
+* @param[in] tstrNetworkInfo* ptstrNetworkInfo
+* @return
+* @author zsalah
+* @date
+* @version 1.0**/
+static void* host_int_ParseJoinBssParam(tstrNetworkInfo* ptstrNetworkInfo)
+{
+ tstrJoinBssParam* pNewJoinBssParam=NULL;
+ NMI_Uint8* pu8IEs;
+ NMI_Uint16 u16IEsLen;
+ NMI_Uint16 index = 0;
+ NMI_Uint8 suppRatesNo = 0;
+ NMI_Uint8 extSuppRatesNo;
+ NMI_Uint16 jumpOffset;
+ NMI_Uint8 pcipherCount;
+ NMI_Uint8 authCount;
+ NMI_Uint8 pcipherTotalCount = 0;
+ NMI_Uint8 authTotalCount = 0;
+ NMI_Uint8 i,j;
+
+ pu8IEs = ptstrNetworkInfo->pu8IEs;
+ u16IEsLen =ptstrNetworkInfo->u16IEsLen;
+
+ pNewJoinBssParam = NMI_MALLOC(sizeof(tstrJoinBssParam));
+ if(pNewJoinBssParam!=NULL)
+ {
+ NMI_memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam));
+ pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
+ pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
+ pNewJoinBssParam->cap_info =ptstrNetworkInfo->u16CapInfo;
+ NMI_memcpy(pNewJoinBssParam->au8bssid,ptstrNetworkInfo->au8bssid,6);
+ /*for(i=0; i<6;i++)
+ PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->au8bssid[i]);*/
+ NMI_memcpy((NMI_Uint8*)pNewJoinBssParam->ssid,ptstrNetworkInfo->au8ssid,ptstrNetworkInfo->u8SsidLen+1);
+ pNewJoinBssParam->ssidLen = ptstrNetworkInfo->u8SsidLen;
+ NMI_memset(pNewJoinBssParam->rsn_pcip_policy,0xFF, 3);
+ NMI_memset(pNewJoinBssParam->rsn_auth_policy,0xFF, 3);
+ /*for(i=0; i<pNewJoinBssParam->ssidLen;i++)
+ PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->ssid[i]);*/
+
+ //parse supported rates:
+ while(index<u16IEsLen)
+ {
+ //supportedRates IE
+ if (pu8IEs[index]== SUPP_RATES_IE)
+ {
+ //PRINT_D(HOSTINF_DBG, "Supported Rates\n");
+ suppRatesNo = pu8IEs[index+1];
+ pNewJoinBssParam->supp_rates[0] = suppRatesNo;
+ index+=2;//skipping ID and length bytes;
+
+ for(i=0; i<suppRatesNo; i++)
+ {
+ pNewJoinBssParam->supp_rates[i+1] = pu8IEs[index+i];
+ //PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[i+1]);
+ }
+ index+=suppRatesNo;
+ continue;
+ }
+ //Ext SupportedRates IE
+ else if(pu8IEs[index]== EXT_SUPP_RATES_IE)
+ {
+ //PRINT_D(HOSTINF_DBG, "Extended Supported Rates\n");
+ //checking if no of ext. supp and supp rates < max limit
+ extSuppRatesNo = pu8IEs[index+1];
+ if(extSuppRatesNo > (MAX_RATES_SUPPORTED-suppRatesNo))
+ pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
+ else
+ pNewJoinBssParam->supp_rates[0]+=extSuppRatesNo;
+ index+=2;
+ //pNewJoinBssParam.supp_rates[0] contains now old number not the ext. no
+ for(i=0; i< (pNewJoinBssParam->supp_rates[0]-suppRatesNo); i++)
+ {
+ pNewJoinBssParam->supp_rates[suppRatesNo+i+1] = pu8IEs[index+i];
+ //PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[suppRatesNo+i+1]);
+ }
+ //printk("\n");
+ index+=extSuppRatesNo;
+ continue;
+ }
+
+ //HT Cap. IE
+ else if(pu8IEs[index]==HT_CAPABILITY_IE)
+ {
+ //if IE found set the flag
+ pNewJoinBssParam->ht_capable = BTRUE;
+ index+=pu8IEs[index+1]+2; //ID,Length bytes and IE body
+ //PRINT_D(HOSTINF_DBG,"HT_CAPABALE\n");
+ continue;
+ }
+ else if((pu8IEs[index] == WMM_IE) && /* WMM Element ID */
+ (pu8IEs[index+2] == 0x00) && (pu8IEs[index+3] == 0x50) &&
+ (pu8IEs[index+4] == 0xF2) && /* OUI */
+ (pu8IEs[index+5] == 0x02) && /* OUI Type */
+ ((pu8IEs[index+6] == 0x00) || (pu8IEs[index+6] == 0x01)) && /* OUI Sub Type */
+ (pu8IEs[index+7] == 0x01))
+ {
+ /* Presence of WMM Info/Param element indicates WMM capability */
+ pNewJoinBssParam->wmm_cap = BTRUE;
+
+ /* Check if Bit 7 is set indicating U-APSD capability */
+ if(pu8IEs[index + 8] & (1 << 7))
+ {
+ pNewJoinBssParam->uapsd_cap = BTRUE;
+ }
+ index += pu8IEs[index + 1]+2;
+ continue;
+ }
+ #ifdef NMI_P2P
+ else if((pu8IEs[index] == P2P_IE) && /* P2P Element ID */
+ (pu8IEs[index+2] == 0x50) && (pu8IEs[index+3] == 0x6f) &&
+ (pu8IEs[index+4] == 0x9a) && /* OUI */
+ (pu8IEs[index+5] == 0x09) && (pu8IEs[index+6] == 0x0c) ) /* OUI Type */
+ {
+ NMI_Uint16 u16P2P_count;
+ pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
+ pNewJoinBssParam->u8NoaEnbaled = 1;
+ pNewJoinBssParam->u8Index = pu8IEs[index + 9];
+
+ /* Check if Bit 7 is set indicating Opss capability */
+ if(pu8IEs[index + 10] & (1 << 7))
+ {
+ pNewJoinBssParam->u8OppEnable= 1;
+ pNewJoinBssParam->u8CtWindow= pu8IEs[index+10];
+ }
+ else
+ pNewJoinBssParam->u8OppEnable= 0;
+ //HOSTINF_DBG
+ PRINT_D(GENERIC_DBG,"P2P Dump \n");
+ for(i=0;i<pu8IEs[index + 7];i++)
+ PRINT_D(GENERIC_DBG," %x \n",pu8IEs[index+9+i]);
+
+ pNewJoinBssParam->u8Count = pu8IEs[index+11];
+ u16P2P_count = index+12;
+
+ NMI_memcpy(pNewJoinBssParam->au8Duration,pu8IEs+u16P2P_count,4);
+ u16P2P_count+=4;
+
+ NMI_memcpy(pNewJoinBssParam->au8Interval,pu8IEs+u16P2P_count,4);
+ u16P2P_count+=4;
+
+ NMI_memcpy(pNewJoinBssParam->au8StartTime ,pu8IEs+u16P2P_count,4);
+
+ index += pu8IEs[index + 1]+2;
+ continue;
+
+ }
+ #endif
+ else if ((pu8IEs[index]==RSN_IE)||
+ ((pu8IEs[index]==WPA_IE)&& (pu8IEs[index+2] == 0x00) &&
+ (pu8IEs[index+3] == 0x50) && (pu8IEs[index+4] == 0xF2) &&
+ (pu8IEs[index+5] == 0x01)))
+ {
+ NMI_Uint16 rsnIndex = index;
+ /*PRINT_D(HOSTINF_DBG,"RSN IE Length:%d\n",pu8IEs[rsnIndex+1]);
+ for(i=0; i<pu8IEs[rsnIndex+1]; i++)
+ {
+ PRINT_D(HOSTINF_DBG,"%0x ",pu8IEs[rsnIndex+2+i]);
+ }*/
+ if(pu8IEs[rsnIndex]==RSN_IE)
+ {
+ pNewJoinBssParam->mode_802_11i = 2;
+ //PRINT_D(HOSTINF_DBG,"\nRSN_IE\n");
+ }
+ else
+ { //check if rsn was previously parsed
+ if(pNewJoinBssParam->mode_802_11i==0)
+ pNewJoinBssParam->mode_802_11i = 1;
+ //PRINT_D(HOSTINF_DBG,"\nWPA_IE\n");
+ rsnIndex+=4;
+ }
+ rsnIndex+=7;//skipping id, length, version(2B) and first 3 bytes of gcipher
+ pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
+ rsnIndex++;
+ //PRINT_D(HOSTINF_DBG,"Group Policy: %0x \n",pNewJoinBssParam->rsn_grp_policy);
+ //initialize policies with invalid values
+
+ jumpOffset = pu8IEs[rsnIndex]*4; //total no.of bytes of pcipher field (count*4)
+
+ /*parsing pairwise cipher*/
+
+ //saving 3 pcipher max.
+ pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 :pu8IEs[rsnIndex];
+ rsnIndex+=2; //jump 2 bytes of pcipher count
+
+ //PRINT_D(HOSTINF_DBG,"\npcipher:%d \n",pcipherCount);
+ for(i=pcipherTotalCount,j=0; i<pcipherCount+pcipherTotalCount&&i<3; i++,j++)
+ {
+ //each count corresponds to 4 bytes, only last byte is saved
+ pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex+((j+1)*4)-1];
+ //PRINT_D(HOSTINF_DBG,"PAIR policy = [%0x,%0x]\n",pNewJoinBssParam->rsn_pcip_policy[i],i);
+ }
+ pcipherTotalCount += pcipherCount;
+ rsnIndex+=jumpOffset;
+
+ jumpOffset = pu8IEs[rsnIndex]*4;
+
+ /*parsing AKM suite (auth_policy)*/
+ //saving 3 auth policies max.
+ authCount = (pu8IEs[rsnIndex] > 3) ? 3 :pu8IEs[rsnIndex];
+ rsnIndex+=2; //jump 2 bytes of pcipher count
+
+ //PRINT_D(HOSTINF_DBG,"\nauth policy: ");
+ for(i=authTotalCount,j=0; i<authTotalCount+authCount; i++,j++)
+ {
+ //each count corresponds to 4 bytes, only last byte is saved
+ pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex+((j+1)*4)-1];
+ }
+ authTotalCount += authCount;
+ //printk("\n");
+ rsnIndex+=jumpOffset;
+ /*pasring rsn cap. only if rsn IE*/
+ if(pu8IEs[index]==RSN_IE)
+ { pNewJoinBssParam->rsn_cap[0]=pu8IEs[rsnIndex];
+ pNewJoinBssParam->rsn_cap[1]=pu8IEs[rsnIndex+1];
+ //PRINT_D(HOSTINF_DBG,"%0x %0x\n",pNewJoinBssParam->rsn_cap[0], pNewJoinBssParam->rsn_cap[1]);
+ rsnIndex+=2 ;
+ }
+ pNewJoinBssParam->rsn_found=1;
+ index+=pu8IEs[index+1]+2; //ID,Length bytes and IE body
+ continue;
+ }
+ else
+ index+=pu8IEs[index+1]+2; //ID,Length bytes and IE body
+
+ }
+
+
+ }
+
+ return (void*)pNewJoinBssParam;
+
+}
+
+void host_int_freeJoinParams(void* pJoinParams){
+ if((tstrJoinBssParam*)pJoinParams != NULL)
+ NMI_FREE((tstrJoinBssParam*)pJoinParams);
+ else
+ PRINT_ER("Unable to FREE null pointer\n");
+}
+#endif /*NMI_PARSE_SCAN_IN_HOST*/
+
+
+/**
+* @brief host_int_addBASession
+* @details Open a block Ack session with the given parameters
+* @param[in] tstrNetworkInfo* ptstrNetworkInfo
+* @return
+* @author anoureldin
+* @date
+* @version 1.0**/
+
+static int host_int_addBASession(NMI_WFIDrvHandle hWFIDrv, char* pBSSID,char TID,short int BufferSize,
+ short int SessionTimeout,void * drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIfBASessionInfo* pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_ADD_BA_SESSION;
+
+ memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
+ pBASessionInfo->u8Ted = TID;
+ pBASessionInfo->u16BufferSize = BufferSize;
+ pBASessionInfo->u16SessionTimeout = SessionTimeout;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+}
+NMI_Sint32 host_int_delBASession(NMI_WFIDrvHandle hWFIDrv, char* pBSSID,char TID,void * drvHandler)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+ tstrHostIfBASessionInfo* pBASessionInfo = &strHostIFmsg.uniHostIFmsgBody.strHostIfBASessionInfo;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_DEL_BA_SESSION;
+
+ memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
+ pBASessionInfo->u8Ted = TID;
+ strHostIFmsg.drvHandler = hWFIDrv;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ /*BugID_5222*/
+ NMI_SemaphoreAcquire(&hWaitResponse, NULL);
+
+ return s32Error;
+}
+
+/**
+* @brief host_int_setup_ipaddress
+* @details setup IP in firmware
+* @param[in] Handle to wifi driver
+* @return Error code.
+* @author Abdelrahman Sobhy
+* @date
+* @version 1.0*/
+NMI_Sint32 host_int_setup_ipaddress(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* u16ipadd, NMI_Uint8 idx)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ // TODO: Enable This feature on softap firmware
+ return 0;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_SET_IPADDRESS;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr= u16ipadd;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx = idx;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+
+
+}
+
+/**
+* @brief host_int_get_ipaddress
+* @details Get IP from firmware
+* @param[in] Handle to wifi driver
+* @return Error code.
+* @author Abdelrahman Sobhy
+* @date
+* @version 1.0*/
+NMI_Sint32 host_int_get_ipaddress(NMI_WFIDrvHandle hWFIDrv, NMI_Uint8* u16ipadd, NMI_Uint8 idx)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+ tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv;
+ tstrHostIFmsg strHostIFmsg;
+
+ if(pstrWFIDrv == NMI_NULL)
+ {
+ NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT);
+ }
+
+ NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg));
+
+ /* prepare the WiphyParams Message */
+ strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_IPADDRESS;
+
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.au8IPAddr= u16ipadd;
+ strHostIFmsg.drvHandler=hWFIDrv;
+ strHostIFmsg.uniHostIFmsgBody.strHostIfSetIP.idx= idx;
+
+ s32Error = NMI_MsgQueueSend(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), NMI_NULL);
+ if(s32Error)
+ {
+ NMI_ERRORREPORT(s32Error, s32Error);
+ }
+ NMI_CATCH(s32Error)
+ {
+
+ }
+
+ return s32Error;
+
+
+}
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_sdio.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_sdio.c
new file mode 100755
index 00000000..9137796e
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_sdio.c
@@ -0,0 +1,1491 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_sdio.c
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+
+
+#ifdef NMC1000_SINGLE_TRANSFER
+#define NMI_SDIO_BLOCK_SIZE 256
+#else
+ #if defined(PLAT_AML8726_M3) //johnny
+ #define NMI_SDIO_BLOCK_SIZE 512
+ #define MAX_SEG_SIZE (1<<12) //4096
+ #else
+ #define NMI_SDIO_BLOCK_SIZE 512
+ #endif
+#endif
+
+typedef struct {
+ void *os_context;
+ nmi_wlan_os_func_t os_func;
+ uint32_t block_size;
+ int (*sdio_cmd52)(sdio_cmd52_t *);
+ int (*sdio_cmd53)(sdio_cmd53_t *);
+ int (*sdio_set_max_speed)(void);
+ int (*sdio_set_default_speed)(void);
+ nmi_debug_func dPrint;
+#if DMA_VER == DMA_VER_2
+ int nint;
+ int has_thrpt_enh;
+ int has_thrpt_enh2;
+ int reg_0xf6_not_clear_bug_fix;
+#endif /* DMA_VER == DMA_VER_2 */
+} nmi_sdio_t;
+
+static nmi_sdio_t g_sdio;
+
+#ifdef NMI_SDIO_IRQ_GPIO
+static int sdio_write_reg(uint32_t addr, uint32_t data);
+static int sdio_read_reg(uint32_t addr, uint32_t *data);
+#endif
+extern unsigned int int_clrd;
+
+/********************************************
+
+ Function 0
+
+********************************************/
+
+static int sdio_set_func0_csa_address(uint32_t adr)
+{
+ sdio_cmd52_t cmd;
+
+ /**
+ Review: BIG ENDIAN
+ **/
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0x10c;
+ cmd.data = (uint8_t)adr;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x10c data...\n");
+ goto _fail_;
+ }
+
+ cmd.address = 0x10d;
+ cmd.data = (uint8_t)(adr>>8);
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x10d data...\n");
+ goto _fail_;
+ }
+
+ cmd.address = 0x10e;
+ cmd.data = (uint8_t)(adr>>16);
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x10e data...\n");
+ goto _fail_;
+ }
+
+ return 1;
+_fail_:
+ return 0;
+}
+
+static int sdio_set_func0_csa_address_byte0(uint32_t adr)
+{
+ sdio_cmd52_t cmd;
+
+
+ /**
+ Review: BIG ENDIAN
+ **/
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0x10c;
+ cmd.data = (uint8_t)adr;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x10c data...\n");
+ goto _fail_;
+ }
+
+ return 1;
+_fail_:
+ return 0;
+}
+static int sdio_set_func0_block_size(uint32_t block_size)
+{
+ sdio_cmd52_t cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0x10;
+ cmd.data = (uint8_t)block_size;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x10 data...\n");
+ goto _fail_;
+ }
+
+ cmd.address = 0x11;
+ cmd.data = (uint8_t)(block_size>>8);
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x11 data...\n");
+ goto _fail_;
+ }
+
+ return 1;
+_fail_:
+ return 0;
+}
+
+/********************************************
+
+ Function 1
+
+********************************************/
+
+static int sdio_set_func1_block_size(uint32_t block_size)
+{
+ sdio_cmd52_t cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0x110;
+ cmd.data = (uint8_t)block_size;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x110 data...\n");
+ goto _fail_;
+ }
+ cmd.address = 0x111;
+ cmd.data = (uint8_t)(block_size>>8);
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0x111 data...\n");
+ goto _fail_;
+ }
+
+ return 1;
+_fail_:
+ return 0;
+}
+
+static int sdio_clear_int(void)
+{
+#ifndef NMI_SDIO_IRQ_GPIO
+ //uint32_t sts;
+ sdio_cmd52_t cmd;
+ cmd.read_write = 0;
+ cmd.function = 1;
+ cmd.raw = 0;
+ cmd.address = 0x4;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ int_clrd++;
+ //printk("intSts=%d\n",cmd.data);
+ return cmd.data;
+#else
+ uint32_t reg;
+ if (!sdio_read_reg(NMI_HOST_RX_CTRL_0, &reg)) {
+ g_sdio.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_HOST_RX_CTRL_0);
+ return 0;
+ }
+ reg &= ~0x1;
+ sdio_write_reg(NMI_HOST_RX_CTRL_0, reg);
+ int_clrd++;
+ return 1;
+#endif
+
+}
+
+uint32_t sdio_xfer_cnt(void)
+{
+ uint32_t cnt = 0;
+ sdio_cmd52_t cmd;
+ cmd.read_write = 0;
+ cmd.function = 1;
+ cmd.raw = 0;
+ cmd.address = 0x1C;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ cnt = cmd.data;
+
+ cmd.read_write = 0;
+ cmd.function = 1;
+ cmd.raw = 0;
+ cmd.address = 0x1D;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ cnt |= (cmd.data<<8);
+
+ cmd.read_write = 0;
+ cmd.function = 1;
+ cmd.raw = 0;
+ cmd.address = 0x1E;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ cnt |= (cmd.data<<16);
+
+ return cnt;
+
+
+}
+
+/********************************************
+
+ Sdio interfaces
+
+********************************************/
+int sdio_check_bs(void)
+{
+ sdio_cmd52_t cmd;
+
+ /**
+ poll until BS is 0
+ **/
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xc;
+ cmd.data = 0;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, get BS register...\n");
+ goto _fail_;
+ }
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+static int sdio_write_reg(uint32_t addr, uint32_t data)
+{
+#ifdef BIG_ENDIAN
+ data = BYTE_SWAP(data);
+#endif
+
+ if((addr >= 0xf0) && (addr <= 0xff))
+ {
+ sdio_cmd52_t cmd;
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = addr;
+ cmd.data = data;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
+ goto _fail_;
+ }
+ }
+ else
+ {
+ sdio_cmd53_t cmd;
+
+ /**
+ set the AHB address
+ **/
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.address = 0x10f;
+ cmd.block_mode = 0;
+ cmd.increment = 1;
+ cmd.count = 4;
+ cmd.buffer = (uint8_t *)&data;
+ cmd.block_size = g_sdio.block_size; //johnny : prevent it from setting unexpected value
+
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53, write reg (%08x)...\n", addr);
+ goto _fail_;
+ }
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+ }
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+static int sdio_write(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ uint32_t block_size = g_sdio.block_size;
+ sdio_cmd53_t cmd;
+ int nblk, nleft;
+
+ cmd.read_write = 1;
+ if (addr > 0) {
+ /**
+ has to be word aligned...
+ **/
+ if (size & 0x3) {
+ size += 4;
+ size &= ~0x3;
+ }
+
+ /**
+ func 0 access
+ **/
+ cmd.function = 0;
+ cmd.address = 0x10f;
+ } else {
+#ifdef NMC1000_SINGLE_TRANSFER
+ /**
+ has to be block aligned...
+ **/
+ nleft = size%block_size;
+ if (nleft > 0) {
+ size += block_size;
+ size &= ~(block_size-1);
+ }
+#else
+ /**
+ has to be word aligned...
+ **/
+ if (size & 0x3) {
+ size += 4;
+ size &= ~0x3;
+ }
+#endif
+
+ /**
+ func 1 access
+ **/
+ cmd.function = 1;
+ cmd.address = 0;
+ }
+
+ nblk = size/block_size;
+ nleft = size%block_size;
+
+ if (nblk > 0) {
+
+#if defined(PLAT_AML8726_M3_BACKUP) //johnny // rachel
+ int i;
+
+ for(i=0; i<nblk; i++)
+ {
+ cmd.block_mode = 0; //1;
+ cmd.increment = 1;
+ cmd.count = block_size; //nblk;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block send...\n",addr);
+ goto _fail_;
+ }
+
+ if (addr > 0)
+ addr += block_size; //addr += nblk*block_size;
+
+ buf += block_size; //buf += nblk*block_size;
+ }
+
+#elif defined(PLAT_AML8726_M3) //johnny
+
+ int i;
+ int rest;
+ int seg_cnt;
+
+ seg_cnt = (nblk*block_size)/MAX_SEG_SIZE;
+ rest = (nblk*block_size) & (MAX_SEG_SIZE-1);
+
+ //printk("[Johnny W] seg_cnt = %d, rest = %d\n", seg_cnt, rest);
+
+ for ( i = 0 ; i < seg_cnt ; i ++ )
+ {
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = MAX_SEG_SIZE/block_size;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+
+ //printk("[Johnny W] cmd.count = %d, cmd.block_size = %d\n", cmd.count, cmd.block_size);
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block send...\n",addr);
+ goto _fail_;
+ }
+
+ if (addr > 0)
+ addr += MAX_SEG_SIZE;
+
+ buf += MAX_SEG_SIZE;
+
+ }
+
+
+ if ( rest > 0 ) {
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = rest/block_size;
+ cmd.buffer = buf;
+ cmd.block_size = block_size; //johnny : prevent it from setting unexpected value
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], bytes send...\n",addr);
+ goto _fail_;
+ }
+
+ if (addr > 0)
+ addr += rest;
+
+ buf += rest;
+
+ }
+
+#else
+
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = nblk;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block send...\n",addr);
+ goto _fail_;
+ }
+ if (addr > 0)
+ addr += nblk*block_size;
+ buf += nblk*block_size;
+
+#endif //platform
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+
+ }
+
+
+ if (nleft > 0) {
+ cmd.block_mode = 0;
+ cmd.increment = 1;
+ cmd.count = nleft;
+ cmd.buffer = buf;
+
+ cmd.block_size = block_size; //johnny : prevent it from setting unexpected value
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], bytes send...\n",addr);
+ goto _fail_;
+ }
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+ }
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+static int sdio_read_reg(uint32_t addr, uint32_t *data)
+{
+ if((addr >= 0xf0) && (addr <= 0xff))
+ {
+ sdio_cmd52_t cmd;
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address= addr;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd 52, read reg (%08x) ...\n", addr);
+ goto _fail_;
+ }
+ *data = cmd.data;
+ }
+ else
+ {
+ sdio_cmd53_t cmd;
+
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.address = 0x10f;
+ cmd.block_mode = 0;
+ cmd.increment = 1;
+ cmd.count = 4;
+ cmd.buffer = (uint8_t *)data;
+
+ cmd.block_size = g_sdio.block_size; //johnny : prevent it from setting unexpected value
+
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53, read reg (%08x)...\n", addr);
+ goto _fail_;
+ }
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+ }
+
+#ifdef BIG_ENDIAN
+ *data = BYTE_SWAP(*data);
+#endif
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+static int sdio_read(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ uint32_t block_size = g_sdio.block_size;
+ sdio_cmd53_t cmd;
+ int nblk, nleft;
+
+ cmd.read_write = 0;
+ if (addr > 0) {
+ /**
+ has to be word aligned...
+ **/
+ if (size & 0x3) {
+ size += 4;
+ size &= ~0x3;
+ }
+
+ /**
+ func 0 access
+ **/
+ cmd.function = 0;
+ cmd.address = 0x10f;
+ } else {
+#ifdef NMC1000_SINGLE_TRANSFER
+ /**
+ has to be block aligned...
+ **/
+ nleft = size%block_size;
+ if (nleft > 0) {
+ size += block_size;
+ size &= ~(block_size-1);
+ }
+#else
+ /**
+ has to be word aligned...
+ **/
+ if (size & 0x3) {
+ size += 4;
+ size &= ~0x3;
+ }
+#endif
+
+ /**
+ func 1 access
+ **/
+ cmd.function = 1;
+ cmd.address = 0;
+ }
+
+ nblk = size/block_size;
+ nleft = size%block_size;
+
+ if (nblk > 0) {
+
+#if defined(PLAT_AML8726_M3_BACKUP) //johnny // rachel
+
+ int i;
+
+ for(i=0; i<nblk; i++)
+ {
+ cmd.block_mode = 0; //1;
+ cmd.increment = 1;
+ cmd.count = block_size; //nblk;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block read...\n",addr);
+ goto _fail_;
+ }
+ if (addr > 0)
+ addr += block_size; //addr += nblk*block_size;
+ buf += block_size; //buf += nblk*block_size;
+ }
+
+#elif defined(PLAT_AML8726_M3) //johnny
+
+ int i;
+ int rest;
+ int seg_cnt;
+
+ seg_cnt = (nblk*block_size)/MAX_SEG_SIZE;
+ rest = (nblk*block_size) & (MAX_SEG_SIZE-1);
+
+ //printk("[Johnny R] seg_cnt = %d, rest = %d\n", seg_cnt, rest);
+
+ for ( i = 0 ; i < seg_cnt ; i ++ )
+ {
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = MAX_SEG_SIZE/block_size;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+
+ //printk("[Johnny R] cmd.count = %d, cmd.block_size = %d\n", cmd.count, cmd.block_size);
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block read...\n",addr);
+ goto _fail_;
+ }
+
+ if (addr > 0)
+ addr += MAX_SEG_SIZE;
+
+ buf += MAX_SEG_SIZE;
+
+ }
+
+
+ if ( rest > 0 ) {
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = rest/block_size;
+ cmd.buffer = buf;
+ cmd.block_size = block_size; //johnny : prevent it from setting unexpected value
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block read...\n",addr);
+ goto _fail_;
+ }
+
+ if (addr > 0)
+ addr += rest;
+
+ buf += rest;
+
+ }
+
+#else
+
+ cmd.block_mode = 1;
+ cmd.increment = 1;
+ cmd.count = nblk;
+ cmd.buffer = buf;
+ cmd.block_size = block_size;
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], block read...\n",addr);
+ goto _fail_;
+ }
+ if (addr > 0)
+ addr += nblk*block_size;
+ buf += nblk*block_size;
+
+#endif //platform
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+
+ } //if (nblk > 0)
+
+ if (nleft > 0) {
+ cmd.block_mode = 0;
+ cmd.increment = 1;
+ cmd.count = nleft;
+ cmd.buffer = buf;
+
+ cmd.block_size = block_size; //johnny : prevent it from setting unexpected value
+
+ if (addr > 0) {
+ if (!sdio_set_func0_csa_address(addr))
+ goto _fail_;
+ }
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53 [%x], bytes read...\n",addr);
+ goto _fail_;
+ }
+
+#if 0
+ if (!sdio_check_bs())
+ goto _fail_;
+#else
+ //g_sdio.os_func.os_sleep(1);
+#endif
+ }
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+/********************************************
+
+ Bus interfaces
+
+********************************************/
+
+static int sdio_deinit(void *pv)
+{
+ return 1;
+}
+
+static int sdio_sync(void)
+{
+ uint32_t reg;
+
+ /**
+ Disable power sequencer
+ **/
+ if (!sdio_read_reg(NMI_MISC, &reg)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed read misc reg...\n");
+ return 0;
+ }
+
+ reg &= ~(1 << 8);
+ if (!sdio_write_reg(NMI_MISC, reg)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed write misc reg...\n");
+ return 0;
+ }
+
+#ifdef NMI_SDIO_IRQ_GPIO
+ {
+ uint32_t reg;
+ int ret;
+
+ /**
+ interrupt pin mux select
+ **/
+ ret = sdio_read_reg(NMI_PIN_MUX_0, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+ reg |= (1<<8);
+ ret = sdio_write_reg(NMI_PIN_MUX_0, reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+
+ /**
+ interrupt enable
+ **/
+ ret = sdio_read_reg(NMI_INTR_ENABLE, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+ reg |= (1<<16);
+ ret = sdio_write_reg(NMI_INTR_ENABLE, reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+ }
+#endif
+
+ return 1;
+}
+
+static int sdio_init(nmi_wlan_inp_t *inp, nmi_debug_func func)
+{
+ sdio_cmd52_t cmd;
+ int loop;
+ uint32_t chipid;
+ memset(&g_sdio, 0, sizeof(nmi_sdio_t));
+
+ g_sdio.dPrint = func;
+ g_sdio.os_context = inp->os_context.os_private;
+ memcpy((void *)&g_sdio.os_func, (void *)&inp->os_func, sizeof(nmi_wlan_os_func_t));
+
+ if (inp->io_func.io_init) {
+ if (!inp->io_func.io_init(g_sdio.os_context)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed io init bus...\n");
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+
+ g_sdio.sdio_cmd52 = inp->io_func.u.sdio.sdio_cmd52;
+ g_sdio.sdio_cmd53 = inp->io_func.u.sdio.sdio_cmd53;
+ g_sdio.sdio_set_max_speed = inp->io_func.u.sdio.sdio_set_max_speed;
+ g_sdio.sdio_set_default_speed = inp->io_func.u.sdio.sdio_set_default_speed;
+
+ /**
+ function 0 csa enable
+ **/
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 1;
+ cmd.address = 0x100;
+ cmd.data = 0x80;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, enable csa...\n");
+ goto _fail_;
+ }
+
+ /**
+ function 0 block size
+ **/
+ if (!sdio_set_func0_block_size(NMI_SDIO_BLOCK_SIZE)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, set func 0 block size...\n");
+ goto _fail_;
+ }
+ g_sdio.block_size = NMI_SDIO_BLOCK_SIZE;
+
+ /**
+ enable func1 IO
+ **/
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 1;
+ cmd.address = 0x2;
+ cmd.data = 0x2;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio] Fail cmd 52, set IOE register...\n");
+ goto _fail_;
+ }
+
+ /**
+ make sure func 1 is up
+ **/
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0x3;
+ loop = 3;
+ do {
+ cmd.data = 0;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, get IOR register...\n");
+ goto _fail_;
+ }
+ if (cmd.data == 0x2)
+ break;
+ } while (loop--);
+
+ if (loop <= 0) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail func 1 is not ready...\n");
+ goto _fail_;
+ }
+
+ /**
+ func 1 is ready, set func 1 block size
+ **/
+ if (!sdio_set_func1_block_size(NMI_SDIO_BLOCK_SIZE)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail set func 1 block size...\n");
+ goto _fail_;
+ }
+
+ /**
+ func 1 interrupt enable
+ **/
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 1;
+ cmd.address = 0x4;
+ cmd.data = 0x3;
+ if (!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, set IEN register...\n");
+ goto _fail_;
+ }
+
+ /**
+ make sure can read back chip id correctly
+ **/
+ if (!sdio_read_reg(0x1000, &chipid)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd read chip id...\n");
+ goto _fail_;
+ }
+
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: chipid (%08x)\n", chipid);
+
+#if DMA_VER == DMA_VER_2
+ if( (chipid & 0xfff) > 0x0d0) {
+ g_sdio.has_thrpt_enh = 1;
+ if( (chipid & 0xfff) > 0x0f0) {
+ g_sdio.has_thrpt_enh2 = 1;
+#ifdef REG_0XF6_NOT_CLEAR_BUG_FIX /* bug 4456 and 4557 */
+ g_sdio.reg_0xf6_not_clear_bug_fix = 1;
+#else /* REG_0XF6_NOT_CLEAR_BUG_FIX */
+ g_sdio.reg_0xf6_not_clear_bug_fix = 0;
+#endif /* REG_0XF6_NOT_CLEAR_BUG_FIX */
+ } else {
+ g_sdio.has_thrpt_enh2 = 0;
+ g_sdio.reg_0xf6_not_clear_bug_fix = 1;
+ }
+ } else {
+ g_sdio.has_thrpt_enh = 0;
+ g_sdio.has_thrpt_enh2 = 0;
+ g_sdio.reg_0xf6_not_clear_bug_fix = 0;
+ }
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: has_thrpt_enh = %d...\n", g_sdio.has_thrpt_enh);
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: has_thrpt_enh2 = %d...\n", g_sdio.has_thrpt_enh2);
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: reg_0xf6_not_clear_bug_fix = %d...\n", g_sdio.reg_0xf6_not_clear_bug_fix);
+#endif
+
+
+ return 1;
+
+_fail_:
+
+ return 0;
+}
+
+static void sdio_set_max_speed(void)
+{
+ g_sdio.sdio_set_max_speed();
+}
+
+static void sdio_set_default_speed(void)
+{
+ g_sdio.sdio_set_default_speed();
+}
+#if DMA_VER == DMA_VER_2
+
+static int sdio_write_ext(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ int ret;
+
+ ret = sdio_write(addr, buf, size);
+
+ if(g_sdio.reg_0xf6_not_clear_bug_fix) {/* bug 4456 and 4557 */
+ if(g_sdio.has_thrpt_enh) {
+ sdio_cmd52_t cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf6;
+ cmd.data = 0;
+ if(!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, set 0xf6 register (%d) ...\n", __LINE__);
+ goto _fail_;
+ }
+ }
+ }
+ return ret;
+
+_fail_:
+ return 0;
+
+}
+
+static int sdio_read_ext(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ int ret;
+
+
+ ret = sdio_read(addr, buf, size);
+
+ if(g_sdio.reg_0xf6_not_clear_bug_fix) { /* bug 4456 and 4557 */
+ if(g_sdio.has_thrpt_enh) {
+ sdio_cmd52_t cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf6;
+ cmd.data = 0;
+ if(!g_sdio.sdio_cmd52(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Fail cmd 52, set 0xf6 register (%d) ...\n", __LINE__);
+ goto _fail_;
+ }
+ }
+ }
+
+ return ret;
+
+_fail_:
+ return 0;
+}
+
+
+
+static int sdio_read_size(uint32_t * size)
+{
+
+ uint32_t tmp;
+ sdio_cmd52_t cmd;
+
+ /**
+ Read DMA count in words
+ **/
+ if (g_sdio.has_thrpt_enh) {
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf2;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ tmp = cmd.data;
+ //printk("%s @ %d: sdio read %x = %x\n", __FUNCTION__, __LINE__, cmd.address, cmd.data);
+
+ //cmd.read_write = 0;
+ //cmd.function = 0;
+ //cmd.raw = 0;
+ cmd.address = 0xf3;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ tmp |= (cmd.data << 8);
+ //printk("%s @ %d: sdio read %x = %x\n", __FUNCTION__, __LINE__, cmd.address, cmd.data);
+ } else {
+
+ uint32_t byte_cnt;
+
+#ifndef NMI_SDIO_IRQ_GPIO
+ byte_cnt = sdio_xfer_cnt(); /* In DAT1 muxed interrupt case, read DMA count using fn0 regs. */
+#else
+ /*sdio_read_reg(0xf01c, &byte_cnt);*/ /*Bug 4534 */
+ /*byte_cnt = sdio_xfer_cnt();*/ /*Bug 4535 */
+ sdio_read_reg(NMI_VMM_TO_HOST_SIZE, &byte_cnt); /* in IRQN interrupt case, read DMA count over AHB. */
+
+
+#endif
+
+ tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
+ }
+
+ *size=tmp;
+ return 1;
+}
+
+static int sdio_read_int(uint32_t * int_status)
+{
+
+ uint32_t tmp;
+ sdio_cmd52_t cmd;
+
+ sdio_read_size(&tmp);
+
+ /**
+ Read IRQ flags
+ **/
+#ifndef NMI_SDIO_IRQ_GPIO
+ //cmd.read_write = 0;
+ cmd.function = 1;
+ //cmd.raw = 0;
+ cmd.address = 0x04;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ //printk("%s @ %d: sdio read %x = %x\n", __FUNCTION__, __LINE__, cmd.address, cmd.data);
+ if(cmd.data & (1 << 0)) {
+ tmp |= INT_0;
+ }
+ if(cmd.data & (1 << 2)) {
+ tmp |= INT_1;
+ }
+ if(cmd.data & (1 << 3)) {
+ tmp |= INT_2;
+ }
+ if(cmd.data & (1 << 4)) {
+ tmp |= INT_3;
+ }
+ if(cmd.data & (1 << 5)) {
+ tmp |= INT_4;
+ }
+ if(cmd.data & (1 << 6)) {
+ tmp |= INT_5;
+ }
+ {
+ int i;
+ for(i=g_sdio.nint; i<MAX_NUM_INT; i++) {
+ if((tmp >> (IRG_FLAGS_OFFSET+i)) & 0x1) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Unexpected interrupt (1) : tmp=%x, data=%x\n", tmp, cmd.data);
+ break;
+ }
+ }
+ }
+#else
+ if (g_sdio.has_thrpt_enh2) {
+ uint32_t irq_flags;
+
+ cmd.read_write = 0;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf7;
+ cmd.data = 0;
+ g_sdio.sdio_cmd52(&cmd);
+ irq_flags = cmd.data & 0x1f;
+ tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
+ } else {
+ int happended, j;
+
+ j = 0;
+ do {
+ uint32_t irq_flags;
+
+ happended = 0;
+
+ sdio_read_reg(0x1a90, &irq_flags);
+ tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
+
+ if(g_sdio.nint > 5) {
+ sdio_read_reg(0x1a94, &irq_flags);
+ tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET+5));
+ }
+
+ {
+ uint32_t unkmown_mask;
+
+ unkmown_mask = ~((1ul << g_sdio.nint) - 1);
+
+ if( (tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
+ happended = 1;
+ }
+ }
+ j++;
+ } while(happended);
+ }
+
+#endif
+
+ *int_status = tmp;
+
+ //printk("int_status = %x\n", *int_status);
+
+ return 1;
+}
+
+static int sdio_clear_int_ext(uint32_t val)
+{
+ int ret;
+
+ //printk("sdio_clear_int_ext = %x\n", val);
+
+#ifdef NMI_SDIO_IRQ_GPIO
+ if (g_sdio.has_thrpt_enh2) {
+ /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
+ /* Cannot clear multiple interrupts. Must clear each interrupt individually */
+ uint32_t flags;
+ flags = val & ((1 << MAX_NUM_INT) - 1);
+ if(flags) {
+ int i;
+
+ ret = 1;
+ for(i=0; i<g_sdio.nint; i++) {
+ if(flags & 1) {
+ sdio_cmd52_t cmd;
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf8;
+ cmd.data = (1 << i);
+
+ ret = g_sdio.sdio_cmd52(&cmd);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0xf8 data (%d) ...\n", __LINE__);
+ goto _fail_;
+ }
+
+ }
+ if(!ret) break;
+ flags >>= 1;
+ }
+ if (!ret) {
+ goto _fail_;
+ }
+ for(i=g_sdio.nint; i<MAX_NUM_INT; i++) {
+ if(flags & 1) g_sdio.dPrint(N_ERR, "[nmi sdio]: Unexpected interrupt cleared %d...\n", i);
+ flags >>= 1;
+ }
+ }
+ } else {
+ uint32_t flags;
+ flags = val & ((1 << MAX_NUM_INT) - 1);
+ if(flags) {
+ int i;
+
+ ret = 1;
+ for(i=0; i<g_sdio.nint; i++) {
+ /* No matter what you write 1 or 0, it will clear interrupt. */
+ if(flags & 1) ret = sdio_write_reg(0x10c8+i*4, 1);
+ if(!ret) break;
+ flags >>= 1;
+ }
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed sdio_write_reg, set reg %x ...\n", 0x10c8+i*4);
+ goto _fail_;
+ }
+ for(i=g_sdio.nint; i<MAX_NUM_INT; i++) {
+ if(flags & 1) g_sdio.dPrint(N_ERR, "[nmi sdio]: Unexpected interrupt cleared %d...\n", i);
+ flags >>= 1;
+ }
+ }
+ }
+#endif /* NMI_SDIO_IRQ_GPIO */
+
+
+ if(g_sdio.has_thrpt_enh) {
+ uint32_t vmm_ctl;
+
+ vmm_ctl = 0;
+ /* select VMM table 0 */
+ if((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) vmm_ctl |= (1 << 0);
+ /* select VMM table 1 */
+ if((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) vmm_ctl |= (1 << 1);
+ /* enable VMM */
+ if((val & EN_VMM) == EN_VMM) vmm_ctl |= (1 << 2);
+
+ if(vmm_ctl) {
+ sdio_cmd52_t cmd;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.raw = 0;
+ cmd.address = 0xf6;
+ cmd.data = vmm_ctl;
+ //printk("%s @ %d: sdio read %x = %x\n", __FUNCTION__, __LINE__, cmd.address, cmd.data);
+ ret = g_sdio.sdio_cmd52(&cmd);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd52, set 0xf6 data (%d) ...\n", __LINE__);
+ goto _fail_;
+ }
+ }
+ } else { /* g_sdio.has_thrpt_enh */
+ uint32_t tbl_ctl;
+
+ tbl_ctl = 0;
+ /* select VMM table 0 */
+ if((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) tbl_ctl |= (1 << 0);
+ /* select VMM table 1 */
+ if((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) tbl_ctl |= (1 << 1);
+
+ if(tbl_ctl) { /* fix bug 4588 */
+ ret = sdio_write_reg(NMI_VMM_TBL_CTL, tbl_ctl);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: fail write reg vmm_tbl_ctl...\n");
+ goto _fail_;
+ }
+ }
+
+ if((val & EN_VMM) == EN_VMM) {
+ /**
+ enable vmm transfer.
+ **/
+
+ if(!tbl_ctl) { /* fix bug 4588 */
+ ret = sdio_write_reg(NMI_VMM_CORE_CTL, 1);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: fail write reg vmm_core_ctl...\n");
+ goto _fail_;
+ }
+ } else {
+ uint32_t data;
+ sdio_cmd53_t cmd;
+
+
+ /**
+ Write NMI_VMM_CORE_CTL the way below to save 2 CMD 52.
+ The code should look like #if 0'ed code below. After writing
+ NMI_VMM_TBL_CTL, then CSA address is now NMI_VMM_TBL_CTL+4,
+ then the least significant byte of the CSA address should
+ be changed to 0.
+ **/
+
+ data = 1;
+ /**
+ set the AHB address
+ **/
+ if (!sdio_set_func0_csa_address_byte0(NMI_VMM_CORE_CTL))
+ goto _fail_;
+
+ cmd.read_write = 1;
+ cmd.function = 0;
+ cmd.address = 0x10f;
+ cmd.block_mode = 0;
+ cmd.increment = 1;
+ cmd.count = 4;
+ cmd.block_size = g_sdio.block_size; //johnny : prevent it from setting unexpected value
+ cmd.buffer = (uint8_t *)&data;
+ if (!g_sdio.sdio_cmd53(&cmd)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed cmd53, write NMI_VMM_CORE_CTL...\n");
+ goto _fail_;
+ }
+ }
+ }
+ }
+
+ return 1;
+_fail_:
+ return 0;
+}
+
+static int sdio_sync_ext(int nint /* how mant interrupts to enable. */)
+{
+ uint32_t reg;
+
+
+ if(nint > MAX_NUM_INT) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Too many interupts (%d)...\n", nint);
+ return 0;
+ }
+ if(g_sdio.has_thrpt_enh2) {
+ if(nint > 5) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Error: Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
+ return 0;
+ }
+ }
+
+ g_sdio.nint = nint;
+
+ /**
+ Disable power sequencer
+ **/
+ if (!sdio_read_reg(NMI_MISC, &reg)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed read misc reg...\n");
+ return 0;
+ }
+
+ reg &= ~(1 << 8);
+ if (!sdio_write_reg(NMI_MISC, reg)) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed write misc reg...\n");
+ return 0;
+ }
+
+#ifdef NMI_SDIO_IRQ_GPIO
+ {
+ uint32_t reg;
+ int ret, i;
+
+
+ /**
+ interrupt pin mux select
+ **/
+ ret = sdio_read_reg(NMI_PIN_MUX_0, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed read reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+ reg |= (1<<8);
+ ret = sdio_write_reg(NMI_PIN_MUX_0, reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed write reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+
+ /**
+ interrupt enable
+ **/
+ ret = sdio_read_reg(NMI_INTR_ENABLE, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed read reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+
+ for(i=0; (i < 5) && (nint > 0); i++, nint--) {
+ reg |= (1 << (27+i));
+ }
+ ret = sdio_write_reg(NMI_INTR_ENABLE, reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed write reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+ if(nint) {
+ ret = sdio_read_reg(NMI_INTR2_ENABLE, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed read reg (%08x)...\n", NMI_INTR2_ENABLE);
+ return 0;
+ }
+
+ for(i=0; (i < 3) && (nint > 0); i++, nint--) {
+ reg |= (1 << i);
+ }
+
+ ret = sdio_read_reg(NMI_INTR2_ENABLE, &reg);
+ if (!ret) {
+ g_sdio.dPrint(N_ERR, "[nmi sdio]: Failed write reg (%08x)...\n", NMI_INTR2_ENABLE);
+ return 0;
+ }
+ }
+ }
+#endif /* NMI_SDIO_IRQ_GPIO */
+ return 1;
+}
+
+#endif /* DMA_VER == DMA_VER_2 */
+/********************************************
+
+ Global sdio HIF function table
+
+********************************************/
+
+nmi_hif_func_t hif_sdio = {
+ sdio_init,
+ sdio_deinit,
+ sdio_read_reg,
+ sdio_write_reg,
+ sdio_read,
+ sdio_write,
+ sdio_sync,
+ sdio_clear_int,
+#if DMA_VER == DMA_VER_2
+ sdio_read_int,
+ sdio_clear_int_ext,
+ sdio_read_size,
+ sdio_write_ext,
+ sdio_read_ext,
+ sdio_sync_ext,
+#endif /* DMA_VER == DMA_VER_2 */
+ sdio_set_max_speed,
+ sdio_set_default_speed,
+};
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_spi.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_spi.c
new file mode 100755
index 00000000..e8345de7
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_spi.c
@@ -0,0 +1,1466 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_spi.c
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+
+extern unsigned int int_clrd;
+
+/*
+#include <linux/kernel.h>
+#include <linux/string.h>
+*/
+typedef struct {
+ void *os_context;
+ int (*spi_tx)(uint8_t *, uint32_t);
+ int (*spi_rx)(uint8_t *, uint32_t);
+ int (*spi_trx)(uint8_t *, uint8_t *, uint32_t);
+ int (*spi_max_speed)(void);
+ nmi_debug_func dPrint;
+ int crc_off;
+#if DMA_VER == DMA_VER_2
+ int nint;
+ int has_thrpt_enh;
+#endif
+} nmi_spi_t;
+
+static nmi_spi_t g_spi;
+
+static int spi_read(uint32_t, uint8_t *, uint32_t);
+static int spi_write(uint32_t, uint8_t *, uint32_t);
+
+/********************************************
+
+ Crc7
+
+********************************************/
+
+static const uint8_t crc7_syndrome_table[256] = {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
+ 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
+ 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
+ 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
+ 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
+ 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
+ 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
+ 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
+ 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
+ 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
+ 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
+ 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
+ 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
+ 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
+ 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+};
+
+static uint8_t crc7_byte(uint8_t crc, uint8_t data)
+{
+ return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+static uint8_t crc7(uint8_t crc, const uint8_t *buffer, uint32_t len)
+{
+ while (len--)
+ crc = crc7_byte(crc, *buffer++);
+ return crc;
+}
+
+/********************************************
+
+ Spi protocol Function
+
+********************************************/
+
+#define CMD_DMA_WRITE 0xc1
+#define CMD_DMA_READ 0xc2
+#define CMD_INTERNAL_WRITE 0xc3
+#define CMD_INTERNAL_READ 0xc4
+#define CMD_TERMINATE 0xc5
+#define CMD_REPEAT 0xc6
+#define CMD_DMA_EXT_WRITE 0xc7
+#define CMD_DMA_EXT_READ 0xc8
+#define CMD_SINGLE_WRITE 0xc9
+#define CMD_SINGLE_READ 0xca
+#define CMD_RESET 0xcf
+
+#define N_OK 1
+#define N_FAIL 0
+#define N_RESET -1
+#define N_RETRY -2
+
+#define DATA_PKT_SZ_256 256
+#define DATA_PKT_SZ_512 512
+#define DATA_PKT_SZ_1K 1024
+#define DATA_PKT_SZ_4K (4 * 1024)
+#define DATA_PKT_SZ_8K (8 * 1024)
+#define DATA_PKT_SZ DATA_PKT_SZ_8K
+
+static int spi_cmd(uint8_t cmd, uint32_t adr, uint32_t data, uint32_t sz, uint8_t clockless)
+{
+ uint8_t bc[9];
+ int len = 5;
+ int result = N_OK;
+
+ bc[0] = cmd;
+ switch (cmd) {
+ case CMD_SINGLE_READ: /* single word (4 bytes) read */
+ bc[1] = (uint8_t)(adr >> 16);
+ bc[2] = (uint8_t)(adr >> 8);
+ bc[3] = (uint8_t)adr;
+ len = 5;
+ break;
+ case CMD_INTERNAL_READ: /* internal register read */
+ bc[1] = (uint8_t)(adr >> 8);
+ if(clockless) bc[1] |= (1 << 7);
+ bc[2] = (uint8_t)adr;
+ bc[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_TERMINATE: /* termination */
+ bc[1] = 0x00;
+ bc[2] = 0x00;
+ bc[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_REPEAT: /* repeat */
+ bc[1] = 0x00;
+ bc[2] = 0x00;
+ bc[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_RESET: /* reset */
+ bc[1] = 0xff;
+ bc[2] = 0xff;
+ bc[3] = 0xff;
+ len = 5;
+ break;
+ case CMD_DMA_WRITE: /* dma write */
+ case CMD_DMA_READ: /* dma read */
+ bc[1] = (uint8_t)(adr >> 16);
+ bc[2] = (uint8_t)(adr >> 8);
+ bc[3] = (uint8_t)adr;
+ bc[4] = (uint8_t)(sz >> 8);
+ bc[5] = (uint8_t)(sz);
+ len = 7;
+ break;
+ case CMD_DMA_EXT_WRITE: /* dma extended write */
+ case CMD_DMA_EXT_READ: /* dma extended read */
+ bc[1] = (uint8_t)(adr >> 16);
+ bc[2] = (uint8_t)(adr >> 8);
+ bc[3] = (uint8_t)adr;
+ bc[4] = (uint8_t)(sz >> 16);
+ bc[5] = (uint8_t)(sz >> 8);
+ bc[6] = (uint8_t)(sz);
+ len = 8;
+ break;
+ case CMD_INTERNAL_WRITE: /* internal register write */
+ bc[1] = (uint8_t)(adr >> 8);
+ if(clockless) bc[1] |= (1 << 7);
+ bc[2] = (uint8_t)(adr);
+ bc[3] = (uint8_t)(data >> 24);
+ bc[4] = (uint8_t)(data >> 16);
+ bc[5] = (uint8_t)(data >> 8);
+ bc[6] = (uint8_t)(data);
+ len = 8;
+ break;
+ case CMD_SINGLE_WRITE: /* single word write */
+ bc[1] = (uint8_t)(adr >> 16);
+ bc[2] = (uint8_t)(adr >> 8);
+ bc[3] = (uint8_t)(adr);
+ bc[4] = (uint8_t)(data >> 24);
+ bc[5] = (uint8_t)(data >> 16);
+ bc[6] = (uint8_t)(data >> 8);
+ bc[7] = (uint8_t)(data);
+ len = 9;
+ break;
+ default:
+ result = N_FAIL;
+ break;
+ }
+
+ if (result) {
+ if (!g_spi.crc_off)
+ bc[len-1] = (crc7(0x7f, (const uint8_t *)&bc[0], len-1)) << 1;
+ else
+ len-=1;
+
+ if (!g_spi.spi_tx(bc, len)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd write, bus error...\n");
+ result = N_FAIL;
+ }
+ }
+
+ return result;
+}
+
+static int spi_cmd_rsp(uint8_t cmd)
+{
+ uint8_t rsp;
+ int result = N_OK;
+
+ /**
+ Command/Control response
+ **/
+ if ((cmd == CMD_RESET) ||
+ (cmd == CMD_TERMINATE) ||
+ (cmd == CMD_REPEAT)) {
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ result = N_FAIL;
+ goto _fail_;
+ }
+ }
+
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response read, bus error...\n");
+ result = N_FAIL;
+ goto _fail_;
+ }
+
+ if (rsp != cmd) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response, cmd (%02x), resp (%02x)\n", cmd, rsp);
+ result = N_FAIL;
+ goto _fail_;
+ }
+
+ /**
+ State response
+ **/
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd state read, bus error...\n");
+ result = N_FAIL;
+ goto _fail_;
+ }
+
+ if (rsp != 0x00) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd state response state (%02x)\n", rsp);
+ result = N_FAIL;
+ }
+
+_fail_:
+
+ return result;
+}
+
+static int spi_cmd_complete(uint8_t cmd, uint32_t adr, uint8_t *b, uint32_t sz, uint8_t clockless)
+{
+ uint8_t wb[32], rb[32];
+ uint8_t wix, rix;
+ uint32_t len2;
+ uint8_t rsp;
+ int len = 0;
+ int result = N_OK;
+
+ wb[0] = cmd;
+ switch (cmd) {
+ case CMD_SINGLE_READ: /* single word (4 bytes) read */
+ wb[1] = (uint8_t)(adr >> 16);
+ wb[2] = (uint8_t)(adr >> 8);
+ wb[3] = (uint8_t)adr;
+ len = 5;
+ break;
+ case CMD_INTERNAL_READ: /* internal register read */
+ wb[1] = (uint8_t)(adr >> 8);
+ if(clockless == 1) wb[1] |= (1 << 7);
+ wb[2] = (uint8_t)adr;
+ wb[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_TERMINATE: /* termination */
+ wb[1] = 0x00;
+ wb[2] = 0x00;
+ wb[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_REPEAT: /* repeat */
+ wb[1] = 0x00;
+ wb[2] = 0x00;
+ wb[3] = 0x00;
+ len = 5;
+ break;
+ case CMD_RESET: /* reset */
+ wb[1] = 0xff;
+ wb[2] = 0xff;
+ wb[3] = 0xff;
+ len = 5;
+ break;
+ case CMD_DMA_WRITE: /* dma write */
+ case CMD_DMA_READ: /* dma read */
+ wb[1] = (uint8_t)(adr >> 16);
+ wb[2] = (uint8_t)(adr >> 8);
+ wb[3] = (uint8_t)adr;
+ wb[4] = (uint8_t)(sz >> 8);
+ wb[5] = (uint8_t)(sz);
+ len = 7;
+ break;
+ case CMD_DMA_EXT_WRITE: /* dma extended write */
+ case CMD_DMA_EXT_READ: /* dma extended read */
+ wb[1] = (uint8_t)(adr >> 16);
+ wb[2] = (uint8_t)(adr >> 8);
+ wb[3] = (uint8_t)adr;
+ wb[4] = (uint8_t)(sz >> 16);
+ wb[5] = (uint8_t)(sz >> 8);
+ wb[6] = (uint8_t)(sz);
+ len = 8;
+ break;
+ case CMD_INTERNAL_WRITE: /* internal register write */
+ wb[1] = (uint8_t)(adr >> 8);
+ if(clockless == 1) wb[1] |= (1 << 7);
+ wb[2] = (uint8_t)(adr);
+ wb[3] = b[3];
+ wb[4] = b[2];
+ wb[5] = b[1];
+ wb[6] = b[0];
+ len = 8;
+ break;
+ case CMD_SINGLE_WRITE: /* single word write */
+ wb[1] = (uint8_t)(adr >> 16);
+ wb[2] = (uint8_t)(adr >> 8);
+ wb[3] = (uint8_t)(adr);
+ wb[4] = b[3];
+ wb[5] = b[2];
+ wb[6] = b[1];
+ wb[7] = b[0];
+ len = 9;
+ break;
+ default:
+ result = N_FAIL;
+ break;
+ }
+
+ if (result != N_OK) {
+ return result;
+ }
+
+ if (!g_spi.crc_off) {
+ wb[len-1] = (crc7(0x7f, (const uint8_t *)&wb[0], len-1)) << 1;
+ } else {
+ len -=1;
+ }
+
+#define NUM_SKIP_BYTES (1)
+#define NUM_RSP_BYTES (2)
+#define NUM_DATA_HDR_BYTES (1)
+#define NUM_DATA_BYTES (4)
+#define NUM_CRC_BYTES (2)
+#define NUM_DUMMY_BYTES (3)
+ if ((cmd == CMD_RESET) ||
+ (cmd == CMD_TERMINATE) ||
+ (cmd == CMD_REPEAT)) {
+ len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES);
+ } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
+ if (!g_spi.crc_off) {
+ len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
+ + NUM_CRC_BYTES + NUM_DUMMY_BYTES);
+ } else {
+ len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES
+ + NUM_DUMMY_BYTES);
+ }
+ } else {
+ len2 = len + (NUM_RSP_BYTES + NUM_DUMMY_BYTES);
+ }
+#undef NUM_DUMMY_BYTES
+
+ if(len2 > (sizeof(wb)/sizeof(wb[0]))) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: spi buffer size too small (%d) (%d)\n",
+ len2, (sizeof(wb)/sizeof(wb[0])));
+ result = N_FAIL;
+ return result;
+ }
+ /* zero spi write buffers. */
+ for(wix = len; wix< len2; wix++) {
+ wb[wix] = 0;
+ }
+ rix = len;
+
+ if (!g_spi.spi_trx(wb, rb, len2)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd write, bus error...\n");
+ result = N_FAIL;
+ return result;
+ }
+
+#if 0
+ {
+ int jj;
+ printk("--- cnd = %x, len=%d, len2=%d\n", cmd, len, len2);
+ for(jj=0; jj<sizeof(wb)/sizeof(wb[0]); jj++) {
+
+ if(jj >= len2) break;
+ if(((jj+1)%16) != 0) {
+ if((jj%16) == 0) {
+ printk("wb[%02x]: %02x ", jj, wb[jj]);
+ } else {
+ printk("%02x ", wb[jj]);
+ }
+ } else {
+ printk("%02x\n", wb[jj]);
+ }
+ }
+ printk("\n");
+
+ for(jj=0; jj<sizeof(rb)/sizeof(rb[0]); jj++) {
+
+ if(jj >= len2) break;
+ if(((jj+1)%16) != 0) {
+ if((jj%16) == 0) {
+ printk("rb[%02x]: %02x ", jj, rb[jj]);
+ } else {
+ printk("%02x ", rb[jj]);
+ }
+ } else {
+ printk("%02x\n", rb[jj]);
+ }
+ }
+ printk("\n");
+ }
+#endif
+
+ /**
+ Command/Control response
+ **/
+ if ((cmd == CMD_RESET) ||
+ (cmd == CMD_TERMINATE) ||
+ (cmd == CMD_REPEAT)) {
+ rix++; /* skip 1 byte */
+ }
+
+ //do {
+ rsp = rb[rix++];
+ // if(rsp == cmd) break;
+ //} while(&rptr[1] <= &rb[len2]);
+
+ if (rsp != cmd) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response, cmd (%02x)"
+ ", resp (%02x)\n", cmd, rsp);
+ result = N_FAIL;
+ return result;
+ }
+
+ /**
+ State response
+ **/
+ rsp = rb[rix++];
+ if (rsp != 0x00) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd state response "
+ "state (%02x)\n", rsp);
+ result = N_FAIL;
+ return result;
+ }
+
+ if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
+ || (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
+ int retry;
+ //uint16_t crc1, crc2;
+ uint8_t crc[2];
+ /**
+ Data Respnose header
+ **/
+ retry = 100;
+ do {
+ /* ensure there is room in buffer later to read data and crc */
+ if(rix < len2) {
+ rsp = rb[rix++];
+ } else {
+ retry = 0;
+ break;
+ }
+ if (((rsp >> 4) & 0xf) == 0xf)
+ break;
+ } while (retry--);
+
+ if (retry <= 0) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Error, data read "
+ "response (%02x)\n", rsp);
+ result = N_RESET;
+ return result;
+ }
+
+ if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
+ /**
+ Read bytes
+ **/
+ if((rix+3) < len2) {
+ b[0] = rb[rix++];
+ b[1] = rb[rix++];
+ b[2] = rb[rix++];
+ b[3] = rb[rix++];
+ } else {
+ g_spi.dPrint(N_ERR, "[nmi spi]: buffer overrun when reading data.\n");
+ result = N_FAIL;
+ return result;
+ }
+
+ if (!g_spi.crc_off) {
+ /**
+ Read Crc
+ **/
+ if((rix+1) < len2) {
+ crc[0] = rb[rix++];
+ crc[1] = rb[rix++];
+ } else {
+ g_spi.dPrint(N_ERR, "[nmi spi]: buffer overrun when reading crc.\n");
+ result = N_FAIL;
+ return result;
+ }
+ }
+ } else if((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
+ int ix;
+
+ /* some data may be read in response to dummy bytes. */
+ for(ix=0; (rix < len2) && (ix < sz);) {
+ b[ix++] = rb[rix++];
+ }
+#if 0
+ if(ix) printk("ttt %d %d\n", sz, ix);
+#endif
+ sz -= ix;
+
+ if(sz > 0) {
+ int nbytes;
+
+ if (sz <= (DATA_PKT_SZ-ix)) {
+ nbytes = sz;
+ } else {
+ nbytes = DATA_PKT_SZ-ix;
+ }
+
+ /**
+ Read bytes
+ **/
+ if (!g_spi.spi_rx(&b[ix], nbytes)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block read, bus error...\n");
+ result = N_FAIL;
+ goto _error_;
+ }
+
+ /**
+ Read Crc
+ **/
+ if (!g_spi.crc_off) {
+ if (!g_spi.spi_rx(crc, 2)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block crc read, bus error...\n");
+ result = N_FAIL;
+ goto _error_;
+ }
+ }
+
+
+ ix += nbytes;
+ sz -= nbytes;
+ }
+
+ /* if any data in left unread, then read the rest using normal DMA code.*/
+ while(sz > 0) {
+ int nbytes;
+
+#if 0
+ printk("rrr %d %d\n", sz, ix);
+#endif
+ if (sz <= DATA_PKT_SZ) {
+ nbytes = sz;
+ } else {
+ nbytes = DATA_PKT_SZ;
+ }
+
+ /**
+ read data response only on the next DMA cycles not
+ the first DMA since data response header is already
+ handled above for the first DMA.
+ **/
+ /**
+ Data Respnose header
+ **/
+ retry = 10;
+ do {
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data response read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+ if (((rsp >> 4) & 0xf) == 0xf)
+ break;
+ } while (retry--);
+
+ if (result == N_FAIL)
+ break;
+
+
+ /**
+ Read bytes
+ **/
+ if (!g_spi.spi_rx(&b[ix], nbytes)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+
+ /**
+ Read Crc
+ **/
+ if (!g_spi.crc_off) {
+ if (!g_spi.spi_rx(crc, 2)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block crc read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+ }
+
+ ix += nbytes;
+ sz -= nbytes;
+ }
+ }
+ }
+_error_:
+ return result;
+}
+
+static int spi_data_read(uint8_t *b, uint32_t sz)
+{
+ int retry, ix, nbytes;
+ int result = N_OK;
+ uint8_t crc[2];
+ uint8_t rsp;
+
+ /**
+ Data
+ **/
+ ix = 0;
+ do {
+ if (sz <= DATA_PKT_SZ)
+ nbytes = sz;
+ else
+ nbytes = DATA_PKT_SZ;
+
+ /**
+ Data Respnose header
+ **/
+ retry = 10;
+ do {
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data response read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+ if (((rsp >> 4) & 0xf) == 0xf)
+ break;
+ } while (retry--);
+
+ if (result == N_FAIL)
+ break;
+
+ if (retry <= 0) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data response read...(%02x)\n", rsp);
+ result = N_FAIL;
+ break;
+ }
+
+ /**
+ Read bytes
+ **/
+ if (!g_spi.spi_rx(&b[ix], nbytes)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+
+ /**
+ Read Crc
+ **/
+ if (!g_spi.crc_off) {
+ if (!g_spi.spi_rx(crc, 2)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block crc read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+ }
+
+ ix += nbytes;
+ sz -= nbytes;
+
+ } while (sz);
+
+ return result;
+}
+
+static int spi_data_write(uint8_t *b, uint32_t sz)
+{
+ int ix, nbytes;
+ int result = 1;
+ uint8_t cmd, order, crc[2] = {0};
+ //uint8_t rsp;
+
+ /**
+ Data
+ **/
+ ix = 0;
+ do {
+ if (sz <= DATA_PKT_SZ)
+ nbytes = sz;
+ else
+ nbytes = DATA_PKT_SZ;
+
+ /**
+ Write command
+ **/
+ cmd = 0xf0;
+ if (ix == 0) {
+ if (sz <= DATA_PKT_SZ)
+
+ order = 0x3;
+ else
+ order = 0x1;
+ } else {
+ if (sz <= DATA_PKT_SZ)
+ order = 0x3;
+ else
+ order = 0x2;
+ }
+ cmd |= order;
+ if (!g_spi.spi_tx(&cmd, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block cmd write, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+
+ /**
+ Write data
+ **/
+ if (!g_spi.spi_tx(&b[ix], nbytes)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block write, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+
+ /**
+ Write Crc
+ **/
+ if (!g_spi.crc_off) {
+ if (!g_spi.spi_tx(crc, 2)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block crc write, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+ }
+
+ /**
+ No need to wait for response
+ **/
+#if 0
+ /**
+ Respnose
+ **/
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block write, response read, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+
+ if (((rsp >> 4) & 0xf) != 0xc) {
+ result = N_FAIL;
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block write response...(%02x)\n", rsp);
+ break;
+ }
+
+ /**
+ State
+ **/
+ if (!g_spi.spi_rx(&rsp, 1)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data block write, read state, bus error...\n");
+ result = N_FAIL;
+ break;
+ }
+#endif
+
+ ix += nbytes;
+ sz -= nbytes;
+ } while (sz);
+
+
+ return result;
+}
+
+/********************************************
+
+ Spi Internal Read/Write Function
+
+********************************************/
+
+static int spi_internal_write(uint32_t adr, uint32_t dat)
+{
+ int result;
+
+#if defined USE_OLD_SPI_SW
+ /**
+ Command
+ **/
+ result = spi_cmd(CMD_INTERNAL_WRITE, adr, dat, 4,0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal write cmd...\n");
+ return 0;
+ }
+
+ result = spi_cmd_rsp(CMD_INTERNAL_WRITE,0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal write cmd response...\n");
+ }
+#else
+
+#ifdef BIG_ENDIAN
+ dat = BYTE_SWAP(dat);
+#endif
+ result = spi_cmd_complete(CMD_INTERNAL_WRITE, adr, (uint8_t*)&dat, 4,0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal write cmd...\n");
+ }
+
+#endif
+ return result;
+}
+
+static int spi_internal_read(uint32_t adr, uint32_t *data)
+{
+ int result;
+
+#if defined USE_OLD_SPI_SW
+ result = spi_cmd(CMD_INTERNAL_READ, adr, 0, 4, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read cmd...\n");
+ return 0;
+ }
+
+ result = spi_cmd_rsp(CMD_INTERNAL_READ, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read cmd response...\n");
+ return 0;
+ }
+
+ /**
+ Data
+ **/
+ result = spi_data_read((uint8_t *)data, 4);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read data...\n");
+ return 0;
+ }
+#else
+ result = spi_cmd_complete(CMD_INTERNAL_READ, adr, (uint8_t*)data, 4, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read cmd...\n");
+ return 0;
+ }
+#endif
+
+
+#ifdef BIG_ENDIAN
+ *data = BYTE_SWAP(*data);
+#endif
+
+ return 1;
+}
+
+/********************************************
+
+ Spi interfaces
+
+********************************************/
+
+static int spi_write_reg(uint32_t addr, uint32_t data)
+{
+ int result = N_OK;
+ uint8_t cmd = CMD_SINGLE_WRITE;
+ uint8_t clockless = 0;
+
+
+#if defined USE_OLD_SPI_SW
+ {
+ result = spi_cmd(cmd, addr, data, 4, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
+ return 0;
+ }
+
+ result = spi_cmd_rsp(cmd, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response, write reg (%08x)...\n", addr);
+ return 0;
+ }
+
+ return 1;
+ }
+#else
+#ifdef BIG_ENDIAN
+ data= BYTE_SWAP(data);
+#endif
+ if(addr < 0x30)
+ {
+ /* Clockless register*/
+ cmd = CMD_INTERNAL_WRITE;
+ clockless = 1;
+ }
+
+ result = spi_cmd_complete(cmd, addr, (uint8_t*)&data, 4, clockless);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, write reg (%08x)...\n", addr);
+ }
+
+ return result;
+#endif
+
+}
+
+static int spi_write(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ int result;
+ uint8_t cmd = CMD_DMA_EXT_WRITE;
+
+ /**
+ has to be greated than 4
+ **/
+ if (size <= 4)
+ return 0;
+
+#if defined USE_OLD_SPI_SW
+ /**
+ Command
+ **/
+ result = spi_cmd(cmd, addr, 0, size, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
+ return 0;
+ }
+
+ result = spi_cmd_rsp(cmd, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi ]: Failed cmd response, write block (%08x)...\n", addr);
+ return 0;
+ }
+#else
+ result = spi_cmd_complete(cmd, addr, NULL, size, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, write block (%08x)...\n", addr);
+ return 0;
+ }
+#endif
+
+ /**
+ Data
+ **/
+ result = spi_data_write(buf, size);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed block data write...\n");
+ }
+
+ return 1;
+}
+
+static int spi_read_reg(uint32_t addr, uint32_t *data)
+{
+ int result = N_OK;
+ uint8_t cmd = CMD_SINGLE_READ;
+ uint8_t clockless = 0;
+
+#if defined USE_OLD_SPI_SW
+ result = spi_cmd(cmd, addr, 0, 4, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
+ return 0;
+ }
+ result = spi_cmd_rsp(cmd, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response, read reg (%08x)...\n", addr);
+ return 0;
+ }
+
+ result = spi_data_read((uint8_t *)data, 4);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed data read...\n");
+ return 0;
+ }
+#else
+ if(addr < 0x30)
+ {
+ //g_spi.dPrint(N_ERR,"***** read addr %d\n\n", addr);
+ /* Clockless register*/
+ cmd = CMD_INTERNAL_READ;
+ clockless = 1;
+ }
+
+ result = spi_cmd_complete(cmd, addr, (uint8_t*)data, 4, clockless);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, read reg (%08x)...\n", addr);
+ return 0;
+ }
+#endif
+
+
+#ifdef BIG_ENDIAN
+ *data = BYTE_SWAP(*data);
+#endif
+
+ return 1;
+}
+
+static int spi_read(uint32_t addr, uint8_t *buf, uint32_t size)
+{
+ uint8_t cmd = CMD_DMA_EXT_READ;
+ int result;
+
+ if (size <= 4)
+ return 0;
+
+#if defined USE_OLD_SPI_SW
+ /**
+ Command
+ **/
+ result = spi_cmd(cmd, addr, 0, size, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
+ return 0;
+ }
+
+ result = spi_cmd_rsp(cmd, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd response, read block (%08x)...\n", addr);
+ return 0;
+ }
+
+ /**
+ Data
+ **/
+ result = spi_data_read(buf, size);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed block data read...\n");
+ return 0;
+ }
+#else
+ result = spi_cmd_complete(cmd, addr, buf, size, 0);
+ if (result != N_OK) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed cmd, read block (%08x)...\n", addr);
+ return 0;
+ }
+#endif
+
+
+ return 1;
+}
+
+/********************************************
+
+ Bus interfaces
+
+********************************************/
+
+static int spi_clear_int(void)
+{
+ uint32_t reg;
+ if (!spi_read_reg(NMI_HOST_RX_CTRL_0, &reg)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_HOST_RX_CTRL_0);
+ return 0;
+ }
+ reg &= ~0x1;
+ spi_write_reg(NMI_HOST_RX_CTRL_0, reg);
+ int_clrd++;
+ return 1;
+}
+
+static int spi_deinit(void *pv)
+{
+ /**
+ TODO:
+ **/
+ return 1;
+}
+
+static int spi_sync(void)
+{
+ uint32_t reg;
+ int ret;
+
+ /**
+ interrupt pin mux select
+ **/
+ ret = spi_read_reg(NMI_PIN_MUX_0, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+ reg |= (1<<8);
+ ret = spi_write_reg(NMI_PIN_MUX_0, reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+
+ /**
+ interrupt enable
+ **/
+ ret = spi_read_reg(NMI_INTR_ENABLE, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+ reg |= (1<<16);
+ ret = spi_write_reg(NMI_INTR_ENABLE, reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int spi_init(nmi_wlan_inp_t *inp, nmi_debug_func func)
+{
+ uint32_t reg;
+ uint32_t chipid;
+
+ static int isinit = 0;
+
+ if(isinit) {
+
+ if (!spi_read_reg(0x1000, &chipid)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Fail cmd read chip id...\n");
+ return 0;
+ }
+ return 1;
+ }
+
+ memset(&g_spi, 0, sizeof(nmi_spi_t));
+
+ g_spi.dPrint = func;
+ g_spi.os_context = inp->os_context.os_private;
+ if (inp->io_func.io_init) {
+ if (!inp->io_func.io_init(g_spi.os_context)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed io init bus...\n");
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ g_spi.spi_tx = inp->io_func.u.spi.spi_tx;
+ g_spi.spi_rx = inp->io_func.u.spi.spi_rx;
+ g_spi.spi_trx = inp->io_func.u.spi.spi_trx;
+ g_spi.spi_max_speed = inp->io_func.u.spi.spi_max_speed;
+
+ /**
+ configure protocol
+ **/
+ g_spi.crc_off = 0;
+
+ // TODO: We can remove the CRC trials if there is a definite way to reset
+ // the SPI to it's initial value.
+ if (!spi_internal_read(NMI_SPI_PROTOCOL_OFFSET, &reg)) {
+ /* Read failed. Try with CRC off. This might happen when module
+ is removed but chip isn't reset*/
+ g_spi.crc_off = 1;
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read protocol with CRC on, retyring with CRC off...\n", __LINE__);
+ if (!spi_internal_read(NMI_SPI_PROTOCOL_OFFSET, &reg)){
+ // Reaad failed with both CRC on and off, something went bad
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed internal read protocol...\n", __LINE__);
+ return 0;
+ }
+ }
+ if(g_spi.crc_off == 0)
+ {
+ reg &= ~0xc; /* disable crc checking */
+ reg &= ~0x70;
+ reg |= (0x5 << 4);
+ if (!spi_internal_write(NMI_SPI_PROTOCOL_OFFSET, reg)) {
+ g_spi.dPrint(N_ERR, "[nmi spi %d]: Failed internal write protocol reg...\n", __LINE__);
+ return 0;
+ }
+ g_spi.crc_off = 1;
+ }
+
+
+ /**
+ make sure can read back chip id correctly
+ **/
+ if (!spi_read_reg(0x1000, &chipid)) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Fail cmd read chip id...\n");
+ return 0;
+ }
+ //g_spi.dPrint(N_INIT, "[nmi spi]: chipid (%08x)\n", chipid);
+
+#if DMA_VER == DMA_VER_2
+ if( (chipid & 0xfff) > 0x0d0) {
+ g_spi.has_thrpt_enh = 1;
+ } else {
+ g_spi.has_thrpt_enh = 0;
+ }
+ g_spi.dPrint(N_ERR, "[nmi spi]: has_thrpt_enh = %d...\n", g_spi.has_thrpt_enh);
+#endif
+
+ isinit = 1;
+
+ return 1;
+}
+
+static void spi_max_bus_speed(void)
+{
+ g_spi.spi_max_speed();
+}
+
+static void spi_default_bus_speed(void)
+{
+}
+
+#if DMA_VER == DMA_VER_2
+
+static int spi_read_size(uint32_t * size)
+{
+ int ret;
+ if(g_spi.has_thrpt_enh) {
+ ret = spi_internal_read(0xe840-NMI_SPI_REG_BASE, size);
+ *size = *size & IRQ_DMA_WD_CNT_MASK;
+ } else {
+ uint32_t tmp;
+ uint32_t byte_cnt;
+
+ if(!(ret = spi_read_reg(NMI_VMM_TO_HOST_SIZE, &byte_cnt))) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read NMI_VMM_TO_HOST_SIZE ...\n");
+ goto _fail_;
+ }
+ tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
+ * size=tmp;
+ }
+
+
+
+_fail_:
+ return ret;
+}
+
+
+
+static int spi_read_int(uint32_t * int_status)
+{
+ int ret;
+ if(g_spi.has_thrpt_enh) {
+ ret = spi_internal_read(0xe840-NMI_SPI_REG_BASE, int_status);
+ } else {
+ uint32_t tmp;
+ uint32_t byte_cnt;
+
+ if(!(ret = spi_read_reg(NMI_VMM_TO_HOST_SIZE, &byte_cnt))) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read NMI_VMM_TO_HOST_SIZE ...\n");
+ goto _fail_;
+ }
+ tmp = (byte_cnt >> 2) & IRQ_DMA_WD_CNT_MASK;
+
+ {
+ int happended, j;
+
+ j = 0;
+ do {
+ uint32_t irq_flags;
+
+ happended = 0;
+
+ spi_read_reg(0x1a90, &irq_flags);
+ tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET);
+
+ if(g_spi.nint > 5) {
+ spi_read_reg(0x1a94, &irq_flags);
+ tmp |= (((irq_flags >> 0) & 0x7) << (IRG_FLAGS_OFFSET+5));
+ }
+
+ {
+ uint32_t unkmown_mask;
+
+ unkmown_mask = ~((1ul << g_spi.nint) - 1);
+
+ if( (tmp >> IRG_FLAGS_OFFSET) & unkmown_mask) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Unexpected interrupt (2): j=%d, tmp=%x, mask=%x\n", j, tmp, unkmown_mask);
+ happended = 1;
+ }
+ }
+ j++;
+ } while(happended);
+ }
+
+ *int_status = tmp;
+
+ }
+
+ //printk("int_status = %x\n", *int_status);
+
+_fail_:
+ return ret;
+}
+
+static int spi_clear_int_ext(uint32_t val)
+{
+ int ret;
+
+ //printk("spi_clear_int_ext = %x\n", val);
+
+ if(g_spi.has_thrpt_enh) {
+ ret = spi_internal_write(0xe844-NMI_SPI_REG_BASE, val);
+ } else {
+ uint32_t flags;
+ flags = val & ((1 << MAX_NUM_INT) - 1);
+ if(flags) {
+ int i;
+
+ ret = 1;
+ for(i=0; i<g_spi.nint; i++) {
+ /* No matter what you write 1 or 0, it will clear interrupt. */
+ if(flags & 1) ret = spi_write_reg(0x10c8+i*4, 1);
+ if(!ret) break;
+ flags >>= 1;
+ }
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed spi_write_reg, set reg %x ...\n", 0x10c8+i*4);
+ goto _fail_;
+ }
+ for(i=g_spi.nint; i<MAX_NUM_INT; i++) {
+ if(flags & 1) g_spi.dPrint(N_ERR, "[nmi spi]: Unexpected interrupt cleared %d...\n", i);
+ flags >>= 1;
+ }
+ }
+
+ {
+ uint32_t tbl_ctl;
+
+ tbl_ctl = 0;
+ /* select VMM table 0 */
+ if((val & SEL_VMM_TBL0) == SEL_VMM_TBL0) tbl_ctl |= (1 << 0);
+ /* select VMM table 1 */
+ if((val & SEL_VMM_TBL1) == SEL_VMM_TBL1) tbl_ctl |= (1 << 1);
+
+ ret = spi_write_reg(NMI_VMM_TBL_CTL, tbl_ctl);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: fail write reg vmm_tbl_ctl...\n");
+ goto _fail_;
+ }
+
+ if((val & EN_VMM) == EN_VMM) {
+ /**
+ enable vmm transfer.
+ **/
+ ret = spi_write_reg(NMI_VMM_CORE_CTL, 1);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: fail write reg vmm_core_ctl...\n");
+ goto _fail_;
+ }
+ }
+ }
+ }
+_fail_:
+ return ret;
+}
+
+static int spi_sync_ext(int nint /* how mant interrupts to enable. */)
+{
+ uint32_t reg;
+ int ret, i;
+
+ if(nint > MAX_NUM_INT) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Too many interupts (%d)...\n", nint);
+ return 0;
+ }
+
+ g_spi.nint = nint;
+
+ /**
+ interrupt pin mux select
+ **/
+ ret = spi_read_reg(NMI_PIN_MUX_0, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+ reg |= (1<<8);
+ ret = spi_write_reg(NMI_PIN_MUX_0, reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_PIN_MUX_0);
+ return 0;
+ }
+
+ /**
+ interrupt enable
+ **/
+ ret = spi_read_reg(NMI_INTR_ENABLE, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+
+ for(i=0; (i < 5) && (nint > 0); i++, nint--) {
+ reg |= (1 << (27+i));
+ }
+ ret = spi_write_reg(NMI_INTR_ENABLE, reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_INTR_ENABLE);
+ return 0;
+ }
+ if(nint) {
+ ret = spi_read_reg(NMI_INTR2_ENABLE, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed read reg (%08x)...\n", NMI_INTR2_ENABLE);
+ return 0;
+ }
+
+ for(i=0; (i < 3) && (nint > 0); i++, nint--) {
+ reg |= (1 << i);
+ }
+
+ ret = spi_read_reg(NMI_INTR2_ENABLE, &reg);
+ if (!ret) {
+ g_spi.dPrint(N_ERR, "[nmi spi]: Failed write reg (%08x)...\n", NMI_INTR2_ENABLE);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif /* DMA_VER == DMA_VER_2 */
+/********************************************
+
+ Global spi HIF function table
+
+********************************************/
+nmi_hif_func_t hif_spi = {
+ spi_init,
+ spi_deinit,
+ spi_read_reg,
+ spi_write_reg,
+ spi_read,
+ spi_write,
+ spi_sync,
+ spi_clear_int,
+#if DMA_VER == DMA_VER_2
+ spi_read_int,
+ spi_clear_int_ext,
+ spi_read_size,
+ spi_write,
+ spi_read,
+ spi_sync_ext,
+#endif /* DMA_VER == DMA_VER_2 */
+ spi_max_bus_speed,
+ spi_default_bus_speed,
+};
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan.c
new file mode 100755
index 00000000..856da6a5
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan.c
@@ -0,0 +1,3131 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_wlan.c
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+#define INLINE static __inline
+
+/********************************************
+
+ Global
+
+********************************************/
+extern unsigned int int_clrd;
+extern nmi_hif_func_t hif_sdio;
+extern nmi_hif_func_t hif_spi;
+extern nmi_cfg_func_t mac_cfg;
+extern void NMI_WFI_mgmt_rx(uint8_t *buff, uint32_t size);
+extern void frmw_to_linux(uint8_t *buff, uint32_t size);
+int sdio_xfer_cnt(void);
+uint32_t nmi_get_chipid(uint8_t update);
+NMI_Uint16 Set_machw_change_vir_if(NMI_Bool bValue);
+
+//static uint32_t vmm_table[NMI_VMM_TBL_SIZE];
+//static uint32_t vmm_table_rbk[NMI_VMM_TBL_SIZE];
+
+//static uint32_t vmm_table_rbk[NMI_VMM_TBL_SIZE];
+
+
+typedef struct {
+ int quit;
+
+ /**
+ input interface functions
+ **/
+ nmi_wlan_os_func_t os_func;
+ nmi_wlan_io_func_t io_func;
+ nmi_wlan_net_func_t net_func;
+ nmi_wlan_indicate_func_t indicate_func;
+
+ /**
+ host interface functions
+ **/
+ nmi_hif_func_t hif_func;
+ void *hif_lock;
+
+ /**
+ configuration interface functions
+ **/
+ nmi_cfg_func_t cif_func;
+ int cfg_frame_in_use;
+ nmi_cfg_frame_t cfg_frame;
+ uint32_t cfg_frame_offset;
+ int cfg_seq_no;
+ void *cfg_wait;
+
+ /**
+ RX buffer
+ **/
+ #ifdef MEMORY_STATIC
+ uint32_t rx_buffer_size;
+ uint8_t *rx_buffer;
+ uint32_t rx_buffer_offset;
+ #endif
+ /**
+ TX buffer
+ **/
+ uint32_t tx_buffer_size;
+ uint8_t *tx_buffer;
+ uint32_t tx_buffer_offset;
+
+ /**
+ TX queue
+ **/
+ void *txq_lock;
+
+ /*Added by Amr - BugID_4720*/
+ void *txq_add_to_head_lock;
+ void *txq_spinlock;
+ unsigned long txq_spinlock_flags;
+
+ struct txq_entry_t *txq_head;
+ struct txq_entry_t *txq_tail;
+ int txq_entries;
+ void *txq_wait;
+ int txq_exit;
+
+ /**
+ RX queue
+ **/
+ void *rxq_lock;
+ struct rxq_entry_t *rxq_head;
+ struct rxq_entry_t *rxq_tail;
+ int rxq_entries;
+ void *rxq_wait;
+ int rxq_exit;
+
+#if DMA_VER == DMA_VER_2
+ int use_dma_v2;
+#endif
+} nmi_wlan_dev_t;
+
+static uint32_t NMI_INT_STATS = 0;
+static uint32_t NMI_GP_REG_1 = 0;
+
+static nmi_wlan_dev_t g_wlan;
+
+INLINE void chip_allow_sleep(void);
+INLINE void chip_wakeup(void);
+/********************************************
+
+ Debug
+
+********************************************/
+
+static uint32_t dbgflag = N_INIT|N_ERR|N_INTR|N_TXQ|N_RXQ;
+
+static void nmi_debug(uint32_t flag, char *fmt, ...)
+{
+ char buf[256];
+ va_list args;
+ int len;
+
+ if (flag & dbgflag) {
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
+
+ if (g_wlan.os_func.os_debug)
+ g_wlan.os_func.os_debug(buf);
+ }
+
+ return;
+}
+
+static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP;
+
+/*BugID_5213*/
+/*acquire_bus() and release_bus() are made INLINE functions*/
+/*as a temporary workaround to fix a problem of receiving*/
+/*unknown interrupt from FW*/
+INLINE void acquire_bus(BUS_ACQUIRE_T acquire)
+{
+
+ g_wlan.os_func.os_enter_cs(g_wlan.hif_lock);
+ #ifndef NMI_OPTIMIZE_SLEEP_INT
+ if(genuChipPSstate != CHIP_WAKEDUP)
+ #endif
+ {
+ if(acquire == ACQUIRE_AND_WAKEUP)
+ chip_wakeup();
+ }
+
+}
+INLINE void release_bus(BUS_RELEASE_T release)
+{
+ #ifdef NMI_OPTIMIZE_SLEEP_INT
+ if(release == RELEASE_ALLOW_SLEEP)
+ chip_allow_sleep();
+ #endif
+ g_wlan.os_func.os_leave_cs(g_wlan.hif_lock);
+}
+/********************************************
+
+ Queue
+
+********************************************/
+
+static void nmi_wlan_txq_remove(struct txq_entry_t *tqe)
+{
+
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ //unsigned long flags;
+ //p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+ if (tqe==p->txq_head)
+ {
+
+ p->txq_head = tqe->next;
+ if(p->txq_head)
+ {
+ p->txq_head->prev=NULL;
+ }
+
+
+ }
+ else if(tqe==p->txq_tail)
+ {
+ p->txq_tail=(tqe->prev);
+ if(p->txq_tail)
+ {
+ p->txq_tail->next=NULL;
+ }
+ }else
+ {
+ tqe->prev->next=tqe->next;
+ tqe->next->prev=tqe->prev;
+
+ }
+ p->txq_entries-=1;
+ //p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+
+}
+
+static struct txq_entry_t *nmi_wlan_txq_remove_from_head(void)
+{
+ struct txq_entry_t * tqe;
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ unsigned long flags;
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+ if (p->txq_head)
+ {
+ //p->os_func.os_enter_cs(p->txq_lock);
+ tqe = p->txq_head;
+ p->txq_head = tqe->next;
+ if(p->txq_head)
+ {
+ p->txq_head->prev=NULL;
+ }
+ p->txq_entries-=1;
+
+ /*Added by Amr - BugID_4720*/
+
+
+ //p->os_func.os_leave_cs(p->txq_lock);
+
+ }
+ else
+ {
+ tqe = NULL;
+ }
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+ return tqe;
+}
+
+static void nmi_wlan_txq_add_to_tail(struct txq_entry_t *tqe)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ unsigned long flags;
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+// p->os_func.os_enter_cs(p->txq_lock);
+ if (p->txq_head == NULL)
+ {
+ tqe->next = NULL;
+ tqe->prev= NULL;
+ p->txq_head = tqe;
+ p->txq_tail = tqe;
+ //p->os_func.os_signal(p->txq_wait);
+ } else {
+ tqe->next = NULL;
+ tqe->prev=p->txq_tail;
+ p->txq_tail->next = tqe;
+ p->txq_tail = tqe;
+ }
+ p->txq_entries+=1;
+ PRINT_D(TX_DBG,"Number of entries in TxQ = %d\n",p->txq_entries);
+// p->os_func.os_leave_cs(p->txq_lock);
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+
+ /**
+ wake up TX queue
+ **/
+ PRINT_D(TX_DBG,"Wake the txq_handling\n");
+
+ p->os_func.os_signal(p->txq_wait);
+
+
+}
+
+static int nmi_wlan_txq_add_to_head(struct txq_entry_t *tqe)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+//printk("### nmi_wlan_txq_add_to_head() locking txq_lock\n");
+ unsigned long flags;
+ /*Added by Amr - BugID_4720*/
+ if(p->os_func.os_wait(p->txq_add_to_head_lock, CFG_PKTS_TIMEOUT))
+ return -1;
+
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+ //p->os_func.os_enter_cs(p->txq_lock);
+ if (p->txq_head == NULL) {
+ tqe->next = NULL;
+ tqe->prev= NULL;
+ p->txq_head = tqe;
+ p->txq_tail = tqe;
+ } else {
+ tqe->next = p->txq_head;
+ tqe->prev= NULL;
+ p->txq_head->prev=tqe;
+ p->txq_head = tqe;
+ }
+ p->txq_entries+=1;
+ PRINT_D(TX_DBG,"Number of entries in TxQ = %d\n",p->txq_entries);
+ //p->os_func.os_leave_cs(p->txq_lock);
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+ p->os_func.os_signal(p->txq_add_to_head_lock);
+
+
+ /**
+ wake up TX queue
+ **/
+ p->os_func.os_signal(p->txq_wait);
+ PRINT_D(TX_DBG,"Wake up the txq_handler\n");
+// complete(p->txq_wait);
+
+ /*Added by Amr - BugID_4720*/
+ return 0;
+
+}
+
+uint32_t Statisitcs_totalAcks=0,Statisitcs_DroppedAcks=0;
+
+#ifdef TCP_ACK_FILTER
+struct Ack_session_info;
+typedef struct Ack_session_info
+{
+ uint32_t Ack_seq_num;
+ uint32_t Bigger_Ack_num;
+ uint16_t src_port;
+ uint16_t dst_port;
+ uint16_t status;
+ //struct Ack_session_info * next;
+ //struct Ack_session_info * prev;
+} Ack_session_info_t;
+
+typedef struct {
+ uint32_t ack_num;
+ //uint32_t seq_num;
+ //uint16_t src_port;
+ //uint16_t dst_port;
+ //uint32_t dst_ip_addr;
+ uint32_t Session_index;
+ struct txq_entry_t * txqe;
+ //Ack_session_info * Ack_session;
+} Pending_Acks_info_t/*Ack_info_t*/;
+
+
+
+
+struct Ack_session_info * Free_head=NULL;
+struct Ack_session_info * Alloc_head=NULL;
+
+#define TCP_FIN_MASK (1<<0)
+#define TCP_SYN_MASK (1<<1)
+#define TCP_Ack_MASK (1<<4)
+#define NOT_TCP_ACK (-1)
+
+#define MAX_TCP_SESSION 25
+#define MAX_PENDING_ACKS 256
+Ack_session_info_t Acks_keep_track_info[2*MAX_TCP_SESSION];
+Pending_Acks_info_t Pending_Acks_info[MAX_PENDING_ACKS];
+
+uint32_t PendingAcks_arrBase=0;
+uint32_t Opened_TCP_session=0;
+uint32_t Pending_Acks=0;
+
+
+
+static int inline Init_TCP_tracking(void)
+{
+
+ /*uint32_t i;
+ Free_head=&Acks_keep_track_info[0];
+ i=1;
+ Acks_keep_track_info[0].next=&Acks_keep_track_info[1];
+ for(i=1<;i<MAX_TCP_SESSION-1;i++)
+ {
+ Acks_keep_track_info[i].next=&Acks_keep_track_info[i+1];
+ Acks_keep_track_info[i].prev=&Acks_keep_track_info[i-1];
+ }
+ Acks_keep_track_info[49].prev=&Acks_keep_track_info[48];
+ */
+ return 0;
+
+}
+static int inline add_TCP_track_session(uint32_t src_prt,uint32_t dst_prt,uint32_t seq)
+{
+ Acks_keep_track_info[Opened_TCP_session].Ack_seq_num=seq;
+ Acks_keep_track_info[Opened_TCP_session].Bigger_Ack_num=0;
+ Acks_keep_track_info[Opened_TCP_session].src_port=src_prt;
+ Acks_keep_track_info[Opened_TCP_session].dst_port=dst_prt;
+ Opened_TCP_session++;
+
+ PRINT_D(TCP_ENH,"TCP Session %d to Ack %d\n",Opened_TCP_session,seq);
+ return 0;
+}
+
+static int inline Update_TCP_track_session(uint32_t index,uint32_t Ack)
+{
+
+ if(Ack>Acks_keep_track_info[index].Bigger_Ack_num)
+ {
+ Acks_keep_track_info[index].Bigger_Ack_num=Ack;
+ }
+ return 0;
+
+}
+static int inline add_TCP_Pending_Ack(uint32_t Ack,uint32_t Session_index,struct txq_entry_t * txqe)
+{
+ Statisitcs_totalAcks++;
+ if(Pending_Acks<MAX_PENDING_ACKS)
+ {
+ Pending_Acks_info[PendingAcks_arrBase+Pending_Acks].ack_num=Ack;
+ Pending_Acks_info[PendingAcks_arrBase+Pending_Acks].txqe=txqe;
+ Pending_Acks_info[PendingAcks_arrBase+Pending_Acks].Session_index=Session_index;
+ txqe->tcp_PendingAck_index=PendingAcks_arrBase+Pending_Acks;
+ Pending_Acks++;
+
+ }
+ else
+ {
+
+ }
+ return 0;
+}
+static int inline remove_TCP_related(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ unsigned long flags;
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+ return 0;
+}
+
+static int inline tcp_process(struct txq_entry_t * tqe)
+{
+ int ret;
+ uint8_t *eth_hdr_ptr;
+ uint8_t * buffer=tqe->buffer;
+ unsigned short h_proto;
+ int i;
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ unsigned long flags;
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+ eth_hdr_ptr = &buffer[0];
+ h_proto = ntohs(*((unsigned short*)&eth_hdr_ptr[12]));
+ if(h_proto == 0x0800) { /* IP */
+ uint8_t * ip_hdr_ptr;
+ uint8_t protocol;
+
+ ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN];
+ protocol = ip_hdr_ptr[9];
+
+
+ if(protocol == 0x06) {
+ uint8_t * tcp_hdr_ptr;
+ uint32_t IHL,Total_Length,Data_offset;
+ tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
+ IHL=(ip_hdr_ptr[0]&0xf)<<2;
+ Total_Length=(((uint32_t)ip_hdr_ptr[2])<<8)+((uint32_t)ip_hdr_ptr[3]);
+ Data_offset=(((uint32_t)tcp_hdr_ptr[12]&0xf0)>>2);
+ if(Total_Length==(IHL+Data_offset)) /*we want to recognize the clear Acks(packet only carry Ack infos not with data) so data size must be equal zero*/
+ {
+ uint32_t seq_no,Ack_no;
+ seq_no =(((uint32_t)tcp_hdr_ptr[4])<<24)+(((uint32_t)tcp_hdr_ptr[5])<<16)+(((uint32_t)tcp_hdr_ptr[6])<<8)+((uint32_t)tcp_hdr_ptr[7]);
+
+ Ack_no =(((uint32_t)tcp_hdr_ptr[8])<<24)+(((uint32_t)tcp_hdr_ptr[9])<<16)+(((uint32_t)tcp_hdr_ptr[10])<<8)+((uint32_t)tcp_hdr_ptr[11]);
+
+
+ for(i=0;i<Opened_TCP_session;i++)
+ {
+ if(Acks_keep_track_info[i].Ack_seq_num == seq_no)
+ {
+ Update_TCP_track_session(i,Ack_no);
+ break;
+ }
+ }
+ if(i==Opened_TCP_session)
+ {
+ add_TCP_track_session( 0, 0, seq_no);
+ }
+ add_TCP_Pending_Ack(Ack_no,i,tqe);
+
+
+ }
+
+ } else {
+ ret = 0;
+ }
+ } else {
+ ret = 0;
+ }
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+ return ret;
+}
+
+
+static int nmi_wlan_txq_filter_dup_tcp_ack(void)
+{
+
+ uint32_t i=0;
+ uint32_t Dropped=0;
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+
+ p->os_func.os_spin_lock(p->txq_spinlock, &p->txq_spinlock_flags);
+ for(i=PendingAcks_arrBase;i<(PendingAcks_arrBase+Pending_Acks);i++) {
+ if(Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].Bigger_Ack_num) {
+ struct txq_entry_t *tqe;
+ PRINT_D(TCP_ENH, "DROP ACK: %u \n", Pending_Acks_info[i].ack_num);
+ tqe = Pending_Acks_info[i].txqe;
+ if(tqe)
+ {
+ nmi_wlan_txq_remove(tqe);
+ Statisitcs_DroppedAcks++;
+ tqe->status = 1; /* mark the packet send */
+ if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status);
+ p->os_func.os_free(tqe);
+ Dropped++;
+ //p->txq_entries -= 1;
+ }
+ }
+ }
+ Pending_Acks=0;
+ Opened_TCP_session=0;
+
+ if(PendingAcks_arrBase==0)
+ {
+ PendingAcks_arrBase=MAX_TCP_SESSION;
+ }else
+ {
+ PendingAcks_arrBase=0;
+ }
+
+
+ p->os_func.os_spin_unlock(p->txq_spinlock, &p->txq_spinlock_flags);
+
+ while(Dropped>0)
+ {
+ /*consume the semaphore count of the removed packet*/
+ p->os_func.os_wait(p->txq_wait,1);
+ Dropped--;
+ }
+
+ return 1;
+}
+#endif
+static int nmi_wlan_txq_add_cfg_pkt(uint8_t *buffer, uint32_t buffer_size)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+
+ PRINT_D(TX_DBG,"Adding config packet ...\n");
+ if (p->quit){
+ PRINT_D(TX_DBG,"Return due to clear function\n");
+ p->os_func.os_signal(p->cfg_wait);
+ return 0;
+ }
+
+ tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+ if (tqe == NULL){
+ PRINT_ER("Failed to allocate memory\n");
+ return 0;
+ }
+
+ tqe->type = NMI_CFG_PKT;
+ tqe->buffer = buffer;
+ tqe->buffer_size = buffer_size;
+ tqe->tx_complete_func = NULL;
+ tqe->priv = NULL;
+#ifdef TCP_ACK_FILTER
+ tqe->tcp_PendingAck_index=NOT_TCP_ACK;
+#endif
+ /**
+ Configuration packet always at the front
+ **/
+ PRINT_D(TX_DBG,"Adding the config packet at the Queue tail\n");
+
+ /*Edited by Amr - BugID_4720*/
+ if(nmi_wlan_txq_add_to_head(tqe))
+ return 0;
+ //nmi_wlan_txq_add_to_tail(tqe);
+ return 1;
+}
+
+static int nmi_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, nmi_tx_complete_func_t func)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+
+ if (p->quit)
+ return 0;
+
+ tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+
+ if (tqe == NULL)
+ return 0;
+ tqe->type = NMI_NET_PKT;
+ tqe->buffer = buffer;
+ tqe->buffer_size = buffer_size;
+ tqe->tx_complete_func = func;
+ tqe->priv = priv;
+
+ PRINT_D(TX_DBG,"Adding mgmt packet at the Queue tail\n");
+#ifdef TCP_ACK_FILTER
+ tqe->tcp_PendingAck_index=NOT_TCP_ACK;
+ tcp_process(tqe);
+#endif
+ nmi_wlan_txq_add_to_tail(tqe);
+ /*return number of itemes in the queue*/
+ return p->txq_entries;
+}
+/*Bug3959: transmitting mgmt frames received from host*/
+#if defined(NMI_AP_EXTERNAL_MLME) || defined(NMI_P2P)
+int nmi_wlan_txq_add_mgmt_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, nmi_tx_complete_func_t func)
+{
+
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+
+ if (p->quit)
+ return 0;
+
+ tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+
+ if (tqe == NULL)
+ return 0;
+ tqe->type = NMI_MGMT_PKT;
+ tqe->buffer = buffer;
+ tqe->buffer_size = buffer_size;
+ tqe->tx_complete_func = func;
+ tqe->priv = priv;
+#ifdef TCP_ACK_FILTER
+ tqe->tcp_PendingAck_index=NOT_TCP_ACK;
+#endif
+ PRINT_D(TX_DBG,"Adding Network packet at the Queue tail\n");
+ nmi_wlan_txq_add_to_tail(tqe);
+ return 1;
+}
+
+#ifdef NMI_FULLY_HOSTING_AP
+int nmi_FH_wlan_txq_add_net_pkt(void *priv, uint8_t *buffer, uint32_t buffer_size, nmi_tx_complete_func_t func)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+
+ if (p->quit)
+ return 0;
+
+ tqe = (struct txq_entry_t *)p->os_func.os_malloc_atomic(sizeof(struct txq_entry_t));
+
+ if (tqe == NULL)
+ return 0;
+ tqe->type = NMI_FH_DATA_PKT;
+ tqe->buffer = buffer;
+ tqe->buffer_size = buffer_size;
+ tqe->tx_complete_func = func;
+ tqe->priv = priv;
+ PRINT_D(TX_DBG,"Adding mgmt packet at the Queue tail\n");
+ nmi_wlan_txq_add_to_tail(tqe);
+ /*return number of itemes in the queue*/
+ return p->txq_entries;
+}
+#endif /* NMI_FULLY_HOSTING_AP*/
+#endif /*NMI_AP_EXTERNAL_MLME*/
+static struct txq_entry_t *nmi_wlan_txq_get_first(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+ unsigned long flags;
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_lock(p->txq_spinlock, &flags);
+
+ //p->os_func.os_enter_cs(p->txq_lock);
+ tqe = p->txq_head;
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+
+ //p->os_func.os_leave_cs(p->txq_lock);
+
+ return tqe;
+}
+
+static struct txq_entry_t *nmi_wlan_txq_get_next(struct txq_entry_t *tqe)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ unsigned long flags;
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_lock(p->txq_spinlock,&flags);
+
+ //p->os_func.os_enter_cs(p->txq_lock);
+ tqe = tqe->next;
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_spin_unlock(p->txq_spinlock, &flags);
+
+ //p->os_func.os_leave_cs(p->txq_lock);
+
+ return tqe;
+}
+
+static int nmi_wlan_rxq_add(struct rxq_entry_t *rqe)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+
+ if (p->quit)
+ return 0;
+
+ p->os_func.os_enter_cs(p->rxq_lock);
+ if (p->rxq_head == NULL) {
+ PRINT_D(RX_DBG,"Add to Queue head\n");
+ rqe->next = NULL;
+ p->rxq_head = rqe;
+ p->rxq_tail = rqe;
+ } else {
+ PRINT_D(RX_DBG,"Add to Queue tail\n");
+ p->rxq_tail->next = rqe;
+ rqe->next = NULL;
+ p->rxq_tail = rqe;
+ }
+ p->rxq_entries+=1;
+ PRINT_D(RX_DBG,"Number of queue entries: %d\n",p->rxq_entries);
+ //printk("Number of queue entries: %d\n",p->rxq_entries);
+ p->os_func.os_leave_cs(p->rxq_lock);
+ return p->rxq_entries;
+}
+
+static struct rxq_entry_t *nmi_wlan_rxq_remove(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+
+ PRINT_D(RX_DBG,"Getting rxQ element\n");
+ if (p->rxq_head) {
+ struct rxq_entry_t *rqe;
+
+ p->os_func.os_enter_cs(p->rxq_lock);
+ rqe = p->rxq_head;
+ p->rxq_head = p->rxq_head->next;
+ p->rxq_entries-=1;
+ PRINT_D(RX_DBG,"RXQ entries decreased\n");
+ p->os_func.os_leave_cs(p->rxq_lock);
+ return rqe;
+ }
+ PRINT_D(RX_DBG,"Nothing to get from Q\n");
+ return NULL;
+}
+
+
+/********************************************
+
+ Power Save handle functions
+
+********************************************/
+
+
+
+#ifdef NMI_OPTIMIZE_SLEEP_INT
+
+INLINE void chip_allow_sleep(void)
+{
+ uint32_t reg=0;
+
+ /* Clear bit 1 */
+ g_wlan.hif_func.hif_read_reg(0xf0, &reg);
+
+ g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0));
+}
+
+INLINE void chip_wakeup(void)
+{
+ uint32_t reg, clk_status_reg, trials=0;
+ uint32_t sleep_time;
+
+ if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI)
+ {
+ do
+ {
+ g_wlan.hif_func.hif_read_reg(1, &reg);
+ /* Set bit 1 */
+ g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1));
+
+ /* Clear bit 1*/
+ g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1));
+
+ do
+ {
+ /* Wait for the chip to stabilize*/
+ NMI_Sleep(2);
+ // Make sure chip is awake. This is an extra step that can be removed
+ // later to avoid the bus access overhead
+ if((nmi_get_chipid(NMI_TRUE) == 0))
+ {
+ nmi_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
+ }
+ }while((nmi_get_chipid(NMI_TRUE) == 0) && ((++trials %3) == 0));
+
+ }while(nmi_get_chipid(NMI_TRUE) == 0);
+ }
+ else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)
+ {
+ g_wlan.hif_func.hif_read_reg(0xf0, &reg);
+ do
+ {
+ /* Set bit 1 */
+ g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0));
+
+ // Check the clock status
+ g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
+
+ // in case of clocks off, wait 2ms, and check it again.
+ // if still off, wait for another 2ms, for a total wait of 6ms.
+ // If still off, redo the wake up sequence
+ while( ((clk_status_reg & 0x1) == 0) && (((++trials) %3) == 0))
+ {
+ /* Wait for the chip to stabilize*/
+ NMI_Sleep(2);
+
+ // Make sure chip is awake. This is an extra step that can be removed
+ // later to avoid the bus access overhead
+ g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
+
+ if((clk_status_reg & 0x1) == 0)
+ {
+ nmi_debug(N_ERR, "clocks still OFF. Wake up failed\n");
+ }
+ }
+ // in case of failure, Reset the wakeup bit to introduce a new edge on the next loop
+ if((clk_status_reg & 0x1) == 0)
+ {
+ // Reset bit 0
+ g_wlan.hif_func.hif_write_reg(0xf0, reg & (~ (1 << 0)));
+ }
+ }while((clk_status_reg & 0x1) == 0);
+ }
+
+
+ if(genuChipPSstate == CHIP_SLEEPING_MANUAL)
+ {
+ g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
+ reg &= ~(1<<0);
+ g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
+
+ if(nmi_get_chipid(NMI_FALSE) >= 0x1002a0)
+ {
+ /* Switch PMU clock back to external */
+ g_wlan.hif_func.hif_read_reg(0x1e48, &reg);
+ reg &= ~(1<<31);
+ g_wlan.hif_func.hif_write_reg(0x1e48, reg);
+ }
+ }
+ genuChipPSstate = CHIP_WAKEDUP;
+}
+#else
+INLINE void chip_wakeup(void)
+{
+ uint32_t reg, trials=0;
+ do
+ {
+ if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI)
+ {
+ g_wlan.hif_func.hif_read_reg(1, &reg) ;
+ /* Make sure bit 1 is 0 before we start. */
+ g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1));
+ /* Set bit 1 */
+ g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1)) ;
+ /* Clear bit 1*/
+ g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1));
+ }
+ else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)
+ {
+ /* Make sure bit 0 is 0 before we start. */
+ g_wlan.hif_func.hif_read_reg(0xf0, &reg);
+ g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0));
+ /* Set bit 1 */
+ g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0));
+ /* Clear bit 1 */
+ g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0));
+ }
+
+ do
+ {
+ /* Wait for the chip to stabilize*/
+ NMI_Sleep(2);
+
+ // Make sure chip is awake. This is an extra step that can be removed
+ // later to avoid the bus access overhead
+ if((nmi_get_chipid(NMI_TRUE) == 0))
+ {
+ nmi_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
+ }
+ }while((nmi_get_chipid(NMI_TRUE) == 0) && ((++trials %3) == 0));
+
+ }while(nmi_get_chipid(NMI_TRUE) == 0);
+
+ if(genuChipPSstate == CHIP_SLEEPING_MANUAL)
+ {
+ g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
+ reg &= ~(1<<0);
+ g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
+
+ if(nmi_get_chipid(NMI_FALSE) >= 0x1002a0)
+ {
+ /* Switch PMU clock back to external */
+ g_wlan.hif_func.hif_read_reg(0x1e48, &reg);
+ reg &= ~(1<<31);
+ g_wlan.hif_func.hif_write_reg(0x1e48, reg);
+ }
+ }
+ genuChipPSstate = CHIP_WAKEDUP;
+}
+#endif
+void chip_sleep_manually(NMI_Uint32 u32SleepTime)
+{
+ uint32_t val32;
+
+ if(genuChipPSstate != CHIP_WAKEDUP)
+ {
+ /* chip is already sleeping. Do nothing */
+ return;
+ }
+ acquire_bus(ACQUIRE_ONLY);
+
+
+ /* We don't need this anymore*/
+ if(nmi_get_chipid(NMI_FALSE) >= 0x1002a0)
+ {
+ // Switch PMU clock source to internal.
+ g_wlan.hif_func.hif_read_reg(0x1e48, &val32);
+ val32 |= (1<<31);
+ g_wlan.hif_func.hif_write_reg(0x1e48, val32);
+ }
+
+ g_wlan.hif_func.hif_write_reg(0x1C08, u32SleepTime);
+
+ g_wlan.hif_func.hif_read_reg(0x1C0C, &val32);
+ val32 |= (1<<0);
+
+#ifdef NMI_OPTIMIZE_SLEEP_INT
+ chip_allow_sleep();
+#endif
+
+ g_wlan.hif_func.hif_write_reg(0x1C0C, val32);
+
+ genuChipPSstate = CHIP_SLEEPING_MANUAL;
+ release_bus(RELEASE_ONLY);
+
+}
+
+
+/********************************************
+
+ Tx, Rx queue handle functions
+
+********************************************/
+
+#ifdef NMC1000_SINGLE_TRANSFER
+static int nmi_wlan_handle_txq(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t reg, dma_addr, buf_offset;
+ uint8_t *txb = p->tx_buffer;
+ int tp_size, skip = 0, ret = 0;
+ struct txq_entry_t *tqe;
+
+ p->txq_exit = 0;
+ do {
+
+ if (p->quit)
+ break;
+
+ if (!skip) {
+ tqe = nmi_wlan_txq_remove_from_head();
+ if (tqe == NULL)
+ break;
+ }
+
+ reg = 0;
+ if (tqe->type == NMI_CFG_PKT) {
+ buf_offset = tp_size = ETH_CONFIG_PKT_HDR_OFFSET;
+ reg = (1<<2);
+ } else {
+ buf_offset = tp_size = ETH_ETHERNET_HDR_OFFSET;
+ }
+ tp_size += tqe->buffer_size;
+ if (tp_size & 0x3) {
+ tp_size += 4;
+ tp_size &= ~0x3;
+ }
+
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ reg |= (1<<1);
+ ret = p->hif_func.hif_write_reg(NMI_HOST_VMM_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg host_vmm_ctl..\n");
+ break;
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+
+ do {
+ ret = p->hif_func.hif_read_reg(NMI_HOST_VMM_CTL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg host_vmm_ctl..\n");
+ break;
+ }
+ if (!(reg & 0x2)) {
+ ret = p->hif_func.hif_read_reg(NMI_VMM_TX_TBL_BASE, &dma_addr);
+ break;
+ }
+ } while(1);
+
+
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg vmm_tx_tbl_base...\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ break;
+ }
+ release_bus(RELEASE_ALLOW_SLEEP);
+
+ if (dma_addr != 0) {
+ uint32_t header;
+
+ header = (tqe->type << 31)|(tqe->buffer_size << 15)|(tp_size);
+#ifdef BIG_ENDIAN
+ header = BYTE_SWAP(header);
+#endif
+ memcpy(txb, &header, 4);
+ memcpy(&txb[buf_offset], tqe->buffer, tqe->buffer_size);
+
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ if ((p->io_func.io_type & 0x1) == HIF_SPI) {
+ if (tqe->type) {
+ dma_addr += NMI_AHB_DATA_MEM_BASE;
+ } else {
+ dma_addr += NMI_AHB_SHARE_MEM_BASE;
+ }
+ ret = p->hif_func.hif_block_tx(dma_addr, txb, tp_size);
+ if (ret) {
+ /**
+ done, interrupt firmware
+ **/
+ reg = dma_addr << 2;
+ reg |= (1 << 1);
+ ret = p->hif_func.hif_write_reg(NMI_HOST_TX_CTRL, reg);
+ }
+ } else if ((p->io_func.io_type & 0x1) == HIF_SDIO) {
+ ret = p->hif_func.hif_block_tx(0, txb, tp_size);
+ }
+
+
+ release_bus(ACQUIRE_AND_WAKEUP);
+ if (ret) {
+ tqe->status = 1;
+ if (tqe->tx_complete_func)
+ tqe->tx_complete_func(tqe->priv, tqe->status);
+ p->os_func.os_free(tqe);
+ skip = 0;
+ } else {
+ nmi_debug(N_ERR, "[nmi txq]: fail block tx...\n");
+ break;
+ }
+ } else {
+ p->os_func.os_sleep(30); /* wait 30 ms and start over */
+ skip = 1;
+ }
+ } while (1);
+
+ p->txq_exit = 1;
+ return ret;
+}
+#else
+
+
+static int nmi_wlan_handle_txq(uint32_t* pu32TxqCount)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ int i, entries = 0;
+ uint32_t sum;
+ uint32_t reg;
+ uint8_t *txb = p->tx_buffer;
+ uint32_t offset = 0;
+ int vmm_sz = 0;
+ struct txq_entry_t *tqe;
+ int ret = 0;
+ int counter;
+ int timeout;
+ uint32_t vmm_table[NMI_VMM_TBL_SIZE];
+ //printk("T");
+ p->txq_exit = 0;
+ do {
+ if (p->quit)
+ break;
+
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_wait(p->txq_add_to_head_lock, CFG_PKTS_TIMEOUT);
+#ifdef TCP_ACK_FILTER
+ nmi_wlan_txq_filter_dup_tcp_ack();
+#endif
+ /**
+ build the vmm list
+ **/
+ PRINT_D(TX_DBG,"Getting the head of the TxQ\n");
+ tqe = nmi_wlan_txq_get_first();
+ i = 0;
+ sum = 0;
+ do {
+ //if ((tqe != NULL) && (i < (8)) &&
+ //if ((tqe != NULL) && (i < (NMI_VMM_TBL_SIZE-1)) &&
+ if ((tqe != NULL) && (i < (NMI_VMM_TBL_SIZE-1)) /* reserve last entry to 0 */)
+ {
+
+ if (tqe->type == NMI_CFG_PKT) {
+ vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
+ }
+ /*Bug3959: transmitting mgmt frames received from host*/
+ /*vmm_sz will only be equal to tqe->buffer_size + 4 bytes (HOST_HDR_OFFSET)*/
+ /* in other cases NMI_MGMT_PKT and NMI_DATA_PKT_MAC_HDR*/
+ else if (tqe->type == NMI_NET_PKT){
+ vmm_sz = ETH_ETHERNET_HDR_OFFSET;
+ }
+#ifdef NMI_FULLY_HOSTING_AP
+ else if (tqe->type == NMI_FH_DATA_PKT)
+ {
+ vmm_sz = FH_TX_HOST_HDR_OFFSET;
+ }
+#endif
+#ifdef NMI_AP_EXTERNAL_MLME
+ else
+ {
+ vmm_sz = HOST_HDR_OFFSET;
+ }
+#endif
+ vmm_sz += tqe->buffer_size;
+ PRINT_D(TX_DBG,"VMM Size before alignment = %d\n",vmm_sz);
+ if (vmm_sz & 0x3) { /* has to be word aligned */
+ vmm_sz = (vmm_sz + 4) & ~0x3;
+ }
+ if((sum+vmm_sz) > p->tx_buffer_size) {
+ break;
+ }
+ PRINT_D(TX_DBG,"VMM Size AFTER alignment = %d\n",vmm_sz);
+ vmm_table[i] = vmm_sz/4; /* table take the word size */
+ PRINT_D(TX_DBG,"VMMTable entry size = %d\n",vmm_table[i]);
+
+ if (tqe->type == NMI_CFG_PKT){
+ vmm_table[i] |= (1 << 10);
+ PRINT_D(TX_DBG,"VMMTable entry changed for CFG packet = %d\n",vmm_table[i]);
+ }
+#ifdef BIG_ENDIAN
+ vmm_table[i] = BYTE_SWAP(vmm_table[i]);
+#endif
+ //p->hif_func.hif_write_reg(0x1160,vmm_table[0]);
+
+ //nmi_debug(N_TXQ, "[nmi txq]: vmm table[%d] = %08x\n", i, vmm_table[i]);
+ i++;
+ sum += vmm_sz;
+ PRINT_D(TX_DBG,"sum = %d\n",sum);
+ tqe = nmi_wlan_txq_get_next(tqe);
+ } else {
+ break;
+ }
+ } while (1);
+
+ if (i == 0){ /* nothing in the queue */
+ PRINT_D(TX_DBG,"Nothing in TX-Q\n");
+ break;
+ } else{
+ PRINT_D(TX_DBG,"Mark the last entry in VMM table - number of previous entries = %d\n",i);
+ vmm_table[i] = 0x0; /* mark the last element to 0 */
+ }
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ counter = 0;
+ do {
+
+ ret = p->hif_func.hif_read_reg(NMI_HOST_TX_CTRL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg vmm_tbl_entry..\n");
+ break;
+ }
+
+ if ((reg&0x1) == 0) {
+ /**
+ write to vmm table
+ **/
+ PRINT_D(TX_DBG,"Writing VMM table ... with Size = %d\n",((i+1)*4));
+ break;
+ } else {
+ counter++;
+ if(counter > 200)
+ {
+ counter = 0;
+ printk("Looping in tx ctrl , forcce quit\n");
+ ret = p->hif_func.hif_write_reg(NMI_HOST_TX_CTRL, 0);
+ break;
+ }
+ /**
+ wait for vmm table is ready
+ **/
+ PRINT_WRN(GENERIC_DBG, "[nmi txq]: warn, vmm table not clear yet, wait... \n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ p->os_func.os_sleep(3); /* wait 3 ms */
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ }
+ } while (!p->quit);
+
+ if(!ret) {
+ goto _end_;
+ }
+
+ timeout = 200;
+ do {
+
+ /**
+ write to vmm table
+ **/
+ ret = p->hif_func.hif_block_tx(NMI_VMM_TBL_RX_SHADOW_BASE, (uint8_t *)vmm_table, ((i+1)*4)); /* Bug 4477 fix */
+ if (!ret) {
+ nmi_debug(N_ERR, "ERR block TX of VMM table.\n");
+ break;
+ }
+
+
+ /**
+ interrupt firmware
+ **/
+ ret = p->hif_func.hif_write_reg(NMI_HOST_VMM_CTL, 0x2);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg host_vmm_ctl..\n");
+ break;
+ }
+
+ /**
+ wait for confirm...
+ **/
+
+ do {
+ ret = p->hif_func.hif_read_reg(NMI_HOST_VMM_CTL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg host_vmm_ctl..\n");
+ break;
+ }
+ if ((reg>>2)&0x1) {
+ /**
+ Get the entries
+ **/
+ entries = ((reg>>3)&0x3f);
+ //entries = ((reg>>3)&0x2f);
+ break;
+ } else{
+ release_bus(RELEASE_ALLOW_SLEEP);
+ p->os_func.os_sleep(3); /* wait 3 ms */
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n",reg);
+ }
+ } while (--timeout);
+ if(timeout <= 0)
+ {
+ ret = p->hif_func.hif_write_reg(NMI_HOST_VMM_CTL, 0x0);
+ break;
+ }
+
+ if (!ret) {
+ break;
+ }
+
+ if (entries == 0) {
+ PRINT_WRN(GENERIC_DBG, "[nmi txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]] \n",reg, i, vmm_table[i-1]);
+
+ /* undo the transaction. */
+ ret = p->hif_func.hif_read_reg(NMI_HOST_TX_CTRL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg NMI_HOST_TX_CTRL..\n");
+ break;
+ }
+ reg &= ~(1ul << 0);
+ ret = p->hif_func.hif_write_reg(NMI_HOST_TX_CTRL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg NMI_HOST_TX_CTRL..\n");
+ break;
+ }
+ break;
+ } else {
+ break;
+ }
+ } while (1);
+
+ if (!ret) {
+ goto _end_;
+ }
+ if(entries == 0) {
+ ret = NMI_TX_ERR_NO_BUF;
+ goto _end_;
+ }
+
+ /* since copying data into txb takes some time, then
+ allow the bus lock to be released let the RX task go. */
+ release_bus(RELEASE_ALLOW_SLEEP);
+
+ /**
+ Copy data to the TX buffer
+ **/
+ offset = 0;
+ i = 0;
+ do {
+ tqe = nmi_wlan_txq_remove_from_head();
+ if (tqe != NULL && (vmm_table[i] != 0)) {
+ uint32_t header, buffer_offset;
+
+#ifdef BIG_ENDIAN
+ vmm_table[i] = BYTE_SWAP(vmm_table[i]);
+#endif
+ vmm_sz = (vmm_table[i] & 0x3ff); /* in word unit */
+ vmm_sz *= 4;
+ header = (tqe->type << 31)|(tqe->buffer_size<<15)|vmm_sz;
+ /*Bug3959: transmitting mgmt frames received from host*/
+ /*setting bit 30 in the host header to indicate mgmt frame*/
+#ifdef NMI_AP_EXTERNAL_MLME
+ if(tqe->type == NMI_MGMT_PKT)
+ {
+ header |= (1<< 30);
+ }
+#endif
+ /*else if(tqe->type == NMI_DATA_PKT_MAC_HDR)
+ {
+ header |= (1<< 29);
+ }*/
+ //nmi_debug(N_TXQ, "[nmi txq]: header (%08x), real size (%d), vmm size (%d)\n", header, tqe->buffer_size, vmm_sz);
+
+#ifdef BIG_ENDIAN
+ header = BYTE_SWAP(header);
+#endif
+ memcpy(&txb[offset], &header, 4);
+ if (tqe->type == NMI_CFG_PKT) {
+ buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
+ }
+ /*Bug3959: transmitting mgmt frames received from host*/
+ /*buffer offset = HOST_HDR_OFFSET in other cases: NMI_MGMT_PKT*/
+ /* and NMI_DATA_PKT_MAC_HDR*/
+ else if (tqe->type == NMI_NET_PKT){
+ char * pBSSID = ((struct tx_complete_data*)(tqe->priv))->pBssid;
+ buffer_offset = ETH_ETHERNET_HDR_OFFSET;
+ //copy the bssid at the sart of the buffer
+ //printk("BSSID[%x][%x][%x]\n",pBSSID[0],pBSSID[1],pBSSID[2]);
+ memcpy(&txb[offset+4],pBSSID ,6);
+ }
+#ifdef NMI_FULLY_HOSTING_AP
+ else if (tqe->type == NMI_FH_DATA_PKT)
+ {
+ buffer_offset = FH_TX_HOST_HDR_OFFSET;
+ }
+#endif
+ else{
+ buffer_offset = HOST_HDR_OFFSET;
+ }
+
+ memcpy(&txb[offset+buffer_offset], tqe->buffer, tqe->buffer_size);
+ offset += vmm_sz;
+ i++;
+ tqe->status = 1; /* mark the packet send */
+ if (tqe->tx_complete_func)
+ tqe->tx_complete_func(tqe->priv, tqe->status);
+ #ifdef TCP_ACK_FILTER
+ if(tqe->tcp_PendingAck_index != NOT_TCP_ACK)
+ {
+ Pending_Acks_info[tqe->tcp_PendingAck_index].txqe=NULL;
+ }
+ #endif
+ p->os_func.os_free(tqe);
+ } else {
+ break;
+ }
+ } while (--entries);
+
+ /**
+ lock the bus
+ **/
+ //PRINT_D(GENERIC_DBG,"Locking hif_lock\n");
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+#if DMA_VER == DMA_VER_2
+ if(g_wlan.use_dma_v2) {
+ ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't start tx VMM ...\n");
+ goto _end_;
+ }
+
+ /**
+ transfer
+ **/
+ ret = p->hif_func.hif_block_tx_ext(0, txb, offset);
+ if(!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't block tx ext...\n");
+ goto _end_;
+ }
+
+ } else
+#endif /* DMA_VER == DMA_VER_2 */
+ {
+
+ /**
+ enable table 0
+ **/
+ reg = 0x1;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_TBL_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg vmm_tbl_ctl...\n");
+ goto _end_;
+ }
+
+ /**
+ enable core
+ **/
+ #ifdef OLD_FPGA_BITFILE
+ ret = p->hif_func.hif_read_reg(NMI_VMM_CORE_CTL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't read reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+ reg |= 0x1;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+ #else
+ reg = 0x1;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi txq]: fail can't write reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+ #endif
+
+ /**
+ transfer
+ **/
+
+ ret = p->hif_func.hif_block_tx(0, txb, offset);
+ if (!ret)
+ nmi_debug(N_ERR, "[nmi txq]: fail can't block tx...\n");
+ }
+_end_:
+
+ release_bus(RELEASE_ALLOW_SLEEP);
+ if (ret != 1)
+ break;
+ } while(0);
+ //remove_TCP_related();
+ /*Added by Amr - BugID_4720*/
+ p->os_func.os_signal(p->txq_add_to_head_lock);
+
+ p->txq_exit = 1;
+ PRINT_D(TX_DBG,"THREAD: Exiting txq\n");
+ //return tx[]q count
+ *pu32TxqCount = p->txq_entries;
+ return ret;
+}
+#endif
+
+static void nmi_wlan_handle_rxq(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ int offset = 0, size, has_packet = 0;
+ uint8_t *buffer;
+ struct rxq_entry_t *rqe;
+
+ p->rxq_exit = 0;
+
+
+
+
+ do {
+// printk("[%s:%d]in 1st do-while\n",__FUNCTION__,__LINE__);
+ if (p->quit){
+ PRINT_D(RX_DBG,"exit 1st do-while due to Clean_UP function \n");
+ p->os_func.os_signal(p->cfg_wait);
+ break;
+ }
+ rqe = nmi_wlan_rxq_remove();
+ if (rqe == NULL){
+ PRINT_D(RX_DBG,"nothing in the queue - exit 1st do-while\n");
+ break;
+ }
+ buffer = rqe->buffer;
+ size = rqe->buffer_size;
+ PRINT_D(RX_DBG,"rxQ entery Size = %d - Address = %p\n",size,buffer);
+ offset = 0;
+
+
+
+ do {
+ uint32_t header;
+ uint32_t pkt_len, pkt_offset, tp_len;
+ int is_cfg_packet;
+ PRINT_D(RX_DBG,"In the 2nd do-while\n");
+ memcpy(&header, &buffer[offset], 4);
+#ifdef BIG_ENDIAN
+ header = BYTE_SWAP(header);
+#endif
+ PRINT_D(RX_DBG,"Header = %04x - Offset = %d\n",header,offset);
+
+
+
+ is_cfg_packet = (header >> 31) & 0x1;
+ pkt_offset = (header >> 22) & 0x1ff;
+ tp_len = (header >> 11)&0x7ff;
+ pkt_len = header & 0x7ff;
+
+ if (pkt_len == 0 || tp_len == 0) {
+ nmi_debug(N_RXQ, "[nmi rxq]: data corrupt, packet len or tp_len is 0 [%d][%d]\n", pkt_len, tp_len);
+ break;
+ }
+
+/*bug 3887: [AP] Allow Management frames to be passed to the host*/
+ #if defined(NMI_AP_EXTERNAL_MLME) || defined(NMI_P2P)
+ #define IS_MANAGMEMENT 0x100
+ #define IS_MANAGMEMENT_CALLBACK 0x080
+ #define IS_MGMT_STATUS_SUCCES 0x040
+
+
+ if(pkt_offset & IS_MANAGMEMENT)
+ {
+ //PRINT_D(GENERIC_DBG,"Mgmt FRAME Received at host--\n\n");
+ //reset mgmt indicator bit, to use pkt_offeset in furthur calculations
+ pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES);
+
+#ifdef USE_WIRELESS
+ NMI_WFI_mgmt_rx(&buffer[offset+HOST_HDR_OFFSET],pkt_len);
+
+#endif
+
+ }
+
+ //BUG4530 fix
+ else
+ #endif
+ {
+ //nmi_debug(N_RXQ, "[nmi rxq]: packet, tp len(%d), len (%d), offset (%d), cfg (%d)\n", tp_len, pkt_len, pkt_offset, is_cfg_packet);
+
+ if (!is_cfg_packet) {
+
+ if (p->net_func.rx_indicate) {
+ if (pkt_len > 0) {
+ p->net_func.rx_indicate(&buffer[offset], pkt_len,pkt_offset);
+ has_packet = 1;
+ }
+ }
+ } else {
+ nmi_cfg_rsp_t rsp;
+
+
+
+ p->cif_func.rx_indicate(&buffer[pkt_offset+offset], pkt_len, &rsp);
+ if (rsp.type == NMI_CFG_RSP) {
+ /**
+ wake up the waiting task...
+ **/
+ PRINT_D(RX_DBG,"p->cfg_seq_no = %d - rsp.seq_no = %d\n",p->cfg_seq_no,rsp.seq_no);
+ if (p->cfg_seq_no == rsp.seq_no) {
+ //PRINT_D(GENERIC_DBG, "Unlocking cfg_wait\n");
+ p->os_func.os_signal(p->cfg_wait);
+ }
+ //p->os_func.os_signal(p->cfg_wait);
+ } else if (rsp.type == NMI_CFG_RSP_STATUS) {
+ /**
+ Call back to indicate status...
+ **/
+ if (p->indicate_func.mac_indicate) {
+ p->indicate_func.mac_indicate(NMI_MAC_INDICATE_STATUS);
+ }
+
+ } else if (rsp.type == NMI_CFG_RSP_SCAN) {
+ if (p->indicate_func.mac_indicate)
+ p->indicate_func.mac_indicate(NMI_MAC_INDICATE_SCAN);
+ }
+ }
+ }
+ offset += tp_len;
+ if (offset >= size)
+ break;
+ } while (1);
+
+
+#ifndef MEMORY_STATIC
+ if (buffer != NULL)
+ p->os_func.os_free((void *)buffer);
+#endif
+ if (rqe != NULL)
+ p->os_func.os_free((void *)rqe);
+
+ if (has_packet) {
+ if (p->net_func.rx_complete)
+ p->net_func.rx_complete();
+ }
+ } while(1);
+
+ p->rxq_exit = 1;
+ PRINT_D(RX_DBG,"THREAD: Exiting RX thread \n");
+ return;
+}
+
+/********************************************
+
+ Isr
+
+********************************************/
+static void nmi_unknown_isr(void){
+ g_wlan.hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+ release_bus(RELEASE_ALLOW_SLEEP);
+}
+static void nmi_pllupdate_isr(uint32_t int_stats1){
+#if (defined NMI_SDIO) && (!defined NMI_SDIO_IRQ_GPIO)
+
+
+ //g_wlan.hif_func.hif_write_reg(NMI_INT_STATS,(int_stats1 & ~PLL_INT));
+ g_wlan.hif_func.hif_write_reg(NMI_INT_STATS,0);
+
+ /* Waiting for PLL */
+ g_wlan.os_func.os_atomic_sleep(NMI_PLL_TO);
+
+ if(!(int_stats1 & DATA_INT)){
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+ else {
+ printk("[PLL]Pending Data wait\n");
+ }
+#else
+ uint32_t int_stats;
+ #ifndef NMI_SDIO
+ int trials= 10;
+ #endif
+
+ if((!(int_stats1 & DATA_INT)) && (!(int_stats1 & SLEEP_INT))){
+ g_wlan.hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+ }
+ g_wlan.hif_func.hif_read_reg(NMI_INT_STATS,&int_stats);
+ g_wlan.hif_func.hif_write_reg(NMI_INT_STATS,(int_stats & ~PLL_INT));
+
+ /* Waiting for PLL */
+ g_wlan.os_func.os_atomic_sleep(NMI_PLL_TO);
+
+#ifndef NMI_SDIO
+ //poll till read a valid data
+ while(!(ISNMC1000(nmi_get_chipid(NMI_TRUE))&&--trials)) {
+ printk("SPI retrying\n");
+ g_wlan.os_func.os_atomic_sleep(1);
+ }
+#endif
+
+ if((!(int_stats1 & DATA_INT)) && (!(int_stats1 & SLEEP_INT))){
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+ else
+ {printk("[PLL]Pending Data wait\n");}
+#endif
+
+}
+
+static void nmi_sleeptimer_isr(uint32_t int_stats1){
+ uint32_t int_stats;
+
+
+ g_wlan.hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+
+ g_wlan.hif_func.hif_read_reg(NMI_INT_STATS,&int_stats);
+ g_wlan.hif_func.hif_write_reg(NMI_INT_STATS,(int_stats & ~SLEEP_INT));
+ /* Wait 1ms tomake sure chip went into sleep
+ Accessing the clockless registers in the transit state fails */
+ if(nmi_get_chipid(NMI_FALSE) < 0x1000D0)
+ {
+ NMI_SleepMicrosec(1200); // failed at 1 ms
+ }
+#ifndef NMI_OPTIMIZE_SLEEP_INT
+ genuChipPSstate = CHIP_SLEEPING_AUTO;
+#endif
+
+ release_bus(RELEASE_ALLOW_SLEEP);
+}
+
+#ifdef NMC1000_SINGLE_TRANSFER
+static void nmi_wlan_handle_isr(uint32_t int_status1)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+#ifdef MEMORY_STATIC
+ uint32_t offset = p->rx_buffer_offset;
+#endif
+ uint8_t *buffer = NULL;
+ uint32_t size, ctl0;
+ int ret;
+ struct rxq_entry_t *rqe;
+
+ /**
+ clear the chip's interrupt
+ **/
+ int_stats1 &= ~(DATA_INT);
+ if(p->hif_func.hif_write_reg(NMI_INT_STATS,int_stats1)!= 1)
+
+ if(!(int_stats1 & SLEEP_INT)){
+ PRINT_D(RX_DBG,"Clearing RX interrupt\n");
+ p->hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+ }
+
+ /**
+ read the rx size
+ **/
+ ret = p->hif_func.hif_read_reg(NMI_HOST_RX_CTRL_0, &ctl0);
+ size = (ctl0 >> 2) & 0xfff;
+
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail can't read reg host_rx_ctrl_0...\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return;
+ }
+
+ if (size > 0) {
+ uint32_t address = 0;
+
+#ifdef MEMORY_STATIC
+ if (p->rx_buffer_size - offset < (2*1024)/*size*/)
+ offset = 0;
+ if(p->rx_buffer)
+ buffer = &p->rx_buffer[offset];
+ else
+ {
+ nmi_debug(N_ERR, "[nmi isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
+ goto _end_;
+ }
+#else
+ buffer = p->os_func.os_malloc(2*1024/*size*/);
+ if (buffer == NULL) {
+ nmi_debug(N_ERR, "[nmi isr]: fail alloc host memory...drop the packets (%d)\n", size);
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return;
+ }
+#endif
+
+
+ /**
+ start bus transfer
+ **/
+ if ((p->io_func.io_type & 0x1) == HIF_SPI) {
+ /**
+ read the spi dam address
+ **/
+ ret = p->hif_func.hif_read_reg(NMI_HOST_RX_CTRL_1, &address);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail can't read reg host_rx_ctrl_1...\n");
+ goto _end_;
+ }
+ if (address & 0x1) {
+ address = NMI_AHB_DATA_MEM_BASE+(address&~0x1);
+ } else {
+ address = NMI_AHB_SHARE_MEM_BASE+address;
+ }
+ } else if ((p->io_func.io_type & 0x1) == HIF_SDIO) {
+ address = 0;
+ }
+ ret = p->hif_func.hif_block_rx(address, buffer, size);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail block rx...\n");
+ } else {
+ if ((p->io_func.io_type & 0x1) == HIF_SPI) {
+ /**
+ indicate rx done to firmware
+ **/
+ ctl0 |= (1<<1);
+ ret = p->hif_func.hif_write_reg(NMI_HOST_RX_CTRL_0, ctl0);
+ }
+ }
+
+_end_:
+ if(!(int_stats1 & SLEEP_INT)){
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+ if (ret) {
+#ifdef MEMORY_STATIC
+ offset += size;
+ p->rx_buffer_offset = offset;
+#endif
+ /**
+ add to rx queue
+ **/
+#if 0
+ {
+ BYTE *bt = (BYTE *)buffer;
+ int i;
+
+ nmi_debug(N_ERR, "*** Receive Packet ***\n");
+
+ for (i = 0; i < size; i++) {
+ if ((i!=0) &&((i%8)==0))
+ nmi_debug(N_ERR, "\n", bt[i]);
+ nmi_debug(N_ERR, "%02x ", bt[i]);
+ }
+ nmi_debug(N_ERR, "\n");
+ }
+#endif
+ rqe = (struct rxq_entry_t *)p->os_func.os_malloc(sizeof(struct rxq_entry_t));
+ if (rqe) {
+ rqe->buffer = buffer;
+ rqe->buffer_size = size;
+ nmi_wlan_rxq_add(rqe);
+ p->os_func.os_signal(p->rxq_wait);
+ }
+ } else {
+#ifndef MEMORY_STATIC
+ if (buffer != NULL)
+ p->os_func.os_free(buffer);
+#endif
+ }
+ }
+}
+
+#else
+#if defined NMI_SDIO && !defined NMI_SDIO_IRQ_GPIO
+static void nmi_wlan_handle_isr(uint32_t xfer_cnt, uint32_t int_stats1)
+#else
+#ifdef PLL_WORKAROUND
+static void nmi_wlan_handle_isr(uint32_t int_stats1)
+#else /* PLL_WORKAROUND */
+static void nmi_wlan_handle_isr(void)
+#endif /* PLL_WORKAROUND */
+#endif
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+#ifdef MEMORY_STATIC
+ uint32_t offset = p->rx_buffer_offset;
+#endif
+ uint8_t *buffer = NULL;
+ uint32_t size, reg;
+ int ret = 0;
+ struct rxq_entry_t *rqe;
+
+ /**
+ clear the chip's interrupt
+ **/
+#if defined PLL_WORKAROUND && ( (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO))
+ int_stats1 &= ~(DATA_INT);
+ p->hif_func.hif_write_reg(NMI_INT_STATS,int_stats1);
+
+ if(!(int_stats1 & SLEEP_INT)){
+ p->hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+ }
+
+#elif (!defined PLL_WORKAROUND) && ( (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO))
+ p->hif_func.hif_clear_int();
+ linux_wlan_enable_irq();
+#endif
+
+
+ /**
+ read the rx size
+ **/
+ #if defined NMI_SDIO && !defined NMI_SDIO_IRQ_GPIO
+ size = xfer_cnt;
+ #else
+ ret = p->hif_func.hif_read_reg(NMI_VMM_TO_HOST_SIZE, &size);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail can't read reg vmm_to_host_size...\n");
+ goto _end_;
+ }
+ #endif
+
+ if (size > 0) {
+#ifdef MEMORY_STATIC
+ if (p->rx_buffer_size - offset < size)
+ offset = 0;
+ if(p->rx_buffer)
+ buffer = &p->rx_buffer[offset];
+ else
+ {
+ nmi_debug(N_ERR, "[nmi isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
+ goto _end_;
+ }
+#else
+ buffer = p->os_func.os_malloc(size);
+ if (buffer == NULL) {
+ nmi_debug(N_ERR, "[nmi isr]: fail alloc host memory...drop the packets (%d)\n", size);
+ goto _end_;
+ }
+#endif
+
+ /**
+ lock bus, no interruption
+ **/
+ //p->os_func.os_enter_cs(p->hif_lock);
+
+ /**
+ enable vmm table 1
+ **/
+ reg = 0x2;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_TBL_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail write reg vmm_tbl_ctl...\n");
+ goto _end_;
+ }
+
+ /**
+ enable vmm transfer
+ **/
+#ifdef OLD_FPGA_BITFILE
+ ret = p->hif_func.hif_read_reg(NMI_VMM_CORE_CTL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail read reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+ reg |= 0x1;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail write reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+#else
+ reg = 0x1;
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail write reg vmm_core_ctl...\n");
+ goto _end_;
+ }
+
+#endif
+
+ ret = p->hif_func.hif_block_rx(0, buffer, size);
+
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail block rx...\n");
+ goto _end_;
+ }
+
+_end_:
+ /**
+ unlock bus
+ **/
+#ifdef PLL_WORKAROUND
+ if(!(int_stats1 & SLEEP_INT)){
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+#else /* PLL_WORKAROUND */
+ release_bus(RELEASE_ALLOW_SLEEP);
+#endif /* PLL_WORKAROUND */
+
+ if (ret) {
+#ifdef MEMORY_STATIC
+ offset += size;
+ p->rx_buffer_offset = offset;
+#endif
+ /**
+ add to rx queue
+ **/
+ rqe = (struct rxq_entry_t *)p->os_func.os_malloc(sizeof(struct rxq_entry_t));
+ if (rqe != NULL) {
+ rqe->buffer = buffer;
+ rqe->buffer_size = size;
+ PRINT_D(RX_DBG,"rxq entery Size= %d - Address = %p\n",rqe->buffer_size,rqe->buffer);
+ nmi_wlan_rxq_add(rqe);
+ p->os_func.os_signal(p->rxq_wait);
+ }
+ } else {
+#ifndef MEMORY_STATIC
+ if (buffer != NULL)
+ p->os_func.os_free(buffer);
+#endif
+ }
+ }
+}
+#endif
+
+#define UNKNOWN_INTERRUPT_WORKAROUND
+
+void nmi_handle_isr_v1(void)
+{
+#if (defined NMI_SDIO) && (!defined NMI_SDIO_IRQ_GPIO)
+
+ uint32_t int_status;
+ uint32_t xfer_cnt = 0;
+
+
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+
+ if(!g_wlan.hif_func.hif_clear_int()){
+ printk("UNKNOWN INT\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return;
+ }
+ xfer_cnt = sdio_xfer_cnt();
+
+ if(xfer_cnt == 0){
+ g_wlan.hif_func.hif_read_reg(NMI_INT_STATS,&int_status);
+ if(int_status & PLL_INT){
+ nmi_pllupdate_isr(int_status);
+ }
+ if(int_status & SLEEP_INT){
+ nmi_sleeptimer_isr(int_status);
+ }
+ }
+ if(xfer_cnt>0){
+ #ifndef NMI_OPTIMIZE_SLEEP_INT
+ /* Chip is up and talking*/
+ genuChipPSstate = CHIP_WAKEDUP;
+ #endif
+ nmi_wlan_handle_isr(xfer_cnt, 0);
+ }
+#else /* ! NMI_SDIO */
+ #ifdef PLL_WORKAROUND
+ uint32_t int_status;
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ g_wlan.hif_func.hif_read_reg(NMI_INT_STATS,&int_status);
+
+
+ if(int_status & PLL_INT){
+ nmi_pllupdate_isr(int_status);
+ }
+ if(int_status & DATA_INT){
+ #ifndef NMI_OPTIMIZE_SLEEP_INT
+ /* Chip is up and talking*/
+ genuChipPSstate = CHIP_WAKEDUP;
+ #endif
+ nmi_wlan_handle_isr(int_status);
+ }
+ /* Sleep Int should be handled first because sometimes firmware sends both
+ interrupts, which caused chip to go to sleep while driver is getting data*/
+ if(int_status & SLEEP_INT){
+ nmi_sleeptimer_isr(int_status);
+ }
+ if(!(int_status & (PLL_INT | DATA_INT | SLEEP_INT | ABORT_INT)) ){
+ printk(">> UNKNOWN_INTERRUPT - 0x%08x\n",int_status);
+#ifdef UNKNOWN_INTERRUPT_WORKAROUND
+ {
+ #define TRIALS 2000
+
+ uint32_t reread_trials = TRIALS;
+ uint32_t vmm_size = 0;
+
+ while(reread_trials-- && (int_status == 0) && (vmm_size == 0)){
+ g_wlan.hif_func.hif_read_reg(NMI_INT_STATS,&int_status);
+ g_wlan.hif_func.hif_read_reg(0x150010, &vmm_size);
+ }
+
+ if(int_status != 0 || vmm_size != 0){
+ printk("Int Status Re-read successfully [Sts: %x - VMM_Size: %d - trials:%d]\n",int_status,vmm_size,(TRIALS - reread_trials));
+ nmi_wlan_handle_isr(DATA_INT);
+ }else{
+ printk("> Int Status Re-Read FAILED: %x\n", int_status);
+ nmi_unknown_isr();
+ }
+
+ }
+#else
+ nmi_unknown_isr();
+#endif
+ }
+
+#else
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ nmi_wlan_handle_isr();
+#endif
+#endif
+}
+
+#if DMA_VER == DMA_VER_2
+/********************************************
+
+ Fast DMA Isr
+
+********************************************/
+static void nmi_unknown_isr_ext(void){
+ g_wlan.hif_func.hif_clear_int_ext(0);
+}
+static void nmi_pllupdate_isr_ext(uint32_t int_stats){
+
+ int trials= 10;
+
+ g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR);
+
+ /* Waiting for PLL */
+ g_wlan.os_func.os_atomic_sleep(NMI_PLL_TO);
+
+ //poll till read a valid data
+ while(!(ISNMC1000(nmi_get_chipid(NMI_TRUE))&&--trials)) {
+ printk("PLL update retrying\n");
+ g_wlan.os_func.os_atomic_sleep(1);
+ }
+}
+
+static void nmi_sleeptimer_isr_ext(uint32_t int_stats1)
+{
+ g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR);
+#ifndef NMI_OPTIMIZE_SLEEP_INT
+ genuChipPSstate = CHIP_SLEEPING_AUTO;
+#endif
+}
+
+static void nmi_wlan_handle_isr_ext(uint32_t int_status)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+#ifdef MEMORY_STATIC
+ uint32_t offset = p->rx_buffer_offset;
+#endif
+ uint8_t *buffer = NULL;
+ uint32_t size;
+ uint32_t retries=0;
+ int ret = 0;
+ struct rxq_entry_t *rqe;
+
+
+ /**
+ Get the rx size
+ **/
+
+ size = ((int_status & 0x7fff) << 2);
+
+ while(!size && retries < 10)
+ {
+ uint32_t time=0;
+ /*looping more secure*/
+ /*zero size make a crashe because the dma will not happen and that will block the firmware*/
+ nmi_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n",time++);
+ p->hif_func.hif_read_size(&size);
+ size = ((size & 0x7fff) << 2);
+ retries++;
+
+ }
+
+ if (size > 0) {
+#ifdef MEMORY_STATIC
+ if (p->rx_buffer_size - offset < size)
+ offset = 0;
+
+ if(p->rx_buffer)
+ buffer = &p->rx_buffer[offset];
+ else
+ {
+ nmi_debug(N_ERR, "[nmi isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
+ goto _end_;
+ }
+
+#else
+ buffer = p->os_func.os_malloc(size);
+ if (buffer == NULL) {
+ nmi_debug(N_ERR, "[nmi isr]: fail alloc host memory...drop the packets (%d)\n", size);
+ NMI_Sleep(100);
+ goto _end_;
+ }
+#endif
+
+ /**
+ clear the chip's interrupt after getting size some register getting corrupted after clear the interrupt
+ **/
+ p->hif_func.hif_clear_int_ext(DATA_INT_CLR|ENABLE_RX_VMM);
+
+
+ /**
+ start transfer
+ **/
+ ret = p->hif_func.hif_block_rx_ext(0, buffer, size);
+
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi isr]: fail block rx...\n");
+ goto _end_;
+ }
+_end_:
+
+
+ if (ret) {
+#ifdef MEMORY_STATIC
+ offset += size;
+ p->rx_buffer_offset = offset;
+#endif
+ /**
+ add to rx queue
+ **/
+ rqe = (struct rxq_entry_t *)p->os_func.os_malloc(sizeof(struct rxq_entry_t));
+ if (rqe != NULL) {
+ rqe->buffer = buffer;
+ rqe->buffer_size = size;
+ PRINT_D(RX_DBG,"rxq entery Size= %d - Address = %p\n",rqe->buffer_size,rqe->buffer);
+ nmi_wlan_rxq_add(rqe);
+ p->os_func.os_signal(p->rxq_wait);
+ }
+ } else {
+#ifndef MEMORY_STATIC
+ if (buffer != NULL)
+ p->os_func.os_free(buffer);
+#endif
+ }
+ }
+
+}
+
+void nmi_handle_isr_v2(void)
+{
+ uint32_t int_status;
+
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+ g_wlan.hif_func.hif_read_int(&int_status);
+
+ if(int_status & PLL_INT_EXT){
+ nmi_pllupdate_isr_ext(int_status);
+ }
+ if(int_status & DATA_INT_EXT){
+ nmi_wlan_handle_isr_ext(int_status);
+ #ifndef NMI_OPTIMIZE_SLEEP_INT
+ /* Chip is up and talking*/
+ genuChipPSstate = CHIP_WAKEDUP;
+ #endif
+ }
+ if(int_status & SLEEP_INT_EXT){
+ nmi_sleeptimer_isr_ext(int_status);
+ }
+
+ if(!(int_status & (ALL_INT_EXT))) {
+ printk(">> UNKNOWN_INTERRUPT - 0x%08x\n",int_status);
+ nmi_unknown_isr_ext();
+ }
+#if ((!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO))
+ linux_wlan_enable_irq();
+#endif
+ release_bus(RELEASE_ALLOW_SLEEP);
+}
+#endif /* DMA_VER == DMA_VER_2 */
+
+void nmi_handle_isr(void)
+{
+
+#if DMA_VER == DMA_VER_2
+ if(g_wlan.use_dma_v2) {
+ nmi_handle_isr_v2();
+ } else {
+ nmi_handle_isr_v1();
+ }
+#else /* DMA_VER == DMA_VER_2 */
+ nmi_handle_isr_v1();
+#endif /* DMA_VER == DMA_VER_2 */
+}
+/********************************************
+
+ Firmware download
+
+********************************************/
+static int nmi_wlan_firmware_download(const uint8_t *buffer, uint32_t buffer_size)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t offset;
+ uint32_t addr, size, size2, blksz;
+ uint8_t *dma_buffer;
+ int ret = 0;
+
+ blksz = (1ul << 12); /* Bug 4703: 4KB Good enough size for most platforms = PAGE_SIZE. */
+ /* Allocate a DMA coherent buffer. */
+
+#if (defined NMC_PREALLOC_AT_BOOT)
+{
+ extern void * get_fw_buffer(void);
+ dma_buffer = (uint8_t *)get_fw_buffer();
+ printk("[MMM] dma_buffer = 0x%x\n", dma_buffer);
+}
+#else
+ dma_buffer = (uint8_t *)g_wlan.os_func.os_malloc(blksz);
+#endif
+ if (dma_buffer == NULL) {
+ /*EIO 5*/
+ ret = -5;
+ PRINT_ER("Can't allocate buffer for firmware download IO error\n ");
+ goto _fail_1;
+ }
+
+ PRINT_D(GENERIC_DBG,"Downloading firmware size = %d ...\n",buffer_size);
+ /**
+ load the firmware
+ **/
+ offset = 0;
+ do {
+ memcpy(&addr, &buffer[offset], 4);
+ memcpy(&size, &buffer[offset+4], 4);
+#ifdef BIG_ENDIAN
+ addr = BYTE_SWAP(addr);
+ size = BYTE_SWAP(size);
+#endif
+ acquire_bus(ACQUIRE_ONLY);
+ offset += 8;
+ while(((int)size) && (offset < buffer_size)) {
+ if(size <= blksz) {
+ size2 = size;
+ } else {
+ size2 = blksz;
+ }
+ /* Copy firmware into a DMA coherent buffer */
+ memcpy(dma_buffer, &buffer[offset], size2);
+ ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2);
+ if (!ret) break;
+
+ addr += size2;
+ offset += size2;
+ size -= size2;
+ }
+ release_bus(RELEASE_ONLY);
+
+ if (!ret){
+ /*EIO 5*/
+ ret = -5;
+ PRINT_ER("Can't download firmware IO error\n ");
+ goto _fail_;
+ }
+ PRINT_D(GENERIC_DBG,"Offset = %d\n",offset);
+ } while (offset < buffer_size);
+
+_fail_:
+
+#if (defined NMC_PREALLOC_AT_BOOT)
+
+#else
+ if(dma_buffer) g_wlan.os_func.os_free(dma_buffer);
+#endif
+
+_fail_1:
+
+ return (ret < 0)? ret:0;
+}
+
+/********************************************
+
+ Common
+
+********************************************/
+static int nmi_wlan_start(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t reg = 0;
+ int ret;
+ uint32_t chipid;
+
+ /**
+ Set the host interface
+ **/
+#ifdef OLD_FPGA_BITFILE
+ acquire_bus(ACQUIRE_ONLY);
+ ret = p->hif_func.hif_read_reg(NMI_VMM_CORE_CTL, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail read reg vmm_core_ctl...\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return ret;
+ }
+ reg |= (p->io_func.io_type<<2);
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CTL, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail write reg vmm_core_ctl...\n");
+ release_bus(RELEASE_ONLY);
+ return ret;
+ }
+#else
+ if (p->io_func.io_type == HIF_SDIO) {
+ reg = 0;
+#ifndef REG_0XF6_NOT_CLEAR_BUG_FIX /* bug 4456 and 4557 */
+ reg |= (1 << 3);
+#endif /* REG_0XF6_NOT_CLEAR_BUG_FIX */ /* bug 4456 and 4557 */
+ } else if (p->io_func.io_type == HIF_SPI) {
+ reg = 1;
+ }
+ acquire_bus(ACQUIRE_ONLY);
+ ret = p->hif_func.hif_write_reg(NMI_VMM_CORE_CFG, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail write reg vmm_core_cfg...\n");
+ release_bus(RELEASE_ONLY);
+ /* EIO 5*/
+ ret = -5;
+ return ret;
+ }
+ reg = 0;
+#ifdef NMI_SDIO_IRQ_GPIO
+ reg |= NMI_HAVE_SDIO_IRQ_GPIO;
+#endif
+
+#if DMA_VER == DMA_VER_2
+ if(p->use_dma_v2) {
+ reg |= NMI_HAVE_DMA_VER_2;
+ }
+#endif
+
+#ifdef VCO_14_SUPPLY
+ if(nmi_get_chipid(NMI_FALSE) < 0x1002a0){
+ reg |= NMI_HAVE_VCO_14_SUPPLY;
+ }
+#endif
+
+#ifdef NMI_HOST_HAS_RTC
+ reg |= NMI_HAVE_RTC;
+#endif
+
+/*BugID_5257*/
+/*Set oscillator frequency*/
+#ifdef XTAL_24
+ reg |= NMI_XTAL_24;
+ nmi_debug(N_ERR, "[nmi start]: set xtal 24Mhz\n");
+#else
+ reg &= ~NMI_XTAL_24;
+ nmi_debug(N_ERR, "[nmi start]: set xtal 26Mhz\n");
+#endif
+
+/*BugID_5271*/
+/*Enable/Disable GPIO configuration for FW logs*/
+#ifdef DISABLE_NMC_UART
+ reg |= NMI_DISABLE_NMC_UART;
+#else
+ reg &= ~NMI_DISABLE_NMC_UART;
+#endif
+
+ ret = p->hif_func.hif_write_reg(NMI_GP_REG_1, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail write NMI_GP_REG_1 ...\n");
+ release_bus(RELEASE_ONLY);
+ /* EIO 5*/
+ ret = -5;
+ return ret;
+ }
+#endif
+
+
+ /**
+ Bus related
+ **/
+#if DMA_VER == DMA_VER_2
+ if(p->use_dma_v2) {
+ p->hif_func.hif_sync_ext(NUM_INT_EXT);
+ } else {
+ p->hif_func.hif_sync();
+ }
+#else
+ p->hif_func.hif_sync();
+#endif
+
+ ret = p->hif_func.hif_read_reg(0x1000, &chipid);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail read reg 0x1000 ...\n");
+ release_bus(RELEASE_ONLY);
+ /* EIO 5*/
+ ret = -5;
+ return ret;
+ }
+
+ /**
+ Go...
+ **/
+
+ //p->hif_func.hif_write_reg(0x150014, reg);
+
+ p->hif_func.hif_read_reg(NMI_GLB_RESET_0,&reg);
+ if((reg & (1ul << 10)) == (1ul << 10)){
+ reg &= ~(1ul << 10);
+ p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg);
+ p->hif_func.hif_read_reg(NMI_GLB_RESET_0,&reg);
+ }
+
+ reg |= (1ul << 10);
+ ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg);
+ p->hif_func.hif_read_reg(NMI_GLB_RESET_0,&reg);
+ release_bus(RELEASE_ONLY);
+
+ return (ret<0)?ret:0;
+}
+
+static int nmi_wlan_stop(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t reg = 0;
+ int ret;
+ uint8_t timeout=10;
+ /**
+ TODO: stop the firmware, need a re-download
+ **/
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+
+ ret = p->hif_func.hif_read_reg(NMI_GLB_RESET_0, &reg);
+ if (!ret) {
+ PRINT_ER("Error while reading reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return ret;
+ }
+
+ reg &= ~(1 << 10);
+
+
+ ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg);
+ if (!ret) {
+ PRINT_ER("Error while writing reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return ret;
+ }
+
+
+
+ do
+ {
+ ret = p->hif_func.hif_read_reg(NMI_GLB_RESET_0, &reg);
+ if (!ret) {
+ PRINT_ER("Error while reading reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return ret;
+ }
+ PRINT_D(GENERIC_DBG,"Read RESET Reg %x : Retry%d\n",reg,timeout);
+ /*Workaround to ensure that the chip is actually reset*/
+ if( (reg & (1 << 10) ) )
+ {
+ PRINT_D(GENERIC_DBG,"Bit 10 not reset : Retry %d\n",timeout);
+ reg &= ~(1 << 10);
+ ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg);
+ timeout--;
+ }
+ else
+ {
+ PRINT_D(GENERIC_DBG,"Bit 10 reset after : Retry %d\n",timeout);
+ ret = p->hif_func.hif_read_reg(NMI_GLB_RESET_0, &reg);
+ if (!ret) {
+ PRINT_ER("Error while reading reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ return ret;
+ }
+ PRINT_D(GENERIC_DBG,"Read RESET Reg %x : Retry%d\n",reg,timeout);
+ break;
+ }
+
+ }while(timeout) ;
+
+#if 1
+/******************************************************************************/
+/* This was add at Bug 4595 to reset the chip while maintaining the bus state */
+/******************************************************************************/
+ reg = ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<8)|(1<<9)|(1<<26)|(1<<29)|(1<<30)); /**/
+ /**/
+ ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg); /**/
+ reg = 0x7FFFFBFF&(~(1<<10)); /**/
+ /**/
+ ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg); /**/
+/******************************************************************************/
+#endif
+
+
+ release_bus(RELEASE_ALLOW_SLEEP);
+
+ return ret;
+}
+
+static void nmi_wlan_cleanup(void)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ struct txq_entry_t *tqe;
+ struct rxq_entry_t *rqe;
+ uint32_t reg = 0;
+ int ret;
+
+ p->quit = 1;
+ /**
+ wait for queue end
+ **/
+ //p->os_func.os_signal(p->txq_wait);
+ //p->os_func.os_signal(p->rxq_wait);
+
+ //complete(p->txq_wait);
+ //complete(p->rxq_wait);
+ /*do {
+ if (p->txq_exit && p->rxq_exit)
+ break;
+ } while (1);*/
+
+ /**
+ clean up the queue
+ **/
+ do {
+ tqe = nmi_wlan_txq_remove_from_head();
+ if (tqe == NULL)
+ break;
+ if (tqe->tx_complete_func)
+ tqe->tx_complete_func(tqe->priv, 0);
+ p->os_func.os_free((void *)tqe);
+ } while (1);
+
+ do {
+ rqe = nmi_wlan_rxq_remove();
+ if (rqe == NULL)
+ break;
+#ifdef MEMORY_DYNAMIC
+ p->os_func.os_free((void *)tqe->buffer);
+#endif
+ p->os_func.os_free((void *)rqe);
+ } while (1);
+
+ /**
+ clean up buffer
+ **/
+
+#if (defined NMC_PREALLOC_AT_BOOT)
+
+#else
+ #ifdef MEMORY_STATIC
+ if (p->rx_buffer)
+ {
+ p->os_func.os_free(p->rx_buffer);
+ p->rx_buffer = NMI_NULL;
+ }
+ #endif
+ if (p->tx_buffer)
+ {
+ p->os_func.os_free(p->tx_buffer);
+ p->tx_buffer = NMI_NULL;
+ }
+#endif
+
+ acquire_bus(ACQUIRE_AND_WAKEUP);
+
+
+ ret = p->hif_func.hif_read_reg(NMI_INT_STATS,&reg);
+ if (!ret) {
+ PRINT_ER("Error while reading reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+ PRINT_ER("Writing ABORT reg\n");
+ ret = p->hif_func.hif_write_reg(NMI_INT_STATS,(reg | ABORT_INT ));
+ if (!ret) {
+ PRINT_ER("Error while writing reg\n");
+ release_bus(RELEASE_ALLOW_SLEEP);
+ }
+ release_bus(RELEASE_ALLOW_SLEEP);
+ /**
+ io clean up
+ **/
+ p->hif_func.hif_deinit(NULL);
+
+}
+
+static int nmi_wlan_cfg_commit(int type,uint32_t drvHandler)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ nmi_cfg_frame_t *cfg = &p->cfg_frame;
+ int total_len = p->cfg_frame_offset+4+ DRIVER_HANDLER_SIZE ;
+ int seq_no = p->cfg_seq_no%256;
+ int driver_handler=(NMI_Uint32)drvHandler;
+
+
+ /**
+ Set up header
+ **/
+ if (type == NMI_CFG_SET) { /* Set */
+ cfg->wid_header[0] = 'W';
+ } else { /* Query */
+ cfg->wid_header[0] = 'Q';
+ }
+ cfg->wid_header[1] = seq_no; /* sequence number */
+ cfg->wid_header[2] = (uint8_t)total_len;
+ cfg->wid_header[3] = (uint8_t)(total_len>>8);
+ cfg->wid_header[4] = (uint8_t)driver_handler;
+ cfg->wid_header[5] = (uint8_t)(driver_handler>>8);
+ cfg->wid_header[6] = (uint8_t)(driver_handler>>16);
+ cfg->wid_header[7] = (uint8_t)(driver_handler>>24);
+ p->cfg_seq_no = seq_no;
+
+ /**
+ Add to TX queue
+ **/
+
+ /*Edited by Amr - BugID_4720*/
+ if(!nmi_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len))
+ return -1;
+
+ return 0;
+}
+
+static int nmi_wlan_cfg_set(int start, uint32_t wid, uint8_t *buffer, uint32_t buffer_size, int commit,uint32_t drvHandler)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t offset;
+ int ret_size;
+
+
+ if (p->cfg_frame_in_use)
+ return 0;
+
+ if (start)
+ p->cfg_frame_offset = 0;
+
+ offset = p->cfg_frame_offset;
+ ret_size = p->cif_func.cfg_wid_set(p->cfg_frame.frame, offset, (uint16_t)wid, buffer, buffer_size);
+ offset += ret_size;
+ p->cfg_frame_offset = offset;
+
+ if (commit) {
+ PRINT_D(TX_DBG,"[NMI]PACKET Commit with sequence number %d\n",p->cfg_seq_no);
+ PRINT_D(RX_DBG,"Processing cfg_set()\n");
+ p->cfg_frame_in_use = 1;
+
+ /*Edited by Amr - BugID_4720*/
+ if(nmi_wlan_cfg_commit(NMI_CFG_SET,drvHandler))
+ ret_size = 0; //BugID_5213
+
+ if(p->os_func.os_wait(p->cfg_wait,CFG_PKTS_TIMEOUT))
+ {
+ printk("Set Timed Out\n");
+ ret_size = 0;
+ }
+ p->cfg_frame_in_use = 0;
+ p->cfg_frame_offset = 0;
+ p->cfg_seq_no += 1;
+
+ }
+
+ return ret_size;
+}
+static int nmi_wlan_cfg_get(int start, uint32_t wid, int commit,uint32_t drvHandler)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ uint32_t offset;
+ int ret_size;
+
+
+ if (p->cfg_frame_in_use)
+ return 0;
+
+ if (start)
+ p->cfg_frame_offset = 0;
+
+ offset = p->cfg_frame_offset;
+ ret_size = p->cif_func.cfg_wid_get(p->cfg_frame.frame, offset, (uint16_t)wid);
+ offset += ret_size;
+ p->cfg_frame_offset = offset;
+
+ if (commit) {
+ p->cfg_frame_in_use = 1;
+
+ /*Edited by Amr - BugID_4720*/
+ if(nmi_wlan_cfg_commit(NMI_CFG_QUERY,drvHandler))
+ ret_size = 0; //BugID_5213
+
+
+ if(p->os_func.os_wait(p->cfg_wait,CFG_PKTS_TIMEOUT))
+ {
+ printk("Get Timed Out\n");
+ ret_size = 0;
+ }
+ PRINT_D(GENERIC_DBG, "[NMI]Get Response received\n");
+ p->cfg_frame_in_use = 0;
+ p->cfg_frame_offset = 0;
+ p->cfg_seq_no += 1;
+ }
+
+ return ret_size;
+}
+
+static int nmi_wlan_cfg_get_val(uint32_t wid, uint8_t *buffer, uint32_t buffer_size)
+{
+ nmi_wlan_dev_t *p = (nmi_wlan_dev_t *)&g_wlan;
+ int ret;
+
+ ret = p->cif_func.cfg_wid_get_val((uint16_t)wid, buffer, buffer_size);
+
+ return ret;
+}
+
+void nmi_bus_set_max_speed(void){
+
+ /* Increase bus speed to max possible. */
+ g_wlan.hif_func.hif_set_max_bus_speed();
+}
+
+void nmi_bus_set_default_speed(void){
+
+ /* Restore bus speed to default. */
+ g_wlan.hif_func.hif_set_default_bus_speed();
+}
+uint32_t init_chip(void)
+{
+ uint32_t chipid;
+ uint32_t reg,ret=0;
+
+
+ acquire_bus(ACQUIRE_ONLY);
+ chipid = nmi_get_chipid(NMI_TRUE);
+
+ if((chipid & 0xfff) >= 0xd0) {
+ NMI_INT_STATS = _NMI_INT_STATS_D0_AND_LATER;
+ NMI_GP_REG_1 = _NMI_GP_REG_1_D0_AND_LATER;
+ } else {
+ NMI_INT_STATS = _NMI_INT_STATS_PRE_D0;
+ NMI_GP_REG_1 = _NMI_GP_REG_1_PRE_D0;
+ }
+
+
+#if DMA_VER == DMA_VER_2
+ if((chipid & 0xfff) >= 0xe0) {
+ g_wlan.use_dma_v2 = 1;
+ } else {
+ g_wlan.use_dma_v2 = 0;
+ }
+#endif /* DMA_VER == DMA_VER_2 */
+
+ if((chipid & 0xfff) != 0xa0) {
+ /**
+ Avoid booting from boot ROM. Make sure that Drive IRQN [SDIO platform]
+ or SD_DAT3 [SPI platform] to ?1?
+ **/
+ /* Set cortus reset register to register control. */
+ ret = g_wlan.hif_func.hif_read_reg(0x1118, &reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail read reg 0x1118 ...\n");
+ return ret;
+ }
+ reg |= (1 << 0);
+ ret = g_wlan.hif_func.hif_write_reg(0x1118, reg);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail write reg 0x1118 ...\n");
+ return ret;
+ }
+ /**
+ Write branch intruction to IRAM (0x71 trap) at location 0xFFFF0000
+ (Cortus map) or C0000 (AHB map).
+ **/
+ ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71);
+ if (!ret) {
+ nmi_debug(N_ERR, "[nmi start]: fail write reg 0xc0000 ...\n");
+ return ret;
+ }
+ }
+
+
+ #if 0
+ if((chipid& 0xfff) < 0xf0) {
+ /* Setting MUX to probe sleep signal on pin 6 of J216*/
+ g_wlan.hif_func.hif_write_reg(0x1060, 0x1);
+ g_wlan.hif_func.hif_write_reg(0x1180, 0x33333333);
+ g_wlan.hif_func.hif_write_reg(0x1184, 0x33333333);
+ g_wlan.hif_func.hif_read_reg(0x1408, &reg);
+ /* set MUX for GPIO_4 (pin 4) to cortus GPIO*/
+ reg &= ~((0x7 << 16));
+ g_wlan.hif_func.hif_write_reg(0x1408, (reg|(0x7 << 12)));
+ }else {
+ /* Enable test bus*/
+ g_wlan.hif_func.hif_write_reg(0x1060, 0x1);
+ /* Rotate bus signals to get sleep signal on pin 6 like it was on previous chips*/
+ g_wlan.hif_func.hif_write_reg(0x1188, 0x70);
+ /* Set output of pin 6 to test bus 0x1*/
+ /* Set output of pin 9 to test bus 0x2*/
+ g_wlan.hif_func.hif_write_reg(0x1180, 0x200100);
+ g_wlan.hif_func.hif_read_reg(0x1408, &reg);
+
+ /* set MUX for GPIO_4 (pin 4) to cortus GPIO*/
+ reg &= ~((0x7 << 16));
+ /* set MUX for GPIO_3 (pin 6) to test bus*/
+ reg |= (0x7 << 12) | (0x7 << 24);
+ g_wlan.hif_func.hif_write_reg(0x1408, reg);
+ }
+ #endif
+
+
+
+ release_bus(RELEASE_ONLY);
+
+ return ret;
+
+}
+
+uint32_t nmi_get_chipid(uint8_t update)
+{
+ static uint32_t chipid = 0;
+ // SDIO can't read into global variables
+ // Use this variable as a temp, then copy to the global
+ uint32_t tempchipid = 0;
+ uint32_t rfrevid;
+
+ if(chipid == 0 || update != 0) {
+ g_wlan.hif_func.hif_read_reg(0x1000,&tempchipid);
+ g_wlan.hif_func.hif_read_reg(0x13f4,&rfrevid);
+ if(!ISNMC1000(tempchipid)) {
+ chipid = 0;
+ goto _fail_;
+ }
+ if (chipid == 0x1002a0) {
+ if (rfrevid == 0x1) {
+ tempchipid = 0x1002a0;
+ } else if (rfrevid == 0x2) {
+ tempchipid = 0x1002a1;
+ }
+ }
+
+ chipid = tempchipid;
+ }
+_fail_:
+ return chipid;
+}
+
+#ifdef COMPLEMENT_BOOT
+uint8_t core_11b_ready(void)
+{
+ uint32_t reg_val;
+
+ acquire_bus(ACQUIRE_ONLY);
+ g_wlan.hif_func.hif_write_reg(0x16082c,1);
+ g_wlan.hif_func.hif_write_reg(0x161600,0x90);
+ g_wlan.hif_func.hif_read_reg(0x161600,&reg_val);
+ release_bus(RELEASE_ONLY);
+
+ if(reg_val == 0x90)
+ return 0;
+ else
+ return 1;
+}
+#endif
+
+int nmi_wlan_init(nmi_wlan_inp_t *inp, nmi_wlan_oup_t *oup)
+{
+
+ int ret = 0;
+
+ printk("Initializing NMI_Wlan ...\n");
+
+ memset((void *)&g_wlan, 0, sizeof(nmi_wlan_dev_t));
+
+ /**
+ store the input
+ **/
+ memcpy((void *)&g_wlan.os_func, (void *)&inp->os_func, sizeof(nmi_wlan_os_func_t));
+ memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(nmi_wlan_io_func_t));
+ memcpy((void *)&g_wlan.net_func, (void *)&inp->net_func, sizeof(nmi_wlan_net_func_t));
+ memcpy((void *)&g_wlan.indicate_func, (void *)&inp->indicate_func, sizeof(nmi_wlan_net_func_t));
+ g_wlan.hif_lock = inp->os_context.hif_critical_section;
+ g_wlan.txq_lock = inp->os_context.txq_critical_section;
+
+ /*Added by Amr - BugID_4720*/
+ g_wlan.txq_add_to_head_lock = inp->os_context.txq_add_to_head_critical_section;
+
+ /*Added by Amr - BugID_4720*/
+ g_wlan.txq_spinlock = inp->os_context.txq_spin_lock;
+
+ g_wlan.rxq_lock = inp->os_context.rxq_critical_section;
+ g_wlan.txq_wait = inp->os_context.txq_wait_event;
+ g_wlan.rxq_wait = inp->os_context.rxq_wait_event;
+ g_wlan.cfg_wait = inp->os_context.cfg_wait_event;
+ g_wlan.tx_buffer_size = inp->os_context.tx_buffer_size;
+#if defined (MEMORY_STATIC)
+ g_wlan.rx_buffer_size = inp->os_context.rx_buffer_size;
+#endif
+
+ //g_wlan.os_func.os_lock(g_wlan.cfg_wait);
+ /***
+ host interface init
+ **/
+
+ if ((inp->io_func.io_type & 0x1) == HIF_SDIO) {
+ if (!hif_sdio.hif_init(inp, nmi_debug)) {
+ /* EIO 5 */
+ ret = -5;
+ goto _fail_;
+ }
+ memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(nmi_hif_func_t));
+ } else{
+ if ((inp->io_func.io_type & 0x1) == HIF_SPI) {
+ /**
+ TODO:
+ **/
+ if (!hif_spi.hif_init(inp, nmi_debug)) {
+ /* EIO 5 */
+ ret = -5;
+ goto _fail_;
+ }
+ memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(nmi_hif_func_t));
+ } else {
+ /* EIO 5 */
+ ret = -5;
+ goto _fail_;
+ }
+ }
+
+ /***
+ mac interface init
+ **/
+ if (!mac_cfg.cfg_init(nmi_debug)) {
+ /* ENOBUFS 105 */
+ ret = -105;
+ goto _fail_;
+ }
+ memcpy((void *)&g_wlan.cif_func, &mac_cfg, sizeof(nmi_cfg_func_t));
+
+
+ /**
+ alloc tx, rx buffer
+ **/
+#if (defined NMC_PREALLOC_AT_BOOT)
+ extern void * get_tx_buffer(void);
+ extern void * get_rx_buffer(void);
+
+ printk("[MMM] malloc before, g_wlan.tx_buffer = 0x%x, g_wlan.rx_buffer = 0x%x\n", g_wlan.tx_buffer, g_wlan.rx_buffer);
+#endif
+
+
+
+ if(g_wlan.tx_buffer == NMI_NULL)
+#if (defined NMC_PREALLOC_AT_BOOT)
+ g_wlan.tx_buffer = (uint8_t *)get_tx_buffer();
+#else
+ g_wlan.tx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.tx_buffer_size);
+#endif
+ printk("[MMM] g_wlan.tx_buffer = 0x%x\n", g_wlan.tx_buffer);
+
+ if (g_wlan.tx_buffer == NMI_NULL) {
+ /* ENOBUFS 105 */
+ ret = -105;
+ PRINT_ER("Can't allocate Tx Buffer");
+ goto _fail_;
+ }
+
+/* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/
+#if defined (MEMORY_STATIC)
+ if(g_wlan.rx_buffer == NMI_NULL)
+ #if (defined NMC_PREALLOC_AT_BOOT)
+ g_wlan.rx_buffer = (uint8_t *)get_rx_buffer();
+ #else
+ g_wlan.rx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.rx_buffer_size);
+ #endif
+ printk("[MMM] g_wlan.rx_buffer =0x%x\n", g_wlan.rx_buffer);
+ if (g_wlan.rx_buffer == NMI_NULL)
+ {
+ /* ENOBUFS 105 */
+ ret = -105;
+ PRINT_ER("Can't allocate Rx Buffer");
+ goto _fail_;
+ }
+#endif
+
+ /**
+ export functions
+ **/
+ oup->wlan_firmware_download = nmi_wlan_firmware_download;
+ oup->wlan_start = nmi_wlan_start;
+ oup->wlan_stop = nmi_wlan_stop;
+ oup->wlan_add_to_tx_que = nmi_wlan_txq_add_net_pkt;
+ oup->wlan_handle_tx_que = nmi_wlan_handle_txq;
+ oup->wlan_handle_rx_que = nmi_wlan_handle_rxq;
+ //oup->wlan_handle_rx_isr = nmi_wlan_handle_isr;
+ oup->wlan_handle_rx_isr = nmi_handle_isr;
+ oup->wlan_cleanup = nmi_wlan_cleanup;
+ oup->wlan_cfg_set = nmi_wlan_cfg_set;
+ oup->wlan_cfg_get = nmi_wlan_cfg_get;
+ oup->wlan_cfg_get_value = nmi_wlan_cfg_get_val;
+
+ /*Bug3959: transmitting mgmt frames received from host*/
+ #if defined(NMI_AP_EXTERNAL_MLME) || defined(NMI_P2P)
+ oup->wlan_add_mgmt_to_tx_que = nmi_wlan_txq_add_mgmt_pkt;
+
+ #ifdef NMI_FULLY_HOSTING_AP
+ oup->wlan_add_data_to_tx_que = nmi_FH_wlan_txq_add_net_pkt;
+ #endif
+ #endif
+
+ if(!init_chip()){
+ /* EIO 5 */
+ ret = -5;
+ goto _fail_;
+ }
+#ifdef TCP_ACK_FILTER
+ Init_TCP_tracking();
+#endif
+ return 1;
+
+_fail_:
+
+#if (defined NMC_PREALLOC_AT_BOOT)
+
+#else
+ #ifdef MEMORY_STATIC
+ if (g_wlan.rx_buffer)
+ {
+ g_wlan.os_func.os_free(g_wlan.rx_buffer);
+ g_wlan.rx_buffer = NMI_NULL;
+ }
+ #endif
+ if (g_wlan.tx_buffer)
+ {
+ g_wlan.os_func.os_free(g_wlan.tx_buffer);
+ g_wlan.tx_buffer = NMI_NULL;
+ }
+#endif
+ return ret;
+
+}
+
+#define BIT31 (1<<31)
+NMI_Uint16 Set_machw_change_vir_if(NMI_Bool bValue)
+{
+ NMI_Uint16 ret;
+ NMI_Uint32 reg;
+
+ /*Reset NMI_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
+ (&g_wlan)->os_func.os_enter_cs((&g_wlan)->hif_lock);
+ ret = (&g_wlan)->hif_func.hif_read_reg(NMI_CHANGING_VIR_IF, &reg);
+ if (!ret)
+ {
+ PRINT_ER("Error while Reading reg NMI_CHANGING_VIR_IF\n");
+ }
+
+ if(bValue== NMI_TRUE)
+ {
+ reg |= (BIT31);
+ }
+ else
+ {
+ reg &= ~(BIT31);
+ }
+
+ ret = (&g_wlan)->hif_func.hif_write_reg(NMI_CHANGING_VIR_IF, reg);
+
+ if (!ret)
+ {
+ PRINT_ER("Error while writing reg NMI_CHANGING_VIR_IF\n");
+ }
+ (&g_wlan)->os_func.os_leave_cs((&g_wlan)->hif_lock);
+
+ return ret;
+}
+
+#ifdef NMI_FULLY_HOSTING_AP
+nmi_wlan_dev_t* Get_wlan_context(NMI_Uint16* pu16size)
+{
+ *pu16size = sizeof(nmi_wlan_dev_t);
+ return &g_wlan;
+}
+#endif
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan_cfg.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan_cfg.c
new file mode 100755
index 00000000..10ea0a36
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/nmi_wlan_cfg.c
@@ -0,0 +1,641 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Newport Media Inc. All rights reserved.
+//
+// Module Name: nmi_wlan_cfg.c
+//
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "nmi_wlan_if.h"
+#include "nmi_wlan.h"
+#include "nmi_wlan_cfg.h"
+#include "CoreConfigurator.h"
+
+#ifdef NMI_FULLY_HOSTING_AP
+#include "include/NMI_host_AP.h"
+void NMI_mgm_HOSTAPD_ACK(void* priv, NMI_Bool bStatus);
+#endif
+
+/********************************************
+
+ Global Data
+
+********************************************/
+
+typedef struct {
+ nmi_debug_func dPrint;
+
+ int mac_status;
+ uint8_t mac_address[7];
+ uint8_t ip_address[5];
+ uint8_t bssid[7];
+ uint8_t ssid[34];
+ uint8_t firmware_version[129];
+ uint8_t supp_rate[24];
+ uint8_t wep_key[28];
+ uint8_t i_psk[66];
+ uint8_t hardwareProductVersion[33];
+ uint8_t phyversion[17];
+ uint8_t supp_username[21];
+ uint8_t supp_password[64];
+ uint8_t assoc_req[256];
+ uint8_t assoc_rsp[256];
+ uint8_t firmware_info[8];
+ uint8_t scan_result[256];
+ uint8_t scan_result1[256];
+} nmi_mac_cfg_t;
+
+static nmi_mac_cfg_t g_mac;
+
+static nmi_cfg_byte_t g_cfg_byte[] = {
+ {WID_BSS_TYPE, 0},
+ {WID_CURRENT_TX_RATE, 0},
+ {WID_CURRENT_CHANNEL, 0},
+ {WID_PREAMBLE, 0},
+ {WID_11G_OPERATING_MODE, 0},
+ {WID_STATUS, 0},
+ {WID_SCAN_TYPE, 0},
+ {WID_KEY_ID, 0},
+ {WID_QOS_ENABLE, 0},
+ {WID_POWER_MANAGEMENT, 0},
+ {WID_11I_MODE, 0},
+ {WID_AUTH_TYPE, 0},
+ {WID_SITE_SURVEY, 0},
+ {WID_LISTEN_INTERVAL, 0},
+ {WID_DTIM_PERIOD, 0},
+ {WID_ACK_POLICY, 0},
+ {WID_BCAST_SSID, 0},
+ {WID_REKEY_POLICY, 0},
+ {WID_SHORT_SLOT_ALLOWED, 0},
+ {WID_START_SCAN_REQ, 0},
+ {WID_RSSI, 0},
+ {WID_LINKSPEED, 0},
+ {WID_AUTO_RX_SENSITIVITY, 0},
+ {WID_DATAFLOW_CONTROL, 0},
+ {WID_SCAN_FILTER, 0},
+ {WID_11N_PROT_MECH, 0},
+ {WID_11N_ERP_PROT_TYPE, 0},
+ {WID_11N_ENABLE, 0},
+ {WID_11N_OPERATING_MODE, 0},
+ {WID_11N_OBSS_NONHT_DETECTION, 0},
+ {WID_11N_HT_PROT_TYPE, 0},
+ {WID_11N_RIFS_PROT_ENABLE, 0},
+ {WID_11N_SMPS_MODE, 0},
+ {WID_11N_CURRENT_TX_MCS, 0},
+ {WID_11N_SHORT_GI_ENABLE, 0},
+ {WID_RIFS_MODE, 0},
+ {WID_TX_ABORT_CONFIG, 0},
+ {WID_11N_IMMEDIATE_BA_ENABLED, 0},
+ {WID_11N_TXOP_PROT_DISABLE, 0},
+ {WID_NIL, 0}
+};
+
+static nmi_cfg_hword_t g_cfg_hword[] = {
+ {WID_LINK_LOSS_THRESHOLD, 0},
+ {WID_RTS_THRESHOLD, 0},
+ {WID_FRAG_THRESHOLD, 0},
+ {WID_SHORT_RETRY_LIMIT, 0},
+ {WID_LONG_RETRY_LIMIT, 0},
+ {WID_BEACON_INTERVAL, 0},
+ {WID_RX_SENSE, 0},
+ {WID_ACTIVE_SCAN_TIME, 0},
+ {WID_PASSIVE_SCAN_TIME, 0},
+ {WID_SITE_SURVEY_SCAN_TIME, 0},
+ {WID_JOIN_START_TIMEOUT, 0},
+ {WID_AUTH_TIMEOUT, 0},
+ {WID_ASOC_TIMEOUT, 0},
+ {WID_11I_PROTOCOL_TIMEOUT, 0},
+ {WID_EAPOL_RESPONSE_TIMEOUT, 0},
+ {WID_11N_SIG_QUAL_VAL, 0},
+ {WID_CCA_THRESHOLD, 0},
+ {WID_NIL, 0}
+};
+
+static nmi_cfg_word_t g_cfg_word[] = {
+ {WID_FAILED_COUNT, 0},
+ {WID_RETRY_COUNT, 0},
+ {WID_MULTIPLE_RETRY_COUNT, 0},
+ {WID_FRAME_DUPLICATE_COUNT, 0},
+ {WID_ACK_FAILURE_COUNT, 0},
+ {WID_RECEIVED_FRAGMENT_COUNT, 0},
+ {WID_MCAST_RECEIVED_FRAME_COUNT, 0},
+ {WID_FCS_ERROR_COUNT, 0},
+ {WID_SUCCESS_FRAME_COUNT, 0},
+ {WID_TX_FRAGMENT_COUNT, 0},
+ {WID_TX_MULTICAST_FRAME_COUNT, 0},
+ {WID_RTS_SUCCESS_COUNT, 0},
+ {WID_RTS_FAILURE_COUNT, 0},
+ {WID_WEP_UNDECRYPTABLE_COUNT, 0},
+ {WID_REKEY_PERIOD, 0},
+ {WID_REKEY_PACKET_COUNT, 0},
+ {WID_HW_RX_COUNT, 0},
+ {WID_GET_INACTIVE_TIME,0},
+ {WID_NIL, 0}
+
+};
+
+static nmi_cfg_str_t g_cfg_str[] = {
+ {WID_SSID, g_mac.ssid}, /* 33 + 1 bytes */
+ {WID_FIRMWARE_VERSION, g_mac.firmware_version},
+ {WID_OPERATIONAL_RATE_SET, g_mac.supp_rate},
+ {WID_BSSID, g_mac.bssid}, /* 6 bytes */
+ {WID_WEP_KEY_VALUE, g_mac.wep_key}, /* 27 bytes */
+ {WID_11I_PSK, g_mac.i_psk}, /* 65 bytes */
+ //{WID_11E_P_ACTION_REQ, g_mac.action_req},
+ {WID_HARDWARE_VERSION, g_mac.hardwareProductVersion},
+ {WID_MAC_ADDR, g_mac.mac_address},
+ {WID_PHY_VERSION, g_mac.phyversion},
+ {WID_SUPP_USERNAME, g_mac.supp_username},
+ {WID_SUPP_PASSWORD, g_mac.supp_password},
+ {WID_SITE_SURVEY_RESULTS, g_mac.scan_result},
+ {WID_SITE_SURVEY_RESULTS, g_mac.scan_result1},
+ //{WID_RX_POWER_LEVEL, g_mac.channel_rssi},
+ {WID_ASSOC_REQ_INFO, g_mac.assoc_req},
+ {WID_ASSOC_RES_INFO, g_mac.assoc_rsp},
+ //{WID_11N_P_ACTION_REQ, g_mac.action_req},
+ {WID_FIRMWARE_INFO, g_mac.firmware_version},
+ {WID_IP_ADDRESS, g_mac.ip_address},
+ {WID_NIL, NULL}
+};
+
+/********************************************
+
+ Configuration Functions
+
+********************************************/
+
+static int nmi_wlan_cfg_set_byte(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t val8)
+{
+ uint8_t *buf;
+
+ if ((offset+4) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+ buf[2] = 1;
+ buf[3] = val8;
+ return 4;
+}
+
+static int nmi_wlan_cfg_set_hword(uint8_t *frame, uint32_t offset, uint16_t id, uint16_t val16)
+{
+ uint8_t *buf;
+
+ if ((offset+5) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+ buf[2] = 2;
+ buf[3] = (uint8_t)val16;
+ buf[4] = (uint8_t)(val16>>8);
+
+ return 5;
+}
+
+static int nmi_wlan_cfg_set_word(uint8_t *frame, uint32_t offset, uint16_t id, uint32_t val32)
+{
+ uint8_t *buf;
+
+ if ((offset+7) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+ buf[2] = 4;
+ buf[3] = (uint8_t)val32;
+ buf[4] = (uint8_t)(val32>>8);
+ buf[5] = (uint8_t)(val32>>16);
+ buf[6] = (uint8_t)(val32>>24);
+
+ return 7;
+}
+
+static int nmi_wlan_cfg_set_str(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *str, uint32_t size)
+{
+ uint8_t *buf;
+
+ if ((offset+size+3) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+ buf[2] = (uint8_t)size;
+
+ if((str != NULL) && (size != 0))
+ {
+ memcpy(&buf[3], str, size);
+ }
+
+ return (size+3);
+}
+
+static int nmi_wlan_cfg_set_bin(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *b, uint32_t size)
+{
+ uint8_t *buf;
+ uint32_t i;
+ uint8_t checksum = 0;
+
+ if ((offset+size+5) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+ buf[2] = (uint8_t)size;
+ buf[3] = (uint8_t)(size>>8);
+
+ if((b != NULL) && (size != 0))
+ {
+ memcpy(&buf[4], b, size);
+ for (i = 0; i < size; i++) {
+ checksum += buf[i+4];
+ }
+ }
+
+ buf[size+4] = checksum;
+
+ return (size+5);
+}
+
+/********************************************
+
+ Configuration Response Functions
+
+********************************************/
+
+static void nmi_wlan_parse_response_frame(uint8_t *info, int size)
+{
+ uint32_t wid, len=0, i;
+ static int seq = 0;
+
+ while (size>0) {
+ i = 0;
+ wid = info[0] | (info[1] << 8);
+#ifdef BIG_ENDIAN
+ wid = BYTE_SWAP(wid);
+#endif
+ PRINT_INFO(GENERIC_DBG,"Processing response for %d seq %d\n",wid,seq++);
+ switch ((wid >> 12) & 0x7) {
+ case WID_CHAR:
+ do {
+ if (g_cfg_byte[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_byte[i].id == wid) {
+ g_cfg_byte[i].val = info[3];
+ break;
+ }
+ i++;
+ } while (1);
+ len = 2;
+ break;
+ case WID_SHORT:
+ do {
+ if (g_cfg_hword[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_hword[i].id == wid) {
+#ifdef BIG_ENDIAN
+ g_cfg_hword[i].val = (info[3]<<8)|(info[4]);
+#else
+ g_cfg_hword[i].val = info[3]|(info[4]<<8);
+#endif
+ break;
+ }
+ i++;
+ } while (1);
+ len = 3;
+ break;
+ case WID_INT:
+ do {
+ if (g_cfg_word[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_word[i].id == wid) {
+#ifdef BIG_ENDIAN
+ g_cfg_word[i].val = (info[3]<<24)|(info[4]<<16)|(info[5]<<8)|(info[6]);
+#else
+ g_cfg_word[i].val = info[3]|(info[4]<<8)|(info[5]<<16)|(info[6]<<24);
+#endif
+ break;
+ }
+ i++;
+ } while (1);
+ len = 5;
+ break;
+ case WID_STR:
+ do {
+ if (g_cfg_str[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_str[i].id == wid) {
+ if(wid == WID_SITE_SURVEY_RESULTS)
+ {
+ static int toggle = 0;
+ PRINT_INFO(GENERIC_DBG,"Site survey results received[%d]\n",
+ size);
+
+ PRINT_INFO(GENERIC_DBG,"Site survey results value[%d]toggle[%d]\n",size,toggle);
+ i += toggle;
+ toggle ^= 1;
+ }
+ memcpy(g_cfg_str[i].str, &info[2], (info[2]+1));
+ break;
+ }
+ i++;
+ } while (1);
+ len = 1+info[2];
+ break;
+ default:
+ break;
+ }
+ size -= (2 + len);
+ info += (2 + len);
+ }
+
+ return;
+}
+
+static int nmi_wlan_parse_info_frame(uint8_t *info, int size)
+{
+ nmi_mac_cfg_t *pd = (nmi_mac_cfg_t *)&g_mac;
+ uint32_t wid, len;
+ int type = NMI_CFG_RSP_STATUS;
+
+ wid = info[0] | (info[1] << 8);
+#if 0
+#ifdef BIG_ENDIAN
+ wid = BYTE_SWAP(wid);
+#endif
+#endif
+
+ len = info[2];
+ PRINT_INFO(GENERIC_DBG,"Status Len = %d Id= %d\n",len,wid);
+ if ((len == 1) && (wid == WID_STATUS)) {
+ pd->mac_status = info[3];
+ type = NMI_CFG_RSP_STATUS;
+ }
+
+ return type;
+}
+
+#if 0
+static int nmi_wlan_parse_network_frame(uint8_t *info, int size)
+{
+ nmi_mac_cfg_t *priv = (nmi_mac_cfg_t *)&g_mac;
+ uint32_t wid, len;
+
+ wid = info[0] | (info[1] << 8);
+ len = info[2] | (info[3] << 8);
+
+ /**
+ Review: this message is only for AP mode.
+ TBD
+ **/
+ if (wid == WID_NETWORK_INFO) { /* not send by the firmware */
+
+ }
+
+ return;
+}
+#endif
+
+/********************************************
+
+ Configuration Exported Functions
+
+********************************************/
+
+static int nmi_wlan_cfg_set_wid(uint8_t *frame, uint32_t offset, uint16_t id, uint8_t *buf, int size)
+{
+ uint8_t type = (id >> 12) & 0xf;
+ int ret = 0;
+
+ if (type == 0) { /* byte command */
+ if (size >= 1)
+ ret = nmi_wlan_cfg_set_byte(frame, offset, id, *buf);
+ } else if (type == 1) { /* half word command */
+ if (size >= 2)
+ ret = nmi_wlan_cfg_set_hword(frame, offset, id, *((uint16_t *)buf));
+ } else if (type == 2) { /* word command */
+ if (size >= 4)
+ ret = nmi_wlan_cfg_set_word(frame, offset, id, *((uint32_t *)buf));
+ } else if (type == 3) { /* string command */
+ ret = nmi_wlan_cfg_set_str(frame, offset, id, buf, size);
+ } else if (type == 4) { /* binary command */
+ ret = nmi_wlan_cfg_set_bin(frame, offset, id, buf, size);
+ } else {
+ g_mac.dPrint(N_ERR, "illegal id\n");
+ }
+
+ return ret;
+}
+
+static int nmi_wlan_cfg_get_wid(uint8_t *frame, uint32_t offset, uint16_t id)
+{
+ uint8_t *buf;
+
+ if ((offset + 2) >= MAX_CFG_FRAME_SIZE)
+ return 0;
+
+ buf = &frame[offset];
+
+ buf[0] = (uint8_t)id;
+ buf[1] = (uint8_t)(id>>8);
+
+ return 2;
+}
+
+static int nmi_wlan_cfg_get_wid_value(uint16_t wid, uint8_t *buffer, uint32_t buffer_size)
+{
+ uint32_t type = (wid >> 12) & 0xf;
+ int i, ret = 0;
+
+ if (wid == WID_STATUS) {
+ *((uint32_t *)buffer) = g_mac.mac_status;
+ return 4;
+ }
+
+ i = 0;
+ if (type == 0) { /* byte command */
+ do {
+ if (g_cfg_byte[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_byte[i].id == wid) {
+ memcpy(buffer, &g_cfg_byte[i].val, 1);
+ ret = 1;
+ break;
+ }
+ i++;
+ } while (1);
+ } else if (type == 1) { /* half word command */
+ do {
+ if (g_cfg_hword[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_hword[i].id == wid) {
+ memcpy(buffer, &g_cfg_hword[i].val, 2);
+ ret = 2;
+ break;
+ }
+ i++;
+ } while (1);
+ } else if (type == 2) { /* word command */
+ do {
+ if (g_cfg_word[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_word[i].id == wid) {
+ memcpy(buffer, &g_cfg_word[i].val, 4);
+ ret = 4;
+ break;
+ }
+ i++;
+ } while (1);
+ } else if (type == 3) { /* string command */
+ do {
+ if (g_cfg_str[i].id == WID_NIL)
+ break;
+
+ if (g_cfg_str[i].id == wid) {
+ uint32_t size = g_cfg_str[i].str[0];
+ if (buffer_size >= size) {
+ if(g_cfg_str[i].id == WID_SITE_SURVEY_RESULTS)
+ {
+ static int toggle = 0;
+ PRINT_INFO(GENERIC_DBG,"Site survey results value[%d]\n",
+ size);
+ i += toggle;
+ toggle ^= 1;
+
+ }
+ memcpy(buffer, &g_cfg_str[i].str[1], size);
+ ret = size;
+ }
+ break;
+ }
+ i++;
+ } while (1);
+ } else {
+ g_mac.dPrint(N_ERR, "[CFG]: illegal type (%08x)\n", wid);
+ }
+
+ return ret;
+}
+
+static int nmi_wlan_cfg_indicate_rx(uint8_t *frame, int size, nmi_cfg_rsp_t *rsp)
+{
+ int ret = 1;
+ uint8_t msg_type;
+ uint8_t msg_id;
+ uint16_t msg_len;
+ #ifdef NMI_FULLY_HOSTING_AP
+ NMI_Uint32* ptru32Frame;
+ NMI_Bool bStatus = frame[2];
+
+ #ifdef BIG_ENDIAN
+ ptru32Frame =(frame[4] << 24) |(frame[5] << 16) | (frame[6] << 8) | frame[7];
+ #else
+ ptru32Frame =(frame[7] << 24) |(frame[6] << 16) | (frame[5] << 8) | frame[4];
+ #endif //BIG_ENDIAN
+
+ #endif //NMI_FULLY_HOSTING_AP
+
+ msg_type = frame[0];
+ msg_id = frame[1]; /* seq no */
+#ifdef BIG_ENDIAN
+ msg_len = (frame[2] << 8) | frame[3];
+#else
+ msg_len = (frame[3] << 8) | frame[2];
+#endif
+ frame += 4;
+ size -= 4;
+
+ /**
+ The valid types of response messages are 'R' (Response), 'I' (Information), and 'N' (Network Information)
+ **/
+
+ switch(msg_type) {
+ case 'R':
+ nmi_wlan_parse_response_frame(frame, size);
+ rsp->type = NMI_CFG_RSP;
+ rsp->seq_no = msg_id;
+ break;
+ case 'I':
+ rsp->type = nmi_wlan_parse_info_frame(frame, size);
+ rsp->seq_no = msg_id;
+ /*call host interface info parse as well*/
+ PRINT_INFO(RX_DBG,"Info message received\n");
+ GnrlAsyncInfoReceived(frame-4, size+4);
+ break;
+ case 'L':
+#ifndef SWITCH_LOG_TERMINAL
+ PRINT_ER("Unexpected firmware log message received \n");
+#else
+ PRINT_D(FIRM_DBG,"\nFIRMWARE LOGS :\n<<\n%s\n>>\n",frame);
+ break;
+#endif
+#if 1
+ case 'N':
+ //NMI_PRINTF("[cfg]Network Message Received\n");
+ NetworkInfoReceived(frame-4, size+4);
+ rsp->type = 0;
+ break;
+#endif
+/*bug3819:*/
+ case'S':
+ PRINT_INFO(RX_DBG,"Scan Notification Received \n");
+ host_int_ScanCompleteReceived(frame-4, size+4);
+ break;
+#ifdef NMI_FULLY_HOSTING_AP
+ case'T':
+ PRINT_INFO(RX_DBG,"TBTT Notification Received \n");
+ process_tbtt_isr();
+ break;
+
+ case'A':
+ PRINT_INFO(RX_DBG,"HOSTAPD ACK Notification Received \n");
+ NMI_mgm_HOSTAPD_ACK(ptru32Frame,bStatus);
+ //printk("ptru32Frame = %0x\n",ptru32Frame);
+ break;
+#endif
+
+ default:
+ PRINT_INFO(RX_DBG,"Receive unknown message type[%d-%d-%d-%d-%d-%d-%d-%d]\n",
+ frame[0],frame[1],frame[2],frame[3],frame[4],
+ frame[5],frame[6],frame[7]);
+ rsp->type = 0;
+ rsp->seq_no = msg_id;
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+static int nmi_wlan_cfg_init(nmi_debug_func func)
+{
+ memset((void *)&g_mac, 0, sizeof(nmi_mac_cfg_t));
+ g_mac.dPrint = func;
+ return 1;
+}
+
+nmi_cfg_func_t mac_cfg = {
+ nmi_wlan_cfg_set_wid,
+ nmi_wlan_cfg_get_wid,
+ nmi_wlan_cfg_get_wid_value,
+ nmi_wlan_cfg_indicate_rx,
+ nmi_wlan_cfg_init,
+};
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_Tx_Rx.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_Tx_Rx.c
new file mode 100755
index 00000000..e689f55a
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_Tx_Rx.c
@@ -0,0 +1,63 @@
+//#define SIMULATION_SHARED
+#ifndef SIMULATION_SHARED_SOCKET
+/*!
+* @file Packet_Tx_Rx.c
+* @brief
+* @author
+* @sa
+* @date 5 Mar 2012
+* @version 1.0
+*/
+
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+
+
+extern NMI_Sint32 SimConfigPktReceived(NMI_Sint8* pspacket, NMI_Sint32 s32PacketLen);
+extern NMI_Sint32 ConfigPktReceived(NMI_Uint8* pu8RxData, NMI_Sint32 s32RxDataLen);
+
+
+
+NMI_Sint32 TransportInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ return s32Error;
+}
+
+NMI_Sint32 TransportDeInit(void)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ return s32Error;
+}
+
+NMI_Sint32 SendRawPacket(NMI_Sint8* pspacket, NMI_Sint32 s32PacketLen)
+{
+ NMI_Sint32 s32Error = NMI_SUCCESS;
+
+ s32Error = SimConfigPktReceived(pspacket, s32PacketLen);
+
+ return s32Error;
+}
+
+/**
+* @brief sends the response to the host
+* @details
+* @param[in] host_rsp Pointer to the packet to be sent
+* @param[in] host_rsp_len length of the packet to be sent
+* @return None
+* @note
+* @author Ittiam
+* @date 18 Feb 2010
+* @version
+*/
+
+void send_host_rsp(NMI_Uint8 *host_rsp, NMI_Uint16 host_rsp_len)
+{
+ ConfigPktReceived(host_rsp, host_rsp_len);
+}
+
+
+
+#endif \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_tx_Rx_socket.c b/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_tx_Rx_socket.c
new file mode 100755
index 00000000..307201fa
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/driver/transport/Packet_tx_Rx_socket.c
@@ -0,0 +1,465 @@
+//#define SIMULATION_SHARED_SOCKET
+#ifdef SIMULATION_SHARED_SOCKET
+
+
+#define MAX_BUFFER_LEN 1596
+
+/*!
+* @file UDP SOCKET.c.h
+* @brief A Simulation for the communication betweeen simulator and
+* @author aismail
+* @sa NMI_OSWrapper.h top level OS wrapper file
+* @date 6 Mar 2012
+* @version 1.0
+*/
+
+
+/*******************************************************************************/
+/* SYSTEM INCLUDES */
+/*******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#pragma comment(lib, "Ws2_32.lib")
+WSADATA wsaData;
+
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#define handle_error(msg) \
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+typedef int SOCKET;
+#endif
+
+
+/*******************************************************************************/
+/* PROJECTS INCLUDES */
+/*******************************************************************************/
+#include "NMI_OsWrapper/include/NMI_OSWrapper.h"
+
+
+/*******************************************************************************/
+/* GLOBAL VARIABLES */
+/*******************************************************************************/
+SOCKET SimulatorSocket,ConfiguratorSocket;
+struct sockaddr_in SimulatorAddress,ConfiguratorAddress;
+int sockaddr_len = sizeof(ConfiguratorAddress);
+NMI_ThreadHandle hSimulator,hConfigurator;
+NMI_Uint8 u8ThreadLoopExitCondition = 0x00;
+NMI_Uint8* pu8Buffer_conf;
+NMI_Sint8* ps8Buffer_sim;
+NMI_Sint32 s32Err = 0;
+NMI_Sint8 s8ExitFrame[] = "Exit Frame";
+NMI_Sint8 s8TimeOutFrame[] = "TimeOut Frame";
+
+#ifndef SIMULATION
+NMI_Uint16 u16SimPort=50001;
+NMI_Sint8 s8IPSim[] = "192.168.11.255";
+#else
+NMI_Uint16 u16SimPort=50001;
+NMI_Sint8 s8IPSim[] = "192.168.10.43";
+#endif
+NMI_Uint16 u16ConPort=50000;
+NMI_Sint8 s8IPCon[] = "192.168.10.43";
+
+/*******************************************************************************/
+/* Stubbed Functions */
+/*******************************************************************************/
+extern NMI_Sint32 SimConfigPktReceived(NMI_Sint8* s8A, NMI_Sint32 s32B);
+//extern NMI_Sint32 ConfigPktReceived(NMI_Sint8* pspacket, NMI_Sint32 s32PacketLen);
+extern NMI_Sint32 ConfigPktReceived(NMI_Uint8* pu8RxPacket, NMI_Sint32 s32RxPacketLen);
+
+void sendto_sim(void)
+{
+}
+
+
+
+NMI_Sint32 SocketInit(struct sockaddr_in* pSourceAddress,struct sockaddr_in* pDestinationAddress,SOCKET *pSock,NMI_Uint16 u16PortSource,NMI_Uint16 u16PortDestination,NMI_Uint8* pu8IPSource,NMI_Uint8* pu8IPDestination)
+{
+ NMI_Sint32 s32bind_status=1;
+#ifdef WIN32
+ WSAStartup(MAKEWORD(2,2), &wsaData);
+#endif
+
+ /*Assign IP and port # of my address */
+ pSourceAddress->sin_family = AF_INET;
+ pSourceAddress->sin_port = htons(u16PortSource);
+#ifdef WIN32
+ pSourceAddress->sin_addr.S_un.S_addr = inet_addr(pu8IPSource);
+#else
+ pSourceAddress->sin_addr.s_addr = inet_addr(pu8IPSource);
+#endif
+
+ /*Assign IP and port # of destination address */
+ pDestinationAddress->sin_family = AF_INET;
+ pDestinationAddress->sin_port = htons(u16PortDestination);
+#ifdef WIN32
+ pDestinationAddress->sin_addr.S_un.S_addr = inet_addr(pu8IPDestination);
+#else
+ pDestinationAddress->sin_addr.s_addr= inet_addr(pu8IPDestination);
+#endif
+
+ /* Assign a socket number to my socket */
+ *pSock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); // UDP configuration
+ if(*pSock <0)
+ perror("socket error");
+
+ /* Enable broadcast */
+ //setsockopt(*Pscok,SO_BROADCAST,
+ /* Bind socket to source socket */
+ s32bind_status = bind(*pSock,(struct sockaddr*) pSourceAddress ,sockaddr_len);
+
+ if(s32bind_status == -1)
+#ifdef WIN32
+ printf("Bind Error: %d",WSAGetLastError());
+#else
+ perror("\nBind:");
+#endif
+
+ return s32bind_status;
+}
+
+
+/**
+* @brief Close socket.
+* @details close socket and release any allocated resources by the sockets.
+
+* @param[in,out] N/A
+* @param[in] mySocket the socket required to release its resources.
+* @return return 0 of successfully close.
+* @note could be implemented as inline function of macro
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+NMI_Sint32 deInitSocket(SOCKET mySocket)
+{
+ u8ThreadLoopExitCondition = 0;
+#ifdef WIN32
+ return closesocket(mySocket);
+#else
+ return close(mySocket);
+#endif
+}
+
+
+/**
+* @brief Represent the simulator side
+* @details Reseives data by socket and pass received data to SimConfigPktReceived to be parsed
+ and configure the chip based on the received socket.
+* @param[in,out] N/A
+* @param[in] N/A
+* @return N/A
+* @note N/A
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+
+void SimulatorThread(void *p)
+{
+ NMI_Sint32 s32Error = 0;
+
+ if((ps8Buffer_sim = malloc(MAX_BUFFER_LEN))==NULL)
+ {
+ s32Err = NMI_FAIL;
+ }
+ else
+ {
+ while(!u8ThreadLoopExitCondition)
+ {
+ NMI_Sint32 s32PacketLength;
+ NMI_Uint32 u32MaxBufferLength = MAX_BUFFER_LEN;
+ NMI_Sint32 receive_status = -1;
+
+ s32PacketLength = recvfrom(SimulatorSocket,ps8Buffer_sim,u32MaxBufferLength,0,
+ (struct sockaddr*)&ConfiguratorAddress,&sockaddr_len);// recv from config
+ printf("\nRecv from %d",s32PacketLength);
+ NMI_Sleep(10);
+ if(s32PacketLength < 0) /* Conection failure */
+ {
+#ifdef WIN32
+ receive_status= WSAGetLastError();
+#endif
+ printf("\nConnection Failure: %d",receive_status);
+ }
+ else if(NMI_strcmp(pu8Buffer_conf,s8ExitFrame) == 0) /* check for exit frame packet to Exit while loop and terminate thread */
+ {
+ u8ThreadLoopExitCondition = 0xff;
+ break;
+ }
+ else
+ {
+ receive_status = 0;
+ printf("\nMessage Received: Message Type: %c Seq Num:%d Messege Length: %x",ps8Buffer_sim[0],(NMI_Uint8)ps8Buffer_sim[1],(NMI_Uint16)*((NMI_Uint16*)&ps8Buffer_sim[4]));
+ SimConfigPktReceived(ps8Buffer_sim,s32PacketLength);
+ }
+
+ } /* end while*/
+ } /* end else if */
+
+}
+
+
+/**
+* @brief Represent the configurator side
+* @details Reseives data by socket and pass received data to SimConfigPktReceived to be parsed
+ and configure the chip based on the received socket.
+* @param[in,out] N/A
+* @param[in] N/A
+* @return N/A
+* @note N/A
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+
+void ConfiguratorThread( void *p)
+{
+ //NMI_Uint8 u8Buffer[MAX_BUFFER_LEN];
+ struct sockaddr_in strRecAddr;
+ if((pu8Buffer_conf = malloc(MAX_BUFFER_LEN))== NULL)
+ {
+ s32Err = 6; /* To deInit previous function in TransInit */
+ }
+ else
+ {
+ while(!u8ThreadLoopExitCondition)
+ {
+
+
+ NMI_Sint32 s32PacketLength = 0;
+ NMI_Uint32 u32MaxBufferLength = MAX_BUFFER_LEN;
+
+ NMI_Sint32 receive_status = 0;
+
+ s32PacketLength = recvfrom(ConfiguratorSocket,pu8Buffer_conf,u32MaxBufferLength,0,
+ (struct sockaddr*)&strRecAddr,&sockaddr_len);// recv from config
+
+ if(s32PacketLength < 0)
+ {
+#ifdef WIN32
+ receive_status = WSAGetLastError();
+#endif
+ printf("\nReceive Configurator Error: %d",receive_status);
+ }
+ else
+ {
+ if(NMI_strcmp(pu8Buffer_conf,s8ExitFrame) == 0) /* check for exit frame packet to Exit while loop and terminate thread */
+ {
+ u8ThreadLoopExitCondition = 0xff;
+ break;
+ }
+ else if(NMI_strcmp(pu8Buffer_conf,s8TimeOutFrame) == 0) /* check for exit frame packet to Exit while loop and terminate thread */
+ {
+ continue;
+ }
+ else
+ {
+ receive_status = 0;
+ }
+
+ ConfigPktReceived(pu8Buffer_conf, s32PacketLength);
+ }
+ } /* End while */
+ } /* End if*/
+
+}
+
+
+
+/**
+* @brief SendRawPacket to
+* @details Opens a file, possibly creating a new file if write enabled and
+ pstrAttrs->bCreate is set to true
+* @param[in,out] s32PacketLen to get number of received bytes on the socket
+* @param[in] pspacket holds that data (packet) wanted to send on ConfiguratorSocket to Simulator.
+* @return Error code indicating success/failure: 0 success, error code for failure
+* @note N/A
+ FILE *fopen( const char *filename, const char *mode );
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+NMI_Sint32 SendRawPacket(NMI_Sint8* ps8Packet, NMI_Sint32 s32PacketLen)
+{
+ NMI_Sint32 s32SendStatus = NMI_FAIL;
+
+ s32SendStatus = sendto(ConfiguratorSocket,ps8Packet,s32PacketLen,0,(struct sock_addr*)&SimulatorAddress,sockaddr_len);
+
+ printf("\nSend Raw Data Status: %d",s32SendStatus);
+
+ if(s32SendStatus < 0)
+ {
+#ifdef WIN32
+ printf("Send Raw Packet Error:",WSAGetLastError());
+#else
+ perror("Send Raw Packet Error");
+#endif
+ }
+ else
+ {
+ s32SendStatus = NMI_SUCCESS;
+ }
+
+
+ sendto_sim();
+ printf("\nSend Done");
+
+ return s32SendStatus;
+}
+
+
+
+
+/**
+* @brief Send response from chip(simulator) to configurator
+* @details Send a packet respond on a packet sent to chip.
+* @param[in,out] N/A
+* @param[in] pu8host_rsp holds that data (packet) wanted to send on ConfiguratorSocket to Simulator.
+* @param[in] u16host_rsp_len holds the size of datapacket
+* @return N/A
+* @note N/A
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+void send_host_rsp(NMI_Uint8 *pu8host_rsp, NMI_Uint16 u16host_rsp_len)
+{
+ NMI_Sint32 send_status;
+ send_status = sendto(SimulatorSocket,pu8host_rsp,u16host_rsp_len,0,(struct sock_addr*)&ConfiguratorAddress,sockaddr_len);
+ if(send_status < 0)
+ printf("SendHost Error: %d",GetLastError());
+// perror("Sending Host Error");
+ /*send to config socket*/
+
+ sendto_sim();
+}
+
+/**
+* @brief Initialize sockets and thread creation
+* @details Call functions used in initilizing sockets and thread creation.
+* @param[in,out] N/A
+* @param[in] N/A
+* @return s32Err 0: for success, otherwise for fail.
+* @note In case ofhaving a failure, the returned value is ORing or all failure done. i.e: the value expresses nothing
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 TransportInit( void)
+{
+ NMI_Sint32 s32Error = 0;
+
+
+ /*Initialize Socket */
+ s32Error = SocketInit(&ConfiguratorAddress,&SimulatorAddress,&ConfiguratorSocket,u16ConPort,u16SimPort,s8IPCon,s8IPSim);
+ if(s32Error != 0)
+ NMI_ERRORREPORT(s32Error,1);
+#ifdef SIMULATION
+ s32Error = SocketInit(&SimulatorAddress,&ConfiguratorAddress,&SimulatorSocket,u16SimPort,u16ConPort,s8IPSim,s8IPCon);
+ if(s32Error != 0)
+ NMI_ERRORREPORT(s32Error,2);
+
+ /* Create Thread */
+ s32Error = NMI_ThreadCreate(&hSimulator,SimulatorThread,NULL, NULL);
+ if(s32Error != 0)
+ NMI_ERRORREPORT(s32Error,3);
+
+#endif
+
+ s32Error = NMI_ThreadCreate(&hConfigurator,ConfiguratorThread,NULL, NULL);
+ if(s32Err != 0)
+ NMI_ERRORREPORT(s32Error,4);
+
+
+
+
+ERRORHANDLER:
+ switch(s32Err)
+ {
+ case 4:
+ case 6:
+ NMI_ThreadDestroy(&hSimulator, NULL);
+ free(ps8Buffer_sim);
+ case 3:
+ case 5:
+ deInitSocket(SimulatorSocket);
+ case 2:
+ deInitSocket(ConfiguratorSocket);
+ break;
+ }
+
+ return s32Err;
+}
+
+
+/**
+* @brief deInitialize sockets and thread creation
+* @details Wait till threads do their work and kill them and after that call deInitsocket
+* @param[in,out] N/A
+* @param[in] N/A
+* @return s32Err 0: for success, otherwise for fail.
+* @note In case ofhaving a failure, the returned value is ORing or all failure done. i.e: the value expresses nothing
+* @author aismail
+* @date 6 Mar 2012
+* @version 1.0
+*/
+
+NMI_Sint32 TransportDeInit( void)
+{
+ NMI_Sint32 s32Err = 0;
+ u8ThreadLoopExitCondition = 0xff;
+
+ /* Send exit condition to running threads */
+ sendto(SimulatorSocket,s8ExitFrame,NMI_strlen(s8ExitFrame)+1,0,(struct sock_addr*)&ConfiguratorAddress,sockaddr_len);
+ sendto(ConfiguratorSocket,s8ExitFrame,NMI_strlen(s8ExitFrame)+1,0,(struct sock_addr*)&SimulatorAddress,sockaddr_len);
+
+ /* Wait till finish to distory thread */
+#ifdef SIMULATION
+ s32Err |= NMI_ThreadDestroy(&hSimulator, NULL);
+#endif
+ s32Err |= NMI_ThreadDestroy(&hConfigurator, NULL);
+
+
+ /* deInit socket and release used resources */
+#ifdef SIMULATION
+ s32Err |= deInitSocket(SimulatorSocket);
+#endif
+ s32Err |= deInitSocket(ConfiguratorSocket);
+
+ free(pu8Buffer_conf);
+ free(ps8Buffer_sim);
+
+
+ return s32Err;
+
+}
+
+
+/**
+* @brief Send Time Out Frame to avoid receive blocking
+* @details Send time out frame to avoid blocking on receiving state and back to normal state.
+* @param[in,out] N/A
+* @param[in] N/A
+* @return s32Err 0: for success, otherwise for fail.
+* @note In case ofhaving a failure, the returned value is ORing or all failure done. i.e: the value expresses nothing
+* @author aismail
+* @date 3 Apr 2012
+* @version 1.0
+*/
+void SendTimeOutFrame(void *p)
+{
+ sendto(ConfiguratorSocket,s8TimeOutFrame,NMI_strlen(s8TimeOutFrame)+1,0,(struct sock_addr*)&SimulatorAddress,sockaddr_len);
+
+}
+
+#endif
+
+
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/Makefile b/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/Makefile
new file mode 100755
index 00000000..a29f4fd8
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/Makefile
@@ -0,0 +1,3 @@
+obj-m += nmc1xxx_mempool.o
+
+nmc1xxx_mempool-objs += nmc1000_exported_buf.o \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/nmc1000_exported_buf.c b/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/nmc1000_exported_buf.c
new file mode 100755
index 00000000..6860c41d
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/nmi_memory/nmc1000_exported_buf.c
@@ -0,0 +1,79 @@
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#define LINUX_RX_SIZE (96*1024)
+#define LINUX_TX_SIZE (64*1024)
+#define NMC1000_FW_SIZE (4*1024)
+
+#define DECLARE_NMC_BUFFER(name) \
+ void *exported_##name = NULL;
+
+#define MALLOC_NMC_BUFFER(name, size) \
+ exported_##name = kmalloc(size, GFP_KERNEL); \
+ if(!exported_##name){ \
+ printk("fail to alloc: %s memory\n", exported_##name); \
+ return -ENOBUFS; \
+ }
+
+#define FREE_NMC_BUFFER(name) \
+ kfree(exported_##name);
+
+/*
+* Add necessary buffer pointers
+*/
+DECLARE_NMC_BUFFER(g_tx_buf)
+DECLARE_NMC_BUFFER(g_rx_buf)
+DECLARE_NMC_BUFFER(g_fw_buf)
+
+void *get_tx_buffer(void)
+{
+ printk("[mem] tx_buf = 0x%x\n", exported_g_tx_buf);
+ return exported_g_tx_buf;
+}
+EXPORT_SYMBOL(get_tx_buffer);
+
+void *get_rx_buffer(void)
+{
+ printk("[mem] rx_buf = 0x%x\n", exported_g_rx_buf);
+ return exported_g_rx_buf;
+}
+EXPORT_SYMBOL(get_rx_buffer);
+
+void *get_fw_buffer(void)
+{
+ printk("[mem] fw_buf = 0x%x\n", exported_g_fw_buf);
+ return exported_g_fw_buf;
+}
+EXPORT_SYMBOL(get_fw_buffer);
+
+static int __init nmc_module_init(void)
+{
+ printk("nmc_module_init\n");
+ /*
+ * alloc necessary memory
+ */
+ MALLOC_NMC_BUFFER(g_tx_buf, LINUX_TX_SIZE)
+ MALLOC_NMC_BUFFER(g_rx_buf, LINUX_RX_SIZE)
+ MALLOC_NMC_BUFFER(g_fw_buf, NMC1000_FW_SIZE)
+
+ return 0;
+}
+
+static void __exit nmc_module_deinit(void)
+{
+ printk("nmc_module_deinit\n");
+ FREE_NMC_BUFFER(g_tx_buf)
+ FREE_NMC_BUFFER(g_rx_buf)
+ FREE_NMC_BUFFER(g_fw_buf)
+
+ return;
+}
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Tony Cho");
+MODULE_DESCRIPTION("NMC1xxx Memory Manager");
+pure_initcall(nmc_module_init);
+module_exit(nmc_module_deinit); \ No newline at end of file
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/svnrevision.h b/drivers/net/wireless/nmi_android4.4_driver/src/svnrevision.h
new file mode 100755
index 00000000..0c57aafc
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/svnrevision.h
@@ -0,0 +1,5 @@
+#ifndef SVNREV_H
+#define SVNREV_H
+#define SVNREV "275"
+#define SVNURL "svn://ssw.gotdns.org/nmc100x/trunk"
+#endif
diff --git a/drivers/net/wireless/nmi_android4.4_driver/src/verify_fw_version.c b/drivers/net/wireless/nmi_android4.4_driver/src/verify_fw_version.c
new file mode 100755
index 00000000..594d9130
--- /dev/null
+++ b/drivers/net/wireless/nmi_android4.4_driver/src/verify_fw_version.c
@@ -0,0 +1,141 @@
+
+#define VERSION_ERROR_STRINTG "Current driver doesn't support the requested firmware"
+
+enum {
+ OP_STATION_MODE = 0,
+ OP_AP_MODE,
+ OP_P2P,
+
+ OP_MAX
+};
+
+struct nmc_version {
+ char driver_ver[10]; // wifi driver version
+ char op_mode; // wifi mode
+ char fw_ver[10]; // wifi firmware version
+ u32 fw_size; // wifi firmware size
+};
+
+static struct nmc_version nmc_ver_list[] =
+{
+ { "9.3.0", STATION_MODE, "0", 143808},
+ { "9.3.0", AP_MODE, "0", 111416},
+ { "9.3.0", GO_MODE|CLIENT_MODE, "0", 141944},
+
+ { "9.3.0", STATION_MODE, "1", 143816},
+ { "9.3.0", AP_MODE, "1", 111420},
+ { "9.3.0", GO_MODE|CLIENT_MODE, "1", 141864},
+
+ { "9.3.1", STATION_MODE, "0", 143808},
+ { "9.3.1", AP_MODE, "0", 111416},
+ { "9.3.1", GO_MODE|CLIENT_MODE, "0", 141944},
+
+ { "9.3.1", STATION_MODE, "1", 143816},
+ { "9.3.1", AP_MODE, "1", 111420},
+ { "9.3.1", GO_MODE|CLIENT_MODE, "1", 141864},
+
+ { "9.3.2", STATION_MODE, "0", 143832},
+ { "9.3.2", AP_MODE, "0", 111448},
+ { "9.3.2", GO_MODE|CLIENT_MODE, "0", 141876},
+
+ { "9.3.3", STATION_MODE, "0", 144012},
+ { "9.3.3", AP_MODE, "0", 112432},
+ { "9.3.3", GO_MODE|CLIENT_MODE, "0", 142084},
+};
+
+
+int check_firmware_version(char iftype, char* driver_version, u32 given_firmware_size)
+{
+ int ret = -1;
+ int i = 0;
+ int cnt = 0;
+
+ cnt = sizeof(nmc_ver_list)/sizeof(struct nmc_version);
+
+ if ( ( iftype == 0 ) || ( driver_version == NULL ) || ( given_firmware_size == 0 ) )
+ {
+ printk("[NMI] invaild arguments\n");
+ return -1;
+ }
+
+ printk("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ printk("[NMI] iftype = %d, driver_version = %s, given_firmware_size = %d, nmc_ver_list count = %d\n", iftype, driver_version, given_firmware_size, cnt);
+
+ switch (iftype)
+ {
+ case STATION_MODE:
+
+ for ( i = OP_STATION_MODE ; i < cnt ; i += OP_MAX )
+ {
+ if ( strcmp(nmc_ver_list[i].driver_ver, driver_version) == 0 )
+ {
+ if ( nmc_ver_list[i].fw_size == given_firmware_size )
+ {
+ printk("[NMI][STATION_MODE] : firmware version level = %s for %s driver\n",nmc_ver_list[i].fw_ver, nmc_ver_list[i].driver_ver);
+
+ return ret = 0;
+ }
+ }
+ }
+
+ printk("[NMI][OP_STATION_MODE] : %s\n",VERSION_ERROR_STRINTG);
+
+ ret = -1;
+
+ break;
+
+ case AP_MODE:
+
+ for ( i = OP_AP_MODE ; i < cnt ; i += OP_MAX )
+ {
+ if ( strcmp(nmc_ver_list[i].driver_ver, driver_version) == 0 )
+ {
+ if ( nmc_ver_list[i].fw_size == given_firmware_size )
+ {
+ printk("[NMI][OP_AP_MODE] :firmware version level = %s for %s driver\n",nmc_ver_list[i].fw_ver, nmc_ver_list[i].driver_ver);
+
+ return ret = 0;
+ }
+ }
+ }
+
+ printk("[NMI][OP_AP_MODE] : %s\n",VERSION_ERROR_STRINTG);
+
+ ret = -1;
+
+ break;
+
+ case GO_MODE:
+ case CLIENT_MODE:
+
+ for ( i = OP_P2P ; i < cnt ; i += OP_MAX )
+ {
+ if ( strcmp(nmc_ver_list[i].driver_ver, driver_version) == 0 )
+ {
+ if ( nmc_ver_list[i].fw_size == given_firmware_size )
+ {
+ printk("[NMI][OP_P2P] : firmware version level = %s for %s driver\n",nmc_ver_list[i].fw_ver, nmc_ver_list[i].driver_ver);
+
+ return ret = 0;
+ }
+ }
+ }
+
+ printk("[NMI][OP_P2P] : %s\n",VERSION_ERROR_STRINTG);
+
+ ret = -1;
+
+ break;
+
+
+ default:
+ printk("[NMI][UNKNOWN Mode] : %s\n",VERSION_ERROR_STRINTG);
+
+ ret = -1;
+ break;
+
+
+ }
+
+ return ret;
+}