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 */
+
+