From 00a7da04cbe2006854ac40cc27ac479dfbcdf62a Mon Sep 17 00:00:00 2001 From: Sateesh Kotapati Date: Wed, 27 Nov 2024 14:55:39 +0530 Subject: [PATCH] Linux SDIO driver code - Initial version Signed-off-by: Sateesh Kotapati --- README.md | 20 + .../Driver/common/include/platform_specific.h | 29 + .../linux/Driver/common/include/sli_api.h | 171 ++ .../linux/Driver/common/include/sli_app.h | 139 + .../Driver/common/include/sli_app_util.h | 30 + .../linux/Driver/common/include/sli_common.h | 58 + .../Driver/common/include/sli_common_types.h | 80 + .../linux/Driver/common/include/sli_config.h | 81 + .../linux/Driver/common/include/sli_global.h | 2522 +++++++++++++++++ .../linux/Driver/common/include/sli_hal.h | 50 + .../Driver/common/include/sli_lib_util.h | 27 + .../linux/Driver/common/include/sli_linux.h | 207 ++ .../linux/Driver/common/include/sli_nic.h | 294 ++ platforms/linux/Driver/common/src/insert.sh | 2 + platforms/linux/Driver/common/src/remove.sh | 1 + .../linux/Driver/common/src/sli_lib_util.c | 121 + .../linux/Driver/common/src/sli_linux_data.c | 551 ++++ .../Driver/common/src/sli_linux_netlink.c | 418 +++ .../Driver/common/src/sli_linux_specific.c | 242 ++ .../linux/Driver/common/src/sli_net_device.c | 998 +++++++ .../Driver/common/src/sli_send_boot_insn.c | 179 ++ .../linux/Driver/sdio/include/sli_sdio.h | 271 ++ platforms/linux/Driver/sdio/src/Makefile | 81 + platforms/linux/Driver/sdio/src/insert.sh | 2 + platforms/linux/Driver/sdio/src/remove.sh | 1 + .../Driver/sdio/src/sli_hal_mcu_ioports.c | 151 + .../linux/Driver/sdio/src/sli_hal_mcu_sdio.c | 1986 +++++++++++++ 27 files changed, 8712 insertions(+) create mode 100644 README.md create mode 100644 platforms/linux/Driver/common/include/platform_specific.h create mode 100644 platforms/linux/Driver/common/include/sli_api.h create mode 100644 platforms/linux/Driver/common/include/sli_app.h create mode 100644 platforms/linux/Driver/common/include/sli_app_util.h create mode 100644 platforms/linux/Driver/common/include/sli_common.h create mode 100644 platforms/linux/Driver/common/include/sli_common_types.h create mode 100644 platforms/linux/Driver/common/include/sli_config.h create mode 100644 platforms/linux/Driver/common/include/sli_global.h create mode 100644 platforms/linux/Driver/common/include/sli_hal.h create mode 100644 platforms/linux/Driver/common/include/sli_lib_util.h create mode 100644 platforms/linux/Driver/common/include/sli_linux.h create mode 100644 platforms/linux/Driver/common/include/sli_nic.h create mode 100644 platforms/linux/Driver/common/src/insert.sh create mode 100644 platforms/linux/Driver/common/src/remove.sh create mode 100644 platforms/linux/Driver/common/src/sli_lib_util.c create mode 100644 platforms/linux/Driver/common/src/sli_linux_data.c create mode 100644 platforms/linux/Driver/common/src/sli_linux_netlink.c create mode 100644 platforms/linux/Driver/common/src/sli_linux_specific.c create mode 100644 platforms/linux/Driver/common/src/sli_net_device.c create mode 100644 platforms/linux/Driver/common/src/sli_send_boot_insn.c create mode 100644 platforms/linux/Driver/sdio/include/sli_sdio.h create mode 100644 platforms/linux/Driver/sdio/src/Makefile create mode 100644 platforms/linux/Driver/sdio/src/insert.sh create mode 100644 platforms/linux/Driver/sdio/src/remove.sh create mode 100644 platforms/linux/Driver/sdio/src/sli_hal_mcu_ioports.c create mode 100644 platforms/linux/Driver/sdio/src/sli_hal_mcu_sdio.c diff --git a/README.md b/README.md new file mode 100644 index 0000000..8096cee --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Procedure for SDIO SAPI Execution + +## Steps + +1. Navigate to the driver source directory: + ```sh + cd linux-sdio-driver/platforms/linux/Driver/sdio/src + ``` + +2. Compile the driver: + ```sh + make clean + make + ``` + +3. Insert the driver: + ```sh + insmod rpssdio.ko + ``` + diff --git a/platforms/linux/Driver/common/include/platform_specific.h b/platforms/linux/Driver/common/include/platform_specific.h new file mode 100644 index 0000000..c5e7a6b --- /dev/null +++ b/platforms/linux/Driver/common/include/platform_specific.h @@ -0,0 +1,29 @@ +/***************************************************************************//** + * @file + * @brief Platform specific + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef PLATFORM_SPECIFIC_H +#define PLATFORM_SPECIFIC_H +#include "sli_global.h" + +#include "sli_nic.h" + +#define SLI_DPRINT(lvl, fmt, args...) if (lvl & SLI_DEBUG_LVL) printk(fmt, ##args) + +#ifndef NULL +#define NULL 0 +#endif +#endif diff --git a/platforms/linux/Driver/common/include/sli_api.h b/platforms/linux/Driver/common/include/sli_api.h new file mode 100644 index 0000000..9f48d15 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_api.h @@ -0,0 +1,171 @@ +/***************************************************************************//** + * @file sli_api.h + * @brief API specific Defines + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + + +#ifndef SLI_API_H +#define SLI_API_H + +/** + * Include Files + */ +#include "sli_global.h" +#include "sli_app_util.h" +/** + * Global Defines + */ + +//! Host interfaces +#define SLI_SPI 0 +#define SLI_UART 1 +#define SLI_USB 2 +#define SLI_SDIO 3 + +#ifdef RS9116 +//! Upgrade Image types +#define BURN_NWP_FW 'B' +#else +#define SLI_UPGRADE_IMAGE_I_FW '2' +#endif +#define SLI_UPGRADE_BL '#' + + +//! Firmware Upgradation form host params +#define FW_UP_PL 0 +#define FW_UP_REQ 1 +#ifdef RS9116 +#define SLI_RPS_HEADER 64 +#else +#define SLI_RPS_HEADER 32 +#endif +#define SLI_FW_UP_SUCCESS 0x0003 + +//!Load Image types +#ifdef RS9116 +#define LOAD_NWP_FW 'A' +#else +#define LOAD_NWP_FW '1' +#endif +#define LOAD_DEFAULT_NWP_FW_ACTIVE_LOW 0x71 + +//!Select Default image +#define SELECT_DEFAULT_NWP_FW '5' + +// bypass bootup +#define ENABLE_GPIO_BASED_BYPASS '7' +#define DISABLE_GPIO_BASED_BYPASS '8' + +//!load default +#define SLI_LOAD_DEFAULT '9' + +//! Check CRC +#define CHECK_NWP_INTEGRITY 'K' + + +#define HOST_INTF_REG_OUT 0x4105003C +#define HOST_INTF_REG_IN 0x41050034 +#define BOARD_READY 0xABCD +#define REG_READ 0xD1 +#define REG_WRITE 0xD2 +#define PONG_WRITE 0xD4 +#define PING_WRITE 0xD5 +#define GPIO_RESET 0xD7 +#define LOAD_BOOTLOADER 0xD8 +#ifdef RS9116 +#define HOST_INTERACT_REG_VALID (0xA0 << 8) +#define HOST_INTERACT_REG_VALID_READ (0xAB << 8) +#else +#define HOST_INTERACT_REG_VALID (0xAB << 8) +#define HOST_INTERACT_REG_VALID_READ (0xAB << 8) +#endif +#define PONG_AVAIL 'O' +#define PING_AVAIL 'I' +#define PONG_VALID 'O' +#define PING_VALID 'I' +#define LOADING_INITIATED '1' +#define SEND_RPS_FILE '2' +#define FWUP_SUCCESSFUL 'S' +#define EOF_REACHED 'E' +#define BOOTUP_OPTIONS_LAST_CONFIG_NOT_SAVED 0xF1 +#define BOOTUP_OPTIONS_CHECKSUM_FAIL 0xF2 +#define INVALID_OPTION 0xF3 +#define CHECKSUM_SUCCESS 0xAA +#define CHECKSUM_FAILURE 0xCC +#define CHECKSUM_INVALID_ADDRESS 0x4C + +#define SLI_SUCCESS 0 +#define SLI_BUSY -1 +#define SLI_FAIL -2 +#define SLI_BUFFER_FULL -3 +#define SLI_IN_SLEEP -4 + + +#define SLI_RESET_LOOP_COUNTER(X) X = 0; +#define SLI_WHILE_LOOP(X, Y) while((X++) < (uint32)Y) +#define SLI_LOOP_COUNT_UPGRADE_IMAGE 0xFFFF +#define SLI_LOOP_COUNT_WAKEUP_REQ 0xFFFFFFFF +#define SLI_LOOP_COUNT_WAKEUP_WAIT 0xFFFFFFFF +#define SLI_LOOP_COUNT_UPGRADE_REQ 0xFFFF +#define SLI_LOOP_COUNT_UPGRADE_CHUNK 0xFFFF +#define SLI_LOOP_COUNT_UPGRADE_STATUS 0xFFFF +#define SLI_LOOP_COUNT_SELECT_OPTION 0xFFFF +#define SLI_CHECK_LOOP_COUNTER(X, Y) { if(X >= Y)\ + return -1;} + +//!SPI Internal Register Offset +#define SLI_SPI_INT_REG_ADDR 0x00 //@ register access method +#define SPI_SPI_MODE_REG_ADDR 0x08 //@ register access method + +//!Power Mode Constants +#define SLI_POWER_MODE_0 0x0000 +#define SLI_POWER_MODE_1 0x0001 +#define SLI_POWER_MODE_2 0x0002 +#define SLI_POWER_MODE_3 0x0003 +#define SLI_POWER_MODE_8 0x0008 +#define SLI_POWER_MODE_9 0x0009 + +#define RSI_RSP_SOFT_RESET 0x1C + +#define BIT(a) ((long int)1 << a) + +/*=====================================================================================*/ +/** + * This is platform dependent operation.Needs to be implemented + * specific to the platform.This timer is mentioned in the following functions + * Application/TCPDemo/Source/main.c + * WLAN/SPI/Source/spi_functs.c + * WLAN/SPI/Source/spi_iface_init.c + * + */ + + + +extern volatile sli_powerstate sli_pwstate; +/* + * Function Prototype Definitions + */ + + +uint8* sli_fill_parameters(uint32 type, uint8 *buffer); +void config_gpio_output(uint8 value); +void config_gpio_input(void); +uint8 get_gpio_value(); +uint8 get_spi_intr_gpio_value(); +int16 sli_module_power_cycle(void); +int16 sli_execute_cmd(uint8 *descparam,uint8 *payloadparam,uint16 size_param); + + +#endif diff --git a/platforms/linux/Driver/common/include/sli_app.h b/platforms/linux/Driver/common/include/sli_app.h new file mode 100644 index 0000000..fcb1da5 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_app.h @@ -0,0 +1,139 @@ +/***************************************************************************//** + * @file + * @brief HEADER, APP, APPLICATION Header file + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ +#include "sli_config.h" +#include "sensor_data.h" +#ifndef SLI_APP_H +#define SLI_APP_H +#define SLI_MAXSOCKETS 10 //@ Maximum number of open sockets + +/* Application control block */ + + +/*===================================================*/ +/** + * Sockets Structure + * Structure linking socket number to protocol + */ +typedef struct { + uint8 ip_version[2]; //@ ip version + uint8 socketDescriptor[2]; //@ socket descriptor + uint8 protocol; //@ PROTOCOL_UDP, PROTOCOL_TCP or PROTOCOL_UNDEFINED + uint8 src_port[2]; //@ socket local port number + union{ + uint8 ipv4_address[4]; //@ Destination ipv4 address + uint8 ipv6_address[16]; //@ Destination ipv6 address + }dest_ip; + uint8 dest_port[2]; //@ Destination port number +} sli_socketsStr; + +/*===================================================*/ +/** + * Sockets Structure Array + * Array of Structures linking socket number to protocol + */ +typedef struct { + rsi_socketsStr socketsArray[RSI_MAXSOCKETS+1]; + //@ Socket numbers are from 1 to 10 +} sli_sockets; + + +//! Host MIB structure and Object OID list +typedef struct MIB_ENTRY_STRUCT +{ + + char *obj_id; +} MIB_ENTRY; + + +typedef struct +{ + /* Error code */ + uint16 error_code; + /* Buffer to receive to response from Wi-Fi module */ + sli_uCmdRsp *uCmdRspFrame; + + /* For Certificate */ + struct SET_CHUNK_S set_chunks; + /* received paket count */ + uint32 rcvd_data_pkt_count; + /* Mac address */ + uint8 mac_addr[6]; +#if SLI_CONCURRENT_MODE + /* Mac address */ + uint8 ap_mac_addr[6]; +#endif + /* packet pending flag */ + volatile uint32 pkt_pending; + +#if (SLI_POWER_MODE == SLI_POWER_MODE_3) + //! backup of frame type + uint8 ps_descparam[16]; + //! Paket pending for power save + void * ps_pkt_pending; + //! size of currently held packet + uint16 ps_size_param; + //! devide sleep indication + uint16 ps_ok_to_send; +#endif +#if (SLI_POWER_MODE) + uint16 power_save_enable; +#endif +#if (defined(SLI_UART_INTERFACE) && !defined(TCP_IP_BYPASS)) + volatile int ack_flag; +#endif + /* PER Continous wave mode state*/ + int8 per_cont_mode_state; + + sli_uConnected_station_t stations_connected[SLI_NO_OF_CLIENTS_SUPPORTED]; + + /* Buffer to hold the received packet */ + uint8 read_packet_buffer[SLI_MAX_PAYLOAD_SIZE]; + + /* For Webpage write */ + uint8 webpage_morechunks; + + /* flag to enable send data*/ + uint8 glbl_send_data; + + /*structure to store socket information */ + volatile sli_sockets socketsStrArray; + + /* Send buffer data */ + uint8 send_buffer[SLI_MAX_PAYLOAD_SIZE]; + + uint8 write_packet_buffer[SLI_MAX_PAYLOAD_SIZE]; + +#if JSON_LOAD + /* Json buffer */ + uint8 json_buffer[JSON_BUFFER_SIZE]; + uint8 json_load_done; + /* User Data Structures */ + app_data_t sensor_data; +#endif + #if WEB_PAGE_LOAD + uint8 webpage_load_done; +#endif + //! frame sent for the send command, includes data + sli_uSend uSendFrame; + uint8 abort_call; +}sli_app_cb_t; + +#define SLI_FILL_PARAMETERS(x,y) sli_fill_parameters(x,y) + +extern sli_app_cb_t sli_app_cb; + +#endif diff --git a/platforms/linux/Driver/common/include/sli_app_util.h b/platforms/linux/Driver/common/include/sli_app_util.h new file mode 100644 index 0000000..3994a37 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_app_util.h @@ -0,0 +1,30 @@ +/***************************************************************************//** + * @file + * @brief Util Header file, the things that are useful for application + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_APP_UTIL_H +#define SLI_APP_UTIL_H +#include "sli_global.h" + + +uint32 sli_bytes4R_to_uint32(uint8 *dBuf); +uint16 sli_bytes2R_to_uint16(uint8 *dBuf); + + +void sli_uint32_to_4bytes(uint8 *dBuf, uint32 val); +void sli_uint16_to_2bytes(uint8 *dBuf, uint16 val); + +#endif diff --git a/platforms/linux/Driver/common/include/sli_common.h b/platforms/linux/Driver/common/include/sli_common.h new file mode 100644 index 0000000..0384559 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_common.h @@ -0,0 +1,58 @@ +/***************************************************************************//** + * @file + * @brief Some common defines + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_COMMON_H +#define SLI_COMMON_H + +#ifndef UINT32 +#define UINT32 unsigned int +#endif +#ifndef UINT16 +#define UINT16 unsigned short +#endif +#ifndef UINT8 +#define UINT8 unsigned char +#endif +#ifndef PVOID +#define PVOID void* +#endif + +#ifndef INT32 +#define INT32 int +#endif +#ifndef INT16 +#define INT16 short +#endif +#ifndef INT8 +#define INT8 char +#endif +#ifndef VOID +#define VOID void +#endif + +extern UINT32 sli_zone_enabled; + +#define SLI_STATIC static +#define SLI_EXTERN extern + +#define SLI_STATUS_FAIL -1 +#define SLI_STATUS_SUCCESS 0 +#define SLI_STATUS INT32 + +#define SLI_MAC_ADDR_LEN 6 + +#endif diff --git a/platforms/linux/Driver/common/include/sli_common_types.h b/platforms/linux/Driver/common/include/sli_common_types.h new file mode 100644 index 0000000..b6c9529 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_common_types.h @@ -0,0 +1,80 @@ +/***************************************************************************//** + * @file + * @brief HEADER, APP, APPLICATION Header file + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_COMMON_TYPES_H +#define SLI_COMMON_TYPES_H +typedef unsigned char UINT08; +typedef signed char INT08; + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef INT8 +typedef signed char INT8; +#endif +#ifndef UINT16 +typedef unsigned short int UINT16; +#endif +#ifndef INT16 +typedef short INT16; +#endif +#ifndef UINT32 +typedef unsigned int UINT32; +#endif + +#ifndef INT32 +typedef int INT32; +#endif + +typedef long SINT32; +typedef long SINT_32; +typedef unsigned long long int UINT64; +typedef long long int INT64; + +#ifndef WINDOWS +typedef unsigned char BOOL; +#endif + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef signed char int8; +typedef short int16; +typedef long int32; + +//ZIgb Datatypes +typedef int sint32, sint_32; +typedef unsigned long long int uint64; +typedef long long int int64; +typedef unsigned char SLI_ZB_STATUS; +#if (defined WINDOWS || defined LINUX_PLATFORM) +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +#endif +#ifdef LINUX_PLATFORM +typedef uint16_t profile_id_t; +typedef uint16_t cluster_id_t; +typedef uint16_t ProfileID; +typedef uint16_t ClusterID; +typedef uint16_t GroupID; +#endif + +#endif diff --git a/platforms/linux/Driver/common/include/sli_config.h b/platforms/linux/Driver/common/include/sli_config.h new file mode 100644 index 0000000..dd567de --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_config.h @@ -0,0 +1,81 @@ +/***************************************************************************//** + * @file + * @brief CONFIG INIT contains the default configurations used in the api's + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_CONFIG_H +#define SLI_CONFIG_H + + +#include "sli_api.h" +/*==============================================*/ +/** + * Global Defines + */ + + +#define SLI_INTERFACE SLI_SDIO //@ SLI_SPI or SLI_UART or SLI_USB or SLI_SDIO host interface for communication with module + +#if (SLI_INTERFACE == SLI_SPI) +#ifndef SLI_SPI_INTERFACE +#define SLI_SPI_INTERFACE +#endif +#undef SLI_UART_INTERFACE +#undef SLI_USB_INTERFACE +#undef SLI_SDIO_INTERFACE +#elif (SLI_INTERFACE == SLI_UART) +#ifndef SLI_UART_INTERFACE +#define SLI_UART_INTERFACE +#endif +#undef SLI_SPI_INTERFACE +#undef SLI_USB_INTERFACE +#undef SLI_SDIO_INTERFACE +#elif (SLI_INTERFACE == SLI_USB) +#ifndef SLI_USB_INTERFACE +#define SLI_USB_INTERFACE +#endif +#undef SLI_SPI_INTERFACE +#undef SLI_UART_INTERFACE +#undef SLI_SDIO_INTERFACE +#elif (SLI_INTERFACE == SLI_SDIO) +#ifndef SLI_SDIO_INTERFACE +#define SLI_SDIO_INTERFACE +#endif +#undef SLI_SPI_INTERFACE +#undef SLI_UART_INTERFACE +#undef SLI_USB_INTERFACE +#endif + +#ifdef SLI_UART_INTERFACE +#ifndef SLI_UART_DEVICE +#ifdef LINUX_PLATFORM +#define SLI_UART_DEVICE "/dev/ttyUSB0" +#elif WINDOWS +#define SLI_UART_DEVICE "\\\\.\\COM98" +#define BYPASS_CARD_READY 0 //@ 0 - for Card Ready Bypass and 1 - Wait for Card Ready +#endif + +#endif +#define SLI_USE_HOST_WAKEUP_AS_INTERRUPT ENABLE +#endif +#define SLI_SECURE_BOOT DISABLE +#define HOST_INTERACTION_MODE ENABLE //@ ENABLE or DISABLE host interaction for bootloader +#define SLI_TCP_IP_BYPASS ENABLE //@ ENABLE or DISABLE TCP/IP bypass mode +#if SLI_TCP_IP_BYPASS +#define SLI_TCP_IP_FEATURE_BIT_MAP TCP_IP_FEAT_BYPASS +#else +#define SLI_TCP_IP_FEATURE_BIT_MAP (TCP_IP_FEAT_DHCPV4_CLIENT | TCP_IP_FEAT_HTTP_CLIENT) +#endif +#endif diff --git a/platforms/linux/Driver/common/include/sli_global.h b/platforms/linux/Driver/common/include/sli_global.h new file mode 100644 index 0000000..7ee21d0 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_global.h @@ -0,0 +1,2522 @@ +/***************************************************************************//** + * @file + * @brief HEADER, GLOBAL, Global Header file + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_GLOBAL_H +#define SLI_GLOBAL_H + + +/** + * Global defines + */ +#define SLI_TRUE 1 +#define SLI_FALSE 0 +#ifndef NULL +#define NULL 0 +#endif + +#define DATA_RX 0 +#define DATA_TX 1 + +//#define PACKED 1 + +#define WLAN_MGMT_TYPE 0x4 +#define WLAN_DATA_TYPE 0x5 +#define ZB_MGMT_TYPE 0x1 +#define ZB_DATA_TYPE 0x1 +#define BT_MGMT_TYPE 0x2 +#define BT_DATA_TYPE 0x2 + +//!Comment This in case the host MCU is of BIG ENDIAN +#define SLI_LITTLE_ENDIAN 1 + +//!Uncomment this if host has hardware timers + + +//! Interrupt Mode Selection +#define SLI_INTERRUPTS + +//! Polled Mode selection +#include "sli_common_types.h" + +#define ENABLE 1 +#define DISABLE 0 + + +#ifndef SLI_HWTIMER +//! need to define this macro if h/w timer is available and it should increment spiTimer2, spiTimer1 +#define SLI_TICKS_PER_SECOND 50000 +#else +#define SLI_TICKS_PER_SECOND 10 +#endif + +/*=======================================================================================*/ +/** + * Device Parameters + */ +#define SLI_MAXSOCKETS 10 //@ Maximum number of open sockets + +/** + * Debugging Parameters + */ +#define SLI_MAX_PAYLOAD_SIZE 1600 //@ Maximum data payload size +#define SLI_AP_SCANNED_MAX 11 //@ Maximum number of scanned acces points +#define SLI_MAX_WFD_DEV_CNT 10 //@ Maximum wifi direct device count + +/** + * Things that are needed in this .h file + */ +#define SLI_FRAME_DESC_LEN 16 //@ Length of the frame descriptor, for both read and write +#define SLI_RXDATA_OFFSET_TCP_V4 26 //@ required Rx data offset value for TCPV4, 26 +#define SLI_RXDATA_OFFSET_TCP_V6 46 //@ required Rx data offset value for TCPV6, 46 +#define SLI_RXDATA_OFFSET_UDP_V4 14 //@ required Rx data offset value for UDP_V4, 14 +#define SLI_RXDATA_OFFSET_UDP_V6 34 //@ required Rx data offset value for UDP_V6, 34 +#define SLI_TXDATA_OFFSET_LUDP 16 //@ required Rx data offset value for LUDP, 26 + + + +#define SLI_PSK_LEN 64 //@ maximum length of PSK +#define SLI_SSID_LEN 34 //@ maximum length of SSID +#define SLI_BSSID_LEN 6 //@ BSSID length +#define SLI_IP_ADD_LEN 4 + + +/** + * Const declaration + * + */ +#define SLI_BYTES_3 3 + +/*===============================================*/ +/** + * Debug Structures + */ +typedef union { + struct { + uint8 assertion_type[4]; + uint8 assertion_level[4]; + } debugFrameSnd; + uint8 uDebugBuf[8]; //@ byte format to send to the spi interface,8 bytes +} sli_uDebug; + + +/*===================================================*/ +/** + * set region + */ + +typedef union { + struct{ + uint8 setregion_code_from_user_cmd; + /*Enable or disable set region from user: + 1-take from user configuration; + 0-Take from Beacons*/ + uint8 region_code; + /*region code(1-US,2-EU,3-JP.4-World Domain)*/ + uint8 module_type[2]; + }setRegionFrameSnd; + uint8 usetRegionBuf[4]; +}sli_usetregion; + + +/*======================================================*/ +/**Set region in AP mode +* +*/ +#define COUNTRY_CODE_LENGTH 3 + +#define MAX_POSSIBLE_CHANNEL 24 +typedef union{ + struct{ + uint8 setregion_code_from_user_cmd; + /*Enable or disable set region from user: + 1-take from user configuration; + 0-Take US or EU or JP*/ + uint8 country_code[3]; + /*region code(1-US,2-EU,3-JP)*/ + uint8 no_of_rules[4]; + struct{ + uint8 first_channel; + uint8 no_of_channels; + uint8 max_tx_power; + }channel_info[MAX_POSSIBLE_CHANNEL]; + }setRegionApFrameSnd; + uint8 usetRegionApBuf[80]; +}sli_usetregion_ap_t; + + +/*===============================================*/ +/** + * Scan Structures + */ + +//! The scan command argument union/variables + +typedef union { + struct { + uint8 channel[4]; //@ RF channel to scan, 0=All, 1-14 for 2.5GHz channels 1-14 + uint8 ssid[SLI_SSID_LEN]; //@ uint8[34], ssid to scan + uint8 reserved[5]; //@ uint8[6], reserved fields + uint8 scan_feature_bitmap; //@ uint8 , scan_feature_bitmap + uint8 channel_bit_map_2_4[2]; //@ uint8[2], channel bit map for 2.4 Ghz + uint8 channel_bit_map_5[4]; //@ uint8[4], channel bit map for 5 Ghz + } scanFrameSnd; + uint8 uScanBuf[SLI_SSID_LEN + 16]; //@ byte format to send to the spi interface, 48 bytes +} sli_uScan; + +/*===============================================*/ +/** + * Multicast Structures + */ + +//! Multicast command structure +typedef union { + struct { + uint8 ip_version[2]; + uint8 req_Type[2]; + union + { + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }group_address; + }multicastFrameSnd; + uint8 uMulticastBuf[20]; +}sli_uMulticast; + + +/*===============================================*/ +/** + * BGScan Structures + */ + +//! The BG scan command argument union/variables +typedef union { + struct { + uint8 bgscan_enable[2]; //@ enable or disable BG scan + uint8 enable_instant_bgscan[2]; //@ Is it instant bgscan or normal bgscan + uint8 bgscan_threshold[2]; //@ bg scan threshold value + uint8 rssi_tolerance_threshold[2]; //@ tolerance threshold + uint8 bgscan_periodicity[2]; //@ periodicity + uint8 active_scan_duration[2]; //@ sctive scan duration + uint8 passive_scan_duration[2]; //@ passive scan duration + uint8 multi_probe; //@ multi probe + } bgscanFrameSnd; + uint8 ubgScanBuf[15]; + //@ byte format to send to the spi interface, 68 bytes +} sli_ubgScan; + + +/*===============================================*/ +/** + * Join Data Frame Structure + */ +//! The BG scan command argument union/variables +typedef union { + struct { + uint8 timeout_bitmap[4]; //@ enable timeout for join or scan + uint8 timeout_value[2]; //@ value of the timeout in ms + } timeoutFrameSnd; + uint8 utimeoutBuf[6]; + //@ byte format to send to the spi interface, 68 bytes +} sli_utimeout; + + +/*===============================================*/ +/** + * Join Data Frame Structure + */ +typedef union { + struct { + uint8 reserved1; //@ reserved bytes:Can be used for security Type + uint8 securityType; //@ 0- Open, 1-WPA, 2-WPA2,6-MIXED_MODE + uint8 dataRate; //@ data rate, 0=auto, 1=1Mbps, 2=2Mbps, 3=5.5Mbps, 4=11Mbps, 12=54Mbps + uint8 powerLevel; //@ transmit power level, 0=low (6-9dBm), 1=medium (10-14dBm, 2=high (15-17dBm) + uint8 psk[SLI_PSK_LEN]; //@ pre-shared key, 63-byte string , last charecter is NULL + uint8 ssid[SLI_SSID_LEN]; //@ ssid of access point to join to, 34-byte string + uint8 join_feature_bitmap; + uint8 reserved2[2]; //@ reserved bytes + uint8 ssid_len; + uint8 listen_interval[4]; + uint8 vap_id; + uint8 join_bssid[6]; + } joinFrameSnd; + uint8 uJoinBuf[SLI_SSID_LEN + SLI_PSK_LEN + 8]; + //@ byte format to send to the spi interface, 106 (0x6A) bytes +} sli_uJoin; + +/*===============================================*/ +/** + * Stations Connected structure + */ +typedef struct { + uint8 mac_addr[6]; +}sli_uConnected_station_t; + +/*===============================================*/ +/** + * PSK Frame Structure + */ +typedef union { + struct { + uint8 TYPE; + uint8 psk_or_pmk[SLI_PSK_LEN]; + uint8 ap_ssid[SLI_SSID_LEN] ; + } PskFrameSnd; + uint8 uPskBuf[1 + SLI_PSK_LEN + SLI_SSID_LEN]; +} sli_uPsk; + + +/*===============================================*/ +/** + * Disconnect Data Frame Structure + */ +typedef struct { + uint8 mode_flag[2]; //@ 0- Module in Client mode, 1- AP mode + uint8 client_mac_addr[6]; //@ client MAC address, Ignored/Reserved in case of client mode +}sli_disassoc_t; + + +/*===============================================*/ +/** + * JSON Structures + */ +#define JSON_BUFFER_SIZE 512 +#define JSON_CHUNK_LEN 1024 +#define SLI_JSON_MAX_CHUNK_LENGTH 1024 +typedef struct sli_jsonCreateObject_s +{ + char filename[24]; + uint8 total_length[2]; + uint8 current_length[2]; + char json_data[SLI_JSON_MAX_CHUNK_LENGTH]; +} sli_jsonCreateObject_t; + +typedef struct sli_tfs_clear_files_s +{ + uint8 clear; +} sli_tfs_clear_files_t; + +typedef struct sli_tfs_erase_file_s +{ + char filename[24]; +} sli_tfs_erase_file_t; + +/*=======================================================*/ +/* + * TCP/IP Configure structures + */ + +typedef union { + struct { + uint8 dhcpMode; //@ 0=Manual, 1=Use DHCP + uint8 ipaddr[4]; //@ IP address of this module if in manual mode + uint8 netmask[4]; //@ Netmask used if in manual mode + uint8 gateway[4]; //@ IP address of default gateway if in manual mode + uint8 hostname[31]; //@ DHCP client host name + uint8 vap_id; //@ vap_id used in concurrent mode, 0 - Station and 1 - AP. + uint8 fqdn_flag[4]; //@ DHCP client FQDN flag option 81 + } ipparamFrameSnd; + uint8 uIpparamBuf[49]; + //@ 16 bytes, byte format to send to spi +} sli_uIpparam; + +/*===============================================*/ +/* + * IPV6 Configure + */ +typedef union{ + struct{ + uint8 mode[2]; + uint8 prefixLength[2]; + uint8 ipaddr6[16]; + uint8 gateway6[16]; + }ipconf6FrameSnd; + uint8 uIpconf6Buf[36]; +}sli_uIPconf6; + + +/*===================================================*/ +/** + * Socket Configure + */ + +#define WEBS_MAX_URL_LEN 51 +#define WEBS_MAX_HOST_LEN 51 + +typedef union { + struct { + uint8 ip_version[2]; //@ ip version4 or 6 + uint8 socketType[2]; //@ 0=TCP Client, 1=UDP Client, 2=TCP Server (Listening TCP) + uint8 moduleSocket[2]; //@ Our local module port number + uint8 destSocket[2]; //@ Port number of what we are connecting to + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }destIpaddr; + uint8 max_count[2]; + uint8 tos[4]; + uint8 ssl_bitmap; + uint8 ssl_ciphers; + uint8 webs_resource_name[WEBS_MAX_URL_LEN]; + uint8 webs_host_name[WEBS_MAX_HOST_LEN]; + uint8 tcp_retry_count; + uint8 socket_bitmap; + uint8 rx_window_size; + uint8 tcp_keepalive_initial_time[2]; + uint8 vap_id; + uint8 socket_cert_inx; + + } socketFrameSnd; + uint8 uSocketBuf[141]; //@ 24 bytes, byte format to send to spi +} sli_uSocket; + +/*===================================================*/ +/** + * Socket Close + */ +typedef union { + struct { + uint8 socketDescriptor[2]; + uint8 port_number[2]; //@ 2bytes, socket descriptor to close + } socketCloseFrameSnd; + uint8 uSocketCloseBuf[2]; //@ byte format to send to the spi interface, 2 bytes +} sli_uSocketClose; + + +/*===================================================*/ +/** + * Socket Read + */ +typedef union { + struct { + //! Socket descriptor + uint8 socketDescriptor; + + //! Receive data length + uint8 data_length[4]; + + //! Timeout in milli seconds + uint8 timeout_in_ms[2]; + + } socketReadFrameSnd; + + uint8 uSocketReadBuf[7]; //@ byte format to send to the spi interface, 2 bytes +} sli_uSocketRead; + +/*===================================================*/ +/** + * LTCP socket Connection status + */ +typedef union { + struct { + uint8 socketDescriptor[2]; //@ 2bytes, socket descriptor for LTCP socket + } queryLtcpConnStatusFrameSnd; + uint8 uLtcpConnStatusBuf[2]; + //@ byte format to send to the spi interface, 2 bytes + } sli_uQueryLtcpConnStatus; + + +/*===================================================*/ +/** + * sent bytes count + */ +typedef union { + struct { + uint8 socketDescriptor[2]; //@ 2bytes, socket descriptor + } querySentBytesCountFrameSnd; + uint8 uSentBytesStatusBuf[2]; + //@ byte format to send to the spi interface, 2 bytes + } sli_uQuerySentBytesCount; + + +/** + * New commads for WiseConnect + * + */ + +/*===================================================*/ +/** + * FIPS Mode + * + */ +typedef union { + struct { + uint8 fips_mode_enable[4]; + } fipsModeFrameSnd; + uint8 uFipsModeBuf[4]; +} sli_uFipsMode; + +/*===============================================*/ +/** + * RECHECK KEY Frame Structure + */ +typedef union { + struct { + uint8 type; /*0- PMK 1- EAP password*/ + uint8 key_store; + uint8 key[128]; /*PMK/EAP password*/ + } RecheckkeyFrameSnd; + uint8 uRecheckKeyBuf[2 + 128]; +} sli_urecheck_key; + +/*===============================================*/ +/** + * AUTO JOIN KEY Frame Structure + */ +typedef union { + struct { + uint8 type[2]; /*0- PMK 1- EAP password*/ + uint8 key[128]; /*PMK/EAP password*/ + } AutojoinkeyFrameSnd; + uint8 uAutojoinKeyBuf[2 + 128]; +} sli_uautojoin_key; + +/*===============================================*/ +/** + * FWUPGRADATION KEY Frame Structure + */ +typedef union { + struct { + uint8 key[16]; /*PMK/EAP password*/ + } FwupgradationkeyFrameSnd; + uint8 uFwupgradationKeyBuf[16]; +} sli_ufwupgradation_key; + +#define SLI_RPS_PAYLOAD_LEN 1024 +typedef struct sli_fw_up_frm_host_s{ + uint8 packet_info[4]; + uint8 payload[SLI_RPS_PAYLOAD_LEN]; +}sli_fw_up_t; + +/*===================================================*/ +/** + * Operational Mode + * + */ +typedef union { + struct { + uint8 oper_mode[4]; //@ operating mode 0-client, 1-p2p, 2-EAP, 6-AP, 8-PER + uint8 feature_bit_map[4]; //@ BIT(0)-Open mode security, BIT(1)-PSK security, BIT(2) JSON objects + uint8 tcp_ip_feature_bit_map[4]; //@ BIT(0)-tcp/ip bypass, BIT(1)-HTTP server,BIT(2)-DHCPV4 client, + //@ BIT(3)-DHCPV6 client, BIT(4)-DHCPV4 server, BIT(5)-DHCPV6 server + uint8 custom_feature_bit_map[4]; + uint8 ext_custom_feature_bit_map[4]; //@ extention of custom feature bitmap, valid only if BIT(31) of custom feature bitmap is set + uint8 bt_feature_bit_map[4]; //@ BT custom feature bitmap, valid only if BIT(31) of extention custom feature bitmap is set + uint8 ext_tcpip_feature_bit_map[4]; + uint8 ble_feature_bit_map[4]; //@ BLE custom feature bitmap, valid only if BIT(31) of bt custom feature bitmap is set + } operModeFrameSnd; + uint8 uOperModeBuf[28]; +} sli_uOperMode; + +/*===================================================*/ +/** + * Antenna Select + * + */ +typedef union { + struct { + uint8 AntennaVal; //@ uint8, Antenna value to set + uint8 gain_2g; //@ uint8, Antenna 2G gain value + uint8 gain_5g; //@ uint8, Antenna 5G gain value + } AntennaSelFrameSnd; + uint8 AnetnnaReqBuf[3]; +} sli_uAntenna; + + +/*===================================================*/ +/** + * feature mode + * + */ +typedef union { + struct { + uint8 pll_mode; //@ uint8, to set pll mode val + uint8 rf_type; //@ uint8, to select rf type + uint8 wireless_mode; //@ uint8, to select wireless mode + uint8 enable_ppp; //@ uint8, to select enable ppp + uint8 afe_type; //@ uint8, to select afe type + uint8 reserved[3]; //@ reserved + uint8 feature_enables[4]; //@ uint32, feature enables + } FeatureFrameSnd; + uint8 FeatureFrameReqBuf[12]; } sli_uFeatureFrame; + + + +/*===================================================*/ +/** + * Config p2p command + * + */ +typedef union { + struct { + uint8 GOIntent[2]; //@ GO Intent Value 0-15 for P2p GO or client , 16 - Soft AP + uint8 deviceName[64]; //@ name of the device + uint8 operChannel[2]; //@ In which channel we are operating after becomes Group owner + uint8 ssidPostFix[64]; //@ Postfix SSID + uint8 psk[64]; //@ PSK of the device + }configP2pFrameSnd; + uint8 uConfigP2pBuf[196]; +}sli_uConfigP2p; + +/*===================================================*/ +/** + * DNS Server command + * + */ +typedef union { + struct { + uint8 ip_version[2]; + uint8 DNSMode[2]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }primary_dns_ip; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }secondary_dns_ip; + }dnsServerFrameSnd; + uint8 uDnsBuf[36]; +}sli_uDnsServer; + + + +/*===================================================*/ +/** + * DNS query command + * + */ + +#define MAX_URL_LEN 90 +typedef union { + struct { + uint8 ip_version[2]; + uint8 aDomainName[MAX_URL_LEN]; + uint8 uDNSServerNumber[2]; + }dnsQryFrameSnd; + uint8 uDnsQryBuf[MAX_URL_LEN + 4]; +}sli_uDnsQry; + + +/*===================================================*/ +/** + * DNS update command + * + */ + +#define MAX_ZONE_LEN 31 +#define MAX_HOST_NAME_LEN 31 + +typedef union { + struct { + uint8 ip_version; + uint8 aZoneName[MAX_ZONE_LEN]; + uint8 aHostName[MAX_HOST_NAME_LEN]; + uint8 uDNSServerNumber[2]; + uint8 ttl[2]; + }dnsUpdateFrameSnd; + uint8 uDnsUpdateBuf[MAX_ZONE_LEN + MAX_HOST_NAME_LEN + 5]; +}sli_uDnsUpdate; + + +/*====================================================*/ +/** + * DHCP USER CLASS command + * + */ + + +/************************DHCP User CLass MAcros************/ +#define SLI_DHCP_USER_CLASS_MAX_COUNT 2 //@ MAX count of DHCP user class +#define SLI_DHCP_USER_CLASS_DATA_MAX_LEN 64 //@ MAX DATA LENGTH of DHCP user class + + +typedef struct dhcp_user_class_data_s +{ + uint8 length; + + uint8 data[SLI_DHCP_USER_CLASS_DATA_MAX_LEN]; +} dhcp_user_class_data_t; +typedef struct sli_dhcp_user_class_s +{ + uint8 mode; + //! User class list count + uint8 count; + + //! User class data + dhcp_user_class_data_t user_class_data[SLI_DHCP_USER_CLASS_MAX_COUNT]; + +} sli_dhcp_user_class_t; + +/*===================================================*/ +/** + * OTAF REQ command + * + */ +typedef union { + struct { + uint8 ip_version; + union{ + uint8 ipv4_address[SLI_IP_ADD_LEN]; + uint8 ipv6_address[SLI_IP_ADD_LEN * 4]; + }server_address; + uint8 server_port[4]; + uint8 chunk_number[2]; + uint8 time_out[2]; + uint8 retry_count[2]; + }OtafReqFrameSnd; + uint8 uOtafReqBuf[27]; +}sli_uOtafReq; + +/*===================================================*/ +/** + * Config EAP command + * + */ +typedef union { + struct { + uint8 eapMethod[32]; //@ EAP method + uint8 innerMethod[32]; //@ Inner method + uint8 userIdentity[64]; //@ user name + uint8 password[128]; //@ Password + uint8 okc_enable[4]; //@Opportunistic Key Caching enable + uint8 private_key_passwd[82]; //@ Private key password for encrypted certificates + }setEapFrameSnd; + uint8 uSetEapBuf[342]; +}sli_uSetEap; + +/*===================================================*/ +/** + * Web server command + * + */ +#define MAX_URL_LENGTH 40 +#define MAX_POST_DATA_LENGTH 512 + +typedef struct +{ + uint8 url_length; + uint8 url_name[MAX_URL_LENGTH]; + uint8 request_type; + uint8 post_content_length[2]; + uint8 post_data[MAX_POST_DATA_LENGTH]; + +}sli_urlReqFrameRcv; + +#define MAX_WEBPAGE_SEND_SIZE 1024 +typedef struct +{ + uint8 filename[24]; + uint8 total_len[2]; + uint8 current_len[2]; + uint8 has_json_data; + uint8 webpage[MAX_WEBPAGE_SEND_SIZE]; +} WebpageSnd_t; + +typedef union +{ + struct { + WebpageSnd_t Webpage_info; + }webServFrameSnd; + uint8 uWebServBuf[1024 + 2 + 2 + 1 + 24]; //@ byte format to send to the spi interface, 1026 bytes +}sli_uWebServer; + + +/*===================================================*/ +/** + * Host Web page command + * + */ +#define MAX_HOST_WEBPAGE_SEND_SIZE 1400 + +typedef struct +{ + uint8 total_len[4]; + uint8 more_chunks; + uint8 webpage[MAX_HOST_WEBPAGE_SEND_SIZE]; +} HostWebpageSnd_t; + + +/*===================================================*/ +/** + * Web Fields command + * + */ + +#define MAX_NO_OF_FIELDS 10 +#ifdef PACKED +typedef struct __attribute__((packed)){ +#else +typedef struct { +#endif + uint8 field_index; + uint8 field_val[64]; +}field_st_t; + +typedef union { +#ifdef PACKED + struct __attribute__((packed)){ +#else + struct { +#endif + uint8 field_cnt; + field_st_t field_st[MAX_NO_OF_FIELDS]; + }webFieldsFrameSnd; + uint8 uWebFieldBuf[680]; //@ byte format to send to the spi interface, 680 bytes +}sli_uWebFields; + +/*===================================================*/ +/** + * Set Mac Address + */ + +typedef union +{ + struct { + uint8 macAddr[6]; //@ byte array, mac address + } setMacAddrFrameSnd; + uint8 setMacAddrBuf[6]; +} sli_uSetMacAddr; + +/*===================================================*/ +/** + * Feature select + */ + +typedef union +{ + struct { + uint8 featsel_bitmapVal[4]; //@ 4 bytes, feat select bitmap value to set + } FeatselFrameSnd; + uint8 uFeatselBuf[4]; +} sli_uFeatsel; + +/*===================================================*/ +/** + * Band + */ + +typedef union +{ + struct { + uint8 bandVal; //@ uint8, band value to set + } bandFrameSnd; + uint8 uBandBuf; +} sli_uBand; + +/*===================================================*/ +/** + * Cfg enable + */ + +typedef union +{ + struct { + uint8 cfg_enable; //@ uint8, config enable flag + } cfgEnableFrameSnd; + uint8 ucfgEnableBuf; +} sli_uCfgEnable; + +/*===================================================*/ +/** + * + * UART Hardware flow control + * + * */ +typedef union { +struct { + uint8 uart_hw_flowcontrol_enable; +}HwFlowControlEnableFrameSnd; + uint8 uHwFlowControlEnableBuf; +}sli_uHwFlowControl; + + +/*===================================================*/ +/** + * Sleep timer + */ + +typedef union { + struct { + uint8 TimeVal[2]; //@ 2bytes, sleep timer value to set + } SleepTimerFrameSnd; + uint8 uSleepTimerBuf[2]; +} sli_uSleepTimer; + +/*===================================================*/ +/** + * RTC time from host + */ + +typedef struct module_rtc_time_s{ + uint8 tm_sec[4]; //@ seconds after the minute [0-60] + uint8 tm_min[4]; //@ minutes after the hour [0-59] + uint8 tm_hour[4]; //@ hours since midnight [0-23] + uint8 tm_mday[4]; //@ day of the month [1-31] + uint8 tm_mon[4]; //@ months since January [0-11] + uint8 tm_year[4]; //@ year since 0 +}module_rtc_time_t; + + +#define HTTP_BUFFER_LEN 1200 +#define HTTP_POST_BUFFER_LEN 900 +#define HTTP_PUT_BUFFER_LEN 900 + +/*===================================================*/ +/** + * HTTP GET / POST Request + */ +typedef union { + struct { + uint8 ip_version[2]; //@ ip version 4 or 6 + uint8 https_enable[2]; //@ enable http features + uint8 http_port[2]; //@ server port number + uint8 buffer[HTTP_BUFFER_LEN]; //@ Username, Password,Hostname, IP address,url,header,data + } HttpReqFrameSnd; + uint8 uHttpReqBuf[HTTP_BUFFER_LEN + 6]; +} sli_uHttpReq; + + + +/*===================================================*/ +/** + * HTTP POST DATA Request + */ +typedef union { + struct { + uint8 current_chunk_length[2]; //@ HTTP data chunk length + uint8 buffer[HTTP_POST_BUFFER_LEN]; //@ HTTP data + } HttpPostDataReqFrameSnd; + uint8 uHttpPostDataReqBuf[HTTP_POST_BUFFER_LEN + 2]; +} sli_uHttpPostDataReq; + + + + + +/*===================================================*/ +/** + * HTTP GET/POST Response + */ +typedef struct TCP_EVT_HTTP_Data_t{ + uint8 more[4]; + uint8 offset[4]; + uint8 data_len[4]; + uint8 data[1400]; +} sli_uHttpRsp; + +/*===================================================*/ +/** + * DNS query struct + */ + + + +#define MAX_DNS_REPLY 10 + +typedef struct TCP_EVT_DNS_Query_Resp +{ + uint8 ip_version[2]; + uint8 uIPCount[2]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_Address[16]; + }aIPaddr[MAX_DNS_REPLY]; +}TCP_EVT_DNS_Query_Resp; + +/*===================================================*/ +/** + * Power mode + */ +typedef union { + struct { + uint8 powerVal; //@ uint8, power value to set + uint8 ulp_mode_enable; //@ 0 - LP, 1 - ULP with RAM retention and 2 - ULP without RAM retention + uint8 listen_interval_dtim; //@ valid value is 0 and 1 + uint8 sli_psp_type; //@ 0 - max PSP, 1 - Fast PSP and 2 - UAPSD + uint16 monitor_interval; //@ Wake up time in ms when psp_type is 1 + } powerFrameSnd; + uint8 uPowerBuf[6]; +} sli_uPower; + +/*===================================================*/ +/** + * Per mode + */ +typedef union { + struct { + uint8 per_mode_enable[2]; //@ uint8, enable/disable per mode + uint8 power[2]; //@ uint8, per mode power + uint8 rate[4]; //@ uint8, per mode rate + uint8 length[2]; //@ uint8, per mode length + uint8 mode[2]; //@ uint8, per mode mode + uint8 channel[2]; //@ uint8, per mode channel + uint8 rate_flags[2]; //@ uint8, per mode rate_flags + uint8 reserved1[2]; //@ uint8, per mode reserved + uint8 aggr_enable[2]; //@ uint8, per mode aggr_enable + uint8 reserved2[2]; //@ uint8, per mode reserved + uint8 no_of_pkts[2]; //@ uint8, per mode no_of_pkts + uint8 delay[4]; //@ uint8, per mode delay + } perModeFrameSnd; + uint8 uPerModeBuf[28]; +}sli_uPerMode; + +/*===================================================*/ +/** + * Per stats + */ +typedef union { + struct { + uint8 per_stats_enable[2]; + uint8 per_stats_channel[2]; + } perStatsFrameSnd; + uint8 uPerStatsBuf[4]; +}sli_uPerStats; + +/*===================================================*/ +/** + * SEND + */ +typedef union { + struct { + uint8 ip_version[2]; //@ ip version 4 or 6 + uint8 socketDescriptor[2]; //@ socket descriptor of the already opened socket connection + uint8 sendBufLen[4]; //@ length of the data to be sent + uint8 sendDataOffsetSize[2]; //@ Data Offset, TCP=46, UDP=34 + uint8 padding[SLI_MAX_PAYLOAD_SIZE]; + //@ large enough for TCP or UDP frames + } sendFrameSnd; + struct { + uint8 ip_version[2]; //@ ip version 4 or 6 + uint8 socketDescriptor[2]; //@ socket descriptor of the already opened socket connection + uint8 sendBufLen[4]; //@ length of the data to be sent + uint8 sendDataOffsetSize[2]; //@ Data Offset, TCP=44, UDP=32 + uint8 destPort[2]; + union{ + uint8 ipv4_address[SLI_IP_ADD_LEN]; + uint8 ipv6_address[SLI_IP_ADD_LEN * 4]; + }destIPaddr; + uint8 sendDataOffsetBuf[SLI_TXDATA_OFFSET_LUDP]; + //@ Empty offset buffer, UDP=26 + uint8 sendDataBuf[SLI_MAX_PAYLOAD_SIZE]; + //@ Data payload buffer, 1400 bytes max + } sendFrameLudpSnd; + uint8 uSendBuf[SLI_MAX_PAYLOAD_SIZE]; + //@ byte format to send to spi, TCP is the larger of the two, 1456 bytes +} sli_uSend; + +/*=============================*/ + +typedef struct +{ + uint8 ip_version; + uint8 ttl[2]; +} mdns_init_t; + +typedef struct +{ + uint8 port[2]; + uint8 ttl[2]; + uint8 more; +} mdns_reg_srv_t; + +typedef struct sli_mdns_t +{ + uint8 command_type; + union + { + mdns_init_t mdns_init; + mdns_reg_srv_t mdns_reg_srv; + } mdns_struct; + + uint8 buffer[1000]; + +} sli_mdns_t; + +/*=============================*/ +/*===================================================*/ +/** + * Frame Descriptor + */ + +typedef union { + struct { + uint8 dataFrmLenAndQueue[2]; + //@ Data frame body length. Bits 14:12=queue, 010 for data, Bits 11:0 are the length + uint8 padding[14]; //@ Unused, set to 0x00 + } frameDscDataSnd; + struct { + uint8 mgmtFrmLenAndQueue[2]; + //@ Data frame body length. Bits 14:12=queue, 000 for data, Bits 11:0 are the length + uint8 mgmtRespType; + //@ Management frame descriptor response status, 0x00=success, else error + uint8 padding[9]; //@ Unused , set to 0x00 + uint8 mgmtFrmDscRspStatus; + uint8 padding1[3]; + } frameDscMgmtRsp; + uint8 uFrmDscBuf[SLI_FRAME_DESC_LEN]; //@ byte format for spi interface, 16 bytes +} sli_uFrameDsc; + +/*===================================================*/ +/** + * Roaming Parameters set structure + */ +typedef union { + struct { + uint8 roam_enable[4]; + uint8 roam_threshold[4]; + uint8 roam_hysteresis[4]; + }roamParamsFrameSnd; + uint8 uRoamParamsBuf[12]; +}sli_uRoamParams; + +/*===================================================*/ +/** + *Structure for rejoin_params + */ +typedef struct sli_rejoin_params_s{ + uint8 sli_max_try[4]; + uint8 sli_scan_interval[4]; + uint8 sli_beacon_missed_count[4]; + uint8 sli_first_time_retry_enable[4]; +} sli_rejoin_params_t; + + +/*===================================================*/ +/** + * HT CAPS Parameters set structure + */ +typedef union { + struct { + uint8 mode_11n_enable[2]; + uint8 ht_caps_bitmap[2]; + }htCapsFrameSnd; + uint8 uHtCapsBuf[4]; +}sli_uHtCaps; + + +/*===================================================*/ +/** + * WMM PS Parameters set structure + */ +typedef union { + struct { + uint8 wmm_ps_enable[2]; + uint8 wmm_ps_type[2]; + uint8 wmm_ps_wakeup_interval[4]; + uint8 wmm_ps_uapsd_bitmap; + }wmmPsFrameSnd; + uint8 uWmmPsBuf[9]; +}sli_uWmmPs; + +/*===================================================*/ +/** + * WPS Parameters set structure + */ +#define SLI_WPS_PIN_LEN 8 +typedef union { + struct { + uint8 wps_method[2]; + uint8 generate_pin[2]; + uint8 wps_pin[SLI_WPS_PIN_LEN]; + }wpsMethodFrameSnd; + uint8 uWpsMethodBuf[12]; +}sli_uWpsMethod; + +/*===================================================*/ +/** + * Command Response Frame Union + */ +typedef struct { + uint8 devState; //@ If New device 1; Device left 0 + uint8 devName[32]; //@ Name the device found or left 32 bytes + uint8 macAddress[6]; //@ Mac address of the device + uint8 devtype[2]; //@ Type of the device 1st byte inidcates primary device type; + //@ 2nd byte indicates sub catagory +}sli_wfdDevInfo; + +typedef struct { + sli_wfdDevInfo devInfo; +}sli_wfdDevRsp; + +typedef struct { + uint8 devCount; + sli_wfdDevInfo strWfdDevInfo[SLI_MAX_WFD_DEV_CNT]; + //@ 32 maximum responses from scan command +} sli_wfdDevResponse; + + +typedef struct { + uint8 rfChannel; //@ rf channel to us, 0=scan for all + uint8 securityMode; //@ security mode, 0=open, 1=wpa1, 2=wpa2, 3=wep + uint8 rssiVal; //@ absolute value of RSSI + uint8 uNetworkType; + uint8 ssid[SLI_SSID_LEN]; //@ 32-byte ssid of scanned access point + uint8 bssid[SLI_BSSID_LEN]; + uint8 reserved[2]; +} sli_scanInfo; + +typedef struct { + uint8 nwType; //@ network type, 0=Ad-Hoc (IBSS), 1=Infrastructure + uint8 securityType; //@ security type, 0=Open, 1=WPA1, 2=WPA2, 3=WEP + uint8 dataRate; //@ data rate, 0=auto, 1=1Mbps, 2=2Mbps, 3=5.5Mbps, 4=11Mbps, 12=54Mbps + uint8 powerLevel; //@ transmit power level, 0=low (6-9dBm), 1=medium (10-14dBm, 2=high (15-17dBm) + uint8 psk[SLI_PSK_LEN]; //@ pre-shared key, 32-byte string + uint8 ssid[SLI_SSID_LEN]; //@ ssid of access point to join to, 32-byte string + uint8 ibssMode; //@ Ad-Hoc Mode (IBSS), 0=Joiner, 1=Creator + uint8 ibssChannel; //@ rf channel number for Ad-Hoc (IBSS) mode + uint8 reserved; +} sli_joinInfo; + +typedef struct { + uint8 scanCount[4]; //@ 4 bytes, number of access points found + uint8 padding[4]; + sli_scanInfo strScanInfo[SLI_AP_SCANNED_MAX]; + //@ 32 maximum responses from scan command +} sli_scanResponse; + +typedef struct { + uint8 macAddress1[6]; + uint8 macAddress2[6]; +}sli_initResponse; + +typedef struct { + uint8 macAddress1[6]; + uint8 macAddress2[6]; +}sli_qryMacFrameRcv; + +typedef struct { + uint8 operState; +}sli_joinResponse; + +typedef struct { + uint8 rssiVal[2]; //@ uint8, RSSI value for the device the module is currently connected to +} sli_rssiFrameRcv; + +typedef struct { + uint8 snrVal; //@ uint8, RSSI value for the device the module is currently connected to +} sli_snrFrameRcv; + + +typedef struct { + uint8 ip_version[2]; //@ ip version 4 or 6 + uint8 socketType[2]; //@ 2 bytes, type of socket created + uint8 socketDescriptor[2]; //@ uinr16, socket descriptor, like a file handle, usually 0x00 + uint8 moduleSocket[2]; //@ 2 bytes, Port number of our local socket + union{ + uint8 ipv4_addr[4]; //@ 4 bytes, Our (module) IPv4 Address + uint8 ipv6_addr[16]; //@ 4 bytes, Our (module) IPv6 Address + }moduleIPaddr; + uint8 mss[2]; //@ 2 bytes, Remote peer MSS size + uint8 window_size[4]; //@ 4 bytes, Remote peer Window size +} sli_socketFrameRcv; + +typedef struct { + uint8 socketDsc[2]; //@ 2 bytes, socket that was closed + uint8 sentBytescnt[4]; //@ 4 bytes, sent bytes count +} sli_socketCloseFrameRcv; + +typedef struct { + uint8 macAddr[6]; //@ MAC address of this module + uint8 ipaddr[4]; //@ Configured IP address + uint8 netmask[4]; //@ Configured netmask + uint8 gateway[4]; //@ Configured default gateway +} sli_ipparamFrameRcv; + +typedef struct { + uint8 macAddr[6]; //@ MAC address of this module + uint8 ipaddr[4]; //@ Configured IP address + uint8 netmask[4]; //@ Configured netmask + uint8 gateway[4]; //@ Configured default gateway +} sli_recvIpChange; + + + +typedef struct { + uint8 prefixLength[2]; //@ prefix length + uint8 ipaddr6[16]; //@ Configured IPv address + uint8 defaultgw6[16]; //@ Router IPv6 address +} sli_ipconf6FrameRcv; + +typedef struct { + uint8 object_id[32]; //@ Object id + uint8 length[4]; //@ Length of set request + uint8 value[200]; //@ value to be set +} sli_snmp_set; + +typedef struct { + uint8 wps_pin[SLI_WPS_PIN_LEN]; +}sli_wpsMethodFrameRcv; + +/*Region Code response in set region command*/ +typedef struct +{ + //! region code selected + uint8 region_code; +}sli_uSetRegionRsp; + +typedef struct { + uint8 state[2]; //@ 2 bytes, connection state, 0=Not Connected, 1=Connected +} sli_conStatusFrameRcv; + +typedef struct { + + uint8 sock_handle[2]; + uint8 SentBytes[4]; + +} sli_sentBytesRsp; + +typedef struct { + uint8 socketDescriptor[2]; + uint8 ip_version[2]; + union + { + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }dest_ip; + uint8 dPort[2]; +} sli_LtcpConnStatusFrameRcv; + +typedef struct sock_info_query_t +{ + uint8 sock_id[2]; + uint8 sock_type[2]; + uint8 sPort[2]; + uint8 dPort[2]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }destIpaddr; + +}sock_info_query_t; + +typedef struct ftp_rsp_t +{ + uint8 command_type; + uint8 more; + uint16 length; + uint8 data[1024]; +}sli_ftp_rsp_t; + + +typedef struct sli_sntp_rsp_t +{ + uint8 command_type; + uint8 sntp_buffer[50]; +}sli_sntp_rsp_t; + + +//! SMTP response structure +typedef struct sli_smtp_rsp_t +{ + //! Receive SMTP command type + uint8 command_type; +}sli_smtp_rsp_t; + +typedef struct sli_http_client_put_rsp_t +{ + //!Receive HTTP_PUT command type + uint8 command_type; + + //! HTTP file/resource end of content + uint8 end_of_file; + +}sli_http_client_put_rsp_t; + +//! SNTP server response structure +typedef struct sli_sntp_server_rsp_t +{ + UINT8 ip_version; + union + { + UINT8 ipv4_address[4]; + UINT8 ipv6_address[16]; + }server_ip_address; + + UINT8 sntp_method; +}sli_sntp_server_rsp_t; + + +//! SNTP server info response structure +typedef struct sli_sntp_server_info_rsp_t +{ + UINT8 command_type; + UINT8 ip_version; + union + { + UINT8 ipv4_address[4]; + UINT8 ipv6_address[16]; + }server_ip_address; + + UINT8 sntp_method; +}sli_sntp_server_info_rsp_t; + +typedef struct mdns_rsp_t +{ + uint8 command_type; + +}sli_mdns_rsp_t; + +#define MN_NUM_SOCKETS 10 +typedef struct { + uint8 wlanState; //@ uint8, 0=NOT Connected, 1=Connected + uint8 Chn_no; //@ channel number of connected AP + uint8 psk[64]; //@ PSK + uint8 mac_addr[6]; //@ Mac address + uint8 ssid[SLI_SSID_LEN]; //@ uint8[32], SSID of connected access point + uint8 connType[2]; //@ 2 bytes, 0=AdHoc, 1=Infrastructure + uint8 sec_type; + uint8 dhcpMode; //@ uint8, 0=Manual IP Configuration,1=DHCP + uint8 ipaddr[4]; //@ uint8[4], Module IP Address + uint8 subnetMask[4]; //@ uint8[4], Module Subnet Mask + uint8 gateway[4]; //@ uint8[4], Gateway address for the Module + uint8 num_open_socks[2]; //@ number of sockets opened + uint8 prefix_length[2]; //@ prefix length for ipv6 address + uint8 ipv6addr[16]; //@ modules ipv6 address + uint8 defaultgw6[16]; //@ router ipv6 address + uint8 tcp_stack_used; //@ BIT(0) =1 - ipv4, BIT(1)=2 - ipv6, BIT(0) & BIT(1)=3 - BOTH + sock_info_query_t socket_info[MN_NUM_SOCKETS]; +} sli_qryNetParmsFrameRcv; + + +#define MAX_STA_SUPPORT 4 + +struct go_sta_info_s +{ + uint8 ip_version[2]; //@ IP version if the connected client + uint8 mac[6]; //@ Mac Address of the connected client + union + { + uint8 ipv4_address[4]; //@ IPv4 Address of the Connected client + uint8 ipv6_address[16]; //@ IPv6 Address of the Connected client + }ip_address; +#ifdef PACKED +}__attribute__((packed)); //@ to avoid padding in the structures +#else +}; +#endif + +typedef struct { + uint8 ssid[SLI_SSID_LEN]; //@ SSID of the P2p GO + uint8 bssid[6]; //@ BSSID of the P2p GO + uint8 channel_number[2]; //@ Operating channel of the GO + uint8 psk[64]; //@ PSK of the GO + uint8 ipv4_address[4]; //@ IPv4 Address of the GO + uint8 ipv6_address[16]; //@ IPv6 Address of the GO + uint8 sta_count[2]; //@ Number of stations Connected to GO + struct go_sta_info_s sta_info[MAX_STA_SUPPORT]; +}sli_qryGOParamsFrameRcv; + + + +typedef struct { + uint8 fwversion[20]; //@ uint8[20], firmware version text string, x.y.z as 1.3.0 +} sli_qryFwversionFrameRcv; + + +typedef struct { + uint8 ip_version[2]; //@ 2 bytes, the ip version of the ip address , 4 or 6 + uint8 recvSocket[2]; //@ 2 bytes, the socket number associated with this read event + uint8 recvBufLen[4]; //@ 4 bytes, length of data received + uint8 recvDataOffsetSize[2]; //@ 2 bytes, offset of data from start of buffer + uint8 fromPortNum[2]; //@ 2 bytes, port number of the device sending the data to us + union{ + uint8 ipv4_address[4]; //@ 4 bytes, IPv4 Address of the device sending the data to us + uint8 ipv6_address[16]; //@ 4 bytes, IPv6 Address of the device sending the data to us + }fromIPaddr; + uint8 recvDataOffsetBuf[SLI_RXDATA_OFFSET_UDP_V4]; + //@ uint8, empty offset buffer, 14 for UDP, 42 bytes from beginning of buffer + uint8 recvDataBuf[SLI_MAX_PAYLOAD_SIZE]; //@ uint8, buffer with received data +} sli_recvFrameUdp; + +typedef struct { + uint8 ip_version[2]; //@ 2 bytes, the ip version of the ip address , 4 or 6 + uint8 recvSocket[2]; //@ 2 bytes, the socket number associated with this read event + uint8 recvBufLen[4]; //@ 4 bytes, length of data received + uint8 recvDataOffsetSize[2]; //@ 2 bytes, offset of data from start of buffer + uint8 fromPortNum[2]; //@ 2 bytes, port number of the device sending the data to us + union{ + uint8 ipv4_address[4]; //@ 4 bytes, IPv4 Address of the device sending the data to us + uint8 ipv6_address[16]; //@ 4 bytes, IPv6 Address of the device sending the data to us + }fromIPaddr; + uint8 recvDataOffsetBuf[SLI_RXDATA_OFFSET_UDP_V6]; + //@ uint8, empty offset buffer, 14 for UDP, 42 bytes from beginning of buffer + uint8 recvDataBuf[SLI_MAX_PAYLOAD_SIZE]; //@ uint8, buffer with received data +} sli_recvFrameUdp6; + + +typedef struct { + uint8 ip_version[2]; //@ 2 bytes, the ip version of the ip address , 4 or 6 + uint8 recvSocket[2]; //@ 2 bytes, the socket number associated with this read event + uint8 recvBufLen[4]; //@ 4 bytes, length of payload data received + uint8 recvDataOffsetSize[2]; //@ 2 bytes, offset of data from start of buffer + uint8 fromPortNum[2]; //@ 2 bytes, port number of the device sending the data to us + union{ + uint8 ipv4_address[4]; //@ 4 bytes, IPv4 Address of the device sending the data to us + uint8 ipv6_address[16]; //@ 4 bytes, IPv6 Address of the device sending the data to us + }fromIPaddr; + uint8 recvDataOffsetBuf[SLI_RXDATA_OFFSET_TCP_V4]; //@ uint8, empty offset buffer, 26 for TCP + uint8 recvDataBuf[SLI_MAX_PAYLOAD_SIZE]; //@ uint8, buffer with received data +} sli_recvFrameTcp; + +typedef struct { + uint8 ip_version[2]; //@ 2 bytes, the ip version of the ip address , 4 or 6 + uint8 recvSocket[2]; //@ 2 bytes, the socket number associated with this read event + uint8 recvBufLen[4]; //@ 4 bytes, length of payload data received + uint8 recvDataOffsetSize[2]; //@ 2 bytes, offset of data from start of buffer + uint8 fromPortNum[2]; //@ 2 bytes, port number of the device sending the data to us + union{ + uint8 ipv4_address[4]; //@ 4 bytes, IPv4 Address of the device sending the data to us + uint8 ipv6_address[16]; //@ 4 bytes, IPv6 Address of the device sending the data to us + }fromIPaddr; + uint8 recvDataOffsetBuf[SLI_RXDATA_OFFSET_TCP_V6]; //@ uint8, empty offset buffer, 26 for TCP + uint8 recvDataBuf[SLI_MAX_PAYLOAD_SIZE]; //@ uint8, buffer with received data +} sli_recvFrameTcp6; + +typedef struct { + uint8 socket[2]; //@ uint8, socket handle for the terminated connection + uint8 sentBytescnt[4]; //@ 4 bytes, sent bytes count +} sli_recvRemTerm; + +typedef struct{ + union{ + uint8 ipv4_address[4]; //@ primary DNS IPv4 + uint8 ipv6_address[16]; //@ primary DNS IPv6 + }primary_dns_ip; + + union{ + uint8 ipv4_address[4]; //@ secondary DNS IPv4 + uint8 ipv6_address[16]; //@ secondary DNS IPv6 + }secondary_dns_ip; +}sli_dnsserverResponse; + +typedef struct { + uint8 ip_version[2]; + uint8 sock_id[2]; //@ 2 bytes, socket handle + uint8 fromPortNum[2]; //@ 2 bytes, remote port number + union{ + uint8 ipv4_address[4]; //@ remote IPv4 Address + uint8 ipv6_address[16]; //@ remote IPv6 Address + }dst_ip_address; + uint8 mss[2]; //@ 2 bytes, remote peer MSS size + uint8 window_size[4]; //@ 4 bytes, remote peer Window size + uint8 srcPortNum[2]; +} sli_recvLtcpEst; + +/* Certificate loading related macros */ +#define MAX_CERT_SEND_SIZE 1400 + +struct cert_info_s +{ + uint8 total_len[2]; + uint8 CertType; + uint8 more_chunks; + uint8 CertLen[2]; + uint8 Cert_inx; + uint8 KeyPwd[127]; +#ifdef PACKED +}__attribute__((packed)); //@packed is used to avoid padding +#else +}; +#endif + +#define MAX_DATA_SIZE (MAX_CERT_SEND_SIZE - sizeof(struct cert_info_s)) + +struct SET_CHUNK_S +{ + struct cert_info_s cert_info; + uint8 Certificate[MAX_DATA_SIZE]; +}; + + +/*==================================================*/ +/*This will keep the wepkey params*/ + +typedef struct { + uint8 index[2]; + uint8 key[4][32]; +}sli_wepkey; + +/*====================================================*/ +/*This will keep the AP configuration parameter*/ + +typedef struct { + uint8 channel_no[2]; + uint8 ssid[SLI_SSID_LEN]; + uint8 security_type; + uint8 encryp_mode; + uint8 psk[SLI_PSK_LEN]; + uint8 beacon_interval[2]; + uint8 dtim_period[2]; + uint8 ap_keepalive_type; + uint8 ap_keepalive_period; + uint8 max_sta_support[2]; // it can be configured from 1 to 4 +}sli_apconfig; + +/*===================================================*/ +/** + * HTTP Credentials command + * + */ + +#define MAX_USERNAME_LEN 31 //! Including NULL character +#define MAX_PASSWORD_LEN 31 //! Including NULL character +typedef union { + struct { + uint8 username[MAX_USERNAME_LEN]; + uint8 password[MAX_PASSWORD_LEN]; + }httpCredentialsFrameSnd; + uint8 uhttpCredentialsBuf[MAX_USERNAME_LEN + MAX_PASSWORD_LEN]; +}sli_uhttpCredentials; +/*SNMP command structure*/ +#define MAX_SNMP_VALUE 200 + +/* Maximum length of OID */ +#define MAX_OID_LENGTH 128 +typedef union { + struct { + uint8 type; + uint8 value[MAX_SNMP_VALUE]; + uint8 objid[MAX_OID_LENGTH]; + } snmpFrameSnd; + uint8 uSnmpBuf[MAX_SNMP_VALUE + 4 + MAX_OID_LENGTH]; +} sli_uSnmp; + + + +typedef struct SNMP_OBJECT_DATA_STRUCT +{ + + uint8 snmp_object_data_type[4]; /* Type of SNMP data contained */ + uint8 snmp_object_data_msw[4]; /* Most significant 32 bits */ + uint8 snmp_object_data_lsw[4]; /* Least significant 32 bits */ + uint8 snmp_ip_version[4]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }snmp_nxd_address; + uint8 snmp_object_octet_string_size[4]; /* Size of OCTET string */ + +} SNMP_OBJECT_DATA; + +typedef struct SNMP_TRAP_OBJECT_STRUCT +{ + + uint8 snmp_object_string_ptr[40]; /* SNMP object string*/ + SNMP_OBJECT_DATA snmp_object_data; /* SNMP object data */ +} SNMP_TRAP_OBJECT; + + +#define SLI_SNMP_TAP_BUFFER_LENGTH 1024 + +/*SNMP trap structure*/ +typedef union { + struct { + uint8 snmp_version; + uint8 ip_version[4]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }destIPaddr; + uint8 community[32]; + uint8 trap_type; + uint8 elapsed_time[4]; + uint8 trap_oid[51]; + uint8 obj_list_count; + uint8 snmp_buf[SLI_SNMP_TAP_BUFFER_LENGTH]; + } snmptrapFrameSnd; + + uint8 uSnmptrapBuf[110+SLI_SNMP_TAP_BUFFER_LENGTH]; +} sli_uSnmptrap; + +/* Structure for SNMP Enable */ +typedef union{ + struct{ + uint8 snmpEnable; + }snmpEnableFrameSnd; + uint8 uSnmpenableBuf; +}sli_uSnmpEnable; + + +//! PUF +typedef union{ + struct{ + uint8 key_index; + uint8 key_size; + uint8 key[32]; + }pufSetKeyFrameSnd; + uint8 uPufsetkeyBuf[36]; +} sli_uPufsetkey; + + +typedef union{ + struct{ + uint8 key_code[44]; + }pufGetKeyFrameSnd; + uint8 uPufgetkey[44]; +} sli_uPufgetkey; + + +typedef union{ + struct{ + uint8 key_code[44]; + }pufLoadKeyFrameSnd; + uint8 uPufloadkey[44]; +} sli_uPufloadkey; + +typedef union{ + struct{ + uint8 mode; + uint8 key[32]; + uint8 iv[32]; + uint8 data_size[2]; + uint8 data[1400]; + }aesEncryptFrameSnd; + uint8 uAesEncrypt[1468]; +} sli_uAesencrypt; + +typedef union{ + struct{ + uint8 mode; + uint8 key[32]; + uint8 iv[32]; + uint8 data_size[2]; + uint8 data[1400]; + }aesDecryptFrameSnd; + uint8 uAesDecrypt[1468]; +} sli_uAesdecrypt; + +typedef union{ + struct{ + UINT8 mode; + UINT8 key[32]; + UINT8 iv[32]; + UINT8 data_size[2]; + UINT8 data[1400]; + }aesMacFrameSnd; + uint8 uAesMac[1468]; +} sli_uAesMac; + +/* Ping Response Frame */ +typedef struct { + uint8 ip_version[2]; + uint8 ping_size[2]; + union{ + uint8 ipv4_addr[4]; //@ 4 bytes, Our (module) IPv4 Address + uint8 ipv6_addr[16]; //@ 4 bytes, Our (module) IPv6 Address + }ping_address; +} sli_uPingRsp; + +/*structure for ping request command*/ +typedef struct sli_ping_request_s{ + uint8 ip_version[2]; + uint8 ping_size[2]; + union{ + uint8 ipv4_address[4]; + uint8 ipv6_address[16]; + }ping_address; + + uint8 timeout[2]; +}sli_ping_request_t; + +/*PSK response structure*/ +typedef struct{ + uint8 pmk[32]; +}sli_PmkResponse; + +/*P2P connection request from wi-fi device*/ +typedef struct sli_p2p_conn_req_s{ + uint8 device_name[32]; +}sli_p2p_conn_req_t; + +/* Module state response */ +typedef struct sli_state_notificaton_s{ + uint8 TimeStamp[4]; + uint8 stateCode; + uint8 reason_code; + uint8 sli_channel; + uint8 sli_rssi; + uint8 sli_bssid[6]; +} sli_state_notificaton_t; + + +/*User store configuration parameters*/ +#define MAX_HTTP_SERVER_USERNAME 31 +#define MAX_HTTP_SERVER_PASSWORD 31 + +typedef struct sc_params_s +{ + uint8 cfg_enable; + uint8 opermode[4]; + uint8 feature_bit_map[4]; + uint8 tcp_ip_feature_bit_map[4]; + uint8 custom_feature_bit_map[4]; + uint8 band; + uint8 scan_feature_bitmap; + uint8 join_ssid[SLI_SSID_LEN]; + uint8 uRate; + uint8 uTxPower; + uint8 reserved_1; + uint8 reserved_2; + uint8 scan_ssid_len; + uint8 keys_restore; + uint8 csec_mode; + uint8 psk[SLI_PSK_LEN]; + uint8 scan_ssid[SLI_SSID_LEN]; + uint8 scan_cnum; + uint8 dhcp_enable; +#define IP_ADDRESS_SZ 4 + uint8 ip[IP_ADDRESS_SZ]; + uint8 sn_mask[IP_ADDRESS_SZ]; + uint8 dgw[IP_ADDRESS_SZ]; + + uint8 eap_method[32]; + uint8 inner_method[32]; + uint8 user_identity[64]; + uint8 passwd[128]; + + uint8 go_intent[2]; + uint8 device_name[64]; + uint8 operating_channel[2]; + uint8 ssid_postfix[64]; + uint8 psk_key[64]; +#define WISE_PMK_LEN 32 + uint8 pmk[WISE_PMK_LEN]; + sli_apconfig apconfig; + uint8 module_mac[6]; + uint8 antenna_select[2]; + uint8 fips_bypass_mode[2]; + sli_wepkey wep_key; + uint8 dhcp6_enable[2]; + uint8 prefix_length[2]; + uint8 ip6[16]; + uint8 dgw6[16]; + uint8 tcp_stack_used; + uint8 bgscan_magic_code[2]; + uint8 bgscan_enable[2]; + uint8 bgscan_threshold[2]; + uint8 rssi_tolerance_threshold[2]; + uint8 bgscan_periodicity[2]; + uint8 active_scan_duration[2]; + uint8 passive_scan_duration[2]; + uint8 multi_probe; + //!Channel bitmap info + uint8 chan_bitmap_magic_code[2]; + uint8 scan_chan_bitmap_stored_2_4_GHz[4]; + uint8 scan_chan_bitmap_stored_5_GHz[4]; + //!Roaming Params info + uint8 roam_magic_code[2]; + sli_uRoamParams roam_params_stored; + //!rejoin params info + uint8 rejoin_magic_code[2]; + sli_rejoin_params_t rejoin_param_stored; + uint8 region_request_from_host; + uint8 sli_region_code_from_host; + uint8 region_code; + uint8 reserved_4[43]; + uint8 multicast_magic_code[2]; + uint8 multicast_bitmap[2]; + uint8 powermode_magic_code[2]; + uint8 powermode; + uint8 ulp_mode; + uint8 wmm_ps_magic_code[2]; + uint8 wmm_ps_enable; + uint8 wmm_ps_type; + uint8 wmm_ps_wakeup_interval[4]; + uint8 wmm_ps_uapsd_bitmap; + uint8 listen_interval[4]; + uint8 listen_interval_dtim; + + uint8 ext_custom_feature_bit_map[4]; + uint8 private_key_password[82]; + uint8 join_bssid[6]; + uint8 join_feature_bitmap; + + //! HT caps + sli_uHtCaps ht_caps; + uint8 ht_caps_magic_word[2]; + + //! Fast psp parameters + uint8 fast_psp_enable; + uint8 monitor_interval[2]; + + //! Request timeout parameters + uint8 req_timeout_magic_word[2]; + uint8 timeout_value[2]; + uint8 timeout_bitmap[4]; + + //! AP IP parameters in Concurrent mode + UINT8 dhcp_ap_enable; + UINT8 ap_ip[4]; /* Module IP address */ + UINT8 ap_sn_mask[4]; /* Sub-net mask */ + UINT8 ap_dgw[4]; /* Default gateway */ + + uint8 dhcp6_ap_enable[2]; /* DHCPv6 enable or disable */ + UINT8 ap_prefix_length[2];/* Prefix length */ + UINT8 ap_ip6[16]; /* Module IPv6 address */ + UINT8 ap_dgw6[16]; /* Module IPv6 address */ + UINT8 ext_tcp_ip_feature_bit_map[4]; + + + /* HTTP/HTTPS Server credentials */ + uint8 http_credentials_avail; + uint8 http_username[MAX_HTTP_SERVER_USERNAME]; + uint8 http_password[MAX_HTTP_SERVER_PASSWORD]; + +}sli_user_store_config_t, sli_cfgGetFrameRcv; + + +typedef struct { + uint8 dev_name[32]; //@ All the characters are part of device name, no Null termination +} sli_ConnAcceptRcv; + + +/* PER stats response */ +typedef struct per_stats_s +{ + //! no. of tx pkts + uint8 tx_pkts[2]; + //! no. of rx pkts + uint8 reserved_1[2]; + //! no. of tx retries + uint8 tx_retries[2]; + //! no. of pkts that pass crc + uint8 crc_pass[2]; + //! no. of pkts failing crc chk + uint8 crc_fail[2]; + //! no. of times cca got stuck + uint8 cca_stk[2]; + //! no of times cca didn't get stuck + uint8 cca_not_stk[2]; + //! no. of pkt aborts + uint8 pkt_abort[2]; + //! no. of false rx starts + uint8 fls_rx_start[2]; + //! cca idle time + uint8 cca_idle[2]; + //! Reserved fields + uint8 reserved_2[26]; + //! no. of rx retries + uint8 rx_retries[2]; + //! rssi value + uint8 reserved_3[2]; + //! cal_rssi + uint8 cal_rssi[2]; + //! lna_gain bb_gain + uint8 reserved_4[4]; + //! xretries pkts dropped + //! number of tx packets dropped after maximum retries + uint8 xretries[2]; + //! consecutive pkts dropped + uint8 max_cons_pkts_dropped[2]; + uint8 reserved_5[2]; + //! BSSID matched broadcast packets count + uint8 bss_broadcast_pkts[2]; + //! BSSID matched multicast packets count + uint8 bss_multicast_pkts[2]; + //! BSSID & multicast filter matched packets count + uint8 bss_filter_matched_multicast_pkts[2]; + +}sli_uPerStatsRsp; + + +/* Card ready Response */ +typedef struct card_ready_s +{ + //! Boot loader checksum + uint8 bootloader_checksum[4]; + + //! Firmware checksum + uint8 firmware_checksum[4]; +}sli_card_readyRsp; + +/* Store Config checksum Response */ +typedef struct store_config_chksum_s +{ + uint8 checksum[20]; +}sli_store_config_checksumRsp; + +//! Generate DRBG random +typedef struct generate_drbg_rand_s +{ + uint8 random_number[32]; +}sli_generate_DRBGRandRsp; + + +//! Socket configuration request frame +typedef struct socket_config_s +{ + //! TCP TX + TCP RX + UDP TX + UDP RX + uint8 total_sockets; + + //! TCP TX + TCP RX + uint8 total_tcp_sockets; + + //! UDP TX + UDP RX + uint8 total_udp_sockets; + + //! TCP TX + uint8 tcp_tx_only_sockets; + + //! TCP RX + uint8 tcp_rx_only_sockets; + + //! UDP TX + uint8 udp_tx_only_sockets; + + //! UDP RX + uint8 udp_rx_only_sockets; + + //! TCP RX High Performance + uint8 tcp_rx_high_performance_sockets; + +} sli_socket_config_t; + +//! RF Current mode configuration +typedef struct rf_current_config_s +{ + //! RF RX current/Power mode + uint8 rf_rx_curr_mode; + //! RF TX current/Power mode + uint8 rf_tx_curr_mode; + //! RF TX strength in dbm + int16 rf_tx_dbm; +} sli_rf_current_config_t; + +/* PUF Setkey Response */ +typedef struct puf_setkey_s +{ + //! Key Code for set key + uint8 key_code[44]; +}sli_puf_setkeyRsp; + +/* PUF Getkey Response */ +typedef struct puf_getkey_s +{ + //! Key for get key + uint8 key[32]; +}sli_puf_getkeyRsp; + +/* AES Encrypt Response */ +typedef struct aes_encrypt_s +{ + //! Encrypted data + uint8 encryt_data[1400]; +}sli_aes_encryptRsp; + +/* AES Decrypt Response */ +typedef struct aes_decrypt_s +{ + //! decrypted data + uint8 decryt_data[1400]; +}sli_aes_decryptRsp; + +/* AES MAC Response */ +typedef struct aes_mac_s +{ + //! MAC data + uint8 mac[32]; +}sli_aes_macRsp; + +//! FTP client +#define FTP_USERNAME_LENGTH 31 +#define FTP_PASSWORD_LENGTH 31 +#define FTP_PATH_LENGTH 51 +#define FTP_MAX_CHUNK_LENGTH 1400 + +typedef struct ftp_connect +{ + //! FTP client IP cersion + uint8 ip_version; + + union + { + //! IPv4 address + UINT8 ipv4_address[4]; + + //! IPv6 address + UINT8 ipv6_address[16]; + } server_ip_address; + + //! FTP client username + uint8 username[FTP_USERNAME_LENGTH]; + + //! FTP client password + uint8 password[FTP_PASSWORD_LENGTH]; + + //! FTP server port + uint8 server_port[4]; +} ftp_connect_t; + +typedef struct ftp_command +{ + //! Directory or file path + uint8 path[FTP_PATH_LENGTH]; + + //! New file name + uint8 new_file_name[FTP_PATH_LENGTH]; +} ftp_command_t; + +typedef struct ftp_file_write +{ + //! command type + uint8 command_type; + + //! End of file + uint8 end_of_file; + + //! Path of file to write + uint8 file_content[FTP_MAX_CHUNK_LENGTH]; + +} sli_ftp_file_write_t; + +typedef struct +{ + //! FTP command type + uint8 command_type; + + union + { + //! structure for FTP connect + ftp_connect_t ftp_connect; + + //! Structure for other commands + ftp_command_t ftp_command; + + }ftp_client_struct; + +}sli_ftp_client_t; + +typedef struct +{ + UINT8 command_type; + UINT8 ip_version; + union + { + UINT8 ipv4_address[4]; + UINT8 ipv6_address[16]; + }server_ip_address; + + UINT8 sntp_method; + UINT8 sntp_timeout[2]; + +} sli_sntp_client_t; + + +/* + * SMTP client + */ + +#define SMTP_CLIENT_CREATE 1 +#define SMTP_CLIENT_INIT 2 +#define SMTP_CLIENT_MAIL_SEND 3 +#define SMTP_CLIENT_DEINIT 4 + + +/* Define for SMTP client initialization */ + +typedef struct +{ + //! SMTP server ip version + uint8 ip_version; + + union + { + //! Server ipv4 address + uint8 ipv4_address[4]; + + //! Server ipv6 address + uint8 ipv6_address[16]; + + } server_ip_address; + + //! SMTP server authentication type + uint8 auth_type; + + //! SMTP server port number + uint8 server_port[4]; + +} smtp_client_init_t; + + +/* Define for SMTP client mail send */ + +typedef struct +{ + //! SMTP mail priority level + uint8 smtp_feature; + + // SMTP client mail body length + uint8 smtp_client_mail_body_length[2]; + +} smtp_mail_send_t; + + +/* Define SMTP client structure */ + +#define SLI_SMTP_BUFFER_LENGTH 1024 + +typedef struct +{ + //! SMTP client command type + uint8 command_type; + + //! SMTP client command structure + union + { + smtp_client_init_t smtp_client_init; + smtp_mail_send_t smtp_mail_send; + + } smtp_struct; + + uint8 smtp_buffer[SLI_SMTP_BUFFER_LENGTH]; + +} sli_smtp_client_t; + + +/* + * HTTP PUT client + */ + +#define HTTP_CLIENT_PUT_CREATE 1 +#define HTTP_CLIENT_PUT_START 2 +#define HTTP_CLIENT_PUT_PACKET 3 +#define HTTP_CLIENT_PUT_DELETE 4 +#define SLI_HTTP_CLIENT_PUT_BUFFER_LENGTH 900 + +/* Define for HTTP PUT client initialization */ + +typedef struct sli_http_client_put_start_t +{ + //! HTTP server ip version + uint8 ip_version; + + //! HTTPS bit map + uint8 https_enable[2]; + + //! HTTP server port number + uint8 port_number[4]; + + //! HTTP Content Length + uint8 content_length[4]; + +} sli_http_client_put_start_t; + +/* Define for HTTP PUT client current length */ + + +typedef struct sli_http_client_put_data_req_t +{ + //! Current chunk length + uint8 current_length[2]; + +} sli_http_client_put_data_req_t; + +/* Define for HTTP PUT client structure */ + + +typedef struct sli_http_client_put_req_s +{ + //! Command type + uint8 command_type; + + union + { + sli_http_client_put_start_t http_client_put_start; + sli_http_client_put_data_req_t http_client_put_data_req; + + } http_client_put_struct; + + uint8 http_put_buffer[SLI_HTTP_CLIENT_PUT_BUFFER_LENGTH]; +} sli_http_client_put_req_t; + + + +/* + * POP3 client + */ + + +#define POP3_CLIENT_MAX_USERNAME_LENGTH 101 +#define POP3_CLIENT_MAX_PASSWORD_LENGTH 101 + +//! POP3 client commands +#define POP3_CLIENT_SESSION_CREATE 1 +#define POP3_CLIENT_GET_MAIL_STATS 2 +#define POP3_CLIENT_GET_MAIL_LIST 3 +#define POP3_CLIENT_RETR_MAIL 4 +#define POP3_CLIENT_MARK_MAIL 5 +#define POP3_CLIENT_UNMARK_MAIL 6 +#define POP3_CLIENT_GET_SERVER_STATUS 7 +#define POP3_CLIENT_SESSION_DELETE 8 + + +typedef struct pop3_client_session_create +{ + //! POP3 server ip version + uint8 ip_version; + + union + { + //! Server ipv4 address + uint8 ipv4_address[4]; + + //! Server ipv6 address + uint8 ipv6_address[16]; + + } server_ip_address; + + //! POP3 server port number + uint8 server_port_number[2]; + + //! POP3 client authentication type + uint8 auth_type; + + //! POP3 client username + uint8 username[POP3_CLIENT_MAX_USERNAME_LENGTH]; + + //! POP3 client password + uint8 password[POP3_CLIENT_MAX_PASSWORD_LENGTH]; + +} pop3_client_session_create_t; + +typedef struct { + + //! POP3 client command type + uint8 command_type; + + //! POP3 client command structure + + union + { + //! POP3 client session create structure + pop3_client_session_create_t pop3_client_session_create; + + //! POP3 client mail index + uint8 pop3_client_mail_index[2]; + + } pop3_struct; + +} sli_pop3_client_t; + + +typedef struct sli_pop3_rsp_s +{ + + uint8 command_type; + + //! Total number of mails + uint8 mail_count[2]; + + //! Total size of all the mails + uint8 size[4]; + +} sli_pop3_rsp_t; + + +typedef struct sli_pop3_mail_data_resp_s +{ + //! Type of the POP3 client command + uint8 command_type; + + //! More data pending flag + uint8 more; + + //! Length the mail chunk + uint8 length[2]; + + //! Data buffer + uint8 data[1000]; + +} sli_pop3_mail_data_resp_t; + + + +typedef struct { + uint8 rspCode[2]; + uint8 status[2]; + //@ 0- For Success ,Non-Zero Value is the Error Code return + union { + //@ response payload + sli_qryMacFrameRcv qryMacaddress; + sli_initResponse initResponse; + sli_scanResponse scanResponse; + sli_joinResponse joinResponse; + sli_PmkResponse PmkResponse; + sli_wfdDevResponse wfdDevResponse; + sli_rssiFrameRcv rssiFrameRcv; + sli_socketFrameRcv socketFrameRcv; + sli_socketCloseFrameRcv socketCloseFrameRcv; + sli_ipparamFrameRcv ipparamFrameRcv; + sli_recvIpChange recvIpchange; + sli_ipconf6FrameRcv ipconf6FrameRcv; + sli_conStatusFrameRcv conStatusFrameRcv; + sli_qryNetParmsFrameRcv qryNetParmsFrameRcv; + sli_qryGOParamsFrameRcv qryGoParamsFrameRcv; + sli_qryFwversionFrameRcv qryFwversionFrameRcv; + sli_dnsserverResponse dnsserverresponse; + sli_recvFrameUdp recvFrameUdp; + sli_recvFrameTcp recvFrameTcp; + sli_recvFrameUdp6 recvFrameUdp6; + sli_recvFrameTcp6 recvFrameTcp6; + sli_recvRemTerm recvRemTerm; + sli_recvLtcpEst recvLtcpEst; + TCP_EVT_DNS_Query_Resp dnsqryresponse; + sli_snrFrameRcv snrFrameRcv; + sli_cfgGetFrameRcv cfgGetFrameRcv; + sli_LtcpConnStatusFrameRcv LtcpConnStatRcv; + sli_urlReqFrameRcv urlReqRcv; + sli_p2p_conn_req_t dev_req; + sli_ConnAcceptRcv ConnectReqRcv; + sli_snmp_set snmp_set; + sli_wpsMethodFrameRcv wpsMethodFrameRcv; + sli_state_notificaton_t stateFrameRcv; + sli_uHttpRsp httpFrameRcv; + sli_uSetRegionRsp setRegFrameRcv; + sli_uPingRsp sli_pingFrameRcv; + sli_uPerStatsRsp sli_perFrameRcv; + sli_card_readyRsp sli_card_readyRcv; + sli_store_config_checksumRsp sli_cfg_chksumRcv; + sli_generate_DRBGRandRsp sli_generateDRBGrandRcv; + sli_sentBytesRsp SentBytes; + sli_ftp_rsp_t ftpFrameRcv; + sli_puf_setkeyRsp setkeyFrameRcv; + sli_puf_getkeyRsp getkeyFrameRcv; + sli_aes_encryptRsp aesEncryptedFrameRcv; + sli_aes_decryptRsp aesDecryptedFrameRcv; + sli_aes_macRsp aesMacFrameRcv; + sli_sntp_rsp_t sntpFrameRcv; + sli_sntp_server_rsp_t sntp_ServerFrameRcv; + sli_sntp_server_info_rsp_t sntpServerInfoRcv; + sli_mdns_rsp_t mdnsFrameRcv; + sli_smtp_rsp_t smtpFrameRcv; + sli_http_client_put_rsp_t httpClientPutFrameRcv; + sli_pop3_rsp_t pop3CmdFrameRcv; + sli_pop3_mail_data_resp_t pop3MailContentRcv; + uint8 uCmdRspBuf[SLI_MAX_PAYLOAD_SIZE]; + }uCmdRspPayLoad; +} sli_uCmdRsp; + + +/*===================================================*/ +/** + * Interrupt Handeling Structure + */ +typedef struct { + uint8 mgmtPacketPending; //@ TRUE for management packet pending in module + uint8 dataPacketPending; //@TRUE for data packet pending in module + uint8 powerIrqPending; //@ TRUE for power interrupt pending in the module + uint8 bufferFull; //@ TRUE=Cannot send data, FALSE=Ok to send data + uint8 bufferEmpty; //@TRUE, Tx buffer empty, seems broken on module + uint8 isrRegLiteFi; +} sli_intStatus; + + + + +/*==============================================*/ + +typedef struct { + uint8 *ptrRecvBuf; //@ Location of the payload data + uint8 recvBufLen[4]; //@ Length of the payload data + int recvType; //@ Whether this receive event was a remote disconnect or read data + uint8 socketNumber[2]; //@ The socket number the event is associated with +} recvArgs; + + + + +/*==================================================*/ +/** + * This structure maintain power save state. + * + */ +typedef struct { + uint8 current_mode; + uint8 ack_pwsave; + uint8 sleep_received; + uint8 ack_sent; +}sli_powerstate; + +//! Debug Print Levels +#define SLI_DEBUG_LVL 0x00ff +//! These bit values may be ored to all different combinations of debug printing +#define SLI_PL0 0xffff +#define SLI_PL1 0x0001 +#define SLI_PL2 0x0002 +#define SLI_PL3 0x0004 +#define SLI_PL4 0x0008 +#define SLI_PL5 0x0010 +#define SLI_PL6 0x0020 +#define SLI_PL7 0x0040 +#define SLI_PL8 0x0080 +#define SLI_PL9 0x0100 +#define SLI_PL10 0x0200 +#define SLI_PL11 0x0400 +#define SLI_PL12 0x0800 +#define SLI_PL13 0x1000 +#define SLI_PL14 0x2000 +#define SLI_PL15 0x4000 +#define SLI_PL16 0x8000 + + + + +enum SLI_INTERRUPT_TYPE { + SLI_TXBUFFER_FULL = 0x01, + SLI_TXBUFFER_EMPTY = 0x02, + SLI_MGMT_PENDING = 0x04, + SLI_DATA_PENDING = 0x08, + SLI_PWR_MODE = 0x10 +}; + +/** + * Enumerations + */ +enum SLI_PROTOCOL { + SLI_PROTOCOL_UDP_V4 = 0x00, + SLI_PROTOCOL_TCP_V4 = 0x01, + SLI_PROTOCOL_UDP_V6 = 0x02, + SLI_PROTOCOL_TCP_V6 = 0x03 +}; + +#define BUFFER_FULL_FAILURE -3 + +/* Status indications */ +#define BUFFER_FULL 0x01 +#define BUFFER_EMPTY 0x02 +#define RX_PKT_PENDING 0x08 +#define POWER_SAVE 0x08 + + + +#define SLI_STATUS_OFFSET 12 +#define SLI_TWOBYTE_STATUS_OFFSET 12 +#define SLI_RSP_TYPE_OFFSET 2 + +extern struct SET_CHUNK_S set_chunks; +extern sli_wfdDevResponse wfdDevData; +extern uint32 interrupt_rcvd; + +#ifdef SLI_HAL +#include "sli_hal.h" +#endif +#include "platform_specific.h" +#include "sli_api.h" +#ifdef LINUX_PLATFORM +#include "string.h" +#endif +#endif diff --git a/platforms/linux/Driver/common/include/sli_hal.h b/platforms/linux/Driver/common/include/sli_hal.h new file mode 100644 index 0000000..077f42f --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_hal.h @@ -0,0 +1,50 @@ +/***************************************************************************//** + * @file + * @brief This file contains the function definition prototypes for HAL + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_HAL_H +#define SLI_HAL_H + + +/** + * INCLUDES + */ +#include "sli_global.h" + +#ifdef SAM9_G20 +#define SPI_INTR_GPIO_PIN AT91_PIN_PB8 +#endif +#ifdef SAM9_G35 +#define SPI_INTR_GPIO_PIN AT91_PIN_PA7 +#endif +#ifdef SAM9_G45 +#define SPI_INTR_GPIO_PIN AT91_PIN_PD0 +#define SPI_WAKEUP_REQ_GPIO AT91_PIN_PB10 +#define SPI_WAKEUP_STAT_GPIO AT91_PIN_PB11 + +#endif +#ifdef X86 +#define SPI_INTR_GPIO_PIN 0 +#endif + + +/** + * Function Prototypes + */ + + +void sli_module_power(uint8 tf); +#endif diff --git a/platforms/linux/Driver/common/include/sli_lib_util.h b/platforms/linux/Driver/common/include/sli_lib_util.h new file mode 100644 index 0000000..1047217 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_lib_util.h @@ -0,0 +1,27 @@ +/***************************************************************************//** + * @file + * @brief Contains prototypes of utils used in sli_lib_util.c + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + + +#ifndef SLI_LIB_UTIL_H +#define SLI_LIB_UTIL_H + +#include "sli_global.h" + +void sli_uint32_to_4bytes(uint8 *dBuf, uint32 val); +void sli_uint16_to_2bytes(uint8 *dBuf, uint16 val); +uint16 sli_bytes2R_to_uint16(uint8 *dBuf); +#endif diff --git a/platforms/linux/Driver/common/include/sli_linux.h b/platforms/linux/Driver/common/include/sli_linux.h new file mode 100644 index 0000000..a17b830 --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_linux.h @@ -0,0 +1,207 @@ +/***************************************************************************//** + * @file + * @brief Operating system specific definitions can be found here + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_LINUX_H +#define SLI_LINUX_H_ +#include "sli_common.h" +#ifdef SLI_SDIO_INTERFACE +#include "sli_sdio.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct _SLI_ADAPTER *PSLI_ADAPTER; + +#define BIT(n) (1 << (n)) +#define TEXT(arg...) arg +#define SLI_DEBUG(zone, fmt, arg...) if(zone & sli_zone_enabled) printk(fmt, ##arg) +#define SLI_ZONE_INFO BIT(0) +#define SLI_ZONE_ERROR BIT(1) +#define SLI_ZONE_INIT BIT(2) +#define SLI_ZONE_OID BIT(3) +#define SLI_ZONE_MGMT_SEND BIT(4) +#define SLI_ZONE_MGMT_RCV BIT(5) +#define SLI_ZONE_DATA_SEND BIT(6) +#define SLI_ZONE_DATA_RCV BIT(7) +#define SLI_ZONE_FSM BIT(8) +#define SLI_ZONE_ISR BIT(9) +#define SLI_ZONE_MGMT_DUMP BIT(10) +#define SLI_ZONE_DATA_DUMP BIT(11) +#define SLI_ZONE_PARSER BIT(12) +#define SLI_ZONE_SPI_DBG BIT(13) +#ifdef RS9116 +#define SLI_ZONE_RS9116_DBG BIT(14) +#endif +#define SLI_ZONE_SDIO_DBG BIT(15) + + +#define sli_carrier_on(dev) netif_carrier_on(dev) +#define sli_carrier_off(dev) netif_carrier_off(dev) +#define sli_vmalloc(temp) vmalloc(temp) +#define sli_vfree(ptr) vfree(ptr) + +#define sli_queue_init(a) skb_queue_head_init(a) +#define sli_queue_purge(a) skb_queue_purge(a) +#define sli_queue_tail(a,b) skb_queue_tail(a,b) +#define sli_queue_head(a,b) skb_queue_head(a,b) +#define sli_queue_len(a) skb_queue_len(a) +#define sli_dequeue(a) skb_dequeue(a) +#define sli_skb_put(a,b) skb_put(a,b) +#define sli_kfree_skb(a) dev_kfree_skb(a) + +#define sli_spinlock_init(a) spin_lock_init(a) +#define sli_lock_bh(a) spin_lock_bh(a) +#define sli_unlock_bh(a) spin_unlock_bh(a) + +#define sli_memcpy(a,b,c) memcpy(a,b,c) +#define sli_memset(a,b,c) memset(a,b,c) +#define sli_memcmp(a,b,c) memcmp(a,b,c) +#define sli_strcpy(a,b) strcpy(a,b) +#define sli_strcpy(a,b) strcpy(a,b) +#define sli_strncpy(a,b,c) strncpy(a,b,c) +#define sli_equal_string(a,b) strcmp(a,b) +#define sli_simple_strtol(a,b,c) simple_strtol(a,b,c) + +#define sli_Signal_Pending() signal_pending(current) +#define sli_netif_rx(a) netif_rx_ni(a) +#define sli_netif_start_queue(a) netif_start_queue(a) +#define sli_netif_queue_stopped(a) netif_queue_stopped(a) +#define sli_netif_stop_queue(a) netif_stop_queue(a) +#define sli_eth_type_trans(a,b) eth_type_trans(a,b) + +#define sli_schedule() schedule() +#define sli_sprintf sprintf + +#define sli_down_interruptible(a) down_interruptible(a) +#define sli_up_sem(a) up(a) +#define sli_down_sem(a) down(a) +#ifdef init_MUTEX +#define sli_init_mutex(a) init_MUTEX(a) +#else +#define sli_sema_init(a,b) sema_init(a,b) +#endif + +#define sli_mem_free(ptr) kfree(ptr) +#define sli_mem_alloc(a,b) kmalloc(a,b) + +#define sli_copy_to_user(a,b,c) copy_to_user(a,b,c) +#define sli_copy_from_user(a,b,c) copy_from_user(a,b,c) + +#define sli_nla_data(a) nla_data(a) +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +#define sli_genlmsg_new(a,b) nlmsg_new(a) +#else +#define sli_genlmsg_new(a,b) genlmsg_new(a,b) +#endif +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +#define sli_genlmsg_put(a,b,c,d,e,f,g,h) genlmsg_put(a,b,c,d,e,f,g,h) +#else +#define sli_genlmsg_put(a,b,c,d,e,f) genlmsg_put(a,b,c,d,e,f) +#endif +#define sli_nla_put(a,b,c,d) nla_put(a,b,c,d) +#define sli_genlmsg_end(a,b) genlmsg_end(a,b) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#define sli_genlmsg_unicast(a,b,c) genlmsg_unicast(a,b,c) +#else +#define sli_genlmsg_unicast(a,b) genlmsg_unicast(a,b) +#endif +#define sli_genl_register_ops(a,b) genl_register_ops(a,b) +#define sli_genl_unregister_ops(a,b) genl_unregister_ops(a,b) +#define sli_genl_register_family(a) genl_register_family(a) +#define sli_genl_unregister_family(a) genl_unregister_family(a) + +#define EVENT_WAIT_FOREVER (0x00) + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 11) +# define get_portid(_info) (_info)->snd_pid +#else +# define get_portid(_info) (_info)->snd_portid +#endif + +#define BIN_FILE 0 +#define HEX_FILE 1 + +#define SLI_THREAD_NAME_LEN 15 +#define SLI_THREAD_PRIORITY 0 +#define SLI_INT_THREAD_PRIORITY 0 + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) +typedef struct work_struct SLI_WORK_QUEUE; +#define sli_Init_Work_Queue(a,b) INIT_WORK(a,b) +#define sli_Schedule_Work(a) schedule_work(a) +#else +typedef struct tq_struct SLI_WORK_QUEUE; +#define sli_Init_Work_Queue(a,b,c) INIT_TQUEUE(a,b,c) +#define sli_Schedule_Work(a) schedule_task(a) +#endif +#define SLI_THREAD_NAME_LEN 15 + +#define SLI_ASSERT(exp) \ + do { \ + if (!(exp)) { \ + SLI_DEBUG(SLI_ZONE_ERROR,"Assertion Failed! %s, %s(), %s:%d\n", \ + #exp, __FUNCTION__, __FILE__, __LINE__); \ + } \ + } while (0) + +typedef struct semaphore SLI_SEMAPHORE, *PRSI_SEMAPHORE; + + +/*Function prototypes*/ +/* net device */ +struct net_device* sli_allocdev(INT32 sizeof_priv, UINT8 vap_id); +INT32 sli_registerdev( struct net_device *dev ); +VOID sli_unregisterdev(struct net_device *dev); +struct net_device_stats *sli_get_stats( struct net_device *dev); +INT32 sli_open(struct net_device *dev); +INT32 sli_stop(struct net_device *dev); +struct net_device* sli_netdevice_op(UINT8 vap_id); + +INT32 sli_xmit(struct sk_buff *skb, struct net_device *dev); +INT32 sli_transmit_thread (PVOID pContext); +INT32 sli_indicate_packet(PSLI_ADAPTER Adapter, UINT8 *DataRcvPacket,UINT32 pktLen, UINT8 sta_id); + +struct sk_buff *sli_alloc_skb(UINT32 len); +VOID sli_kfree_skb(struct sk_buff *skb); +VOID sli_dump(INT32 zone, PVOID vdata, INT32 len); +INT32 sli_Kill_Thread( PSLI_ADAPTER Adapter); +INT32 sli_Init_Thread ( PSLI_ADAPTER Adapter); +INT32 sli_Init_Event(SLI_EVENT *pEvent); +INT32 sli_Delete_Event (SLI_EVENT *pEvent); +INT32 sli_Wait_Event(SLI_EVENT *pEvent,UINT32 timeOut); +VOID sli_Set_Event(SLI_EVENT *pEvent); +INT32 sli_Reset_Event(SLI_EVENT *pEvent); +PSLI_ADAPTER sli_getpriv(struct net_device *glbl_net_device); + + + +/* netlink */ +#ifdef SLI_UART_INTERFACE +INT32 sli_send_rsp_to_userspace(PSLI_ADAPTER Adapter, UINT8 *rspBuff, UINT8 to_uart); +#else +INT32 sli_send_rsp_to_userspace(PSLI_ADAPTER Adapter, UINT8 *rspBuff); +#endif +INT32 sli_register_genl(void); +INT32 sli_unregister_genl(void); +#endif //SLI_LINUX_H_ diff --git a/platforms/linux/Driver/common/include/sli_nic.h b/platforms/linux/Driver/common/include/sli_nic.h new file mode 100644 index 0000000..1be74bc --- /dev/null +++ b/platforms/linux/Driver/common/include/sli_nic.h @@ -0,0 +1,294 @@ +/***************************************************************************//** + * @file + * @brief LINUX SPI driver + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_NIC_H +#define SLI_NIC_H + +#include "linux/netdevice.h" +#include +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +#include +#else +#include "linux/semaphore.h" +#endif +#include "sli_common.h" +#include "sli_global.h" + +/* sli ioctl */ +#define SLI_WSC_PRIV_IOCTLS SIOCDEVPRIVATE +#define OID_WSC_GET_STATUS SLI_WSC_PRIV_IOCTLS + 0x1 +#define OID_WSC_BOOT_READ SLI_WSC_PRIV_IOCTLS + 0x2 +#define OID_WSC_BOOT_WRITE SLI_WSC_PRIV_IOCTLS + 0x3 +#define OID_WSC_BOOT_PING_WRITE SLI_WSC_PRIV_IOCTLS + 0x4 +#define OID_WSC_BOOT_PONG_WRITE SLI_WSC_PRIV_IOCTLS + 0x5 +#define OID_WSC_POWER_SAVE_ENABLE SLI_WSC_PRIV_IOCTLS + 0x6 +#define OID_WSC_WAKEUP SLI_WSC_PRIV_IOCTLS + 0x7 +#define OID_MASTER_READ SLI_WSC_PRIV_IOCTLS + 0x8 + +#define USB_MAX_PACKET_SIZE 2048 + +#define BIT(n) (1 << (n)) +#define MAX_SPI_PKT_SIZE 1600 + +#define SLI_LITTLE_ENDIAN 1 //! Comment this for Big Endian + +#define SLI_DESC_LEN 16 +#define CPC_HEADER_LENGTH 7 +#define SLI_LENGTH_OF_ADDRESS 6 +#define MAX_BUFF_SIZE 4900 +#define SLI_HEADER_SIZE 14 + +#define MGMT_QUEUE 0 +#define DATA_QUEUE 1 + +#define SND_DATA_Q 0x5 + +#define WLAN_PORT_ID 0x1111 +#define ZB_PORT_ID 0x2222 +#define BT_PORT_ID 0x3333 +#ifdef SLI_UART_INTERFACE +#define UART_PORT_ID 0x1122 +#endif + + + +#define FSM_OPEN 1 +#define FSM_RESET 2 + +/* Status indications */ +#define BUFFER_FULL 0x01 +#define BUFFER_EMPTY 0x02 +#define RX_PKT_PENDING 0x04 +#define POWER_SAVE 0x08 + +/* Kernel version between and including a & b */ +#define KERNEL_VERSION_BTWN_2_6_(a,b) \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,a)) && \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,b))) + +#define KERNEL_VERSION_EQUALS_2_6_(a) \ + (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,a)) + +/* Kernel version greater than equals */ +#define KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(a) \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,a)) + +/* Kernel version Less than equals */ +#define KERNEL_VERSION_LESS_THAN_EQUALS_2_6_(a) \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,a)) + + +#define KERNEL_VERSION_BTWN_2_6_(a,b) \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,a)) && \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,b))) + +#define KERNEL_VERSION_EQUALS_2_6_(a) \ + (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,a)) + +/* Kernel version greater than equals */ +#define KERNEL_VERSION_GREATER_THAN_2_6_(a) \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,a)) + +#define DEVINIT __devinit +#define DEVEXIT __devexit +#define INIT __init +#define EXIT __e +/* Update types from user to kernel */ +enum { + MODULE_POWER_CYCLE = 0x01, + UPDATE_JOIN_DONE = 0x02, + PS_CONTINUE = 0x03, + WKP_FROM_HOST = 0x04, + UPDATE_CONCURRENT_AP_JOIN_DONE = 0x05, + SOFT_RESET = 0X06, + TCP_IP_BYPASS_MACRO = 0X10, + GPIO_POWERSAVE = 0x08, + ULP_ENABLED = 0X09, + WMM_SUPPORT = 0x11, +}; + +typedef struct _SLI_EVENT { + atomic_t eventCondition; + wait_queue_head_t eventQueue; +}SLI_EVENT, *PSLI_EVENT; + +#ifdef SLI_USB_INTERFACE +#define USB_VENDOR_REGISTER_READ 0x15 +#define USB_VENDOR_REGISTER_WRITE 0x16 +#ifdef RS9116 +#define USB_TX_HEAD_ROOM_WLAN 256 +#else +#define USB_TX_HEAD_ROOM_WLAN 236 +#endif +#define USB_TX_HEAD_ROOM_ZB 0 +#ifdef RS9116 +#define USB_TX_HEAD_ROOM_BT 128 +#else +#define USB_TX_HEAD_ROOM_BT 0 +#endif +#define USB_RPINE_VENDER_ID 0x1618 +#define USB_RPINE_VENDER_ID_2 0x41B +#ifdef RS9116 +#define USB_RPINE_PRODUCT_ID 0x9116 +#else +#define USB_RPINE_PRODUCT_ID 0x9113 +#endif +#define USB_WLAN 0x0 +#define USB_BT_ZB 0x1 +#ifdef RS9116 +#define USB_ZB_ONLY 0x2 +#endif +#endif + +typedef struct _SLI_ADAPTER +{ +#ifdef SLI_SPI_INTERFACE + struct spi_device *spi; +#endif +#ifdef SLI_USB_INTERFACE + struct usb_device *usbdev; + struct usb_interface *interface; +#ifdef RS9116 +#define MAX_BULK_END_POINTS 3 +#else +#define MAX_BULK_END_POINTS 2 +#endif + UINT8 *rx_buf[MAX_BULK_END_POINTS]; + UINT32 rx_len[MAX_BULK_END_POINTS]; + UINT32 tx_len[MAX_BULK_END_POINTS]; + UINT32 max_rx_len[MAX_BULK_END_POINTS]; + UINT8 rx_endpoint_address[MAX_BULK_END_POINTS]; + UINT8 tx_endpoint_address[MAX_BULK_END_POINTS]; + #ifdef RS9116 +#define MAX_RX_URBS 3 +#else +#define MAX_RX_URBS 2 +#endif + struct urb *rx_usb_urb[MAX_RX_URBS]; + #ifdef RS9116 +#define MAX_TX_URBS 3 +#else +#define MAX_TX_URBS 2 +#endif + struct urb *tx_usb_urb[MAX_TX_URBS]; + +#endif + struct workqueue_struct *workqueue; + struct net_device *net_device0; + struct net_device *net_device1; + UINT8 rx_buffer[MAX_BUFF_SIZE]; + volatile UINT8 sli_status; + UINT32 FSM_STATE; + UINT32 FSM_STATE_AP1; + struct _SLI_EVENT Event; +#ifdef SLI_UART_INTERFACE + struct _SLI_EVENT DATA_ACKEvent; + uint8 data_ack_missed; +#endif + struct _SLI_EVENT PwrSaveEvent; + INT32 txPkt_count; + volatile UINT8 BufferFull; + UINT8 bufferfull_indicated; + sli_powerstate sli_pwstate; + struct net_device_stats stats; + struct sk_buff_head list[4]; + struct work_struct handler; + spinlock_t lockqueue; + spinlock_t locks[4]; +#ifdef SLI_UART_INTERFACE + spinlock_t uart_data_ack_flag_sem; +#endif + UINT8 PermanentAddress[SLI_LENGTH_OF_ADDRESS]; + UINT32 PktLen; /*Transmit pkt length*/ + UINT8 DataRcvPacket[MAX_BUFF_SIZE]; + UINT8 DataSndPacket[MAX_BUFF_SIZE]; + struct semaphore int_check_sem; + struct semaphore sleep_ack_sem; + struct semaphore tx_data_sem; + UINT32 RcvPktLen; + UINT32 InterruptStatus; + UINT32 handler_intr_cnt; + UINT32 int_ctr; + UINT32 isr_intr_cnt; + UINT32 once_full; + UINT32 once_empty; + UINT32 pdca_int_cnt; + UINT8 qos_enable; + UINT8 about_to_send; + UINT8 halt_flag; + volatile INT32 total_pkts_qd; + UINT16 save_flsh_status; + UINT32 wlan_seq_num; + UINT32 zb_seq_num; + UINT32 bt_seq_num; +#ifdef SLI_UART_INTERFACE + UINT32 uart_seq_num; +#endif + INT32 txThreadId; + int transmit_thread_exit; + struct completion txThreadComplete; + uint8 irq_registered; + uint8 power_save_enable; + +#ifdef ENABLE_WMM_FEATURE + /* WMM specific variables */ + int32 per_q_wt[NUM_EDCA_QUEUES]; + int32 wme_org_q[NUM_EDCA_QUEUES]; + int32 pkt_contended[NUM_EDCA_QUEUES]; + //global varibles from onebox_wmm.c + uint8 selected_qnum; + uint8 pkt_cnt; + uint8 tid; + uint8 priority; + struct chanAccParams wme_wmeChanParams; + uint8 dbg_test_values_loaded; +#endif +#ifdef RSI_AUTOMATION_ENABLE + uint8 tcp_ip_bypass; +#endif +#if SLI_SDIO_INTERFACE + #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))&& \ + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23))) + PSDDEVICE pDevice; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + struct sdio_func *pfunction; + uint32 TransmitBlockSize; + uint32 ReceiveBlockSize; +#endif + uint8 next_read_delay; + uint8 sdio_high_speed_enable; + uint8 stop_card_writing; + uint8 io_enable; + uint8 io_ready; + uint8 int_enable; + uint8 bus_interface_control; +#endif +} SLI_ADAPTER, *PSLI_ADAPTER; + +typedef struct _SLI_NET_DEV +{ + PSLI_ADAPTER sli_adapter_ptr; +} SLI_NET_DEV, *PSLI_NET_DEV; + + +#define SLI_MAX_PKTS_QUEUED 6400 + + + + + +#endif //SLI_NIC_H diff --git a/platforms/linux/Driver/common/src/insert.sh b/platforms/linux/Driver/common/src/insert.sh new file mode 100644 index 0000000..6f72930 --- /dev/null +++ b/platforms/linux/Driver/common/src/insert.sh @@ -0,0 +1,2 @@ +insmod rpsspi.ko + diff --git a/platforms/linux/Driver/common/src/remove.sh b/platforms/linux/Driver/common/src/remove.sh new file mode 100644 index 0000000..dde341c --- /dev/null +++ b/platforms/linux/Driver/common/src/remove.sh @@ -0,0 +1 @@ +rmmod rpsspi diff --git a/platforms/linux/Driver/common/src/sli_lib_util.c b/platforms/linux/Driver/common/src/sli_lib_util.c new file mode 100644 index 0000000..37bc5d0 --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_lib_util.c @@ -0,0 +1,121 @@ +/***************************************************************************//** + * @file + * @brief Generic function utils such as bytes2Touint16 + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ +#include "sli_global.h" + +/** + * Global defines + */ + +/*=============================================================================*/ +/** + * @fn void sli_uint16_to_2bytes(uint8 *dBuf, uint16 val) + * @brief Convert uint16 to two byte array + * @param[in] uint8 *dBuf,pointer to buffer to put the data in + * @param[in] uint16 data to convert + * @param[out] none + * @return none + */ +void sli_uint16_to_2bytes(uint8 *dBuf, uint16 val) +{ +#ifdef SLI_LITTLE_ENDIAN + dBuf[0] = val & 0x00ff; + dBuf[1] = (val >> 8) & 0x00ff; +#else + dBuf[1] = val & 0x00ff; + dBuf[0] = (val >> 8) & 0x00ff; +#endif +} + +/*=============================================================================*/ +/** + * @fn void sli_uint32_to_4bytes(uint8 *dBuf, uint32 val) + * @brief Convert uint32 to four byte array + * @param[in] uint8 *dBuf,pointer to the buffer to put the data in + * @param[in] uint32 data to convert + * @param[out] none + * @return none + */ +void sli_uint32_to_4bytes(uint8 *dBuf, uint32 val) +{ +#ifdef SLI_LITTLE_ENDIAN + dBuf[0] = val & 0x000000ff; + dBuf[1] = (val >> 8) & 0x000000ff; + dBuf[2] = (val >> 16) & 0x000000ff; + dBuf[3] = (val >> 24) & 0x000000ff; +#else + dBuf[3] = val & 0x000000ff; + dBuf[2] = (val >> 8) & 0x000000ff; + dBuf[1] = (val >> 16) & 0x000000ff; + dBuf[0] = (val >> 24) & 0x000000ff; +#endif +} + +/*=============================================================================*/ +/** + * @fn uint16 sli_bytes2R_to_uint16(uint8 *dBuf) + * @brief Convert a 2 byte array to uint16, first byte in array is LSB + * @param[in] uint8 *dBuf,pointer to a buffer to get the data from + * @param[out] none + * @return uint16, converted data + */ +uint16 sli_bytes2R_to_uint16(uint8 *dBuf) +{ + uint16 val; +#ifdef SLI_LITTLE_ENDIAN + val = dBuf[1]; + val <<= 8; + val |= dBuf[0] & 0x000000ff; +#else + val = dBuf[0]; + val <<= 8; + val |= dBuf[1] & 0x000000ff; +#endif + return val; +} + +/*=============================================================================*/ +/** + * @fn uint32 sli_bytes4R_to_uint32(uint8 *dBuf) + * @brief Convert a 4 byte array to uint32, first byte in array is LSB + * @param[in] uint8 *dBuf,pointer to buffer to get the data from + * @param[out] none + * @return uint32, converted data + */ +uint32 sli_bytes4R_to_uint32(uint8 *dBuf) +{ + uint32 val; //! the 32-bit value to return + +#ifdef SLI_LITTLE_ENDIAN + val = dBuf[3]; + val <<= 8; + val |= dBuf[2] & 0x000000ff; + val <<= 8; + val |= dBuf[1] & 0x000000ff; + val <<= 8; + val |= dBuf[0] & 0x000000ff; +#else + val = dBuf[0]; + val <<= 8; + val |= dBuf[1] & 0x000000ff; + val <<= 8; + val |= dBuf[2] & 0x000000ff; + val <<= 8; + val |= dBuf[3] & 0x000000ff; +#endif + + return val; +} diff --git a/platforms/linux/Driver/common/src/sli_linux_data.c b/platforms/linux/Driver/common/src/sli_linux_data.c new file mode 100644 index 0000000..0130eb0 --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_linux_data.c @@ -0,0 +1,551 @@ +/***************************************************************************//** + * @file + * @brief File contains functions related to data tranfer over net device. + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ +#include "sli_linux.h" +#include "sli_nic.h" +#include "sli_api.h" +#include + +/*==============================================*/ +/** + * @fn INT32 sli_xmit (struct sk_buff *skb, + * struct net_device *dev) + * @brief To transmit data + * @param[in] struct sk_buff *skb, + * Pointer to the socket buffer structure + * @param[in] struct net_device *dev, + * Pointer to our network device structure + * @param[out] none + * @return errCode + * -ve = FAIL + * 0 = SUCCESS + * @section description + * When a packet is sent by the upper layers, the transmit entry + * point registered at the time of initialization will be called. + * This function will que the skb and set the event. + */ +#ifdef ENABLE_WMM_FEATURE +void onebox_set_contention_vals(struct chanAccParams wme_wmeChanParams, PSLI_ADAPTER adapter); +uint8 core_determine_hal_queue(PSLI_ADAPTER adapter); +#endif + +INT32 sli_xmit (struct sk_buff *skb, struct net_device *dev) +{ + PSLI_ADAPTER Adapter = sli_getpriv (dev); +#ifdef ENABLE_WMM_FEATURE + UINT16 pkt_priority = BE_Q_STA; + UINT8 tos; +#endif + UINT32 qId; + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG,"\nsli_xmit:\n"); +#endif + SLI_DEBUG (SLI_ZONE_DATA_SEND, "+sli_xmit\n"); + + /*Checking if data pkt is rcvd in open state or not */ + if (Adapter->FSM_STATE != FSM_OPEN) + { + goto fail; + } + + /* Checking the size of the packet */ + if (skb->len > 1528) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_xmit: Big packet "); + goto fail; + } + +#ifdef ENABLE_WMM_FEATURE + + if(!Adapter->dbg_test_values_loaded) + { + Adapter->dbg_test_values_loaded = 1; + onebox_set_contention_vals(Adapter->wme_wmeChanParams,Adapter); + } + + if (Adapter->total_pkts_qd > SLI_MAX_PKTS_QUEUED){ + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_xmit: failed due to total pkt qd crossed SLI_MAX_PKTS_QUEUED\n"); + + } + +#ifdef SLI_WMM_PS_SUPPORT + /* Incase of device encap pick the tos from the IP hdr */ + tos = skb->data[15] >> 5; + Adapter->tid = tos; + Adapter->priority = TID_TO_WME_AC(tos); +#else + Adapter->priority = 1; +#endif + switch (Adapter->priority) + { + case WME_AC_VO: + pkt_priority = VO_Q_STA; + break; + case WME_AC_VI: + pkt_priority = VI_Q_STA; + break; + case WME_AC_BE: + pkt_priority = BE_Q_STA; + break; + case WME_AC_BK: + pkt_priority = BK_Q_STA; + break; + default: + /* Should not come here */ + pkt_priority = BE_Q_STA; + } + qId = pkt_priority; + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_xmit: qId of packet %d and tid %d\n", qId,Adapter->tid); + + sli_lock_bh(&Adapter->lockqueue); + Adapter->total_pkts_qd++; + sli_unlock_bh(&Adapter->lockqueue); + + /*Acquiring the lock on the skb queues */ + sli_queue_tail (&Adapter->list[qId], skb); + + + sli_Set_Event(&Adapter->Event); + + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_xmit: Signalled\n"); + return NETDEV_TX_OK; +#else + qId = DATA_QUEUE; + + if (Adapter->total_pkts_qd > SLI_MAX_PKTS_QUEUED) + { + { + + sli_Set_Event(&Adapter->Event); + } + + goto fail; + } + + sli_lock_bh(&Adapter->lockqueue); + Adapter->total_pkts_qd++; + sli_unlock_bh(&Adapter->lockqueue); + + /*Acquiring the lock on the skb queues */ + sli_queue_tail (&Adapter->list[qId - 1], skb); + { + + sli_Set_Event(&Adapter->Event); + } + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_xmit: Signalled\n"); + return NETDEV_TX_OK; +#endif +fail: + SLI_DEBUG (SLI_ZONE_DATA_SEND, "-Dropped\n"); + Adapter->stats.tx_dropped++; + sli_kfree_skb (skb); + return 0; +} + + +/*==============================================*/ +/** + * @fn VOID sli_transmit_thread (PVOID pContext) + * @brief Tranmit thread to write data onto card + * @param[in] PVOID pContext + * @param[out] none + * @return none + * @section description + * This thread dequeues the skb from the list and adds the + * descriptor. Finally, it writes onto the card. + */ +INT32 sli_transmit_thread (PVOID pContext) +{ + PSLI_ADAPTER Adapter = (PSLI_ADAPTER) pContext; + UINT32 Len = 0, i; + UINT32 q_num, que_end; + UINT32 que_start = 0; + INT32 status; + UINT8 cmd_qnum = SND_DATA_Q; + UINT8 desc[SLI_DESC_LEN]; + UINT8 int_status = 0; + UINT32 num_pkts = 0; + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG,"\nsli_transmit_thread:\n"); +#endif + SLI_DEBUG (SLI_ZONE_DATA_SEND, + "sli_transmit_thread: XMIT thread started\n"); + + set_user_nice(current,-5); + + #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 11) + daemonize("XMIT-Thread"); + #endif + +#ifdef ENABLE_WMM_FEATURE + do + { + UINT8 InterruptStatus = 0; + UINT8 tid = 0; + struct sk_buff *rcvskb; + struct sk_buff *rcvskb_free; + + + if (Adapter->BufferFull) + { + status = sli_Wait_Event (&Adapter->Event, 10); + } + else + { + status = sli_Wait_Event (&Adapter->Event, EVENT_WAIT_FOREVER); + } + + sli_Reset_Event (&Adapter->Event); + while(1) + { + q_num = core_determine_hal_queue(Adapter); + if (Adapter->FSM_STATE != FSM_OPEN) + { + SLI_DEBUG(SLI_ZONE_DATA_SEND,(TEXT("transmit_thread: FSM is not in OPEN State\n"))); + break; + } + + if (q_num == INVALID_QUEUE) + { + SLI_DEBUG(SLI_ZONE_DATA_SEND,TEXT("\nqos_pro: No More Pkt Due to invalid queueno\n")); + break; + } + sli_lock_bh(&Adapter->lockqueue); + Adapter->total_pkts_qd--; + sli_unlock_bh(&Adapter->lockqueue); + + rcvskb = sli_dequeue (&Adapter->list[q_num]); + + SLI_DEBUG (SLI_ZONE_DATA_SEND, "Deque frm %d\n", q_num); + if (rcvskb == NULL) + { + SLI_DEBUG (SLI_ZONE_ERROR, + "sli_transmit_thread: ERROR!!!! skb NULL %d\n", + q_num); + SLI_DEBUG(SLI_ZONE_DATA_SEND,(TEXT("No packet queued and trying to deque packet\n"))); + break; + } + + tid = WME_AC_TO_TID(q_num); + sli_memset (desc, 0, 16); +#ifdef SLI_LITTLE_ENDIAN + *(UINT16 *)&desc[0] = (((rcvskb->len) | (SND_DATA_Q << 12)) & 0x7fff); +#else + desc[0] = (UINT8)((UINT16)((rcvskb->len ) & 0x00ff)); + desc[1] = (UINT8)((UINT16)((((rcvskb->len )| (SND_DATA_Q << 4)) >> 8) & 0x00ff)); +#endif + /*Keep Tid at 14th byte upper nibble*/ + desc[14] |= (((tid & 0xf) << 4) | (q_num & 0xf)); + Len = rcvskb->len; + + SLI_DEBUG (SLI_ZONE_DATA_SEND, "Queue %d and Tid of the queue %d\n", q_num,tid); + //need to send the data from application + Adapter->txPkt_count++; + do + { + //need to send the data from application + sli_down_interruptible(&Adapter->int_check_sem); + status = sli_execute_cmd(desc, rcvskb->data, Len); + + sli_up_sem(&Adapter->int_check_sem); + if (status == -2) + { + SLI_DEBUG (SLI_ZONE_ERROR, "\nstatus : %d\n",status); + SLI_DEBUG (SLI_ZONE_ERROR, + "trying data %d bytes, Pkt_Count:%d\n", + Len, Adapter->txPkt_count); + + } + if (status == 0) + { + break; + } + }while(1); + + if(status == -1) + break; + if (status != SLI_STATUS_SUCCESS) + { +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG (SLI_ZONE_ERROR, + "desc Pkt Count: %d\n", + Adapter->txPkt_count); +#endif + sli_kfree_skb (rcvskb); + Adapter->stats.tx_dropped++; + break; + } + + + SLI_DEBUG (SLI_ZONE_DATA_SEND, + "sli_transmit_thread: Pkt of %d bytes written on card\n", + Len); + sli_kfree_skb (rcvskb); + Adapter->stats.tx_packets++; + Adapter->stats.tx_bytes += Len; + + if(Adapter->transmit_thread_exit) + { + sli_lock_bh(&Adapter->lockqueue); + while(Adapter->total_pkts_qd > 0) + { + rcvskb_free= sli_dequeue (&Adapter->list[q_num]); + Adapter->total_pkts_qd--; + sli_kfree_skb (rcvskb_free); + } + sli_unlock_bh(&Adapter->lockqueue); + break; + } + } + } while (Adapter->transmit_thread_exit == 0); +#else + + do + { + UINT8 InterruptStatus = 0; + struct sk_buff *rcvskb; + struct sk_buff *rcvskb_free; + if (Adapter->BufferFull) + { + status = sli_Wait_Event (&Adapter->Event, 10); + } + else + { + status = sli_Wait_Event (&Adapter->Event, EVENT_WAIT_FOREVER); + } + + sli_Reset_Event (&Adapter->Event); + + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_transmit_thread:event released\n"); + que_end = 1; + if (Adapter->transmit_thread_exit ) + { + SLI_DEBUG (SLI_ZONE_DATA_SEND, + "sli_transmit_thread: Halt flag set\n"); + break; + } + que_loop: + for (q_num = que_start; q_num < que_end; ++q_num) + { + UINT32 pkts_given = 0; + SLI_DEBUG (SLI_ZONE_DATA_SEND, "sli_transmit_thread: Q_NUM:%d\n", + q_num); + + if (Adapter->FSM_STATE != FSM_OPEN) + { + SLI_DEBUG(SLI_ZONE_DATA_SEND,(TEXT("ganges_transmit_thread: FSM is not in OPEN State\n"))); + break; + } + + do + { + + ++pkts_given; + + sli_lock_bh(&Adapter->lockqueue); + + if (Adapter->total_pkts_qd > 0) + { + Adapter->total_pkts_qd--; + } + else + { + sli_unlock_bh(&Adapter->lockqueue); + break; + } + sli_unlock_bh(&Adapter->lockqueue); + rcvskb = sli_dequeue (&Adapter->list[q_num]); + + SLI_DEBUG (SLI_ZONE_DATA_SEND, "Deque frm%d\n", q_num); + if (rcvskb == NULL) + { + SLI_DEBUG (SLI_ZONE_ERROR, + "sli_transmit_thread: ERROR!!!! skb NULL %d\n", + q_num); + break; + } + + sli_memset (desc, 0, 16); + sli_uint16_to_2bytes(desc, (((rcvskb->len) & 0xFFF) | (SND_DATA_Q << 12))); + Len = rcvskb->len; + + //need to send the data from application + Adapter->txPkt_count++; + do + { + //need to send the data from application + sli_down_interruptible(&Adapter->int_check_sem); + status = sli_execute_cmd(desc, rcvskb->data, Len); + sli_up_sem(&Adapter->int_check_sem); + + if (status == -2) + { + SLI_DEBUG (SLI_ZONE_ERROR, "\nstatus : %d\n",status); + SLI_DEBUG (SLI_ZONE_ERROR, + "trying data %d bytes, Pkt_Count:%d\n", + Len, Adapter->txPkt_count); + + } + if (status == 0) + { + break; + } + } while (1); + if(status == -1) + break; + if (status != SLI_STATUS_SUCCESS) + { +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG (SLI_ZONE_ERROR, + "desc Pkt Count: %d\n", + Adapter->txPkt_count); +#endif + sli_kfree_skb (rcvskb); + Adapter->stats.tx_dropped++; + break; + } + + + SLI_DEBUG (SLI_ZONE_DATA_SEND, + "sli_transmit_thread: Pkt of %d bytes written on card\n", + Len); + sli_kfree_skb (rcvskb); + Adapter->stats.tx_packets++; + Adapter->stats.tx_bytes += Len; + if(Adapter->transmit_thread_exit) + { + sli_lock_bh(&Adapter->lockqueue); + while(Adapter->total_pkts_qd > 0) + { + rcvskb_free= sli_dequeue (&Adapter->list[q_num]); + Adapter->total_pkts_qd--; + sli_kfree_skb (rcvskb_free); + } + sli_unlock_bh(&Adapter->lockqueue); + break; + } + } while (Adapter->total_pkts_qd > 0); + } + } while (Adapter->transmit_thread_exit == 0); + +#endif + + complete_and_exit(&Adapter->txThreadComplete, 0); + +} + +/*==============================================*/ +/** + * @fn INT32 sli_indicate_packet(PSLI_ADAPTER Adapter, + * UINT8 * DataRcvPacket, + * UINT32 pktLen) + * @brief Indicated the packet to upper layer + * @param[in] PSLI_ADAPTER Adapter, + * Pointer to the private data of the device + * @param[in] UINT8 *DataRcvPacket, Pointer to a packet + * @param[in] UINT32 pktLen, Length of the packet + * @param[out] none + * @return On success 0, else a negative number + * @section description + * This function copies the packet into a skb structure and + * indicates to the upper layer + */ +INT32 sli_indicate_packet(PSLI_ADAPTER Adapter, UINT8 * DataRcvPacket, UINT32 pktLen, UINT8 sta_id) +{ + struct sk_buff *rxskb; + INT32 i = 0; + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG,"\nsli_indicate_packet:\n"); +#endif +#if SLI_CONCURRENT_MODE + if ((sta_id == 0) && (Adapter->FSM_STATE != FSM_OPEN)) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_indicate_packet: Station is not in open state\n"); + goto fail; + } + else if ((sta_id != 0) && (Adapter->FSM_STATE_AP1 != FSM_OPEN)) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_indicate_packet: AP1 is not in open state\n"); + goto fail; + } + +#else + if (Adapter->FSM_STATE != FSM_OPEN) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_indicate_packet: Not in open state\n"); + goto fail; + } +#endif + + if (pktLen > 1536) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_indicate_packet: Big packet revd\n"); + goto fail; + } + + if (pktLen < SLI_HEADER_SIZE) + { + SLI_DEBUG (SLI_ZONE_ERROR, "sli_indicate_packet: Runt packet recvd\n"); + goto fail; + } + /*Allocate skb and copy the data into it */ + rxskb = sli_alloc_skb (pktLen); + if (!rxskb) + { + SLI_DEBUG (SLI_ZONE_ERROR, + "sli_indicate_packet: Low on memory, packet dropped\n"); + goto fail; + } + + sli_memcpy (sli_skb_put (rxskb, pktLen), DataRcvPacket, pktLen); + /*Filling the various other fields of skb */ +#if SLI_CONCURRENT_MODE + if(sta_id == 0) + { + rxskb->dev = Adapter->net_device0; + rxskb->protocol = sli_eth_type_trans (rxskb, Adapter->net_device0); + } + else + { + //! These station belongs to VAP 1 (which is for AP1) + rxskb->dev = Adapter->net_device1; + rxskb->protocol = rsi_eth_type_trans (rxskb, Adapter->net_device1); + } +#else + rxskb->dev = Adapter->net_device0; + rxskb->protocol = sli_eth_type_trans (rxskb, Adapter->net_device0); +#endif + + rxskb->ip_summed = CHECKSUM_NONE; + + sli_netif_rx (rxskb); + + SLI_DEBUG (SLI_ZONE_DATA_RCV, + "sli_indicate_packet: Pkt of %d bytes indicated\n", pktLen); + + Adapter->stats.rx_packets++; + Adapter->stats.rx_bytes += pktLen; + return 0; +fail: + Adapter->stats.rx_dropped++; + return -1; +} + +/* $EOF */ +/* Log */ diff --git a/platforms/linux/Driver/common/src/sli_linux_netlink.c b/platforms/linux/Driver/common/src/sli_linux_netlink.c new file mode 100644 index 0000000..6688a12 --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_linux_netlink.c @@ -0,0 +1,418 @@ +/***************************************************************************/ /** + * @file + * @brief This contains all the functions with netlink socket usage + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include "sli_global.h" +#include "sli_linux.h" +#include + +#if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(33) +#include +#endif +#include "sli_config.h" +extern SLI_STATUS sli_submit_rx_urb(PSLI_ADAPTER Adapter, UINT8 endpoint); + +INT32 sli_read_req_from_userspace(struct sk_buff *skb_2,struct genl_info *info); +/* attributes (variables): the index in this enum is used as a reference for the + * type, userspace application has to indicate the corresponding type the policy + * is used for security considerations + */ +enum { + SLI_USER_A_UNSPEC, + SLI_USER_A_MSG, + __SLI_USER_A_MAX, +}; +#define SLI_USER_A_MAX (__SLI_USER_A_MAX - 1) + +/* attribute policy: defines which attribute has which type (e.g int, char * + * etc) possible values defined in net/netlink.h + */ +static struct nla_policy sli_user_genl_policy[SLI_USER_A_MAX + 1] = { +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) + [SLI_USER_A_MSG] = { .type = NLA_STRING }, +#else + [SLI_USER_A_MSG] = { .type = NLA_NUL_STRING }, +#endif +}; +extern struct net_device *glbl_net_device; + +#define SLI_VERSION_NR 1 +/* family definition */ +static struct genl_family sli_user_gnl_family = { + .hdrsize = 0, + .name = "CTRL_PKT_TXRX", //! the name of this family, used by userspace + .version = SLI_VERSION_NR, //! version number + .maxattr = SLI_USER_A_MAX, +}; + +/* commands: enumeration of all commands (functions), + * used by userspace application to identify command to be executed + */ +enum { + SLI_USER_C_UNSPEC, + SLI_USER_C_CMD, + __SLI_USER_C_MAX, +}; + + +#define SLI_USER_C_MAX (__SLI_USER_C_MAX - 1) + +/*==============================================*/ +/** + * @fn INT16 sli_update_device(PSLI_ADAPTER Adapter, + * UINT8 *data) + * @brief updates the device + * @param[in] PSLI_ADAPTER Adapter, Pointer to Adapter + * @param[in] UINT8 *data + * @param[out] none + * @return Reurns 0 + * @section description + * This function used to parse the data to be updated. + * This is used when user sends some info to update. + * Used to update MAC address and FSM state + */ +INT16 sli_update_device(PSLI_ADAPTER Adapter, UINT8 *data) +{ + UINT8 type = *(data + SLI_DESC_LEN); + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_update_device:\n"); +#endif + switch (type) { + case UPDATE_JOIN_DONE: + sli_memcpy(Adapter->net_device0->dev_addr, + data + SLI_DESC_LEN + 1 /* type */, 6); + Adapter->FSM_STATE = FSM_OPEN; + break; + + case UPDATE_CONCURRENT_AP_JOIN_DONE: + sli_memcpy(Adapter->net_device1->dev_addr, + data + SLI_DESC_LEN + 1 /* type */, 6); + Adapter->FSM_STATE_AP1 = FSM_OPEN; + break; + + case SOFT_RESET: + Adapter->FSM_STATE = FSM_RESET; + break; +#ifdef RSI_AUTOMATION_ENABLE + case TCP_IP_BYPASS_MACRO: + Adapter->tcp_ip_bypass = *(data + SLI_DESC_LEN + 1); + break; +#endif + + default: + break; + } + + return 0; +} + +/*==============================================*/ +/** + * @fn INT32 sli_read_req_from_userspace( + * struct genl_info *info) + * @brief Gets the command request from user space + * over netlink socket + * @param[in] struct sk_buff *skb_2, pointer to sk_buff structure + * @param[in] struct genl_info *info, read command info pointer + * @param[out] none + * @return errCode + * 0 = SUCCESS + * else FAIL + * @section description + * This API is used to read the command from user over netlink + * socket. + */ +INT32 sli_read_req_from_userspace(struct sk_buff *skb_2,struct genl_info *info) +{ + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + struct nlattr *na; + INT32 rc; + void *msg_head; + UINT8 *mydata; + INT16 retval = 0; + UINT16 i = 0; + uint16 send_len; + SLI_STATUS Status = SLI_STATUS_SUCCESS; + +#ifdef SLI_DEBUG_PRINT +#endif + + if (info == NULL) { + goto out; + } + + /*for each attribute there is an index in info->attrs which points to a nlattr + * structure in this structure the data is given + */ + na = info->attrs[SLI_USER_A_MSG]; + if (na) { + mydata = (char *)sli_nla_data(na); + if (mydata == NULL) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "error while receiving data\n"); + } + } else { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "no info->attrs %i\n", SLI_USER_A_MSG); + } + + /* mydata points to the descriptor + payload of the command. + * We need to send this to WSC module by writing it over SPI interface. + */ + send_len = mydata[2] | (mydata[3] << 8); + send_len = send_len & 0xfff; + + if (*(mydata + 1) == 0xEE) { + Status = sli_init_interface(Adapter); + + if (Status == SLI_STATUS_FAIL) { + SLI_DEBUG(SLI_ZONE_ERROR, "sli_probe: Failed to enable interface\n"); + return -1; + } else { + Adapter->irq_registered = 1; + } + + sli_down_interruptible(&Adapter->int_check_sem); + do { + retval = sli_execute_cmd(mydata, mydata + 7, send_len); + } while (retval == -3); + sli_up_sem(&Adapter->int_check_sem); + + } else if (1) { + sli_down_interruptible(&Adapter->int_check_sem); + send_len = send_len & 0xfff; + do { + retval = sli_execute_cmd(mydata, mydata + 7, send_len); + } while (retval == -3); + sli_up_sem(&Adapter->int_check_sem); + } else { + retval = sli_update_device(Adapter, mydata); + } + + if (get_portid(info) == WLAN_PORT_ID) { + Adapter->wlan_seq_num = info->snd_seq; + } else if (get_portid(info) == ZB_PORT_ID) { + Adapter->zb_seq_num = info->snd_seq; + } else if (get_portid(info) == BT_PORT_ID) { + Adapter->bt_seq_num = info->snd_seq; + } + return retval; + + out: + SLI_DEBUG(SLI_ZONE_SPI_DBG, + "an error occured in sli_read_pkt_from_userspace:\n"); + return -2; +} + +/*==============================================*/ +/** + * @fn INT32 sli_send_rsp_to_userspace( + * PSLI_ADAPTER Adapter, + * rspBuff) + * @brief Sends the response to user space over netlink + * socket + * @param[in] PSLI_ADAPTER Adapter, pointer to adapter + * @param[in] rspBuff, pointer to response buffer + * @param[out] none + * @return errCode + * -1 = FAIL + * 0 = SUCCESS + * @section description + * This API is used to read the command from user over netlink + * socket. + */ +INT32 sli_send_rsp_to_userspace(PSLI_ADAPTER Adapter, UINT8 *rspBuff) +{ + struct nlattr *na = NULL; + struct sk_buff *skb = NULL; + INT32 rc; + void *msg_head = NULL; + UINT16 rspBufLen, total_len; + INT16 retval; + UINT8 i = 0; + UINT8 queue_no; + UINT32 seq_num, snd_pid = 0; + /* send the response to user space */ + /* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE*/ + rspBufLen = rspBuff[2] | (rspBuff[3] << 8); + rspBufLen &= 0x0FFF; + + total_len = CPC_HEADER_LENGTH + rspBufLen; + skb = sli_genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (skb == NULL) { + retval = 1; + goto out; + } + + if (!Adapter) { + goto out; + } + +#if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(33) + struct net *net = &init_net; +#else +#if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(32) + struct net *net = &init_net; +#endif +#endif + +#if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(32) + if (!net) { + goto out; + } +#endif + /* create the message headers */ + /* arguments of genlmsg_put: + struct sk_buff *, + INT32 (sending) pid, + INT32 sequence number, + struct genl_family *, + INT32 flags, + u8 command index (why do we need this?) + */ + seq_num = Adapter->wlan_seq_num; + snd_pid = WLAN_PORT_ID; +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) + msg_head = sli_genlmsg_put(skb, 0, seq_num + 1, sli_user_gnl_family.id, 0, 0, + SLI_USER_C_CMD, sli_user_gnl_family.version); +#else + msg_head = sli_genlmsg_put(skb, 0, seq_num + 1, &sli_user_gnl_family, 0, + SLI_USER_C_CMD); +#endif + if (msg_head == NULL) { + retval = 2; + rc = -ENOMEM; + goto out; + } + /* add a SLI_USER_A_MSG attribute (actual value to be sent) */ + rc = sli_nla_put(skb, SLI_USER_A_MSG, total_len, rspBuff); + if (rc != 0) { + retval = 3; + goto out; + } + /* finalize the message */ + sli_genlmsg_end(skb, msg_head); +#if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(32) + /* send the message back */ + rc = sli_genlmsg_unicast(net, skb, snd_pid); +#else + /* send the message back */ + rc = sli_genlmsg_unicast(skb, snd_pid); +#endif + if (rc != 0) { + retval = 4; + goto out; + } + return 0; + out: +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, + "an error occured in sli_send_rsp_to_userspace : %d, rc : %d\n", + retval, rc); +#endif + return -1; +} + +/* commands: mapping between the command enumeration and the actual function*/ +struct genl_ops sli_user_gnl_ops = { + .cmd = SLI_USER_C_CMD, + .flags = 0, + .policy = sli_user_genl_policy, + .doit = sli_read_req_from_userspace, + .dumpit = NULL, +}; + +/*==============================================*/ +/** + * @fn INT32 sli_register_genl(void) + * @brief Registers genl family and operations + * @param[in] none + * @param[out] none + * @return errCode + * 0 = SUCCESS + * else FAIL + * @section description + * This API is used to register genl ops and family. + */ +INT32 sli_register_genl(void) +{ + INT32 rc; + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_register_genl:\n"); +#endif + /*register new family*/ +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 12, 34) + sli_user_gnl_family.ops = &sli_user_gnl_ops; + sli_user_gnl_family.n_ops = 1; +#endif + rc = sli_genl_register_family(&sli_user_gnl_family); + if (rc != 0) { + return rc; + } + + /*register functions (commands) of the new family*/ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34) + rc = sli_genl_register_ops(&sli_user_gnl_family, &sli_user_gnl_ops); + if (rc != 0) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "register ops: %i\n", rc); + sli_genl_unregister_family(&sli_user_gnl_family); + return rc; + } +#endif + return rc; +} + +/*==============================================*/ +/** + * @fn INT32 sli_unregister_genl(void) + * @brief Unregisters genl family and operations + * @param[in] none + * @param[out] none + * @return errCode + * 0 = SUCCESS + * else FAIL + * @section description + * This API is used to unregister genl related ops. + */ +INT32 sli_unregister_genl(void) +{ + INT32 ret; + +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_unregister_genl:\n"); +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 12, 34) + /*unregister the functions*/ + ret = sli_genl_unregister_ops(&sli_user_gnl_family, &sli_user_gnl_ops); + if (ret != 0) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "unregister ops: %i\n", ret); + return ret; + } +#endif + + /*unregister the family*/ + ret = sli_genl_unregister_family(&sli_user_gnl_family); + if (ret != 0) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "unregister family %i\n", ret); + return ret; + } + + return ret; +} + +/* $EOF */ +/* Log */ diff --git a/platforms/linux/Driver/common/src/sli_linux_specific.c b/platforms/linux/Driver/common/src/sli_linux_specific.c new file mode 100644 index 0000000..83d6555 --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_linux_specific.c @@ -0,0 +1,242 @@ +/***************************************************************************/ /** + * @file + * @brief This contains all the linux specific code + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include +#include +#include + +#include "sli_linux.h" +#include "sli_nic.h" +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) +#include +#endif + +/* Globals */ +UINT32 sli_zone_enabled = SLI_ZONE_ERROR | SLI_ZONE_INIT | SLI_ZONE_SPI_DBG +#ifdef RS9116 + | SLI_ZONE_RS9116_DBG +#endif + | SLI_ZONE_SDIO_DBG; +/*==============================================*/ +/** + * @fn struct sk_buff* sli_alloc_skb(UINT32 Len) + * @brief allocates skb + * @param[in] UINT32 Len, length to be allocated + * @param[out] none + * @return struct sk_buff*, pointer to allocated socket buffer + * @section description + * This is used to allocate skb. + */ +struct sk_buff *sli_alloc_skb(UINT32 Len) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_alloc_skb:\n"); +#endif + return dev_alloc_skb(Len + 2); /*FIXME - CHECK DIS*/ +} + +/*==============================================*/ +/** + * @fn VOID sli_dump(INT32 zone, PVOID vdata, INT32 len) + * @brief Dumps the data through debugger + * @param[in] INT32 zone, Pointer to Adapter + * @param[in] PVOID vdata, Data to dump + * @param[in] INT32 len, length of the data to dump + * @param[out] none + * @return none + * @section description + * This function dumps the given data through the debugger + */ +VOID sli_dump(INT32 zone, PVOID vdata, INT32 len) +{ + INT32 ii; +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_dump\n"); +#endif + UINT8 *data = vdata; + for (ii = 0; ii < len; ii++) { + if (!(ii % 16)) { + SLI_DEBUG(zone, "\n"); + } + SLI_DEBUG(zone, "%02x ", data[ii]); + } + SLI_DEBUG(zone, "\n"); +} + +/*==============================================*/ +/** + * @fn INT32 sli_Init_Event(SLI_EVENT *pEvent) + * @brief Initializes event + * @param[in] SLI_EVENT *pEvent, Pointer to event + * @return 0 + * @section description + * This function initializes event. + */ +INT32 sli_Init_Event(SLI_EVENT *pEvent) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Init_Event:\n"); +#endif + SLI_DEBUG(SLI_ZONE_INFO, (TEXT("Initialising the event %p addr\n"), pEvent)); + + atomic_set(&pEvent->eventCondition, 1); + init_waitqueue_head(&pEvent->eventQueue); + return 0; +} + +/*==============================================*/ +/** + * @fn INT32 sli_Delete_Event(SLI_EVENT *pEvent) + * @brief Deletes event + * @param[in] SLI_EVENT *pEvent, Pointer to event + * @return 0 + * @section description + * This function Deletes event. + */ +INT32 sli_Delete_Event(SLI_EVENT *pEvent) +{ + /**Dummy for Linux*/ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Delete_Event:\n"); +#endif + return 0; +} + +/*==============================================*/ +/** + * @fn INT32 sli_Wait_Event(SLI_EVENT *pEvent, UINT32 timeOut) + * @brief Wait event + * @param[in] SLI_EVENT *pEvent, Pointer to event + * @param[in] UINT32 timeOut, Wait timeout + * @return 0 + * @section description + * This function handles the wait event functionality. + */ +INT32 sli_Wait_Event(SLI_EVENT *pEvent, UINT32 timeOut) +{ + INT32 Status = 0; +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Wait_Event:\n"); +#endif + if (!timeOut) { + wait_event_interruptible(pEvent->eventQueue, + (atomic_read(&pEvent->eventCondition) == 0)); + } else { + Status = wait_event_interruptible_timeout( + pEvent->eventQueue, (atomic_read(&pEvent->eventCondition) == 0), + timeOut); + } /* End if */ + + return Status; +} + +/*==============================================*/ +/** + * @fn INT32 sli_Set_Event(SLI_EVENT *pEvent) + * @brief Set event + * @param[in] SLI_EVENT *pEvent, Pointer to event + * @return none + * @section description + * This function handles the set event functionality. + */ +VOID sli_Set_Event(SLI_EVENT *pEvent) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Set_Event:\n"); +#endif + atomic_set(&pEvent->eventCondition, 0); + wake_up_interruptible(&pEvent->eventQueue); +} + +/*==============================================*/ +/** + * @fn INT32 sli_Reset_Event(SLI_EVENT *pEvent) + * @brief Reset event + * @param[in] SLI_EVENT *pEvent, Pointer to event + * @return VOID + * @section description + * This function handles the reset event functionality. + */ +INT32 sli_Reset_Event(SLI_EVENT *pEvent) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Reset_Event:\n"); +#endif + atomic_set(&pEvent->eventCondition, 1); +} + +/*==============================================*/ +/** + * @fn INT32 sli_Kill_Thread(PSLI_ADAPTER Adapter) + * @brief Kills the thread + * @param[in] PSLI_ADAPTER Adapter, Pointer to Adapter + * @return 0 + * @section description + * This function kills the thread + */ +INT32 sli_Kill_Thread(PSLI_ADAPTER Adapter) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Kill_Thread:\n"); +#endif + Adapter->transmit_thread_exit = 1; + sli_Set_Event(&Adapter->Event); + wait_for_completion(&Adapter->txThreadComplete); + Adapter->txThreadId = 0; + return 0; +} + +/*==============================================*/ +/** + * @fn INT32 sli_Init_Thread(PSLI_ADAPTER Adapter) + * @brief Initializes thread + * @param[in] PSLI_ADAPTER Adapter, Pointer to Adapter + * @return 0 on success, else failure + * @section description + * This function initializes event. + */ +uint8 name_p[20] = "XMIT-Thread"; +INT32 sli_Init_Thread(PSLI_ADAPTER Adapter) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_Init_Thread:\n"); +#endif + INT32 (*function)(PVOID pContext) = NULL; + + function = sli_transmit_thread; + + Adapter->txThreadId = 0; + Adapter->transmit_thread_exit = 0; + init_completion(&Adapter->txThreadComplete); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) + Adapter->txThreadId = + kernel_thread(function, Adapter, CLONE_FS | CLONE_FILES); +#else + Adapter->txThreadId = (int)kthread_run(function, Adapter, name_p); +#endif + + if (Adapter->txThreadId < 0) { + SLI_DEBUG(SLI_ZONE_ERROR, (TEXT("sli_probe: Unable to initialize thrd\n"))); + return SLI_STATUS_FAIL; + } else { + return SLI_STATUS_SUCCESS; + } /* End if */ +} + +/* $EOF */ +/* Log */ diff --git a/platforms/linux/Driver/common/src/sli_net_device.c b/platforms/linux/Driver/common/src/sli_net_device.c new file mode 100644 index 0000000..4a3927f --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_net_device.c @@ -0,0 +1,998 @@ +/***************************************************************************/ /** + * @file + * @brief This contains all the LINUX network device specific code + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include "sli_api.h" +#include "sli_global.h" +#include "sli_linux.h" +#include "sli_nic.h" +#ifdef SLI_SPI_INTERFACE +#include +#include +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) +#include +#include +#include +#else +#include +#endif +#include "sli_hal.h" +#endif +#include "sli_sdio.h" + +#include "sli_api.h" +#include "sli_global.h" +#include "sli_linux.h" +#include "sli_nic.h" + +/* globals */ +struct net_device *glbl_net_device = NULL; +PSLI_ADAPTER Adapter = NULL; + +#ifdef ENABLE_WMM_FEATURE +void dbg_test_values(PSLI_ADAPTER adapter); +#endif + +VOID sli_interrupt_handler(struct work_struct *work); + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +static SD_PNP_INFO sli_IdTable[] __devinitdata = { + { .SDIO_ManufacturerID = 0x101, + .SDIO_ManufacturerCode = 0x041b, + .SDIO_FunctionNo = 1, + .SDIO_FunctionClass = 0 }, + { .SDIO_ManufacturerID = 0x201, + .SDIO_ManufacturerCode = 0x041b, + .SDIO_FunctionNo = 1, + .SDIO_FunctionClass = 0 }, + { .SDIO_ManufacturerID = 0x301, + .SDIO_ManufacturerCode = 0x041b, + .SDIO_FunctionNo = 1, + .SDIO_FunctionClass = 0 }, + { .SDIO_ManufacturerID = 0x100, + .SDIO_ManufacturerCode = 0x0303, + .SDIO_FunctionNo = 1, + .SDIO_FunctionClass = 0 }, + {} +}; + +static SDFUNCTION sli_driver = { + .pName = "sli-SDIO WLAN", + .Version = CT_SDIO_STACK_VERSION_CODE, /* FIXME */ + .MaxDevices = 1, + .NumDevices = 0, + .pIds = sli_IdTable, + .pProbe = (PVOID)sli_sdio_probe, + .pRemove = sli_sdio_disconnect, + .pSuspend = NULL, + .pResume = NULL, + .pWake = NULL, +}; + +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +static const struct sdio_device_id sli_IdTable[] = { + { SDIO_DEVICE(0x303, 0x100) }, { SDIO_DEVICE(0x041B, 0x0301) }, + { SDIO_DEVICE(0x041B, 0x0201) }, { SDIO_DEVICE(0x041B, 0x9330) }, + { SDIO_DEVICE(0x041B, 0x9116) }, { SDIO_DEVICE(0x041B, 0x9117) }, + { SDIO_DEVICE(0x041B, 0x917) }, { /* Blank */ }, +}; + +static struct sdio_driver sli_driver = { + .name = "sli-SDIO WLAN", + .id_table = sli_IdTable, + .probe = sli_sdio_probe, + .remove = sli_sdio_disconnect, +}; +#endif + +/*==============================================*/ +/** + * @fn VOID sli_deinit_interface(PVOID pContext) + * @brief Interrupt handler + * @param[in] pContext, Pointer to our adapter + * @param[out] none + * @return none + * @section description: + * This function de-intializes the bus driver + */ +VOID sli_deinit_interface(PVOID pContext) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_deinit_interface:\n"); +#endif + PSLI_ADAPTER Adapter = (PSLI_ADAPTER)pContext; + return; +} + +/* statics */ + +/*==============================================*/ +/** + * @fn struct net_device* sli_allocdev( + * INT32 sizeof_priv) + * @brief Allocate & initializes the network device + * @param[in] sizeof_priv, size of the priv area to be allocated + * @param[out] none + * @return Pointer to the network device structure is returned + * @section description + * Allocate & initialize the network device.This function + * allocates memory for the network device & initializes it + * with ethernet generic values + */ +struct net_device *sli_allocdev(INT32 sizeof_priv, uint8 vap_id) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_allocdev:\n"); +#endif + struct net_device *dev = NULL; + if (vap_id == 0) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) + dev = alloc_netdev(sizeof_priv, "sli_wlan0", ether_setup); +#else + dev = alloc_netdev(sizeof_priv, "sli_wlan0", NET_NAME_UNKNOWN, ether_setup); +#endif +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_INIT, + "sli_allocdev: device allocated for sli_wlan0 %p\n", dev); +#endif + } else if (vap_id == 1) { + //! AP interface in concurrent mode +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) + dev = alloc_netdev(sizeof_priv, "sli_wlan1", ether_setup); +#else + dev = alloc_netdev(sizeof_priv, "sli_wlan1", NET_NAME_UNKNOWN, ether_setup); +#endif +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_INIT, "sli_allocdev: device allocated for sli_wlan1\n"); +#endif + } + return dev; +} + +/*==============================================*/ +/** + * @fn INT32 sli_registerdev(struct net_device *dev) + * @brief Register the network device + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return On success 0 is returned else a negative value signifying + * failure + * @section description + * This function is used to register the network device. + */ +INT32 sli_registerdev(struct net_device *dev) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_registerdev:\n"); +#endif + return register_netdev(dev); +} + +/*==============================================*/ +/** + * @fn INT32 sli_unregisterdev(struct net_device *dev) + * @brief Unregister the network device + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return On success 0 is returned else a negative value signifying + * failure + * @section description + * This function is used to unregisters the network device + * & returns it back to the kernel + */ +VOID sli_unregisterdev(struct net_device *dev) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_unregisterdev:\n"); +#endif + unregister_netdev(dev); + free_netdev(dev); + return; +} + +/*==============================================*/ +/** + * @fn struct net_device_stats * + * sli_get_stats(struct net_device *dev) + * @brief Gives the stats info + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return Pointer to the net_device_stats structure + * @section description + * This function gives the statistical information regarding + * the interface + */ +struct net_device_stats *sli_get_stats(struct net_device *dev) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_get_stats:\n"); +#endif + PSLI_ADAPTER Adapter = sli_getpriv(dev); + return &Adapter->stats; +} + +/*==============================================*/ +/** + * @fn PSLI_ADAPTER sli_getpriv(struct net_device *dev) + * @brief Get the pointer for the adapter + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return Pointer to the adapter On success 0, negative value signifying + * failure + * @section description + * This function get the pointer for the adapter + */ +PSLI_ADAPTER sli_getpriv(struct net_device *dev) +{ + PSLI_NET_DEV sli_net_device = netdev_priv(dev); + return sli_net_device->sli_adapter_ptr; +} + +/*==============================================*/ +/** + * @fn PSLI_NET_DEV sli_getdevpriv(struct net_device *dev) + * @brief Get the pointer for the adapter + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return Pointer to the adapter On success 0, negative value signifying + * failure + * @section description + * This function get the pointer for the adapter + */ +PSLI_NET_DEV sli_getdevpriv(struct net_device *dev) +{ + PSLI_NET_DEV sli_net_device = netdev_priv(dev); + return sli_net_device; +} + +/*==============================================*/ +/** + * @fn INT32 sli_ioctl(struct net_device *dev, + * struct ifreq *ifr, + * INT32 cmd) + * @brief Gives the stats info + * @param[in] dev, pointer to our network device structure + * @param[in] ifr, pointer to ifr structure + * @param[in] cmd, type of command or request + * @param[out] none + * @return Pointer to the net_device_stats structure + * @section description + * This function is registered to driver and will be called when + * ioctl issued from user space. + */ +INT32 sli_ioctl(struct net_device *dev, struct ifreq *ifr, INT32 cmd) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_ioctl:\n"); +#endif + PSLI_ADAPTER Adapter = sli_getpriv(dev); + struct iwreq *wrq = (struct iwreq *)ifr; + int16 retval = 0; + uint8 local_buffer[4096]; + uint16 data = 0; + uint32 addr, len, i, len_dwords; + uint8 get_status = 0; + + switch (cmd) { + case OID_WSC_GET_STATUS: { + sli_down_interruptible(&Adapter->int_check_sem); + sli_up_sem(&Adapter->int_check_sem); + + if (retval && copy_to_user(wrq->u.data.pointer, &retval, sizeof(UINT8))) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "sli_ioctl : Failed to perform operation\n"); + return -EFAULT; + } else if (copy_to_user(wrq->u.data.pointer, &get_status, sizeof(UINT8))) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "sli_ioctl : Failed to perform operation\n"); + return -EFAULT; + } + } break; + case OID_WSC_BOOT_READ: { + sli_down_interruptible(&Adapter->int_check_sem); + retval = sli_boot_insn(REG_READ, &data); + sli_up_sem(&Adapter->int_check_sem); + if (retval < 0) { + return -EFAULT; + } + if (copy_to_user(wrq->u.data.pointer, &data, sizeof(uint16))) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "sli_ioctl : Failed to perform operation\n"); + return -EFAULT; + } + } break; + case OID_WSC_BOOT_WRITE: { + sli_down_interruptible(&Adapter->int_check_sem); + copy_from_user(local_buffer, wrq->u.data.pointer, 2); + retval = sli_boot_insn(REG_WRITE, (uint16 *)local_buffer); + sli_up_sem(&Adapter->int_check_sem); + if (retval < 0) { + return -EFAULT; + } + } break; + case OID_WSC_BOOT_PING_WRITE: { + sli_down_interruptible(&Adapter->int_check_sem); + copy_from_user(local_buffer, wrq->u.data.pointer, 4096); + retval = sli_boot_insn(PING_WRITE, (uint16 *)local_buffer); + sli_up_sem(&Adapter->int_check_sem); + if (retval < 0) { + return -EFAULT; + } + } break; + case OID_WSC_BOOT_PONG_WRITE: { + sli_down_interruptible(&Adapter->int_check_sem); + copy_from_user(local_buffer, wrq->u.data.pointer, 4096); + retval = sli_boot_insn(PONG_WRITE, (uint16 *)local_buffer); + sli_up_sem(&Adapter->int_check_sem); + if (retval < 0) { + return -EFAULT; + } + } break; + case OID_WSC_POWER_SAVE_ENABLE: { + uint8 currentPowerMode = 0; + sli_down_interruptible(&Adapter->int_check_sem); + copy_from_user(¤tPowerMode, wrq->u.data.pointer, 1); + Adapter->power_save_enable = !!currentPowerMode; + sli_up_sem(&Adapter->int_check_sem); + } break; + case OID_MASTER_READ: { + addr = *(uint32_t *)wrq->u.data.pointer; + len = wrq->u.data.length; + len_dwords = (len & 3) ? ((len / 4) + 1) : (len / 4); + memset(local_buffer, 0, sizeof(local_buffer)); + sli_down_interruptible(&Adapter->int_check_sem); + for (i = 0; i < len_dwords; i++) { + retval = sli_boot_req(local_buffer + (i * 4), addr + (i * 4)); + } + sli_up_sem(&Adapter->int_check_sem); + if (retval < 0) { + return -EFAULT; + } + if (copy_to_user((wrq->u.data.pointer), local_buffer, len)) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "sli_ioctl : failed to perform\n"); + return -EFAULT; + } + } break; + } + return retval; +} + +/*==============================================*/ +/** + * @fn INT32 sli_open(struct net_device *dev) + * @brief Opens the interface + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return On success 0 is returned else a negative value signifying + * failure + * @section description + * This function opens the interface + */ +INT32 +sli_open(struct net_device *dev) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_open:\n"); +#endif + return 0; +} + +/*==============================================*/ +/** + * @fn INT32 sli_stop(struct net_device *dev) + * @brief Stops/brings down the interface + * @param[in] dev, pointer to our network device structure + * @param[out] none + * @return On success 0 is returned else a negative value signifying + * failure + * @section description + * This function stops/brings down the interface + */ +INT32 +sli_stop(struct net_device *dev) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_stop:\n"); +#endif + SLI_DEBUG(SLI_ZONE_INFO, "sli_stop\n"); + return 0; +} + +/*==============================================*/ +/** + * @fn struct net_device* sli_netdevice_op(vap_id) + * @brief netdevice related operations + * @param[in] vap_id device vap id + * @param[out] none + * @return dev, Pointer to net device structure + * @section description + * This function performs all net device related operations like + * allocating,initializing and registering the netdevice. + */ +struct net_device *sli_netdevice_op(UINT8 vap_id) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_netdevice_op:\n"); +#endif + struct net_device *dev; + PSLI_NET_DEV net_dev; + + /*Allocate & initialize the network device structure*/ + dev = sli_allocdev(sizeof(SLI_NET_DEV), vap_id); + + if (dev == NULL) { + SLI_DEBUG(SLI_ZONE_ERROR, + "sli_netdevice_op: Failure in allocation of net-device\n"); + return dev; + } + + //! Net device settings init + net_dev = sli_getdevpriv(dev); + net_dev->sli_adapter_ptr = Adapter; + +#if KERNEL_VERSION_LESS_THAN_EQUALS_2_6_(28) + dev->open = sli_open; + dev->stop = sli_stop; + dev->hard_start_xmit = sli_xmit; + dev->get_stats = sli_get_stats; + dev->do_ioctl = sli_ioctl; + dev->hard_header_len = 30; +#else + static struct net_device_ops dev_ops = { + .ndo_open = sli_open, + .ndo_stop = sli_stop, + .ndo_start_xmit = sli_xmit, + .ndo_do_ioctl = sli_ioctl, + .ndo_get_stats = sli_get_stats, + }; + + dev->netdev_ops = &dev_ops; + dev->hard_header_len = 30; +#endif + if (sli_registerdev(dev) != 0) { + SLI_DEBUG( + SLI_ZONE_ERROR, + "sli_netdevice_op: Registration of net-device failed for vap id %d\n", + vap_id); + free_netdev(dev); + return NULL; + } + + return dev; +} + +/*==============================================*/ +/** + * @fn SLI_STATUS sli_probe(VOID) + * @brief All the initializations at load time + * @param[in] none + * @param[out] none + * @return SLI_STATUS_SUCCESS in case of successful initialization + * or a negative error code signifying failure + * @section description + * This function is called at the module load time. + * All the initialization work is done here. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +BOOLEAN __devinit sli_sdio_probe(PSDFUNCTION pfunction, PSDDEVICE pDevice) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int sli_sdio_probe(struct sdio_func *pfunction, const struct sdio_device_id *id) +#endif +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_probe:\n"); +#endif + struct net_device *dev = NULL; +#if SLI_CONCURRENT_MODE + struct net_device *dev_ap = NULL; +#endif + SLI_STATUS status = SLI_STATUS_SUCCESS; + UINT8 ii; + UINT16 retval = 0; + + + //! Freeing Adapter if it is already allocated. + if (Adapter != NULL) { + SLI_DEBUG(SLI_ZONE_INIT, "sli_probe: Freed Adapter\n"); + kfree(Adapter); + Adapter = NULL; + } + + //! Allocating memory for Adapter from kernel Heap memory pool + Adapter = (PSLI_ADAPTER)kmalloc(sizeof(SLI_ADAPTER), GFP_ATOMIC); + + if (Adapter == NULL) { + SLI_DEBUG(SLI_ZONE_INIT, "sli_probe: kmalloc failed\n"); + } + + //! Reseting the adapter + sli_memset(Adapter, 0, sizeof(SLI_ADAPTER)); + + dev = sli_netdevice_op(0); + if (!dev) { + SLI_DEBUG(SLI_ZONE_ERROR, + "sli_probe: Failed to perform netdevice operations\n"); + return SLI_STATUS_FAIL; + } + +#if SLI_CONCURRENT_MODE + dev_ap = sli_netdevice_op(1); + if (!dev_ap) { + SLI_DEBUG(SLI_ZONE_ERROR, + "sli_probe: Failed to perform netdevice operations for AP1\n"); + return SLI_STATUS_FAIL; + } +#endif + + SLI_DEBUG(SLI_ZONE_INIT, "sli_probe: Net device operations suceeded\n"); + +#ifdef ENABLE_WMM_FEATURE + dbg_test_values(Adapter); +#endif + + Adapter->net_device0 = dev; +#if SLI_CONCURRENT_MODE + Adapter->net_device1 = dev_ap; +#endif + glbl_net_device = dev; + + for (ii = 0; ii < 4; ii++) { + sli_queue_init(&Adapter->list[ii]); + } + + Adapter->workqueue = create_singlethread_workqueue("gdvr_work"); + if (Adapter->workqueue == NULL) { + SLI_DEBUG(SLI_ZONE_INIT, "Work queue Fail\n"); + goto fail; + } + SLI_DEBUG(SLI_ZONE_INIT, "\n SDIO: claiming host"); + sli_sdio_claim_host(pfunction); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + status = sli_enable_interface(pDevice); + + if (!SDIO_SUCCESS((status))) { + SLI_DEBUG(SLI_ZONE_ERROR, (TEXT("%s: Failed to enable interface for the " + "kernels b/w 2.6.18 and 2.6.22\n"), + __func__)); + sli_sdio_release_host(pfunction); + return status; + } +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + status = sli_enable_interface(pfunction); + if (status != 0) { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, "%s: Failed to enable interface\n", __func__); + sli_sdio_release_host(pfunction); + return status; + } +#endif + + sli_sdio_release_host(pfunction); + + /*Enable the SPI interface*/ +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)) + INIT_WORK(&Adapter->handler, (void *)sli_interrupt_handler, + (void *)&Adapter->handler); +#else + INIT_WORK(&Adapter->handler, (void *)sli_interrupt_handler); +#endif + SLI_DEBUG(SLI_ZONE_INIT, "sli_probe: Enabled the interface\n"); + + sli_spinlock_init(&Adapter->lockqueue); +#ifdef init_MUTEX + sli_init_mutex(&Adapter->int_check_sem); + sli_init_mutex(&Adapter->sleep_ack_sem); // default + sli_init_mutex(&Adapter->tx_data_sem); // default +#else + sli_sema_init(&Adapter->int_check_sem, 1); + sli_sema_init(&Adapter->sleep_ack_sem, 1); + sli_sema_init(&Adapter->tx_data_sem, 1); +#endif + + /* Requesting thread */ + sli_Init_Event(&Adapter->Event); + + sli_Init_Event(&Adapter->PwrSaveEvent); + sli_Init_Thread(Adapter); + SLI_DEBUG(SLI_ZONE_INIT, "sli_probe: Initialized thread & Event\n"); + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + Adapter->pDevice = pDevice; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + Adapter->pfunction = pfunction; +#endif + + sli_setcontext(pfunction, (void *)Adapter); + /*Initalizing the hardware*/ + sli_sdio_claim_host(pfunction); + + status = sli_setupcard(Adapter); + if (status != 0) { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s:Failed to setup card\n"), __func__)); + kfree((uint8 *)Adapter->DataRcvPacket[0]); + sli_sdio_release_host(pfunction); + goto fail; + } + + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s: Setup card succesfully\n"), __func__)); +#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) + Adapter->sdio_high_speed_enable = 1; +#endif + sli_sdio_release_host(pfunction); + + if (sli_init_host_interface(Adapter) != 0) { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s:Failed to init slave regs\n"), __func__)); + sli_sdio_release_host(pfunction); + goto fail; + } + + return status; + /*Failure in one of the steps will cause the control to be transferred here*/ + fail_out: + for (ii = 0; ii < 4; ii++) { + sli_queue_purge(&Adapter->list[ii]); + } + sli_sdio_claim_host(pfunction); + sli_sdio_release_irq(pfunction); + + /*Disable the interface*/ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + sli_disable_interface(pDevice); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + sli_disable_interface(pfunction); +#endif + /* Release the host. It should be called after calling sdio_disable_func() */ + sli_sdio_release_host(pfunction); + + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s: Failed to initialize...Exiting\n"), __func__)); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return 1; +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + return 0; +#endif + + fail_out1: + sli_deinit_interface(Adapter); + + fail: + if (dev) { + /*Unregisters & returns the network device to the kernel*/ + sli_unregisterdev(dev); + } + +#if SLI_CONCURRENT_MODE + if (dev_ap) { + /*Unregisters & returns the network device to the kernel*/ + sli_unregisterdev(dev_ap); + } +#endif + + /*Disable the interface*/ + + SLI_DEBUG(SLI_ZONE_ERROR, "sli_probe: Failure to initialize\n"); + return SLI_STATUS_FAIL; +} + +/*==============================================*/ +/** + * @fn VOID sli_interrupt_handler(struct work_struct *work) + * @brief Interrupt handler + * @param[in] struct work_struct *work, Pointer to work_struct + * structure + * @param[out] none + * @return none + * @section description: + * Upon the occurence of an interrupt, the interrupt handler will + * be called + */ +uint8 interrupt_recv = 0; +VOID sli_interrupt_handler(struct work_struct *work) +{ +#ifdef SLI_DEBUG_PRINT +#endif + interrupt_recv++; + PSLI_ADAPTER Adapter = container_of(work, SLI_ADAPTER, handler); + uint32 InterruptType = 0; + INT32 retval; + uint8 temp; + UINT8 InterruptStatus = 0; + uint16 offset; + uint32 length, status; + UINT8 *rx_buff = NULL; + +#ifdef DSLI_DEBUG_PRINT + uint32 i = 0; +#endif + + uint32 i = 0; + do { + retval = read_register(Adapter, SDIO_FUN1_INT_REG, 0, &InterruptStatus); + if (retval != 0) { + schedule(); + } + Adapter->InterruptStatus = InterruptStatus; + InterruptStatus &= 0xE; + if (InterruptStatus == 0) { + return; + } + + rx_buff = Adapter->rx_buffer; + + do { + InterruptType = SLI_GET_INTERRUPT_TYPE(InterruptStatus); + switch (InterruptType) { + case SDIO_BUFFER_FULL: { + Adapter->BufferFull = 1; + ack_interrupt(Adapter, SD_PKT_BUFF_FULL); + SLI_DEBUG(SLI_ZONE_SDIO_DBG, "BUFFER FULL \n"); + return; + } break; + + case SDIO_BUFFER_FREE: { + Adapter->BufferFull = 0; + ack_interrupt(Adapter, SD_PKT_BUFF_EMPTY); + SLI_DEBUG(SLI_ZONE_SDIO_DBG, "BUFFER EMPTY \n"); + return; + } break; + + case FIRMWARE_STATUS: { + Adapter->FSM_STATE = FSM_CARD_NOT_READY; + SLI_DEBUG(SLI_ZONE_SPI_DBG, "FIRMWARE CARD NOT READY\n"); + return; + } break; + + case SDIO_DATA_PENDING: { + sli_up_sem(&Adapter->int_check_sem); + + if (sli_sdio_frame_read(Adapter)) { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("ganges_interrupt_handler: Unable to recv pkt\n"))); + sli_down_sem(&Adapter->int_check_sem); + return; + } + length = + ((Adapter->DataRcvPacket[2] | (Adapter->DataRcvPacket[3] << 8)) + & 0xfff) + + CPC_HEADER_LENGTH; + memcpy(rx_buff, &Adapter->DataRcvPacket[0], length); + sli_send_rsp_to_userspace(Adapter, rx_buff); + sli_down_sem(&Adapter->int_check_sem); + } break; + + default: { + sli_up_sem(&Adapter->int_check_sem); + ack_interrupt(Adapter, InterruptStatus); + SLI_DEBUG( + SLI_ZONE_SPI_DBG, + (TEXT("ganges_interrupt_handler: No more pending interrupts\n"))); + sli_down_sem(&Adapter->int_check_sem); + return; + } + } + InterruptStatus ^= BIT(InterruptType - 1); + } while (InterruptStatus); + } while (1); + return; +} + +/*==============================================*/ +/** + * @fn SLI_STATUS sli_linux_disconnect(VOID) + * @brief Reverse of probe + * @param[in] none + * @param[out] none + * @return SLI_STATUS_SUCCESS in case of successful initialization + * or a negative error code signifying failure + * @section description + * This function performs the reverse of the probe function. + */ +SLI_STATUS sli_linux_disconnect(VOID) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_linux_disconnect:\n"); +#endif + SLI_STATUS Status = SLI_STATUS_SUCCESS; + UINT32 ii; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + + SLI_DEBUG(SLI_ZONE_INFO, "sli_linux_disconnect: Deinitializing\n"); + + Adapter->FSM_STATE = 0; + + sli_Delete_Event(&Adapter->PwrSaveEvent); + + sli_Delete_Event(&Adapter->Event); + + SLI_DEBUG(SLI_ZONE_INFO, "Killing thread \n"); + Adapter->halt_flag = 1; + + sli_Kill_Thread(Adapter); + + SLI_DEBUG(SLI_ZONE_INFO, "Purge queue \n"); + for (ii = 0; ii < 4; ii++) { + sli_queue_purge(&Adapter->list[ii]); + } + + /*Return the network device to the kernel*/ + SLI_DEBUG(SLI_ZONE_INFO, "Deinit interface \n"); + sli_deinit_interface(Adapter); + SLI_DEBUG(SLI_ZONE_INFO, "Unregister netdev \n"); + sli_unregisterdev(Adapter->net_device0); +#if SLI_CONCURRENT_MODE + sli_unregisterdev(Adapter->net_device1); +#endif + + /*Disable the interface*/ + SLI_DEBUG(SLI_ZONE_INFO, "sli_linux_disconnect: Disabling the interface\n"); + return Status; +} + +/*==============================================*/ +/** + * @fn SLI_STATUS sli_init_interface(PVOID pContext) + * @brief Interrupt handler + * @param[in] pContext, Pointer to our adapter + * @param[out] none + * @return Returns SLI_STATUS_SUCCESS or SLI_STATUS_FAIL + * @section description: + * This function intializes the bus driver + */ +SLI_STATUS +sli_init_interface(PVOID pContext) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_init_interface:\n"); +#endif + INT32 ret = 0; + PSLI_ADAPTER Adapter = (PSLI_ADAPTER)pContext; + + uint32 status; + sli_sdio_claim_host(Adapter->pfunction); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + status = sli_request_interrupt_handler(Adapter->pDevice, + sli_sdio_interrupt_handler, Adapter); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + status = sli_request_interrupt_handler(Adapter->pfunction, + sli_sdio_interrupt_handler, Adapter); +#endif + if (status != 0) { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s:Failed to register interrupt\n"), __func__)); + sli_sdio_release_host(Adapter->pfunction); + return -1; + } + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s: Registered Interrupt handler\n"), __func__)); + + /*Initalizing the hardware*/ + sli_sdio_release_host(Adapter->pfunction); + + return SLI_STATUS_SUCCESS; +} + +/*==============================================*/ +/** + * @fn SLI_STATIC INT32 __init + * sli_module_init(VOID) + * @brief module init + * @param[in] pContext, Pointer to our adapter + * @param[out] none + * @return 0 in case of success or a negative + * value signifying failure + * @section description: + * This function is invoked when the module is loaded into the + * kernel. It registers the client driver. + */ +SLI_STATIC INT32 __init sli_module_init(VOID) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_module_init:\n"); +#endif + INT32 rc; + + SLI_STATUS status = SLI_STATUS_SUCCESS; + SLI_DEBUG(SLI_ZONE_SPI_DBG, "INIT MODULE\n"); + + rc = sli_register_genl(); + if (rc != 0) { + goto failure; + } + + SLI_DEBUG(SLI_ZONE_SDIO_DBG, "SDIO REGISTER DRIVER \n"); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + status = SDIOErrorToOSError(SDIO_RegisterFunction(&onebox_driver)); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + status = sdio_register_driver(&sli_driver); +#endif + if (status) { + goto failure; + } + return 0; + + failure: + SLI_DEBUG(SLI_ZONE_SPI_DBG, "an error occured while inserting the module\n"); + return -1; +} + +/*==============================================*/ +/** + * @fn SLI_STATIC VOID __exit + * sli_module_exit(VOID) + * @brief module exit + * @param[in] VOID + * @param[out] none + * @return none + * @section description: + * At the time of removing/unloading the module, this function is + * called. It unregisters the client driver. + */ +SLI_STATIC VOID __exit sli_module_exit(VOID) +{ +#ifdef SLI_DEBUG_PRINT + SLI_DEBUG(SLI_ZONE_SPI_DBG, "\nsli_module_exit:\n"); +#endif + INT32 ret; + SLI_DEBUG(SLI_ZONE_SPI_DBG, "EXIT MODULE\n"); + int32 status; + /*Unregistering the client driver*/ + ret = sli_unregister_genl(); + if (ret != 0) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "genl unregister failed %i\n", ret); + return; + } + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + status = SDIO_UnregisterFunction(&sli_driver); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + sdio_unregister_driver(&sli_driver); +#endif + + //! Free the Adapter when driver is removed + if (Adapter != NULL) { + SLI_DEBUG(SLI_ZONE_SPI_DBG, "Freed Adapter successfully\n"); + kfree(Adapter); + Adapter = NULL; + } + + if (status) { + goto fail; + } + + SLI_DEBUG(SLI_ZONE_SPI_DBG, "Module removed successfully\n"); + return; + fail: + SLI_DEBUG(SLI_ZONE_ERROR, "Error in removing the module\n"); + return; +} + +module_init(sli_module_init); +module_exit(sli_module_exit); +MODULE_LICENSE("GPL"); + +/* $EOF */ +/* Log */ diff --git a/platforms/linux/Driver/common/src/sli_send_boot_insn.c b/platforms/linux/Driver/common/src/sli_send_boot_insn.c new file mode 100644 index 0000000..9023643 --- /dev/null +++ b/platforms/linux/Driver/common/src/sli_send_boot_insn.c @@ -0,0 +1,179 @@ +/***************************************************************************/ /** + * @file + * @brief SEND BOOT INSN: send boot instructions to WiFi module + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include "sli_global.h" + +int16 sli_secure_ping_pong_wr(uint32 ping_pong, uint8 *src_addr, + uint16 size_param); +/*==============================================*/ +/** + * @fn int16 sli_boot_insn(uint8 type, uint16 *data) + * @brief Sends boot instructions to WiFi module + * @param[in] uint8 type, type of the insruction to perform + * @param[in] uint32 *data, pointer to data which is to be read/write + * @param[out] none + * @return errCode + * < 0 = Command issued failure/Invalid command + * 0 = SUCCESS + * > 0 = Read value + * @section description + * This API is used to send boot instructions to WiFi module. + */ +extern int16 sli_mem_rd(uint32 reg_address, uint16 len, uint8 *value); +extern int16 sli_mem_wr(uint32 reg_address, uint16 len, uint8 *value); + +int16 sli_boot_insn(uint8 type, uint16 *data) +{ + int16 retval = 0; + uint16 local = 0; + uint32 j = 0; + uint32 cmd = 0; + uint16 read_data = 0; + volatile int32 loop_counter = 0; +#ifdef SLI_DEBUG_PRINT + SLI_DPRINT(SLI_PL3, "\nBootInsn\n"); +#endif + + switch (type) { + case REG_READ: + retval = sli_mem_rd(HOST_INTF_REG_OUT, 2, (uint8 *)&read_data); + *data = read_data; + break; + + case REG_WRITE: + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)data); + break; + + case PING_WRITE: +#if SLI_SECURE_BOOT +#ifndef SLI_OFFSET_BASED + retval = sli_secure_ping_pong_wr(0, (uint8 *)data, 4096); +#else + retval = sli_secure_ping_pong_wr_offset(0, (uint8 *)data, 4096); +#endif + local = 0xab49; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&local); +#else + for (j = 0; j < 2048; j++) { + retval = + sli_mem_wr(0x18000 + (j * 2), 2, (uint8 *)((uint32)data + (j * 2))); + if (retval < 0) { + return retval; + } + } + + local = 0xab49; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&local); +#endif + break; + + case PONG_WRITE: +#if SLI_SECURE_BOOT +#ifndef SLI_OFFSET_BASED + retval = sli_secure_ping_pong_wr(1, (uint8 *)data, 4096); +#else + retval = sli_secure_ping_pong_wr_offset(1, (uint8 *)data, 4096); +#endif + local = 0xab4f; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&local); +#else + for (j = 0; j < 2048; j++) { + retval = + sli_mem_wr(0x19000 + (j * 2), 2, (uint8 *)((uint32)data + (j * 2))); + if (retval < 0) { + return retval; + } + } + // Perform the write operation + local = 0xab4f; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&local); +#endif + // Perform the write operation + break; + + case BURN_NWP_FW: + cmd = BURN_NWP_FW | HOST_INTERACT_REG_VALID; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&cmd); + if (retval < 0) { + return retval; + } + SLI_RESET_LOOP_COUNTER(loop_counter); + SLI_WHILE_LOOP(loop_counter, SLI_LOOP_COUNT_UPGRADE_IMAGE) { + retval = sli_mem_rd(HOST_INTF_REG_OUT, 2, (uint8 *)&read_data); + if (retval < 0) { + return retval; + } + if (read_data == (SEND_RPS_FILE | HOST_INTERACT_REG_VALID)) { + break; + } + } + SLI_CHECK_LOOP_COUNTER(loop_counter, SLI_LOOP_COUNT_UPGRADE_IMAGE); + break; + + case LOAD_NWP_FW: + cmd = LOAD_NWP_FW | HOST_INTERACT_REG_VALID; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&cmd); + break; + case LOAD_DEFAULT_NWP_FW_ACTIVE_LOW: + cmd = LOAD_DEFAULT_NWP_FW_ACTIVE_LOW | HOST_INTERACT_REG_VALID; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&cmd); + break; + case SLI_UPGRADE_BL: + cmd = SLI_UPGRADE_BL | HOST_INTERACT_REG_VALID; + retval = sli_mem_wr(HOST_INTF_REG_IN, 2, (uint8 *)&cmd); + if (retval < 0) { + return retval; + } + SLI_RESET_LOOP_COUNTER(loop_counter); + SLI_WHILE_LOOP(loop_counter, SLI_LOOP_COUNT_UPGRADE_IMAGE) { + retval = sli_mem_rd(HOST_INTF_REG_OUT, 2, (uint8 *)&read_data); + if (retval < 0) { + return retval; + } + if (read_data == (SEND_RPS_FILE | HOST_INTERACT_REG_VALID)) { + break; + } + } + SLI_CHECK_LOOP_COUNTER(loop_counter, SLI_LOOP_COUNT_UPGRADE_IMAGE); + break; + default: + retval = -2; + break; + } + return retval; +} +/*==============================================*/ +/** + * @fn int16_t sli_boot_req() + * @brief Sends boot instructions to WiFi module + * @param[in] uint32 *data + * @param[in] uint32 addr + * @param[out] none + * @return errCode + * 0 = SUCCESS + * > 0 = Read value + * @section description + * This API is used to send boot instructions to WiFi module. + */ +int16 sli_boot_req(uint32 *data, uint32 addr) +{ + int16 retval = -1; + if (data != NULL) { + retval = sli_mem_rd(addr, 4, (uint32 *)data); + } + return retval; +} diff --git a/platforms/linux/Driver/sdio/include/sli_sdio.h b/platforms/linux/Driver/sdio/include/sli_sdio.h new file mode 100644 index 0000000..bf102eb --- /dev/null +++ b/platforms/linux/Driver/sdio/include/sli_sdio.h @@ -0,0 +1,271 @@ +/***************************************************************************//** + * @file + * @brief This file contians the function prototypes of related to sdio interface + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SLI_SDIO_H +#define SLI_SDIO_H + +#include "sli_nic.h" +#include "sli_common.h" + +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))&&(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23))) +#include +#include +#include +#include +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +/* Interrupt Status Values */ +typedef enum { + SDIO_BUFFER_FULL = 0X1, + SDIO_BUFFER_FREE = 0X2, + FIRMWARE_STATUS = 0X3, + SDIO_DATA_PENDING = 0X4, + SDIO_UNKNOWN_INTERRUPT= 0XB +} INTERRUPT_TYPE; + +#define SD_DATA_PENDING (1 << 3) +#define SD_FIRMWARE_STATUS (1 << 2) +#define SD_PKT_BUFF_EMPTY (1 << 1) +#define SD_PKT_BUFF_FULL (1 << 0) + +#define FSM_CARD_NOT_READY 0 +#define SLI_GET_INTERRUPT_TYPE(_I) \ + (_I & (SD_PKT_BUFF_FULL)) ? \ + SDIO_BUFFER_FULL :\ + (_I & ( SD_PKT_BUFF_EMPTY)) ? \ + SDIO_BUFFER_FREE :\ + (_I & ( SD_FIRMWARE_STATUS)) ? \ + FIRMWARE_STATUS:\ + (_I & ( SD_DATA_PENDING)) ? \ + SDIO_DATA_PENDING: SDIO_UNKNOWN_INTERRUPT + + + +#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \ + (arg) = (((rw) & 1) << 31) | \ + (((func) & 0x7) << 28) | \ + (((raw) & 1) << 27) | \ + (1 << 26) | \ + (((address) & 0x1FFFF) << 9) | \ + (1 << 8) | \ + ((writedata) & 0xFF) + +#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \ + SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00) +#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \ + SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value) +#define SDIO_MASTER_ACCESS_MSBYTE 0x000FA +#define SDIO_MASTER_ACCESS_LSBYTE 0x000FB +#define FLASH_SIZE_ADDR 0x04000016 + +#define WATCH_DOG_TIMER_1 0x16c +#define WATCH_DOG_TIMER_2 0x16d +#define WATCH_DOG_DELAY_TIMER_1 0x16e +#define WATCH_DOG_DELAY_TIMER_2 0x16f +#define WATCH_DOG_TIMER_ENABLE 0x170 + +#define RESTART_WDT BIT(11) +#define BYPASS_ULP_ON_WDT BIT(1) + +#ifdef USE_USB_INTF +#define RF_SPI_PROG_REG_BASE_ADDR 0x40080000 +#else +#define RF_SPI_PROG_REG_BASE_ADDR 0 +#endif + +#define GSPI_CTRL_REG0 (RF_SPI_PROG_REG_BASE_ADDR) +#define GSPI_CTRL_REG1 (RF_SPI_PROG_REG_BASE_ADDR + 0x2) +#define GSPI_DATA_REG0 (RF_SPI_PROG_REG_BASE_ADDR + 0x4) +#define GSPI_DATA_REG1 (RF_SPI_PROG_REG_BASE_ADDR + 0x6) +#define GSPI_DATA_REG2 (RF_SPI_PROG_REG_BASE_ADDR + 0x8) + +#define GSPI_DMA_MODE BIT(13) + +#define GSPI_2_ULP BIT(12) +#define GSPI_TRIG BIT(7) +#define GSPI_READ BIT(6) +#define GSPI_RF_SPI_ACTIVE BIT(8) +/*CONTENT OF THIS REG IS WRITTEN TO ADDRESS IN SD_CSA_PTR*/ + +#define SD_REQUEST_MASTER 0x10000 + +#define SLI_SDIO_BLOCK_SIZE 256 + +#define sli_likely(a) likely(a) + +#define SLI_RCV_BUFFER_LEN 1600 +#define FRAME_DESC_SZ 16 + +#define SLI_DESC_QUEUE_NUM_MASK 0x7 +#define SLI_DESC_AGGR_ENAB_MASK 0x80 + + + +/* FOR SD CARD ONLY */ +#define SDIO_RX_NUM_BLOCKS_REG 0x000F1 +#define SDIO_FW_STATUS_REG 0x000F2 +#define SDIO_NXT_RD_DELAY2 0x000F5 /* Next read delay 2 */ +#define SDIO_FUN1_INT_REG 0x000F9 /* Function interrupt register*/ +#define SDIO_READ_START_LVL 0x000FC +#define SDIO_READ_FIFO_CTL 0x000FD +#define SDIO_WRITE_FIFO_CTL 0x000FE +#define SDIO_WAKEUP_REG 0x000FF + +#define WLAN_TX_D_Q 5 +/* common registers in SDIO function1 */ +#define SDIO_FUN1_INTR_CLR_REG 0x0008 +#define TA_SOFT_RESET_REG 0x0004 +#define TA_TH0_PC_REG 0x0400 +#define TA_HOLD_THREAD_REG 0x0844 +#define TA_RELEASE_THREAD_REG 0x0848 +#define TA_POLL_BREAK_STATUS_REG 0x085C + +/* WLAN registers in SDIO function 1 */ +#define SDIO_RF_CNTRL_REG 0x0000000C /* Lower MAC control register-1 */ +#define SDIO_LMAC_CNTRL_REG 0x00000024 /* Lower MAC control register */ +#define SDIO_LMAC_LOAD_REG 0x00000020 /* Lower MAC load register */ +#define SDIO_TCP_CHK_SUM 0x0000006C /* TCP check sum enable register */ + +#define RF_SELECT 0x0000000c /* RF Select Register */ + +/* SDIO STANDARD CARD COMMON CNT REG(CCCR) */ + +/*IN THESE REGISTERS EACH BIT(0-7) REFERS TO A FUNCTION */ + +#define CCCR_REVISION 0x00 +#define SD_SPEC_REVISION 0x01 +#define SD_IO_ENABLE 0x02 +#define SD_IO_READY 0x03 +#define SD_INT_ENABLE 0x04 +#define SD_INT_PENDING 0x05 +#define SD_IO_ABART 0x06 +#define SD_BUS_IF_CNT 0x07 +#define SD_CARD_CAPABILITY 0x08 + +/*PTR to CARD'S COMMON CARD INFO STRUCT(CIS):0x09-0x0B*/ +#define SD_CIS_PTR 0x09 +#define SD_BUS_SUSPEND 0x0C +#define SD_FUNCTION_SELEC 0x0D +#define SD_EXEC_FLAGS 0x0E +#define SD_READY_FLAGS 0x0F +#define SD_FN0_BLK_SZ 0x10 /*FUNCTION0 BLK SIZE:0x10-0x11 */ +#define SD_RESERVED 0x12 /*0x12-0xFF:reserved for future */ +#define SDIO_REG_HIGH_SPEED 0x13 + + +/* SDIO_FUN1_FIRM_LD_CTRL_REG register bits */ + +#define TA_SOFT_RST_CLR 0 +#define TA_SOFT_RST_SET BIT(0) +#define TA_PC_ZERO 0 +#define TA_HOLD_THREAD_VALUE 0xF +#define TA_RELEASE_THREAD_VALUE 0xF +#define TA_DM_LOAD_CLR BIT(21) +#define TA_DM_LOAD_SET BIT(20) + + +/* Function prototypes */ +struct sli_osd_host_intf_operations *sli_get_osd_host_intf_operations(void); +struct sli_osi_host_intf_operations *sli_get_osi_host_intf_operations(void); +struct sli_os_intf_operations *sli_get_os_intf_operations(void); +struct sli_os_intf_operations *sli_get_os_intf_operations_from_origin(void); + +int read_register(PSLI_ADAPTER adapter, uint32 Addr,uint8 fun_num,uint8 *data); +int write_register(PSLI_ADAPTER adapter,uint8 reg_dmn,uint32 Addr,uint8 *data); +int host_intf_read_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len); +int host_intf_write_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len, uint8 queueno); +void send_ulp_sleep_ack_to_ta(PSLI_ADAPTER adapter); +void send_sleep_status_to_coex(uint8 qnum, uint8 ack_status); +int read_register_multiple(PSLI_ADAPTER adapter, + uint32 Addr, + uint32 Count, + uint8 *data ); +int write_register_multiple(PSLI_ADAPTER adapter, + uint32 Addr, + uint8 *data, + uint32 Count); +int ack_interrupt(PSLI_ADAPTER adapter,uint8 INT_BIT); +int register_driver(void); +void unregister_driver(void); +int remove(void); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +struct net_device * sli_getcontext(PSDFUNCTION pfunction); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +void* sli_getcontext(struct sdio_func *pfunction); +#endif + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_claim_host(PSDFUNCTION pFunction); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_claim_host(struct sdio_func *pfunction); +#endif + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +BOOLEAN __devinit sli_sdio_probe(PSDFUNCTION pfunction, PSDDEVICE pDevice); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int sli_sdio_probe(struct sdio_func *pfunction, const struct sdio_device_id *id); +#endif + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_release_host(PSDFUNCTION pFunction); +#el if KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_release_host(struct sdio_func *pfunction); +#endif +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_interrupt_handler(PVOID pContext); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_interrupt_handler(struct sdio_func *function); +#endif + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_setcontext(PSDFUNCTION pFunction, void *adapter); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_setcontext(struct sdio_func *pfunction, void *adapter); +#endif + +int sli_setupcard(PSLI_ADAPTER adapter); +int init_host_interface(PSLI_ADAPTER adapter); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int32 sli_sdio_release_irq(PSDFUNCTION pFunction); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int32 sli_sdio_release_irq(struct sdio_func *pfunction); +#endif + +int32 deregister_sdio_irq(PSLI_ADAPTER adapter); + +int sli_setclock(PSLI_ADAPTER adapter, uint32 Freq); + +int sli_abort_handler(PSLI_ADAPTER Adapter ); +int sli_init_sdio_slave_regs(PSLI_ADAPTER adapter); +int disable_sdio_interrupt(PSLI_ADAPTER adapter); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID __devexit sli_sdio_disconnect ( PSDFUNCTION pfunction, PSDDEVICE pDevice); +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_disconnect ( struct sdio_func *pfunction); +#endif + +#endif diff --git a/platforms/linux/Driver/sdio/src/Makefile b/platforms/linux/Driver/sdio/src/Makefile new file mode 100644 index 0000000..905bace --- /dev/null +++ b/platforms/linux/Driver/sdio/src/Makefile @@ -0,0 +1,81 @@ +#*HEADER******************************************************************* +#Copyright (c) +#All rights reserved +#This software embodies materials and concepts that are confidential +#to Redpine Signals and is made available solely pursuant to the terms +#of a written license agreement with Redpine Signals +# +#Project name : WiSeConnect +#Module name : Linux SDIO Driver +#File Name : Makefile +# +#File Description: +# This is the Makefile For RSI Linux USB Driver +# +# +#Author : +# +#Rev History: +#Ver By date Description +#--------------------------------------------------------- +#1.1 Initial version +#--------------------------------------------------------- +#*END********************************************************************* + +DEF_KERNEL_DIR := /lib/modules/$(shell uname -r)/build + +ifeq ($(KERNELDIR),) + KERNELDIR := $(DEF_KERNEL_DIR) +endif + + +ifeq ($(DRIVER_DIR),) +DRIVER_DIR=$(PWD) +endif + + +SDIO_INCLUDE=$(DRIVER_DIR)/../include/ +COMMON_INCLUDE=$(DRIVER_DIR)/../../common/include/ +COMMON_SRC=../../common/src +EXTRA_CFLAGS += -DLINUX +EXTRA_CFLAGS += -DSLI_SDIO_INTERFACE +EXTRA_CFLAGS += -D m32 + +EXTRA_CFLAGS += -I$(SDIO_INCLUDE) +EXTRA_CFLAGS += -I$(COMMON_INCLUDE) +EXTRA_CFLAGS += -I$(KERNELDIR) +EXTRA_CFLAGS += -Wimplicit +EXTRA_CFLAGS += -w +EXTRA_CFLAGS += -DRSI_AUTOMATION_ENABLE +EXTRA_CFLAGS += -Wstrict-prototypes +EXTRA_CFLAGS += -DRS9116 +EXTRA_CFLAGS += -DRSI_SDIO_MULTI_BLOCK_SUPPORT + +SRC_FILES := $(COMMON_SRC)/sli_linux_netlink.o \ + $(COMMON_SRC)/sli_net_device.o \ + $(COMMON_SRC)/sli_linux_specific.o \ + $(COMMON_SRC)/sli_linux_data.o \ + $(COMMON_SRC)/sli_send_boot_insn.o \ + $(COMMON_SRC)/sli_lib_util.o \ + sli_hal_mcu_ioports.o \ + sli_hal_mcu_sdio.o \ + +obj-m := $(INSTALLDIR)rpssdio.o +$(INSTALLDIR)rpssdio-objs := ${SRC_FILES} + +all: + @echo "Compiling driver code" + make -C $(KERNELDIR) SUBDIRS=$(PWD) modules + +clean: + @echo "Cleaning driver binary files" + rm -rf $(INSTALLDIR)rpssdio.* + rm -rf $(INSTALLDIR)*.rpssdio.*.* + rm -rf *.o *.mod.* *.symvers + rm -rf .rps* + rm -rf .rsi* + rm -rf .tmp_versions + rm -rf modules.order + rm -rf $(COMMON_SRC)/*.o + rm -rf $(COMMON_SRC)/*.cmd + rm -rf $(COMMON_SRC)/.*.cmd diff --git a/platforms/linux/Driver/sdio/src/insert.sh b/platforms/linux/Driver/sdio/src/insert.sh new file mode 100644 index 0000000..61e2425 --- /dev/null +++ b/platforms/linux/Driver/sdio/src/insert.sh @@ -0,0 +1,2 @@ +cat /dev/null > /var/log/messages +insmod rpssdio.ko diff --git a/platforms/linux/Driver/sdio/src/remove.sh b/platforms/linux/Driver/sdio/src/remove.sh new file mode 100644 index 0000000..304a301 --- /dev/null +++ b/platforms/linux/Driver/sdio/src/remove.sh @@ -0,0 +1 @@ +rmmod rpssdio diff --git a/platforms/linux/Driver/sdio/src/sli_hal_mcu_ioports.c b/platforms/linux/Driver/sdio/src/sli_hal_mcu_ioports.c new file mode 100644 index 0000000..594cc7d --- /dev/null +++ b/platforms/linux/Driver/sdio/src/sli_hal_mcu_ioports.c @@ -0,0 +1,151 @@ +/***************************************************************************//** + * @file + * @brief Functions to control IO pins of the microcontroller + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include "sli_global.h" +#include "sli_hal.h" +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18)) +#include +#else +#include +#endif + +/** + * Global Variales + */ + + + +/*====================================================*/ +/** + * @fn void sli_module_reset(uint8 tf) + * @brief Sets or clears the reset pin on the wifi module + * @param[in] uint8 tf, true or false, true sets reset, false clears reset + * @param[out] none + * @return none + * @description This HAL API is used to set or clear the active-low reset pin of the Wi-Fi module. + */ +void sli_module_reset(uint8 tf) +{ + if (tf == SLI_TRUE) { + } + else { + } + + +} + +/*====================================================*/ +/** + * @fn void sli_module_power(uint8 tf) + * @brief Turns on or off the power to the wifi module + * @param[in] uint8 tf, true or false, true turns on power, false turns off power + * @param[out] none + * @return none + * @description This HAL API is used to turn on or off the power to the Wi-Fi module. + */ +void sli_module_power(uint8 tf) +{ + if (tf == SLI_TRUE) { + } + else { + } + + } + +/*===========================================================*/ +/** + * @fn int16 sli_module_power_cycle(void) + * @brief MODULE POWER ON, Power cycles the module + * @param[in] none + * @param[out] none + * @return errCode + * -1 = Error + * 0 = OK + * @description This API is used to power cycle the module. + * This API is valid only if there is a power gate, external to the module, + * which is controlling the power to the module using a GPIO signal of the MCU. + */ +int16 sli_module_power_cycle(void) +{ + return 0; +} + +/*===========================================================*/ +/** + * @fn void config_gpio_output(uint8 value) + * @brief Configures gpio pin in output mode,with a value + * @param[in] uint8 value, value to be configures + * @param[out] none + * @return errCode + * -1 = Error + * 0 = OK + * @description This API is used to configure host gpio pin in output mode. + */ +void config_gpio_output(uint8 value) +{ +#ifdef SAM9_G45 + at91_set_gpio_output(SPI_WAKEUP_REQ_GPIO, value); +#endif + +} + +/*===========================================================*/ +/** + * @fn void config_gpio_input(void) + * @brief Configures gpio pin in input mode + * @param[in] none + * @param[out] none + * @return errCode + * -1 = Error + * 0 = OK + * @description This API is used to configure host gpio pin in input mode. + */ +void config_gpio_input(void) +{ +#ifdef SAM9_G45 + at91_set_gpio_input(SPI_WAKEUP_STAT_GPIO, 0); +#endif +} + +/*===========================================================*/ +/** + * @fn uint8 get_gpio_value() + * @brief Gets the gpio value + * @param[in] none + * @param[out] none + * @return errCode + * -1 = Error + * 0 = OK + * @description This API is used to gets the host gpio value. + */ +uint8 get_gpio_value() +{ +#ifdef SAM9_G45 + return at91_get_gpio_value(SPI_WAKEUP_STAT_GPIO) ; +#else + return 0; +#endif +} + +uint8 get_spi_intr_gpio_value() +{ +#ifdef SAM9_G45 + return at91_get_gpio_value(SPI_INTR_GPIO_PIN) ; +#else + return 1; +#endif +} diff --git a/platforms/linux/Driver/sdio/src/sli_hal_mcu_sdio.c b/platforms/linux/Driver/sdio/src/sli_hal_mcu_sdio.c new file mode 100644 index 0000000..b8f9ee7 --- /dev/null +++ b/platforms/linux/Driver/sdio/src/sli_hal_mcu_sdio.c @@ -0,0 +1,1986 @@ +/***************************************************************************//** + * @file + * @brief The file contains Generic HAL changes for SDIO. + ******************************************************************************* + * # License + * Copyright 2024 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#include "sli_sdio.h" +#include "sli_nic.h" +#include +#include +#include "sli_linux.h" +#include "sli_api.h" +#include "sli_hal.h" + + +extern struct net_device *glbl_net_device; +#define align_address(a) ((unsigned long)(a) & ~0x7) + + +/**=========================================================================================================== + * @fn static int sli_cmd52writebyte(struct mmc_card *card, unsigned int address, unsigned char byte) + * @brief This function issues cmd52 byte write onto the card. + * @param Pointer to the mmc_card. + * @param address to write. + * @param data to write. + * @return the write status + */ +static int sli_cmd52writebyte(struct mmc_card *card, unsigned int address, unsigned char byte) +{ + struct mmc_command ioCmd; + unsigned long arg; + + memset(&ioCmd,0,sizeof(ioCmd)); + SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte); + ioCmd.opcode = SD_IO_RW_DIRECT; + ioCmd.arg = arg; + ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + + return mmc_wait_for_cmd(card->host, &ioCmd, 0); +}/* End */ + + +/**========================================================================================================== + * @fn static int sli_cmd52readbyte(struct mmc_card *card, unsigned int address, unsigned char *byte) + * @brief This function issues cmd52 byte read onto the card. + * @param Pointer to the mmc_card. + * @param address to read from. + * @param variable to store read value. + * @return the read status + */ +static int sli_cmd52readbyte(struct mmc_card *card, unsigned int address, unsigned char *byte) +{ + struct mmc_command ioCmd; + unsigned long arg; + int err; + + memset(&ioCmd,0,sizeof(ioCmd)); + SDIO_SET_CMD52_READ_ARG(arg,0,address); + ioCmd.opcode = SD_IO_RW_DIRECT; + ioCmd.arg = arg; + ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &ioCmd, 0); + + if ((!err) && (byte)) + { + *byte = ioCmd.resp[0] & 0xFF; + } + + return err; +}/* End */ + + + + + + + + + + + +/**=========================================================================== + * @fn int sli_issue_sdiocommand(struct sdio_func *func, uint32 opcode, uint32 arg, uint32 flags, uint32 *resp) + * @brief This function issues sdio commands. + * @param Pointer to the sdio_func. + * @param opcode value. + * @param arguments to pass. + * @param flags. + * @param pointer to store response. + * @return the command status + */ +static int sli_issue_sdiocommand(struct sdio_func *func, uint32 opcode, uint32 arg, uint32 flags, uint32 *resp) +{ + struct mmc_command cmd; + int err; + struct mmc_host *host; + + host = func->card->host; + + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = opcode; + cmd.arg = arg; + cmd.flags = flags; + err = mmc_wait_for_cmd(host, &cmd, 3); + + if ((!err) && (resp)) + { + *resp = cmd.resp[0]; + } + + return err; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn int __devinit sli_enable_interface(PVOID ptr) + * @brief This function enables the SDcard interface. + * @param Pointer to SDcard interface. + * @return On success SD_SUCCESS is returned or SD_ERROR_NODEV on error. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int __devinit sli_enable_interface(PVOID ptr) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int sli_enable_interface(PVOID ptr) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + PSDDEVICE pDevice = (PSDDEVICE)ptr; + SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData; + fData.EnableFlags = SDCONFIG_ENABLE_FUNC; + fData.TimeOut = 500; + return SDLIB_IssueConfig(pDevice, + SDCONFIG_FUNC_ENABLE_DISABLE, + &fData, + sizeof(fData)); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + int32 ret; + struct sdio_func *pfunction = (struct sdio_func *)ptr; + + /* Wait for 100 ms timeout to enable the function */ + pfunction->enable_timeout = 500; + ret = sdio_enable_func(pfunction); + return ret; +#endif +}/* End */ + + + + + + + + + + +/**=========================================================================== + * @fn VOID sli_reset_card(struct sdio_func *pfunction) + * @brief This function resets and re-initializes the card. + * @param Pointer to sdio_func. + * @VOID + */ +VOID sli_reset_card(struct sdio_func *pfunction) +{ + int ret = 0; + uint8 val =0; + uint8 status; + + //! Taking the backup values of CCCR registers + sli_cccr_register_backup(pfunction); + /* Reset RS9116 chip */ + ret = sli_cmd52writebyte(pfunction->card, SDIO_CCCR_ABORT, (1 << 3)); + /* Card will not send any response as it is getting reset immediately + * Hence expect a timeout status from host controller */ + if (ret != -ETIMEDOUT) + { + + } + /* Wait for few milli seconds to get rid of residue charges if any */ + msleep(2); + /* Initialize the SDIO card */ + do + { + int err; + struct mmc_card *card = pfunction->card; + struct mmc_host *host = card->host; + uint8 cmd52_resp; + uint32 clock; + uint32 resp, i; + uint16 rca; + int bit = fls(host->ocr_avail) - 1; + /* emulate the mmc_power_up(...) */ + host->ios.vdd = bit; + host->ios.clock = host->f_min; + host->ios.chip_select = MMC_CS_DONTCARE; + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.power_mode = MMC_POWER_UP; + host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; + host->ops->set_ios(host, &host->ios); + /* + * This delay should be sufficient to allow the power supply + * to reach the minimum voltage. + */ + msleep(2); + host->ios.clock = host->f_min; + host->ios.clock = 4000; + host->ios.power_mode = MMC_POWER_ON; + host->ops->set_ios(host, &host->ios); + /* + * This delay must be at least 74 clock sizes, or 1 ms, or the + * time required to reach a stable voltage. + */ + msleep(2); + /* Issue CMD0. Goto idle state */ + host->ios.chip_select = MMC_CS_HIGH; + host->ops->set_ios(host, &host->ios); + msleep(2); + err = sli_issue_sdiocommand(pfunction, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL); + host->ios.chip_select = MMC_CS_DONTCARE; + host->ops->set_ios(host, &host->ios); + msleep(2); + host->use_spi_crc = 0; + + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, "%s: CMD0 failed : %d \n",__func__,err); + break; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,12,74) + if (!host->ocr) +#else + if (!card->ocr) +#endif + { + /* Issue CMD5, arg = 0 */ + err = sli_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD5 failed : %d \n"),__func__,err)); + break; + } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,12,74) + err = sli_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); + host->ocr = resp; +#else + card->ocr = resp; +#endif + } + msleep(100); + /* Issue CMD5, arg = ocr. Wait till card is ready */ + { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,12,74) + err = sli_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); + msleep(100); + + err = sli_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); +#else + err = sli_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, card->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); +#endif + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD5 failed : %d \n"),__func__,err)); + break; + } + if (resp & MMC_CARD_BUSY) + { + break; + } + /* Adding some delay for the card to stable */ + msleep(10); + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,12,74) + host->ocr = resp; +#else + card->ocr = resp; +#endif + + + /* Issue CMD3, get RCA */ + err = sli_issue_sdiocommand(pfunction, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD3 failed : %d \n"),__func__,err)); + break; + } + rca = resp >> 16; + host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; + host->ops->set_ios(host, &host->ios); + + /* Issue CMD7, select card */ + err = sli_issue_sdiocommand(pfunction, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD7 failed : %d \n"),__func__,err)); + break; + } + + /* Enable high speed */ + if (card->host->caps & MMC_CAP_SD_HIGHSPEED) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: Set high speed mode\n"),__func__)); + err = sli_cmd52readbyte(card, SDIO_CCCR_SPEED, &cmd52_resp); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD52 read to CCCR speed register failed : %d \n"),__func__,err)); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,15,10) + card->state &= ~MMC_STATE_HIGHSPEED; +#endif + /* no need to break */ + } + else + { + /* CMD52 write to CCCR speed register */ + err = sli_cmd52writebyte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS)); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD52 write to CCCR speed register failed : %d \n"),__func__,err)); + break; + } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + mmc_card_set_highspeed(card); +#endif + host->ios.timing = MMC_TIMING_SD_HS; + host->ops->set_ios(host, &host->ios); + } + } + /* Set clock */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) + if (mmc_card_highspeed(card)) +#else + if (mmc_card_hs(card)) +#endif + { + /*!setting the clock speed */ + clock = 10000000; + } + else + { + clock = card->cis.max_dtr; + } + + if (clock > host->f_max) + { + clock = host->f_max; + } + host->ios.clock = clock; + host->ops->set_ios(host, &host->ios); + + if (card->host->caps & MMC_CAP_4_BIT_DATA) + { + /* CMD52: Set bus width & disable card detect resistor */ + err = sli_cmd52writebyte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT); + if (err) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("%s: CMD52 to set bus mode failed : %d \n"),__func__,err)); + break; + } + host->ios.bus_width = MMC_BUS_WIDTH_4; + host->ops->set_ios(host, &host->ios); + } + } while (0); + + /* Writing back the CCCR Register values after chip got reset */ + sli_write_cccr_registers(pfunction); + return; +}/* End */ + + + + + + + + + + +/**=========================================================================== + * @fn int sli_disable_interface(void *ptr) + * @brief This function disables the card interface. + * @param Pointer to SDcard interface. + * @return On success SD_SUCCESS is returned or SD_ERROR_NODEV on error. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int __devexit sli_disable_interface(void *ptr) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int sli_disable_interface(void *ptr) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + PSDDEVICE pDevice = (PSDDEVICE)ptr; + SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData; + + fData.EnableFlags = SDCONFIG_DISABLE_FUNC; + fData.TimeOut = 500; + return SDLIB_IssueConfig(pDevice, + SDCONFIG_FUNC_ENABLE_DISABLE, + &fData, + sizeof(fData)); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + struct sdio_func *pfunction = (struct sdio_func*)ptr; + int ret = 0; + + ret = sdio_disable_func(pfunction); + if (ret) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, (TEXT("Failed to diable sdio func : %d \n"),ret)); + } + return ret; +#endif +}/* End */ + + + + + + + + + +/**======================================================================================================== + * @fn int32 sli_request_interrupt_handler(void *ptr,sdio_irq_handler_t interrupt_handler, PVOID pContext) + * @brief This function registers the client driver's interrupt handler + * with the bus driver. + * @param Pointer to SD card interface. + * @param Pointer to interrupt handler. + * @return VOID. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int32 __devinit sli_request_interrupt_handler(void *ptr, + sdio_irq_handler_t interrupt_handler, + PVOID pContext + ) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int32 sli_request_interrupt_handler(void *ptr, + sdio_irq_handler_t interrupt_handler, + PVOID pContext + ) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + PSDDEVICE pDevice = (PSDDEVICE)ptr; + int32 status; + + SDDEVICE_SET_IRQ_HANDLER(pDevice, interrupt_handler, pContext); + SLI_DEBUG(SLI_ZONE_INIT, + (TEXT("%s: Unmasking IRQ \n"), __func__)); + status = SDLIB_IssueConfig(pDevice, SDCONFIG_FUNC_UNMASK_IRQ, NULL, 0); + if (!SDIO_SUCCESS((status))) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT( "%s: failed to unmask IRQ %d\n"), __func__, status)); + } +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + struct sdio_func *pfunction = (struct sdio_func*)ptr; + int32 status; + status = sdio_claim_irq(pfunction,(sdio_irq_handler_t *)interrupt_handler); + if (status != 0) + { + printk(" failed to unmask IRQ \n"); + } +#endif + return status; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn VOID sli_sdio_interrupt_handler(struct sdio_func *function) + * @brief This function registers the sdio driver's interrupt handler + * @param Pointer to interrupt handler. + * @return VOID. + */ + +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_interrupt_handler(PVOID pContext) +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) +VOID sli_sdio_interrupt_handler(struct sdio_func *function) +#endif +{ + + PSLI_ADAPTER adapter ; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + adapter = (PSLI_ADAPTER)pContext; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + adapter = sli_getcontext(function); +#endif +#if KERNEL_VERSION_GREATER_THAN_2_6_(26) + adapter->irq_registered = current; +#endif + queue_work(adapter->workqueue, &adapter->handler); +#if KERNEL_VERSION_GREATER_THAN_2_6_(26) + adapter->irq_registered = NULL; +#endif + return; +}/* End */ + + + + + + + + + + + +/**=========================================================================== + * @fn int16 sli_init_host_interface(PSLI_ADAPTER Adapter) + * @brief This function does the actual initialization of SDBUS slave registers. + * @param Pointer to the driver adapter structure. + * @return on success 0 and on failure -1. + */ +int16 sli_init_host_interface(PSLI_ADAPTER Adapter) +{ + UINT8 byte; + int8 status; + SLI_DEBUG(SLI_ZONE_INIT,(TEXT("+ ganges_init_sdio_slave_regs\n"))); + + /* initialize Next read delay */ + if (Adapter->next_read_delay) + { + SLI_DEBUG(SLI_ZONE_INIT, + (TEXT("init_sdio_slave_regs: Initialzing SDIO_NXT_RD_DELAY2\n"))); + byte = Adapter->next_read_delay; + + status = write_register(Adapter, + 0, + SDIO_NXT_RD_DELAY2, + &byte); + if (status) + { + SLI_DEBUG(SLI_ZONE_INIT, + (TEXT("init_sdio_slave_regs: fail to write SDIO_NXT_RD_DELAY2\n"))); + return -1; + } + } + + if (Adapter->sdio_high_speed_enable) + { +#define SDIO_REG_HIGH_SPEED 0x13 + SLI_DEBUG(SLI_ZONE_INIT, + (TEXT("init_sdio_slave_regs: Enabling SDIO High speed\n"))); + byte = 0x3; + + /* Enabling SDIO high speed */ + status =write_register(Adapter, + 0, + SDIO_REG_HIGH_SPEED, + &byte); + if (status) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("init_sdio_slave_regs: fail to enable SDIO high speed\n"))); + return -1; + } + + } + SLI_DEBUG(SLI_ZONE_INIT,(TEXT("- ganges_init_sdio_slave_regs\n"))); + return 0; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn VOID sli_sdio_disconnect ( struct sdio_func *pfunction) + * @brief This function performs the reverse of the probe function.. + * @param Pointer to sdio_func structure. + * @param Pointer to sdio_device_id structure. + * @return VOID. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID __devexit sli_sdio_disconnect ( PSDFUNCTION pfunction, PSDDEVICE pDevice) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_disconnect ( struct sdio_func *pfunction) +#endif +{ + int status; + uint32 ii; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + struct net_device *dev = pfunction->pContext; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + struct net_device *dev = sli_getcontext(pfunction); +#endif + PSLI_ADAPTER adapter = sli_getpriv(glbl_net_device); + adapter->FSM_STATE = 0; + SLI_DEBUG(SLI_ZONE_INFO,"Killing thread \n"); + adapter->halt_flag = 1; + sli_sdio_claim_host(pfunction); + if(adapter->irq_registered != NULL) + { + sli_sdio_release_irq(pfunction); + } + sdio_disable_func(pfunction); + sli_sdio_release_host(pfunction); + adapter->stop_card_writing = 2; + + sli_Kill_Thread(adapter); + sli_Delete_Event(&adapter->PwrSaveEvent); + sli_Delete_Event(&adapter->Event); + + + SLI_DEBUG(SLI_ZONE_INFO,"Purge queue \n"); + for (ii = 0; ii < 4; ii++) + { + sli_queue_purge(&adapter->list[ii]); + } + sli_sdio_claim_host(pfunction); + /* Resetting the sdio card to make it ready for the next run */ + sli_reset_card(pfunction); + /* Release host */ + sli_sdio_release_host(pfunction); + unregister_netdev(adapter->net_device0); + free_netdev(adapter->net_device0); + return; +}/* End */ + + + + + + + + + + +/**=========================================================================== + * @fn int __devinit sli_setblocklength(PSLI_ADAPTER adapter, uint32 length) + * @brief This function sets the host block length. + * @param Pointer to Driver adapter structure. + * @param Block lenght to be set. + * @return On success SD_SUCCESS is returned or negative error code on failure. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int __devinit sli_setblocklength(PSLI_ADAPTER adapter, uint32 length) +{ + PSDDEVICE pDevice = adapter->pDevice; + int32 blklength; + + SLI_DEBUG(SLI_ZONE_INIT,(TEXT( "%s: Setting the block length\n"), __func__)); + + SDLIB_SetFunctionBlockSize(pDevice,256); + blklength = SDDEVICE_GET_OPER_BLOCK_LEN(pDevice); + + SLI_DEBUG(SLI_ZONE_INFO,(TEXT( "%s: Operational blk length is %d\n", __func__), + blklength)); + return int_SUCCESS; +} +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int sli_setblocklength(PSLI_ADAPTER adapter, uint32 length) +{ + int32 status; + status = sdio_set_block_size(adapter->pfunction, length); + adapter->pfunction->max_blksize = 256; + return status; +} /* End */ +#endif + + + + + + + + +/**=========================================================================== + * @fn VOID sli_sdio_release_host(PSDFUNCTION pFunction) + * @brief This function releases a bus after a certain SDIO function. + * @param Pointer to sdio_func structure. + * @return VOID. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_release_host(PSDFUNCTION pFunction) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_sdio_release_host(struct sdio_func *pfunction) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + /*No code here*/ +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + sdio_release_host(pfunction); +#endif + return; +}/* End */ + + + + + + + + +/**=========================================================================== + * @fn int VOID sli_setcontext(PSDFUNCTION pFunction, void *adapter) + * @brief This function sets the private data of the card function as + * our n/w interface. + * @param Pointer to sdio_func structure. + * @param Pointer to our network interface + * @return VOID. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_setcontext(PSDFUNCTION pFunction, void *adapter) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +VOID sli_setcontext(struct sdio_func *pfunction, void *adapter) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + /*No code for 2.6.18*/ +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + sdio_set_drvdata(pfunction, adapter); +#endif + return; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn void* sli_getcontext(struct sdio_func *pfunction) + * @brief This function gets the private data of the cards function. + * @param Pointer to sdio_func structure. + * @return Pointer to a our network interface. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +struct net_device * sli_getcontext(PSDFUNCTION pfunction) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +void* sli_getcontext(struct sdio_func *pfunction) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return NULL; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + void *dev; + dev = sdio_get_drvdata(pfunction); + return dev; +#endif +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn int32 sli_sdio_release_irq(PSDFUNCTION pFunction) + * @brief This function releases the irq registered with the card. + * @param Pointer to sdio_func structure. + * @return 0 on sucess else a negative number with specific failure. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +int32 sli_sdio_release_irq(PSDFUNCTION pFunction) +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) +int32 sli_sdio_release_irq(struct sdio_func *pfunction) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return 0; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + return sdio_release_irq(pfunction); +#endif +}/* End */ + + + + + + + +/**=========================================================================== + * @fn int32 deregister_sdio_irq(PSLI_ADAPTER adapter) + * @brief This function deregisters the irq with the card. + * @param Pointer to sdio_func structure. + * @return 0 on sucess else a negative number with specific failure. + */ +int32 deregister_sdio_irq(PSLI_ADAPTER adapter) +{ +#if KERNEL_VERSION_GREATER_THAN_2_6_(26) + int32 s; + + sli_sdio_claim_host(adapter->pfunction); + s = sli_sdio_release_irq(adapter->pfunction); + if (s) { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT("%s: Unable to Deregister irq"), __func__)); + } + sli_sdio_release_host(adapter->pfunction); + + return s; +#endif +}/* End */ + + + + + + + + +/**=========================================================================== + * @fn int sli_setupcard(PSLI_ADAPTER adapter) + * @brief This function queries and sets the card's features. + * @param Pointer to Driver adapter structure. + * @return On success int_SUCCESS else int_FAILURE is returned. + */ +int sli_setupcard(PSLI_ADAPTER adapter) +{ + int Status = 0; + + /* Setting sdio clock frequency to 50MHz */ +#ifdef FPGA_VALIDATION + sli_setclock(adapter,6000); +#else + sli_setclock(adapter,30000); +#endif + if(Status!=0) + { + SLI_DEBUG(SLI_ZONE_INFO, + (TEXT("%s: Unsuccessful at setting clk"), __func__)); + return Status; + } +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + adapter->CardCapability = SDDEVICE_GET_SDIO_CARD_CAPS(adapter->pDevice); + SLI_DEBUG(SLI_ZONE_INFO,(TEXT("%s: Card Cap: %0x\n"), __func__, + adapter->CardCapability)); + SLI_DEBUG(SLI_ZONE_INFO,(TEXT("%s: Common CIS Ptr: %0x\n"), __func__, + SDDEVICE_GET_SDIO_COMMON_CISPTR(adapter->pDevice))); + SLI_DEBUG(SLI_ZONE_INFO,(TEXT("%s: Funcn CIS Ptr: %0x\n"), __func__, + SDDEVICE_GET_SDIO_FUNC_CISPTR(adapter->pDevice))); + SLI_DEBUG(SLI_ZONE_INFO,(TEXT("%s: CSA Ptr: %0x\n"), __func__, + SDDEVICE_GET_SDIO_FUNC_CSAPTR(adapter->pDevice))); +#endif + adapter->TransmitBlockSize = 256; + adapter->ReceiveBlockSize = 256; + Status = sli_setblocklength(adapter, adapter->TransmitBlockSize); + + if(Status != 0) + { + SLI_DEBUG(SLI_ZONE_INFO, + (TEXT("%s: Unable to set block length\n"), __func__)); + return Status; + } + + return Status; +}/* End */ + + + + + +/**=========================================================================== + * @fn int sli_setclock(PSLI_ADAPTER adapter, uint32 Freq) + * @brief This function sets the clock frequency + * @param adapter Pointer To sli_ADAPTER sturct + * @param Frequency Clock frequency + */ +int sli_setclock(PSLI_ADAPTER adapter, uint32 Freq) +{ +#if KERNEL_VERSION_BTWN_2_6_(18,22) + SDCONFIG_BUS_MODE_DATA busSettings; +#ifdef SLI_WITHOUT_HARDWARE + { + return int_SUCCESS; + } +#endif + adapter->os_intf_ops->sli_memset(&busSettings, 0, sizeof(SDCONFIG_BUS_MODE_DATA)); + busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(adapter->pDevice); + + SLI_DEBUG(SLI_ZONE_INIT, + (TEXT("%s: Forcing SDIO clock to %dMHz\n"), __func__, + busSettings.ClockRate)); + + busSettings.ClockRate = Freq * 1000; + return SDLIB_IssueConfig(adapter->pDevice, SDCONFIG_BUS_MODE_CTRL, + &busSettings, sizeof(SDCONFIG_BUS_MODE_DATA)); +#else + uint32 clock; + struct mmc_host *host = adapter->pfunction->card->host; + + clock = Freq * 1000; + if (clock > host->f_max) + { + clock = host->f_max; + } + printk("clock =%ld\r\n", clock); + host->ios.clock = clock; + host->ops->set_ios(host, &host->ios); + return 0; +#endif +}/* End */ + + + + + +/**=========================================================================== + * @fn int read_register(PSLI_ADAPTER adapter, uint32 Addr,uint8 fun_num,uint8 *data) + * @brief This function reads one byte of information from a register. + * @param Pointer to Driver adapter structure. + * @param Function Number. + * @param Address of the register. + * @param Pointer to the data that stores the data read. + * @return On success int_SUCCESS else int_FAILURE. + */ +int read_register(PSLI_ADAPTER adapter, uint32 Addr,uint8 fun_num,uint8 *data) +{ + + int32 status; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return SDLIB_IssueCMD52(adapter->pDevice, + fun_num, + Addr, + data, + 1, + SLI_FALSE + ); + +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + + if(sli_likely(adapter->irq_registered!= current)) + { + sli_sdio_claim_host(adapter->pfunction); + } + if (fun_num == 0) + { + *data = sdio_f0_readb(adapter->pfunction, Addr, &status); + } + else + { + *data = sdio_readb(adapter->pfunction, Addr, &status); + } /* End if */ + + if (sli_likely(adapter->irq_registered != current)) + { + sli_sdio_release_host(adapter->pfunction); + } + if (status) + { + return -1; + } + else + { + return 0; + }/* End if */ +#endif +}/* End */ + + + + + + +/**=========================================================================== + * @fn int write_register(PSLI_ADAPTER adapter,uint8 reg_dmn,uint32 Addr,uint8 *data) + * @brief This function writes one byte of information into a register. + * @param Pointer to Driver adapter structure. + * @param Function Number. + * @param Address of the register. + * @param Pointer to the data tha has to be written. + * @return On success int_SUCCESS else int_FAILURE. + */ +int write_register(PSLI_ADAPTER adapter,uint8 reg_dmn,uint32 Addr,uint8 *data) +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return SDLIB_IssueCMD52(adapter->pDevice, + reg_dmn, + Addr, + data, + 1, + SLI_TRUE + ); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + int status=0; + + if (sli_likely(adapter->irq_registered != current)) + { + sli_sdio_claim_host(adapter->pfunction); + } + + if (reg_dmn == 0) + { + + sdio_f0_writeb(adapter->pfunction, *data, Addr, &status); + } + else + { + sdio_writeb(adapter->pfunction, *data, Addr, &status); + } /* End if */ + if (sli_likely(adapter->irq_registered != current)) + { + sli_sdio_release_host(adapter->pfunction); + } + if (status) + { + return -1; + } + else + { + return 0; + } /* End if */ +#endif +}/* End */ + + + + + + + +/**========================================================================================== + * @fn int read_register_multiple(PSLI_ADAPTER adapter,uint32 Addr,uint32 Count,uint8 *data) + * @brief This function read multiple bytes of information from the SD card. + * @param Pointer to Driver adapter structure. + * @param Function Number. + * @param Address of the register. + * @param Length of the data to be read. + * @param Pointer to the read data. + * @return On success int_SUCCESS else int_FAILURE. + */ +int read_register_multiple(PSLI_ADAPTER adapter, + + uint32 Addr, + uint32 Count, + uint8 *data ) +{ + uint32 status; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + PSDREQUEST pReq = NULL; + PSDDEVICE pDevice ; + uint32 num_blocks = Count / 256; +#endif + uint32 ii; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + pDevice = adapter->pDevice; + + if (Count % 256 != 0) + { + ++num_blocks; + } + + pReq = SDDeviceAllocRequest(pDevice); + if (pReq == NULL) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Request Allocation Failed\n"), __func__)); + return int_NO_RESOURCES; + } + + /* If Length Less Than 256 Then Byte Mode */ + if (Count < 256) + { + SDIO_SET_CMD53_ARG(pReq->Argument, + CMD53_READ, + 1, + CMD53_BYTE_BASIS, + CMD53_FIXED_ADDRESS, + Addr, + Count); + pReq->pDataBuffer = data; + pReq->Command = CMD53; + pReq->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS; + pReq->BlockLen = Count; + pReq->BlockCount = 1; + } + else /* Block Mode */ + { + SDIO_SET_CMD53_ARG(pReq->Argument, + CMD53_READ, + 1, + CMD53_BLOCK_BASIS, + CMD53_FIXED_ADDRESS, + Addr, + num_blocks); + pReq->pDataBuffer = data; + pReq->Command = CMD53; + pReq->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS; + pReq->BlockLen = adapter->ReceiveBlockSize; + pReq->BlockCount = num_blocks; + } /* End if */ + status = SDDEVICE_CALL_REQUEST_FUNC(pDevice, pReq); + if (!status) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Synch Cmd53 read failed\n"), __func__)); + } + else + { + /* + * SLI_DEBUG(SLI_ZONE_ERROR, + * "sli_read_register_multiple: Synch Cmd53 read Success\n"); + * */ + } /* End if */ + + SDDeviceFreeRequest(pDevice,pReq); + return status; +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + + if (sli_likely(adapter->irq_registered != current)) + { + SLI_DEBUG(SLI_ZONE_INFO, + (TEXT("%s: Calling sdio_claim_host here\n"), __func__)); + sli_sdio_claim_host(adapter->pfunction); + } + + status = sdio_readsb(adapter->pfunction, data, Addr, Count); + if (sli_likely(adapter->irq_registered != current)) + { + sli_sdio_release_host(adapter->pfunction); + } + if (status != 0) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Synch Cmd53 read failed\n"), __func__)); + } + return status; +#endif + +}/* End */ + + + + + + +/**============================================================================================ + * @fn int write_register_multiple(PSLI_ADAPTER adapter,uint32 Addr,uint8 *data,uint32 Count) + * @brief This function writes multiple bytes of information to the SD card. + * @param Pointer to Driver adapter structure. + * @param Function Number. + * @param Address of the register. + * @param Length of the data. + * @param Pointer to the data that has to be written. + * @return On success int_SUCCESS else int_FAILURE. + */ +int write_register_multiple(PSLI_ADAPTER adapter, + uint32 Addr, + uint8 *data, + uint32 Count + ) +{ + int32 status = 0; +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + PSDDEVICE pDevice; + PSDREQUEST pReq = NULL; + uint32 num_blocks = Count / 256; +#endif +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + pDevice = adapter->pDevice; + if (Count % 256 != 0) + { + ++num_blocks; + } + + pReq = SDDeviceAllocRequest(pDevice); + if (pReq == NULL) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Resource Allocation Failed\n"), __func__)); + return int_NO_RESOURCES; + } + + /* If Length Less Than 256 Then Byte Mode */ + if (Count < 256) + { + SDIO_SET_CMD53_ARG(pReq->Argument, + CMD53_WRITE, + 1, + CMD53_BYTE_BASIS, + CMD53_FIXED_ADDRESS, + Addr, + Count); + pReq->pDataBuffer = &data[0]; + pReq->Command = CMD53; + pReq->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | + SDREQ_FLAGS_DATA_TRANS | + SDREQ_FLAGS_DATA_WRITE; + pReq->BlockCount = 1; + pReq->BlockLen = Count; + + } + else /* Block Mode */ + { + SDIO_SET_CMD53_ARG(pReq->Argument, + CMD53_WRITE, + 1, + CMD53_BLOCK_BASIS, + CMD53_FIXED_ADDRESS, + Addr, + num_blocks); + pReq->pDataBuffer = &data[0]; + pReq->Command = CMD53; + pReq->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | + SDREQ_FLAGS_DATA_TRANS | + SDREQ_FLAGS_DATA_WRITE; + pReq->BlockCount = num_blocks; + pReq->BlockLen = adapter->TransmitBlockSize; + } /* End if i */ + do + { + status = SDDEVICE_CALL_REQUEST_FUNC(pDevice, pReq); + if (!(status)) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Synch Cmd53 write failed %d\n"), __func__, + status)); + } + } while (!(status)); + SDDeviceFreeRequest(pDevice,pReq); + + return status; + +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + if(0) + { + return -1; + } + if(sli_likely(adapter->irq_registered!= current)) + { + sli_sdio_claim_host(adapter->pfunction); + } +// printk("In %s func Addr = %x Count = %d \n ",__func__,Addr,Count); + status = sdio_writesb(adapter->pfunction,Addr,data,Count); + if(status !=0) + { + } + + if(sli_likely(adapter->irq_registered!= current)) + { + sli_sdio_release_host(adapter->pfunction); + } + if (status != 0) + { + printk("%s: Synch Cmd53 write failed %d\n", __func__, status); + } + return status; +#endif +} /* End */ + + + + + + +/**=========================================================================== + * @fn int sli_open_sdbus_handle(PSLI_ADAPTER adapter) + * @brief Dummy for linux + * @Params Pointer to Driver adapter structure. + * Return None + */ + int sli_open_sdbus_handle(PSLI_ADAPTER adapter) +{ + /**Dummy for Linux*/ + return 0; +} /* End */ + + + + + +/**=========================================================================== + * @fn int remove() + * @brief Dummy for linux sdio + * @Params None + * @Return Value None + */ +int remove() +{ + /**Dummy for Linux*/ + return 0; +} /* End */ + + + + + +/**=========================================================================== + * @fn void claim_device(PSLI_ADAPTER adapter) + * @brief This function claims the device. + * @param Pointer to driver adapter structure. + * @return VOID. + */ +void claim_device(PSLI_ADAPTER adapter) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + struct sdio_func *pfunc = adapter->pfunction; + sdio_claim_host(pfunc); + adapter->irq_registered = current; +#endif +} /* End */ + + + + + + + +/**=========================================================================== + * @fn void release_device(PSLI_ADAPTER adapter) + * @brief This function releases the device. + * @param Pointer to driver adapter structure. + * @return VOID. + */ +void release_device(PSLI_ADAPTER adapter) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) + struct sdio_func *pfunc = adapter->pfunction; + adapter->irq_registered = NULL; + sdio_release_host(pfunc); +#endif +} /* End */ + + + + + + + + + + + +/**=========================================================================== + * @fn int32 sli_sdio_device_interrupt_status(PSLI_ADAPTER Adapter,uint8 fun_num,uint32 address,uint8 *data) + * @brief This function registers the device interrupt status. + * @param Pointer to Driver adapter structure. + * @param Function Number. + * @param Address of the register. + * @param Pointer to the data that stores the data read. + * @return On success int_SUCCESS else int_FAILURE. + */ +int32 sli_sdio_device_interrupt_status(PSLI_ADAPTER Adapter,uint8 fun_num,uint32 address,uint8 *data) +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + return SDLIB_IssueCMD52(Adapter->pDevice, + fun_num, + address, + data, + 1, + TRUE + ); +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + int status=0; + if (sli_likely(Adapter->irq_registered != current)) + { + sli_sdio_claim_host(Adapter->pfunction); + } + + if (fun_num == 0) + { + *data = sdio_f0_readb(Adapter->pfunction, + address, + &status); + } + else + { + *data = sdio_readb(Adapter->pfunction, + address, + &status); + } /* End if */ + if (likely(Adapter->irq_registered != current)) + { + sdio_release_host(Adapter->pfunction); + } + if (status) + { + return -1; + } + else + { + return 0; + } /* End if */ +#endif +} /* End */ + + + + + + + +/**=========================================================================== + * @fn VOID sli_sdio_claim_host(struct sdio_func *pfunction) + * @brief This function exclusively claims a bus before a certain SDIO function. + * @param Pointer to sdio_func structure. + * @return VOID. + */ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) +VOID sli_sdio_claim_host(PSDFUNCTION pFunction) +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) +VOID sli_sdio_claim_host(struct sdio_func *pfunction) +#endif +{ +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + /*No code here*/ +#elif KERNEL_VERSION_GREATER_THAN_2_6_(26) + sdio_claim_host(pfunction); +#endif + return; +}/* End */ + + + + + + + + +/**=========================================================================== + * @fn int32 sli_sdio_frame_read(PSLI_ADAPTER Adapter) + * @brief This function read frames from the SD card. + * @param Pointer to driver adapter structure. + * @param Pointer to received packet. + * @param Pointer to length of the received packet. + * @return 0 if success else -1. + */ +int32 sli_sdio_frame_read(PSLI_ADAPTER Adapter) +{ + int32 status; + uint32 q_no; + uint32 pktLen; + uint16 type; + uint8 regval; + uint8 num_blocks; + uint16 rcv_pkt_len; + status = read_register(Adapter,SDIO_RX_NUM_BLOCKS_REG,0,®val); + if(status != 0) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG,"\nReading number of blocks failed"); + return -1; + } + num_blocks = regval & 0x1F; + if(num_blocks == 0) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG,"\n number of blocks received is zero"); + return -1; + } + rcv_pkt_len = 256 * num_blocks; + status = host_intf_read_pkt(Adapter,(uint8 *)Adapter->DataRcvPacket,rcv_pkt_len); + if(status != 0 ) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG,"\n EEROR in reading packet"); + return -1; + + } + return 0; +}/* End */ + + + + + + + +/**=========================================================================== + * @fn int16 sdio_read_buffer_full() + * @brief This function checks the buffer full conditions. + * @param None. + * @return 0 if success else -1. + */ +int16 sdio_read_buffer_full() +{ + uint32 READ_BUFFER_ADDRESS = 0; + uint8 temp; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + read_register(Adapter,SDIO_FUN1_INT_REG,0,&temp); + if(temp & SDIO_BUFFER_FULL) + { + return -1; + } + return 0; +}/* End */ + + + + + + + +/**=========================================================================== + * @fn INT32 ack_interrupt(PSLI_ADAPTER Adapter,uint8 INT_BIT) + * @brief This function acks the interrupt received. + * @param Pointer to the driver adapter structure. + * @param Interrupt bit to write into register. + * @return VOID. + */ +INT32 ack_interrupt(PSLI_ADAPTER Adapter,uint8 INT_BIT) +{ + int32 status; + uint8 reg_dmn =1; + status = write_register(Adapter,reg_dmn,SDIO_FUN1_INTR_CLR_REG|SD_REQUEST_MASTER,&INT_BIT); + if(status !=0) + { + return status; + } + return status; +}/* End */ + + + + + + + + + + + +/**=========================================================================== + * @fn INT16 sli_execute_cmd(UINT8 *descparam, UINT8 *payload, UINT16 payload_len) + * @brief Common function for all the commands. + * @param uint8 *descparam, pointer to the frame descriptor parameter structure + * @param uint8 *payload, pointer to the command payload parameter structure + * @param uint16 payload_len, size of the payload for the command + * @return errCode + * 0 = SUCCESS + */ +INT16 sli_execute_cmd(UINT8 *descparam, UINT8 *payload, UINT16 payload_len) +{ + UINT16 status; + UINT8 *data_ptr =NULL,*data_ptr_act =NULL; + UINT8 transfer[4100]; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + uint32 i ; + + data_ptr = &transfer[0]; + sli_memcpy(data_ptr,descparam,7); + if (payload_len) + { + memcpy((data_ptr+7),payload, payload_len); + } + while(sdio_read_buffer_full()); + + status= host_intf_write_pkt(Adapter,data_ptr ,payload_len+7,(data_ptr[1] >> 4)); + if(status != 0) + { + status = -1; + } + + + if(data_ptr[2]== RSI_RSP_SOFT_RESET) + { + } + return status; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn int host_intf_read_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len) + * @brief This function reads the packet from the SD card. + * @param Pointer to the driver's private data structure + * @param Pointer to the packet data read from the the device + * @param Length of the data to be read from the device. + * @return 0 if success else a negative number. + */ +int host_intf_read_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len) +{ + int Status = 0; + if (!Len) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG, + (TEXT( "%s: Pkt size is zero\n"),__func__)); + return Status; + } + /*Reading the actual data*/ + Status = read_register_multiple(adapter,Len,Len,(uint8 *)pkt); + + if (Status != 0) + { + SLI_DEBUG(SLI_ZONE_SDIO_DBG,(TEXT("%s: Failed to read frame from the card: %d\n"),__func__, + Status)); + return Status; + } + return Status; +}/* End */ + + +/**=========================================================================== + * @fn int host_intf_write_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len, uint8 queueno) + * @brief This function writes the packet to the device. + * @param Pointer to the driver's private data structure + * @param Pointer to the data to be written on to the device + * @param Length of the data to be written on to the device. + * @return 0 if success else a negative number. + */ +int host_intf_write_pkt(PSLI_ADAPTER adapter,uint8 *pkt,uint32 Len, uint8 queueno) +{ + uint32 block_size = adapter->TransmitBlockSize; + uint32 num_blocks,Address,Length; +#ifndef RSI_SDIO_MULTI_BLOCK_SUPPORT + uint32 ii; +#endif + int32 status = 0; + + if( !Len && (queueno == WLAN_TX_D_Q )) + { + return -1; + } /* End if */ + num_blocks = Len/block_size; + if (Len % block_size) + { + num_blocks++; + } + + if (num_blocks == 0) + { + num_blocks = 1; + } + + Address = num_blocks * block_size | (queueno << 12); + Length = num_blocks * block_size; + +#ifdef RSI_SDIO_MULTI_BLOCK_SUPPORT + status = write_register_multiple(adapter, + Address, + (uint8 *)pkt, + Length); + if (status != 0) + { + printk(" Unable to write onto the card \n"); + return status; + } /* End if */ +#else + /* Non multi block read */ + for(ii = 0; ii < num_blocks; ii++) + { + if(ii==0) + { + status = write_register_multiple(adapter, + Address, + (uint8 *)(pkt + (ii*block_size)), + block_size); + } + else + { + status = write_register_multiple(adapter, + (num_blocks*block_size), + (uint8 *)(pkt + (ii*block_size)), + block_size); + } /* End if */ + if(status != 0) + { + + return status; + } /* End if */ + } /* End for loop */ +#endif + + return status; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn int16 sli_sdio_master_access_msword(uint16 ms_word) + * @brief This function set the AHB master access MS word in the SDIO slave registers. + * @param Pointer to the driver adapter structure. + * @param ms word need to be initialized. + * @return 0 if success else a negative number. + */ +int16 sli_sdio_master_access_msword(uint16 ms_word) +{ + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + unsigned char byte; + uint8 reg_dmn; + int32 status=SLI_STATUS_SUCCESS; + reg_dmn = 0; //TA domain + /* Initialize master address MS word register with given value*/ + byte=(unsigned char*)(ms_word&0x00FF); + status = write_register(Adapter, reg_dmn ,SDIO_MASTER_ACCESS_MSBYTE, &byte); + if(status != SLI_STATUS_SUCCESS) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: fail to access MASTER_ACCESS_MSBYTE\n"), __func__)); + return -1; + } + byte=(unsigned char)(ms_word >>8); + status =write_register(Adapter, reg_dmn ,SDIO_MASTER_ACCESS_LSBYTE, &byte); + if(status != SLI_STATUS_SUCCESS) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: fail to access MASTER_ACCESS_LSBYTE\n"), __func__)); + return -1; + } + return SLI_STATUS_SUCCESS; +}/* End */ + + + + + + + + + +/**=========================================================================== + * @fn int16 sli_mem_rd(uint32 reg_address,uint16 len,uint32 *value) + * @brief Reads a register specified by reg_address & stores in value + * @param uint32 reg_address: Address of the register to read + * @param uint16 len: Number of bytes to read. (def: 2 since we have 16 bit regs) + * @param uint16* value: Variable in which the read value is stored + * @return 0 if success else a negative number. + */ +int16 sli_mem_rd(uint32 reg_address,uint16 len,uint32 *value) +{ + uint32 *data = NULL; + uint16 ms_addr = 0; + uint32 align[2] = {}; + uint32 addr_on_bus; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + data = (uint32 *)align_address(&align[1]); + ms_addr = (reg_address >> 16); + if (sli_sdio_master_access_msword(ms_addr)!= SLI_STATUS_SUCCESS) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Unable to set ms word to common reg\n"), __func__)); + return -1; + } + reg_address = reg_address & 0xFFFF; + + addr_on_bus = (reg_address & 0xFF000000); + if ((addr_on_bus == (FLASH_SIZE_ADDR & 0xFF000000)) || /* This is for flash access*/ + (addr_on_bus == 0x0)) {/* This check is for Internal RAM access */ + addr_on_bus = (reg_address & ~(0x3)); + } + else { + /* This is for accessing peripherals on APB(AMBA- Peripheral Bus) bus of the device */ + addr_on_bus = reg_address; + } + /* Bringing TA out of reset */ + if(read_register_multiple( Adapter,addr_on_bus | SD_REQUEST_MASTER,4, (uint8 *)data )!= SLI_STATUS_SUCCESS) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: AHB register read failed\n"), __func__)); + return -1; + + } + if(len == 2) { + if((reg_address & 0x3) == 0) { + *value = *data; + } + else { + *value = ((*data >> 16)); + } + *value = (*value & 0xFFFF); + } + else if(len == 1) { + if((reg_address & 0x3) == 0) { + *value = *data; + } else if((reg_address & 0x3) == 1) { + *value = (*data >> 8); + } else if((reg_address & 0x3) == 2) { + *value = (*data >> 16); + } else { + *value = (*data >> 24); + } + *value = (*value & 0xFF); + } + else { /*len is 4 */ + *value = *data; + } + + return SLI_STATUS_SUCCESS; +}/* End */ + + + + + + + + +/**=========================================================================== + * @fn int16 sli_mem_wr(uint32 reg_address,uint16 len,uint32 *value) + * @brief Writes the given data to the specified register address in the WiFi Module + * @param uint32 reg_address Address of the register to read + * @param uint16 len Number of bytes to read. (def: 2 since we have 16 bit regs) + * @param uint16* value Variable in which the read value is stored + * @return 0 if success else a negative number. + * + */ +int16 sli_mem_wr(uint32 reg_address,uint16 len,uint32 *value) +{ + uint16 ms_addr = 0; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + unsigned long data1[2]; + unsigned long *data_alligned; + data_alligned =(unsigned long *)align_address(&data1[1]); + if(len == 2) { + *data_alligned = ((*value << 16) |(*value & 0xFFFF)); + } + else if(len == 1) { + uint32 temp_data; + temp_data = (*value & 0xFF); + *data_alligned = ((temp_data << 24) | (temp_data << 16) | (temp_data << 8) | (temp_data)); + } + else { + *data_alligned = *value; + } + + len = 4; + + ms_addr = (reg_address >> 16); + if(sli_sdio_master_access_msword(ms_addr)!= SLI_STATUS_SUCCESS) + + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Unable to set ms word to common reg\n"), __func__)); + return -1; + } + reg_address = reg_address & 0xFFFF; + if(write_register_multiple(Adapter, + reg_address | + SD_REQUEST_MASTER, + (uint8 *)data_alligned, + len)!= SLI_STATUS_SUCCESS) + { + SLI_DEBUG(SLI_ZONE_ERROR, + (TEXT("%s: Unable to do AHB reg write\n"), __func__)); + return -1; + } + return SLI_STATUS_SUCCESS; +}/* End */ + + + + + + + + + + + + +/**=========================================================================== + * @fn VOID sli_write_cccr_registers(struct sdio_func *pfunction) + * @brief This function takes the backup of the CCCR registers. + * @param Pointer to sdio_func. + * @return VOID + */ +VOID sli_cccr_register_backup(struct sdio_func *pfunction) +{ + int ret = 0; + uint8 val =0; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); + Adapter->io_enable =read_register(Adapter, SDIO_CCCR_IOEx,0, &val); + Adapter->io_ready =read_register(Adapter, SDIO_CCCR_IORx,0, &val); + Adapter->int_enable =read_register(Adapter, SDIO_CCCR_IENx,0, &val); + Adapter->bus_interface_control =read_register(Adapter, SDIO_CCCR_IF,0, &val); +}/* End */ + + + + + + + +/**=========================================================================== + * @fn int __devinit sli_enable_interface(PVOID ptr) + * @brief This function takes the writes the backup values of the CCCR registers. + * @param Pointer to sdio_func. + * @return VOID + */ +VOID sli_write_cccr_registers(struct sdio_func *pfunction) +{ + int ret = 0; + uint8 val =0; + PSLI_ADAPTER adapter = sli_getpriv(glbl_net_device); + ret = sli_cmd52writebyte(pfunction->card, SDIO_CCCR_IOEx,adapter->io_enable); + msleep(2); + ret = sli_cmd52writebyte(pfunction->card, SDIO_CCCR_IORx,adapter->io_ready); + msleep(2); + ret = sli_cmd52writebyte(pfunction->card, SDIO_CCCR_IENx, adapter->int_enable); + msleep(2); + ret = sli_cmd52writebyte(pfunction->card, SDIO_CCCR_IF, adapter->bus_interface_control); + msleep(2); + +}/* End */ + + + + + + + + + + +/**=========================================================================== + * @fn VOID sli_reinit_card(struct sdio_func *pfunction) + * @brief This function reinitialises the card + * @param Pointer to sdio_func. + * @return 0 if success else a negative number. + */ +VOID sli_reinit_card(struct sdio_func *pfunction) +{ + int ret = 0; + uint8 val =0; + uint8 status; + PSLI_ADAPTER Adapter = sli_getpriv(glbl_net_device); +#if KERNEL_VERSION_BTWN_2_6_(18, 22) + +#elif KERNEL_VERSION_GREATER_THAN_EQUALS_2_6_(26) + sli_sdio_claim_host(Adapter->pfunction); + /* Resetting the sdio card to make it ready for the next run */ + sli_reset_card(Adapter->pfunction); + status = sli_setupcard(Adapter); + if (status != 0) + { + SLI_DEBUG(SLI_ZONE_ERROR,(TEXT("%s:Failed to setup card\n"), __func__)); + kfree((uint8 *)Adapter->DataRcvPacket[0]); + sli_sdio_release_host(Adapter->pfunction); + goto out; + } + +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) + Adapter->sdio_high_speed_enable = 1; +#endif + if(sli_init_host_interface(Adapter)!= 0) + { + SLI_DEBUG(SLI_ZONE_ERROR,(TEXT("%s:Failed to init slave regs\n"), __func__)); + sli_sdio_release_host(Adapter->pfunction); + goto out; + } + /* Release host */ + sli_sdio_release_host(Adapter->pfunction); +#endif + return status; +out : + status = -1; + return status; +}/* End */ + +