From 871480933a1c28f8a9fed4c4d34d06c439a7a422 Mon Sep 17 00:00:00 2001 From: Srikant Patnaik Date: Sun, 11 Jan 2015 12:28:04 +0530 Subject: Moved, renamed, and deleted files The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure. --- .../net/wireless/nmi/Nmc1000_Release7.0/Makefile | 20 + .../NMI_c1000_Driver_Porting_Guide.doc | Bin 0 -> 141824 bytes .../NMI_c1000_REL06_2_1_MAY_2013.doc | Bin 0 -> 154112 bytes .../NMI_c1000_REL07_0_6_JUN_2013.doc | Bin 0 -> 156160 bytes .../src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h | 55 + .../src/NMI_OsWrapper/OsKconfig/Kconfig | 116 + .../binary/windows/NMI_OsWrapper_win32.lib | Bin 0 -> 356008 bytes .../src/NMI_OsWrapper/doc/PublicAPI.doxygen | 263 + .../src/NMI_OsWrapper/doc/runDoxygen.bat | 1 + .../src/NMI_OsWrapper/include/NMI_ErrorSupport.h | 84 + .../src/NMI_OsWrapper/include/NMI_Event.h | 124 + .../src/NMI_OsWrapper/include/NMI_FileOps.h | 456 ++ .../src/NMI_OsWrapper/include/NMI_Log.h | 43 + .../src/NMI_OsWrapper/include/NMI_Math.h | 368 ++ .../src/NMI_OsWrapper/include/NMI_Memory.h | 330 + .../src/NMI_OsWrapper/include/NMI_MsgQueue.h | 134 + .../src/NMI_OsWrapper/include/NMI_OSWrapper.h | 133 + .../src/NMI_OsWrapper/include/NMI_Semaphore.h | 116 + .../src/NMI_OsWrapper/include/NMI_Sleep.h | 45 + .../src/NMI_OsWrapper/include/NMI_Socket.h | 95 + .../src/NMI_OsWrapper/include/NMI_StrUtils.h | 415 ++ .../src/NMI_OsWrapper/include/NMI_Thread.h | 155 + .../src/NMI_OsWrapper/include/NMI_Time.h | 207 + .../src/NMI_OsWrapper/include/NMI_Timer.h | 154 + .../src/NMI_OsWrapper/include/NMI_platform.h | 207 + .../src/NMI_OsWrapper/source/linux/Makefile | 67 + .../source/linux/include/NMI_platform.h | 209 + .../NMI_OsWrapper/source/linux/source/NMI_Event.c | 112 + .../source/linux/source/NMI_FileOps.c | 539 ++ .../NMI_OsWrapper/source/linux/source/NMI_Math.c | 440 ++ .../NMI_OsWrapper/source/linux/source/NMI_Memory.c | 72 + .../source/linux/source/NMI_MsgQueue.c | 213 + .../source/linux/source/NMI_Semaphore.c | 67 + .../NMI_OsWrapper/source/linux/source/NMI_Sleep.c | 27 + .../NMI_OsWrapper/source/linux/source/NMI_Socket.c | 188 + .../source/linux/source/NMI_StrUtils.c | 483 ++ .../NMI_OsWrapper/source/linux/source/NMI_Thread.c | 52 + .../NMI_OsWrapper/source/linux/source/NMI_Time.c | 167 + .../NMI_OsWrapper/source/linux/source/NMI_Timer.c | 181 + .../src/NMI_OsWrapper/source/linuxkernel/Makefile | 71 + .../source/linuxkernel/include/NMI_platform.h | 184 + .../source/linuxkernel/source/NMI_Memory.c | 71 + .../source/linuxkernel/source/NMI_MsgQueue.c | 234 + .../source/linuxkernel/source/NMI_Semaphore.c | 78 + .../source/linuxkernel/source/NMI_Sleep.c | 39 + .../source/linuxkernel/source/NMI_StrUtils.c | 482 ++ .../source/linuxkernel/source/NMI_Thread.c | 38 + .../source/linuxkernel/source/NMI_Time.c | 163 + .../source/linuxkernel/source/NMI_Timer.c | 52 + .../source/win32/include/NMI_platform.h | 160 + .../nmi/Nmc1000_Release7.0/src/driver/Makefile | 121 + .../nmi/Nmc1000_Release7.0/src/driver/Makefile_US | 53 + .../Nmc1000_Release7.0/src/driver/NMI_host_AP.c | 339 + .../driver/core_configurator/CoreConfigurator.c | 2285 +++++++ .../driver/core_simulator/CoreConfigSimulator.c | 4739 ++++++++++++++ .../src/driver/core_simulator/FIFO_Buffer.c | 182 + .../src/driver/include/CoreConfigSimulator.h | 20 + .../src/driver/include/CoreConfigurator.h | 496 ++ .../src/driver/include/FIFO_Buffer.h | 23 + .../src/driver/include/NMI_host_AP.h | 145 + .../src/driver/include/host_interface.h | 1144 ++++ .../Nmc1000_Release7.0/src/driver/include/itypes.h | 59 + .../src/driver/include/linux_wlan_common.h | 132 + .../src/driver/include/nmi_type.h | 34 + .../src/driver/include/nmi_wlan.h | 335 + .../src/driver/include/nmi_wlan_cfg.h | 33 + .../src/driver/include/nmi_wlan_if.h | 939 +++ .../Nmc1000_Release7.0/src/driver/linux/Makefile | 155 + .../src/driver/linux/allwinner_run_eval.sh | 4 + .../src/driver/linux/ap_soft.conf | 34 + .../driver/linux/include/NMI_WFI_CfgOperations.h | 82 + .../src/driver/linux/include/NMI_WFI_NetDevice.h | 266 + .../src/driver/linux/init_deinit_test.sh | 51 + .../src/driver/linux/nmi_wfi_load | 10 + .../src/driver/linux/nmi_wfi_unload | 6 + .../src/driver/linux/panda_run_eval.sh | 6 + .../src/driver/linux/panda_run_fpga.sh | 4 + .../driver/linux/source/NMI_WFI_CfgOperations.c | 3281 ++++++++++ .../src/driver/linux/source/NMI_WFI_NetDevice.c | 969 +++ .../src/driver/linux/source/linux_mon.c | 521 ++ .../src/driver/linux/source/linux_wlan.c | 2561 ++++++++ .../src/driver/linux/source/linux_wlan_sdio.c | 282 + .../src/driver/linux/source/linux_wlan_sdio.h | 14 + .../src/driver/linux/source/linux_wlan_spi.c | 489 ++ .../src/driver/linux/source/linux_wlan_spi.h | 14 + .../src/driver/linux/source/nmi_custom_gpio.c | 169 + .../src/driver/linux/source/nmi_debugfs.c | 264 + .../src/driver/linux/source/nmi_queue.c | 235 + .../src/driver/linux/source/nmi_queue.h | 56 + .../src/driver/linux/source/nmi_wm8880_gpio.c | 87 + .../driver/nmi_driver_interface/host_interface.c | 6609 ++++++++++++++++++++ .../nmi/Nmc1000_Release7.0/src/driver/nmi_sdio.c | 1490 +++++ .../nmi/Nmc1000_Release7.0/src/driver/nmi_spi.c | 1466 +++++ .../nmi/Nmc1000_Release7.0/src/driver/nmi_wlan.c | 2501 ++++++++ .../Nmc1000_Release7.0/src/driver/nmi_wlan_cfg.c | 621 ++ .../src/driver/transport/Packet_Tx_Rx.c | 63 + .../src/driver/transport/Packet_tx_Rx_socket.c | 465 ++ .../nmi/Nmc1000_Release7.0/src/svnrevision.h | 6 + 98 files changed, 41770 insertions(+) create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/Makefile create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_Driver_Porting_Guide.doc create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL06_2_1_MAY_2013.doc create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL07_0_6_JUN_2013.doc create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/OsKconfig/Kconfig create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/PublicAPI.doxygen create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/runDoxygen.bat create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_ErrorSupport.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Event.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_FileOps.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Log.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Math.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Memory.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_MsgQueue.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_OSWrapper.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Semaphore.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Sleep.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Socket.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_StrUtils.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Thread.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Time.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Timer.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_platform.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/Makefile create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/include/NMI_platform.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Event.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Math.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Time.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/Makefile create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/win32/include/NMI_platform.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/Makefile create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/Makefile_US create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/NMI_host_AP.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_configurator/CoreConfigurator.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_simulator/CoreConfigSimulator.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_simulator/FIFO_Buffer.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/CoreConfigSimulator.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/CoreConfigurator.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/FIFO_Buffer.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/NMI_host_AP.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/host_interface.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/itypes.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/linux_wlan_common.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_type.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan_cfg.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan_if.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/Makefile create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/allwinner_run_eval.sh create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/ap_soft.conf create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_CfgOperations.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_NetDevice.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/init_deinit_test.sh create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_load create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_unload create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/panda_run_eval.sh create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/panda_run_fpga.sh create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_CfgOperations.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_NetDevice.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_mon.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_custom_gpio.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_debugfs.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.h create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_wm8880_gpio.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_driver_interface/host_interface.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_sdio.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_spi.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan_cfg.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/transport/Packet_Tx_Rx.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/transport/Packet_tx_Rx_socket.c create mode 100755 drivers/net/wireless/nmi/Nmc1000_Release7.0/src/svnrevision.h (limited to 'drivers/net/wireless/nmi/Nmc1000_Release7.0') diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/Makefile b/drivers/net/wireless/nmi/Nmc1000_Release7.0/Makefile new file mode 100755 index 00000000..b3d075f3 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/Makefile @@ -0,0 +1,20 @@ +#ARCH = arm +ARCH = x86 +MAKE = make +#CC = arm-linux-gcc +#AR = arm-linux-ar +RM = rm +MV = mv +ECHO = echo +CP = cp +PWD = $(shell pwd) + + +KERNELDIR ?= /lib/modules/$(shell uname -r)/build + +all: + $(MAKE) -C ./driver/linux + + +clean: + $(MAKE) -C ./driver/linux clean diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_Driver_Porting_Guide.doc b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_Driver_Porting_Guide.doc new file mode 100755 index 00000000..a415ab3d Binary files /dev/null and b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_Driver_Porting_Guide.doc differ diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL06_2_1_MAY_2013.doc b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL06_2_1_MAY_2013.doc new file mode 100755 index 00000000..0d55facb Binary files /dev/null and b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL06_2_1_MAY_2013.doc differ diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL07_0_6_JUN_2013.doc b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL07_0_6_JUN_2013.doc new file mode 100755 index 00000000..91eca92a Binary files /dev/null and b/drivers/net/wireless/nmi/Nmc1000_Release7.0/NMI_c1000_REL07_0_6_JUN_2013.doc differ diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/OsConfig/NMI_OSConfig.h new file mode 100755 index 00000000..0e723261 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/OsKconfig/Kconfig b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/OsKconfig/Kconfig new file mode 100755 index 00000000..9da064d8 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib new file mode 100755 index 00000000..f76d5bfd Binary files /dev/null and b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/binary/windows/NMI_OsWrapper_win32.lib differ diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/PublicAPI.doxygen b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/PublicAPI.doxygen new file mode 100755 index 00000000..7f92699e --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/runDoxygen.bat b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/doc/runDoxygen.bat new file mode 100755 index 00000000..ed03d6b2 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_ErrorSupport.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_ErrorSupport.h new file mode 100755 index 00000000..7924e4e2 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Event.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Event.h new file mode 100755 index 00000000..0d38f5da --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_FileOps.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_FileOps.h new file mode 100755 index 00000000..42f0c8cd --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Log.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Log.h new file mode 100755 index 00000000..2c149e06 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Math.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Math.h new file mode 100755 index 00000000..7adcc78b --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Memory.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Memory.h new file mode 100755 index 00000000..27ac5e2b --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_MsgQueue.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_MsgQueue.h new file mode 100755 index 00000000..e2d21572 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_OSWrapper.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_OSWrapper.h new file mode 100755 index 00000000..07d755d4 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Semaphore.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Semaphore.h new file mode 100755 index 00000000..dc65fb84 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Sleep.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Sleep.h new file mode 100755 index 00000000..f183ed17 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Socket.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Socket.h new file mode 100755 index 00000000..cd7ff454 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_StrUtils.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_StrUtils.h new file mode 100755 index 00000000..ae99958d --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Thread.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Thread.h new file mode 100755 index 00000000..42ff55cd --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Time.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Time.h new file mode 100755 index 00000000..653d9099 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Timer.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_Timer.h new file mode 100755 index 00000000..ee1978f7 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_platform.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/include/NMI_platform.h new file mode 100755 index 00000000..f814dd97 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/Makefile b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/Makefile new file mode 100755 index 00000000..7482ef0d --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/include/NMI_platform.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/include/NMI_platform.h new file mode 100755 index 00000000..14883a7c --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Event.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Event.c new file mode 100755 index 00000000..29bd2cfa --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_FileOps.c new file mode 100755 index 00000000..a9ce643d --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Math.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Math.c new file mode 100755 index 00000000..48bfa805 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Memory.c new file mode 100755 index 00000000..d3b4ecaa --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_MsgQueue.c new file mode 100755 index 00000000..caa814bb --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Semaphore.c new file mode 100755 index 00000000..d07bfa0d --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Sleep.c new file mode 100755 index 00000000..b55abaaa --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Socket.c new file mode 100755 index 00000000..0f76f79a --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_StrUtils.c new file mode 100755 index 00000000..18a14937 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Thread.c new file mode 100755 index 00000000..0db814b9 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Time.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Time.c new file mode 100755 index 00000000..2db75643 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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, ¤t_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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linux/source/NMI_Timer.c new file mode 100755 index 00000000..0d3d136d --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/Makefile b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/Makefile new file mode 100755 index 00000000..0fea48cc --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/Makefile @@ -0,0 +1,71 @@ +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 +MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm +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 +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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/include/NMI_platform.h new file mode 100755 index 00000000..8b6f7d85 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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; + NMI_Bool bExiting; + NMI_Uint32 u32ReceiversCount; + NMI_SemaphoreHandle strCriticalSection; + 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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Memory.c new file mode 100755 index 00000000..d73bdaf4 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c new file mode 100755 index 00000000..88e4e267 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_MsgQueue.c @@ -0,0 +1,234 @@ + +#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; + tstrNMI_SemaphoreAttrs strSemAttrs; + + 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); + + 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 */ + NMI_SemaphoreAcquire(&pHandle->strCriticalSection, NMI_NULL); + pHandle->u32ReceiversCount--; + NMI_SemaphoreRelease(&pHandle->strCriticalSection, NMI_NULL); + } + else + { + /* other non-timeout scenarios */ + 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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Semaphore.c new file mode 100755 index 00000000..203ff42c --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Sleep.c new file mode 100755 index 00000000..9d0334d9 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_StrUtils.c new file mode 100755 index 00000000..2e3c206e --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Thread.c new file mode 100755 index 00000000..325afbd7 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Time.c new file mode 100755 index 00000000..63dbbdbb --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c new file mode 100755 index 00000000..a9375419 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/linuxkernel/source/NMI_Timer.c @@ -0,0 +1,52 @@ + +#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(pHandle); + s32RetStatus = del_timer_sync(pHandle); // tony + 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/Nmc1000_Release7.0/src/NMI_OsWrapper/source/win32/include/NMI_platform.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/NMI_OsWrapper/source/win32/include/NMI_platform.h new file mode 100755 index 00000000..868d8473 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/Makefile b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/Makefile new file mode 100755 index 00000000..8c49ca89 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/Makefile @@ -0,0 +1,121 @@ +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 + +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 +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 +MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm +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 +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 + + +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/Nmc1000_Release7.0/src/driver/Makefile_US b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/Makefile_US new file mode 100755 index 00000000..b8863b69 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/NMI_host_AP.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/NMI_host_AP.c new file mode 100755 index 00000000..5bebfc2c --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/NMI_host_AP.c @@ -0,0 +1,339 @@ +/*! +* @file NMI_host_AP.c +* @brief code related to AP mode on driver +* @author asobhy +* @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 + + +beacon_info strBeaconInfo = {0}; + + +/* +* @brief NMI_beacon_tx_complete +* @details call back function for beacon transmission through vmm , does nothing at the moment +* @return +* @author asobhy +* @date 09 APRIL 2013 +* @version 1.0 +*/ +static void NMI_beacon_tx_complete(void* priv, int status) +{ + + 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 asobhy +* @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 asobhy +* @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"); + + /* 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 asobhy +* @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 asobhy +* @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; + + // TODO: + /* 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(BTRUE == get_mc_bit_bcn(old_bcn_idx)) + while(requeue_ps_packet(NULL, &g_mc_q, BTRUE, BFALSE) + == 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 ; + + // TODO: + /* 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(g_beacon_index);*/ + + /* send the updated beacon to firmware */ + NMI_beacon_xmit(strBeaconInfo.u8beacon_frame,strBeaconInfo.u16beacon_len); + + + } + + +} + + +#endif + + diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_configurator/CoreConfigurator.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_configurator/CoreConfigurator.c new file mode 100755 index 00000000..480b0657 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_configurator/CoreConfigurator.c @@ -0,0 +1,2285 @@ + +/*! +* @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[NUM_TOTAL_SWITCHES] = +{ + {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_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 */ +}; + +/*****************************************************************************/ +/* 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_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; +} + +/* 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; + + 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); + + /* 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); + + 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 < 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_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_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))) + { + 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))) + { + ret = -1; + printk("[Sendconfigpkt]Set Timed out\n"); + break; + } + } + } + + return ret; +} +#endif +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_simulator/CoreConfigSimulator.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_simulator/CoreConfigSimulator.c new file mode 100755 index 00000000..8411e135 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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 4 +#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 4 +#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 8 +#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/Nmc1000_Release7.0/src/driver/core_simulator/FIFO_Buffer.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/core_simulator/FIFO_Buffer.c new file mode 100755 index 00000000..d70f6762 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/CoreConfigSimulator.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/CoreConfigSimulator.h new file mode 100755 index 00000000..8df2ab35 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/CoreConfigurator.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/CoreConfigurator.h new file mode 100755 index 00000000..3cb2a980 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/CoreConfigurator.h @@ -0,0 +1,496 @@ + +/*! +* @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 + +#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 */ + +#define NUM_TOTAL_SWITCHES (NUM_BASIC_SWITCHES + NUM_FHSS_SWITCHES + NUM_11N_BASIC_SWITCHES + NUM_11N_HUT_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 8 +#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; +/* 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 u32TimeRcvdInScan; /* of type unsigned long to be accepted by the linux kernel macro time_after() */ +#ifdef AGING_ALG + NMI_Uint8 u8Found; +#endif + NMI_Uint8 *pu8IEs; + NMI_Uint16 u16IEsLen; +}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; + +#ifdef NMI_P2P +/*Structure to hold Received mgmt frame*/ +typedef struct _tstrRcvdMgmtFrame +{ + NMI_Uint8* pu8Buffer; + NMI_Uint32 u32Length; +}tstrRcvdMgmtFrame; +#endif + +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); +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/Nmc1000_Release7.0/src/driver/include/FIFO_Buffer.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/FIFO_Buffer.h new file mode 100755 index 00000000..086ca1ac --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/NMI_host_AP.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/NMI_host_AP.h new file mode 100755 index 00000000..9dac67f4 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/NMI_host_AP.h @@ -0,0 +1,145 @@ +#ifndef __NMI_HOST_AP__ +#define __NMI_HOST_AP__ + +#include "nmi_wlan_if.h" +#include "nmi_wlan.h" +#include "host_interface.h" + +#ifdef NMI_FULLY_HOSTING_AP +/*! +* @file NMI_host_AP.h +* @brief code related to AP fully hosting mode on NMI driver +* @author asobhy +* @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 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)) + + + +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; + +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 { + 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; + 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; + + + 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); + + 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 + + +#endif // NMI_FULLY_HOSTING_AP + +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/host_interface.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/host_interface.h new file mode 100755 index 00000000..1006f797 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/host_interface.h @@ -0,0 +1,1144 @@ +/*! +* @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 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 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 enum +{ + HOST_IF_IDLE = 0, + HOST_IF_SCANNING = 1, + HOST_IF_WAITING_CONN_REQ = 2, + HOST_IF_WAITING_CONN_RESP = 3, + HOST_IF_CONNECTED = 4, + 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]; +}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*); + +/*Connect callBack function definition*/ +typedef void(*tNMIpfConnectResult)(tenuConnDisconnEvent, + tstrConnectInfo*, + NMI_Uint8, + tstrDisconnectNotifInfo*, + void*); + +#ifdef NMI_P2P +/*Receving mgmt frame callback function*/ +typedef void(*tNMIpfRemainOnChan)(tstrRcvdMgmtFrame *,void*); + +/*Remain on channel callback function*/ +typedef void(*tNMIpfRemainOnChanExpired)(void*); +#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; + +#ifdef NMI_P2P +typedef struct +{ + NMI_Uint16 channel; + NMI_Uint32 u32duration; + tNMIpfRemainOnChan RxProbeReq; + tNMIpfRemainOnChanExpired pRemainOnChanExpired; + void * pVoid; +}tstrHostIfRemainOnChan; +#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; + #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; +}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 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); + +/** +* @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); + +#ifdef NMI_P2P +/** +* @brief host_int_remain_on_channel +* @details Remaining on specific channel required by wpas +* @param[in] +* @return Error code. +* @author Mai Daftedar +* @date +* @version 1.0 +*/ +NMI_Sint32 host_int_remain_on_channel(NMI_WFIDrvHandle hWFIDrv, NMI_Uint32 u32duration,NMI_Uint16 chan, tNMIpfRemainOnChan RxMgmt,tNMIpfRemainOnChanExpired RemainOnChanExpired,void* pvUserArg); +#endif + +static NMI_Sint32 Handle_ScanDone(tenuScanEvent enuEvent); + +static int host_int_addBASession(char* pBSSID,char TID,short int BufferSize, + short int SessionTimeout); + + +/*****************************************************************************/ +/* */ +/* EOF */ +/* */ +/*****************************************************************************/ +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/itypes.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/itypes.h new file mode 100755 index 00000000..c3600183 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/linux_wlan_common.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/linux_wlan_common.h new file mode 100755 index 00000000..a80aaa43 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/linux_wlan_common.h @@ -0,0 +1,132 @@ +#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, + + /*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) + +/*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(®ION))&(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(®ION))&(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(®ION))&(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 + +#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") + +//#define LINUX_RX_SIZE (8*1024) +#define LINUX_TX_SIZE (8*1024) + +#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 +#else + #define MODALIAS "NMI_SPI" + #define GPIO_NUM 139 + +#endif + + +void linux_wlan_enable_irq(void); +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_type.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_type.h new file mode 100755 index 00000000..b04901b5 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/nmi_wlan.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan.h new file mode 100755 index 00000000..ee54275f --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan.h @@ -0,0 +1,335 @@ +#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 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) + +/******************************************** + + 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 +#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) + + + +/******************************************** + + 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 +#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; + int type; + 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[4]; + 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/Nmc1000_Release7.0/src/driver/include/nmi_wlan_cfg.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan_cfg.h new file mode 100755 index 00000000..5f604cdf --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/include/nmi_wlan_if.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan_if.h new file mode 100755 index 00000000..36db058e --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/include/nmi_wlan_if.h @@ -0,0 +1,939 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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 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); + 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; + + //uint32_t rx_buffer_size; + 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 + +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); + int (*wlan_cfg_get)(int, uint32_t, int); + 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); + #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, +}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 { + 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, + + /* 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, + /* 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, + /*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, + + + + + /* 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, + + /* 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/Nmc1000_Release7.0/src/driver/linux/Makefile b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/Makefile new file mode 100755 index 00000000..29173a6a --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/Makefile @@ -0,0 +1,155 @@ +# 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 +#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 + +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 +MAKE_FLAGS := CROSS_COMPILE=$(DEV_TREE)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm +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 +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/Nmc1000_Release7.0/src/driver/linux/allwinner_run_eval.sh b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/allwinner_run_eval.sh new file mode 100755 index 00000000..879a98fc --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/ap_soft.conf b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/ap_soft.conf new file mode 100755 index 00000000..b00fb121 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/ap_soft.conf @@ -0,0 +1,34 @@ +interface=wlan0 +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=10 +#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/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_CfgOperations.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_CfgOperations.h new file mode 100755 index 00000000..05ee65e8 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_CfgOperations.h @@ -0,0 +1,82 @@ +/*! +* @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" + +#include "NMI_host_AP.h" + + +/* 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) + + +#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ) +#ifdef AGING_ALG +#define SCAN_RESULT_EXPIRE (40 * HZ) +#endif +#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) + } +}; +#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); +int NMI_WFI_init_mon_interface(char *name, struct net_device *real_dev ); +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_NetDevice.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_NetDevice.h new file mode 100755 index 00000000..d73644a6 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/include/NMI_WFI_NetDevice.h @@ -0,0 +1,266 @@ +/*! +* @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" + +#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 +/* + * 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 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; +}; + +/*p2p state*/ +enum p2p_state +{ + IDLE, + LISTEN, + GRP_FORMATION +}; +#endif /*NMI_P2P*/ + +struct NMI_WFI_priv { + struct wireless_dev *wdev; + struct cfg80211_scan_request* pstrScanReq; + + #ifdef NMI_P2P + NMI_Uint32 u32listen_freq; + enum p2p_state tenuState; + struct nmi_wfi_p2pListenParams strRemainOnChanParams; + #endif + + NMI_Bool bCfgScanning; + NMI_Uint32 u32RcvdChCount; + NMI_Uint32 u32LastScannedNtwrksCount; + tstrNetworkInfo astrLastScannedNtwrks[MAX_NUM_SCANNED_NETWORKS]; +#ifdef AGING_ALG + NMI_Uint32 u32LastScannedNtwrksCountShadow; + tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; +#endif + 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; + 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; +}; + +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 monitor_flag; + int close; + struct net_device_stats netstats; + 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[6]; + unsigned char eth_dst_address[6]; + + const struct firmware* nmc_firmware; /* Bug 4703 */ + + struct net_device* nmc_netdev; + struct net_device* real_ndev; +#ifdef NMI_SDIO + int already_claim; + struct sdio_func* nmc_sdio_func; +#else + struct spi_device* nmc_spidev; +#endif + + NMI_Uint8 iftype; +} linux_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/Nmc1000_Release7.0/src/driver/linux/init_deinit_test.sh b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/init_deinit_test.sh new file mode 100755 index 00000000..31bcc7a2 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_load b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_load new file mode 100755 index 00000000..a4e42aa6 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_unload b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/nmi_wfi_unload new file mode 100755 index 00000000..134c9352 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/panda_run_eval.sh b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/panda_run_eval.sh new file mode 100755 index 00000000..043b7a9a --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/panda_run_eval.sh @@ -0,0 +1,6 @@ +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 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/Nmc1000_Release7.0/src/driver/linux/panda_run_fpga.sh b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/panda_run_fpga.sh new file mode 100755 index 00000000..d8a1a897 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_CfgOperations.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_CfgOperations.c new file mode 100755 index 00000000..86466187 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_CfgOperations.c @@ -0,0 +1,3281 @@ +/*! +* @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" + +NMI_SemaphoreHandle SemHandleUpdateStats; +static NMI_SemaphoreHandle hSemScanReq; +static NMI_Bool gbAutoRateAdjusted = NMI_FALSE; + + +extern void linux_wlan_free(void* vp); +extern int linux_wlan_get_firmware(linux_wlan_t* p_nic); +int RefreshScanResult(struct NMI_WFI_priv* priv); + +#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; + void* buff; +}; +#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), +}; + + +static void clear_cached_scan_results(struct NMI_WFI_priv* nmi_wifi_priv){ + NMI_Uint32 i; + + for(i = 0; i <nmi_wifi_priv->u32LastScannedNtwrksCount; i++) + { + if(nmi_wifi_priv->astrLastScannedNtwrks[i].pu8IEs != NULL) + { + NMI_FREE(nmi_wifi_priv->astrLastScannedNtwrks[i].pu8IEs); + } + } + + NMI_memset((void*)nmi_wifi_priv->astrLastScannedNtwrks, 0, sizeof(nmi_wifi_priv->astrLastScannedNtwrks)); + nmi_wifi_priv->u32LastScannedNtwrksCount = 0; +} + +#ifdef AGING_ALG +static NMI_TimerHandle hAgingTimer; +#define AGING_TIME 9*1000 + +void clear_shadow_scan(void* pUserVoid){ + struct NMI_WFI_priv* priv; + int i; + priv = (struct NMI_WFI_priv*)pUserVoid; + + for(i = 0; i < priv->u32LastScannedNtwrksCountShadow; i++){ + if(priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].pu8IEs != NULL) + NMI_FREE(priv->astrLastScannedNtwrksShadow[i].pu8IEs); + } + priv->u32LastScannedNtwrksCountShadow = 0; + + NMI_TimerDestroy(&hAgingTimer,NMI_NULL); +} +void refresh_scan(void* pUserVoid,uint8_t all){ + struct NMI_WFI_priv* priv; + struct wiphy* wiphy; + int i; + + priv = (struct NMI_WFI_priv*)pUserVoid; + wiphy = priv->dev->ieee80211_ptr->wiphy; + + for(i = 0; i < priv->u32LastScannedNtwrksCountShadow; i++) + { + tstrNetworkInfo* pstrNetworkInfo; + pstrNetworkInfo = &(priv->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); + + + cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, 0, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + } + + } + } +} + +void reset_shadow_found(void* pUserVoid){ + struct NMI_WFI_priv* priv; + int i; + priv = (struct NMI_WFI_priv*)pUserVoid; + for(i=0;i<priv->u32LastScannedNtwrksCountShadow;i++){ + priv->astrLastScannedNtwrksShadow[i].u8Found = 0; + } +} + +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<priv->u32LastScannedNtwrksCountShadow;i++){ + if(time_after(now, priv->astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))){ + PRINT_D(CFG80211_DBG,"Network expired in ScanShadow: %s \n",priv->astrLastScannedNtwrksShadow[i].au8ssid); + + if(priv->astrLastScannedNtwrksShadow[i].pu8IEs != NULL) + NMI_FREE(priv->astrLastScannedNtwrksShadow[i].pu8IEs); + + for(j=i;(j<priv->u32LastScannedNtwrksCountShadow-1);j++){ + priv->astrLastScannedNtwrksShadow[j] = priv->astrLastScannedNtwrksShadow[j+1]; + } + priv->u32LastScannedNtwrksCountShadow--; + } + } + + PRINT_D(CFG80211_DBG,"Number of cached networks: %d\n",priv->u32LastScannedNtwrksCountShadow); + if(priv->u32LastScannedNtwrksCountShadow != 0) + NMI_TimerStart(&hAgingTimer, AGING_TIME, pUserVoid, NMI_NULL); + else + PRINT_D(CFG80211_DBG,"No need to restart Aging timer\n"); +} + +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(priv->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<priv->u32LastScannedNtwrksCountShadow;i++){ + if(NMI_memcmp(priv->astrLastScannedNtwrksShadow[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0){ + state = i; + break; + } + } + } + return state; +} + +void add_network_to_shadow(tstrNetworkInfo* pstrNetworkInfo,void* pUserVoid){ + struct NMI_WFI_priv* priv; + int8_t ap_found = is_network_in_shadow(pstrNetworkInfo,pUserVoid); + priv = (struct NMI_WFI_priv*)pUserVoid; + + if(priv->u32LastScannedNtwrksCountShadow >= MAX_NUM_SCANNED_NETWORKS_SHADOW){ + PRINT_D(CFG80211_DBG,"Shadow network reached its maximum limit\n"); + return; + } + + if(ap_found == -1){ + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].s8rssi = pstrNetworkInfo->s8rssi; + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u16CapInfo = pstrNetworkInfo->u16CapInfo; + + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u8SsidLen = pstrNetworkInfo->u8SsidLen; + NMI_memcpy(priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].au8ssid, + pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen); + + NMI_memcpy(priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].au8bssid, + pstrNetworkInfo->au8bssid, ETH_ALEN); + + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod; + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod; + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u8channel = pstrNetworkInfo->u8channel; + + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u16IEsLen = pstrNetworkInfo->u16IEsLen; + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].pu8IEs = + (NMI_Uint8*)NMI_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated + by the NMI_WFI_CfgScan() function */ + NMI_memcpy(priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].pu8IEs, + pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); + + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u32TimeRcvdInScan = jiffies; + priv->astrLastScannedNtwrksShadow[priv->u32LastScannedNtwrksCountShadow].u8Found = 1; + priv->u32LastScannedNtwrksCountShadow++; + }else{ + priv->astrLastScannedNtwrksShadow[ap_found].u8Found = 1; + priv->astrLastScannedNtwrksShadow[ap_found].u32TimeRcvdInScan = jiffies; + } +} +#else + int FirstNetworkReceived = NMI_TRUE; +#endif + +/** +* @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) + { + struct NMI_WFI_priv* priv; + struct wiphy* wiphy; + NMI_Sint32 s32Freq; + struct ieee80211_channel *channel; + NMI_Sint32 s32Error = NMI_SUCCESS; + + priv = (struct NMI_WFI_priv*)pUserVoid; + + + if(priv->bCfgScanning == NMI_TRUE) + { + PRINT_D(CFG80211_DBG,"Scanning in progress..\n"); + + if(enuScanEvent == SCAN_EVENT_NETWORK_FOUND) + { +#ifndef AGING_ALG + if(FirstNetworkReceived == NMI_TRUE) + { + clear_cached_scan_results(priv); + FirstNetworkReceived = NMI_FALSE; + } +#endif + 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(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); + if(pstrNetworkInfo != NMI_NULL) + { + PRINT_D(CFG80211_DBG,"Network information received\n"); + + priv->u32RcvdChCount++; + #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); + + cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, 0, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + + /* BugID_4209: cache the last Scan results such that in Connect Response Callback function, a check is + done if the intended network has been in the scan results more than a specified time (currently 2.8sec), + the cached last scan results are raised again to the upper nl80211 kernel layer to refresh its scan results + to prevent it from generating kernel warning. */ + + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].s8rssi = pstrNetworkInfo->s8rssi; + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u16CapInfo = pstrNetworkInfo->u16CapInfo; + + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u8SsidLen = pstrNetworkInfo->u8SsidLen; + NMI_memcpy(priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].au8ssid, + pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen); + + NMI_memcpy(priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].au8bssid, + pstrNetworkInfo->au8bssid, ETH_ALEN); + + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod; + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod; + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u8channel = pstrNetworkInfo->u8channel; + + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u16IEsLen = pstrNetworkInfo->u16IEsLen; + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].pu8IEs = + (NMI_Uint8*)NMI_MALLOC(pstrNetworkInfo->u16IEsLen); /* will be deallocated + by the NMI_WFI_CfgScan() function */ + NMI_memcpy(priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].pu8IEs, + pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen); + + priv->astrLastScannedNtwrks[priv->u32LastScannedNtwrksCount].u32TimeRcvdInScan = jiffies; + priv->u32LastScannedNtwrksCount++; + #ifdef AGING_ALG + add_network_to_shadow(pstrNetworkInfo,priv); + #endif + + + + } + } + else + { + PRINT_ER("Discovered networks exceeded the max limit\n"); + } + } + else if(enuScanEvent == SCAN_EVENT_DONE) + { + PRINT_D(CFG80211_DBG,"Scan Done \n"); + + #ifdef AGING_ALG + PRINT_D(CFG80211_DBG,"Refreshing Scan ... \n"); + refresh_scan(priv,0); + #endif + 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(&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(&hSemScanReq, NULL); + + } + /*Aborting any scan operation during mac close*/ + else if(enuScanEvent == SCAN_EVENT_ABORTED) + { + NMI_SemaphoreAcquire(&hSemScanReq, NULL); + + PRINT_D(CFG80211_DBG,"Aborting scan \n"); + if(priv->pstrScanReq != NMI_NULL) + { +#ifndef AGING_ALG + RefreshScanResult(priv); +#else + refresh_scan(priv,1); +#endif + cfg80211_scan_done(priv->pstrScanReq,NMI_FALSE); + priv->pstrScanReq = NMI_NULL; + } + NMI_SemaphoreRelease(&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 RefreshScanResult(struct NMI_WFI_priv* priv) +{ + struct wiphy* wiphy; + int i = 0; + + PRINT_D(CFG80211_DBG," network %s expired. Refreshing scan results\n", + priv->astrLastScannedNtwrks[i].au8ssid); + + wiphy = priv->dev->ieee80211_ptr->wiphy; + + for(i = 0; i < priv->u32LastScannedNtwrksCount; i++) + { + tstrNetworkInfo* pstrNetworkInfo; + NMI_Sint32 s32Freq; + struct ieee80211_channel *channel; + + pstrNetworkInfo = &(priv->astrLastScannedNtwrks[i]); + + if(pstrNetworkInfo != NMI_NULL) + { + PRINT_D(CFG80211_DBG,"cached Network information retrieved\n"); + + #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); + + printk("Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d," + "BeaconPeriod: %d \n",channel->center_freq, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), + pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod); + + + cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, 0, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + + } + } + return 0; +} + +/** +* @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 +*/ +static void CfgConnectResult(tenuConnDisconnEvent enuConnDisconnEvent, + tstrConnectInfo* pstrConnectInfo, + NMI_Uint8 u8MacStatus, + tstrDisconnectNotifInfo* pstrDisconnectNotifInfo, + void* pUserVoid) +{ + struct NMI_WFI_priv* priv; + struct net_device* dev; + + 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; + 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); + + + + /* 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 < priv->u32LastScannedNtwrksCount; i++) + { + if(NMI_memcmp(priv->astrLastScannedNtwrks[i].au8bssid, + pstrConnectInfo->au8bssid, ETH_ALEN) == 0) + { + unsigned long now = jiffies; + + if(time_after(now, + priv->astrLastScannedNtwrks[i].u32TimeRcvdInScan + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) + { + bNeedScanRefresh = NMI_TRUE; + } + + break; + } + } + + if(bNeedScanRefresh == NMI_TRUE) + { + //RefreshScanResult(priv); + #ifdef AGING_ALG + refresh_scan(priv, 1); + #else + RefreshScanResult(priv); + #endif + #if 0 + struct wiphy* wiphy; + + PRINT_D(CFG80211_DBG," network %s expired. Refreshing scan results\n", + priv->astrLastScannedNtwrks[i].au8ssid); + + wiphy = priv->dev->ieee80211_ptr->wiphy; + + for(i = 0; i < priv->u32LastScannedNtwrksCount; i++) + { + tstrNetworkInfo* pstrNetworkInfo; + NMI_Sint32 s32Freq; + struct ieee80211_channel *channel; + + pstrNetworkInfo = &(priv->astrLastScannedNtwrks[i]); + + if(pstrNetworkInfo != NMI_NULL) + { + PRINT_D(CFG80211_DBG,"cached Network information retrieved\n"); + + #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); + + 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); + + + cfg80211_inform_bss(wiphy, channel, pstrNetworkInfo->au8bssid, 0, pstrNetworkInfo->u16CapInfo, + pstrNetworkInfo->u16BeaconPeriod, (const u8*)pstrNetworkInfo->pu8IEs, + (size_t)pstrNetworkInfo->u16IEsLen, (((NMI_Sint32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL); + + } + } + #endif + } + + } + + + 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; + + PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d\n", + pstrDisconnectNotifInfo->u16reason); + + NMI_memset(priv->au8AssociatedBss, 0, ETH_ALEN); + + 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 +*/ +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) +{ + + NMI_Uint32 channelnum = 0; + struct NMI_WFI_priv* priv; + NMI_Sint32 s32Error = NMI_SUCCESS; + priv = wiphy_priv(wiphy); + + channelnum = ieee80211_frequency_to_channel(channel->center_freq); + + PRINT_D(CFG80211_DBG,"Setting channel %d with frequency %d\n", channelnum, channel->center_freq ); + + 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 +*/ +static int NMI_WFI_CfgScan(struct wiphy *wiphy,struct net_device *dev, + struct cfg80211_scan_request *request) +{ + struct NMI_WFI_priv* priv; + NMI_Uint32 i; + NMI_Sint32 s32Error = NMI_SUCCESS; + NMI_Uint8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS]; + tstrHiddenNetwork strHiddenNetwork; + static int ScanNo = 0; + + ScanNo++; + + priv = wiphy_priv(wiphy); + + priv->pstrScanReq = request; + + #ifdef NMI_P2P + /*If in listen state, abort scanning*/ + if (priv->tenuState == LISTEN) { + NMI_PRINTF("ABORTING SCAN REQUEST: LISTENING\n"); + + cfg80211_scan_done(priv->pstrScanReq,NMI_TRUE); + priv->pstrScanReq = NMI_NULL; + priv->bCfgScanning = NMI_FALSE; + return s32Error; + } + #endif + + priv->u32RcvdChCount = 0; + + //if(ScanNo < 3) + //clear_cached_scan_results(priv); + #if 0 + else + { + printk("Cheatiniiiiiiiiiiiig \n"); + RefreshScanResult(priv); + cfg80211_scan_done(priv->pstrScanReq,NMI_TRUE); + return 0; + } +#endif + + +#ifdef AGING_ALG + clear_cached_scan_results(priv); + reset_shadow_found(priv); +#else + FirstNetworkReceived = NMI_TRUE; +#endif + priv->bCfgScanning = NMI_TRUE; + + 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; + tstrNetworkInfo* pstrNetworkInfo = NULL; + + priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG,"Connecting to SSID [%s]\n",sme->ssid); + PRINT_INFO(CFG80211_DBG,"Required SSID = %s\n , AuthType = %d \n", sme->ssid,sme->auth_type); + + for(i = 0; i < priv->u32LastScannedNtwrksCount; i++) + { + if((sme->ssid_len == priv->astrLastScannedNtwrks[i].u8SsidLen) && + NMI_memcmp(priv->astrLastScannedNtwrks[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(priv->astrLastScannedNtwrks[i].au8bssid, + sme->bssid, + ETH_ALEN) == 0) + { + PRINT_INFO(CFG80211_DBG,"BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if(i < priv->u32LastScannedNtwrksCount) + { + PRINT_D(CFG80211_DBG, "Required bss is in scan results\n"); + + pstrNetworkInfo = &(priv->astrLastScannedNtwrks[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(priv->u32LastScannedNtwrksCount == 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) */ + //switch(sme->crypto.wpa_versions) + //{ + //printk(">> sme->crypto.wpa_versions: %x\n",sme->crypto.wpa_versions); + //case NL80211_WPA_VERSION_1: + 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{ + //break; + //default: + + pcwpa_version = "Default"; + PRINT_D(CFG80211_DBG,"Adding key with cipher group = %x\n",sme->crypto.cipher_group); + 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"; + } + 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"; + } + else + { + s32Error = -ENOTSUPP; + PRINT_ER("Not supported cipher: Error(%d)\n",s32Error); + //PRINT_ER("Cipher-Group: %x\n",sme->crypto.cipher_group); + + goto done; + } + + 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); + 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); + //break; + } + + /* 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, "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); + + 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); + 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; + + + + priv = wiphy_priv(wiphy); + + PRINT_D(CFG80211_DBG,"Disconnecting with reason code(%d)\n", reason_code); + + + 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); + + 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) + { + + if(priv->nmi_gtk[key_index] == NULL) + priv->nmi_gtk[key_index] = (struct nmi_wfi_key *)NMI_MALLOC(sizeof(struct nmi_wfi_key)); + if(priv->nmi_ptk[key_index] == NULL) + priv->nmi_ptk[key_index] = (struct nmi_wfi_key *)NMI_MALLOC(sizeof(struct nmi_wfi_key)); + + #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; + } + + 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(priv->nmi_gtk[key_index]->seq == NULL) + 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; + } + + + priv->nmi_ptk[key_index]->key = (NMI_Uint8 *)NMI_MALLOC(params->key_len); + 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); + 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; + } + 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; + } + 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); + + 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 +*/ +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; + linux_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) + { + 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 "); + + + 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) + { + gbAutoRateAdjusted = NMI_TRUE; + } + + if(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; + } + } + + } + + + + 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; + tstrCfgParamVal pstrCfgParamVal; + struct NMI_WFI_priv* priv; + + PRINT_D(CFG80211_DBG, "Setting Bitrate mask function\n"); + + 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"); + + 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_mgmt_tx_complete +* @details Returns result of transmitting mgmt frame on air, success or fail +* @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) +{ + +} + +/** +* @brief NMI_WFI_receive_mgmt +* @details +* @param[in] Received frame + priv +* @return None +* @author mdaftedar +* @date 20 MAY 2013 +* @version 1.0 +*/ +static void NMI_WFI_receive_mgmt(tstrRcvdMgmtFrame* pstrRcvdMgmtFrame,void* pUserVoid) +{ + PRINT_D(GENERIC_DBG,"Received mgmt frame\n"); +} + +/** +* @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"); + + /*Sending cancel remain on channel to FW*/ + priv->tenuState = IDLE; + + /*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); +} + + +/** +* @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); + priv->tenuState = LISTEN; + + PRINT_D(GENERIC_DBG, "Remaining on channel\n"); + + /*Setting params needed by NMI_WFI_RemainOnChannelExpired()*/ + priv->strRemainOnChanParams.pstrListenChan = chan; + priv->strRemainOnChanParams.u64ListenCookie = *cookie; + priv->strRemainOnChanParams.tenuChannelType = channel_type; + + /*Abort on-going scan*/ + NMI_SemaphoreAcquire(&hSemScanReq, NULL); + if ( priv->pstrScanReq != NMI_NULL) + { + NMI_PRINTF("ABORTING SCAN: LISTENING\n"); + cfg80211_scan_done(priv->pstrScanReq,NMI_TRUE); + priv->pstrScanReq = NMI_NULL; + priv->bCfgScanning = NMI_FALSE; + } + NMI_SemaphoreRelease(&hSemScanReq, NULL); + + /*Getting listen frequency*/ + #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_receive_mgmt,NMI_WFI_RemainOnChannelExpired,(void *)priv); + + /*Inform wpas of being ready on the desired channel*/ + cfg80211_ready_on_channel(dev, *cookie, chan,channel_type, duration, GFP_KERNEL); + + 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) +{ + PRINT_D(CFG80211_DBG, "Cancel remain on channel\n"); + return 0; + +} +#endif + +/** +* @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; + } + + 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 +*/ +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; + linux_wlan_t* nic; + + nic = netdev_priv(dev); + + PRINT_D(HOSTAPD_DBG,"In Change virtual interface function\n"); + + priv = wiphy_priv(wiphy); + + PRINT_D(HOSTAPD_DBG,"Wireless interface name =%s\n", dev->name); + + switch(type) + { + case NL80211_IFTYPE_STATION: + + PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_STATION\n"); + + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + nic->iftype = STATION_MODE; + + #ifndef SIMULATION + PRINT_D(HOSTAPD_DBG,"Downloading STATION firmware\n"); + linux_wlan_get_firmware(nic); + #endif + break; + + case NL80211_IFTYPE_AP: + + PRINT_D(HOSTAPD_DBG,"Interface type = NL80211_IFTYPE_AP\n"); + + //mon_priv = netdev_priv(dev); + //mon_priv->real_ndev = dev; + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_AP; + priv->wdev->iftype = type; + nic->iftype = AP_MODE; + + #ifndef SIMULATION + PRINT_D(HOSTAPD_DBG,"Downloading AP firmware\n"); + linux_wlan_get_firmware(nic); + #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 ); + + #ifndef NMI_FULLY_HOSTING_AP + s32Error = host_int_add_beacon( priv->hNMIWFIDrv, + settings->beacon_interval, + settings->dtim_period, + beacon->head_len, beacon->head, + beacon->tail_len, beacon->tail); + #else + s32Error = host_add_beacon( priv->hNMIWFIDrv, + settings->beacon_interval, + settings->dtim_period, + beacon->head_len, beacon->head, + beacon->tail_len, 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, beacon->head, + beacon->tail_len, beacon->tail); +#else + s32Error = host_add_beacon( priv->hNMIWFIDrv, + settings->beacon_interval, + settings->dtim_period, + beacon->head_len, beacon->head, + beacon->tail_len, 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_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + + PRINT_D(HOSTAPD_DBG,"Deleting beacon\n"); + + #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 ); + + #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_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + + PRINT_D(HOSTAPD_DBG,"Deleting beacon\n"); + + #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}}; + linux_wlan_t* nic; + + + NMI_NULLCHECK(s32Error, wiphy); + + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + if(nic->iftype == AP_MODE) + { + + 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, ¶ms->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); + } + + 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; + linux_wlan_t* nic; + + + NMI_NULLCHECK(s32Error, wiphy); + NMI_NULLCHECK(s32Error, mac); + + priv = wiphy_priv(wiphy); + nic = netdev_priv(dev); + + if(nic->iftype == AP_MODE) + { + PRINT_D(HOSTAPD_DBG,"Deleting station\n"); + + PRINT_INFO(HOSTAPD_DBG,"With mac address: %x%x%x%x%x%x\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); + + s32Error = host_int_del_station(priv->hNMIWFIDrv , mac); + 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}}; + linux_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) + { + + 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, ¶ms->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); + } + 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(2,6,37) +int +#else +struct net_device * +#endif +NMI_WFI_add_virt_intf(struct wiphy *wiphy, char *name, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + linux_wlan_t *nic; + struct NMI_WFI_priv* priv; + //struct NMI_WFI_mon_priv* mon_priv; + NMI_Sint32 s32Error = NMI_SUCCESS; + priv = wiphy_priv(wiphy); + + + + PRINT_D(HOSTAPD_DBG,"Adding monitor interface\n"); + + 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"); + + s32Error = NMI_WFI_init_mon_interface(name,nic->nmc_netdev); + if(!s32Error) + { + 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(2,6,37) + return s32Error; + #else + return priv->wdev->netdev; + #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 +*/ + +int NMI_WFI_del_virt_intf(struct wiphy *wiphy,struct net_device *dev) +{ + PRINT_D(HOSTAPD_DBG,"Deleting virtual interface\n"); + return NMI_SUCCESS; +} + +/** +* @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 +#ifdef NMI_P2P +/** +* @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) +{ + PRINT_D(GENERIC_DBG,"Frame registering Frame Type: %x\n",frame_type); +} + +/** +* @brief NMI_WFI_mgmt_tx_frame +* @details +* +* @param[in] +* @return NONE. +* @author mdaftedar +* @date 01 JUL 2012 +* @version +*/ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) +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, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie) +#endif +{ + linux_wlan_t* nic; + struct p2p_mgmt_data *mgmt_tx; + nic =netdev_priv(dev); + + PRINT_D(GENERIC_DBG,"In NMI_WFI_mgmt_tx function \n"); + + /*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(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*/ + nic->oup.wlan_add_mgmt_to_tx_que(mgmt_tx,mgmt_tx->buff,mgmt_tx->size,NMI_WFI_mgmt_tx_complete); + + cfg80211_mgmt_tx_status(dev,*cookie,buf,len,true,GFP_KERNEL); + return 0; +} +#endif +#endif /*NMI_P2P*/ +#endif /*NMI_AP_EXTERNAL_MLME*/ + + +static struct cfg80211_ops NMI_WFI_cfg80211_ops = { + + .set_channel = NMI_WFI_CfgSetChannel, + .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, + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) + .action = NMI_WFI_action, + #endif + #else + #ifdef NMI_P2P + .mgmt_tx = NMI_WFI_mgmt_tx, + .mgmt_frame_register = NMI_WFI_frame_register, + #endif/*NMI_P2P*/ + #endif + #endif /* NMI_AP_EXTERNAL_MLME*/ + .get_station = NMI_WFI_get_station, + .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, +#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; + } + + NMI_SemaphoreCreate(&SemHandleUpdateStats,NULL); + /*Return hardware description structure (wiphy)'s priv*/ + priv = wdev_priv(wdev); + + /*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 + wdev->wiphy->max_remain_on_channel_duration = 5000; + /*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); + 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); + + /*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; + + s32Error = NMI_TimerCreate(&hAgingTimer, remove_network_from_shadow, NMI_NULL); + + if(s32Error < 0){ + PRINT_ER("Failed to creat refresh Timer\n"); + return s32Error; + } + + NMI_SemaphoreFillDefault(&strSemaphoreAttrs); + + ///////////////////////////////////////// + //strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemScanReq, &strSemaphoreAttrs); + + priv = wdev_priv(net->ieee80211_ptr); + s32Error = host_int_init(&priv->hNMIWFIDrv); + 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); + + clear_cached_scan_results(priv); +#ifdef AGING_ALG + /* Clear the Shadow scan */ + clear_shadow_scan(priv); +#endif + NMI_SemaphoreDestroy(&hSemScanReq,NULL); + + s32Error = host_int_deinit(priv->hNMIWFIDrv); + 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/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_NetDevice.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/NMI_WFI_NetDevice.c new file mode 100755 index 00000000..41847cba --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/linux_mon.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_mon.c new file mode 100755 index 00000000..0f3b8471 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_mon.c @@ -0,0 +1,521 @@ +/*! +* @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_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)); + +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]; +/** +* @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) +{ + + //NMI_Uint32 i; + + + 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); + }*/ + + kfree(pv_data->buff); + + kfree(pv_data); +} +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; + } + + 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; + + } + memcpy(mgmt_tx->buff,buf,len); + mgmt_tx->size=len; + //NMI_PRINTF("--IN mon_mgmt_tx: Sending MGMT Pkt to tx queue--\n"); + nic->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 ; + + /* Bug 4601 */ + if(nmi_wfi_mon == NULL) + return NMI_FAIL; + + //if(skb->data[3] == 0x10 || skb->data[3] == 0xb0) + PRINT_INFO(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; + } + + if(INFO) + { + for(i=0; i<skb->len ; i++) + PRINT_INFO(HOSTAPD_DBG,"Data[%d] %02x\n",i,skb->data[i]); + } + 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) + { + for(i=0; i<20 ; i++) + PRINT_INFO(HOSTAPD_DBG,"Radiotap_hdr[%d] %02x\n",i,skb->data[i]); + } + /* Skip the ratio tap header */ + skb_pull(skb, rtap_len); + 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, + +}; + +/** +* @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 +*/ +int NMI_WFI_init_mon_interface(char *name , struct net_device *real_dev ) +{ + NMI_Uint32 ret = NMI_SUCCESS; + struct NMI_WFI_mon_priv *priv ; + + 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; + + + +} + +/** +* @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/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan.c new file mode 100755 index 00000000..c0fc8780 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan.c @@ -0,0 +1,2561 @@ +#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> +#include <linux/inetdevice.h> +#include <linux/etherdevice.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> + +#include <linux/version.h> +#include <linux/semaphore.h> + +#include "svnrevision.h" + +#ifdef NMI_SDIO +#include "linux_wlan_sdio.h" +#else +#include "linux_wlan_spi.h" +#endif +//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}; + //brandy_0724 ]] + +extern tstrNMI_WFIDrv* gWFiDrvHandle; + +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 +}; + +#if defined(PLAT_WMS8304) // added by rachel +#include "nmi_custom_gpio.c" +#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> + +int wmt_nmc1000_intr_num=15; //gpio 15 +#endif + +#define nmi_wlan_deinit(nic) if(&nic->oup != NULL) \ + if(nic->oup.wlan_cleanup != NULL) \ + nic->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 +//]] + +// [[ 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 + +#if defined(PLAT_AML8726_M3) //[[ johnny : because of dummy irq +static int _available_irq_ready = 0; +#endif + +#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); +static void linux_wlan_unlock(void* vp); + + +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); +static int mac_init_fn(struct net_device *ndev); +int mac_xmit(struct sk_buff *skb, struct net_device *dev); +static int mac_open(struct net_device *ndev); +static 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); + + +struct tx_complete_data{ + int size; + void* buff; + struct sk_buff *skb; +}; + + + /* + 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; + +#if 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, + +}; + +#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; +} + +#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 + +NMI_Bool gbIPaddrObtained = NMI_FALSE; + +static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct in_ifaddr *dev_iface = (struct in_ifaddr *)ptr; + + if(dev_iface == NULL) + { + NMI_PRINTF("dev_iface = NULL\n"); + return NOTIFY_DONE; + } + + switch (event) { + + case NETDEV_UP: + + gbIPaddrObtained = NMI_TRUE; + + host_int_set_power_mgmt((NMI_WFIDrvHandle)gWFiDrvHandle, 1, 0); + + PRINT_INFO(GENERIC_DBG, "[%s] Up IP\n", dev_iface->ifa_label); + + break; + + case NETDEV_DOWN: + + gbIPaddrObtained = NMI_FALSE; + + host_int_set_power_mgmt((NMI_WFIDrvHandle)gWFiDrvHandle, 0, 0); + + PRINT_INFO(GENERIC_DBG, "[%s] Down IP\n", dev_iface->ifa_label); + + break; + + default: + + PRINT_INFO(GENERIC_DBG, "[%s] unknown dev event: %lu\n", dev_iface->ifa_label, event); + + break; + } + + return NOTIFY_DONE; + +} + + +/* + * 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){ + linux_wlan_t *nic = (linux_wlan_t*)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(nic->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(&nic->rx_work_queue); + return IRQ_HANDLED; +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_unlock(&nic->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){ + linux_wlan_t* nic; + nic = container_of(work,linux_wlan_t,rx_work_queue); +#endif + + /*While mac is closing cacncel the handling of any interrupts received*/ + if(nic->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(nic->oup.wlan_handle_rx_isr != 0){ + nic->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 (nic->close){ + + while(!kthread_should_stop()) + schedule(); + + break; + } + int_rcvdB++; + PRINT_D(INT_DBG,"Interrupt received BH\n"); + if(nic->oup.wlan_handle_rx_isr != 0){ + nic->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); + +#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) + nic->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(nic->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", + nic->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(&nic->dev_irq_num != 0){ + free_irq(nic->dev_irq_num, nic); +#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; +} + +static 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"); + + } + +} + + +static int linux_wlan_rxq_task(void* vp){ + + linux_wlan_t *pd = (linux_wlan_t*)vp; + /* inform nmc1000_wlan_init that RXQ task is started. */ + linux_wlan_unlock(&pd->rxq_thread_started); + while(1) { + linux_wlan_lock(&pd->rxq_event); + //wait_for_completion(&pd->rxq_event); + if (pd->close){ + /*Unlock the mutex in the mac_close function to indicate the exiting of the RX thread */ + linux_wlan_unlock(&pd->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"); + pd->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; + linux_wlan_t *pd = (linux_wlan_t*)vp; + +#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(&pd->txq_thread_started); + while(1) { + + PRINT_D(TX_DBG,"txq_task Taking a nap :)\n"); + linux_wlan_lock(&pd->txq_event); + //wait_for_completion(&pd->txq_event); + PRINT_D(TX_DBG,"txq_task Who waked me up :$\n"); + + if (pd->close){ + /*Unlock the mutex in the mac_close function to indicate the exiting of the TX thread */ + linux_wlan_unlock(&pd->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 + pd->oup.wlan_handle_tx_que(); +#else + do { + ret = pd->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(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&&!pd->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(linux_wlan_t* p_nic){ + + linux_wlan_t* nic = p_nic; + int ret = 0; + const struct firmware* nmc_firmware; + char *firmware; + + + if(nic->iftype == AP_MODE) + firmware = AP_FIRMWARE; + else + firmware = STA_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, &nic->nmc_sdio_func->dev) != 0){ + PRINT_ER("%s - firmare not available\n",firmware); + ret = -1; + goto _fail_; + } +#else + if( request_firmware(&nmc_firmware,firmware, &nic->nmc_spidev->dev) != 0){ + PRINT_ER("%s - firmare not available\n",firmware); + ret = -1; + goto _fail_; + } +#endif + nic->nmc_firmware = nmc_firmware; /* Bug 4703 */ + +_fail_: + + return ret; + +} + +static int linux_wlan_start_firmware(linux_wlan_t* nic){ + + int ret = 0; + /* start firmware */ + PRINT_D(INIT_DBG,"Starting Firmware ...\n"); + ret = nic->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"); + linux_wlan_lock(&nic->sync_event); + /* + 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; + linux_wlan_t* nic = p_nic; + + if(nic->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 = nic->oup.wlan_firmware_download(nic->nmc_firmware->data, nic->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(nic->nmc_firmware); + nic->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(linux_wlan_t* p_nic){ + + linux_wlan_t* nic = p_nic; + unsigned char c_val[64]; + //brandy_0724 unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2}; + unsigned int chipid = 0; + PRINT_D(TX_DBG,"Start configuring Firmware\n"); + + //brandy_0724 get_random_bytes(&mac_add[5], 1); + + PRINT_D(INIT_DBG,"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); + + + + /*to tell fw that we are going to use PC test - NMI specific*/ + c_val[0] = 0; + if (!nic->oup.wlan_cfg_set(1, WID_PC_TEST_MODE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = INFRASTRUCTURE; + if (!nic->oup.wlan_cfg_set(0, WID_BSS_TYPE, c_val, 1, 0)) + goto _fail_; + + + c_val[0] = RATE_AUTO; /* bug 4275: Enable autorate and limit it to 24Mbps */ + if (!nic->oup.wlan_cfg_set(0, WID_CURRENT_TX_RATE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = G_MIXED_11B_2_MODE; + if (!nic->oup.wlan_cfg_set(0, WID_11G_OPERATING_MODE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 1; + if (!nic->oup.wlan_cfg_set(0, WID_CURRENT_CHANNEL, c_val, 1, 0)) + goto _fail_; + + c_val[0] = G_SHORT_PREAMBLE; + if (!nic->oup.wlan_cfg_set(0, WID_PREAMBLE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = AUTO_PROT; + if (!nic->oup.wlan_cfg_set(0, WID_11N_PROT_MECH, c_val, 1, 0)) + goto _fail_; + +#ifdef SWITCH_LOG_TERMINAL + c_val[0] = AUTO_PROT; + if (!nic->oup.wlan_cfg_set(0, WID_LOGTerminal_Switch, c_val, 1, 0)) + goto _fail_; +#endif + + c_val[0] = ACTIVE_SCAN; + if (!nic->oup.wlan_cfg_set(0, WID_SCAN_TYPE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = SITE_SURVEY_OFF; + if (!nic->oup.wlan_cfg_set(0, WID_SITE_SURVEY, c_val, 1, 0)) + goto _fail_; + + *((int *)c_val) = 0xffff; /* Never use RTS-CTS */ + if (!nic->oup.wlan_cfg_set(0, WID_RTS_THRESHOLD, c_val, 2, 0)) + goto _fail_; + + *((int *)c_val) = 2346; + if (!nic->oup.wlan_cfg_set(0, WID_FRAG_THRESHOLD, c_val, 2, 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 (!nic->oup.wlan_cfg_set(0, WID_SSID, c_val, (strlen(c_val)+1), 0)) + goto _fail_; +#endif + + c_val[0] = 0; + if (!nic->oup.wlan_cfg_set(0, WID_BCAST_SSID, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 1; + if (!nic->oup.wlan_cfg_set(0, WID_QOS_ENABLE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = NO_POWERSAVE; + if (!nic->oup.wlan_cfg_set(0, WID_POWER_MANAGEMENT, c_val, 1, 0)) + goto _fail_; + + c_val[0] = NO_ENCRYPT; //NO_ENCRYPT, 0x79 + if (!nic->oup.wlan_cfg_set(0, WID_11I_MODE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = OPEN_SYSTEM; + if (!nic->oup.wlan_cfg_set(0, WID_AUTH_TYPE, c_val, 1, 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 (!nic->oup.wlan_cfg_set(0, WID_WEP_KEY_VALUE, c_val, (strlen(c_val)+1), 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 (!nic->oup.wlan_cfg_set(0, WID_11I_PSK, c_val, (strlen(c_val)), 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 (!nic->oup.wlan_cfg_set(0, WID_1X_KEY, c_val, (strlen(c_val)+1), 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 (!nic->oup.wlan_cfg_set(0, WID_1X_SERV_ADDR, c_val, 4, 0)) + goto _fail_; + + c_val[0] = 3; + if (!nic->oup.wlan_cfg_set(0, WID_LISTEN_INTERVAL, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 3; + if (!nic->oup.wlan_cfg_set(0, WID_DTIM_PERIOD, c_val, 1, 0)) + goto _fail_; + + c_val[0] = NORMAL_ACK; + if (!nic->oup.wlan_cfg_set(0, WID_ACK_POLICY, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 0; + if (!nic->oup.wlan_cfg_set(0, WID_USER_CONTROL_ON_TX_POWER, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 48; + if (!nic->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11A, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 28; + if (!nic->oup.wlan_cfg_set(0, WID_TX_POWER_LEVEL_11B, c_val, 1, 0)) + goto _fail_; + + /* Beacon Interval */ + /* -------------------------------------------------------------------- */ + /* Configuration : Sets the beacon interval value */ + /* Values to set : Any 16-bit value */ + /* -------------------------------------------------------------------- */ + + *((int *)c_val) = 100; + if (!nic->oup.wlan_cfg_set(0, WID_BEACON_INTERVAL, c_val, 2, 0)) + goto _fail_; + + c_val[0] = REKEY_DISABLE; + if (!nic->oup.wlan_cfg_set(0, WID_REKEY_POLICY, c_val, 1, 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 (!nic->oup.wlan_cfg_set(0, WID_REKEY_PERIOD, c_val, 4, 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 (!nic->oup.wlan_cfg_set(0, WID_REKEY_PACKET_COUNT, c_val, 4, 0)) + goto _fail_; + + c_val[0] = 1; + if (!nic->oup.wlan_cfg_set(0, WID_SHORT_SLOT_ALLOWED, c_val, 1, 0)) + goto _fail_; + + c_val[0] = G_SELF_CTS_PROT; + if (!nic->oup.wlan_cfg_set(0, WID_11N_ERP_PROT_TYPE, c_val, 1, 0)) + goto _fail_; + + if((chipid & 0xfff) > 0xd0) + c_val[0] = 1; /* Enable N */ + else + c_val[0] = 0; /* Disable N */ + + if (!nic->oup.wlan_cfg_set(0, WID_11N_ENABLE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = HT_MIXED_MODE; + if (!nic->oup.wlan_cfg_set(0, WID_11N_OPERATING_MODE, c_val, 1, 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 (!nic->oup.wlan_cfg_set(0, WID_11N_TXOP_PROT_DISABLE, c_val, 1, 0)) + goto _fail_; + + memcpy(c_val, mac_add, 6); + + if (!nic->oup.wlan_cfg_set(0, WID_MAC_ADDR, c_val, 6, 0)) + goto _fail_; + + /** + AP only + **/ + c_val[0] = DETECT_PROTECT_REPORT; + if (!nic->oup.wlan_cfg_set(0, WID_11N_OBSS_NONHT_DETECTION, c_val, 1, 0)) + goto _fail_; + + c_val[0] = RTS_CTS_NONHT_PROT; + if (!nic->oup.wlan_cfg_set(0, WID_11N_HT_PROT_TYPE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 0; + if (!nic->oup.wlan_cfg_set(0, WID_11N_RIFS_PROT_ENABLE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = MIMO_MODE; + if (!nic->oup.wlan_cfg_set(0, WID_11N_SMPS_MODE, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 6; /* Limit TX rate below MCS-7 for NMC1000F0. Should be changed in to 7 in NMC1002. */ + if (!nic->oup.wlan_cfg_set(0, WID_11N_CURRENT_TX_MCS, c_val, 1, 0)) + goto _fail_; + + c_val[0] = 1; /* Enable N with immediate block ack. */ + if (!nic->oup.wlan_cfg_set(0, WID_11N_IMMEDIATE_BA_ENABLED, c_val, 1, 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 (!nic->oup.wlan_cfg_set(0, WID_RESET, c_val, 1, 1)) + goto _fail_; + + + return 0; + +_fail_: + return -1; +} + + +/**************************/ +void nmc1000_wlan_deinit(linux_wlan_t *nic) { + + if(nic->nmc1000_initialized) + { + + PRINT_D(INIT_DBG,"Deinitializing nmc1000 ...\n"); + + if(nic == NULL){ + PRINT_ER("nic is NULL\n"); + return; + } + + nmi_bus_set_default_speed(); + + PRINT_D(INIT_DBG,"Disabling IRQ\n"); + #if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO) + linux_wlan_disable_irq(IRQ_WAIT); + #else + disable_sdio_interrupt(); + #endif + + + /* not sure if the following unlocks are needed or not*/ + if(&nic->rxq_event != NULL){ + linux_wlan_unlock(&nic->rxq_event); + } + + if(&nic->txq_event != NULL){ + linux_wlan_unlock(&nic->txq_event); + } + + + #if (RX_BH_TYPE == RX_BH_WORK_QUEUE) + /*Removing the work struct from the linux kernel workqueue*/ + if(&nic->rx_work_queue != NULL) + flush_work(&nic->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(nic); + + + if(&nic->oup != NULL){ + if(nic->oup.wlan_stop != NULL) + nic->oup.wlan_stop(); + } + + PRINT_D(INIT_DBG,"Deinitializing NMI Wlan\n"); + nmi_wlan_deinit(nic); + + /*De-Initialize locks*/ + PRINT_D(INIT_DBG,"Deinitializing Locks\n"); + wlan_deinit_locks(nic); + + /* announce that nmc1000 is not initialized */ + nic->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){ + + linux_wlan_t* nic = p_nic; + + PRINT_D(INIT_DBG,"Initializing Locks ...\n"); + + /*initialize mutexes*/ + linux_wlan_init_mutex("hif_lock/hif_cs",&nic->hif_cs,1); + linux_wlan_init_mutex("rxq_lock/rxq_cs",&nic->rxq_cs,1); + linux_wlan_init_mutex("txq_lock/txq_cs",&nic->txq_cs,1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_spin_lock("txq_spin_lock/txq_cs",&nic->txq_spinlock,1); + + /*Added by Amr - BugID_4720*/ + linux_wlan_init_lock("txq_add_to_head_lock/txq_cs",&nic->txq_add_to_head_cs,1); + + linux_wlan_init_lock("txq_wait/txq_event",&nic->txq_event,0); + linux_wlan_init_lock("rxq_wait/rxq_event",&nic->rxq_event,0); + + linux_wlan_init_lock("cfg_wait/cfg_event",&nic->cfg_event,0); + linux_wlan_init_lock("sync_event",&nic->sync_event,0); + + linux_wlan_init_lock("rxq_lock/rxq_started",&nic->rxq_thread_started,0); + linux_wlan_init_lock("rxq_lock/txq_started",&nic->txq_thread_started,0); + + #if (RX_BH_TYPE == RX_BH_KTHREAD) + linux_wlan_init_lock("BH_SEM", &nic->rx_sem, 0); + #endif + + return 0; +} + +static int wlan_deinit_locks(linux_wlan_t* nic){ + PRINT_D(INIT_DBG,"De-Initializing Locks\n"); + + if(&nic->hif_cs != NULL) + linux_wlan_deinit_mutex(&nic->hif_cs); + + if(&nic->rxq_cs != NULL) + linux_wlan_deinit_mutex(&nic->rxq_cs); + + if(&nic->txq_cs != NULL) + linux_wlan_deinit_mutex(&nic->txq_cs); + + /*Added by Amr - BugID_4720*/ + if(&nic->txq_spinlock!= NULL) + linux_wlan_deinit_spin_lock(&nic->txq_spinlock); + + if(&nic->rxq_event != NULL) + linux_wlan_deinit_lock(&nic->rxq_event); + + if(&nic->txq_event != NULL) + linux_wlan_deinit_lock(&nic->txq_event); + + /*Added by Amr - BugID_4720*/ + if(&nic->txq_add_to_head_cs!= NULL) + linux_wlan_deinit_lock(&nic->txq_add_to_head_cs); + + if(&nic->rxq_thread_started != NULL) + linux_wlan_deinit_lock(&nic->rxq_thread_started); + + if(&nic->txq_thread_started != NULL) + linux_wlan_deinit_lock(&nic->txq_thread_started); + + if(&nic->cfg_event != NULL) + linux_wlan_deinit_lock(&nic->cfg_event); + + if(&nic->sync_event != NULL) + linux_wlan_deinit_lock(&nic->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 *)&nic->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 *)&nic->txq_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_add_to_head_critical_section=(void *)&nic->txq_add_to_head_cs; + + /*Added by Amr - BugID_4720*/ + nwi->os_context.txq_spin_lock = (void *)&nic->txq_spinlock; + + nwi->os_context.txq_wait_event = (void *)&nic->txq_event; + //nwi.os_context.rx_buffer_size = LINUX_RX_SIZE; + nwi->os_context.rxq_critical_section = (void *)&nic->rxq_cs; + nwi->os_context.rxq_wait_event = (void *)&nic->rxq_event; + nwi->os_context.cfg_wait_event = (void *)&nic->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*/ + nwi->net_func.rx_indicate = frmw_to_linux; + nwi->net_func.rx_complete = linux_wlan_rx_complete; + nwi->indicate_func.mac_indicate = linux_wlan_mac_indicate; +} + +int wlan_initialize_threads(linux_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(&nic->rx_work_queue, isr_bh_routine); +#elif (RX_BH_TYPE == RX_BH_KTHREAD) + PRINT_D(INIT_DBG,"Creating kthread for Rxq BH\n"); + nic->rx_bh_thread = kthread_run(isr_bh_routine,(void*)nic,"K_RXQ_BH"); + if(nic->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"); + nic->rxq_thread = kthread_run(linux_wlan_rxq_task,(void*)nic,"K_RXQ_TASK"); + if(nic->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(&nic->rxq_thread_started); + + /* create tx task */ + PRINT_D(INIT_DBG,"Creating kthread for transmission\n"); + nic->txq_thread = kthread_run(linux_wlan_txq_task,(void*)nic,"K_TXQ_TASK"); + if(nic->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"); + nic->txq_thread = kthread_run(DebuggingThreadTask,(void*)nic,"DebugThread"); + if(nic->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(&nic->txq_thread_started); + + return 0; + + _fail_2: + /*De-Initialize 2nd thread*/ + nic->close = 1; + linux_wlan_unlock(&nic->rxq_event); + kthread_stop(nic->rxq_thread); + + _fail_1: + #if(RX_BH_TYPE == RX_BH_KTHREAD) + /*De-Initialize 1st thread*/ + nic->close = 1; + linux_wlan_unlock(&nic->rx_sem); + kthread_stop(nic->rx_bh_thread); + _fail_: + #endif + nic->close = 0; + return ret; +} + +static void wlan_deinitialize_threads(linux_wlan_t* nic){ + + nic->close = 1; + PRINT_D(INIT_DBG,"Deinitializing Threads\n"); + if(&nic->rxq_event != NULL) + linux_wlan_unlock(&nic->rxq_event); + + + if(nic->rxq_thread != NULL){ + kthread_stop(nic->rxq_thread); + nic->rxq_thread = NULL; + } + + + if(&nic->txq_event != NULL) + linux_wlan_unlock(&nic->txq_event); + + + if(nic->txq_thread != NULL){ + kthread_stop(nic->txq_thread); + nic->txq_thread = NULL; + } + + #if(RX_BH_TYPE == RX_BH_KTHREAD) + if(&nic->rx_sem != NULL) + linux_wlan_unlock(&nic->rx_sem); + + if(nic->rx_bh_thread != NULL){ + kthread_stop(nic->rx_bh_thread); + nic->rx_bh_thread= NULL; + } + #endif +//brandy_0724 [[ +#if 0 + if (&nmi_mac_thread != NULL){ + kthread_stop(nmi_mac_thread); + nmi_mac_thread= NULL; + } +#endif +//brandy_0724 ]] +} + +//brandy_0724 [[ +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 { + fp = filp_open("/data/wlan", O_WRONLY, 0640); + 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 */ + fp = filp_open("/data/wlan", O_WRONLY|O_CREAT, 0640); + 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; +} +//brandy_0724 ]] + +int nmc1000_wlan_init(linux_wlan_t* p_nic) +{ + nmi_wlan_inp_t nwi; + nmi_wlan_oup_t nwo; + linux_wlan_t* nic = p_nic; + int ret = 0; + + if(!nic->nmc1000_initialized){ + nic->mac_status = NMI_MAC_STATUS_INIT; + nic->close = 0; + nic->nmc1000_initialized = 0; +#if defined(PLAT_AML8726_M3)//[[ johnny : because of dummy irq + _available_irq_ready = 0; +#endif + wlan_init_locks(nic); + + //brandy_0724 [[ for fixed Mac addr + 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"); + } + //brandy_0724 ]] + + linux_to_wlan(&nwi,nic); + + ret = nmi_wlan_init(&nwi, &nwo); + if (ret < 0) { + PRINT_ER("Initializing NMI_Wlan FAILED\n"); + goto _fail_locks_; + } + memcpy(&nic->oup, &nwo, sizeof(nmi_wlan_oup_t)); + + /*Save the oup structre into global pointer*/ + gpstrWlanOps = &nic->oup; + + + ret = wlan_initialize_threads(nic); + if (ret < 0) { + PRINT_ER("Initializing Threads FAILED\n"); + goto _fail_irq_; + } + +#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO) + if(init_irq(nic)){ + PRINT_ER("couldn't initialize IRQ\n"); + ret = -EIO; + goto _fail_locks_; + } +#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_; + } + + /*Download firmware*/ + ret = linux_wlan_firmware_download(nic); + 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(); + + /* Initialize firmware with default configuration */ + ret = linux_wlan_init_test_config(nic); + + if(ret < 0){ + PRINT_ER("Failed to configure firmware\n"); + goto _fail_threads_; + } + + nic->nmc1000_initialized = 1; + return 0; /*success*/ + +_fail_threads_: + wlan_deinitialize_threads(nic); +_fail_irq_: +#if (!defined NMI_SDIO) || (defined NMI_SDIO_IRQ_GPIO) + deinit_irq(nic); + +#endif +_fail_locks_: + wlan_deinit_locks(nic); + 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 + +/* This fn is called, when this device is setup using ifconfig */ +#if !defined (NM73131_0_BOARD) +int mac_open(struct net_device *ndev){ + + linux_wlan_t* nic; + unsigned char mac_add[] = {0x00, 0x80, 0xC2, 0x5E, 0xa2, 0xb2}; + int status; + int ret = 0; + struct NMI_WFI_priv* priv; + + gbIPaddrObtained = NMI_FALSE; + + nic = netdev_priv(ndev); + + linux_wlan_lock(&close_exit_sync); + + /*initialize platform*/ + ret = nmc1000_wlan_init(nic); + if(ret < 0) + { + PRINT_ER("Failed to initialize nmc1000\n"); + linux_wlan_unlock(&close_exit_sync); + return ret; + } + +#ifdef USE_WIRELESS + ret = NMI_WFI_InitHostInt(ndev); + if(ret < 0) + { + PRINT_ER("Failed to initialize host interface\n"); + nmc1000_wlan_deinit(nic); + linux_wlan_unlock(&close_exit_sync); + return ret; + } +#endif + + + get_random_bytes(&mac_add[5], 1); + + +#ifdef USE_WIRELESS + priv = wiphy_priv(nic->nmc_netdev->ieee80211_ptr->wiphy); + status = host_int_get_MacAddress(priv->hNMIWFIDrv, mac_add); +#else + host_int_set_MacAddress(NULL, mac_add); + status = host_int_get_MacAddress(NULL, mac_add); +#endif + /* TODO: get MAC address whenever the source is EPROM - hardcoded and copy it to ndev*/ + memcpy(ndev->dev_addr, mac_add, 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); + + netif_wake_queue(ndev); + + //linux_wlan_lock(&close_exit_sync); + + 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) +{ + linux_wlan_t* nic= netdev_priv(dev); + + + return &nic->netstats; +} + +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) +{ + linux_wlan_t* nic; + struct tx_complete_data* tx_data = NULL; + int QueueCount; + //char* saddr,*daddr,*pu8UdpBuffer; + char *pu8UdpBuffer; + struct iphdr *ih; +// struct ethhdr *eth; +// char* ethsaddr,*ethdaddr; +// int i; + //char* TestBuff; + + 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; + /*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) + { + PRINT_D(TX_DBG,"DHCP Message transmitted\n"); + //printk("[MMM] DHCP Message transmitted\n"); + } + 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 = ð->h_source; + ethdaddr = ð->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; + QueueCount = nic->oup.wlan_add_to_tx_que((void*)tx_data, + tx_data->buff, + tx_data->size, + linux_wlan_tx_complete); + + + if(QueueCount > FLOW_CONTROL_UPPER_THRESHOLD) + { + // printk("Stopping queue\n"); + netif_stop_queue(ndev); + + } + + + /* Wake up the network interface queue */ + //netif_wake_queue(ndev); + + + return 0; +} + + +int mac_close(struct net_device *ndev) +{ + + linux_wlan_t* nic; + + gbIPaddrObtained = NMI_FALSE; + + nic = netdev_priv(ndev); + + PRINT_D(GENERIC_DBG,"Mac close\n"); + + /* Stop the network interface queue */ + netif_stop_queue(ndev); + +#ifdef USE_WIRELESS + NMI_WFI_DeInitHostInt(ndev); +#endif + + PRINT_D(GENERIC_DBG,"Deinitializing nmc1000\n"); + nmc1000_wlan_deinit(nic); + +#ifdef USE_WIRELESS +#ifdef NMI_AP_EXTERNAL_MLME + NMI_WFI_deinit_mon_interface(); +#endif +#endif + linux_wlan_unlock(&close_exit_sync); + + 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; + linux_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(!nic->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){ + + 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; +// static int once = 1; +// int i; + linux_wlan_t *nic; + + 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 || g_linux_wlan->nmc_netdev == NULL){ + PRINT_ER("nmc_netdev in g_linux_wlan is NULL"); + } + skb->dev = g_linux_wlan->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(g_linux_wlan->nmc_netdev); +#ifdef USE_WIRELESS + /* if(nic->monitor_flag) + { + NMI_WFI_monitor_rx(g_linux_wlan->nmc_netdev,skb); + return; + }*/ +#endif + skb->protocol = eth_type_trans(skb, g_linux_wlan->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"); + //printk("[MMM] 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); + } +} + +int nmc_netdev_init(void){ + + linux_wlan_t* nic; + struct net_device* ndev; + + linux_wlan_init_lock("close_exit_sync",&close_exit_sync,1); + + /*allocate ethernet device with linux_wlan_t as its private data*/ + if(! (ndev = alloc_etherdev(sizeof(linux_wlan_t)))){ + PRINT_ER("Failed to allocate ethernet dev\n"); + return -1; + } + + nic = netdev_priv(ndev); + memset(nic,sizeof(linux_wlan_t),0); + + nic->nmc_netdev = ndev; + + + /*Reset interrupt count debug*/ + int_rcvdU= 0; + int_rcvdB= 0; + int_clrd = 0; + + g_linux_wlan = nic; + + ether_setup(ndev); + +#if defined(NM73131) // tony, 2012-09-20 + strcpy(ndev->name,"nmc_eth%d"); +#else //PANDA_BOARD, PLAT_ALLWINNER_A10, PLAT_ALLWINNER_A20, PLAT_AML8726_M3 or PLAT_WMS8304 + strcpy(ndev->name,"wlan%d"); +#endif + nmc_set_netdev_ops(ndev); +#ifdef USE_WIRELESS +{ + struct wireless_dev *wdev; + /*Register WiFi*/ + wdev = NMI_WFI_WiphyRegister(ndev); + if(wdev == NULL){ + PRINT_ER("Can't register NMI Wiphy\n"); + return -1; + } + + /*Pointing the priv structure the netdev*/ + + /*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 */ + } + + + +#ifndef NMI_SDIO + if(!linux_spi_init(&nic->nmc_spidev)){ + PRINT_ER("Can't initialize SPI \n"); + return -1; /* ERROR */ + } + nic->nmc_spidev = nmc_spi_dev; +#else + nic->nmc_sdio_func= local_sdio_func; +#endif + + nic->iftype = STATION_MODE; + + register_inetaddr_notifier(&g_dev_notifier); + + return 0; +} + +#if defined(PLAT_AML8726_M3) + #include <mach/gpio.h> + #include <mach/gpio_data.h> + #include <mach/pinmux.h> + extern void sdio_reinit(void); + extern void extern_wifi_set_enable(int is_on); + +#elif defined(PLAT_ALLWINNER_A10) + extern void sunximmc_rescan_card(unsigned id, unsigned insert); + extern void mmc_pm_power(int mode, int* updown); + extern int mmc_pm_get_io_val(char* name); + extern int mmc_pm_gpio_ctrl(char* name, int level); + #define NMC1000_SDIO_CARD_ID 3 + int nmc1000_power_val = 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 + +#elif defined(PLAT_WM8880) + /*simulate virtual sdio card insert and removal*/ + extern void force_remove_sdio2(void); + extern void wmt_detect_sdio2(void); + +#endif + +/*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", NMC1000_DRIVER_VERSION, SVNREV, STA_FIRMWARE); + +#if defined(PLAT_AML8726_M3) + extern_wifi_set_enable(1); + sdio_reinit(); + +#elif defined(PLAT_ALLWINNER_A10) + nmc1000_power_val = 1; + mmc_pm_power(0, &nmc1000_power_val); // POWER UP + sunximmc_rescan_card(NMC1000_SDIO_CARD_ID, 1); + +#elif defined(PLAT_ALLWINNER_A20) + + wifi_pm_power(1); + sw_mci_rescan_card(NMC1000_SDIO_CARD_ID, 1); + +#elif defined(PLAT_WMS8304) // added by rachel + NmiWifiCardPower(0); + msleep(100); + NmiWifiCardPower(1); + +#elif defined(PLAT_WM8880) + NmiWifiCardPower(1); + wmt_detect_sdio2(); + +#endif + +#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 +} +module_init(init_nmc_driver); + +static void __exit exit_nmc_driver(void){ + + #define CLOSE_TIMEOUT 12*1000 + + unregister_inetaddr_notifier(&g_dev_notifier); + + 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->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"); + + PRINT_D(INIT_DBG,"Unregistering netdev...\n"); + unregister_netdev(g_linux_wlan->nmc_netdev); + + + #ifdef USE_WIRELESS + PRINT_D(INIT_DBG,"Freeing Wiphy...\n"); + NMI_WFI_WiphyFree(g_linux_wlan->nmc_netdev); + #endif + + PRINT_D(INIT_DBG,"Freeing netdev...\n"); + free_netdev(g_linux_wlan->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((&nmc_bus) != NULL) + { + #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); + g_linux_wlan = NULL; + PRINT_D(INIT_DBG,"Module_exit Done.\n"); +#if defined (NMC_DEBUGFS) + nmc_debugfs_remove(); +#endif + +#if defined(PLAT_AML8726_M3) + extern_wifi_set_enable(0); + +#elif defined(PLAT_ALLWINNER_A10) + nmc1000_power_val = 0; + mmc_pm_power(0, &nmc1000_power_val); // POWER DOWN + sunximmc_rescan_card(NMC1000_SDIO_CARD_ID, 0); + +#elif defined(PLAT_ALLWINNER_A20) + wifi_pm_power(0); + sw_mci_rescan_card(NMC1000_SDIO_CARD_ID, 0); + +#elif defined(PLAT_WMS8304) // added by rachel + NmiWifiCardPower(0); + +#elif defined(PLAT_WM8880) + force_remove_sdio2(); + NmiWifiCardPower(0); // simon + +#endif +} +module_exit(exit_nmc_driver); + +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.c new file mode 100755 index 00000000..b2abd388 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.c @@ -0,0 +1,282 @@ +#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_PANDA_ES_OMAP4460) +#define MAX_SPEED 25000000 //johnny change +#elif defined(PLAT_WM8880) +#define MAX_SPEED /*20000000*/50000000 /* tony increased to 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; +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) }, +}; + +#ifndef NMI_SDIO_IRQ_GPIO +// [[ added by rachel 13-07-18 +typedef enum { + NMI_SDIO_HOST_NO_TAKEN = 0, + NMI_SDIO_HOST_IRQ_TAKEN = 1, + NMI_SDIO_HOST_DIS_TAKEN = 2, +} sdio_host_lock; +static sdio_host_lock sdio_intr_lock = NMI_SDIO_HOST_NO_TAKEN; +static wait_queue_head_t sdio_intr_waitqueue; +// ]] +#endif + +static void nmi_sdio_interrupt(struct sdio_func *func) +{ +#ifndef NMI_SDIO_IRQ_GPIO + if(sdio_intr_lock == NMI_SDIO_HOST_DIS_TAKEN) + return; + sdio_intr_lock = NMI_SDIO_HOST_IRQ_TAKEN; + + sdio_release_host(func); + nmi_handle_isr(); + sdio_claim_host(func); + + sdio_intr_lock = NMI_SDIO_HOST_NO_TAKEN; + wake_up_interruptible(&sdio_intr_waitqueue); +#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; +} + +extern void set_wifi_name(char * name); +static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id){ + PRINT_D(INIT_DBG,"SDIO probe \n"); + local_sdio_func = func; + PRINT_D(INIT_DBG,"Initializing netdev\n"); + if(nmc_netdev_init()){ + PRINT_ER("Couldn't initialize netdev\n"); + return -1; + } + //added by rubbitxiao + set_wifi_name("nmc1000.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_intr_lock = NMI_SDIO_HOST_NO_TAKEN; + + 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; + + if(sdio_intr_lock == NMI_SDIO_HOST_IRQ_TAKEN ) + wait_event_interruptible(sdio_intr_waitqueue, sdio_intr_lock == NMI_SDIO_HOST_NO_TAKEN ); + sdio_intr_lock = NMI_SDIO_HOST_DIS_TAKEN; + + 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); + + sdio_intr_lock = NMI_SDIO_HOST_NO_TAKEN; +#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 + +#ifndef NMI_SDIO_IRQ_GPIO + init_waitqueue_head(&sdio_intr_waitqueue); +#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/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_sdio.h new file mode 100755 index 00000000..68b3da25 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.c new file mode 100755 index 00000000..a6682b47 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/linux_wlan_spi.h new file mode 100755 index 00000000..6f5eb1ae --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/nmi_custom_gpio.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_custom_gpio.c new file mode 100755 index 00000000..bd592f3f --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/nmi_debugfs.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_debugfs.c new file mode 100755 index 00000000..b11572f4 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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(®ION)); + 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(®ION)), 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(®ION)); + return -EFAULT; + } + + atomic_set(®ION, (int)flag); + printk("new debug-region is %x\n", atomic_read(®ION)); + + 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/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.c new file mode 100755 index 00000000..3b46fb43 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_queue.h new file mode 100755 index 00000000..cdfc8fbe --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/linux/source/nmi_wm8880_gpio.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/linux/source/nmi_wm8880_gpio.c new file mode 100755 index 00000000..a0155f55 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/nmi_driver_interface/host_interface.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_driver_interface/host_interface.c new file mode 100755 index 00000000..8d73ecfc --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_driver_interface/host_interface.c @@ -0,0 +1,6609 @@ +#include "host_interface.h" +#include "NMI_OsWrapper/include/NMI_OSWrapper.h" +#include "itypes.h" +#include "CoreConfigurator.h" +#define DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern NMI_Sint32 TransportInit(void); +extern NMI_Sint32 TransportDeInit(void); +#ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP +extern NMI_Bool gbIPaddrObtained; +#endif + +/*****************************************************************************/ +/* 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_LISTEN_TIMER_FIRED ((NMI_Uint16)22) +#define HOST_IF_MSG_GET_LINKSPEED ((NMI_Uint16)23) + + +#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 +/*****************************************************************************/ +/* 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; +} 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 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 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; + #ifdef NMI_P2P + tstrHostIfRemainOnChan strHostIfRemainOnChan;/*p2p remain on channel message body*/ + tstrRcvdMgmtFrame strRcvdMgmtFrame; /*p2p received mgmt frame message body*/ + #endif + +} 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 */ +}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; +}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 */ +/* */ +/*****************************************************************************/ + +NMI_SemaphoreHandle gtOsCfgValuesSem; + +tstrNMI_WFIDrv* gWFiDrvHandle = NMI_NULL; + +static NMI_TimerHandle hScanTimer; +static NMI_TimerHandle hConnectTimer; +#ifdef NMI_P2P +static NMI_TimerHandle hRemainOnChannel; +#endif +//static NMI_SemaphoreHandle timer_synch_sem; +//static NMI_SemaphoreHandle hSemTimerThrdEnd; +//static NMI_ThreadHandle TimerThreadHandler; +//static NMI_Bool bTerminate_TimerThread = NMI_FALSE; + +static NMI_ThreadHandle HostIFthreadHandler; +static NMI_MsgQueueHandle gMsgQHostIF; +static NMI_SemaphoreHandle hSemHostIFthrdEnd; + +static NMI_SemaphoreHandle hSemTestKeyBlock; +static NMI_SemaphoreHandle hSemTestDisconnectBlock; +static NMI_SemaphoreHandle hSemGetRSSI; +static NMI_SemaphoreHandle hSemGetLINKSPEED; +static NMI_SemaphoreHandle hSemGetCHNL; +static NMI_SemaphoreHandle hSemInactiveTime; + +#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; +#ifdef NMI_AP_EXTERNAL_MLME +static NMI_Uint32 gu32InactiveTime = 0; +#endif +#ifndef SIMULATION +static NMI_Uint32 gu32WidConnRstHack = 0; +#endif + +/*Bug4218: Parsing Join Param*/ +#ifdef NMI_PARSE_SCAN_IN_HOST +/*Table containing needed join parameters for each AP found in most recent scan*/ +static tstrBssTable gtstrBssTable; +/*Bug4218: Parsing Join Param*/ +static void host_int_addJoinBssParam(tstrNetworkInfo* ptstrNetworkInfo); +/*Bug4218: Parsing Join Param*/ +static tstrJoinBssParam* host_int_getJoinBssParam(NMI_Uint8* ssid,NMI_Uint8 ssidLen); +#endif /*NMI_PARSE_SCAN_IN_HOST*/ + +extern void chip_sleep_manually(NMI_Uint32 u32SleepTime); + +/** +* @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(tstrHostIFSetChan* pstrHostIFSetChan) +{ + + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + + /*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); + if(s32Error == NMI_SUCCESS) + { + PRINT_ER("Failed to set channel\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + + } + + NMI_CATCH(s32Error) + { + + } + 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(tstrHostIFCfgParamAttr* strHostIFCfgParamAttr) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWIDList[32]; + NMI_Uint8 u8WidCnt= 0; + NMI_SemaphoreAcquire(>OsCfgValuesSem,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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + gWFiDrvHandle->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); + + if(s32Error) + { + PRINT_ER("Error in setting CFG params\n"); + + } + NMI_CATCH(s32Error) + { + } + NMI_SemaphoreRelease(>OsCfgValuesSem, 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(tstrHostIFscanAttr* pstrHostIFscanAttr) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWIDList[5]; + NMI_Uint32 u32WidsCount = 0; + #ifdef NMI_PARSE_SCAN_IN_HOST + tstrJoinBssParam * ptstrJoinBssParam; + #endif + NMI_Uint32 i; + NMI_Uint8* pu8Buffer; + NMI_Uint8 valuesize=0; + NMI_Uint8* pu8HdnNtwrksWidVal = NULL; + + PRINT_D(HOSTINF_DBG,"Setting SCAN params\n"); + PRINT_D(HOSTINF_DBG,"Scanning: In [%d] state \n", gWFiDrvHandle->enuHostIFstate); + + gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult; + gWFiDrvHandle->strNMI_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg; + + if((gWFiDrvHandle->enuHostIFstate >= HOST_IF_SCANNING) && (gWFiDrvHandle->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",gWFiDrvHandle->enuHostIFstate); + NMI_ERRORREPORT(s32Error, NMI_BUSY); + } + + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + if((gbIPaddrObtained == NMI_FALSE) && (gWFiDrvHandle->enuHostIFstate == HOST_IF_CONNECTED)) + { + PRINT_INFO(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"); + + + gWFiDrvHandle->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(gWFiDrvHandle->enuHostIFstate == HOST_IF_CONNECTED) + { + gbScanWhileConnected = NMI_TRUE; + } + else if(gWFiDrvHandle->enuHostIFstate == HOST_IF_IDLE) + { + gbScanWhileConnected = NMI_FALSE; + } + /*Bug4218: Parsing Join Param*/ + //cleaning JoinTable + #ifdef NMI_PARSE_SCAN_IN_HOST + while(gtstrBssTable.u8noBssEntries!=0) + { + //PRINT_D(HOSTINF_DBG,"Freeing Join Parameters Table\n"); + ptstrJoinBssParam = gtstrBssTable.head; + gtstrBssTable.head = (tstrJoinBssParam*)gtstrBssTable.head->nextJoinBss; + NMI_FREE(ptstrJoinBssParam); + gtstrBssTable.u8noBssEntries-=1; + } + #endif/*NMI_PARSE_SCAN_IN_HOST*/ + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE); + + 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(&hScanTimer, NMI_NULL); + /*if there is an ongoing scan request*/ + Handle_ScanDone(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(tenuScanEvent enuEvent) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + + PRINT_D(HOSTINF_DBG,"in Handle_ScanDone()\n"); + + /*if there is an ongoing scan request*/ + if(gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult) + { + gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult(enuEvent, NMI_NULL, + gWFiDrvHandle->strNMI_UsrScanReq.u32UserScanPvoid); + /*delete current scan request*/ + gWFiDrvHandle->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 +*/ + +static NMI_Sint32 Handle_Connect(tstrHostIFconnectAttr* pstrHostIFconnectAttr) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWIDList[5]; + NMI_Uint32 u32WidsCount = 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(HOSTINF_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)gWFiDrvHandle, + 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, + &gWFiDrvHandle->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 < gWFiDrvHandle->u32SurveyResultsCount; i++) + { + NMI_memcpy(&gWFiDrvHandle->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 < gWFiDrvHandle->u32SurveyResultsCount; i++) + { + if(NMI_memcmp(gWFiDrvHandle->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(gWFiDrvHandle->astrSurveyResults[i].BSSID, + pstrHostIFconnectAttr->pu8bssid, + 6) == 0) + { + PRINT_INFO(HOSTINF_DBG,"BSSID is passed from the user and matched\n"); + break; + } + } + } + } + + if(i < gWFiDrvHandle->u32SurveyResultsCount) + { + u8bssDscListIndex = i; + + PRINT_INFO(HOSTINF_DBG,"Connecting to network of Bss Idx %d and SSID %s and channel %d \n", + u8bssDscListIndex, gWFiDrvHandle->astrSurveyResults[u8bssDscListIndex].SSID, + gWFiDrvHandle->astrSurveyResults[u8bssDscListIndex].Channel); + + PRINT_INFO(HOSTINF_DBG,"Saving connection parameters in global structure\n"); + + if(pstrHostIFconnectAttr->pu8bssid != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = (NMI_Uint8*)NMI_MALLOC(6); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if(pstrHostIFconnectAttr->pu8ssid != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->ssidLen+1); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if(pstrHostIFconnectAttr->pu8IEs != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->IEsLen); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + gWFiDrvHandle->strNMI_UsrConnReq.u8security= pstrHostIFconnectAttr->u8security; + gWFiDrvHandle->strNMI_UsrConnReq.tenuAuth_type= pstrHostIFconnectAttr->tenuAuth_type; + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + gWFiDrvHandle->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 = gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = gWFiDrvHandle->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*)(&(gWFiDrvHandle->strNMI_UsrConnReq.u8security)); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG,"Encrypt Mode = %x\n",gWFiDrvHandle->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*)(&gWFiDrvHandle->strNMI_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG,"Authentication Type = %x\n",gWFiDrvHandle->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); + if(s32Error) + { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + else + { + gWFiDrvHandle->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 = host_int_getJoinBssParam(pstrHostIFconnectAttr->pu8ssid,pstrHostIFconnectAttr->ssidLen); + if(ptstrJoinBssParam==NULL) + { + PRINT_ER("Required BSSID not found\n"); + NMI_ERRORREPORT(s32Error,NMI_NOT_FOUND); + } + #endif /*NMI_PARSE_SCAN_IN_HOST*/ + + if(pstrHostIFconnectAttr->pu8bssid != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = (NMI_Uint8*)NMI_MALLOC(6); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6); + } + + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen; + if(pstrHostIFconnectAttr->pu8ssid != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->ssidLen+1); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid, + pstrHostIFconnectAttr->ssidLen); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0'; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen; + if(pstrHostIFconnectAttr->pu8IEs != NULL) + { + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = (NMI_Uint8*)NMI_MALLOC(pstrHostIFconnectAttr->IEsLen); + NMI_memcpy(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs, + pstrHostIFconnectAttr->IEsLen); + } + + gWFiDrvHandle->strNMI_UsrConnReq.u8security= pstrHostIFconnectAttr->u8security; + gWFiDrvHandle->strNMI_UsrConnReq.tenuAuth_type= pstrHostIFconnectAttr->tenuAuth_type; + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult; + gWFiDrvHandle->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 = gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs; + strWIDList[u32WidsCount].s32ValueSize = gWFiDrvHandle->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*)(&(gWFiDrvHandle->strNMI_UsrConnReq.u8security)); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG,"Encrypt Mode = %x\n",gWFiDrvHandle->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*)(&gWFiDrvHandle->strNMI_UsrConnReq.tenuAuth_type); + u32WidsCount++; + + PRINT_INFO(HOSTINF_DBG,"Authentication Type = %x\n",gWFiDrvHandle->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", + gWFiDrvHandle->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; + strWIDList[u32WidsCount].s32ValueSize = 79; + 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; + + /* 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 + gWFiDrvHandle->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); + + /* 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 + + s32Error = SendConfigPkt(SET_CFG, strWIDList, u32WidsCount, NMI_FALSE); + if(s32Error) + { + PRINT_ER("Handle_Connect()] failed to send config packet\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + else + { + gWFiDrvHandle->enuHostIFstate = HOST_IF_WAITING_CONN_RESP; + } + #endif + + NMI_CATCH(s32Error) + { + tstrConnectInfo strConnectInfo; + + NMI_TimerStop(&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*/ + gWFiDrvHandle->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_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) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrConnectInfo strConnectInfo; + tstrWID strWID; + NMI_Uint16 u16DummyReasonCode = 0; + + gWFiDrvHandle->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(gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult != NULL) + { + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + NMI_memcpy(strConnectInfo.au8bssid, + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid, 6); + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + strConnectInfo.ReqIEsLen = gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (NMI_Uint8*)NMI_MALLOC(gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen); + NMI_memcpy(strConnectInfo.pu8ReqIEs, + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs, + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen); + } + + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + MAC_DISCONNECTED, + NULL, + gWFiDrvHandle->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); + if(s32Error) + { + PRINT_ER("Failed to send dissconect config packet\n"); + } + + /* Deallocation of the Saved Connect Request in the global Handle */ + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = NULL; + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = NULL; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = 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(tstrRcvdNetworkInfo* pstrRcvdNetworkInfo) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrNetworkInfo * pstrNetworkInfo = NULL; + NMI_Uint32 i; + + PRINT_INFO(HOSTINF_DBG,"Handling received network info\n"); + + /*if there is a an ongoing scan request*/ + if(gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult) + { + PRINT_D(HOSTINF_DBG,"State: Scanning, parsing network information received\n"); + ParseNetworkInfo(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo); + if((pstrNetworkInfo == NULL) + ||(gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult == NMI_NULL)) + { + NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT); + } + + /* check whether this network is discovered before */ + for(i = 0; i < gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount; i++) + { + + if((gWFiDrvHandle->strNMI_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) && + (pstrNetworkInfo->au8bssid != NULL)) + { + if(NMI_memcmp(gWFiDrvHandle->strNMI_UsrScanReq.astrFoundNetworkInfo[i].au8bssid, + pstrNetworkInfo->au8bssid, 6) == 0) + { + /* network is already discovered before */ + PRINT_D(HOSTINF_DBG,"Network previously discovered\n"); + break; + } + } + } + + if(i == gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount) + { + /* 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(gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) + { + if((gWFiDrvHandle->strNMI_UsrScanReq.astrFoundNetworkInfo[gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount].au8bssid != NULL) + && (pstrNetworkInfo->au8bssid != NULL)) + { + NMI_memcpy(gWFiDrvHandle->strNMI_UsrScanReq.astrFoundNetworkInfo[gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount].au8bssid, + pstrNetworkInfo->au8bssid, 6); + + gWFiDrvHandle->strNMI_UsrScanReq.u32RcvdChCount++; + + gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, + gWFiDrvHandle->strNMI_UsrScanReq.u32UserScanPvoid); + /*Bug4218: Parsing Join Param*/ + //add new BSS to JoinBssTable + #ifdef NMI_PARSE_SCAN_IN_HOST + host_int_addJoinBssParam(pstrNetworkInfo); + #endif/*NMI_PARSE_SCAN_IN_HOST*/ + } + } + else + { + PRINT_WRN(HOSTINF_DBG,"Discovered networks exceeded max. limit \n"); + } + } + } + + + NMI_CATCH(s32Error) + { + + } + + /* 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(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; + tstrConnectInfo strConnectInfo; + tstrDisconnectNotifInfo strDisconnectNotifInfo; + NMI_Sint32 s32Err = NMI_SUCCESS; + + PRINT_D(HOSTINF_DBG,"Current State = %d,Received state = %d\n",gWFiDrvHandle->enuHostIFstate, + pstrRcvdGnrlAsyncInfo->pu8Buffer[7]); + + if((gWFiDrvHandle->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || + (gWFiDrvHandle->enuHostIFstate == HOST_IF_CONNECTED)) + { + if((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) || + (gWFiDrvHandle->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]; + + if(gWFiDrvHandle->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,"MAC status = %d\n",u8MacStatus); + + 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)gWFiDrvHandle, + 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"); + } + else if(u8MacStatus == MAC_DISCONNECTED) + { + NMI_ERROR("Received MAC status is MAC_DISCONNECTED\n"); + } + + //TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP + // through a structure of type tstrConnectRespInfo + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + PRINT_D(HOSTINF_DBG,"Retrieving actual BSSID from AP\n"); + NMI_memcpy(strConnectInfo.au8bssid, gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid, 6); + + if((u8MacStatus == MAC_CONNECTED) && + (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) + + + { + NMI_memcpy(gWFiDrvHandle->au8AssociatedBSSID, + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid, ETH_ALEN); + } + } + + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + strConnectInfo.ReqIEsLen = gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen; + strConnectInfo.pu8ReqIEs = (NMI_Uint8*)NMI_MALLOC(gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen); + NMI_memcpy(strConnectInfo.pu8ReqIEs, + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs, + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen); + } + + + NMI_TimerStop(&hConnectTimer, NMI_NULL); + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP, + &strConnectInfo, + u8MacStatus, + NULL, + gWFiDrvHandle->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 + gbIPaddrObtained = NMI_FALSE; + host_int_set_power_mgmt((NMI_WFIDrvHandle)gWFiDrvHandle, 0, 0); + #endif + + PRINT_D(HOSTINF_DBG,"MAC status : CONNECTED and Connect Status : Successful\n"); + gWFiDrvHandle->enuHostIFstate = HOST_IF_CONNECTED; + #ifdef NMI_PARSE_SCAN_IN_HOST + //open a BA session if possible + //if(gWFiDrvHandle->strNMI_UsrConnReq.IsHTCapable) + + #endif + + //host_int_addBASession(gWFiDrvHandle->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); + gWFiDrvHandle->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; + } + + + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = NULL; + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = NULL; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = NULL; + } + + } + else if((u8MacStatus == MAC_DISCONNECTED) && + (gWFiDrvHandle->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)); + + strDisconnectNotifInfo.u16reason = 0; + strDisconnectNotifInfo.ie = NULL; + strDisconnectNotifInfo.ie_len = 0; + + if(gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult != NULL) + { + #ifdef DISABLE_PWRSAVE_AND_SCAN_DURING_IP + gbIPaddrObtained = NMI_FALSE; + host_int_set_power_mgmt((NMI_WFIDrvHandle)gWFiDrvHandle, 0, 0); + #endif + + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, + NULL, + 0, + &strDisconnectNotifInfo, + gWFiDrvHandle->strNMI_UsrConnReq.u32UserConnectPvoid); + + } + + else + { + PRINT_ER("Connect result callback function is NULL \n"); + } + + NMI_memset(gWFiDrvHandle->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; + } + */ + + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = NULL; + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = NULL; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = NULL; + } + + gWFiDrvHandle->enuHostIFstate = HOST_IF_IDLE; + gbScanWhileConnected = NMI_FALSE; + + } + + } + + 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(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; + + + 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_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_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); + } + 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); + } + 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_FREE(pu8keybuf); + + //////////////////////////// + NMI_SemaphoreRelease(&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(gWFiDrvHandle->enuHostIFstate == HOST_IF_CONNECTED) + { + NMI_memcpy(pu8keybuf, gWFiDrvHandle->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_FREE(pu8keybuf); + + //////////////////////////// + NMI_SemaphoreRelease(&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_FREE(pu8keybuf); + + //////////////////////////// + NMI_SemaphoreRelease(&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_FREE(pu8keybuf); + + //////////////////////////// + NMI_SemaphoreRelease(&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_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) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint16 u16DummyReasonCode = 0; + + 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 + gbIPaddrObtained = NMI_FALSE; + + host_int_set_power_mgmt((NMI_WFIDrvHandle)gWFiDrvHandle, 0, 0); + #endif + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_FALSE); + + 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(gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult != NULL) + { + + gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, + 0, &strDisconnectNotifInfo,gWFiDrvHandle->strNMI_UsrConnReq.u32UserConnectPvoid); + } + else + { + NMI_ERROR("strNMI_UsrConnReq.pfUserConnectResult = NULL \n"); + } + + gbScanWhileConnected = NMI_FALSE; + + gWFiDrvHandle->enuHostIFstate = HOST_IF_IDLE; + + NMI_memset(gWFiDrvHandle->au8AssociatedBSSID, 0, ETH_ALEN); + + + /* Deallocation */ + gWFiDrvHandle->strNMI_UsrConnReq.ssidLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ssid = NULL; + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid); + gWFiDrvHandle->strNMI_UsrConnReq.pu8bssid = NULL; + } + + gWFiDrvHandle->strNMI_UsrConnReq.ConnReqIEsLen = 0; + if(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs != NULL) + { + NMI_FREE(gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs); + gWFiDrvHandle->strNMI_UsrConnReq.pu8ConnReqIEs = NULL; + } + + + } + + NMI_CATCH(s32Error) + { + + } + + //////////////////////////// + NMI_SemaphoreRelease(&hSemTestDisconnectBlock, NMI_NULL); + /////////////////////////// + +} + + +static NMI_Sint32 Switch_Log_Terminal(void) +{ + + + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + static char dummy=9; + + + 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); + + + 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) +{ + + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + //tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + + 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); + /*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(&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) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + + 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); + if(s32Error) + { + PRINT_ER("Failed to get RSSI value\n"); + NMI_ERRORREPORT(s32Error, NMI_FAIL); + } + + NMI_CATCH(s32Error) + { + + } + NMI_SemaphoreRelease(&hSemGetRSSI, NMI_NULL); + + +} + + +static void Handle_GetLinkspeed(void) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + + 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); + if(s32Error) + { + PRINT_ER("Failed to get LINKSPEED value\n"); + NMI_ERRORREPORT(s32Error, NMI_FAIL); + } + + NMI_CATCH(s32Error) + { + + } + NMI_SemaphoreRelease(&hSemGetLINKSPEED, NMI_NULL); + + +} + + +#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(tstrHostIfStaInactiveT* strHostIfStaInactiveT) +{ + + NMI_Sint32 s32Error = NMI_SUCCESS; + NMI_Uint8 *stamac; + tstrWID strWID; + + + + 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); + /*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); + /*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(&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(tstrHostIFSetBeacon* pstrSetBeaconParam) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint8* pu8CurrByte; + + 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); + 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(tstrHostIFDelBeacon* pstrDelBeacon) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint8* pu8CurrByte; + + strWID.u16WIDid = (NMI_Uint16)WID_DEL_BEACON; + strWID.enuWIDtype = WID_CHAR; + strWID.s32ValueSize = 0; + + 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); + 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(tstrNMI_AddStaParam* pstrStationParam) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint8* pu8CurrByte; + + 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); + 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(tstrHostIFDelSta* pstrDelStaParam) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint8* pu8CurrByte; + + 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); + 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(tstrNMI_AddStaParam* pstrStationParam) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Uint8* pu8CurrByte; + + 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); + 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 P2P Remain on channel handler +* @param[in] +* @return NONE +* @author +* @date +* @version 1.0 +*/ +static int Handle_RemainOnChan(tstrHostIfRemainOnChan* pstrHostIfRemainOnChan) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + + gWFiDrvHandle->strHostIfRemainOnChan.RxProbeReq= pstrHostIfRemainOnChan->RxProbeReq; + gWFiDrvHandle->strHostIfRemainOnChan.pVoid=pstrHostIfRemainOnChan->pVoid; + gWFiDrvHandle->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired; + + /*Start remain-on-channel timer, if listen state*/ + NMI_TimerStart(&hRemainOnChannel, pstrHostIfRemainOnChan->u32duration, NMI_NULL, NMI_NULL); + + 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(tstrHostIfRemainOnChan* pstrHostIfRemainOnChan) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + + /*Stopping remain-on-channel timer*/ + NMI_TimerStop(&hRemainOnChannel, NMI_NULL); + + if(gWFiDrvHandle->strHostIfRemainOnChan.pRemainOnChanExpired) + { + gWFiDrvHandle->strHostIfRemainOnChan.pRemainOnChanExpired(gWFiDrvHandle->strHostIfRemainOnChan.pVoid); + } + + 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; + + /* prepare the Timer Callback message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_LISTEN_TIMER_FIRED; + + /* 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(tstrHostIfPowerMgmtParam* strPowerMgmtParam) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrWID strWID; + NMI_Sint8 s8PowerMode; + 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); + if(s32Error) + { + PRINT_ER("Failed to send power management config packet\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + + NMI_CATCH(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; + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + while(1) + { + NMI_MsgQueueRecv(&gMsgQHostIF, &strHostIFmsg, sizeof(tstrHostIFmsg), &u32Ret, NMI_NULL); + + if(strHostIFmsg.u16MsgId == HOST_IF_MSG_EXIT) + { + PRINT_D(GENERIC_DBG,"THREAD: Exiting HostIfThread\n"); + break; + } + + switch(strHostIFmsg.u16MsgId) + { + case HOST_IF_MSG_SCAN: + { + Handle_Scan(&strHostIFmsg.uniHostIFmsgBody.strHostIFscanAttr); + break; + } + case HOST_IF_MSG_CONNECT: + { + Handle_Connect(&strHostIFmsg.uniHostIFmsgBody.strHostIFconnectAttr); + break; + } + case HOST_IF_MSG_RCVD_NTWRK_INFO: + { + Handle_RcvdNtwrkInfo(&strHostIFmsg.uniHostIFmsgBody.strRcvdNetworkInfo); + break; + } + case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: + { + Handle_RcvdGnrlAsyncInfo(&strHostIFmsg.uniHostIFmsgBody.strRcvdGnrlAsyncInfo); + break; + } + case HOST_IF_MSG_KEY: + { + Handle_Key(&strHostIFmsg.uniHostIFmsgBody.strHostIFkeyAttr); + break; + } + case HOST_IF_MSG_CFG_PARAMS: + { + + Handle_CfgParam(&strHostIFmsg.uniHostIFmsgBody.strHostIFCfgParamAttr); + break; + } + case HOST_IF_MSG_SET_CHANNEL: + { + Handle_SetChannel(&strHostIFmsg.uniHostIFmsgBody.strHostIFSetChan); + break; + } + case HOST_IF_MSG_DISCONNECT: + { + Handle_Disconnect(); + break; + } + case HOST_IF_MSG_RCVD_SCAN_COMPLETE: + { + NMI_TimerStop(&hScanTimer, NMI_NULL); + PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); + + if(gWFiDrvHandle->enuHostIFstate != HOST_IF_CONNECTED) + { + /* force the chip manually to sleep */ + chip_sleep_manually(INFINITE_SLEEP_TIME); + } + + Handle_ScanDone(SCAN_EVENT_DONE); + break; + } + case HOST_IF_MSG_GET_RSSI: + { + Handle_GetRssi(); + break; + } + case HOST_IF_MSG_GET_LINKSPEED: + { + Handle_GetLinkspeed(); + break; + } + case HOST_IF_MSG_GET_CHNL: + { + Handle_GetChnl(); + break; + } + + #ifdef NMI_AP_EXTERNAL_MLME + case HOST_IF_MSG_ADD_BEACON: + { + Handle_AddBeacon(&strHostIFmsg.uniHostIFmsgBody.strHostIFSetBeacon); + break; + } + break; + + case HOST_IF_MSG_DEL_BEACON: + { + Handle_DelBeacon(&strHostIFmsg.uniHostIFmsgBody.strHostIFDelBeacon); + break; + } + break; + + case HOST_IF_MSG_ADD_STATION: + { + Handle_AddStation(&strHostIFmsg.uniHostIFmsgBody.strAddStaParam); + break; + } + + case HOST_IF_MSG_DEL_STATION: + { + Handle_DelStation(&strHostIFmsg.uniHostIFmsgBody.strDelStaParam); + break; + } + case HOST_IF_MSG_EDIT_STATION: + { + Handle_EditStation(&strHostIFmsg.uniHostIFmsgBody.strEditStaParam); + break; + } + case HOST_IF_MSG_GET_INACTIVETIME: + { + Handle_Get_InActiveTime(&strHostIFmsg.uniHostIFmsgBody.strHostIfStaInactiveT); + break; + } + #endif /*NMI_AP_EXTERNAL_MLME*/ + case HOST_IF_MSG_SCAN_TIMER_FIRED: + { + NMI_PRINTF("Scan Timeout\n"); + Handle_ScanDone(SCAN_EVENT_DONE); + break; + } + case HOST_IF_MSG_CONNECT_TIMER_FIRED: + { + NMI_PRINTF("Connect Timeout \n"); + Handle_ConnectTimeout(); + break; + } + case HOST_IF_MSG_POWER_MGMT: + { + Handle_PowerManagement(&strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam); + break; + } + #ifdef NMI_P2P + case HOST_IF_MSG_REMAIN_ON_CHAN: + { + Handle_RemainOnChan(&strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + } + case HOST_IF_MSG_LISTEN_TIMER_FIRED: + { + Handle_ListenStateExpired(&strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan); + break; + } + #endif + 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(void* pvArg) +{ + tstrHostIFmsg strHostIFmsg; + tenuScanConnTimer enuScanConnTimer; + + enuScanConnTimer = (tenuScanConnTimer)pvArg; + + PRINT_D(HOSTINF_DBG, "TimerCB(): rcvd enuScanConnTimer=%d\n", enuScanConnTimer); + + /* prepare the Timer Callback message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + if(enuScanConnTimer == SCAN_TIMER) + { + strHostIFmsg.u16MsgId = HOST_IF_MSG_SCAN_TIMER_FIRED; + strHostIFmsg.uniHostIFmsgBody.strTimerCb.pvUsrArg = (void*)enuScanConnTimer; + } + else if(enuScanConnTimer == CONNECT_TIMER) + { + strHostIFmsg.u16MsgId = HOST_IF_MSG_CONNECT_TIMER_FIRED; + strHostIFmsg.uniHostIFmsgBody.strTimerCb.pvUsrArg = (void*)enuScanConnTimer; + } + + /* 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.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_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.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_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.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_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.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_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; + + /* 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(&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; + + #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(&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; + + 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; + tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + tstrWID strWID; + + if(pstrWFIDrv == NMI_NULL ) + { + NMI_ERRORREPORT(s32Error,NMI_INVALID_ARGUMENT); + } + strWID.u16WIDid = (NMI_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (NMI_Uint8*)NMI_MALLOC(ETH_ALEN); + strWID.s32ValueSize = ETH_ALEN; + + s32Error = SendConfigPkt(GET_CFG, &strWID, 1, NMI_TRUE); + + NMI_memcpy(pu8MacAddress,strWID.ps8WidVal,ETH_ALEN); + /*get the value by searching the local copy*/ + NMI_FREE(strWID.ps8WidVal); + if(s32Error) + { + PRINT_ER("Failed to get mac address\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + + else + { + PRINT_INFO(HOSTINF_DBG,"MAC address retrieved:: \n"); + + PRINT_INFO(HOSTINF_DBG,"%2x.%2x.%2x.%2x.%2x.%2x.\n",(NMI_Uint8)(strWID.ps8WidVal[0]),(NMI_Uint8)(strWID.ps8WidVal[1]), + (NMI_Uint8)(strWID.ps8WidVal[2]),(NMI_Uint8)(strWID.ps8WidVal[3]),(NMI_Uint8)(strWID.ps8WidVal[4]),(NMI_Uint8)(strWID.ps8WidVal[5])); + + PRINT_INFO(HOSTINF_DBG,"\n"); + } + + NMI_CATCH(s32Error) + { + + } + + 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; + tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + tstrWID strWID; + + if(pstrWFIDrv == NMI_NULL) + { + PRINT_ER("Driver not initialized: pstrWFIDrv = NULL \n"); + NMI_ERRORREPORT(s32Error, NMI_INVALID_ARGUMENT); + } + + strWID.u16WIDid = (NMI_Uint16)WID_MAC_ADDR; + strWID.enuWIDtype = WID_STR; + strWID.ps8WidVal = (NMI_Sint8*)pu8MacAddress; + strWID.s32ValueSize = ETH_ALEN; + + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE); + + + if(s32Error) + { + PRINT_D(HOSTINF_DBG,"Failed to set mac address\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + else + { + PRINT_INFO(HOSTINF_DBG,"MAC address set :: \n"); + + PRINT_INFO(HOSTINF_DBG,"%2x.%2x.%2x.%2x.%2x.%2x.\n",(NMI_Uint8)(strWID.ps8WidVal[0]),(NMI_Uint8)(strWID.ps8WidVal[1]), + (NMI_Uint8)(strWID.ps8WidVal[2]),(NMI_Uint8)(strWID.ps8WidVal[3]),(NMI_Uint8)(strWID.ps8WidVal[4]),(NMI_Uint8)(strWID.ps8WidVal[5])); + + PRINT_INFO(HOSTINF_DBG,"\n"); + } + + 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); + + /*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) +{ + 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(gWFiDrvHandle == NULL) + { + PRINT_ER("Driver not initialized: gWFiDrvHandle = 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; + + 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(&hConnectTimer, HOST_IF_CONNECT_TIMEOUT, (void*)enuScanConnTimer, NMI_NULL); + + 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(gWFiDrvHandle == 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; + + /* 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(&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); + 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; + tstrWID strWID; + + 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_CURRENT_CHANNEL; + strWID.enuWIDtype= WID_CHAR; + strWID.ps8WidVal = (NMI_Char*)&u8ChNum; + strWID.s32ValueSize = sizeof(NMI_Char); + + /*Sending Cfg*/ + s32Error = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE); + if(s32Error) + { + PRINT_ER("Failed to send set channel config packet\n"); + NMI_ERRORREPORT(s32Error,NMI_INVALID_STATE); + } + + 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; + + /* 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(&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); + 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; + + /* 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(&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); + /*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; + + + /* prepare the Get RSSI Message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_RSSI; + + /* 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(&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) +{ + NMI_Sint32 s32Error = NMI_SUCCESS; + tstrHostIFmsg strHostIFmsg; + + + /* prepare the Get LINKSPEED Message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_GET_LINKSPEED; + + /* 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(&hSemGetLINKSPEED, NULL); + + + if(ps8lnkspd == NULL) + { + PRINT_ER("LINKSPEED pointer value is null"); + return NMI_FAIL; + } + + + *ps8lnkspd = gs8lnkspd; + + + 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.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; + NMI_TimerStart(&hScanTimer, HOST_IF_SCAN_TIMEOUT, (void*)enuScanConnTimer, 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; + + 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(>OsCfgValuesSem,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)gWFiDrvHandle->strCfgValues.bss_type; + + } + break; + case WID_AUTH_TYPE: + { + + *pu16WID_Value =(NMI_Uint16)gWFiDrvHandle->strCfgValues.auth_type; + + } + break; + case WID_AUTH_TIMEOUT: + { + + *pu16WID_Value = gWFiDrvHandle->strCfgValues.auth_timeout; + + } + break; + + case WID_POWER_MANAGEMENT: + { + + *pu16WID_Value = (NMI_Uint16)gWFiDrvHandle->strCfgValues.power_mgmt_mode; + } + break; + case WID_SHORT_RETRY_LIMIT: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.short_retry_limit; + } + break; + case WID_LONG_RETRY_LIMIT: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.long_retry_limit; + + } + break; + case WID_FRAG_THRESHOLD: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.frag_threshold; + } + break; + case WID_RTS_THRESHOLD: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.rts_threshold; + } + break; + case WID_PREAMBLE: + { + *pu16WID_Value = (NMI_Uint16)gWFiDrvHandle->strCfgValues.preamble_type; + } + break; + case WID_SHORT_SLOT_ALLOWED: + { + *pu16WID_Value =(NMI_Uint16) gWFiDrvHandle->strCfgValues.short_slot_allowed; + } + break; + case WID_11N_TXOP_PROT_DISABLE: + { + *pu16WID_Value = (NMI_Uint16)gWFiDrvHandle->strCfgValues.txop_prot_disabled; + } + break; + case WID_BEACON_INTERVAL: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.beacon_interval; + } + break; + case WID_DTIM_PERIOD: + { + *pu16WID_Value = (NMI_Uint16)gWFiDrvHandle->strCfgValues.dtim_period; + } + break; + case WID_SITE_SURVEY: + { + *pu16WID_Value = (NMI_Uint16)gWFiDrvHandle->strCfgValues.site_survey_enabled; + } + break; + case WID_SITE_SURVEY_SCAN_TIME: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.site_survey_scan_time; + } + break; + + case WID_ACTIVE_SCAN_TIME: + { + + *pu16WID_Value= gWFiDrvHandle->strCfgValues.active_scan_time; + } + break; + case WID_PASSIVE_SCAN_TIME: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.passive_scan_time; + + } + break; + case WID_CURRENT_TX_RATE: + { + *pu16WID_Value = gWFiDrvHandle->strCfgValues.curr_tx_rate; + } + break; + default: + break; + } + + NMI_SemaphoreRelease(>OsCfgValuesSem, 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 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; +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; + return 0; + } + PRINT_D(HOSTINF_DBG,"Initializing host interface\n"); + + gbScanWhileConnected = NMI_FALSE; + + NMI_SemaphoreFillDefault(&strSemaphoreAttrs); + + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemHostIFthrdEnd, &strSemaphoreAttrs); + + ///////////////////////////////////////// + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemTestKeyBlock, &strSemaphoreAttrs); + ///////////////////////////////////////// + + ///////////////////////////////////////// + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemTestDisconnectBlock, &strSemaphoreAttrs); + ///////////////////////////////////////// + + ///////////////////////////////////////// + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemGetRSSI, &strSemaphoreAttrs); + + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemGetLINKSPEED, &strSemaphoreAttrs); + ///////////////////////////////////////// + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemGetCHNL, &strSemaphoreAttrs); + + ///////////////////////////////////////// + strSemaphoreAttrs.u32InitCount = 0; + NMI_SemaphoreCreate(&hSemInactiveTime, &strSemaphoreAttrs); + + + s32Error = NMI_MsgQueueCreate(&gMsgQHostIF, NMI_NULL); + if(s32Error < 0){ + PRINT_ER("Failed to creat MQ\n"); + goto _fail_; + } + + 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(&hScanTimer, TimerCB, NMI_NULL); + if(s32Error < 0){ + PRINT_ER("Failed to creat Timer\n"); + goto _fail_thread_; + } + + s32Error = NMI_TimerCreate(&hConnectTimer, TimerCB, NMI_NULL); + if(s32Error < 0){ + PRINT_ER("Failed to creat Timer\n"); + goto _fail_timer_1; + } + + #ifdef NMI_P2P + /*Remain on channel timer*/ + s32Error = NMI_TimerCreate(&hRemainOnChannel, ListenTimerCB, NMI_NULL); + if(s32Error < 0){ + PRINT_ER("Failed to creat Remain-on-channel Timer\n"); + goto _fail_timer_3; + } + #endif + + NMI_SemaphoreCreate(>OsCfgValuesSem,NULL); + NMI_SemaphoreAcquire(>OsCfgValuesSem,NULL); + + /*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*/ + gWFiDrvHandle = pstrWFIDrv; + + PRINT_D(HOSTINF_DBG,"Global handle pointer value=%x\n",(NMI_Uint32)gWFiDrvHandle); + +#ifdef SIMULATION + TransportInit(); +#endif + + gWFiDrvHandle->enuHostIFstate = HOST_IF_IDLE; + //gWFiDrvHandle->bPendingConnRequest = NMI_FALSE; + + /*Initialize CFG WIDS Defualt Values*/ + gWFiDrvHandle->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF; + gWFiDrvHandle->strCfgValues.scan_source = DEFAULT_SCAN; + gWFiDrvHandle->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME; + gWFiDrvHandle->strCfgValues.passive_scan_time= PASSIVE_SCAN_TIME; + gWFiDrvHandle->strCfgValues.curr_tx_rate = AUTORATE; + + 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", + gWFiDrvHandle->strCfgValues.site_survey_enabled,gWFiDrvHandle->strCfgValues.scan_source, + gWFiDrvHandle->strCfgValues.active_scan_time,gWFiDrvHandle->strCfgValues.passive_scan_time, + gWFiDrvHandle->strCfgValues.curr_tx_rate); + + NMI_SemaphoreRelease(>OsCfgValuesSem,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; + return s32Error; + + +_fail_mem_: + if(pstrWFIDrv != NMI_NULL) + NMI_FREE(pstrWFIDrv); +#ifdef NMI_P2P +_fail_timer_3: + NMI_TimerDestroy(&hRemainOnChannel, NMI_NULL); +#endif +_fail_timer_2: + NMI_SemaphoreRelease(>OsCfgValuesSem,NULL); + NMI_TimerDestroy(&hConnectTimer,NMI_NULL); +_fail_timer_1: + NMI_TimerDestroy(&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; +#ifdef NMI_PARSE_SCAN_IN_HOST + tstrJoinBssParam * ptstrJoinBssParam; +#endif + /*obtain driver handle*/ + tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + if(u32Intialized == 0) + { + PRINT_ER("Host Interface is not initialized\n"); + return 0; + } + PRINT_D(HOSTINF_DBG,"De-initializing host interface\n"); + + + /*Calling the CFG80211 scan done function with the abort flag set to true*/ + if(gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult) + { + gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NMI_NULL, + gWFiDrvHandle->strNMI_UsrScanReq.u32UserScanPvoid); + + gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult= NMI_NULL; + } + /*deinit configurator and simulator*/ +#ifdef SIMULATION + CoreConfigSimulatorDeInit(); +#endif + CoreConfiguratorDeInit(); +#ifdef SIMULATION + TransportDeInit(); +#endif + +#if 0 // tony + if(NMI_TimerDestroy(&hScanTimer, NMI_NULL)){ + printk(">> Scan timer is active \n"); + msleep(HOST_IF_SCAN_TIMEOUT+1000); + } + + if(NMI_TimerDestroy(&hConnectTimer, NMI_NULL)){ + printk(">> Connect timer is active \n"); + msleep(HOST_IF_CONNECT_TIMEOUT+1000); + } +#else + NMI_TimerDestroy(&hScanTimer, NMI_NULL); + NMI_TimerDestroy(&hConnectTimer, NMI_NULL); +#endif + + #ifdef NMI_P2P + /*Destroy Remain-onchannel Timer*/ + NMI_TimerDestroy(&hRemainOnChannel, NMI_NULL); + #endif + + pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE; + + gbScanWhileConnected = NMI_FALSE; + + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + + strHostIFmsg.u16MsgId = HOST_IF_MSG_EXIT; + 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); + + if(pstrWFIDrv != NMI_NULL) + { + NMI_FREE(pstrWFIDrv); + } + /*Bug4218: Parsing Join Param*/ + //cleaning JoinTable + #ifdef NMI_PARSE_SCAN_IN_HOST + while(gtstrBssTable.u8noBssEntries!=0) + { + //PRINT_D(HOSTINF_DBG,"Freeing Join Parameters Table\n"); + ptstrJoinBssParam = gtstrBssTable.head; + gtstrBssTable.head = (tstrJoinBssParam*)gtstrBssTable.head->nextJoinBss; + NMI_FREE(ptstrJoinBssParam); + gtstrBssTable.u8noBssEntries-=1; + } + #endif /*NMI_PARSE_SCAN_IN_HOST*/ + /* Destroy the MSG Queue */ + NMI_MsgQueueDestroy(&gMsgQHostIF, NMI_NULL); + + /*Destroy Semaphores*/ + NMI_SemaphoreDestroy(&hSemHostIFthrdEnd,NULL); + + NMI_SemaphoreDestroy(&hSemTestKeyBlock,NULL); + NMI_SemaphoreDestroy(&hSemTestDisconnectBlock,NULL); + NMI_SemaphoreDestroy(&hSemGetRSSI,NULL); + NMI_SemaphoreDestroy(&hSemGetLINKSPEED,NULL); + NMI_SemaphoreDestroy(&hSemGetCHNL,NULL); + NMI_SemaphoreDestroy(&hSemInactiveTime,NULL); + + NMI_SemaphoreAcquire(>OsCfgValuesSem,NULL); + NMI_SemaphoreDestroy(>OsCfgValuesSem,NULL); + + /*Setting the gloabl driver handler with NULL*/ + u32Intialized = 0; + gWFiDrvHandle = 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; + + if(gWFiDrvHandle == NMI_NULL) + { + PRINT_ER("NetworkInfo received but driver not init[%x]\n",(NMI_Uint32)gWFiDrvHandle); + return; + } + + /* prepare the Asynchronous Network Info message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_NTWRK_INFO; + + 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; + + PRINT_D(HOSTINF_DBG,"General asynchronous info packet received \n"); + + if(gWFiDrvHandle == NULL) + { + PRINT_ER("Wifi driver handler is equal to NULL\n"); + return; + } + + if(gWFiDrvHandle->strNMI_UsrConnReq.pfUserConnectResult == NMI_NULL) + { + /* received mac status is not needed when there is no current Connect Request */ + return; + } + + /* prepare the General Asynchronous Info message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; + + 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; + + PRINT_D(GENERIC_DBG,"Scan notification received \n"); + + if(gWFiDrvHandle == NULL) + { + return; + } + /*if there is an ongoing scan request*/ + if(gWFiDrvHandle->strNMI_UsrScanReq.pfUserScanResult) + { + /* prepare theScan Done message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + + strHostIFmsg.u16MsgId = HOST_IF_MSG_RCVD_SCAN_COMPLETE; + + + /* 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, tNMIpfRemainOnChan RxMgmt,tNMIpfRemainOnChanExpired RemainOnChanExpired,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 WiphyParams Message */ + NMI_memset(&strHostIFmsg, 0, sizeof(tstrHostIFmsg)); + strHostIFmsg.u16MsgId = HOST_IF_MSG_REMAIN_ON_CHAN; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.channel= chan; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.RxProbeReq = RxMgmt; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pRemainOnChanExpired = RemainOnChanExpired; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.pVoid=pvUserArg; + strHostIFmsg.uniHostIFmsgBody.strHostIfRemainOnChan.u32duration=u32duration; + + 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; + 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; + + 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; + + 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; + + 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; + + 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; + +/* Set power management only for platforms with RTC +The internal clock has a bug in NMc1000CA*/ + + tstrNMI_WFIDrv * pstrWFIDrv = (tstrNMI_WFIDrv *)hWFIDrv; + tstrHostIFmsg strHostIFmsg; + tstrHostIfPowerMgmtParam* pstrPowerMgmtParam = &strHostIFmsg.uniHostIFmsgBody.strPowerMgmtparam; + + // 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; + + 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; +} + + +/*Bug4218: Parsing Join Param*/ +#ifdef NMI_PARSE_SCAN_IN_HOST +/*Bug4218: Parsing Join Param*/ +/** +* @brief host_int_addToJoinBssTable +* @details Add Join Parameters to the end of BssTable (linked list) +* @param[in] tstrJoinBssParam* pNewJoinBssParam +* @return Error code. +* @author zsalah +* @date +* @version 1.0**/ +static NMI_Sint32 host_int_addToJoinBssTable(tstrJoinBssParam* pNewJoinBssParam) +{ + if(pNewJoinBssParam!=NULL) + { + //PRINT_D(HOSTINF_DBG,"Adding JOIN PARAMETERS\n"); + if (gtstrBssTable.u8noBssEntries==0) + { + pNewJoinBssParam->nextJoinBss = NULL; + gtstrBssTable.head = pNewJoinBssParam; + gtstrBssTable.tail = pNewJoinBssParam; + + } + else + { + pNewJoinBssParam->nextJoinBss = NULL; + gtstrBssTable.tail->nextJoinBss = (struct _tstrJoinParam*)pNewJoinBssParam; + gtstrBssTable.tail = pNewJoinBssParam; + + } + gtstrBssTable.u8noBssEntries+=1; + PRINT_D(HOSTINF_DBG,"Added Entry to table, count= %d \n",gtstrBssTable.u8noBssEntries); + return 0; + } + return -1; +} + +/*Bug4218: Parsing Join Param*/ +/** +* @brief host_int_getJoinBssParam +* @details get the JoinParam entry of a given ssid from JoinParamTable +* @param[in] NMI_Uint8* ssid,NMI_Uint8 ssidLen +* @return tstrJoinBssParam* +* @author zsalah +* @date +* @version 1.0**/ +tstrJoinBssParam* host_int_getJoinBssParam(NMI_Uint8* ssid,NMI_Uint8 ssidLen) +{ + tstrJoinBssParam* ptstrCurrBssParam; + NMI_Uint8 u8noBssEntries; + int i; + ptstrCurrBssParam = gtstrBssTable.head; + u8noBssEntries = gtstrBssTable.u8noBssEntries; + PRINT_D(HOSTINF_DBG,"NO of Enteries = %d\n",gtstrBssTable.u8noBssEntries); + if(gtstrBssTable.u8noBssEntries==0) + return NULL; + for(i=0; i<ssidLen;i++) + PRINT_D(HOSTINF_DBG,"%c",ssid[i]); + while(!(u8noBssEntries==0)) + { + + if(NMI_memcmp(ptstrCurrBssParam->ssid,ssid,ssidLen)==0) + { + PRINT_D(HOSTINF_DBG,"\nFound Join Entry\n"); + return ptstrCurrBssParam; + } + else + ptstrCurrBssParam = (tstrJoinBssParam*)ptstrCurrBssParam->nextJoinBss; + u8noBssEntries--; + } + PRINT_D(HOSTINF_DBG,"Entry Not Foundin Table\n"); + return NULL;; +} +/*Bug4218: Parsing Join Param*/ +/** +* @brief host_int_addJoinBssParam +* @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_addJoinBssParam(tstrNetworkInfo* ptstrNetworkInfo) +{ + tstrJoinBssParam* pNewJoinBssParam=NULL; + NMI_Uint8* pu8IEs; + NMI_Uint16 u16IEsLen; + NMI_Uint16 index = 0; + NMI_Uint8 suppRatesNo; + NMI_Uint8 extSuppRatesNo; + NMI_Uint16 jumpOffset; + NMI_Uint8 pcipherCount; + NMI_Uint8 authCount; + NMI_Uint8 i; + + 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; + /*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]); + } + printk("\n"); + 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; + } + 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 + NMI_memset(pNewJoinBssParam->rsn_pcip_policy,0xFF, 3); + NMI_memset(pNewJoinBssParam->rsn_auth_policy,0xFF, 3); + + 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: "); + for(i=1; i<=pcipherCount; i++) + { + //each count corresponds to 4 bytes, only last byte is saved + pNewJoinBssParam->rsn_pcip_policy[i-1] = pu8IEs[rsnIndex+(i*4)-1]; + //PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->rsn_pcip_policy[i-1]); + } + 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=1; i<=authCount; i++) + { + //each count corresponds to 4 bytes, only last byte is saved + pNewJoinBssParam->rsn_auth_policy[i-1] = pu8IEs[rsnIndex+(i*4)-1]; + printk("%0x ",pNewJoinBssParam->rsn_auth_policy[i-1]); + } + //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 + + } + + + } + + host_int_addToJoinBssTable(pNewJoinBssParam); +} +#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**/ +#define BLOCK_ACK_REQ_SIZE 0x14 + +static int host_int_addBASession(char* pBSSID,char TID,short int BufferSize, + short int SessionTimeout) +{ + tstrWID strWID; + int AddbaTimeout = 100; + char* ptr = NULL; + int s32Err; + printk("Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n", + pBSSID[0],pBSSID[1],pBSSID[2],pBSSID[3],pBSSID[4],pBSSID[5],TID,BufferSize,SessionTimeout); + + 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,pBSSID, 6); + ptr += 6; + *ptr++ = TID; + /* BA Policy*/ + *ptr++ = 1; + /* Buffer size*/ + *ptr++ = (BufferSize & 0xFF); + *ptr++ = ((BufferSize>>16) & 0xFF); + /* BA timeout*/ + *ptr++ = (SessionTimeout& 0xFF); + *ptr++ = ((SessionTimeout>>16) & 0xFF); + /* ADDBA timeout*/ + *ptr++ = (AddbaTimeout& 0xFF); + *ptr++ = ((AddbaTimeout>>16) & 0xFF); + /* Group Buffer Max Frames*/ + *ptr++ = 8; + /* Group Buffer Timeout */ + *ptr++ = 0; + + s32Err = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE); + if(s32Err) + 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,pBSSID, 6); + ptr += 6; + /* TID*/ + *ptr++ = TID; + /* Max Num MSDU */ + *ptr++ = 8; + /* BA timeout*/ + *ptr++ = (SessionTimeout& 0xFF); + *ptr++ = ((SessionTimeout>>16) & 0xFF); + /*Ack-Policy */ + *ptr++ = 3; + s32Err = SendConfigPkt(SET_CFG, &strWID, 1, NMI_TRUE); + + return s32Err; + + +} + + + + diff --git a/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_sdio.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_sdio.c new file mode 100755 index 00000000..bb0f5012 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_sdio.c @@ -0,0 +1,1490 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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, ®)) { + 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++) + { + //printk("[MMM] buf = 0x%0x, addr = 0x%x\n", buf, addr); + 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, ®)) { + 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, ®); + 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, ®); + 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, ®)) { + 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, ®); + 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, ®); + 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, ®); + 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, ®); + 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/Nmc1000_Release7.0/src/driver/nmi_spi.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_spi.c new file mode 100755 index 00000000..e8345de7 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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, ®)) { + 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, ®); + 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, ®); + 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, ®)) { + /* 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, ®)){ + // 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, ®); + 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, ®); + 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, ®); + 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, ®); + 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/Nmc1000_Release7.0/src/driver/nmi_wlan.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan.c new file mode 100755 index 00000000..7ce9cfe9 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan.c @@ -0,0 +1,2501 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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_monitor_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); + +//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 + **/ + 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; + +static uint32_t NMI_INT_STATS = 0; +static uint32_t NMI_GP_REG_1 = 0; + +static nmi_wlan_dev_t g_wlan; + +/******************************************** + + 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; +} + +/******************************************** + + Queue + +********************************************/ +static struct txq_entry_t *nmi_wlan_txq_remove(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; + 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; + p->txq_head = tqe; + p->txq_tail = tqe; + //p->os_func.os_signal(p->txq_wait); + } else { + tqe->next = NULL; + 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; + p->txq_head = tqe; + p->txq_tail = tqe; + } else { + tqe->next = p->txq_head; + 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; + +} + +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; + /** + 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"); + 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; + PRINT_D(TX_DBG,"Adding Network packet at the Queue tail\n"); + nmi_wlan_txq_add_to_tail(tqe); + return 1; +} +#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 + +********************************************/ + +static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP; + +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, ®) ; + /* 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, ®); + 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 &= ~(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 &= ~(1<<31); + g_wlan.hif_func.hif_write_reg(0x1e48, reg); + } + } + genuChipPSstate = CHIP_WAKEDUP; +} + +void chip_sleep_manually(NMI_Uint32 u32SleepTime) +{ + uint32_t val32; + + if(genuChipPSstate != CHIP_WAKEDUP) + { + /* chip is already sleeping. Do nothing */ + return; + } + + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + + 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); + g_wlan.hif_func.hif_write_reg(0x1C0C, val32); + + genuChipPSstate = CHIP_SLEEPING_MANUAL; + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); + +} + + +/******************************************** + + 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(); + 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; + } + + p->os_func.os_enter_cs(p->hif_lock); + 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; + p->os_func.os_leave_cs(p->hif_lock); + } + + do { + ret = p->hif_func.hif_read_reg(NMI_HOST_VMM_CTL, ®); + 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"); + p->os_func.os_leave_cs(p->hif_lock); + break; + } + p->os_func.os_leave_cs(p->hif_lock); + + 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); + + p->os_func.os_enter_cs(p->hif_lock); + 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); + } + + + p->os_func.os_leave_cs(p->hif_lock); + 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; + uint32_t vmm_table[NMI_VMM_TBL_SIZE]; + + 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); + + /** + 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_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 */ + } + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_wakeup(); + } + + do { + + ret = p->hif_func.hif_read_reg(NMI_HOST_TX_CTRL, ®); + 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 { + /** + wait for vmm table is ready + **/ + PRINT_WRN(GENERIC_DBG, "[nmi txq]: warn, vmm table not clear yet, wait... \n"); + p->os_func.os_leave_cs(p->hif_lock); + p->os_func.os_sleep(3); /* wait 3 ms */ + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_wakeup(); + } + } + } while (!p->quit); + + if(!ret) { + goto _end_; + } + int 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, ®); + 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{ + p->os_func.os_leave_cs(p->hif_lock); + p->os_func.os_sleep(3); /* wait 3 ms */ + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_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, ®); + 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. */ + p->os_func.os_leave_cs(p->hif_lock); + + /** + Copy data to the TX buffer + **/ + offset = 0; + i = 0; + do { + tqe = nmi_wlan_txq_remove(); + 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){ + buffer_offset = ETH_ETHERNET_HDR_OFFSET; + } + 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); + p->os_func.os_free(tqe); + } else { + break; + } + } while (--entries); + + /** + lock the bus + **/ + //PRINT_D(GENERIC_DBG,"Locking hif_lock\n"); + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_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, ®); + 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_: + p->os_func.os_leave_cs(p->hif_lock); + if (ret != 1) + break; + } while(0); + + /*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; +/*bug 3887: [AP] Allow Management frames to be passed to the host*/ + #ifdef NMI_AP_EXTERNAL_MLME + #define IS_MANAGMEMENT 0x100 + #define IS_MANAGMEMENT_CALLBACK 0x080 + #define IS_MGMT_STATUS_SUCCES 0x040 + + + if(pkt_offset & IS_MANAGMEMENT) + { + PRINT_D(RX_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); + //NMI_PRINTF("OFFSET = %0x\n",pkt_offset); +#ifdef USE_WIRELESS + NMI_WFI_monitor_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 (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; + } + + + + if (!is_cfg_packet) { + + if (p->net_func.rx_indicate) { + if (pkt_len > 0) { + p->net_func.rx_indicate(&buffer[pkt_offset+offset], pkt_len); + 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(); + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); +} +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)){ + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); + } + 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))){ + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); + } + 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 + } + genuChipPSstate = CHIP_SLEEPING_AUTO; + + + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); +} + +#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"); + p->os_func.os_leave_cs(p->hif_lock); + return; + } + + if (size > 0) { + uint32_t address = 0; + +#ifdef MEMORY_STATIC + if (p->rx_buffer_size - offset < (2*1024)/*size*/) + offset = 0; + buffer = &p->rx_buffer[offset]; +#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); + p->os_func.os_leave_cs(p->hif_lock); + 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)){ + p->os_func.os_leave_cs(p->hif_lock); + } + 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; + 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; + buffer = &p->rx_buffer[offset]; +#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, ®); + 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)){ + p->os_func.os_leave_cs(p->hif_lock); + } +#else /* PLL_WORKAROUND */ + p->os_func.os_leave_cs(p->hif_lock); +#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; + + + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + + if(!g_wlan.hif_func.hif_clear_int()){ + printk("UNKNOWN INT\n"); + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); + 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){ + /* Chip is up and talking*/ + genuChipPSstate = CHIP_WAKEDUP; + nmi_wlan_handle_isr(xfer_cnt, 0); + } +#else /* ! NMI_SDIO */ + #ifdef PLL_WORKAROUND + uint32_t int_status; + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + 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){ + /* Chip is up and talking*/ + genuChipPSstate = CHIP_WAKEDUP; + 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 + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + 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); + + genuChipPSstate = CHIP_SLEEPING_AUTO; +} + +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; + 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++; + + } + + /** + 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); + + if (size > 0) { +#ifdef MEMORY_STATIC + if (p->rx_buffer_size - offset < size) + offset = 0; + buffer = &p->rx_buffer[offset]; +#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 + /** + 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; + + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + 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); + /* Chip is up and talking*/ + genuChipPSstate = CHIP_WAKEDUP; + } + 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 + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); +} +#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; + + blksz = (1ul << 12); /* Bug 4703: 4KB Good enough size for most platforms = PAGE_SIZE. */ + /* Allocate a DMA coherent buffer. */ + dma_buffer = (uint8_t *)g_wlan.os_func.os_malloc(blksz); + 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 + p->os_func.os_enter_cs(p->hif_lock); + 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; + } + p->os_func.os_leave_cs(p->hif_lock); + + 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(dma_buffer) g_wlan.os_func.os_free(dma_buffer); +_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 + p->os_func.os_enter_cs(p->hif_lock); + ret = p->hif_func.hif_read_reg(NMI_VMM_CORE_CTL, ®); + if (!ret) { + nmi_debug(N_ERR, "[nmi start]: fail read reg vmm_core_ctl...\n"); + p->os_func.os_leave_cs(p->hif_lock); + 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"); + p->os_func.os_leave_cs(p->hif_lock); + 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; + } + p->os_func.os_enter_cs(p->hif_lock); + 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"); + p->os_func.os_leave_cs(p->hif_lock); + /* 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 + 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"); + p->os_func.os_unlock(p->hif_lock); + /* 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"); + p->os_func.os_leave_cs(p->hif_lock); + /* 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,®); + 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 |= (1ul << 10); + ret = p->hif_func.hif_write_reg(NMI_GLB_RESET_0, reg); + p->hif_func.hif_read_reg(NMI_GLB_RESET_0,®); + p->os_func.os_leave_cs(p->hif_lock); + + 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 + **/ + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_wakeup(); + } + + ret = p->hif_func.hif_read_reg(NMI_GLB_RESET_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + p->os_func.os_leave_cs(p->hif_lock); + 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"); + p->os_func.os_leave_cs(p->hif_lock); + return ret; + } + + + + do + { + ret = p->hif_func.hif_read_reg(NMI_GLB_RESET_0, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + p->os_func.os_leave_cs(p->hif_lock); + 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, ®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + p->os_func.os_leave_cs(p->hif_lock); + return ret; + } + PRINT_D(GENERIC_DBG,"Read RESET Reg %x : Retry%d\n",reg,timeout); + break; + } + + }while(timeout) ; + +/******************************************************************************/ +/* 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)); /**/ + /**/ + 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); /**/ +/******************************************************************************/ + + + p->os_func.os_leave_cs(p->hif_lock); + + 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(); + 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 (p->tx_buffer) { + p->os_func.os_free(p->tx_buffer); + } +#if 0 + if (p->rx_buffer) { + p->os_func.os_free(p->rx_buffer); + } +#endif + p->os_func.os_enter_cs(p->hif_lock); + + if(genuChipPSstate != CHIP_WAKEDUP) + { + chip_wakeup(); + } + + ret = p->hif_func.hif_read_reg(NMI_INT_STATS,®); + if (!ret) { + PRINT_ER("Error while reading reg\n"); + p->os_func.os_leave_cs(p->hif_lock); + } + 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"); + p->os_func.os_leave_cs(p->hif_lock); + } + p->os_func.os_leave_cs(p->hif_lock); + /** + io clean up + **/ + p->hif_func.hif_deinit(NULL); + +} + +static int nmi_wlan_cfg_commit(int type) +{ + 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; + int seq_no = p->cfg_seq_no%256; + + /** + 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); + 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) +{ + 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)) + return 0; + + 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) +{ + 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)) + return 0; + + + 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 Rsponse 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; + + + g_wlan.os_func.os_enter_cs(g_wlan.hif_lock); + chipid = nmi_get_chipid(NMI_TRUE); + + + printk("ChipID = %x\n",chipid); + + + 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, ®); + 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, ®); + /* 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, ®); + + /* 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 + + + + g_wlan.os_func.os_leave_cs(g_wlan.hif_lock); + + 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; +} + + +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; + //g_wlan.rx_buffer_size = inp->os_context.rx_buffer_size; + + //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 + **/ + g_wlan.tx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.tx_buffer_size); + if (g_wlan.tx_buffer == NULL) { + /* ENOBUFS 105 */ + ret = -105; + goto _fail_; + } + +/* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/ +#if 0 + g_wlan.rx_buffer = (uint8_t *)g_wlan.os_func.os_malloc(g_wlan.rx_buffer_size); + if (g_wlan.rx_buffer == NULL) + 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; + #endif + + if(!init_chip()){ + /* EIO 5 */ + ret = -5; + goto _fail_; + } + + return 1; + +_fail_: + + if (g_wlan.tx_buffer) + g_wlan.os_func.os_free(g_wlan.tx_buffer); + +#if 0 + if (g_wlan.rx_buffer) + g_wlan.os_func.os_free(g_wlan.rx_buffer); +#endif + 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/Nmc1000_Release7.0/src/driver/nmi_wlan_cfg.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan_cfg.c new file mode 100755 index 00000000..08809f2b --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/nmi_wlan_cfg.c @@ -0,0 +1,621 @@ +//////////////////////////////////////////////////////////////////////////// +// +// 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" +#endif + +/******************************************** + + Global Data + +********************************************/ + +typedef struct { + nmi_debug_func dPrint; + + int mac_status; + uint8_t mac_address[7]; + 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_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, 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; + + 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; +#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/Nmc1000_Release7.0/src/driver/transport/Packet_Tx_Rx.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/transport/Packet_Tx_Rx.c new file mode 100755 index 00000000..e689f55a --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/driver/transport/Packet_tx_Rx_socket.c b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/driver/transport/Packet_tx_Rx_socket.c new file mode 100755 index 00000000..307201fa --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/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/Nmc1000_Release7.0/src/svnrevision.h b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/svnrevision.h new file mode 100755 index 00000000..e07f3be4 --- /dev/null +++ b/drivers/net/wireless/nmi/Nmc1000_Release7.0/src/svnrevision.h @@ -0,0 +1,6 @@ +#ifndef SVNREV_H +#define SVNREV_H +#define NMC1000_DRIVER_VERSION "7.04" +#define SVNREV "3614" +#define SVNURL "svn://ssw.gotdns.org/SSW/sandbox/Wi-Fi/src/driver/head/platform/via/wm8880/head/Hexing/ANDROID_3.4.5-DS/ANDROID_3.4.5/drivers/net/wireless/nmi/Nmc1000_Release7.0" +#endif -- cgit