diff --git a/port/main.c b/port/main.c index f4b21847..e876be17 100644 --- a/port/main.c +++ b/port/main.c @@ -134,8 +134,11 @@ int main(int argc, char **argv) } /* printf("netsrv: %zu interface%s\n", have_intfs, have_intfs == 1 ? "" : "s"); */ - if (!have_intfs) +#if !LWIP_WIFI + if (have_intfs == 0) { exit(1); + } +#endif #if LWIP_IPSEC ipsecdev_attach(LWIP_IPSEC_DEV); diff --git a/wi-fi/hal/Makefile b/wi-fi/hal/Makefile index aaa9ff11..a8b81966 100644 --- a/wi-fi/hal/Makefile +++ b/wi-fi/hal/Makefile @@ -8,7 +8,7 @@ NAME := wifi-hal -LOCAL_SRCS := cyhal_gpio.c cyhal_sdio.c cyhal_utils.c cyabs_rtos.c cy_log.c +LOCAL_SRCS := cyhal_gpio.c cyhal_sdio.c cyhal_usb.c cyhal_utils.c cyabs_rtos.c cy_log.c LOCAL_CFLAGS += -Idrivers diff --git a/wi-fi/hal/cy_log.h b/wi-fi/hal/cy_log.h index 87f85562..2879ba22 100644 --- a/wi-fi/hal/cy_log.h +++ b/wi-fi/hal/cy_log.h @@ -151,6 +151,7 @@ typedef enum { CYLF_GPIO, /**< GPIO Facility */ CYLF_SDIO, /**< SDIO Facility */ CYLF_MIDDLEWARE, /**< Middleware Facility */ + CYLF_USB, /**< USB Facility */ CYLF_MAX /**< Must be last, not an actual index */ } CY_LOG_FACILITY_T; diff --git a/wi-fi/hal/cyabs_rtos.c b/wi-fi/hal/cyabs_rtos.c index b0a72d89..beba0c1c 100644 --- a/wi-fi/hal/cyabs_rtos.c +++ b/wi-fi/hal/cyabs_rtos.c @@ -17,14 +17,15 @@ #include #include #include +#include cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function, - const char *name, void *stack, uint32_t stack_size, - cy_thread_priority_t priority, cy_thread_arg_t arg) + const char *name, void *stack, uint32_t stack_size, + cy_thread_priority_t priority, cy_thread_arg_t arg) { cy_log_msg(CYLF_RTOS, CY_LOG_DEBUG, "cy_rtos_create_thread (thread=%p name=%s stack=%p stack_size=%u priority=%d)\n", - thread, name, stack, stack_size, priority); + thread, name, stack, stack_size, priority); if (thread == NULL) return CY_RTOS_BAD_PARAM; @@ -142,7 +143,7 @@ cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex) cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount) { cy_log_msg(CYLF_RTOS, CY_LOG_DEBUG, "cy_rtos_init_semaphore (semaphore=%p maxcount=%u initcount=%u)\n", - semaphore, maxcount, initcount); + semaphore, maxcount, initcount); if (semaphore == NULL) return CY_RTOS_BAD_PARAM; @@ -265,3 +266,105 @@ cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms) return CY_RSLT_SUCCESS; } + + +static inline unsigned cy_rtos_queue_increment(cy_queue_t *queue, unsigned index) +{ + return (index + 1) & (queue->length - 1); +} + + +static inline bool cy_rtos_queue_is_power_of_2(size_t n) +{ + return (n & (n - 1)) == 0; +} + + +/* preconditions: + * - length must be a power of 2 + * - if queue->data != NULL, it should point to an array of at least length * itemsize bytes + */ +cy_rslt_t cy_rtos_queue_init(cy_queue_t *queue, size_t length, size_t itemsize) +{ + if (queue == NULL || !cy_rtos_queue_is_power_of_2(length) || length == 0 || itemsize == 0) { + return CY_RTOS_BAD_PARAM; + } + + queue->data = malloc(length * itemsize); + if (queue->data == NULL) { + return CY_RTOS_NO_MEMORY; + } + + queue->length = length; + queue->itemsz = itemsize; + atomic_init(&queue->head, 0); + atomic_init(&queue->tail, 0); + + return CY_RSLT_SUCCESS; +} + + +static inline void *cy_rtos_queue_get_at(cy_queue_t *queue, unsigned int index) +{ + return (void *)((uintptr_t)queue->data + (index * queue->itemsz)); +} + + +cy_rslt_t cy_rtos_queue_put(cy_queue_t *queue, const void *item_ptr) +{ + const unsigned current_head = atomic_load_explicit(&queue->head, memory_order_relaxed); + const unsigned next_head = cy_rtos_queue_increment(queue, current_head); + if (next_head == atomic_load_explicit(&queue->tail, memory_order_acquire)) { + return CY_RTOS_QUEUE_FULL; + } + + (void)memcpy(cy_rtos_queue_get_at(queue, current_head), item_ptr, queue->itemsz); + atomic_store_explicit(&queue->head, next_head, memory_order_release); + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cy_rtos_queue_get(cy_queue_t *queue, void *item_ptr) +{ + const unsigned current_tail = atomic_load_explicit(&queue->tail, memory_order_relaxed); + if (current_tail == atomic_load_explicit(&queue->head, memory_order_acquire)) { + return CY_RTOS_QUEUE_EMPTY; + } + + (void)memcpy(item_ptr, cy_rtos_queue_get_at(queue, current_tail), queue->itemsz); + atomic_store_explicit(&queue->tail, cy_rtos_queue_increment(queue, current_tail), memory_order_release); + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cy_rtos_queue_count(cy_queue_t *queue, size_t *num_waiting) +{ + *num_waiting = (atomic_load(&queue->head) - atomic_load(&queue->tail)) & (queue->length - 1); + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cy_rtos_queue_space(cy_queue_t *queue, size_t *num_spaces) +{ + size_t num_waiting; + /* cy_rtos_queue_count cannot error */ + (void)cy_rtos_queue_count(queue, &num_waiting); + *num_spaces = (queue->length - 1) - num_waiting; + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cy_rtos_queue_reset(cy_queue_t *queue) +{ + atomic_store(&queue->head, 0); + atomic_store(&queue->tail, 0); + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cy_rtos_queue_deinit(cy_queue_t *queue) +{ + free(queue->data); + queue->data = NULL; + return CY_RSLT_SUCCESS; +} diff --git a/wi-fi/hal/cyabs_rtos.h b/wi-fi/hal/cyabs_rtos.h index 734ec9bc..62bc06b0 100644 --- a/wi-fi/hal/cyabs_rtos.h +++ b/wi-fi/hal/cyabs_rtos.h @@ -99,6 +99,20 @@ extern "C" { /** \} group_abstraction_rtos_common */ +/** + * \ingroup group_abstraction_rtos_queue + * \{ + */ + +/** The Queue is already full and can't accept any more items at this time */ +#define CY_RTOS_QUEUE_FULL \ + CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 3) +/** The Queue is empty and has nothing to remove */ +#define CY_RTOS_QUEUE_EMPTY \ + CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 4) + +/** \} group_abstraction_rtos_queue */ + /********************************************* TYPES **********************************************/ /** @@ -124,13 +138,6 @@ typedef enum cy_thread_state { */ typedef void (*cy_thread_entry_fn_t)(cy_thread_arg_t arg); -typedef struct { - handle_t mutex; - handle_t cond; - volatile unsigned int v; - unsigned int m; -} cy_semaphore_t; - /********************************************* Threads ********************************************/ @@ -469,6 +476,103 @@ cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms); /** \} group_abstraction_rtos_time */ + +/********************************************* Queue **********************************************/ +/** + * \ingroup group_abstraction_rtos_queue + * \{ + */ + +/** Create a queue. + * + * This is a queue of data where entries are placed on the back of the queue + * and removed from the front of the queue. + * + * @param[out] queue Pointer to the queue handle + * @param[in] length The maximum length of the queue in items + * @param[in] itemsize The size of each item in the queue. + * + * @return The status of the init request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref + * CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_queue_init(cy_queue_t *queue, size_t length, size_t itemsize); + +/** Put an item in a queue. + * + * This function puts an item in the queue. The item is copied + * into the queue using a memory copy and the data pointed to by item_ptr + * is no longer referenced once the call returns. + * + * @param[in] queue Pointer to the queue handle + * @param[in] item_ptr Pointer to the item to place in the queue + * + * @return The status of the put request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref + * CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_FULL] + */ +cy_rslt_t cy_rtos_queue_put(cy_queue_t *queue, const void *item_ptr); + +/** Gets an item in a queue. + * + * This function gets an item from the queue. The item is copied + * out of the queue into the memory provide by item_ptr. This space must be + * large enough to hold a queue entry as defined when the queue was initialized. + * + * @param[in] queue Pointer to the queue handle + * @param[in] item_ptr Pointer to the memory for the item from the queue + * + * @return The status of the get request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref + * CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_EMPTY] + */ +cy_rslt_t cy_rtos_queue_get(cy_queue_t *queue, void *item_ptr); + +/** Return the number of items in the queue. + * + * This function returns the number of items currently in the queue. + * + * @param[in] queue Pointer to the queue handle + * @param[out] num_waiting Pointer to the return count + * + * @return The status of the count request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_queue_count(cy_queue_t *queue, size_t *num_waiting); + +/** Return the amount of empty space in the queue. + * + * This function returns the amount of empty space in the + * queue. For instance, if the queue was created with 10 entries max and there + * are currently 2 entries in the queue, this will return 8. + * + * @param[in] queue Pointer to the queue handle + * @param[out] num_spaces Pointer to the return count. + * + * @return The status of the space request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_queue_space(cy_queue_t *queue, size_t *num_spaces); + +/** Reset the queue. + * + * This function sets the queue to empty. + * + * @param[in] queue pointer to the queue handle + * + * @return The status of the reset request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_queue_reset(cy_queue_t *queue); + +/** Deinitialize the queue handle. + * + * This function de-initializes the queue and returns all + * resources used by the queue. + * + * @param[in] queue Pointer to the queue handle + * + * @return The status of the deinit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR] + */ +cy_rslt_t cy_rtos_queue_deinit(cy_queue_t *queue); + +/** \} group_abstraction_rtos_queue */ + + #ifdef __cplusplus } // extern "C" #endif diff --git a/wi-fi/hal/cyabs_rtos_impl.h b/wi-fi/hal/cyabs_rtos_impl.h index cce6240f..f91d14d0 100644 --- a/wi-fi/hal/cyabs_rtos_impl.h +++ b/wi-fi/hal/cyabs_rtos_impl.h @@ -28,6 +28,7 @@ #pragma once +#include #include #include @@ -65,14 +66,14 @@ extern "C" { * MAX >= REALTIME >= HIGH >= ABOVENORMAL >= NORMAL >= BELOWNORMAL >= LOW >= MIN */ typedef enum { - CY_RTOS_PRIORITY_MIN = 0, /**< Minimum allowable Thread priority */ - CY_RTOS_PRIORITY_LOW = 1, /**< A low priority Thread */ - CY_RTOS_PRIORITY_BELOWNORMAL = 2, /**< A slightly below normal Thread priority */ - CY_RTOS_PRIORITY_NORMAL = 3, /**< The normal Thread priority */ - CY_RTOS_PRIORITY_ABOVENORMAL = 4, /**< A slightly elevated Thread priority */ - CY_RTOS_PRIORITY_HIGH = 5, /**< A high priority Thread */ - CY_RTOS_PRIORITY_REALTIME = 6, /**< Realtime Thread priority */ - CY_RTOS_PRIORITY_MAX = 7 /**< Maximum allowable Thread priority */ + CY_RTOS_PRIORITY_MIN = 7, /**< Minimum allowable Thread priority */ + CY_RTOS_PRIORITY_LOW = 6, /**< A low priority Thread */ + CY_RTOS_PRIORITY_BELOWNORMAL = 5, /**< A slightly below normal Thread priority */ + CY_RTOS_PRIORITY_NORMAL = 4, /**< The normal Thread priority */ + CY_RTOS_PRIORITY_ABOVENORMAL = 3, /**< A slightly elevated Thread priority */ + CY_RTOS_PRIORITY_HIGH = 2, /**< A high priority Thread */ + CY_RTOS_PRIORITY_REALTIME = 1, /**< Realtime Thread priority */ + CY_RTOS_PRIORITY_MAX = 0 /**< Maximum allowable Thread priority */ } cy_thread_priority_t; /** Alias for the RTOS specific definition of a thread handle */ @@ -83,6 +84,19 @@ typedef void *cy_thread_arg_t; typedef handle_t cy_mutex_t; /** Alias for the RTOS specific time unit (in milliseconds) */ typedef time_t cy_time_t; +/** Alias for the RTOS specific semaphore implementation */ +typedef struct { + handle_t mutex; + handle_t cond; + volatile unsigned int v; + unsigned int m; +} cy_semaphore_t; +/** Alias for the RTOS specific queue implementation */ +typedef struct { + atomic_uint head, tail; + size_t length, itemsz; + void *data; +} cy_queue_t; /** \} group_abstraction_rtos_port */ diff --git a/wi-fi/hal/cyhal.h b/wi-fi/hal/cyhal.h index 837e460f..52dfdf30 100644 --- a/wi-fi/hal/cyhal.h +++ b/wi-fi/hal/cyhal.h @@ -78,3 +78,6 @@ /** Macro specifying whether the SPI driver is available for the current device \def CYHAL_DRIVER_AVAILABLE_SPI */ #define CYHAL_DRIVER_AVAILABLE_SPI 0 +/** Macro specifying whether the USB Dev driver is available for the current device \def CYHAL_DRIVER_AVAILABLE_USB_DEV + */ +#define CYHAL_DRIVER_AVAILABLE_USB_DEV 1 diff --git a/wi-fi/hal/cyhal_gpio.c b/wi-fi/hal/cyhal_gpio.c index 16e82c6d..cb8ce12a 100644 --- a/wi-fi/hal/cyhal_gpio.c +++ b/wi-fi/hal/cyhal_gpio.c @@ -9,6 +9,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "cybsp.h" +#if !((CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) || (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE)) + #include "cyhal_gpio.h" #include "cyhal_utils.h" #include "cyabs_rtos.h" @@ -167,3 +170,5 @@ void cyhal_gpio_irq_enable(cyhal_gpio_t pin, cyhal_gpio_irq_event_t event, bool { cy_log_msg(CYLF_GPIO, CY_LOG_ERR, "cyhal_gpio_irq_enable - not implemented!\n"); } + +#endif /* !((CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) || (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE)) */ diff --git a/wi-fi/hal/cyhal_hw_types.h b/wi-fi/hal/cyhal_hw_types.h index f592dace..c8d83340 100644 --- a/wi-fi/hal/cyhal_hw_types.h +++ b/wi-fi/hal/cyhal_hw_types.h @@ -43,6 +43,7 @@ /* #include "TODO: Port specific header file" */ +#include #ifdef __cplusplus extern "C" { @@ -84,6 +85,11 @@ typedef struct void *empty; } cyhal_m2m_t; +/** USB object */ +typedef struct { + void *usb_priv; +} cyhal_usb_t; + /** \} group_hal_hw_types_data_structures */ #if defined(__cplusplus) diff --git a/wi-fi/hal/cyhal_sdio.c b/wi-fi/hal/cyhal_sdio.c index 7e47e4e7..148b840c 100644 --- a/wi-fi/hal/cyhal_sdio.c +++ b/wi-fi/hal/cyhal_sdio.c @@ -9,6 +9,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "cybsp.h" +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) + #include "cyhal_sdio.h" #include "cyhal_utils.h" #include "cyabs_rtos.h" @@ -780,3 +783,5 @@ void cyhal_sdio_irq_enable(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, bool sdio_common.irq_enabled = enable; } } + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) */ diff --git a/wi-fi/hal/cyhal_spi.h b/wi-fi/hal/cyhal_spi.h index 8fb8eb98..fca5c957 100644 --- a/wi-fi/hal/cyhal_spi.h +++ b/wi-fi/hal/cyhal_spi.h @@ -41,6 +41,7 @@ #include #include +#include #include "cy_result.h" #include "cyhal_hw_types.h" #include "cyhal_modules.h" diff --git a/wi-fi/hal/cyhal_usb.c b/wi-fi/hal/cyhal_usb.c new file mode 100644 index 00000000..4d4e2018 --- /dev/null +++ b/wi-fi/hal/cyhal_usb.c @@ -0,0 +1,313 @@ +/* + * Phoenix-RTOS --- LwIP port + * + * LwIP Wi-Fi - USB HAL + * + * Copyright 2025 Phoenix Systems + * Author: Julian Uziembło + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#include "cybsp.h" +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) + +#include +#include +#include +#include +#include +#include +#include + +#include "usbwlan.h" + +#include "cy_log.h" +#include "cyabs_rtos.h" +#include "cyhal_usb.h" + + +typedef struct { + int fd; + oid_t oid; +} usb_priv_t; + + +cy_rslt_t cyhal_usb_init(cyhal_usb_t *obj, const char *path) +{ + if (obj == NULL) { + return CY_RTOS_BAD_PARAM; + } + + usb_priv_t *priv; + oid_t oid; + + obj->usb_priv = NULL; + + if (lookup(path, NULL, &oid) < 0) { + return CYHAL_USB_RSLT_ERR_DEVICE_NOT_FOUND; + } + + priv = malloc(sizeof(*priv)); + if (priv == NULL) { + cy_log_msg(CYLF_USB, CY_LOG_ERR, "no memory for usb_priv\n"); + return CY_RTOS_NO_MEMORY; + } + memset(priv, 0, sizeof(*priv)); + + priv->oid = oid; + priv->fd = open(path, O_RDWR); + if (priv->fd < 0) { + cy_log_msg(CYLF_USB, CY_LOG_ERR, "couldn't open %s: %s (%d)\n", path, strerror(errno), errno); + free(priv); + return CYHAL_USB_RSLT_ERR_DEVICE_OP(errno); + } + + obj->usb_priv = priv; + + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cyhal_usb_wait_state(const char *path, bool state) +{ + int result; + __attribute__((unused)) oid_t oid; + + do { + result = lookup(path, NULL, &oid); + usleep(10 * 1000); + } while ((result >= 0) != state); + + return CY_RSLT_SUCCESS; +} + + +static int cyhal_usb_devctl(const usb_priv_t *priv, void *buffer, size_t buflen, const usbwlan_i_t *imsg) +{ + bool is_tx; + msg_t msg = { + .type = mtDevCtl, + .oid = priv->oid, + }; + + switch (imsg->type) { + case usbwlan_ctrlOut: + case usbwlan_regWrite: + is_tx = true; + msg.i.data = buffer; + msg.i.size = buflen; + break; + + case usbwlan_ctrlIn: + case usbwlan_regRead: + case usbwlan_dl: + is_tx = false; + msg.o.data = buffer; + msg.o.size = buflen; + break; + + case usbwlan_abort: + is_tx = false; + break; + + default: + return -EOPNOTSUPP; + } + + memcpy(msg.i.raw, imsg, sizeof(*imsg)); + + int length = msgSend(priv->oid.port, &msg); + if (length < 0) { + return length; + } + else { + if (msg.o.err < 0) { + return msg.o.err; + } + else { + length = msg.o.err; + } + } + + if (is_tx && length != buflen) { + return -EINVAL; + } + + return length; +} + + +cy_rslt_t cyhal_usb_free(cyhal_usb_t *obj) +{ + if (obj == NULL) { + return CY_RTOS_BAD_PARAM; + } + + usb_priv_t *priv = obj->usb_priv; + + if (priv != NULL) { + if (priv->fd != -1) { + usbwlan_i_t abortmsg = { .type = usbwlan_abort }; + cyhal_usb_devctl(priv, NULL, 0, &abortmsg); + close(priv->fd); + priv->fd = -1; + } + memset(&priv->oid, 0, sizeof(priv->oid)); + + free(priv); + obj->usb_priv = NULL; + } + + return CY_RSLT_SUCCESS; +} + + +static inline cy_rslt_t cyhal_usb_convert_result(int result) +{ + return (result >= 0) ? CY_RSLT_SUCCESS : CYHAL_USB_RSLT_ERR_DEVICE_OP(result); +} + + +cy_rslt_t cyhal_usb_dl_cmd(const cyhal_usb_t *obj, uint8_t cmd, void *buffer, size_t buflen) +{ + if (obj == NULL || obj->usb_priv == NULL) { + return CY_RTOS_BAD_PARAM; + } + const usb_priv_t *priv = obj->usb_priv; + const usbwlan_i_t imsg = { + .type = usbwlan_dl, + .dl = { + .cmd = cmd, + .wIndex = (cmd == CYHAL_USB_DL_CMD_GO) ? 1 : 0, + } + }; + return cyhal_usb_convert_result(cyhal_usb_devctl(priv, buffer, buflen, &imsg)); +} + + +cy_rslt_t cyhal_usb_bulk_send(const cyhal_usb_t *obj, void *buffer, size_t *buflen) +{ + if (obj == NULL || obj->usb_priv == NULL) { + return CY_RTOS_BAD_PARAM; + } + + const usb_priv_t *priv = obj->usb_priv; + ssize_t status; + ssize_t remaining = *buflen; + uint8_t *ptr = buffer; + + while (remaining > 0) { + status = write(priv->fd, ptr, remaining); + if (status < 0) { + if ((errno == EAGAIN) || (errno == EINTR)) { + usleep(100); + continue; + } + else { + return CYHAL_USB_RSLT_ERR_DEVICE_OP(errno); + } + } + remaining -= status; + ptr += status; + } + + *buflen = (size_t)(ptr - (uint8_t *)buffer); + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cyhal_usb_bulk_receive(const cyhal_usb_t *obj, void *buffer, size_t *buflen) +{ + if (obj == NULL || obj->usb_priv == NULL) { + return CY_RTOS_BAD_PARAM; + } + + const usb_priv_t *priv = obj->usb_priv; + ssize_t status; + + for (;;) { + status = read(priv->fd, buffer, *buflen); + if (status < 0 && (errno == EAGAIN || errno == EINTR)) { + usleep(100); + continue; + } + else { + break; + } + } + + if (status < 0) { + return CYHAL_USB_RSLT_ERR_DEVICE_OP(errno); + } + + *buflen = status; + return CY_RSLT_SUCCESS; +} + + +cy_rslt_t cyhal_usb_ctrl_send(const cyhal_usb_t *obj, void *buffer, size_t *buflen) +{ + if (obj == NULL || obj->usb_priv == NULL) { + return CY_RTOS_BAD_PARAM; + } + + const usb_priv_t *priv = obj->usb_priv; + const usbwlan_i_t umsg = { .type = usbwlan_ctrlOut }; + ssize_t status; + cy_rslt_t result; + + for (;;) { + status = cyhal_usb_devctl(priv, buffer, *buflen, &umsg); + if (status < 0 && (errno == EAGAIN || errno == EINTR)) { + usleep(100); + continue; + } + else { + break; + } + } + + result = cyhal_usb_convert_result(status); + if (result == CY_RSLT_SUCCESS) { + *buflen = status; + } + + return result; +} + + +cy_rslt_t cyhal_usb_ctrl_receive(const cyhal_usb_t *obj, void *buffer, size_t *buflen) +{ + if (obj == NULL || obj->usb_priv == NULL) { + return CY_RTOS_BAD_PARAM; + } + + const usb_priv_t *priv = obj->usb_priv; + const usbwlan_i_t umsg = { .type = usbwlan_ctrlIn }; + ssize_t status; + cy_rslt_t result; + + for (;;) { + status = cyhal_usb_devctl(priv, buffer, *buflen, &umsg); + if (status < 0 && (errno == EAGAIN || errno == EINTR)) { + usleep(100); + continue; + } + else { + break; + } + } + + result = cyhal_usb_convert_result(status); + if (result == CY_RSLT_SUCCESS) { + *buflen = status; + } + + return result; +} + + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) */ diff --git a/wi-fi/hal/cyhal_usb.h b/wi-fi/hal/cyhal_usb.h new file mode 100644 index 00000000..6ec0d64e --- /dev/null +++ b/wi-fi/hal/cyhal_usb.h @@ -0,0 +1,144 @@ +/* + * Phoenix-RTOS --- LwIP port + * + * LwIP Wi-Fi - USB HAL + * + * Copyright 2025 Phoenix Systems + * Author: Julian Uziembło + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + +#ifndef PHOENIX_CYHAL_USB_H_ +#define PHOENIX_CYHAL_USB_H_ + +#include + +#include "cyhal_modules.h" +#include "cy_result.h" +#include "cyhal_hw_types.h" + +/* Control messages: bRequest values */ +#define CYHAL_USB_DL_CMD_GETSTATE 0x0 /* returns the rdl_state_t struct */ +#define CYHAL_USB_DL_CMD_CHECK_CRC 0x1 /* currently unused */ +#define CYHAL_USB_DL_CMD_GO 0x2 /* execute downloaded image */ +#define CYHAL_USB_DL_CMD_START 0x3 /* initialize dl state */ +#define CYHAL_USB_DL_CMD_REBOOT 0x4 /* reboot the device in 2 seconds */ +#define CYHAL_USB_DL_CMD_GETVER 0x5 /* returns the bootrom_id_t struct */ +#define CYHAL_USB_DL_CMD_GO_PROTECTED 0x6 /* execute the downloaded code and set reset event to occur in 2 seconds. It is the responsibility of the downloaded code to clear this event */ +#define CYHAL_USB_DL_CMD_EXEC 0x7 /* jump to a supplied address */ +#define CYHAL_USB_DL_CMD_RESETCFG 0x8 /* To support single enum on dongle - not used by bootloader */ +#define CYHAL_USB_DL_CMD_DEFER_RESP_OK 0x9 /* Potentially defer the response to setup if resp unavailable */ +#define CYHAL_USB_DL_CMD_RDHW 0x10 /* Read a hardware address (Ctl-in) */ +#define CYHAL_USB_DL_CMD_RDHW32 0x10 /* Read a 32 bit word */ +#define CYHAL_USB_DL_CMD_RDHW16 0x11 /* Read 16 bits */ +#define CYHAL_USB_DL_CMD_RDHW8 0x12 /* Read an 8 bit byte */ +#define CYHAL_USB_DL_CMD_WRHW 0x14 /* Write a hardware address (Ctl-out) */ +#define CYHAL_USB_DL_CMD_WRHW_BLK 0x13 /* Block write to hardware access */ + +/* States */ +#define CYHAL_USB_DL_STATE_WAITING 0 /* waiting to rx first pkt */ +#define CYHAL_USB_DL_STATE_READY 1 /* hdr was good, waiting for more of the compressed image */ +#define CYHAL_USB_DL_STATE_BAD_HDR 2 /* hdr was corrupted */ +#define CYHAL_USB_DL_STATE_BAD_CRC 3 /* compressed image was corrupted */ +#define CYHAL_USB_DL_STATE_RUNNABLE 4 /* download was successful,waiting for go cmd */ +#define CYHAL_USB_DL_STATE_START_FAIL 5 /* failed to initialize correctly */ +#define CYHAL_USB_DL_STATE_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM value */ +#define CYHAL_USB_DL_STATE_IMAGE_TOOBIG 7 /* firmware image too big */ + +#define WHD_USB_MAX_BULK_TRANSFER_SIZE (512) /* Max packet size for high speed USB device */ + +#define CYHAL_USB_RSLT_ERR_DEVICE_NOT_FOUND CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_USB, 0x1) +#define CYHAL_USB_RSLT_ERR_DEVICE_OP(err) CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_USB, err) + + +/** Initialize the USB peripheral + * + * @param[out] obj The USB object + * @param[in] path USB device path + * @return The status of the init request + */ +cy_rslt_t cyhal_usb_init(cyhal_usb_t *obj, const char *path); + + +/** Release the USB peripheral. + * + * @param[in,out] obj The USB object + * @return The status of the deinit request + */ +cy_rslt_t cyhal_usb_free(cyhal_usb_t *obj); + + +/** Wait USB state (down/up) + * + * @param[in] path File path to the USB + * @param state The state to wait for: false=down, true=up + * @return The status of USB + */ +cy_rslt_t cyhal_usb_wait_state(const char *path, bool state); + + +/** Send download command + * + * @param[in] obj The USB object + * @param cmd command to send (CYHAL_USB_DL_CMD_*) + * @param[out] buffer buffer to store the response, should be at least buflen size + * @param buflen length of buffer + * @return The status of the cmd request + */ +cy_rslt_t cyhal_usb_dl_cmd(const cyhal_usb_t *obj, uint8_t cmd, void *buffer, size_t buflen); + + +/** Send bulk + * + * @param[in] obj The USB object + * @param[in] buffer buffer to send, should be at least buflen size + * @param buflen length of buffer + * @return The status of bulk send + */ +cy_rslt_t cyhal_usb_bulk_send(const cyhal_usb_t *obj, void *buffer, size_t *buflen); + + +/** Receive bulk + * + * @param[in] obj The USB object + * @param[out] buffer buffer to receive into, should be at least buflen size + * @param buflen length of buffer + * @return The status of bulk receive + */ +cy_rslt_t cyhal_usb_bulk_receive(const cyhal_usb_t *obj, void *buffer, size_t *buflen); + + +/** Send ctrl + * + * @param[in] obj The USB object + * @param[in] buffer buffer to send, should be at least buflen size + * @param buflen length of buffer + * @return The status of ctrl send + */ +cy_rslt_t cyhal_usb_ctrl_send(const cyhal_usb_t *obj, void *buffer, size_t *buflen); + + +/** Receive ctrl + * + * @param[in] obj The USB object + * @param[out] buffer buffer to receive into, should be at least buflen size + * @param buflen length of buffer + * @return The status of ctrl receive + */ +cy_rslt_t cyhal_usb_ctrl_receive(const cyhal_usb_t *obj, void *buffer, size_t *buflen); + + +/** Wait for bulk IN transmission to become available + * + * @param[in] obj The USB object + * @param[out] buffer buffer to receive into, should be at least buflen size + * @param buflen length of buffer + * @return The status of ctrl receive + */ +cy_rslt_t cyhal_usb_wait_bulk(const cyhal_usb_t *obj); + + +#endif /* PHOENIX_CYHAL_USB_H_ */ diff --git a/wi-fi/lwip/cy_lwip.c b/wi-fi/lwip/cy_lwip.c index c329e879..cc649e30 100644 --- a/wi-fi/lwip/cy_lwip.c +++ b/wi-fi/lwip/cy_lwip.c @@ -311,7 +311,7 @@ static err_t wifiinit(struct netif *iface) res = whd_wifi_get_mac_address(whd_iface, &macaddr); if (res != CY_RSLT_SUCCESS) { - wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "whd_wifi_get_mac_address call failed, err = %lx\n", res); + wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "whd_wifi_get_mac_address call failed, err = %" PRIx32 "\n", res); return res; } memcpy(&iface->hwaddr, &macaddr, sizeof(macaddr)); diff --git a/wi-fi/lwip/cy_lwip_dhcp_server.c b/wi-fi/lwip/cy_lwip_dhcp_server.c index e44ec428..e887fa9d 100644 --- a/wi-fi/lwip/cy_lwip_dhcp_server.c +++ b/wi-fi/lwip/cy_lwip_dhcp_server.c @@ -162,7 +162,7 @@ typedef struct static const uint8_t *find_option(const dhcp_header_t *request, uint8_t option_num); static bool get_client_ip_address_from_cache(const cy_lwip_mac_addr_t *client_mac_address, cy_lwip_ip_address_t *client_ip_address); static cy_rslt_t add_client_to_cache(const cy_lwip_mac_addr_t *client_mac_address, const cy_lwip_ip_address_t *client_ip_address); -static void ipv4_to_string(char *buffer, uint32_t ipv4_address); +static void ipv4_to_string(char buffer[16], uint32_t ipv4_address); static void cy_dhcp_thread_func(cy_thread_arg_t thread_input); static cy_rslt_t udp_create_socket(cy_lwip_udp_socket_t *socket, uint16_t port, cy_lwip_nw_interface_role_t interface); static cy_rslt_t udp_delete_socket(cy_lwip_udp_socket_t *socket); diff --git a/wi-fi/lwip/cy_network_buffer.h b/wi-fi/lwip/cy_network_buffer.h index cfb5ee7f..8af697e2 100644 --- a/wi-fi/lwip/cy_network_buffer.h +++ b/wi-fi/lwip/cy_network_buffer.h @@ -77,7 +77,7 @@ whd_result_t cy_buffer_pool_init(void *tx_packet_pool, void *rx_packet_pool); * @return : CY_RSLT_SUCCESS or WHD_BUFFER_ALLOC_FAIL if the buffer could not be allocated */ whd_result_t cy_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, - unsigned short size, unsigned long timeout_ms); + unsigned short size, uint32_t timeout_ms); /** Releases a packet buffer * diff --git a/wi-fi/lwip/cy_network_buffer_lwip.c b/wi-fi/lwip/cy_network_buffer_lwip.c index 97c0cd12..69119e27 100644 --- a/wi-fi/lwip/cy_network_buffer_lwip.c +++ b/wi-fi/lwip/cy_network_buffer_lwip.c @@ -53,7 +53,7 @@ whd_result_t cy_buffer_pool_init(void *tx_packet_pool, void *rx_packet_pool) // cy_host_buffer_get //-------------------------------------------------------------------------------------------------- whd_result_t cy_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, - unsigned short size, unsigned long timeout_ms) + unsigned short size, uint32_t timeout_ms) { struct pbuf *p = NULL; uint32_t counter = 0; diff --git a/wi-fi/lwip/cybsp.c b/wi-fi/lwip/cybsp.c index 95b52dbb..1ddcf865 100644 --- a/wi-fi/lwip/cybsp.c +++ b/wi-fi/lwip/cybsp.c @@ -25,15 +25,16 @@ * limitations under the License. *******************************************************************************/ -#include #include "cybsp.h" #if defined(__cplusplus) extern "C" { #endif +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) static cyhal_sdio_t sdio_obj; + //-------------------------------------------------------------------------------------------------- // cybsp_get_wifi_sdio_obj //-------------------------------------------------------------------------------------------------- @@ -41,6 +42,7 @@ cyhal_sdio_t *cybsp_get_wifi_sdio_obj(void) { return &sdio_obj; } +#endif //-------------------------------------------------------------------------------------------------- @@ -50,6 +52,7 @@ cy_rslt_t cybsp_init(void) { cy_rslt_t result = CY_RSLT_SUCCESS; +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) // Initialize SDIO interface. This must be done before other HAL API calls as some SDIO // implementations require specific peripheral instances. // NOTE: The full WiFi interface still needs to be initialized via cybsp_wifi_init_primary(). @@ -58,7 +61,12 @@ cy_rslt_t cybsp_init(void) // Reserves: CYBSP_WIFI_SDIO, CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2, // CYBSP_WIFI_SDIO_D3, CYBSP_WIFI_SDIO_CMD and CYBSP_WIFI_SDIO_CLK. result = cyhal_sdio_init(&sdio_obj); + + if (result == CY_RSLT_SUCCESS) { + result = cyhal_sdio_start_irq_thread(cybsp_get_wifi_sdio_obj()); + } } +#endif // CYHAL_HWMGR_RSLT_ERR_INUSE error code could be returned if any needed for BSP resource was // reserved by user previously. Please review the Device Configurator (design.modus) and the BSP @@ -69,7 +77,10 @@ cy_rslt_t cybsp_init(void) void cybsp_free(void) { +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) + cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cyhal_sdio_free(&sdio_obj); +#endif } diff --git a/wi-fi/lwip/cybsp.h b/wi-fi/lwip/cybsp.h index 720695ae..6021fb51 100644 --- a/wi-fi/lwip/cybsp.h +++ b/wi-fi/lwip/cybsp.h @@ -30,6 +30,8 @@ #include "cybsp_types.h" #include "cyhal_sdio.h" +#include "lwipopts.h" + #if defined(__cplusplus) extern "C" { #endif @@ -58,14 +60,18 @@ cy_rslt_t cybsp_init(void); void cybsp_free(void); +#ifndef CYBSP_WIFI_INTERFACE_TYPE #define CYBSP_WIFI_INTERFACE_TYPE CYBSP_SDIO_INTERFACE +#endif /* CYBSP_WIFI_INTERFACE_TYPE */ +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) /** * \brief Get the initialized sdio object used for communicating with the WiFi Chip. * \note This function should only be called after cybsp_init(); * \returns The initialized sdio object. */ cyhal_sdio_t *cybsp_get_wifi_sdio_obj(void); +#endif /** \} group_bsp_functions */ diff --git a/wi-fi/lwip/cybsp_types.h b/wi-fi/lwip/cybsp_types.h index 71ec3e4a..0af2eb65 100644 --- a/wi-fi/lwip/cybsp_types.h +++ b/wi-fi/lwip/cybsp_types.h @@ -34,6 +34,7 @@ extern "C" { #define CYBSP_SDIO_INTERFACE (0) #define CYBSP_SPI_INTERFACE (1) #define CYBSP_M2M_INTERFACE (2) +#define CYBSP_USB_INTERFACE (3) #ifdef __cplusplus } diff --git a/wi-fi/lwip/cybsp_wifi.c b/wi-fi/lwip/cybsp_wifi.c index 598425a0..d7ef7924 100644 --- a/wi-fi/lwip/cybsp_wifi.c +++ b/wi-fi/lwip/cybsp_wifi.c @@ -34,6 +34,10 @@ #include "cycfg.h" #endif +#include "whd_wifi_api.h" + +#include "lwipopts.h" + #if defined(__cplusplus) extern "C" { #endif @@ -58,12 +62,14 @@ extern "C" { #define WIFI_MODE_SPI #elif (CYHAL_DRIVER_AVAILABLE_DMA && (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE)) #define WIFI_MODE_M2M +#elif (CYHAL_DRIVER_AVAILABLE_USB_DEV && (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE)) +#define WIFI_MODE_USB #else // For old versions of HAL/BSP fallback to the default interface #define WIFI_MODE_SDIO #endif -#if !defined(WIFI_MODE_M2M) +#if !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) #define SDIO_ENUMERATION_TRIES (500) #define SDIO_RETRY_DELAY_MS (1) @@ -164,7 +170,13 @@ typedef cyhal_transfer_t cyhal_sdio_transfer_type_t; #define CYHAL_SDIO_XFER_TYPE_WRITE CYHAL_WRITE #endif -#endif // if !defined(WIFI_MODE_M2M) +#elif defined(WIFI_MODE_USB) + +#ifndef WIFI_DEVICE_PATH +#define WIFI_DEVICE_PATH "/dev/wlan0" +#endif + +#endif /* !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) */ static whd_driver_t whd_drv; @@ -190,7 +202,7 @@ static whd_netif_funcs_t netif_if_default = { .whd_network_process_ethernet_data = cy_network_process_ethernet_data, }; -#if !defined(WIFI_MODE_M2M) +#if !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) static const whd_oob_config_t OOB_CONFIG = { .host_oob_pin = CY_WIFI_HOST_WAKE_GPIO, .dev_gpio_sel = DEFAULT_OOB_PIN, @@ -213,7 +225,7 @@ static void _cybsp_wifi_reset_wifi_chip(void) } -#endif // if !defined(WIFI_MODE_M2M) +#endif /* !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) */ #if defined(WIFI_MODE_SDIO) @@ -491,8 +503,22 @@ static cy_rslt_t _cybsp_wifi_m2m_init_bus(void) return rslt; } +#elif defined(WIFI_MODE_USB) + +static cyhal_usb_t usb_obj; -#endif // defined(WIFI_MODE_M2M) +//-------------------------------------------------------------------------------------------------- +// _cybsp_wifi_usb_init_bus +//-------------------------------------------------------------------------------------------------- +cy_rslt_t _cybsp_wifi_usb_init_bus(void) +{ + whd_usb_config_t whd_usb_config = { + .path = WIFI_DEVICE_PATH, + }; + return whd_bus_usb_attach(whd_drv, &whd_usb_config, &usb_obj); +} + +#endif //-------------------------------------------------------------------------------------------------- @@ -500,7 +526,7 @@ static cy_rslt_t _cybsp_wifi_m2m_init_bus(void) //-------------------------------------------------------------------------------------------------- static inline cy_rslt_t _cybsp_wifi_bus_init(void) { -#if !defined(WIFI_MODE_M2M) +#if !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) _cybsp_wifi_reset_wifi_chip(); #endif #if defined(WIFI_MODE_SDIO) @@ -509,6 +535,8 @@ static inline cy_rslt_t _cybsp_wifi_bus_init(void) return _cybsp_wifi_spi_init_bus(); #elif defined(WIFI_MODE_M2M) return _cybsp_wifi_m2m_init_bus(); +#elif defined(WIFI_MODE_USB) + return _cybsp_wifi_usb_init_bus(); #endif } @@ -530,6 +558,8 @@ static inline void _cybsp_wifi_bus_detach(void) whd_bus_spi_detach(whd_drv); #elif defined(WIFI_MODE_M2M) whd_bus_m2m_detach(whd_drv); +#elif defined(WIFI_MODE_USB) + whd_bus_usb_detach(whd_drv); #endif } @@ -543,7 +573,7 @@ cy_rslt_t cybsp_wifi_init_primary_extended(whd_interface_t *interface, whd_buffer_funcs_t *buffer_if, whd_netif_funcs_t *netif_if) { -#if defined(WIFI_MODE_M2M) +#if defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB) cy_rslt_t result = CY_RSLT_SUCCESS; #else cy_rslt_t result = cyhal_gpio_init(CYBSP_WIFI_WL_REG_ON, CYHAL_GPIO_DIR_OUTPUT, @@ -582,7 +612,7 @@ cy_rslt_t cybsp_wifi_init_primary_extended(whd_interface_t *interface, } } -#if !defined(WIFI_MODE_M2M) +#if !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) if (result != CY_RSLT_SUCCESS) { cyhal_gpio_free(CYBSP_WIFI_WL_REG_ON); } @@ -611,7 +641,7 @@ cy_rslt_t cybsp_wifi_deinit(whd_interface_t interface) if (result == CY_RSLT_SUCCESS) { _cybsp_wifi_bus_detach(); -#if !defined(WIFI_MODE_M2M) +#if !(defined(WIFI_MODE_M2M) || defined(WIFI_MODE_USB)) cyhal_gpio_free(CYBSP_WIFI_WL_REG_ON); #endif // While deinit() takes an interface, it only uses it to get the underlying whd driver to diff --git a/wi-fi/lwip/main.c b/wi-fi/lwip/main.c index 049053c0..df9ede20 100644 --- a/wi-fi/lwip/main.c +++ b/wi-fi/lwip/main.c @@ -235,18 +235,9 @@ static void wifi_ap_thread(void *arg) break; } - result = cyhal_sdio_start_irq_thread(cybsp_get_wifi_sdio_obj()); - if (result != CY_RSLT_SUCCESS) { - wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't start IRQ thread\n"); - cybsp_free(); - break; - } - result = cybsp_wifi_init_primary(&wifi_common.iface.whd_iface); if (result != CY_RSLT_SUCCESS) { wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't init Wi-Fi interface\n"); - /* cyhal_sdio_stop_irq_thread can be safely called twice */ - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); break; } @@ -257,7 +248,6 @@ static void wifi_ap_thread(void *arg) if (result != CY_RSLT_SUCCESS) { wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't add Wi-Fi interface\n"); cybsp_wifi_deinit(wifi_common.iface.whd_iface); - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); break; } @@ -267,29 +257,26 @@ static void wifi_ap_thread(void *arg) wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't bring up Wi-Fi interface\n"); cy_lwip_remove_interface(&wifi_common.iface); cybsp_wifi_deinit(wifi_common.iface.whd_iface); - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); break; } result = whd_wifi_init_ap(wifi_common.iface.whd_iface, &ssid, AP_SECURITY_MODE, key, key_len, AP_CHANNEL); - if (result != CY_RSLT_SUCCESS) { + if (result != WHD_SUCCESS) { wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't init Wi-Fi AP\n"); cy_lwip_network_down(&wifi_common.iface); cy_lwip_remove_interface(&wifi_common.iface); cybsp_wifi_deinit(wifi_common.iface.whd_iface); - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); break; } result = whd_wifi_start_ap(wifi_common.iface.whd_iface); - if (result != CY_RSLT_SUCCESS) { + if (result != WHD_SUCCESS) { wm_cy_log_msg(CYLF_MIDDLEWARE, CY_LOG_ERR, "can't start Wi-Fi AP\n"); cy_lwip_network_down(&wifi_common.iface); cy_lwip_remove_interface(&wifi_common.iface); cybsp_wifi_deinit(wifi_common.iface.whd_iface); - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); break; } @@ -309,7 +296,6 @@ static void wifi_ap_thread(void *arg) cy_lwip_network_down(&wifi_common.iface); cy_lwip_remove_interface(&wifi_common.iface); cybsp_wifi_deinit(wifi_common.iface.whd_iface); - cyhal_sdio_stop_irq_thread(cybsp_get_wifi_sdio_obj()); cybsp_free(); } diff --git a/wi-fi/whd/.clang-format b/wi-fi/whd/.clang-format new file mode 100644 index 00000000..79fc7686 --- /dev/null +++ b/wi-fi/whd/.clang-format @@ -0,0 +1,8 @@ +--- +# disable clang-format to keep the original LwIP code style +DisableFormat: 'true' + +# clang-format has a bug in which it insists on sorting includes even if disabled +SortIncludes: 'false' + +... diff --git a/wi-fi/whd/Makefile b/wi-fi/whd/Makefile index e2819bc6..556eea1f 100644 --- a/wi-fi/whd/Makefile +++ b/wi-fi/whd/Makefile @@ -8,10 +8,13 @@ NAME := wifi-whd -LOCAL_SRCS := whd_ap.c whd_buffer_api.c whd_cdc_bdc.c whd_chip.c whd_chip_constants.c whd_clm.c whd_debug.c \ - whd_events.c whd_logging.c whd_management.c whd_network_if.c whd_resource_if.c whd_resources.c \ - whd_sdpcm.c whd_thread.c whd_utils.c whd_wifi_api.c whd_wifi.c whd_wifi_p2p.c bus_protocols/whd_bus.c \ - bus_protocols/whd_bus_common.c bus_protocols/whd_bus_sdio_protocol.c +LOCAL_SRCS := whd_ap.c whd_buffer_api.c whd_cdc_bdc.c whd_chip.c whd_chip_constants.c whd_clm.c \ + whd_commonring.c whd_debug.c whd_events.c whd_flowring.c whd_logging.c whd_management.c \ + whd_msgbuf_txrx.c whd_network_if.c whd_proto.c whd_resource_if.c whd_resources.c \ + whd_ring.c whd_sdpcm.c whd_thread.c whd_utils.c whd_wifi_api.c whd_wifi.c whd_wifi_p2p.c \ + bus_protocols/whd_bus.c bus_protocols/whd_bus_common.c bus_protocols/whd_bus_m2m_protocol.c \ + bus_protocols/whd_bus_sdio_protocol.c bus_protocols/whd_bus_spi_protocol.c \ + bus_protocols/whd_bus_usb_protocol.c LOCAL_CFLAGS += -DCYHAL_API_VERSION=1 diff --git a/wi-fi/whd/bus_protocols/whd_bus.c b/wi-fi/whd/bus_protocols/whd_bus.c index 6b94b16e..09064c39 100644 --- a/wi-fi/whd/bus_protocols/whd_bus.c +++ b/wi-fi/whd/bus_protocols/whd_bus.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,7 @@ * */ -#include +#include "whd_utils.h" #include "whd_bus.h" #include "whd_int.h" @@ -27,197 +27,213 @@ whd_driver_t g_bt_whd_driver; whd_result_t whd_bus_write_reg_value(whd_driver_t whd_driver, uint32_t address, - uint8_t value_length, uint32_t value) + uint8_t value_length, uint32_t value) { - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); - return whd_bus_write_backplane_value(whd_driver, address, value_length, value); + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + return whd_bus_write_backplane_value(whd_driver, address, value_length, value); + } whd_result_t whd_bus_read_reg_value(whd_driver_t whd_driver, uint32_t address, - uint8_t value_length, uint8_t *value) + uint8_t value_length, uint8_t *value) { - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); - return whd_bus_read_backplane_value(whd_driver, address, value_length, value); + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + return whd_bus_read_backplane_value(whd_driver, address, value_length, value); + } whd_result_t whd_bus_share_bt_init(whd_driver_t whd_driver) { - if (!whd_driver) - return WHD_WLAN_ERROR; - g_bt_whd_driver = whd_driver; - return WHD_SUCCESS; + if (!whd_driver) + return WHD_WLAN_ERROR; + g_bt_whd_driver = whd_driver; + return WHD_SUCCESS; } whd_driver_t whd_bt_get_whd_driver(void) { - if (g_bt_whd_driver) - return g_bt_whd_driver; - else - return NULL; + if (g_bt_whd_driver) + return g_bt_whd_driver; + else + return NULL; } whd_result_t whd_bus_bt_attach(whd_driver_t whd_driver, void *btdata, - void (*bt_int_fun)(void *data)) -{ - whd_bt_dev_t btdev; - if (whd_driver->bt_dev) { - return WHD_SUCCESS; - } - /* Allocate bt dev */ - btdev = (whd_bt_dev_t)malloc(sizeof(struct whd_bt_dev)); - if (btdev == NULL) { - WPRINT_WHD_ERROR(("Memory allocation failed for whd_bt_dev_t in %s\n", __FUNCTION__)); - return WHD_BUFFER_UNAVAILABLE_PERMANENT; - } - btdev->bt_data = btdata; - btdev->intr = WHD_TRUE; - whd_driver->bt_dev = btdev; - whd_bus_init_stats(whd_driver); - btdev->bt_int_cb = bt_int_fun; - if (!btdev->bt_int_cb) { - btdev->intr = WHD_FALSE; - } - return WHD_SUCCESS; + void (*bt_int_fun)(void *data) ) +{ + whd_bt_dev_t btdev; + if (whd_driver->bt_dev) + { + return WHD_SUCCESS; + } + /* Allocate bt dev */ + btdev = (whd_bt_dev_t)whd_mem_malloc(sizeof(struct whd_bt_dev) ); + if (btdev == NULL) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bt_dev_t in %s\n", __FUNCTION__) ); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + btdev->bt_data = btdata; + btdev->intr = WHD_TRUE; + whd_driver->bt_dev = btdev; + whd_bus_init_stats(whd_driver); + btdev->bt_int_cb = bt_int_fun; + if (!btdev->bt_int_cb) + { + btdev->intr = WHD_FALSE; + } + return WHD_SUCCESS; } void whd_bus_bt_detach(whd_driver_t whd_driver) { - whd_bt_dev_t btdev = whd_driver->bt_dev; - if (btdev) { - if (btdev->bt_data) - btdev->bt_data = NULL; - if (btdev->bt_int_cb) - btdev->bt_int_cb = NULL; - if (whd_driver->bt_dev) { - whd_driver->bt_dev = NULL; - free(btdev); - } - } + whd_bt_dev_t btdev = whd_driver->bt_dev; + if (btdev) + { + if (btdev->bt_data) + btdev->bt_data = NULL; + if (btdev->bt_int_cb) + btdev->bt_int_cb = NULL; + if (whd_driver->bt_dev) + { + whd_driver->bt_dev = NULL; + whd_mem_free(btdev); + } + } } whd_result_t whd_bus_init(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_init_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_init_fptr(whd_driver); } whd_result_t whd_bus_deinit(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_deinit_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_deinit_fptr(whd_driver); } whd_bool_t whd_bus_wake_interrupt_present(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_wake_interrupt_present_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_wake_interrupt_present_fptr(whd_driver); } whd_result_t whd_bus_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer) { - return whd_driver->bus_if->whd_bus_send_buffer_fptr(whd_driver, buffer); + return whd_driver->bus_if->whd_bus_send_buffer_fptr(whd_driver, buffer); } uint32_t whd_bus_packet_available_to_read(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_packet_available_to_read_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_packet_available_to_read_fptr(whd_driver); } whd_result_t whd_bus_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer) { - return whd_driver->bus_if->whd_bus_read_frame_fptr(whd_driver, buffer); + return whd_driver->bus_if->whd_bus_read_frame_fptr(whd_driver, buffer); } whd_result_t whd_bus_write_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint32_t value) + uint32_t value) { - return whd_driver->bus_if->whd_bus_write_backplane_value_fptr(whd_driver, address, register_length, value); + return whd_driver->bus_if->whd_bus_write_backplane_value_fptr(whd_driver, address, register_length, value); } whd_result_t whd_bus_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint8_t *value) + uint8_t *value) { - return whd_driver->bus_if->whd_bus_read_backplane_value_fptr(whd_driver, address, register_length, value); + return whd_driver->bus_if->whd_bus_read_backplane_value_fptr(whd_driver, address, register_length, value); } whd_result_t whd_bus_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint8_t *value) + uint8_t value_length, uint8_t *value) { - return whd_driver->bus_if->whd_bus_read_register_value_fptr(whd_driver, function, address, value_length, value); + return whd_driver->bus_if->whd_bus_read_register_value_fptr(whd_driver, function, address, value_length, value); } whd_result_t whd_bus_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint32_t value) + uint8_t value_length, uint32_t value) { - return whd_driver->bus_if->whd_bus_write_register_value_fptr(whd_driver, function, address, value_length, value); + return whd_driver->bus_if->whd_bus_write_register_value_fptr(whd_driver, function, address, value_length, value); } whd_result_t whd_bus_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t size, - whd_transfer_bytes_packet_t *data) + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data) { - return whd_driver->bus_if->whd_bus_transfer_bytes_fptr(whd_driver, direction, function, address, size, data); + return whd_driver->bus_if->whd_bus_transfer_bytes_fptr(whd_driver, direction, function, address, size, data); } whd_result_t whd_bus_poke_wlan(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_poke_wlan_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_poke_wlan_fptr(whd_driver); } whd_result_t whd_bus_wakeup(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_wakeup_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_wakeup_fptr(whd_driver); } whd_result_t whd_bus_sleep(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_sleep_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_sleep_fptr(whd_driver); } whd_result_t whd_bus_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore) { - return whd_driver->bus_if->whd_bus_wait_for_wlan_event_fptr(whd_driver, transceive_semaphore); + return whd_driver->bus_if->whd_bus_wait_for_wlan_event_fptr(whd_driver, transceive_semaphore); } whd_bool_t whd_bus_use_status_report_scheme(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_use_status_report_scheme_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_use_status_report_scheme_fptr(whd_driver); } uint8_t whd_bus_backplane_read_padd_size(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_backplane_read_padd_size_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_backplane_read_padd_size_fptr(whd_driver); } uint32_t whd_bus_get_max_transfer_size(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_get_max_transfer_size_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_get_max_transfer_size_fptr(whd_driver); } void whd_bus_init_stats(whd_driver_t whd_driver) { - whd_driver->bus_if->whd_bus_init_stats_fptr(whd_driver); + whd_driver->bus_if->whd_bus_init_stats_fptr(whd_driver); } whd_result_t whd_bus_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) { - return whd_driver->bus_if->whd_bus_print_stats_fptr(whd_driver, reset_after_print); + return whd_driver->bus_if->whd_bus_print_stats_fptr(whd_driver, reset_after_print); } whd_result_t whd_bus_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware) { - return whd_driver->bus_if->whd_bus_reinit_stats_fptr(whd_driver, wake_from_firmware); + return whd_driver->bus_if->whd_bus_reinit_stats_fptr(whd_driver, wake_from_firmware); } whd_result_t whd_bus_irq_register(whd_driver_t whd_driver) { - return whd_driver->bus_if->whd_bus_irq_register_fptr(whd_driver); + return whd_driver->bus_if->whd_bus_irq_register_fptr(whd_driver); } whd_result_t whd_bus_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) { - return whd_driver->bus_if->whd_bus_irq_enable_fptr(whd_driver, enable); + return whd_driver->bus_if->whd_bus_irq_enable_fptr(whd_driver, enable); } whd_result_t whd_bus_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, - whd_bool_t direct_resource, uint32_t address, uint32_t image_size) + whd_bool_t direct_resource, uint32_t address, uint32_t image_size) +{ + return whd_driver->bus_if->whd_bus_download_resource_fptr(whd_driver, resource, direct_resource, address, + image_size); +} + +#ifdef BLHS_SUPPORT +whd_result_t whd_bus_common_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage) { - return whd_driver->bus_if->whd_bus_download_resource_fptr(whd_driver, resource, direct_resource, address, image_size); + return whd_driver->bus_if->whd_bus_blhs_fptr(whd_driver, stage); } + +#endif diff --git a/wi-fi/whd/bus_protocols/whd_bus.h b/wi-fi/whd/bus_protocols/whd_bus.h index 6a3420f8..8d1580ec 100644 --- a/wi-fi/whd/bus_protocols/whd_bus.h +++ b/wi-fi/whd/bus_protocols/whd_bus.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,20 +21,14 @@ #include "whd_bus_protocol_interface.h" #include "whd_resource_api.h" +#include "whd_bus_common.h" #ifndef INCLUDED_WHD_BUS_H_ #define INCLUDED_WHD_BUS_H_ #ifdef __cplusplus -extern "C" { -#endif - -#if 0 -typedef struct whd_bus_if *whd_bus_if_t; - -typedef whd_result_t (*whd_bus_transfer_t)(whd_bus_if_t *bus_if, whd_bus_transfer_direction_t dir, - uint8_t *data, uint16_t data_size, void *arg1, void *arg2, void *arg3, - void *arg4); +extern "C" +{ #endif typedef whd_result_t (*whd_bus_init_t)(whd_driver_t whd_driver); @@ -47,18 +41,18 @@ typedef whd_result_t (*whd_bus_read_frame_t)(whd_driver_t whd_driver, whd_buffer typedef whd_result_t (*whd_bus_set_backplane_window_t)(whd_driver_t whd_driver, uint32_t addr, uint32_t *cur_base_addr); typedef whd_result_t (*whd_bus_write_backplane_value_t)(whd_driver_t whd_driver, uint32_t address, - uint8_t register_length, uint32_t value); + uint8_t register_length, uint32_t value); typedef whd_result_t (*whd_bus_read_backplane_value_t)(whd_driver_t whd_driver, uint32_t address, - uint8_t register_length, uint8_t *value); + uint8_t register_length, uint8_t *value); typedef whd_result_t (*whd_bus_write_register_value_t)(whd_driver_t whd_driver, whd_bus_function_t function, - uint32_t address, uint8_t value_length, uint32_t value); + uint32_t address, uint8_t value_length, uint32_t value); typedef whd_result_t (*whd_bus_read_register_value_t)(whd_driver_t whd_driver, whd_bus_function_t function, - uint32_t address, uint8_t value_length, uint8_t *value); + uint32_t address, uint8_t value_length, uint8_t *value); typedef whd_result_t (*whd_bus_transfer_bytes_t)(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t size, - whd_transfer_bytes_packet_t *data); + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data); typedef whd_result_t (*whd_bus_poke_wlan_t)(whd_driver_t whd_driver); @@ -67,7 +61,7 @@ typedef whd_result_t (*whd_bus_sleep_t)(whd_driver_t whd_driver); typedef uint8_t (*whd_bus_backplane_read_padd_size_t)(whd_driver_t whd_driver); typedef whd_result_t (*whd_bus_send_buffer_t)(whd_driver_t whd_driver, whd_buffer_t buffer); typedef whd_result_t (*whd_bus_wait_for_wlan_event_t)(whd_driver_t whd_driver, - cy_semaphore_t *transceive_semaphore); + cy_semaphore_t *transceive_semaphore); typedef whd_bool_t (*whd_bus_use_status_report_scheme_t)(whd_driver_t whd_driver); typedef uint32_t (*whd_bus_get_max_transfer_size_t)(whd_driver_t whd_driver); @@ -77,47 +71,53 @@ typedef whd_result_t (*whd_bus_reinit_stats_t)(whd_driver_t whd_driver, whd_bool typedef whd_result_t (*whd_bus_irq_register_t)(whd_driver_t whd_driver); typedef whd_result_t (*whd_bus_irq_enable_t)(whd_driver_t whd_driver, whd_bool_t enable); typedef whd_result_t (*whd_bus_download_resource_t)(whd_driver_t whd_driver, whd_resource_type_t resource, - whd_bool_t direct_resource, uint32_t address, - uint32_t image_size); - -typedef struct whd_bus_info { - whd_bus_init_t whd_bus_init_fptr; - whd_bus_deinit_t whd_bus_deinit_fptr; - - whd_bus_ack_interrupt_t whd_bus_ack_interrupt_fptr; - whd_bus_send_buffer_t whd_bus_send_buffer_fptr; - - whd_bus_wake_interrupt_present_t whd_bus_wake_interrupt_present_fptr; - whd_bus_packet_available_to_read_t whd_bus_packet_available_to_read_fptr; - whd_bus_read_frame_t whd_bus_read_frame_fptr; - - whd_bus_set_backplane_window_t whd_bus_set_backplane_window_fptr; - whd_bus_write_backplane_value_t whd_bus_write_backplane_value_fptr; - whd_bus_read_backplane_value_t whd_bus_read_backplane_value_fptr; + whd_bool_t direct_resource, uint32_t address, + uint32_t image_size); +typedef whd_result_t (*whd_bus_blhs_t)(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage); + +typedef struct whd_bus_info +{ + whd_bus_init_t whd_bus_init_fptr; + whd_bus_deinit_t whd_bus_deinit_fptr; + + whd_bus_ack_interrupt_t whd_bus_ack_interrupt_fptr; + whd_bus_send_buffer_t whd_bus_send_buffer_fptr; + + whd_bus_wake_interrupt_present_t whd_bus_wake_interrupt_present_fptr; + whd_bus_packet_available_to_read_t whd_bus_packet_available_to_read_fptr; + whd_bus_read_frame_t whd_bus_read_frame_fptr; +#ifndef PROTO_MSGBUF + whd_bus_set_backplane_window_t whd_bus_set_backplane_window_fptr; +#endif + whd_bus_write_backplane_value_t whd_bus_write_backplane_value_fptr; + whd_bus_read_backplane_value_t whd_bus_read_backplane_value_fptr; - whd_bus_write_register_value_t whd_bus_write_register_value_fptr; - whd_bus_read_register_value_t whd_bus_read_register_value_fptr; + whd_bus_write_register_value_t whd_bus_write_register_value_fptr; + whd_bus_read_register_value_t whd_bus_read_register_value_fptr; - whd_bus_transfer_bytes_t whd_bus_transfer_bytes_fptr; + whd_bus_transfer_bytes_t whd_bus_transfer_bytes_fptr; - whd_bus_poke_wlan_t whd_bus_poke_wlan_fptr; + whd_bus_poke_wlan_t whd_bus_poke_wlan_fptr; - whd_bus_wakeup_t whd_bus_wakeup_fptr; - whd_bus_sleep_t whd_bus_sleep_fptr; + whd_bus_wakeup_t whd_bus_wakeup_fptr; + whd_bus_sleep_t whd_bus_sleep_fptr; - whd_bus_backplane_read_padd_size_t whd_bus_backplane_read_padd_size_fptr; + whd_bus_backplane_read_padd_size_t whd_bus_backplane_read_padd_size_fptr; - whd_bus_wait_for_wlan_event_t whd_bus_wait_for_wlan_event_fptr; - whd_bus_use_status_report_scheme_t whd_bus_use_status_report_scheme_fptr; + whd_bus_wait_for_wlan_event_t whd_bus_wait_for_wlan_event_fptr; + whd_bus_use_status_report_scheme_t whd_bus_use_status_report_scheme_fptr; - whd_bus_get_max_transfer_size_t whd_bus_get_max_transfer_size_fptr; + whd_bus_get_max_transfer_size_t whd_bus_get_max_transfer_size_fptr; - whd_bus_init_stats_t whd_bus_init_stats_fptr; - whd_bus_print_stats_t whd_bus_print_stats_fptr; - whd_bus_reinit_stats_t whd_bus_reinit_stats_fptr; - whd_bus_irq_register_t whd_bus_irq_register_fptr; - whd_bus_irq_enable_t whd_bus_irq_enable_fptr; - whd_bus_download_resource_t whd_bus_download_resource_fptr; + whd_bus_init_stats_t whd_bus_init_stats_fptr; + whd_bus_print_stats_t whd_bus_print_stats_fptr; + whd_bus_reinit_stats_t whd_bus_reinit_stats_fptr; + whd_bus_irq_register_t whd_bus_irq_register_fptr; + whd_bus_irq_enable_t whd_bus_irq_enable_fptr; + whd_bus_download_resource_t whd_bus_download_resource_fptr; +#ifdef BLHS_SUPPORT + whd_bus_blhs_t whd_bus_blhs_fptr; +#endif } whd_bus_info_t; diff --git a/wi-fi/whd/bus_protocols/whd_bus_common.c b/wi-fi/whd/bus_protocols/whd_bus_common.c index 910c1736..3bab4ed2 100644 --- a/wi-fi/whd/bus_protocols/whd_bus_common.c +++ b/wi-fi/whd/bus_protocols/whd_bus_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,8 +18,8 @@ /** @file * */ -#include #include "cyabs_rtos.h" +#include "whd_utils.h" #include "whd_bus.h" #include "whd_bus_common.h" @@ -35,42 +35,37 @@ #include "whd_resource_api.h" #include "whd_types_int.h" - /****************************************************** * Macros ******************************************************/ -#define WHD_SAVE_INTERRUPTS(flags) \ - do { \ - UNUSED_PARAMETER(flags); \ - } while (0); -#define WHD_RESTORE_INTERRUPTS(flags) \ - do { \ - } while (0); +#define WHD_SAVE_INTERRUPTS(flags) do { UNUSED_PARAMETER(flags); } while (0); +#define WHD_RESTORE_INTERRUPTS(flags) do { } while (0); /****************************************************** * Constants ******************************************************/ -#define INDIRECT_BUFFER_SIZE (1024) -#define WHD_BUS_ROUND_UP_ALIGNMENT (64) -#define WHD_BUS_MAX_TRANSFER_SIZE (WHD_BUS_MAX_BACKPLANE_TRANSFER_SIZE) +#define INDIRECT_BUFFER_SIZE (1024) +#define WHD_BUS_ROUND_UP_ALIGNMENT (64) +#define WHD_BUS_MAX_TRANSFER_SIZE (WHD_BUS_MAX_BACKPLANE_TRANSFER_SIZE) -#define WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS ((uint32_t)-1) +#define WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS ( (uint32_t)-1 ) /****************************************************** * Structures ******************************************************/ -struct whd_bus_common_info { - whd_bool_t bus_is_up; +struct whd_bus_common_info +{ + whd_bool_t bus_is_up; - whd_time_t delayed_bus_release_deadline; - whd_bool_t delayed_bus_release_scheduled; - uint32_t delayed_bus_release_timeout_ms; - volatile uint32_t delayed_bus_release_timeout_ms_request; + whd_time_t delayed_bus_release_deadline; + whd_bool_t delayed_bus_release_scheduled; + uint32_t delayed_bus_release_timeout_ms; + volatile uint32_t delayed_bus_release_timeout_ms_request; - uint32_t backplane_window_current_base_address; - whd_bool_t bus_flow_control; - volatile whd_bool_t resource_download_abort; + uint32_t backplane_window_current_base_address; + whd_bool_t bus_flow_control; + volatile whd_bool_t resource_download_abort; }; /****************************************************** @@ -88,276 +83,314 @@ whd_result_t whd_bus_common_write_wifi_nvram_image(whd_driver_t whd_driver); whd_bool_t whd_bus_is_up(whd_driver_t whd_driver) { - return whd_driver->bus_common_info->bus_is_up; + return whd_driver->bus_common_info->bus_is_up; } void whd_bus_set_state(whd_driver_t whd_driver, whd_bool_t state) { - whd_driver->bus_common_info->bus_is_up = state; + whd_driver->bus_common_info->bus_is_up = state; } whd_result_t whd_bus_set_flow_control(whd_driver_t whd_driver, uint8_t value) { - if (value != 0) { - whd_driver->bus_common_info->bus_flow_control = WHD_TRUE; - } - else { - whd_driver->bus_common_info->bus_flow_control = WHD_FALSE; - } - return WHD_SUCCESS; + if (value != 0) + { + whd_driver->bus_common_info->bus_flow_control = WHD_TRUE; + } + else + { + whd_driver->bus_common_info->bus_flow_control = WHD_FALSE; + } + return WHD_SUCCESS; } whd_bool_t whd_bus_is_flow_controlled(whd_driver_t whd_driver) { - return whd_driver->bus_common_info->bus_flow_control; + return whd_driver->bus_common_info->bus_flow_control; } - +#ifndef PROTO_MSGBUF whd_result_t whd_bus_set_backplane_window(whd_driver_t whd_driver, uint32_t addr) { - uint32_t *curbase = &whd_driver->bus_common_info->backplane_window_current_base_address; - return whd_driver->bus_if->whd_bus_set_backplane_window_fptr(whd_driver, addr, curbase); + uint32_t *curbase = &whd_driver->bus_common_info->backplane_window_current_base_address; + return whd_driver->bus_if->whd_bus_set_backplane_window_fptr(whd_driver, addr, curbase); } - - +#endif void whd_bus_common_info_init(whd_driver_t whd_driver) { - struct whd_bus_common_info *bus_common = (struct whd_bus_common_info *)malloc(sizeof(struct whd_bus_common_info)); - - if (bus_common != NULL) { - whd_driver->bus_common_info = bus_common; - - bus_common->delayed_bus_release_deadline = 0; - bus_common->delayed_bus_release_scheduled = WHD_FALSE; - bus_common->delayed_bus_release_timeout_ms = PLATFORM_WLAN_ALLOW_BUS_TO_SLEEP_DELAY_MS; - bus_common->delayed_bus_release_timeout_ms_request = WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS; - bus_common->backplane_window_current_base_address = 0; - - bus_common->bus_is_up = WHD_FALSE; - bus_common->bus_flow_control = WHD_FALSE; - - bus_common->resource_download_abort = WHD_FALSE; - } - else { - WPRINT_WHD_ERROR(("Memory allocation failed for whd_bus_common_info in %s\n", __FUNCTION__)); - } + struct whd_bus_common_info *bus_common = (struct whd_bus_common_info *)whd_mem_malloc(sizeof(struct whd_bus_common_info) ); + + if (bus_common != NULL) + { + whd_driver->bus_common_info = bus_common; + + bus_common->delayed_bus_release_deadline = 0; + bus_common->delayed_bus_release_scheduled = WHD_FALSE; + bus_common->delayed_bus_release_timeout_ms = PLATFORM_WLAN_ALLOW_BUS_TO_SLEEP_DELAY_MS; + bus_common->delayed_bus_release_timeout_ms_request = WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS; + bus_common->backplane_window_current_base_address = 0; + + bus_common->bus_is_up = WHD_FALSE; + bus_common->bus_flow_control = WHD_FALSE; + + bus_common->resource_download_abort = WHD_FALSE; + } + else + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bus_common_info in %s\n", __FUNCTION__) ); + } } void whd_bus_common_info_deinit(whd_driver_t whd_driver) { - if (whd_driver->bus_common_info != NULL) { - free(whd_driver->bus_common_info); - whd_driver->bus_common_info = NULL; - } + if (whd_driver->bus_common_info != NULL) + { + whd_mem_free(whd_driver->bus_common_info); + whd_driver->bus_common_info = NULL; + } } void whd_delayed_bus_release_schedule_update(whd_driver_t whd_driver, whd_bool_t is_scheduled) { - whd_driver->bus_common_info->delayed_bus_release_scheduled = is_scheduled; - whd_driver->bus_common_info->delayed_bus_release_deadline = 0; + whd_driver->bus_common_info->delayed_bus_release_scheduled = is_scheduled; + whd_driver->bus_common_info->delayed_bus_release_deadline = 0; } uint32_t whd_bus_handle_delayed_release(whd_driver_t whd_driver) { uint32_t time_until_release = 0; - whd_time_t current_time = 0; + cy_time_t current_time = 0; struct whd_bus_common_info *bus_common = whd_driver->bus_common_info; - if (bus_common->delayed_bus_release_timeout_ms_request != WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS) { - whd_bool_t schedule = - ((bus_common->delayed_bus_release_scheduled != 0) || - (bus_common->delayed_bus_release_deadline != 0)) ? - WHD_TRUE : - WHD_FALSE; - uint32_t flags; + if (bus_common->delayed_bus_release_timeout_ms_request != WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS) + { + whd_bool_t schedule = + ( (bus_common->delayed_bus_release_scheduled != 0) || + (bus_common->delayed_bus_release_deadline != 0) ) ? WHD_TRUE : WHD_FALSE; + uint32_t flags; - WHD_SAVE_INTERRUPTS(flags); - bus_common->delayed_bus_release_timeout_ms = bus_common->delayed_bus_release_timeout_ms_request; - bus_common->delayed_bus_release_timeout_ms_request = WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS; - WHD_RESTORE_INTERRUPTS(flags); + WHD_SAVE_INTERRUPTS(flags); + bus_common->delayed_bus_release_timeout_ms = bus_common->delayed_bus_release_timeout_ms_request; + bus_common->delayed_bus_release_timeout_ms_request = WHD_BUS_WLAN_ALLOW_SLEEP_INVALID_MS; + WHD_RESTORE_INTERRUPTS(flags); - DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule); - } + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule); + } - if (bus_common->delayed_bus_release_scheduled == WHD_TRUE) { - bus_common->delayed_bus_release_scheduled = WHD_FALSE; + if (bus_common->delayed_bus_release_scheduled == WHD_TRUE) + { + bus_common->delayed_bus_release_scheduled = WHD_FALSE; if (bus_common->delayed_bus_release_timeout_ms != 0) { cy_rtos_get_time(¤t_time); bus_common->delayed_bus_release_deadline = current_time + - bus_common->delayed_bus_release_timeout_ms; + bus_common->delayed_bus_release_timeout_ms; time_until_release = bus_common->delayed_bus_release_timeout_ms; } } else if (bus_common->delayed_bus_release_deadline != 0) { - whd_time_t now; - - cy_rtos_get_time(&now); - - if (bus_common->delayed_bus_release_deadline - now <= bus_common->delayed_bus_release_timeout_ms) { - time_until_release = bus_common->delayed_bus_release_deadline - now; - } - - if (time_until_release == 0) { - bus_common->delayed_bus_release_deadline = 0; - } - } - - if (time_until_release != 0) { - if (whd_bus_is_up(whd_driver) == WHD_FALSE) { - time_until_release = 0; - } - else if (whd_bus_platform_mcu_power_save_deep_sleep_enabled(whd_driver)) { - time_until_release = 0; - } - } - - return time_until_release; + cy_time_t now; + + cy_rtos_get_time(&now); + + if (bus_common->delayed_bus_release_deadline - now <= bus_common->delayed_bus_release_timeout_ms) + { + time_until_release = bus_common->delayed_bus_release_deadline - now; + } + + if (time_until_release == 0) + { + bus_common->delayed_bus_release_deadline = 0; + } + } + + if (time_until_release != 0) + { + if (whd_bus_is_up(whd_driver) == WHD_FALSE) + { + time_until_release = 0; + } + else if (whd_bus_platform_mcu_power_save_deep_sleep_enabled(whd_driver) ) + { + time_until_release = 0; + } + } + + return time_until_release; } whd_bool_t whd_bus_platform_mcu_power_save_deep_sleep_enabled(whd_driver_t whd_driver) { - return WHD_FALSE; + return WHD_FALSE; } void whd_bus_init_backplane_window(whd_driver_t whd_driver) { - whd_driver->bus_common_info->backplane_window_current_base_address = 0; + whd_driver->bus_common_info->backplane_window_current_base_address = 0; } whd_result_t whd_bus_write_wifi_firmware_image(whd_driver_t whd_driver) { - whd_result_t result = WHD_SUCCESS; - uint32_t ram_start_address; - uint32_t image_size; + whd_result_t result = WHD_SUCCESS; + uint32_t ram_start_address; + uint32_t image_size; - /* Pass the ram_start_address to the firmware Download +#ifdef BLHS_SUPPORT + CHECK_RETURN(whd_bus_common_blhs(whd_driver, PREP_FW_DOWNLOAD) ); +#endif + + /* Pass the ram_start_address to the firmware Download * CR4 chips have offset and CM3 starts from 0 */ - ram_start_address = GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + ram_start_address = GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); - result = whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, &image_size); + result = whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, &image_size); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Fatal error: download_resource doesn't exist, %s failed at line %d \n", __func__, - __LINE__)); - return result; - } + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource doesn't exist, %s failed at line %d \n", __func__, + __LINE__) ); + return result; + } - if (image_size <= 0) { - WPRINT_WHD_ERROR(("Fatal error: download_resource cannot load with invalid size, %s failed at line %d \n", - __func__, __LINE__)); - return WHD_BADARG; - } + if (image_size <= 0) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource cannot load with invalid size, %s failed at line %d \n", + __func__, __LINE__) ); + return WHD_BADARG; + } - result = whd_bus_download_resource(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, WHD_FALSE, ram_start_address, image_size); + result = + whd_bus_download_resource(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, WHD_FALSE, ram_start_address, image_size); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Bus common resource download failed, %s failed at %d \n", __func__, __LINE__)); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Bus common resource download failed, %s failed at %d \n", __func__, __LINE__) ); - return result; +#ifdef BLHS_SUPPORT + CHECK_RETURN(whd_bus_common_blhs(whd_driver, POST_FW_DOWNLOAD) ); + CHECK_RETURN(whd_bus_common_blhs(whd_driver, CHK_FW_VALIDATION) ); +#endif + + return result; } void whd_bus_set_resource_download_halt(whd_driver_t whd_driver, whd_bool_t halt) { - whd_driver->bus_common_info->resource_download_abort = halt; + whd_driver->bus_common_info->resource_download_abort = halt; } /* Default implementation of WHD bus resume function, which does nothing */ whd_result_t whd_bus_resume_after_deep_sleep(whd_driver_t whd_driver) { - whd_assert("In order to support deep-sleep platform need to implement this function", 0); - return WHD_UNSUPPORTED; + whd_assert("In order to support deep-sleep platform need to implement this function", 0); + return WHD_UNSUPPORTED; } whd_result_t whd_bus_mem_bytes(whd_driver_t whd_driver, uint8_t direct, - uint32_t address, uint32_t size, uint8_t *data) + uint32_t address, uint32_t size, uint8_t *data) { - whd_bus_transfer_direction_t direction = direct ? BUS_WRITE : BUS_READ; - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); - return whd_bus_transfer_backplane_bytes(whd_driver, direction, address, size, data); + whd_bus_transfer_direction_t direction = direct ? BUS_WRITE : BUS_READ; + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); +#ifndef PROTO_MSGBUF + return whd_bus_transfer_backplane_bytes(whd_driver, direction, address, size, data); +#else + return whd_bus_transfer_bytes(whd_driver, direction, BACKPLANE_FUNCTION, address, size, (whd_transfer_bytes_packet_t *)data); +#endif } whd_result_t whd_bus_transfer_backplane_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - uint32_t address, uint32_t size, uint8_t *data) + uint32_t address, uint32_t size, uint8_t *data) { - whd_buffer_t pkt_buffer = NULL; - uint8_t *packet; - uint32_t transfer_size; - uint32_t remaining_buf_size; - uint32_t window_offset_address; - uint32_t trans_addr; - whd_result_t result; - - result = whd_host_buffer_get(whd_driver, &pkt_buffer, (direction == BUS_READ) ? WHD_NETWORK_RX : WHD_NETWORK_TX, - (uint16_t)(whd_bus_get_max_transfer_size(whd_driver) + - whd_bus_backplane_read_padd_size( - whd_driver) + - MAX_BUS_HEADER_SIZE), - WHD_BACKPLAIN_BUF_TIMEOUT); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Packet buffer allocation failed in %s at %d \n", __func__, __LINE__)); - goto done; - } - packet = (uint8_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, pkt_buffer); - CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); - for (remaining_buf_size = size; remaining_buf_size != 0; - remaining_buf_size -= transfer_size, address += transfer_size) { - transfer_size = (remaining_buf_size > - whd_bus_get_max_transfer_size(whd_driver)) ? - whd_bus_get_max_transfer_size(whd_driver) : - remaining_buf_size; - - /* Check if the transfer crosses the backplane window boundary */ - window_offset_address = address & BACKPLANE_ADDRESS_MASK; - if ((window_offset_address + transfer_size) > BACKPLANE_ADDRESS_MASK) { - /* Adjust the transfer size to within current window */ - transfer_size = BACKPLANE_WINDOW_SIZE - window_offset_address; - } - result = whd_bus_set_backplane_window(whd_driver, address); - if (result == WHD_UNSUPPORTED) { - /* No backplane support, write data to address directly */ - trans_addr = address; - } - else if (result == WHD_SUCCESS) { - trans_addr = address & BACKPLANE_ADDRESS_MASK; - } - else { - goto done; - } - - if (direction == BUS_WRITE) { - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(((whd_transfer_bytes_packet_t *)packet)->data, data + size - remaining_buf_size, transfer_size); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - result = whd_bus_transfer_bytes(whd_driver, direction, BACKPLANE_FUNCTION, - trans_addr, (uint16_t)transfer_size, - (whd_transfer_bytes_packet_t *)packet); - if (result != WHD_SUCCESS) { - goto done; - } - } - else { - result = whd_bus_transfer_bytes(whd_driver, direction, BACKPLANE_FUNCTION, - trans_addr, - (uint16_t)(transfer_size + whd_bus_backplane_read_padd_size(whd_driver)), - (whd_transfer_bytes_packet_t *)packet); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("whd_bus_transfer_bytes failed\n")); - goto done; - } - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(data + size - remaining_buf_size, (uint8_t *)((whd_transfer_bytes_packet_t *)packet)->data + whd_bus_backplane_read_padd_size(whd_driver), transfer_size); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - } - } + whd_buffer_t pkt_buffer = NULL; + uint8_t *packet; + uint32_t transfer_size; + uint32_t remaining_buf_size; + uint32_t window_offset_address; + uint32_t trans_addr; + whd_result_t result; + + result = whd_host_buffer_get(whd_driver, &pkt_buffer, (direction == BUS_READ) ? WHD_NETWORK_RX : WHD_NETWORK_TX, + ( uint16_t )(whd_bus_get_max_transfer_size(whd_driver) + + whd_bus_backplane_read_padd_size( + whd_driver) + MAX_BUS_HEADER_SIZE), WHD_BACKPLAIN_BUF_TIMEOUT); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Packet buffer allocation failed in %s at %d \n", __func__, __LINE__) ); + goto done; + } + packet = (uint8_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, pkt_buffer); + CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); + for (remaining_buf_size = size; remaining_buf_size != 0; + remaining_buf_size -= transfer_size, address += transfer_size) + { + transfer_size = (remaining_buf_size > + whd_bus_get_max_transfer_size(whd_driver) ) ? whd_bus_get_max_transfer_size(whd_driver) : + remaining_buf_size; + + /* Check if the transfer crosses the backplane window boundary */ + window_offset_address = address & BACKPLANE_ADDRESS_MASK; + if ( (window_offset_address + transfer_size) > BACKPLANE_ADDRESS_MASK ) + { + /* Adjust the transfer size to within current window */ + transfer_size = BACKPLANE_WINDOW_SIZE - window_offset_address; + } +#ifndef PROTO_MSGBUF + result = whd_bus_set_backplane_window(whd_driver, address); +#endif + if (result == WHD_UNSUPPORTED) + { + /* No backplane support, write data to address directly */ + trans_addr = address; + } + else if (result == WHD_SUCCESS) + { + trans_addr = address & BACKPLANE_ADDRESS_MASK; + } + else + { + goto done; + } + + if (direction == BUS_WRITE) + { + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy( ( (whd_transfer_bytes_packet_t *)packet )->data, data + size - remaining_buf_size, transfer_size ); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + result = whd_bus_transfer_bytes(whd_driver, direction, BACKPLANE_FUNCTION, + trans_addr, (uint16_t)transfer_size, + (whd_transfer_bytes_packet_t *)packet); + if (result != WHD_SUCCESS) + { + goto done; + } + } + else + { + result = whd_bus_transfer_bytes(whd_driver, direction, BACKPLANE_FUNCTION, + trans_addr, + ( uint16_t )(transfer_size + whd_bus_backplane_read_padd_size(whd_driver) ), + (whd_transfer_bytes_packet_t *)packet); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_transfer_bytes failed\n") ); + goto done; + } + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(data + size - remaining_buf_size, (uint8_t *)( (whd_transfer_bytes_packet_t *)packet )->data + + whd_bus_backplane_read_padd_size(whd_driver), transfer_size); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + } + } done: - whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); - if (pkt_buffer != NULL) { - CHECK_RETURN(whd_buffer_release(whd_driver, pkt_buffer, - (direction == BUS_READ) ? WHD_NETWORK_RX : WHD_NETWORK_TX)); - } - CHECK_RETURN(result); - - return WHD_SUCCESS; +#ifndef PROTO_MSGBUF + whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); +#endif + if (pkt_buffer != NULL) + { + CHECK_RETURN(whd_buffer_release(whd_driver, pkt_buffer, + (direction == BUS_READ) ? WHD_NETWORK_RX : WHD_NETWORK_TX) ); + } + CHECK_RETURN(result); + + return WHD_SUCCESS; } diff --git a/wi-fi/whd/bus_protocols/whd_bus_common.h b/wi-fi/whd/bus_protocols/whd_bus_common.h index 6003a241..9658ed80 100644 --- a/wi-fi/whd/bus_protocols/whd_bus_common.h +++ b/wi-fi/whd/bus_protocols/whd_bus_common.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,6 +15,7 @@ * limitations under the License. */ #include "whd.h" +#include "whd_trxhdr.h" #include #ifndef INCLUDED_WHD_BUS_COMMON_H @@ -24,9 +25,21 @@ extern "C" { #endif -#define WHD_BACKPLAIN_BUF_TIMEOUT (0xFFFFFFFF) -#define WHD_RX_BUF_TIMEOUT (10) +#define WHD_BACKPLAIN_BUF_TIMEOUT (0xFFFFFFFF) +#define WHD_RX_BUF_TIMEOUT (10) +typedef enum +{ + CHK_BL_INIT = 0, + PREP_FW_DOWNLOAD, + POST_FW_DOWNLOAD, + CHK_FW_VALIDATION, +#ifdef DM_43022C1 + PREP_NVRAM_DOWNLOAD, +#endif + POST_NVRAM_DOWNLOAD, + POST_WATCHDOG_RESET +} whd_bus_blhs_stage_t; struct whd_bus_common_info; @@ -37,15 +50,15 @@ void whd_bus_common_info_deinit(whd_driver_t whd_driver); * A high number will mean a longer delay before sleep after the last operation (higher performance) * A shorter delay will mean quicker sleep after last operation (lower power use) */ -extern void whd_bus_sdio_wlan_set_delayed_bus_powersave_milliseconds(whd_driver_t whd_driver, uint32_t time_ms); +extern void whd_bus_sdio_wlan_set_delayed_bus_powersave_milliseconds(whd_driver_t whd_driver, uint32_t time_ms); extern whd_result_t whd_bus_resume_after_deep_sleep(whd_driver_t whd_driver); extern whd_result_t whd_bus_write_wifi_firmware_image(whd_driver_t whd_driver); extern whd_result_t whd_bus_write_wifi_nvram_image(whd_driver_t whd_driver); -extern void whd_bus_set_resource_download_halt(whd_driver_t whd_driver, whd_bool_t halt); +extern void whd_bus_set_resource_download_halt(whd_driver_t whd_driver, whd_bool_t halt); extern whd_result_t whd_bus_transfer_backplane_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - uint32_t address, uint32_t size, uint8_t *data); + uint32_t address, uint32_t size, uint8_t *data); extern void whd_bus_init_backplane_window(whd_driver_t whd_driver); whd_result_t whd_bus_set_backplane_window(whd_driver_t whd_driver, uint32_t addr); @@ -58,7 +71,7 @@ void whd_bus_set_state(whd_driver_t whd_driver, whd_bool_t state); extern void whd_delayed_bus_release_schedule_update(whd_driver_t whd_driver, whd_bool_t is_scheduled); /* handle delayed sleep of bus */ -extern uint32_t whd_bus_handle_delayed_release(whd_driver_t whd_driver); +extern uint32_t whd_bus_handle_delayed_release(whd_driver_t whd_driver); whd_bool_t whd_bus_platform_mcu_power_save_deep_sleep_enabled(whd_driver_t whd_driver); #ifdef __cplusplus } /*extern "C" */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.c b/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.c new file mode 100644 index 00000000..b5f714f4 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.c @@ -0,0 +1,789 @@ +/* + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * Broadcom WLAN M2M Protocol interface + * + * Implements the WHD Bus Protocol Interface for M2M + * Provides functions for initialising, de-intitialising 802.11 device, + * sending/receiving raw packets etc + */ + +#include "cybsp.h" +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) + +#include "cyhal_dma.h" +#include "cyhal_hw_types.h" +#include "whd_bus_m2m_protocol.h" + +#include "whd_bus.h" +#include "whd_bus_common.h" +#include "whd_chip_reg.h" +#include "whd_chip_constants.h" +#include "whd_buffer_api.h" +#include "whd_types_int.h" +#include "whd_types.h" +#include "whd_thread_internal.h" +#include "whd_resource_if.h" +#include "whd_wlioctl.h" +#include "whd_m2m.h" +#include "whd_proto.h" +#ifdef PROTO_MSGBUF +#include "whd_ring.h" +#endif /* PROTO_MSGBUF */ +/****************************************************** +* Constants +******************************************************/ + +#define WHD_BUS_M2M_BACKPLANE_READ_PADD_SIZE (0) +#define WHD_BUS_M2M_MAX_BACKPLANE_TRANSFER_SIZE (WHD_PAYLOAD_MTU) +#define BOOT_WLAN_WAIT_TIME (5) /* 5ms wait time */ +#define M2M_DMA_RX_BUFFER_SIZE (WHD_PHYSICAL_HEADER + WLC_IOCTL_MEDLEN) + +#define ARMCR4_SW_INT0 (0x1 << 0) + +#if !defined (__IAR_SYSTEMS_ICC__) +/* assume registers are Device memory, so have implicit CPU memory barriers */ +#define MEMORY_BARRIER_AGAINST_COMPILER_REORDERING() __asm__ __volatile__ ("" : : : "memory") +#define REGISTER_WRITE_WITH_BARRIER(type, address, value) \ + do {*(volatile type *)(address) = (type)(value); \ + MEMORY_BARRIER_AGAINST_COMPILER_REORDERING();} while (0) +#define REGISTER_READ(type, address) \ + (*(volatile type *)(address) ) +#endif + +#define WHD_THREAD_POLL_TIMEOUT (CY_RTOS_NEVER_TIMEOUT) + +/****************************************************** +* Structures +******************************************************/ +struct whd_bus_priv +{ + whd_m2m_config_t m2m_config; + cyhal_m2m_t *m2m_obj; +}; + +/****************************************************** +* Variables +******************************************************/ +static whd_bus_info_t whd_bus_m2m_info; +static struct whd_bus_priv whd_bus_priv; + +/****************************************************** +* Function declarations +******************************************************/ +static whd_result_t whd_bus_m2m_init(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_deinit(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus); +static whd_result_t whd_bus_m2m_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer); + +static whd_bool_t whd_bus_m2m_wake_interrupt_present(whd_driver_t whd_driver); +static uint32_t whd_bus_m2m_packet_available_to_read(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer); + +static whd_result_t whd_bus_m2m_write_backplane_value(whd_driver_t whd_driver, uint32_t address, + uint8_t register_length, uint32_t value); +static whd_result_t whd_bus_m2m_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, + uint8_t *value); +static whd_result_t whd_bus_m2m_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint32_t value); +static whd_result_t whd_bus_m2m_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint8_t *value); +static whd_result_t whd_bus_m2m_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data); + +static whd_result_t whd_bus_m2m_poke_wlan(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_wakeup(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_sleep(whd_driver_t whd_driver); +static uint8_t whd_bus_m2m_backplane_read_padd_size(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore); +static whd_bool_t whd_bus_m2m_use_status_report_scheme(whd_driver_t whd_driver); +static uint32_t whd_bus_m2m_get_max_transfer_size(whd_driver_t whd_driver); +static void whd_bus_m2m_init_stats(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print); +static whd_result_t whd_bus_m2m_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware); +static whd_result_t whd_bus_m2m_irq_register(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_irq_enable(whd_driver_t whd_driver, whd_bool_t enable); +#ifdef BLHS_SUPPORT +static whd_result_t whd_bus_m2m_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage); +#endif /* BLHS_SUPPORT */ +static whd_result_t whd_bus_m2m_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, uint32_t image_size); +static whd_result_t whd_bus_m2m_write_wifi_nvram_image(whd_driver_t whd_driver); +static whd_result_t whd_bus_m2m_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *curaddr); + +static whd_result_t boot_wlan(whd_driver_t whd_driver); +whd_bool_t whd_ensure_wlan_is_up(whd_driver_t whd_driver); +whd_result_t m2m_bus_write_wifi_firmware_image(whd_driver_t whd_driver); +void whd_bus_m2m_irq_handler(void *callback_arg, cyhal_m2m_event_t events); + + +/****************************************************** +* Function definitions +******************************************************/ + +// Functions for whd_driver->bus_if function list +whd_result_t whd_bus_m2m_attach(whd_driver_t whd_driver, whd_m2m_config_t *whd_m2m_config, cyhal_m2m_t *m2m_obj) +{ + WPRINT_WHD_INFO( ("m2m_attach\n") ); + + whd_driver->bus_if = &whd_bus_m2m_info; + whd_driver->bus_priv = &whd_bus_priv; + + memset(whd_driver->bus_if, 0, sizeof(whd_bus_info_t) ); + memset(whd_driver->bus_priv, 0, sizeof(struct whd_bus_priv) ); + + whd_driver->bus_priv->m2m_obj = m2m_obj; + whd_driver->bus_priv->m2m_config = *whd_m2m_config; + +#ifndef PROTO_MSGBUF + whd_driver->proto_type = WHD_PROTO_BCDC; +#else + whd_driver->proto_type = WHD_PROTO_MSGBUF; +#endif /* PROTO_MSGBUF */ + + whd_driver->bus_if->whd_bus_init_fptr = whd_bus_m2m_init; + whd_driver->bus_if->whd_bus_deinit_fptr = whd_bus_m2m_deinit; + + whd_driver->bus_if->whd_bus_ack_interrupt_fptr = whd_bus_m2m_ack_interrupt; + whd_driver->bus_if->whd_bus_send_buffer_fptr = whd_bus_m2m_send_buffer; + + whd_driver->bus_if->whd_bus_wake_interrupt_present_fptr = whd_bus_m2m_wake_interrupt_present; + whd_driver->bus_if->whd_bus_packet_available_to_read_fptr = whd_bus_m2m_packet_available_to_read; + whd_driver->bus_if->whd_bus_read_frame_fptr = whd_bus_m2m_read_frame; + + + whd_driver->bus_if->whd_bus_write_backplane_value_fptr = whd_bus_m2m_write_backplane_value; + whd_driver->bus_if->whd_bus_read_backplane_value_fptr = whd_bus_m2m_read_backplane_value; + + whd_driver->bus_if->whd_bus_write_register_value_fptr = whd_bus_m2m_write_register_value; + whd_driver->bus_if->whd_bus_read_register_value_fptr = whd_bus_m2m_read_register_value; + + whd_driver->bus_if->whd_bus_transfer_bytes_fptr = whd_bus_m2m_transfer_bytes; + + whd_driver->bus_if->whd_bus_poke_wlan_fptr = whd_bus_m2m_poke_wlan; + + whd_driver->bus_if->whd_bus_wakeup_fptr = whd_bus_m2m_wakeup; + whd_driver->bus_if->whd_bus_sleep_fptr = whd_bus_m2m_sleep; + + whd_driver->bus_if->whd_bus_backplane_read_padd_size_fptr = whd_bus_m2m_backplane_read_padd_size; + + whd_driver->bus_if->whd_bus_wait_for_wlan_event_fptr = whd_bus_m2m_wait_for_wlan_event; + whd_driver->bus_if->whd_bus_use_status_report_scheme_fptr = whd_bus_m2m_use_status_report_scheme; + + whd_driver->bus_if->whd_bus_get_max_transfer_size_fptr = whd_bus_m2m_get_max_transfer_size; + + whd_driver->bus_if->whd_bus_init_stats_fptr = whd_bus_m2m_init_stats; + whd_driver->bus_if->whd_bus_print_stats_fptr = whd_bus_m2m_print_stats; + whd_driver->bus_if->whd_bus_reinit_stats_fptr = whd_bus_m2m_reinit_stats; + whd_driver->bus_if->whd_bus_irq_register_fptr = whd_bus_m2m_irq_register; + whd_driver->bus_if->whd_bus_irq_enable_fptr = whd_bus_m2m_irq_enable; + whd_driver->bus_if->whd_bus_download_resource_fptr = whd_bus_m2m_download_resource; + whd_driver->bus_if->whd_bus_set_backplane_window_fptr = whd_bus_m2m_set_backplane_window; + +#ifdef BLHS_SUPPORT + whd_driver->bus_if->whd_bus_blhs_fptr = whd_bus_m2m_blhs; +#endif /* BLHS_SUPPORT */ + return WHD_SUCCESS; +} + +void whd_bus_m2m_detach(whd_driver_t whd_driver) +{ + whd_driver->bus_if = NULL; + whd_driver->bus_priv = NULL; +} + +void whd_bus_m2m_irq_handler(void *callback_arg, cyhal_m2m_event_t events) +{ + whd_driver_t whd_driver = (whd_driver_t)callback_arg; + + whd_bus_m2m_irq_enable(whd_driver, WHD_FALSE); + whd_thread_notify_irq(whd_driver); +} + +static whd_result_t whd_bus_m2m_init(whd_driver_t whd_driver) +{ + whd_result_t result = WHD_SUCCESS; + +#if !defined (__IAR_SYSTEMS_ICC__) + /* Get chip id */ + whd_chip_set_chip_id(whd_driver, (uint16_t)REGISTER_READ(uint32_t, CHIPCOMMON_BASE_ADDRESS) ); +#endif + + result = boot_wlan(whd_driver); + +#ifdef PROTO_MSGBUF + CHECK_RETURN(whd_bus_m2m_sharedmem_init(whd_driver) ); +#else + if (result == WHD_SUCCESS) + { + cyhal_m2m_init(whd_driver->bus_priv->m2m_obj, M2M_DMA_RX_BUFFER_SIZE); + cyhal_m2m_register_callback(whd_driver->bus_priv->m2m_obj, whd_bus_m2m_irq_handler, whd_driver); + } +#endif /* PROTO_MSGBUF */ + + return result; +} + +static whd_result_t whd_bus_m2m_deinit(whd_driver_t whd_driver) +{ + //PLATFORM_WLAN_POWERSAVE_RES_UP(); + + /* Down M2M and WLAN */ + CHECK_RETURN(whd_disable_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_CPU_HALT) ); + cyhal_m2m_free(whd_driver->bus_priv->m2m_obj); + + /* Put WLAN to reset. */ + //host_platform_reset_wifi( WICED_TRUE ); + + //PLATFORM_WLAN_POWERSAVE_RES_DOWN( NULL, WICED_FALSE ); + + /* Force resource down even if resource up/down is unbalanced */ + //PLATFORM_WLAN_POWERSAVE_RES_DOWN( NULL, WICED_TRUE ); + + CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver) ); + + whd_bus_set_resource_download_halt(whd_driver, WHD_FALSE); + + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_FALSE); + + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus) +{ + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer) +{ + whd_result_t result = WHD_SUCCESS; + + if (cyhal_m2m_tx_send(whd_driver->bus_priv->m2m_obj, buffer) != CY_RSLT_SUCCESS) + { + result = WHD_WLAN_ERROR; + } + + return result; +} + +static whd_bool_t whd_bus_m2m_wake_interrupt_present(whd_driver_t whd_driver) +{ + /* functionality is only currently needed and present on SDIO */ + return WHD_FALSE; +} + +static uint32_t whd_bus_m2m_packet_available_to_read(whd_driver_t whd_driver) +{ + return 1; +} + +static whd_result_t whd_bus_m2m_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer) +{ + whd_result_t result = WHD_SUCCESS; + cyhal_m2m_event_t m2m_event; + uint16_t *hwtag; + void *packet = NULL; + bool signal_txdone; + + cyhal_m2m_rx_prepare(whd_driver->bus_priv->m2m_obj); + + m2m_event = cyhal_m2m_intr_status(whd_driver->bus_priv->m2m_obj, &signal_txdone); + if (signal_txdone) + { + /* Signal WLAN core there is a TX done by setting wlancr4 SW interrupt 0 */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, GET_C_VAR(whd_driver, PMU_BASE_ADDRESS) + 0x1c, + (uint8_t)4, ARMCR4_SW_INT0) ); + } + + /* Handle DMA interrupts */ + if ( (m2m_event & CYHAL_M2M_TX_CHANNEL_INTERRUPT) != 0 ) + { + cyhal_m2m_tx_release(whd_driver->bus_priv->m2m_obj); + } + + /* Handle DMA receive interrupt */ + cyhal_m2m_rx_receive(whd_driver->bus_priv->m2m_obj, &packet, &hwtag); + if (packet == NULL) + { + result = WHD_NO_PACKET_TO_RECEIVE; + } + else + { + *buffer = packet; + + /* move the data pointer 12 bytes(sizeof(wwd_buffer_header_t)) + * back to the start of the pakcet + */ + whd_buffer_add_remove_at_front(whd_driver, buffer, -(int)sizeof(whd_buffer_header_t) ); +#ifndef PROTO_MSGBUF + whd_sdpcm_update_credit(whd_driver, (uint8_t *)hwtag); +#endif /* PROTO_MSGBUF */ + } + + cyhal_m2m_rx_prepare(whd_driver->bus_priv->m2m_obj); + + return result; +} + +static whd_result_t whd_bus_m2m_write_backplane_value(whd_driver_t whd_driver, uint32_t address, + uint8_t register_length, uint32_t value) +{ +#if !defined (__IAR_SYSTEMS_ICC__) + MEMORY_BARRIER_AGAINST_COMPILER_REORDERING(); + + if (register_length == 4) + { + REGISTER_WRITE_WITH_BARRIER(uint32_t, address, value); + } + else if (register_length == 2) + { + REGISTER_WRITE_WITH_BARRIER(uint16_t, address, value); + } + else if (register_length == 1) + { + REGISTER_WRITE_WITH_BARRIER(uint8_t, address, value); + } + else + { + return WHD_WLAN_ERROR; + } +#endif + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_read_backplane_value(whd_driver_t whd_driver, uint32_t address, + uint8_t register_length, /*@out@*/ uint8_t *value) +{ +#if !defined (__IAR_SYSTEMS_ICC__) + MEMORY_BARRIER_AGAINST_COMPILER_REORDERING(); + + if (register_length == 4) + { + *( (uint32_t *)value ) = REGISTER_READ(uint32_t, address); + } + else if (register_length == 2) + { + *( (uint16_t *)value ) = REGISTER_READ(uint16_t, address); + } + else if (register_length == 1) + { + *value = REGISTER_READ(uint8_t, address); + } + else + { + return WHD_WLAN_ERROR; + } +#endif + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint32_t value) +{ + // Not used by M2M bus + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint8_t *value) +{ + // Not used by M2M bus + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data) +{ + if (function != BACKPLANE_FUNCTION) + { + return WHD_DOES_NOT_EXIST; + } + + if (direction == BUS_WRITE) + { + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy( (uint8_t *)address, data->data, size ); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + if (address == 0) + { + uint32_t resetinst = *( (uint32_t *)data->data ); + + /* CR4_FF_ROM_SHADOW_INDEX_REGISTER */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, GET_C_VAR(whd_driver, PMU_BASE_ADDRESS) + 0x080, + (uint8_t)1, 0) ); + + /* CR4_FF_ROM_SHADOW_DATA_REGISTER */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, GET_C_VAR(whd_driver, PMU_BASE_ADDRESS) + 0x084, + (uint8_t)4, resetinst) ); + } + } + else + { + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(data->data, (uint8_t *)address, size); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + } + + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_poke_wlan(whd_driver_t whd_driver) +{ + // Not used by M2M bus + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_wakeup(whd_driver_t whd_driver) +{ + WPRINT_WHD_INFO( ("bus_m2m_wakeup\n") ); + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_sleep(whd_driver_t whd_driver) +{ + WPRINT_WHD_INFO( ("bus_m2m_sleep\n") ); + return WHD_SUCCESS; +} + +static uint8_t whd_bus_m2m_backplane_read_padd_size(whd_driver_t whd_driver) +{ + return WHD_BUS_M2M_BACKPLANE_READ_PADD_SIZE; +} + +static whd_result_t whd_bus_m2m_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore) +{ + whd_result_t result = WHD_SUCCESS; + uint32_t timeout_ms; + +#ifdef PROTO_MSGBUF + timeout_ms = 1; + uint32_t delayed_release_timeout_ms; + + delayed_release_timeout_ms = whd_bus_handle_delayed_release(whd_driver); + if (delayed_release_timeout_ms != 0) + { + timeout_ms = delayed_release_timeout_ms; + } + else + { + result = whd_bus_suspend(whd_driver); + + if (result == WHD_SUCCESS) + { + timeout_ms = CY_RTOS_NEVER_TIMEOUT; + } + } + + result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, + WHD_THREAD_POLL_TIMEOUT), WHD_FALSE); +#else + timeout_ms = CY_RTOS_NEVER_TIMEOUT; + whd_bus_m2m_irq_enable(whd_driver, WHD_TRUE); + result = cy_rtos_get_semaphore(transceive_semaphore, timeout_ms, WHD_FALSE); +#endif + return result; +} + +static whd_bool_t whd_bus_m2m_use_status_report_scheme(whd_driver_t whd_driver) +{ + /* !M2M_RX_POLL_MODE */ + return WHD_FALSE; +} + +static uint32_t whd_bus_m2m_get_max_transfer_size(whd_driver_t whd_driver) +{ + return WHD_BUS_M2M_MAX_BACKPLANE_TRANSFER_SIZE; +} + +static void whd_bus_m2m_init_stats(whd_driver_t whd_driver) +{ + /* To be implemented */ +} + +static whd_result_t whd_bus_m2m_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) +{ + /* To be implemented */ + UNUSED_VARIABLE(reset_after_print); + WPRINT_MACRO( ("Bus stats not available\n") ); + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_m2m_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware) +{ + UNUSED_PARAMETER(wake_from_firmware); + /* functionality is only currently needed and present on SDIO */ + return WHD_UNSUPPORTED; +} + +static whd_result_t whd_bus_m2m_irq_register(whd_driver_t whd_driver) +{ + return WHD_TRUE; +} + +static whd_result_t whd_bus_m2m_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + if (enable) + { + WPRINT_WHD_INFO( ("M2M interrupt enable\n") ); + _cyhal_system_m2m_enable_irq(); + _cyhal_system_sw0_enable_irq(); + } + else + { + WPRINT_WHD_INFO( ("M2M interrupt disable\n") ); + _cyhal_system_m2m_disable_irq(); + _cyhal_system_sw0_disable_irq(); + } + return WHD_TRUE; +} + +whd_result_t m2m_bus_write_wifi_firmware_image(whd_driver_t whd_driver) +{ +#ifndef PROTO_MSGBUF + /* Halt ARM and remove from reset */ + WPRINT_WHD_INFO( ("Reset wlan core..\n") ); + VERIFY_RESULT(whd_reset_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_CPU_HALT) ); +#endif /* PROTO_MSGBUF */ + + return whd_bus_write_wifi_firmware_image(whd_driver); +} + +static whd_result_t boot_wlan(whd_driver_t whd_driver) +{ + whd_result_t result = WHD_SUCCESS; + + /* Load wlan firmware from sflash */ + result = m2m_bus_write_wifi_firmware_image(whd_driver); + if ( (result == WHD_UNFINISHED) || (result != WHD_SUCCESS) ) + { + /* for user abort, then put wifi module into known good state */ + return result; + } + + VERIFY_RESULT(whd_bus_m2m_write_wifi_nvram_image(whd_driver) ); + +#ifndef PROTO_MSGBUF + /* Release ARM core */ + WPRINT_WHD_INFO( ("Release WLAN core..\n") ); + VERIFY_RESULT(whd_wlan_armcore_run(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE) ); + +#if (PLATFORM_BACKPLANE_ON_CPU_CLOCK_ENABLE == 0) + /* + * Wifi firmware initialization will change some BBPLL settings. When backplane clock + * source is not on CPU clock, accessing backplane during that period might wedge the + * ACPU. Running a delay loop in cache can avoid the wedge. At least 3ms is required + * to avoid the problem. + */ + cy_rtos_delay_milliseconds(10); +#endif /* PLATFORM_BACKPLANE_ON_CPU_CLOCK_ENABLE == 0 */ +#endif /* PROTO_MSGBUF */ + + return result; +} + +#ifdef BLHS_SUPPORT +uint8_t whd_bus_m2m_blhs_read_h2d(whd_driver_t whd_driver, uint32_t *val) +{ + return whd_bus_m2m_read_backplane_value(whd_driver, (uint32_t)M2M_REG_DAR_H2D_MSG_0, 1, (uint8_t *)val); +} + +uint8_t whd_bus_m2m_blhs_write_h2d(whd_driver_t whd_driver, uint32_t val) +{ + return whd_bus_m2m_write_backplane_value(whd_driver, (uint32_t)M2M_REG_DAR_H2D_MSG_0, 1, val); +} + +uint8_t whd_bus_m2m_blhs_wait_d2h(whd_driver_t whd_driver, uint8_t state) +{ + uint8_t byte_data; + uint32_t loop_count = 0; + + /* while ( ( ( whd_bus_read_backplane_value(whd_driver, M2M_REG_DAR_SC0_MSG_0, 1, &byte_data) ) == 0 ) && + ( (byte_data & M2M_BLHS_WLRDY_BIT) == 0 ) ) + { + vt_printf("%d ", byte_data); + } */ + + byte_data = 0; + + WPRINT_WHD_DEBUG( ("Wait for D2H - %d \n", state) ); + + while ( ( (whd_bus_m2m_read_backplane_value(whd_driver, M2M_REG_DAR_D2H_MSG_0, 1, &byte_data) ) == 0 ) && + ( (byte_data & state) == 0 ) && + (loop_count < 30000) ) + { + loop_count += 10; + } + if (loop_count >= 30000) + { + WPRINT_WHD_ERROR( ("%s: D2H Wait TimeOut! \n", __FUNCTION__) ); + return -1; + } + + return 0; +} + +static whd_result_t whd_bus_m2m_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage) +{ + uint32_t val; + + switch (stage) + { + case PREP_FW_DOWNLOAD: + CHECK_RETURN(whd_bus_m2m_blhs_write_h2d(whd_driver, M2M_BLHS_H2D_BL_INIT) ); + CHECK_RETURN(whd_bus_m2m_blhs_wait_d2h(whd_driver, M2M_BLHS_D2H_READY) ); + CHECK_RETURN(whd_bus_m2m_blhs_write_h2d(whd_driver, M2M_BLHS_H2D_DL_FW_START) ); + break; + case POST_FW_DOWNLOAD: + CHECK_RETURN(whd_bus_m2m_blhs_write_h2d(whd_driver, M2M_BLHS_H2D_DL_FW_DONE) ); + if (whd_bus_m2m_blhs_wait_d2h(whd_driver, M2M_BLHS_D2H_TRXHDR_PARSE_DONE) != 0) + { + whd_bus_m2m_blhs_read_h2d(whd_driver, &val); + whd_bus_m2m_blhs_write_h2d(whd_driver, (val | M2M_BLHS_H2D_BL_RESET_ON_ERROR) ); + return 1; + } + break; + case CHK_FW_VALIDATION: + if ( (whd_bus_m2m_blhs_wait_d2h(whd_driver, M2M_BLHS_D2H_VALDN_DONE) != 0) || + (whd_bus_m2m_blhs_wait_d2h(whd_driver, M2M_BLHS_D2H_VALDN_RESULT) != 0) ) + { + whd_bus_m2m_blhs_read_h2d(whd_driver, &val); + whd_bus_m2m_blhs_write_h2d(whd_driver, (val | M2M_BLHS_H2D_BL_RESET_ON_ERROR) ); + return 1; + } + break; + case POST_NVRAM_DOWNLOAD: + CHECK_RETURN(whd_bus_m2m_blhs_read_h2d(whd_driver, &val) ); + CHECK_RETURN(whd_bus_m2m_blhs_write_h2d(whd_driver, (val | M2M_BLHS_H2D_DL_NVRAM_DONE) ) ); + break; + case POST_WATCHDOG_RESET: + CHECK_RETURN(whd_bus_m2m_blhs_write_h2d(whd_driver, M2M_BLHS_H2D_BL_INIT) ); + CHECK_RETURN(whd_bus_m2m_blhs_wait_d2h(whd_driver, M2M_BLHS_D2H_READY) ); + default: + return 1; + } + + return 0; +} + +#endif /* BLHS_SUPPORT */ + +static whd_result_t whd_bus_m2m_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, + uint32_t image_size) +{ + whd_result_t result = WHD_SUCCESS; + uint32_t size_out; + +#ifdef PROTO_MSGBUF + uint8_t *image; + + CHECK_RETURN(whd_get_resource_block(whd_driver, resource, 0, (const uint8_t **)&image, &size_out) ); + + trx_header_t *trx = (trx_header_t *)&image[0]; + if (trx->magic == TRX_MAGIC) + { + image_size = trx->len; + address -= sizeof(*trx); + } + else + { + result = WHD_BADARG; + WPRINT_WHD_ERROR( ("%s: TRX header mismatch\n", __FUNCTION__) ); + return result; + } + memcpy( (void *)TRANS_ADDR(address), image, image_size ); +#else + uint32_t reset_instr = 0; + + CHECK_RETURN(whd_resource_read(whd_driver, resource, 0, + GET_C_VAR(whd_driver, CHIP_RAM_SIZE), &size_out, + (uint8_t *)(address) ) ); + + CHECK_RETURN(whd_resource_read(whd_driver, resource, 0, 4, &size_out, &reset_instr) ); + + /* CR4_FF_ROM_SHADOW_INDEX_REGISTER */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, GET_C_VAR(whd_driver, PMU_BASE_ADDRESS) + 0x080, + (uint8_t)1, 0) ); + + /* CR4_FF_ROM_SHADOW_DATA_REGISTER */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, GET_C_VAR(whd_driver, PMU_BASE_ADDRESS) + 0x084, + (uint8_t)4, reset_instr) ); +#endif /* PROTO_MSGBUF */ + + return result; +} + +static whd_result_t whd_bus_m2m_write_wifi_nvram_image(whd_driver_t whd_driver) +{ + uint32_t nvram_size; + uint32_t nvram_destination_address; + uint32_t nvram_size_in_words; + uint32_t size_out; + uint32_t image_size; + + /* Get the size of the variable image */ + CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_NVRAM, &image_size) ); + + /* Round up the size of the image */ + nvram_size = ROUND_UP(image_size, 4); + + /* Put the NVRAM image at the end of RAM leaving the last 4 bytes for the size */ + nvram_destination_address = (GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4) - nvram_size; + nvram_destination_address += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + +#ifdef PROTO_MSGBUF + CHECK_RETURN(whd_resource_read(whd_driver, WHD_RESOURCE_WLAN_NVRAM, 0, + image_size, &size_out, (uint8_t *)TRANS_ADDR(nvram_destination_address) ) ); +#else + /* Write NVRAM image into WLAN RAM */ + CHECK_RETURN(whd_resource_read(whd_driver, WHD_RESOURCE_WLAN_NVRAM, 0, + image_size, &size_out, (uint8_t *)nvram_destination_address) ); +#endif /* PROTO_MSGBUF */ + + /* Calculate the NVRAM image size in words (multiples of 4 bytes) and its bitwise inverse */ + nvram_size_in_words = nvram_size / 4; + nvram_size_in_words = (~nvram_size_in_words << 16) | (nvram_size_in_words & 0x0000FFFF); + +#ifdef PROTO_MSGBUF + memcpy( (uint8_t *)TRANS_ADDR( (GET_C_VAR(whd_driver, + ATCM_RAM_BASE_ADDRESS) + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4) ), + (uint8_t *)&nvram_size_in_words, 4 ); +#else + memcpy( (uint8_t *)(GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4), + (uint8_t *)&nvram_size_in_words, 4 ); +#endif /* PROTO_MSGBUF */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_m2m_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *cur_addr) +{ + return WHD_UNSUPPORTED; +} + +whd_bool_t whd_ensure_wlan_is_up(whd_driver_t whd_driver) +{ + if ( (whd_driver != NULL) && (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) ) + return WHD_TRUE; + else + return WHD_FALSE; +} + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.h b/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.h new file mode 100644 index 00000000..76ca9d38 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_m2m_protocol.h @@ -0,0 +1,45 @@ +/* + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "whd.h" +#include "bus_protocols/whd_bus_protocol_interface.h" + +#ifndef INCLUDED_M2M_WHD_BUS_PROTOCOL_H +#define INCLUDED_M2M_WHD_BUS_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** +* Function declarations +******************************************************/ +extern void whd_delayed_bus_release_schedule_update(whd_driver_t whd_driver, whd_bool_t is_scheduled); +#define DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule) \ + do { whd_delayed_bus_release_schedule_update(whd_driver, schedule); } while (0) + + +/****************************************************** +* Global variables +******************************************************/ + + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +#endif /* ifndef INCLUDED_M2M_WHD_BUS_PROTOCOL_H */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_protocol_interface.h b/wi-fi/whd/bus_protocols/whd_bus_protocol_interface.h index 6b5e7a31..75fa8ade 100644 --- a/wi-fi/whd/bus_protocols/whd_bus_protocol_interface.h +++ b/wi-fi/whd/bus_protocols/whd_bus_protocol_interface.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,37 +21,38 @@ #include "whd_network_types.h" #include "whd_types_int.h" #include "whd_resource_api.h" +#include "whd_bus_common.h" #ifndef INCLUDED_WHD_BUS_PROTOCOL_INTERFACE_H_ #define INCLUDED_WHD_BUS_PROTOCOL_INTERFACE_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** * Constants ******************************************************/ -typedef enum { - BUS_FUNCTION = 0, - BACKPLANE_FUNCTION = 1, - WLAN_FUNCTION = 2 +typedef enum +{ + BUS_FUNCTION = 0, + BACKPLANE_FUNCTION = 1, + WLAN_FUNCTION = 2 } whd_bus_function_t; #define BUS_FUNCTION_MASK (0x3) /* Update this if adding functions */ -#define WHD_BUS_FAIL (0xFFFFFFFF) +#define WHD_BUS_FAIL (0xFFFFFFFF) /****************************************************** * Macros ******************************************************/ #define PLATFORM_WLAN_ALLOW_BUS_TO_SLEEP_DELAY_MS 10 -#define DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule) \ - do { \ - whd_delayed_bus_release_schedule_update(whd_driver, \ - schedule); \ - } while (0) +#define DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule) do { whd_delayed_bus_release_schedule_update(whd_driver, \ + schedule); \ +} while (0) /****************************************************** * Structures @@ -61,8 +62,8 @@ typedef enum { typedef struct { - uint8_t bus_header[MAX_BUS_HEADER_SIZE]; - uint32_t data[1]; + uint8_t bus_header[MAX_BUS_HEADER_SIZE]; + uint32_t data[1]; } whd_transfer_bytes_packet_t; #pragma pack() @@ -75,17 +76,17 @@ typedef void (*whd_bus_irq_callback_t)(void *handler_arg, uint32_t event); /* Share bus to BT */ extern whd_result_t whd_bus_write_reg_value(whd_driver_t whd_driver, uint32_t address, - uint8_t value_length, uint32_t value); + uint8_t value_length, uint32_t value); extern whd_result_t whd_bus_read_reg_value(whd_driver_t whd_driver, uint32_t address, - uint8_t value_length, uint8_t *value); + uint8_t value_length, uint8_t *value); extern whd_result_t whd_bus_mem_bytes(whd_driver_t whd_driver, uint8_t direct, - uint32_t address, uint32_t size, uint8_t *data); + uint32_t address, uint32_t size, uint8_t *data); extern whd_driver_t whd_bt_get_whd_driver(void); extern whd_result_t whd_bus_share_bt_init(whd_driver_t whd_driver); extern whd_result_t whd_bus_bt_attach(whd_driver_t whd_driver, void *btdata, - void (*bt_int_fun)(void *data)); + void (*bt_int_fun)(void *data) ); extern void whd_bus_bt_detach(whd_driver_t whd_driver); -extern uint32_t whd_get_bt_info(whd_driver_t whd_drv, whd_bt_info_t bt_info); +extern whd_result_t whd_get_bt_info(whd_driver_t whd_drv, whd_bt_info_t bt_info); /* Initialisation functions */ extern whd_result_t whd_bus_init(whd_driver_t whd_driver); extern whd_result_t whd_bus_deinit(whd_driver_t whd_driver); @@ -93,26 +94,26 @@ extern whd_result_t whd_bus_deinit(whd_driver_t whd_driver); /* Device register access functions */ extern whd_result_t whd_bus_set_backplane_window(whd_driver_t whd_driver, uint32_t addr); extern whd_result_t whd_bus_write_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint32_t value); + uint32_t value); extern whd_result_t whd_bus_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint8_t *value); + uint8_t *value); extern whd_result_t whd_bus_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint32_t value); + uint8_t value_length, uint32_t value); extern whd_result_t whd_bus_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint8_t *value); + uint8_t value_length, uint8_t *value); /* Device data transfer functions */ extern whd_result_t whd_bus_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer); extern whd_result_t whd_bus_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t size, - whd_transfer_bytes_packet_t *data); + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data); /* Frame transfer function */ extern whd_result_t whd_bus_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer); -extern uint32_t whd_bus_packet_available_to_read(whd_driver_t whd_driver); +extern uint32_t whd_bus_packet_available_to_read(whd_driver_t whd_driver); extern whd_result_t whd_bus_poke_wlan(whd_driver_t whd_driver); -extern whd_result_t whd_bus_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore); +extern whd_result_t whd_bus_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore); extern whd_result_t whd_bus_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus); extern whd_bool_t whd_bus_wake_interrupt_present(whd_driver_t whd_driver); @@ -127,13 +128,16 @@ extern uint8_t whd_bus_backplane_read_padd_size(whd_driver_t whd_driver); extern whd_bool_t whd_bus_use_status_report_scheme(whd_driver_t whd_driver); extern uint32_t whd_bus_get_max_transfer_size(whd_driver_t whd_driver); -extern void whd_bus_init_stats(whd_driver_t whd_driver); +extern void whd_bus_init_stats(whd_driver_t whd_driver); extern whd_result_t whd_bus_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print); extern whd_result_t whd_bus_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware); extern whd_result_t whd_bus_irq_enable(whd_driver_t whd_driver, whd_bool_t enable); extern whd_result_t whd_bus_irq_register(whd_driver_t whd_driver); extern whd_result_t whd_bus_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, - whd_bool_t direct_resource, uint32_t address, uint32_t image_size); + whd_bool_t direct_resource, uint32_t address, uint32_t image_size); +#ifdef BLHS_SUPPORT +extern whd_result_t whd_bus_common_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage); +#endif /****************************************************** * Global variables ******************************************************/ diff --git a/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.c b/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.c index 7a12cad3..60ac0444 100644 --- a/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.c +++ b/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,9 +23,10 @@ * sending/receiving raw packets etc */ -#include #include "cybsp.h" -#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) +#include "whd_utils.h" + +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) && !defined(COMPONENT_WIFI_INTERFACE_OCI) #include "cyabs_rtos.h" #include "cyhal_sdio.h" @@ -45,45 +46,51 @@ #include "whd_resource_if.h" #include "whd_types_int.h" #include "whd_types.h" +#include "whd_proto.h" + +#ifdef DM_43022C1 +#include "resources.h" +#endif +#ifdef CYCFG_ULP_SUPPORT_ENABLED +#include "cy_network_mw_core.h" +#endif /****************************************************** * Constants ******************************************************/ /* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ #define F0_WORKING_TIMEOUT_MS (500) #define F1_AVAIL_TIMEOUT_MS (500) #define F2_AVAIL_TIMEOUT_MS (500) #define F2_READY_TIMEOUT_MS (1000) #define ALP_AVAIL_TIMEOUT_MS (100) -#define HT_AVAIL_TIMEOUT_MS (5000) +#define HT_AVAIL_TIMEOUT_MS (2500) #define ABORT_TIMEOUT_MS (100) /* Taken from FALCON_5_90_195_26 dhd/sys/dhd_sdio.c. */ -#define SDIO_F2_WATERMARK (8) +#define SDIO_F2_WATERMARK (8) -#define INITIAL_READ 4 +#define INITIAL_READ 4 -#define WHD_THREAD_POLL_TIMEOUT (CY_RTOS_NEVER_TIMEOUT) +#define WHD_THREAD_POLL_TIMEOUT (CY_RTOS_NEVER_TIMEOUT) -#define WHD_THREAD_POKE_TIMEOUT (100) +#define WHD_THREAD_POKE_TIMEOUT (100) -#define WHD_INT_CLEAR_TIMEOUT 1000 - -#define HOSTINTMASK (I_HMB_SW_MASK) +#define HOSTINTMASK (I_HMB_SW_MASK) /****************************************************** * Structures ******************************************************/ -struct whd_bus_priv { - whd_sdio_config_t sdio_config; - whd_bus_stats_t whd_bus_stats; - cyhal_sdio_t *sdio_obj; - cy_semaphore_t int_clear_semaphore; +struct whd_bus_priv +{ + whd_sdio_config_t sdio_config; + whd_bus_stats_t whd_bus_stats; + cyhal_sdio_t *sdio_obj; }; /* For BSP backward compatible, should be removed the macro once 1.0 is not supported */ @@ -101,16 +108,16 @@ typedef cyhal_transfer_t cyhal_sdio_transfer_t; ******************************************************/ static whd_result_t whd_bus_sdio_transfer(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t data_size, - uint8_t *data, sdio_response_needed_t response_expected); + whd_bus_function_t function, uint32_t address, uint16_t data_size, + uint8_t *data, sdio_response_needed_t response_expected); static whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint8_t value, - sdio_response_needed_t response_expected, uint8_t *response); + whd_bus_function_t function, uint32_t address, uint8_t value, + sdio_response_needed_t response_expected, uint8_t *response); static whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, sdio_transfer_mode_t mode, uint32_t address, - uint16_t data_size, uint8_t *data, - sdio_response_needed_t response_expected, - uint32_t *response); + whd_bus_function_t function, sdio_transfer_mode_t mode, uint32_t address, + uint16_t data_size, uint8_t *data, + sdio_response_needed_t response_expected, + uint32_t *response); static whd_result_t whd_bus_sdio_abort_read(whd_driver_t whd_driver, whd_bool_t retry); static whd_result_t whd_bus_sdio_download_firmware(whd_driver_t whd_driver); @@ -129,459 +136,647 @@ static whd_result_t whd_bus_sdio_deinit_oob_intr(whd_driver_t whd_driver); static whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver); static whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver); static whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable); +#ifdef BLHS_SUPPORT +static whd_result_t whd_bus_sdio_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage); +#endif static whd_result_t whd_bus_sdio_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, - whd_bool_t direct_resource, uint32_t address, uint32_t image_size); + whd_bool_t direct_resource, uint32_t address, uint32_t image_size); static whd_result_t whd_bus_sdio_write_wifi_nvram_image(whd_driver_t whd_driver); /****************************************************** * Global Function definitions ******************************************************/ -uint32_t whd_bus_sdio_attach(whd_driver_t whd_driver, whd_sdio_config_t *whd_sdio_config, cyhal_sdio_t *sdio_obj) +whd_result_t whd_bus_sdio_attach(whd_driver_t whd_driver, whd_sdio_config_t *whd_sdio_config, cyhal_sdio_t *sdio_obj) { - struct whd_bus_info *whd_bus_info; + struct whd_bus_info *whd_bus_info; - if (!whd_driver || !whd_sdio_config) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } + if (!whd_driver || !whd_sdio_config) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } - whd_bus_info = (whd_bus_info_t *)malloc(sizeof(whd_bus_info_t)); + whd_bus_info = (whd_bus_info_t *)whd_mem_malloc(sizeof(whd_bus_info_t) ); - if (whd_bus_info == NULL) { - WPRINT_WHD_ERROR(("Memory allocation failed for whd_bus_info in %s\n", __FUNCTION__)); - return WHD_BUFFER_UNAVAILABLE_PERMANENT; - } - memset(whd_bus_info, 0, sizeof(whd_bus_info_t)); + if (whd_bus_info == NULL) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bus_info in %s\n", __FUNCTION__) ); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_bus_info, 0, sizeof(whd_bus_info_t) ); - whd_driver->bus_if = whd_bus_info; + whd_driver->bus_if = whd_bus_info; - whd_driver->bus_priv = (struct whd_bus_priv *)malloc(sizeof(struct whd_bus_priv)); + whd_driver->bus_priv = (struct whd_bus_priv *)whd_mem_malloc(sizeof(struct whd_bus_priv) ); - if (whd_driver->bus_priv == NULL) { - WPRINT_WHD_ERROR(("Memory allocation failed for whd_bus_priv in %s\n", __FUNCTION__)); - return WHD_BUFFER_UNAVAILABLE_PERMANENT; - } - memset(whd_driver->bus_priv, 0, sizeof(struct whd_bus_priv)); + if (whd_driver->bus_priv == NULL) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bus_priv in %s\n", __FUNCTION__) ); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_driver->bus_priv, 0, sizeof(struct whd_bus_priv) ); - whd_driver->bus_priv->sdio_obj = sdio_obj; - whd_driver->bus_priv->sdio_config = *whd_sdio_config; + whd_driver->bus_priv->sdio_obj = sdio_obj; + whd_driver->bus_priv->sdio_config = *whd_sdio_config; - whd_bus_info->whd_bus_init_fptr = whd_bus_sdio_init; - whd_bus_info->whd_bus_deinit_fptr = whd_bus_sdio_deinit; + whd_driver->proto_type = WHD_PROTO_BCDC; - whd_bus_info->whd_bus_write_backplane_value_fptr = whd_bus_sdio_write_backplane_value; - whd_bus_info->whd_bus_read_backplane_value_fptr = whd_bus_sdio_read_backplane_value; - whd_bus_info->whd_bus_write_register_value_fptr = whd_bus_sdio_write_register_value; - whd_bus_info->whd_bus_read_register_value_fptr = whd_bus_sdio_read_register_value; + whd_bus_info->whd_bus_init_fptr = whd_bus_sdio_init; + whd_bus_info->whd_bus_deinit_fptr = whd_bus_sdio_deinit; - whd_bus_info->whd_bus_send_buffer_fptr = whd_bus_sdio_send_buffer; - whd_bus_info->whd_bus_transfer_bytes_fptr = whd_bus_sdio_transfer_bytes; + whd_bus_info->whd_bus_write_backplane_value_fptr = whd_bus_sdio_write_backplane_value; + whd_bus_info->whd_bus_read_backplane_value_fptr = whd_bus_sdio_read_backplane_value; + whd_bus_info->whd_bus_write_register_value_fptr = whd_bus_sdio_write_register_value; + whd_bus_info->whd_bus_read_register_value_fptr = whd_bus_sdio_read_register_value; - whd_bus_info->whd_bus_read_frame_fptr = whd_bus_sdio_read_frame; + whd_bus_info->whd_bus_send_buffer_fptr = whd_bus_sdio_send_buffer; + whd_bus_info->whd_bus_transfer_bytes_fptr = whd_bus_sdio_transfer_bytes; - whd_bus_info->whd_bus_packet_available_to_read_fptr = whd_bus_sdio_packet_available_to_read; - whd_bus_info->whd_bus_poke_wlan_fptr = whd_bus_sdio_poke_wlan; - whd_bus_info->whd_bus_wait_for_wlan_event_fptr = whd_bus_sdio_wait_for_wlan_event; + whd_bus_info->whd_bus_read_frame_fptr = whd_bus_sdio_read_frame; - whd_bus_info->whd_bus_ack_interrupt_fptr = whd_bus_sdio_ack_interrupt; - whd_bus_info->whd_bus_wake_interrupt_present_fptr = whd_bus_sdio_wake_interrupt_present; + whd_bus_info->whd_bus_packet_available_to_read_fptr = whd_bus_sdio_packet_available_to_read; + whd_bus_info->whd_bus_poke_wlan_fptr = whd_bus_sdio_poke_wlan; + whd_bus_info->whd_bus_wait_for_wlan_event_fptr = whd_bus_sdio_wait_for_wlan_event; - whd_bus_info->whd_bus_wakeup_fptr = whd_bus_sdio_wakeup; - whd_bus_info->whd_bus_sleep_fptr = whd_bus_sdio_sleep; + whd_bus_info->whd_bus_ack_interrupt_fptr = whd_bus_sdio_ack_interrupt; + whd_bus_info->whd_bus_wake_interrupt_present_fptr = whd_bus_sdio_wake_interrupt_present; - whd_bus_info->whd_bus_backplane_read_padd_size_fptr = whd_bus_sdio_backplane_read_padd_size; - whd_bus_info->whd_bus_use_status_report_scheme_fptr = whd_bus_sdio_use_status_report_scheme; + whd_bus_info->whd_bus_wakeup_fptr = whd_bus_sdio_wakeup; + whd_bus_info->whd_bus_sleep_fptr = whd_bus_sdio_sleep; - whd_bus_info->whd_bus_get_max_transfer_size_fptr = whd_bus_sdio_get_max_transfer_size; + whd_bus_info->whd_bus_backplane_read_padd_size_fptr = whd_bus_sdio_backplane_read_padd_size; + whd_bus_info->whd_bus_use_status_report_scheme_fptr = whd_bus_sdio_use_status_report_scheme; - whd_bus_info->whd_bus_init_stats_fptr = whd_bus_sdio_init_stats; - whd_bus_info->whd_bus_print_stats_fptr = whd_bus_sdio_print_stats; - whd_bus_info->whd_bus_reinit_stats_fptr = whd_bus_sdio_reinit_stats; - whd_bus_info->whd_bus_irq_register_fptr = whd_bus_sdio_irq_register; - whd_bus_info->whd_bus_irq_enable_fptr = whd_bus_sdio_irq_enable; - whd_bus_info->whd_bus_download_resource_fptr = whd_bus_sdio_download_resource; - whd_bus_info->whd_bus_set_backplane_window_fptr = whd_bus_sdio_set_backplane_window; - return WHD_SUCCESS; + whd_bus_info->whd_bus_get_max_transfer_size_fptr = whd_bus_sdio_get_max_transfer_size; + + whd_bus_info->whd_bus_init_stats_fptr = whd_bus_sdio_init_stats; + whd_bus_info->whd_bus_print_stats_fptr = whd_bus_sdio_print_stats; + whd_bus_info->whd_bus_reinit_stats_fptr = whd_bus_sdio_reinit_stats; + whd_bus_info->whd_bus_irq_register_fptr = whd_bus_sdio_irq_register; + whd_bus_info->whd_bus_irq_enable_fptr = whd_bus_sdio_irq_enable; +#ifdef BLHS_SUPPORT + whd_bus_info->whd_bus_blhs_fptr = whd_bus_sdio_blhs; +#endif + whd_bus_info->whd_bus_download_resource_fptr = whd_bus_sdio_download_resource; + whd_bus_info->whd_bus_set_backplane_window_fptr = whd_bus_sdio_set_backplane_window; + + return WHD_SUCCESS; } void whd_bus_sdio_detach(whd_driver_t whd_driver) { - if (whd_driver->bus_if != NULL) { - free(whd_driver->bus_if); - whd_driver->bus_if = NULL; - } - if (whd_driver->bus_priv != NULL) { - free(whd_driver->bus_priv); - whd_driver->bus_priv = NULL; - } + if (whd_driver->bus_if != NULL) + { + whd_mem_free(whd_driver->bus_if); + whd_driver->bus_if = NULL; + } + if (whd_driver->bus_priv != NULL) + { + whd_mem_free(whd_driver->bus_priv); + whd_driver->bus_priv = NULL; + } } whd_result_t whd_bus_sdio_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus) { - return whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, intstatus); + return whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, intstatus); } whd_result_t whd_bus_sdio_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore) { - whd_result_t result = WHD_SUCCESS; - uint32_t timeout_ms = 1; - uint32_t delayed_release_timeout_ms; - - REFERENCE_DEBUG_ONLY_VARIABLE(result); - - delayed_release_timeout_ms = whd_bus_handle_delayed_release(whd_driver); - if (delayed_release_timeout_ms != 0) { - timeout_ms = delayed_release_timeout_ms; - } - else { - result = whd_allow_wlan_bus_to_sleep(whd_driver); - whd_assert("Error setting wlan sleep", (result == WHD_SUCCESS) || (result == WHD_PENDING)); - - if (result == WHD_SUCCESS) { - timeout_ms = CY_RTOS_NEVER_TIMEOUT; - } - } - - /* Check if we have run out of bus credits */ - if ((whd_sdpcm_has_tx_packet(whd_driver) == WHD_TRUE) && (whd_sdpcm_get_available_credits(whd_driver) == 0)) { - /* Keep poking the WLAN until it gives us more credits */ - result = whd_bus_poke_wlan(whd_driver); - whd_assert("Poking failed!", result == WHD_SUCCESS); - - result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, WHD_THREAD_POKE_TIMEOUT), WHD_FALSE); - } - else { - result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, WHD_THREAD_POLL_TIMEOUT), WHD_FALSE); - } - whd_assert("Could not get whd sleep semaphore\n", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT)); - - return result; + whd_result_t result = WHD_SUCCESS; + uint32_t timeout_ms = 1; + uint32_t delayed_release_timeout_ms; + + REFERENCE_DEBUG_ONLY_VARIABLE(result); + + delayed_release_timeout_ms = whd_bus_handle_delayed_release(whd_driver); + if (delayed_release_timeout_ms != 0) + { + timeout_ms = delayed_release_timeout_ms; + } + else + { + result = whd_allow_wlan_bus_to_sleep(whd_driver); + whd_assert("Error setting wlan sleep", (result == WHD_SUCCESS) || (result == WHD_PENDING) ); + + if (result == WHD_SUCCESS) + { + timeout_ms = CY_RTOS_NEVER_TIMEOUT; + } + } + + /* Check if we have run out of bus credits */ + if ( (whd_sdpcm_has_tx_packet(whd_driver) == WHD_TRUE) && (whd_sdpcm_get_available_credits(whd_driver) == 0) ) + { + /* Keep poking the WLAN until it gives us more credits */ + result = whd_bus_poke_wlan(whd_driver); + whd_assert("Poking failed!", result == WHD_SUCCESS); + + result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, + WHD_THREAD_POKE_TIMEOUT), WHD_FALSE); + } + else + { + result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, + WHD_THREAD_POLL_TIMEOUT), WHD_FALSE); + } + whd_assert("Could not get whd sleep semaphore\n", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT) ); + + return result; } /* Device data transfer functions */ whd_result_t whd_bus_sdio_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer) { - whd_result_t retval; - retval = - whd_bus_transfer_bytes(whd_driver, BUS_WRITE, WLAN_FUNCTION, 0, - (uint16_t)(whd_buffer_get_current_piece_size(whd_driver, - buffer) - - sizeof(whd_buffer_t)), - (whd_transfer_bytes_packet_t *)(whd_buffer_get_current_piece_data_pointer(whd_driver, - buffer) + - sizeof(whd_buffer_t))); - CHECK_RETURN(whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX)); - if (retval == WHD_SUCCESS) { - DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); - } - CHECK_RETURN(retval); - - return WHD_SUCCESS; + whd_result_t retval; + retval = + whd_bus_transfer_bytes(whd_driver, BUS_WRITE, WLAN_FUNCTION, 0, + (uint16_t)(whd_buffer_get_current_piece_size(whd_driver, + buffer) - sizeof(whd_buffer_t) ), + (whd_transfer_bytes_packet_t *)(whd_buffer_get_current_piece_data_pointer(whd_driver, + buffer) + + sizeof(whd_buffer_t) ) ); + CHECK_RETURN(whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX) ); + if (retval == WHD_SUCCESS) + { + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); + } + CHECK_RETURN (retval); + + return WHD_SUCCESS; } whd_result_t whd_bus_sdio_init(whd_driver_t whd_driver) { - uint8_t byte_data; - whd_result_t result; - uint32_t loop_count; - whd_time_t elapsed_time, current_time; - uint32_t wifi_firmware_image_size = 0; - uint16_t chip_id; - - whd_bus_set_flow_control(whd_driver, WHD_FALSE); - - whd_bus_init_backplane_window(whd_driver); - - /* Setup the backplane*/ - loop_count = 0; - do { - /* Enable function 1 (backplane) */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, - SDIO_FUNC_ENABLE_1)); - if (loop_count != 0) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - } - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, &byte_data)); - loop_count++; - if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout while setting up the backplane, %s failed at %d \n", __func__, __LINE__)); - return WHD_TIMEOUT; - } - } while (byte_data != (uint8_t)SDIO_FUNC_ENABLE_1); - - if (whd_driver->bus_priv->sdio_config.sdio_1bit_mode == WHD_FALSE) { - /* Read the bus width and set to 4 bits */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, - &byte_data)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, - (byte_data & (~BUS_SD_DATA_WIDTH_MASK)) | - BUS_SD_DATA_WIDTH_4BIT)); - /* NOTE: We don't need to change our local bus settings since we're not sending any data (only using CMD52) + uint8_t byte_data; +#ifdef DM_43022C1 + uint8_t secure_chk = -1; +#endif + whd_result_t result; + uint32_t loop_count; + whd_time_t elapsed_time, current_time; + uint32_t wifi_firmware_image_size = 0; + uint16_t chip_id; + uint8_t *aligned_addr = NULL; + memset(&whd_driver->chip_info, 0, sizeof(whd_driver->chip_info) ); + + whd_bus_set_flow_control(whd_driver, WHD_FALSE); + + whd_bus_init_backplane_window(whd_driver); + + /* Setup the backplane*/ + loop_count = 0; + do + { + /* Enable function 1 (backplane) */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, + SDIO_FUNC_ENABLE_1) ); + if (loop_count != 0) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + } + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, &byte_data) ); + loop_count++; + if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout while setting up the backplane, %s failed at %d \n", __func__, __LINE__) ); + return WHD_TIMEOUT; + } + } while (byte_data != (uint8_t)SDIO_FUNC_ENABLE_1); + + if (whd_driver->bus_priv->sdio_config.sdio_1bit_mode == WHD_FALSE) + { + /* Read the bus width and set to 4 bits */ + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, + &byte_data) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, + (byte_data & (~BUS_SD_DATA_WIDTH_MASK) ) | + BUS_SD_DATA_WIDTH_4BIT) ); + /* NOTE: We don't need to change our local bus settings since we're not sending any data (only using CMD52) * until after we change the bus speed further down */ - } - - /* Set the block size */ - - /* Wait till the backplane is ready */ - loop_count = 0; - while (((result = whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)) == WHD_SUCCESS) && - ((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - (byte_data != (uint8_t)SDIO_64B_BLOCK) && - (loop_count < (uint32_t)F0_WORKING_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) { - /* If the system fails here, check the high frequency crystal is working */ - WPRINT_WHD_ERROR(("Timeout while setting block size, %s failed at %d \n", __func__, __LINE__)); - return WHD_TIMEOUT; - } - } - - CHECK_RETURN(result); - - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F1BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_1, (uint8_t)1, - (uint32_t)0)); /* Function 2 = 64 */ - - /* Register interrupt handler*/ - whd_bus_sdio_irq_register(whd_driver); - /* Enable SDIO IRQ */ - whd_bus_sdio_irq_enable(whd_driver, WHD_TRUE); - - /* Enable/Disable Client interrupts */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, - INTR_CTL_MASTER_EN | INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN)); - - if (whd_driver->bus_priv->sdio_config.high_speed_sdio_clock) { - /* This code is required if we want more than 25 MHz clock */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, &byte_data)); - if ((byte_data & 0x1) != 0) { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, - byte_data | SDIO_SPEED_EHS)); - } - else { - WPRINT_WHD_ERROR(("Error reading bus register, %s failed at %d \n", __func__, __LINE__)); - return WHD_BUS_READ_REGISTER_ERROR; - } - } /* HIGH_SPEED_SDIO_CLOCK */ - - - /* Wait till the backplane is ready */ - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - ((byte_data & SDIO_FUNC_READY_1) == 0) && - (loop_count < (uint32_t)F1_AVAIL_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - if (loop_count >= (uint32_t)F1_AVAIL_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout while waiting for backplane to be ready\n")); - return WHD_TIMEOUT; - } - CHECK_RETURN(result); - - /* Set the ALP */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, - (uint32_t)(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ | - SBSDIO_FORCE_ALP))); - - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - ((byte_data & SBSDIO_ALP_AVAIL) == 0) && - (loop_count < (uint32_t)ALP_AVAIL_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - if (loop_count >= (uint32_t)ALP_AVAIL_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout while waiting for alp clock\n")); - return WHD_TIMEOUT; - } - CHECK_RETURN(result); - - /* Clear request for ALP */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, 0)); - - /* Disable the extra SDIO pull-ups */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0)); - /* Enable F1 and F2 */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, - SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2)); - - /* Setup host-wake signals */ - CHECK_RETURN(whd_bus_sdio_init_oob_intr(whd_driver)); - - /* Enable F2 interrupt only */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, - INTR_CTL_MASTER_EN | INTR_CTL_FUNC2_EN)); - - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, &byte_data)); - - /* Read the chip id */ - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, CHIPCOMMON_BASE_ADDRESS, 2, (uint8_t *)&chip_id)); - whd_chip_set_chip_id(whd_driver, chip_id); - - cy_rtos_get_time(&elapsed_time); - result = whd_bus_sdio_download_firmware(whd_driver); - cy_rtos_get_time(¤t_time); - elapsed_time = current_time - elapsed_time; - CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, &wifi_firmware_image_size)); - WPRINT_WHD_INFO(("WLAN FW download size: %u bytes\n", wifi_firmware_image_size)); - WPRINT_WHD_INFO(("WLAN FW download time: %llu ms\n", elapsed_time)); - - if (result != WHD_SUCCESS) { - /* either an error or user abort */ - WPRINT_WHD_ERROR(("SDIO firmware download error, %s failed at %d \n", __func__, __LINE__)); - return result; - } - - /* Wait for F2 to be ready */ - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - ((byte_data & SDIO_FUNC_READY_2) == 0) && - (loop_count < (uint32_t)F2_READY_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - if (loop_count >= (uint32_t)F2_READY_TIMEOUT_MS) { - /* If your system fails here, it could be due to incorrect NVRAM variables. + } + + /* Set the block size */ + + /* Wait till the backplane is ready */ + loop_count = 0; + while ( ( (result = whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ) == WHD_SUCCESS ) && + ( (result = whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + (byte_data != (uint8_t)SDIO_64B_BLOCK) && + (loop_count < (uint32_t)F0_WORKING_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) + { + /* If the system fails here, check the high frequency crystal is working */ + WPRINT_WHD_ERROR( ("Timeout while setting block size, %s failed at %d \n", __func__, __LINE__) ); + return WHD_TIMEOUT; + } + } + + CHECK_RETURN(result); + + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F1BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_1, (uint8_t)1, + (uint32_t)0) ); /* Function 2 = 64 */ + + /* Register interrupt handler*/ + whd_bus_sdio_irq_register(whd_driver); + /* Enable SDIO IRQ */ + whd_bus_sdio_irq_enable(whd_driver, WHD_TRUE); + + /* Enable/Disable Client interrupts */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, + INTR_CTL_MASTER_EN | INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN) ); + + if (whd_driver->bus_priv->sdio_config.high_speed_sdio_clock) + { + /* This code is required if we want more than 25 MHz clock */ + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, &byte_data) ); + if ( (byte_data & 0x1) != 0 ) + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, + byte_data | SDIO_SPEED_EHS) ); + } + else + { + WPRINT_WHD_ERROR( ("Error reading bus register, %s failed at %d \n", __func__, __LINE__) ); + return WHD_BUS_READ_REGISTER_ERROR; + } + }/* HIGH_SPEED_SDIO_CLOCK */ + + + + /* Wait till the backplane is ready */ + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + ( (byte_data & SDIO_FUNC_READY_1) == 0 ) && + (loop_count < (uint32_t)F1_AVAIL_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + if (loop_count >= (uint32_t)F1_AVAIL_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout while waiting for backplane to be ready\n") ); + return WHD_TIMEOUT; + } + CHECK_RETURN(result); + + /* Set the ALP */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + (uint32_t)(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ | + SBSDIO_FORCE_ALP) ) ); + + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + ( (byte_data & SBSDIO_ALP_AVAIL) == 0 ) && + (loop_count < (uint32_t)ALP_AVAIL_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + if (loop_count >= (uint32_t)ALP_AVAIL_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout while waiting for alp clock\n") ); + return WHD_TIMEOUT; + } + CHECK_RETURN(result); + + /* Clear request for ALP */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, 0) ); + + /* Disable the extra SDIO pull-ups */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0) ); + /* Enable F1 and F2 */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, + SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2) ); + + /* Setup host-wake signals */ + CHECK_RETURN(whd_bus_sdio_init_oob_intr(whd_driver) ); + + /* Enable F2 interrupt only */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, + INTR_CTL_MASTER_EN | INTR_CTL_FUNC2_EN) ); + + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, &byte_data) ); + +#ifndef DM_43022C1 + /* Check if chip supports CHIPID Read from SDIO core and bootloader handshake */ + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BRCM_CARDCAP, (uint8_t)1, + &byte_data) ); + + if ( (byte_data & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE) != 0 ) + { + WPRINT_WHD_INFO( ("Chip supports bootloader handshake \n") ); + } + + if ( (byte_data & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) != 0 ) + { + uint8_t addrlow, addrmid, addrhigh; + uint32_t reg_addr; + uint8_t devctl; + whd_driver->chip_info.chipid_in_sdiocore = 1; + CHECK_RETURN(whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_DEVICE_CTL, 1, &devctl) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_DEVICE_CTL, + (uint8_t)1, (devctl | SBSDIO_DEVCTL_ADDR_RST) ) ); + + CHECK_RETURN(whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_FUNC1_SBADDRLOW, 1, + &addrlow) ); + CHECK_RETURN(whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_FUNC1_SBADDRMID, 1, + &addrmid) ); + CHECK_RETURN(whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_FUNC1_SBADDRHIGH, 1, + &addrhigh) ); + + reg_addr = ( (addrlow << 8) | (addrmid << 16) | (addrhigh << 24) ) + SDIO_CORE_CHIPID_REG; + + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SBSDIO_DEVICE_CTL, + (uint8_t)1, devctl) ); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, reg_addr, 2, (uint8_t *)&chip_id) ); + whd_chip_set_chip_id(whd_driver, chip_id); + WPRINT_WHD_INFO( ("chip ID: %d, Support ChipId Read from SDIO Core \n", chip_id) ); + } + else + { + /* Read the chip id */ + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, CHIPCOMMON_BASE_ADDRESS, 2, (uint8_t *)&chip_id) ); + whd_chip_set_chip_id(whd_driver, chip_id); + WPRINT_WHD_INFO( ("chip ID: %d \n", chip_id) ); + } +#else + + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BACKPLANE_FUNCTION, SBSDIO_FUNC1_SECURE_MODE, (uint8_t)1, + &secure_chk) ); + if ( secure_chk == 0 ) /* Secure mode register - will be updated later */ + { + WPRINT_WHD_INFO( ("43022DM : Chip supports bootloader handshake \n") ); + } + else + { + WPRINT_WHD_ERROR( ("43022DM : Error in the Secure Bootloader Check \n") ); + } + + /* Read the chip id */ + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, CHIPCOMMON_BASE_ADDRESS, 2, (uint8_t *)&chip_id) ); + whd_chip_set_chip_id(whd_driver, chip_id); + WPRINT_WHD_INFO( ("chip ID: %d \n", chip_id) ); + +#endif + + cy_rtos_get_time(&elapsed_time); + result = whd_bus_sdio_download_firmware(whd_driver); + cy_rtos_get_time(¤t_time); + elapsed_time = current_time - elapsed_time; + CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, &wifi_firmware_image_size) ); + WPRINT_WHD_INFO( ("WLAN FW download size: %" PRIu32 " bytes\n", wifi_firmware_image_size) ); + WPRINT_WHD_INFO( ("WLAN FW download time: %" PRIu32 " ms\n", elapsed_time) ); + + if (result != WHD_SUCCESS) + { + /* either an error or user abort */ + WPRINT_WHD_ERROR( ("SDIO firmware download error, %s failed at %d \n", __func__, __LINE__) ); + return result; + } + + /* Wait for F2 to be ready */ + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + ( (byte_data & SDIO_FUNC_READY_2) == 0 ) && + (loop_count < (uint32_t)F2_READY_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + if (loop_count >= (uint32_t)F2_READY_TIMEOUT_MS) + { + /* If your system fails here, it could be due to incorrect NVRAM variables. * Check which 'wifi_nvram_image.h' file your platform is using, and * check that it matches the WLAN device on your platform, including the * crystal frequency. */ - WPRINT_WHD_ERROR(("Timeout while waiting for function 2 to be ready\n")); - /* Reachable after hitting assert */ - return WHD_TIMEOUT; - } - - CHECK_RETURN(whd_chip_specific_init(whd_driver)); - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); + WPRINT_WHD_ERROR( ("Timeout while waiting for function 2 to be ready\n") ); + /* Reachable after hitting assert */ + return WHD_TIMEOUT; + } + if (whd_driver->aligned_addr == NULL) + { + if ( (aligned_addr = whd_mem_malloc(WHD_LINK_MTU) ) == NULL ) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for aligned_addr in %s \n", __FUNCTION__) ); + return WHD_MALLOC_FAILURE; + } + whd_driver->aligned_addr = aligned_addr; + } + result = whd_chip_specific_init(whd_driver); + if (result != WHD_SUCCESS) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + CHECK_RETURN(result); + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + CHECK_RETURN(result); #if (CYHAL_API_VERSION >= 2) - cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, - WHD_TRUE); + cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, + WHD_TRUE); #else - cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, WHD_TRUE); + cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, WHD_TRUE); #endif - UNUSED_PARAMETER(elapsed_time); - return result; + UNUSED_PARAMETER(elapsed_time); + + return result; } whd_result_t whd_bus_sdio_deinit(whd_driver_t whd_driver) { - CHECK_RETURN(whd_bus_sdio_deinit_oob_intr(whd_driver)); + if (whd_driver->aligned_addr) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + + CHECK_RETURN(whd_bus_sdio_deinit_oob_intr(whd_driver) ); #if (CYHAL_API_VERSION >= 2) - cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, - WHD_TRUE); + cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, + WHD_FALSE); #else - cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, WHD_FALSE); + cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, WHD_FALSE); #endif - CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver)); - - whd_bus_set_resource_download_halt(whd_driver, WHD_FALSE); + CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver) ); + whd_bus_set_resource_download_halt(whd_driver, WHD_FALSE); - DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_FALSE); + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_FALSE); - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_bool_t whd_bus_sdio_wake_interrupt_present(whd_driver_t whd_driver) { - uint32_t int_status = 0; - - /* Ensure the wlan backplane bus is up */ - if (WHD_SUCCESS != whd_ensure_wlan_bus_is_up(whd_driver)) - return WHD_FALSE; - - if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, - (uint8_t *)&int_status) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error reading interrupt status\n", __FUNCTION__)); - goto exit; - } - if ((I_HMB_HOST_INT & int_status) != 0) { - /* Clear any interrupts */ - if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, - I_HMB_HOST_INT) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error clearing interrupts\n", __FUNCTION__)); - goto exit; - } - if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, - (uint8_t *)&int_status) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error reading interrupt status\n", __FUNCTION__)); - goto exit; - } - WPRINT_WHD_DEBUG(("whd_bus_sdio_wake_interrupt_present after clearing int_status = [%x]\n", - (uint8_t)int_status)); - return WHD_TRUE; - } + uint32_t int_status = 0; + + /* Ensure the wlan backplane bus is up */ + if (WHD_SUCCESS != whd_ensure_wlan_bus_is_up(whd_driver) ) + return WHD_FALSE; + + if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (uint8_t *)&int_status) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + goto exit; + } + if ( (I_HMB_HOST_INT & int_status) != 0 ) + { + /* Clear any interrupts */ + if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + I_HMB_HOST_INT) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error clearing interrupts\n", __FUNCTION__) ); + goto exit; + } + if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (uint8_t *)&int_status) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + goto exit; + } + WPRINT_WHD_DEBUG( ("whd_bus_sdio_wake_interrupt_present after clearing int_status = [%x]\n", + (uint8_t)int_status) ); + return WHD_TRUE; + } exit: - return WHD_FALSE; + return WHD_FALSE; } uint32_t whd_bus_sdio_packet_available_to_read(whd_driver_t whd_driver) { - uint32_t int_status = 0; - uint32_t hmb_data = 0; - uint8_t error_type = 0; - whd_bt_dev_t btdev = whd_driver->bt_dev; - - /* Ensure the wlan backplane bus is up */ - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); - - /* Read the IntStatus */ - if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, - (uint8_t *)&int_status) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error reading interrupt status\n", __FUNCTION__)); - int_status = 0; - return WHD_BUS_FAIL; - } - - if ((I_HMB_HOST_INT & int_status) != 0) { - /* Read mailbox data and ack that we did so */ - if (whd_bus_read_backplane_value(whd_driver, SDIO_TO_HOST_MAILBOX_DATA(whd_driver), 4, - (uint8_t *)&hmb_data) == WHD_SUCCESS) - if (whd_bus_write_backplane_value(whd_driver, SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)4, - SMB_INT_ACK) != WHD_SUCCESS) - WPRINT_WHD_ERROR(("%s: Failed writing SMB_INT_ACK\n", __FUNCTION__)); - - /* dongle indicates the firmware has halted/crashed */ - if ((I_HMB_DATA_FWHALT & hmb_data) != 0) { - WPRINT_WHD_ERROR(("%s: mailbox indicates firmware halted\n", __FUNCTION__)); - whd_wifi_print_whd_log(whd_driver); - error_type = WLC_ERR_FW; - whd_set_error_handler_locally(whd_driver, &error_type, NULL, NULL, NULL); - } - } - if (btdev && btdev->bt_int_cb) { - if ((I_HMB_FC_CHANGE & int_status) != 0) { - btdev->bt_int_cb(btdev->bt_data); - int_status = 0; - } - } - - if ((HOSTINTMASK & int_status) != 0) { - /* Clear any interrupts */ - if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, - int_status & HOSTINTMASK) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error clearing interrupts\n", __FUNCTION__)); - int_status = 0; - goto exit; - } - - cy_rtos_set_semaphore(&whd_driver->bus_priv->int_clear_semaphore, WHD_FALSE); - } + uint32_t int_status = 0; + uint32_t hmb_data = 0; + uint8_t error_type = 0; + whd_bt_dev_t btdev = whd_driver->bt_dev; +#ifdef CYCFG_ULP_SUPPORT_ENABLED + uint16_t wlan_chip_id; + wlan_chip_id = whd_chip_get_chip_id(whd_driver); +#endif + + /* Ensure the wlan backplane bus is up */ + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + + /* Read the IntStatus */ + if (whd_bus_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (uint8_t *)&int_status) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + int_status = 0; + return WHD_BUS_FAIL; + } + + if ( (I_HMB_HOST_INT & int_status) != 0 ) + { + /* Read mailbox data and ack that we did so */ + if ((whd_bus_read_backplane_value(whd_driver, SDIO_TO_HOST_MAILBOX_DATA(whd_driver), 4, + (uint8_t *)&hmb_data) == WHD_SUCCESS) && (hmb_data > 0)) + if (whd_bus_write_backplane_value(whd_driver, SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)4, + SMB_INT_ACK) != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("%s: Failed writing SMB_INT_ACK\n", __FUNCTION__) ); + + /* dongle indicates the firmware has halted/crashed */ + if ( (I_HMB_DATA_FWHALT & hmb_data) != 0 ) + { + WPRINT_WHD_ERROR( ("%s: mailbox indicates firmware halted\n", __FUNCTION__) ); + whd_wifi_print_whd_log(whd_driver); + error_type = WLC_ERR_FW; + whd_set_error_handler_locally(whd_driver, &error_type, NULL, NULL, NULL); + } +#ifdef CYCFG_ULP_SUPPORT_ENABLED + else if(hmb_data == 0 && ( wlan_chip_id == 43012 || wlan_chip_id == 43022 )) + { + WPRINT_WHD_DEBUG( ("%s: mailbox indication about DS1/DS2 Exit\n", __FUNCTION__) ); + if(whd_driver->ds_exit_in_progress == WHD_FALSE) + { + if(whd_wlan_bus_complete_ds_wake(whd_driver, true) == WHD_SUCCESS) + { + WPRINT_WHD_DEBUG(("DS EXIT Triggered: Start Re-Downloading Firmware \n")); + /* If we are running LPA, then LPA will disable MCU SDIO clock.So, re-dowanload fails. + in ordet to avoid this, releasing the clock before FW re-download */ + cyhal_syspm_lock_deepsleep(); + whd_sdpcm_quit(whd_driver); + /* Re-Download Firmware no need to check return, as it affects sync of whd thread, error will be thrown */ + whd_bus_reinit_stats(whd_driver, true); + cyhal_syspm_unlock_deepsleep(); + } + } + else + { + WPRINT_WHD_ERROR(("DS1/DS2 Exit(FW Re-download) is already in progress \n")); + } + } + + if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (int_status & I_HMB_HOST_INT)) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error clearing interrupts\n", __FUNCTION__) ); + int_status = 0; + goto exit; + } + int_status &= ~I_HMB_HOST_INT; + + if ((int_status & I_HMB_FC_STATE) != 0 ) + { + WPRINT_WHD_DEBUG(("Dongle reports I_HMB_FC_STATE\n")); + if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (int_status & I_HMB_FC_STATE)) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error clearing interrupts\n", __FUNCTION__) ); + int_status = 0; + goto exit; + } + int_status &= ~I_HMB_FC_STATE; + } +#endif /* CYCFG_ULP_SUPPORT_ENABLED */ + + } + + if (btdev && btdev->bt_int_cb) + { + if ( (I_HMB_FC_CHANGE & int_status) != 0 ) + { + btdev->bt_int_cb(btdev->bt_data); + int_status = 0; + } + } + + if ( (HOSTINTMASK & int_status) != 0 ) + { + /* Clear any interrupts */ + if (whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + int_status & HOSTINTMASK) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error clearing interrupts\n", __FUNCTION__) ); + int_status = 0; + goto exit; + } + } exit: - return ((int_status) & (FRAME_AVAILABLE_MASK)); + return ( (int_status) & (FRAME_AVAILABLE_MASK) ); } /* @@ -594,101 +789,110 @@ uint32_t whd_bus_sdio_packet_available_to_read(whd_driver_t whd_driver) */ whd_result_t whd_bus_sdio_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer) { - uint16_t hwtag[8]; - uint16_t extra_space_required; - whd_result_t result; - uint8_t *data = NULL; - - *buffer = NULL; - - /* Ensure the wlan backplane bus is up */ - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); - - /* Read the frame header and verify validity */ - memset(hwtag, 0, sizeof(hwtag)); - - result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)INITIAL_READ, (uint8_t *)hwtag, - RESPONSE_NEEDED); - if (result != WHD_SUCCESS) { - (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); /* ignore return - not much can be done if this fails */ - WPRINT_WHD_ERROR(("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_RX_FAIL; - } - - if (((hwtag[0] | hwtag[1]) == 0) || - ((hwtag[0] ^ hwtag[1]) != (uint16_t)0xFFFF)) { - return WHD_HWTAG_MISMATCH; - } - - if ((hwtag[0] == (uint16_t)12) && - (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP)) { - result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)8, (uint8_t *)&hwtag[2], - RESPONSE_NEEDED); - if (result != WHD_SUCCESS) { - /* ignore return - not much can be done if this fails */ - (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); - WPRINT_WHD_ERROR(("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_RX_FAIL; - } - whd_sdpcm_update_credit(whd_driver, (uint8_t *)hwtag); - return WHD_SUCCESS; - } - - /* Calculate the space we need to store entire packet */ - if ((hwtag[0] > (uint16_t)INITIAL_READ)) { - extra_space_required = (uint16_t)(hwtag[0] - (uint16_t)INITIAL_READ); - } - else { - extra_space_required = 0; - } - - /* Allocate a suitable buffer */ - result = whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_RX, - (uint16_t)(INITIAL_READ + extra_space_required + sizeof(whd_buffer_header_t)), - (whd_sdpcm_has_tx_packet(whd_driver) ? 0 : WHD_RX_BUF_TIMEOUT)); - if (result != WHD_SUCCESS) { - /* Read out the first 12 bytes to get the bus credit information, 4 bytes are already read in hwtag */ - whd_assert("Get buffer error", - ((result == WHD_BUFFER_UNAVAILABLE_TEMPORARY) || (result == WHD_BUFFER_UNAVAILABLE_PERMANENT))); - result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)8, (uint8_t *)&hwtag[2], - RESPONSE_NEEDED); - if (result != WHD_SUCCESS) { - /* ignore return - not much can be done if this fails */ - (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); - WPRINT_WHD_ERROR(("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_RX_FAIL; - } - result = whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); - whd_assert("Read-abort failed", result == WHD_SUCCESS); - REFERENCE_DEBUG_ONLY_VARIABLE(result); - - whd_sdpcm_update_credit(whd_driver, (uint8_t *)hwtag); - WPRINT_WHD_ERROR(("Failed to allocate a buffer to receive into, %s failed at %d \n", __func__, __LINE__)); - return WHD_RX_BUFFER_ALLOC_FAIL; - } - data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - /* Copy the data already read */ - memcpy(data + sizeof(whd_buffer_header_t), hwtag, (size_t)INITIAL_READ); - - /* Read the rest of the data */ - if (extra_space_required > 0) { - data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, extra_space_required, - data + sizeof(whd_buffer_header_t) + - INITIAL_READ, - RESPONSE_NEEDED); - - if (result != WHD_SUCCESS) { - (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); /* ignore return - not much can be done if this fails */ - CHECK_RETURN(whd_buffer_release(whd_driver, *buffer, WHD_NETWORK_RX)); - WPRINT_WHD_ERROR(("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_RX_FAIL; - } - } - DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); - return WHD_SUCCESS; + uint16_t hwtag[8]; + uint16_t extra_space_required; + whd_result_t result; + uint8_t *data = NULL; + + *buffer = NULL; + + /* Ensure the wlan backplane bus is up */ + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + + /* Read the frame header and verify validity */ + memset(hwtag, 0, sizeof(hwtag) ); + + result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)INITIAL_READ, (uint8_t *)hwtag, + RESPONSE_NEEDED); + if (result != WHD_SUCCESS) + { + (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); /* ignore return - not much can be done if this fails */ + WPRINT_WHD_ERROR( ("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_RX_FAIL; + } + + if ( ( (hwtag[0] | hwtag[1]) == 0 ) || + ( (hwtag[0] ^ hwtag[1]) != (uint16_t)0xFFFF ) ) + { + return WHD_HWTAG_MISMATCH; + } + + if ( (hwtag[0] == (uint16_t)12) && + (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) ) + { + result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)8, (uint8_t *)&hwtag[2], + RESPONSE_NEEDED); + if (result != WHD_SUCCESS) + { + /* ignore return - not much can be done if this fails */ + (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); + WPRINT_WHD_ERROR( ("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_RX_FAIL; + } + whd_sdpcm_update_credit(whd_driver, (uint8_t *)hwtag); + return WHD_SUCCESS; + } + + /* Calculate the space we need to store entire packet */ + if ( (hwtag[0] > (uint16_t)INITIAL_READ) ) + { + extra_space_required = (uint16_t)(hwtag[0] - (uint16_t)INITIAL_READ); + } + else + { + extra_space_required = 0; + } + + /* Allocate a suitable buffer */ + result = whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_RX, + (uint16_t)(INITIAL_READ + extra_space_required + sizeof(whd_buffer_header_t) ), + (whd_sdpcm_has_tx_packet(whd_driver) ? 0 : WHD_RX_BUF_TIMEOUT) ); + if (result != WHD_SUCCESS) + { + /* Read out the first 12 bytes to get the bus credit information, 4 bytes are already read in hwtag */ + whd_assert("Get buffer error", + ( (result == WHD_BUFFER_UNAVAILABLE_TEMPORARY) || (result == WHD_BUFFER_UNAVAILABLE_PERMANENT) ) ); + result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, (uint16_t)8, (uint8_t *)&hwtag[2], + RESPONSE_NEEDED); + if (result != WHD_SUCCESS) + { + /* ignore return - not much can be done if this fails */ + (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); + WPRINT_WHD_ERROR( ("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_RX_FAIL; + } + result = whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); + whd_assert("Read-abort failed", result == WHD_SUCCESS); + REFERENCE_DEBUG_ONLY_VARIABLE(result); + + whd_sdpcm_update_credit(whd_driver, (uint8_t *)hwtag); + WPRINT_WHD_ERROR( ("Failed to allocate a buffer to receive into, %s failed at %d \n", __func__, __LINE__) ); + return WHD_RX_BUFFER_ALLOC_FAIL; + } + data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + /* Copy the data already read */ + memcpy(data + sizeof(whd_buffer_header_t), hwtag, (size_t)INITIAL_READ); + + /* Read the rest of the data */ + if (extra_space_required > 0) + { + data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + result = whd_bus_sdio_transfer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, extra_space_required, + data + sizeof(whd_buffer_header_t) + + INITIAL_READ, RESPONSE_NEEDED); + + if (result != WHD_SUCCESS) + { + (void)whd_bus_sdio_abort_read(whd_driver, WHD_FALSE); /* ignore return - not much can be done if this fails */ + CHECK_RETURN(whd_buffer_release(whd_driver, *buffer, WHD_NETWORK_RX) ); + WPRINT_WHD_ERROR( ("Error during SDIO receive, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_RX_FAIL; + } + } + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); + return WHD_SUCCESS; } /****************************************************** @@ -697,53 +901,53 @@ whd_result_t whd_bus_sdio_read_frame(whd_driver_t whd_driver, whd_buffer_t *buff /* Device register access functions */ whd_result_t whd_bus_sdio_write_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint32_t value) + uint32_t value) { - CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address)); + CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address) ); - address &= SBSDIO_SB_OFT_ADDR_MASK; + address &= SBSDIO_SB_OFT_ADDR_MASK; - if (register_length == 4) - address |= SBSDIO_SB_ACCESS_2_4B_FLAG; + if (register_length == 4) + address |= SBSDIO_SB_ACCESS_2_4B_FLAG; - CHECK_RETURN(whd_bus_sdio_transfer(whd_driver, BUS_WRITE, BACKPLANE_FUNCTION, address, register_length, - (uint8_t *)&value, RESPONSE_NEEDED)); + CHECK_RETURN(whd_bus_sdio_transfer(whd_driver, BUS_WRITE, BACKPLANE_FUNCTION, address, register_length, + (uint8_t *)&value, RESPONSE_NEEDED) ); - return whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); + return whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); } whd_result_t whd_bus_sdio_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, - uint8_t *value) + uint8_t *value) { - *value = 0; - CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address)); + *value = 0; + CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address) ); - address &= SBSDIO_SB_OFT_ADDR_MASK; + address &= SBSDIO_SB_OFT_ADDR_MASK; - if (register_length == 4) - address |= SBSDIO_SB_ACCESS_2_4B_FLAG; + if (register_length == 4) + address |= SBSDIO_SB_ACCESS_2_4B_FLAG; - CHECK_RETURN(whd_bus_sdio_transfer(whd_driver, BUS_READ, BACKPLANE_FUNCTION, address, register_length, value, - RESPONSE_NEEDED)); + CHECK_RETURN(whd_bus_sdio_transfer(whd_driver, BUS_READ, BACKPLANE_FUNCTION, address, register_length, value, + RESPONSE_NEEDED) ); - return whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); + return whd_bus_set_backplane_window(whd_driver, CHIPCOMMON_BASE_ADDRESS); } whd_result_t whd_bus_sdio_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint32_t value) + uint8_t value_length, uint32_t value) { - return whd_bus_sdio_transfer(whd_driver, BUS_WRITE, function, address, value_length, (uint8_t *)&value, - RESPONSE_NEEDED); + return whd_bus_sdio_transfer(whd_driver, BUS_WRITE, function, address, value_length, (uint8_t *)&value, + RESPONSE_NEEDED); } whd_result_t whd_bus_sdio_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t size, - whd_transfer_bytes_packet_t *data) + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data) { - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - return whd_bus_sdio_transfer(whd_driver, direction, function, address, size, (uint8_t *)data->data, - RESPONSE_NEEDED); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + return whd_bus_sdio_transfer(whd_driver, direction, function, address, size, (uint8_t *)data->data, + RESPONSE_NEEDED); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) } /****************************************************** @@ -751,232 +955,281 @@ whd_result_t whd_bus_sdio_transfer_bytes(whd_driver_t whd_driver, whd_bus_transf ******************************************************/ static whd_result_t whd_bus_sdio_transfer(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t data_size, - uint8_t *data, sdio_response_needed_t response_expected) + whd_bus_function_t function, uint32_t address, uint16_t data_size, + uint8_t *data, sdio_response_needed_t response_expected) { - /* Note: this function had broken retry logic (never retried), which has been removed. + /* Note: this function had broken retry logic (never retried), which has been removed. * Failing fast helps problems on the bus get brought to light more quickly * and preserves the original behavior. */ - whd_result_t result = WHD_SUCCESS; - uint16_t data_byte_size; - uint16_t data_blk_size; - - if (data_size == 0) { - return WHD_BADARG; - } - else if (data_size == (uint16_t)1) { - return whd_bus_sdio_cmd52(whd_driver, direction, function, address, *data, response_expected, data); - } - else if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) { - return whd_bus_sdio_cmd53(whd_driver, direction, function, - (data_size >= (uint16_t)64) ? SDIO_BLOCK_MODE : SDIO_BYTE_MODE, address, data_size, - data, response_expected, NULL); - } - else { - /* We need to handle remaining size for source image download */ - data_byte_size = data_size % SDIO_64B_BLOCK; - data_blk_size = data_size - data_byte_size; - if (data_blk_size != 0) { - result = whd_bus_sdio_cmd53(whd_driver, direction, function, SDIO_BLOCK_MODE, address, - data_blk_size, data, response_expected, NULL); - if (result != WHD_SUCCESS) { - return result; - } - data += data_blk_size; - address += data_blk_size; - } - if (data_byte_size) { - result = whd_bus_sdio_cmd53(whd_driver, direction, function, SDIO_BYTE_MODE, address, - data_byte_size, data, response_expected, NULL); - } - return result; - } + whd_result_t result = WHD_SUCCESS; + uint16_t data_byte_size; + uint16_t data_blk_size; + + if (data_size == 0) + { + return WHD_BADARG; + } + else if (data_size == (uint16_t)1) + { + return whd_bus_sdio_cmd52(whd_driver, direction, function, address, *data, response_expected, data); + } + else if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) + { + return whd_bus_sdio_cmd53(whd_driver, direction, function, + (data_size >= (uint16_t)64) ? SDIO_BLOCK_MODE : SDIO_BYTE_MODE, address, data_size, + data, response_expected, NULL); + } + else + { + /* We need to handle remaining size for source image download */ + data_byte_size = data_size % SDIO_64B_BLOCK; + data_blk_size = data_size - data_byte_size; + if (data_blk_size != 0) + { + result = whd_bus_sdio_cmd53(whd_driver, direction, function, SDIO_BLOCK_MODE, address, + data_blk_size, data, response_expected, NULL); + if (result != WHD_SUCCESS) + { + return result; + } + data += data_blk_size; + address += data_blk_size; + } + if (data_byte_size) + { + result = whd_bus_sdio_cmd53(whd_driver, direction, function, SDIO_BYTE_MODE, address, + data_byte_size, data, response_expected, NULL); + } + return result; + } } static whd_result_t whd_bus_sdio_cmd52(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint8_t value, - sdio_response_needed_t response_expected, uint8_t *response) + whd_bus_function_t function, uint32_t address, uint8_t value, + sdio_response_needed_t response_expected, uint8_t *response) { - uint32_t sdio_response; - whd_result_t result; - sdio_cmd_argument_t arg; - arg.value = 0; - arg.cmd52.function_number = (uint32_t)(function & BUS_FUNCTION_MASK); - arg.cmd52.register_address = (uint32_t)(address & 0x00001ffff); - arg.cmd52.rw_flag = (uint32_t)((direction == BUS_WRITE) ? 1 : 0); - arg.cmd52.write_data = value; - - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); - result = cyhal_sdio_send_cmd(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, - CYHAL_SDIO_CMD_IO_RW_DIRECT, arg.value, - &sdio_response); - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (result != WHD_SUCCESS), cmd52_fail); - - if (response != NULL) { - *response = (uint8_t)(sdio_response & 0x00000000ff); - } - - CHECK_RETURN(result); - return WHD_SUCCESS; + uint32_t sdio_response = 0; + whd_result_t result; + sdio_cmd_argument_t arg; + arg.value = 0; + arg.cmd52.function_number = (uint32_t)(function & BUS_FUNCTION_MASK); + arg.cmd52.register_address = (uint32_t)(address & 0x00001ffff); + arg.cmd52.rw_flag = (uint32_t)( (direction == BUS_WRITE) ? 1 : 0 ); + arg.cmd52.write_data = value; + + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd52); + result = cyhal_sdio_send_cmd(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, + CYHAL_SDIO_CMD_IO_RW_DIRECT, arg.value, + &sdio_response); + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, (result != WHD_SUCCESS), cmd52_fail); + + if (response != NULL) + { + *response = (uint8_t)(sdio_response & 0x00000000ff); + } + + /* Possibly device might not respond to this cmd. So, don't check return value here */ + if ( (result != WHD_SUCCESS) && (address == SDIO_SLEEP_CSR) ) + { + return result; + } + + CHECK_RETURN(result); + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_cmd53(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, sdio_transfer_mode_t mode, uint32_t address, - uint16_t data_size, uint8_t *data, - sdio_response_needed_t response_expected, uint32_t *response) + whd_bus_function_t function, sdio_transfer_mode_t mode, uint32_t address, + uint16_t data_size, uint8_t *data, + sdio_response_needed_t response_expected, uint32_t *response) { - sdio_cmd_argument_t arg; - whd_result_t result; - - if (direction == BUS_WRITE) { - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); - } - - arg.value = 0; - arg.cmd53.function_number = (uint32_t)(function & BUS_FUNCTION_MASK); - arg.cmd53.register_address = (uint32_t)(address & BIT_MASK(17)); - arg.cmd53.op_code = (uint32_t)1; - arg.cmd53.rw_flag = (uint32_t)((direction == BUS_WRITE) ? 1 : 0); - - if (mode == SDIO_BYTE_MODE) { - whd_assert("whd_bus_sdio_cmd53: data_size > 512 for byte mode", (data_size <= (uint16_t)512)); - arg.cmd53.count = (uint32_t)(data_size & 0x1FF); - - result = - cyhal_sdio_bulk_transfer(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, arg.value, - (uint32_t *)data, data_size, response); - - if (result != CY_RSLT_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d cyhal_sdio_bulk_transfer SDIO_BYTE_MODE failed\n", __func__, __LINE__)); - goto done; - } - } - else { - arg.cmd53.count = (uint32_t)((data_size / (uint16_t)SDIO_64B_BLOCK) & BIT_MASK(9)); - if ((uint32_t)(arg.cmd53.count * (uint16_t)SDIO_64B_BLOCK) < data_size) { - ++arg.cmd53.count; - } - arg.cmd53.block_mode = (uint32_t)1; - - result = - cyhal_sdio_bulk_transfer(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, arg.value, - (uint32_t *)data, data_size, response); - - if (result != CY_RSLT_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d cyhal_sdio_bulk_transfer failed\n", __func__, __LINE__)); - goto done; - } - } - - if (direction == BUS_READ) { - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); - } + sdio_cmd_argument_t arg; + whd_result_t result; + + if (direction == BUS_WRITE) + { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_write); + } + + arg.value = 0; + arg.cmd53.function_number = (uint32_t)(function & BUS_FUNCTION_MASK); + arg.cmd53.register_address = (uint32_t)(address & BIT_MASK(17) ); + arg.cmd53.op_code = (uint32_t)1; + arg.cmd53.rw_flag = (uint32_t)( (direction == BUS_WRITE) ? 1 : 0 ); + + if (mode == SDIO_BYTE_MODE) + { + whd_assert("whd_bus_sdio_cmd53: data_size > 512 for byte mode", (data_size <= (uint16_t )512) ); + arg.cmd53.count = (uint32_t)(data_size & 0x1FF); + + result = + cyhal_sdio_bulk_transfer(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, arg.value, + (uint32_t *)data, data_size, response); + + if (result != CY_RSLT_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d cyhal_sdio_bulk_transfer SDIO_BYTE_MODE failed\n", __func__, __LINE__) ); + goto done; + } + } + else + { + arg.cmd53.count = (uint32_t)( (data_size / (uint16_t)SDIO_64B_BLOCK) & BIT_MASK(9) ); + if ( (uint32_t)(arg.cmd53.count * (uint16_t)SDIO_64B_BLOCK) < data_size ) + { + ++arg.cmd53.count; + } + arg.cmd53.block_mode = (uint32_t)1; + + result = + cyhal_sdio_bulk_transfer(whd_driver->bus_priv->sdio_obj, (cyhal_sdio_transfer_t)direction, arg.value, + (uint32_t *)data, data_size, response); + + if (result != CY_RSLT_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d cyhal_sdio_bulk_transfer SDIO_BLOCK_MODE failed\n", __func__, __LINE__) ); + goto done; + } + } + + if (direction == BUS_READ) + { + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, cmd53_read); + } done: - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, - ((result != WHD_SUCCESS) && (direction == BUS_READ)), - cmd53_read_fail); - WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, - ((result != WHD_SUCCESS) && (direction == BUS_WRITE)), - cmd53_write_fail); - CHECK_RETURN(result); - return WHD_SUCCESS; + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, + ( (result != WHD_SUCCESS) && (direction == BUS_READ) ), + cmd53_read_fail); + WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver->bus_priv, + ( (result != WHD_SUCCESS) && (direction == BUS_WRITE) ), + cmd53_write_fail); + CHECK_RETURN(result); + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_download_firmware(whd_driver_t whd_driver) { - uint8_t csr_val = 0; - whd_result_t result; - uint32_t loop_count; - uint32_t ram_start_address; - - ram_start_address = GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); - if (ram_start_address != 0) { - CHECK_RETURN(whd_reset_core(whd_driver, WLAN_ARM_CORE, SICF_CPUHALT, SICF_CPUHALT)); - } - else { - CHECK_RETURN(whd_disable_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE)); - CHECK_RETURN(whd_disable_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE)); - CHECK_RETURN(whd_reset_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE)); - - CHECK_RETURN(whd_chip_specific_socsram_init(whd_driver)); - } - -#if 0 - /* 43362 specific: Remap JTAG pins to UART output */ - uint32_t data = 0; - CHECK_RETURN(whd_bus_write_backplane_value(0x18000650, 1, 1) ); - CHECK_RETURN(whd_bus_read_backplane_value(0x18000654, 4, (uint8_t *)&data) ); - data |= (1 << 24); - CHECK_RETURN(whd_bus_write_backplane_value(0x18000654, 4, data) ); + uint8_t csr_val = 0; + whd_result_t result; + uint32_t loop_count; + +#ifndef BLHS_SUPPORT + uint32_t ram_start_address; + + ram_start_address = GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + + if (ram_start_address != 0) + { + CHECK_RETURN(whd_reset_core(whd_driver, WLAN_ARM_CORE, SICF_CPUHALT, SICF_CPUHALT) ); + } + else + { + CHECK_RETURN(whd_disable_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE) ); + CHECK_RETURN(whd_disable_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE) ); + CHECK_RETURN(whd_reset_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE) ); + CHECK_RETURN(whd_chip_specific_socsram_init(whd_driver) ); + } +#endif + +#ifdef BLHS_SUPPORT + CHECK_RETURN(whd_bus_common_blhs(whd_driver, CHK_BL_INIT) ); +#endif + +#ifndef DM_43022C1 + result = whd_bus_write_wifi_firmware_image(whd_driver); + + if (result == WHD_UNFINISHED) + { + WPRINT_WHD_INFO( ("User aborted fw download\n") ); + /* user aborted */ + return result; + } + else if (result != WHD_SUCCESS) + { + whd_assert("Failed to load wifi firmware\n", result == WHD_SUCCESS); + return result; + } + + CHECK_RETURN(whd_bus_sdio_write_wifi_nvram_image(whd_driver) ); +#else + /* For the Chip - 43022(DM) : Download NVRAM before Firmware */ + CHECK_RETURN(whd_bus_sdio_write_wifi_nvram_image(whd_driver) ); + + result = whd_bus_write_wifi_firmware_image(whd_driver); + + if (result == WHD_UNFINISHED) + { + WPRINT_WHD_INFO( ("User aborted fw download\n") ); + /* user aborted */ + return result; + } + else if (result != WHD_SUCCESS) + { + whd_assert("Failed to load wifi firmware\n", result == WHD_SUCCESS); + return result; + } #endif - result = whd_bus_write_wifi_firmware_image(whd_driver); - - if (result == WHD_UNFINISHED) { - WPRINT_WHD_INFO(("User aborted fw download\n")); - /* user aborted */ - return result; - } - else if (result != WHD_SUCCESS) { - whd_assert("Failed to load wifi firmware\n", result == WHD_SUCCESS); - return result; - } - - CHECK_RETURN(whd_bus_sdio_write_wifi_nvram_image(whd_driver)); - - /* Take the ARM core out of reset */ - if (ram_start_address != 0) { - CHECK_RETURN(whd_reset_core(whd_driver, WLAN_ARM_CORE, 0, 0)); - } - else { - CHECK_RETURN(whd_reset_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE)); - - result = whd_device_core_is_up(whd_driver, WLAN_ARM_CORE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not bring ARM core up\n")); - /* Reachable after hitting assert */ - return result; - } - } - - /* Wait until the High Throughput clock is available */ - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, - &csr_val)) == WHD_SUCCESS) && - ((csr_val & SBSDIO_HT_AVAIL) == 0) && - (loop_count < (uint32_t)HT_AVAIL_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - if (loop_count >= (uint32_t)HT_AVAIL_TIMEOUT_MS) { - /* If your system times out here, it means that the WLAN firmware is not booting. + /* Take the ARM core out of reset */ +#ifndef BLHS_SUPPORT + if (ram_start_address != 0) + { + CHECK_RETURN(whd_reset_core(whd_driver, WLAN_ARM_CORE, 0, 0) ); + } + else + { + CHECK_RETURN(whd_reset_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE) ); + + result = whd_device_core_is_up(whd_driver, WLAN_ARM_CORE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not bring ARM core up\n") ); + /* Reachable after hitting assert */ + return result; + } + } +#endif + /* Wait until the High Throughput clock is available */ + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + &csr_val) ) == WHD_SUCCESS ) && + ( (csr_val & SBSDIO_HT_AVAIL) == 0 ) && + (loop_count < (uint32_t)HT_AVAIL_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + if (loop_count >= (uint32_t)HT_AVAIL_TIMEOUT_MS) + { + /* If your system times out here, it means that the WLAN firmware is not booting. * Check that your WLAN chip matches the 'wifi_image.c' being built - in GNU toolchain, $(CHIP) * makefile variable must be correct. */ - WPRINT_WHD_ERROR(("Timeout while waiting for high throughput clock\n")); - /* Reachable after hitting assert */ - return WHD_TIMEOUT; - } - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error while waiting for high throughput clock\n")); - /* Reachable after hitting assert */ - return result; - } - - /* Set up the interrupt mask and enable interrupts */ - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SDIO_INT_HOST_MASK(whd_driver), (uint8_t)4, HOSTINTMASK)); - - /* Enable F2 interrupts. This wasn't required for 4319 but is for the 43362 */ - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SDIO_FUNCTION_INT_MASK(whd_driver), (uint8_t)1, - SDIO_FUNC_MASK_F1 | SDIO_FUNC_MASK_F2)); - - /* Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped. */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_FUNCTION2_WATERMARK, (uint8_t)1, - (uint32_t)SDIO_F2_WATERMARK)); - - return WHD_SUCCESS; + WPRINT_WHD_ERROR( ("Timeout while waiting for high throughput clock\n") ); + /* Reachable after hitting assert */ + return WHD_TIMEOUT; + } + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error while waiting for high throughput clock\n") ); + /* Reachable after hitting assert */ + return result; + } + + /* Set up the interrupt mask and enable interrupts */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SDIO_INT_HOST_MASK(whd_driver), (uint8_t)4, HOSTINTMASK) ); + + /* Enable F2 interrupts. This wasn't required for 4319 but is for the 43362 */ + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SDIO_FUNCTION_INT_MASK(whd_driver), (uint8_t)1, + SDIO_FUNC_MASK_F1 | SDIO_FUNC_MASK_F2) ); + + /* Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped. */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_FUNCTION2_WATERMARK, (uint8_t)1, + (uint32_t)SDIO_F2_WATERMARK) ); + + return WHD_SUCCESS; } /** Aborts a SDIO read of a packet from the 802.11 device @@ -1001,298 +1254,340 @@ static whd_result_t whd_bus_sdio_download_firmware(whd_driver_t whd_driver) */ static whd_result_t whd_bus_sdio_abort_read(whd_driver_t whd_driver, whd_bool_t retry) { - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, read_aborts); + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, read_aborts); - /* Abort transfer on WLAN_FUNCTION */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOABORT, (uint8_t)1, - (uint32_t)WLAN_FUNCTION)); + /* Abort transfer on WLAN_FUNCTION */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOABORT, (uint8_t)1, + (uint32_t)WLAN_FUNCTION) ); - /* Send frame terminate */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_FRAME_CONTROL, (uint8_t)1, - SFC_RF_TERM)); + /* Send frame terminate */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_FRAME_CONTROL, (uint8_t)1, + SFC_RF_TERM) ); - /* If we want to retry message, send NAK */ - if (retry == WHD_TRUE) { - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)1, - SMB_NAK)); - } + /* If we want to retry message, send NAK */ + if (retry == WHD_TRUE) + { + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)1, + SMB_NAK) ); + } - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_result_t whd_bus_sdio_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, - uint8_t value_length, uint8_t *value) + uint8_t value_length, uint8_t *value) { - memset(value, 0, (size_t)value_length); - return whd_bus_sdio_transfer(whd_driver, BUS_READ, function, address, value_length, value, RESPONSE_NEEDED); + memset(value, 0, (size_t)value_length); + return whd_bus_sdio_transfer(whd_driver, BUS_READ, function, address, value_length, value, RESPONSE_NEEDED); } whd_result_t whd_bus_sdio_poke_wlan(whd_driver_t whd_driver) { - return whd_bus_write_backplane_value(whd_driver, SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)4, SMB_DEV_INT); + return whd_bus_write_backplane_value(whd_driver, SDIO_TO_SB_MAILBOX(whd_driver), (uint8_t)4, SMB_DEV_INT); } whd_result_t whd_bus_sdio_wakeup(whd_driver_t whd_driver) { - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_result_t whd_bus_sdio_sleep(whd_driver_t whd_driver) { - return WHD_SUCCESS; + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_set_oob_interrupt(whd_driver_t whd_driver, uint8_t gpio_pin_number) { - if (gpio_pin_number != 0) { - /* Redirect to OOB interrupt to GPIO1 */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_SELECT, (uint8_t)1, - (uint32_t)0xF)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_OUTPUT, (uint8_t)1, - (uint32_t)0x0)); - - /* Enable GPIOx (bit x) */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_ENABLE, (uint8_t)1, - (uint32_t)0x2)); - - /* Set GPIOx (bit x) on Chipcommon GPIO Control register */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, CHIPCOMMON_GPIO_CONTROL, (uint8_t)4, - (uint32_t)0x2)); - } - - return WHD_SUCCESS; + if (gpio_pin_number != 0) + { + /* Redirect to OOB interrupt to GPIO1 */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_SELECT, (uint8_t)1, + (uint32_t)0xF) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_OUTPUT, (uint8_t)1, + (uint32_t)0x0) ); + + /* Enable GPIOx (bit x) */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_GPIO_ENABLE, (uint8_t)1, + (uint32_t)0x2) ); + + /* Set GPIOx (bit x) on Chipcommon GPIO Control register */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, CHIPCOMMON_GPIO_CONTROL, (uint8_t)4, + (uint32_t)0x2) ); + } + + return WHD_SUCCESS; } void whd_bus_sdio_init_stats(whd_driver_t whd_driver) { - memset(&whd_driver->bus_priv->whd_bus_stats, 0, sizeof(whd_bus_stats_t)); + memset(&whd_driver->bus_priv->whd_bus_stats, 0, sizeof(whd_bus_stats_t) ); } whd_result_t whd_bus_sdio_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) { - WPRINT_MACRO(("Bus Stats.. \n" - "cmd52:%" PRIu32 ", cmd53_read:%" PRIu32 ", cmd53_write:%" PRIu32 "\n" - "cmd52_fail:%" PRIu32 ", cmd53_read_fail:%" PRIu32 ", cmd53_write_fail:%" PRIu32 "\n" - "oob_intrs:%" PRIu32 ", sdio_intrs:%" PRIu32 ", error_intrs:%" PRIu32 ", read_aborts:%" PRIu32 - "\n", - whd_driver->bus_priv->whd_bus_stats.cmd52, whd_driver->bus_priv->whd_bus_stats.cmd53_read, - whd_driver->bus_priv->whd_bus_stats.cmd53_write, - whd_driver->bus_priv->whd_bus_stats.cmd52_fail, - whd_driver->bus_priv->whd_bus_stats.cmd53_read_fail, - whd_driver->bus_priv->whd_bus_stats.cmd53_write_fail, - whd_driver->bus_priv->whd_bus_stats.oob_intrs, - whd_driver->bus_priv->whd_bus_stats.sdio_intrs, - whd_driver->bus_priv->whd_bus_stats.error_intrs, - whd_driver->bus_priv->whd_bus_stats.read_aborts)); - - if (reset_after_print == WHD_TRUE) { - memset(&whd_driver->bus_priv->whd_bus_stats, 0, sizeof(whd_bus_stats_t)); - } - - return WHD_SUCCESS; + WPRINT_INFO(("Bus Stats.. \n" + "cmd52:%" PRIu32 ", cmd53_read:%" PRIu32 ", cmd53_write:%" PRIu32 "\n" + "cmd52_fail:%" PRIu32 ", cmd53_read_fail:%" PRIu32 ", cmd53_write_fail:%" PRIu32 "\n" + "oob_intrs:%" PRIu32 ", sdio_intrs:%" PRIu32 ", error_intrs:%" PRIu32 ", read_aborts:%" PRIu32 + "\n", + whd_driver->bus_priv->whd_bus_stats.cmd52, whd_driver->bus_priv->whd_bus_stats.cmd53_read, + whd_driver->bus_priv->whd_bus_stats.cmd53_write, + whd_driver->bus_priv->whd_bus_stats.cmd52_fail, + whd_driver->bus_priv->whd_bus_stats.cmd53_read_fail, + whd_driver->bus_priv->whd_bus_stats.cmd53_write_fail, + whd_driver->bus_priv->whd_bus_stats.oob_intrs, + whd_driver->bus_priv->whd_bus_stats.sdio_intrs, + whd_driver->bus_priv->whd_bus_stats.error_intrs, + whd_driver->bus_priv->whd_bus_stats.read_aborts)); + + if (reset_after_print == WHD_TRUE) + { + memset(&whd_driver->bus_priv->whd_bus_stats, 0, sizeof(whd_bus_stats_t) ); + } + +#ifdef CYCFG_ULP_SUPPORT_ENABLED + if (whd_driver->ds_cb_info.callback != NULL) + { + CHECK_RETURN(whd_wifi_get_deepsleep_stats(whd_driver, whd_driver->ds_cb_info.buf, whd_driver->ds_cb_info.buflen) ); + } + else + { + WPRINT_WHD_ERROR( ("No callback registered") ); + } +#endif + + return WHD_SUCCESS; } /* Waking the firmware up from Deep Sleep */ whd_result_t whd_bus_sdio_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware) { - whd_result_t result = WHD_SUCCESS; - uint8_t byte_data; - uint32_t loop_count; - loop_count = 0; - - /* Setup the backplane*/ - loop_count = 0; - - do { - /* Enable function 1 (backplane) */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, - SDIO_FUNC_ENABLE_1)); - if (loop_count != 0) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - } - - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, &byte_data)); - loop_count++; - if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout on CCCR update\n")); - return WHD_TIMEOUT; - } - } while (byte_data != (uint8_t)SDIO_FUNC_ENABLE_1); - - if (whd_driver->bus_priv->sdio_config.sdio_1bit_mode == WHD_FALSE) { - /* Read the bus width and set to 4 bits */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, - &byte_data)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, - (byte_data & (~BUS_SD_DATA_WIDTH_MASK)) | BUS_SD_DATA_WIDTH_4BIT)); - /* NOTE: We don't need to change our local bus settings since we're not sending any data (only using CMD52) + whd_result_t result = WHD_SUCCESS; + uint8_t byte_data; + uint32_t loop_count; + loop_count = 0; + + /* Setup the backplane*/ + loop_count = 0; + + do + { + /* Enable function 1 (backplane) */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, + SDIO_FUNC_ENABLE_1) ); + if (loop_count != 0) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + } + + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, &byte_data) ); + loop_count++; + if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout on CCCR update\n") ); + return WHD_TIMEOUT; + } + } while (byte_data != (uint8_t)SDIO_FUNC_ENABLE_1); + + if (whd_driver->bus_priv->sdio_config.sdio_1bit_mode == WHD_FALSE) + { + /* Read the bus width and set to 4 bits */ + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, + &byte_data) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BICTRL, (uint8_t)1, + (byte_data & (~BUS_SD_DATA_WIDTH_MASK) ) | BUS_SD_DATA_WIDTH_4BIT) ); + /* NOTE: We don't need to change our local bus settings since we're not sending any data (only using CMD52) * until after we change the bus speed further down */ - } - - /* Set the block size */ - /* Wait till the backplane is ready */ - loop_count = 0; - while (((result = whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)) == WHD_SUCCESS) && - ((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - (byte_data != (uint8_t)SDIO_64B_BLOCK) && - (loop_count < (uint32_t)F0_WORKING_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) { - /* If the system fails here, check the high frequency crystal is working */ - WPRINT_WHD_ERROR(("Timeout while setting block size\n")); - return WHD_TIMEOUT; - } - } - - CHECK_RETURN(result); - - WPRINT_WHD_DEBUG(("Modding registers for blocks\n")); - - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F1BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_0, (uint8_t)1, - (uint32_t)SDIO_64B_BLOCK)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_1, (uint8_t)1, - (uint32_t)0)); /* Function 2 = 64 */ - - /* Enable/Disable Client interrupts */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, - INTR_CTL_MASTER_EN | INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN)); - - - if (whd_driver->bus_priv->sdio_config.high_speed_sdio_clock) { - WPRINT_WHD_DEBUG(("SDIO HS clock enable\n")); - - /* This code is required if we want more than 25 MHz clock */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, &byte_data)); - if ((byte_data & 0x1) != 0) { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, - byte_data | SDIO_SPEED_EHS)); - } - else { - WPRINT_WHD_ERROR(("Error writing to WLAN register, %s failed at %d \n", __func__, __LINE__)); - return WHD_BUS_READ_REGISTER_ERROR; - } - } /* HIGH_SPEED_SDIO_CLOCK */ - - /* Wait till the backplane is ready */ - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, - &byte_data)) == WHD_SUCCESS) && - ((byte_data & SDIO_FUNC_READY_1) == 0) && - (loop_count < (uint32_t)F1_AVAIL_TIMEOUT_MS)) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - - if (loop_count >= (uint32_t)F1_AVAIL_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout while waiting for backplane to be ready\n")); - return WHD_TIMEOUT; - } - CHECK_RETURN(result); - - /* Set the ALP */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, - (uint32_t)(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ | - SBSDIO_FORCE_ALP))); - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, - &byte_data)) != WHD_SUCCESS) || - (((byte_data & SBSDIO_ALP_AVAIL) == 0) && - (loop_count < (uint32_t)ALP_AVAIL_TIMEOUT_MS))) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - if (loop_count >= (uint32_t)ALP_AVAIL_TIMEOUT_MS) { - WPRINT_WHD_ERROR(("Timeout while waiting for alp clock\n")); - return WHD_TIMEOUT; - } - CHECK_RETURN(result); - - /* Clear request for ALP */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, 0)); - - /* Disable the extra SDIO pull-ups */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0)); - - /* Enable F1 and F2 */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, - SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2)); - - /* Setup host-wake signals */ - CHECK_RETURN(whd_bus_sdio_init_oob_intr(whd_driver)); - - /* Enable F2 interrupt only */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, - INTR_CTL_MASTER_EN | INTR_CTL_FUNC2_EN)); - - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, &byte_data)); - - result = whd_bus_sdio_download_firmware(whd_driver); - - if (result != WHD_SUCCESS) { - /* either an error or user abort */ - WPRINT_WHD_DEBUG(("FW download failed\n")); - return result; - } - - /* Wait for F2 to be ready */ - loop_count = 0; - while (((result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, - &byte_data)) != WHD_SUCCESS) || - (((byte_data & SDIO_FUNC_READY_2) == 0) && - (loop_count < (uint32_t)F2_READY_TIMEOUT_MS))) { - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - loop_count++; - } - - if (loop_count >= (uint32_t)F2_READY_TIMEOUT_MS) { - WPRINT_WHD_DEBUG(("Timeout while waiting for function 2 to be ready\n")); - - if (WHD_TRUE == wake_from_firmware) { - /* If your system fails here, it could be due to incorrect NVRAM variables. + } + + /* Set the block size */ + /* Wait till the backplane is ready */ + loop_count = 0; + while ( ( (result = whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ) == WHD_SUCCESS ) && + ( (result = whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + (byte_data != (uint8_t)SDIO_64B_BLOCK) && + (loop_count < (uint32_t)F0_WORKING_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + if (loop_count >= (uint32_t)F0_WORKING_TIMEOUT_MS) + { + /* If the system fails here, check the high frequency crystal is working */ + WPRINT_WHD_ERROR( ("Timeout while setting block size\n") ); + return WHD_TIMEOUT; + } + } + + CHECK_RETURN(result); + + WPRINT_WHD_DEBUG( ("Modding registers for blocks\n") ); + + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F1BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_0, (uint8_t)1, + (uint32_t)SDIO_64B_BLOCK) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_F2BLKSIZE_1, (uint8_t)1, + (uint32_t)0) ); /* Function 2 = 64 */ + + /* Enable/Disable Client interrupts */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, + INTR_CTL_MASTER_EN | INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN) ); + + + if (whd_driver->bus_priv->sdio_config.high_speed_sdio_clock) + { + WPRINT_WHD_DEBUG( ("SDIO HS clock enable\n") ); + + /* This code is required if we want more than 25 MHz clock */ + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, &byte_data) ); + if ( (byte_data & 0x1) != 0 ) + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_SPEED_CONTROL, 1, + byte_data | SDIO_SPEED_EHS) ); + } + else + { + WPRINT_WHD_ERROR( ("Error writing to WLAN register, %s failed at %d \n", __func__, __LINE__) ); + return WHD_BUS_READ_REGISTER_ERROR; + } + } /* HIGH_SPEED_SDIO_CLOCK */ + + /* Wait till the backplane is ready */ + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, + &byte_data) ) == WHD_SUCCESS ) && + ( (byte_data & SDIO_FUNC_READY_1) == 0 ) && + (loop_count < (uint32_t)F1_AVAIL_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + + if (loop_count >= (uint32_t)F1_AVAIL_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout while waiting for backplane to be ready\n") ); + return WHD_TIMEOUT; + } + CHECK_RETURN(result); + + /* Set the ALP */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + (uint32_t)(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ | + SBSDIO_FORCE_ALP) ) ); + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + &byte_data) ) != WHD_SUCCESS ) || + ( ( (byte_data & SBSDIO_ALP_AVAIL) == 0 ) && + (loop_count < (uint32_t)ALP_AVAIL_TIMEOUT_MS) ) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + if (loop_count >= (uint32_t)ALP_AVAIL_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("Timeout while waiting for alp clock\n") ); + return WHD_TIMEOUT; + } + CHECK_RETURN(result); + + /* Clear request for ALP */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, 0) ); + + /* Disable the extra SDIO pull-ups */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0) ); + + /* Enable F1 and F2 */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, + SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2) ); + /* Enable F2 interrupt only */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTEN, (uint8_t)1, + INTR_CTL_MASTER_EN | INTR_CTL_FUNC2_EN) ); + + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, &byte_data) ); + WPRINT_WHD_DEBUG(("FW RE-DOWNL STARTS \n")); + + result = whd_bus_sdio_download_firmware(whd_driver); + + if (result != WHD_SUCCESS) + { + /* either an error or user abort */ + WPRINT_WHD_ERROR( ("FW re-download failed\n") ); + return result; + } + else + { + WPRINT_WHD_ERROR( (" # DS0-FW DOWNLOAD DONE # \n") ); + whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; + } + + /* Wait for F2 to be ready */ + loop_count = 0; + while ( ( (result = whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, + &byte_data) ) != WHD_SUCCESS ) || + ( ( (byte_data & SDIO_FUNC_READY_2) == 0 ) && + (loop_count < (uint32_t)F2_READY_TIMEOUT_MS) ) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + + if (loop_count >= (uint32_t)F2_READY_TIMEOUT_MS) + { + WPRINT_WHD_DEBUG( ("Timeout while waiting for function 2 to be ready\n") ); + + if (WHD_TRUE == wake_from_firmware) + { + /* If your system fails here, it could be due to incorrect NVRAM variables. * Check which 'wifi_nvram_image.h' file your platform is using, and * check that it matches the WLAN device on your platform, including the * crystal frequency. */ - WPRINT_WHD_ERROR(("F2 failed on wake fr FW\n")); - /* Reachable after hitting assert */ - return WHD_TIMEOUT; - } - /* Else: Ignore this failure if we're doing a reinit due to host wake: Linux DHD also ignores */ - } + WPRINT_WHD_ERROR( ("F2 failed on wake fr FW\n") ); + /* Reachable after hitting assert */ + return WHD_TIMEOUT; + } + /* Else: Ignore this failure if we're doing a reinit due to host wake: Linux DHD also ignores */ + + } + + /* Update wlan state */ + whd_driver->internal_info.whd_wlan_status.state = WLAN_UP; + /* Do chip specific init */ + CHECK_RETURN(whd_chip_specific_init(whd_driver) ); - /* Do chip specific init */ - CHECK_RETURN(whd_chip_specific_init(whd_driver)); + /* Ensure Bus is up */ + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); - /* Ensure Bus is up */ - CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); + /* Allow bus to go to sleep */ + CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver) ); - /* Allow bus to go to sleep */ - CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver)); + CHECK_RETURN(whd_sdpcm_init(whd_driver)); - WPRINT_WHD_INFO(("whd_bus_reinit Completed \n")); - return WHD_SUCCESS; +#ifdef CYCFG_ULP_SUPPORT_ENABLED + whd_driver->ds_exit_in_progress = WHD_FALSE; +#endif + + WPRINT_WHD_INFO( ("whd_bus_reinit Completed \n") ); + return WHD_SUCCESS; } uint8_t whd_bus_sdio_backplane_read_padd_size(whd_driver_t whd_driver) { - return WHD_BUS_SDIO_BACKPLANE_READ_PADD_SIZE; + return WHD_BUS_SDIO_BACKPLANE_READ_PADD_SIZE; } whd_bool_t whd_bus_sdio_use_status_report_scheme(whd_driver_t whd_driver) { - return WHD_FALSE; + return WHD_FALSE; } uint32_t whd_bus_sdio_get_max_transfer_size(whd_driver_t whd_driver) { - return WHD_BUS_SDIO_MAX_BACKPLANE_TRANSFER_SIZE; + return WHD_BUS_SDIO_MAX_BACKPLANE_TRANSFER_SIZE; } #if (CYHAL_API_VERSION >= 2) @@ -1301,44 +1596,41 @@ static void whd_bus_sdio_irq_handler(void *handler_arg, cyhal_sdio_event_t event static void whd_bus_sdio_irq_handler(void *handler_arg, cyhal_sdio_irq_event_t event) #endif { - whd_driver_t whd_driver = (whd_driver_t)handler_arg; - - /* WHD registered only for CY_CYHAL_SDIO_CARD_INTERRUPT */ - if (event != CYHAL_SDIO_CARD_INTERRUPT) { - WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", event)); - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, error_intrs); - return; - } + whd_driver_t whd_driver = (whd_driver_t)handler_arg; - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); + /* WHD registered only for CY_CYHAL_SDIO_CARD_INTERRUPT */ + if (event != CYHAL_SDIO_CARD_INTERRUPT) + { + WPRINT_WHD_ERROR( ("Unexpected interrupt event %d\n", event) ); + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, error_intrs); + return; + } - /* call thread notify to wake up WHD thread */ - whd_thread_notify_irq(whd_driver); + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, sdio_intrs); - /* wait for interrupt clear */ - cy_rtos_get_semaphore(&whd_driver->bus_priv->int_clear_semaphore, WHD_INT_CLEAR_TIMEOUT, WHD_FALSE); + /* call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); } whd_result_t whd_bus_sdio_irq_register(whd_driver_t whd_driver) { - cy_rtos_init_semaphore(&whd_driver->bus_priv->int_clear_semaphore, 1, 0); #if (CYHAL_API_VERSION >= 2) - cyhal_sdio_register_callback(whd_driver->bus_priv->sdio_obj, whd_bus_sdio_irq_handler, whd_driver); + cyhal_sdio_register_callback(whd_driver->bus_priv->sdio_obj, whd_bus_sdio_irq_handler, whd_driver); #else - cyhal_sdio_register_irq(whd_driver->bus_priv->sdio_obj, whd_bus_sdio_irq_handler, whd_driver); + cyhal_sdio_register_irq(whd_driver->bus_priv->sdio_obj, whd_bus_sdio_irq_handler, whd_driver); #endif - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_result_t whd_bus_sdio_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) { #if (CYHAL_API_VERSION >= 2) - cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, - enable); + cyhal_sdio_enable_event(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, CYHAL_ISR_PRIORITY_DEFAULT, + enable); #else - cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, enable); + cyhal_sdio_irq_enable(whd_driver->bus_priv->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, enable); #endif - return WHD_SUCCESS; + return WHD_SUCCESS; } #if (CYHAL_API_VERSION >= 2) @@ -1347,198 +1639,510 @@ static void whd_bus_sdio_oob_irq_handler(void *arg, cyhal_gpio_event_t event) static void whd_bus_sdio_oob_irq_handler(void *arg, cyhal_gpio_irq_event_t event) #endif { - whd_driver_t whd_driver = (whd_driver_t)arg; - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + whd_driver_t whd_driver = (whd_driver_t)arg; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; #if (CYHAL_API_VERSION >= 2) - const cyhal_gpio_event_t expected_event = (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + const cyhal_gpio_event_t expected_event = (config->is_falling_edge == WHD_TRUE) + ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; #else - const cyhal_gpio_irq_event_t expected_event = (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + const cyhal_gpio_irq_event_t expected_event = (config->is_falling_edge == WHD_TRUE) + ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; #endif - if (event != expected_event) { - WPRINT_WHD_ERROR(("Unexpected interrupt event %d\n", event)); - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, error_intrs); - return; - } + if (event != expected_event) + { + WPRINT_WHD_ERROR( ("Unexpected interrupt event %d\n", event) ); + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, error_intrs); + return; + } - WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, oob_intrs); + WHD_BUS_STATS_INCREMENT_VARIABLE(whd_driver->bus_priv, oob_intrs); - /* Call thread notify to wake up WHD thread */ - whd_thread_notify_irq(whd_driver); + /* Call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); } static whd_result_t whd_bus_sdio_register_oob_intr(whd_driver_t whd_driver) { - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + + CHECK_RETURN(cyhal_gpio_init(config->host_oob_pin, CYHAL_GPIO_DIR_INPUT, config->drive_mode, config->init_drive_state)); - cyhal_gpio_init(config->host_oob_pin, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_NONE, 0); #if (CYHAL_API_VERSION >= 2) - static cyhal_gpio_callback_data_t cbdata; - cbdata.callback = whd_bus_sdio_oob_irq_handler; - cbdata.callback_arg = whd_driver; - cyhal_gpio_register_callback(config->host_oob_pin, &cbdata); + static cyhal_gpio_callback_data_t cbdata; + cbdata.callback = whd_bus_sdio_oob_irq_handler; + cbdata.callback_arg = whd_driver; + cyhal_gpio_register_callback(config->host_oob_pin, &cbdata); #else - cyhal_gpio_register_irq(config->host_oob_pin, config->intr_priority, whd_bus_sdio_oob_irq_handler, - whd_driver); + cyhal_gpio_register_irq(config->host_oob_pin, config->intr_priority, whd_bus_sdio_oob_irq_handler, + whd_driver); #endif - return WHD_SUCCESS; + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_unregister_oob_intr(whd_driver_t whd_driver) { - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + + cyhal_gpio_free(config->host_oob_pin); #if (CYHAL_API_VERSION >= 2) - cyhal_gpio_register_callback(config->host_oob_pin, NULL); + cyhal_gpio_register_callback(config->host_oob_pin, NULL); #else - cyhal_gpio_register_irq(config->host_oob_pin, config->intr_priority, NULL, NULL); + cyhal_gpio_register_irq(config->host_oob_pin, config->intr_priority, NULL, NULL); #endif - return WHD_SUCCESS; + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_enable_oob_intr(whd_driver_t whd_driver, whd_bool_t enable) { - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; #if (CYHAL_API_VERSION >= 2) - const cyhal_gpio_event_t event = - (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + const cyhal_gpio_event_t event = + (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; - cyhal_gpio_enable_event(config->host_oob_pin, event, config->intr_priority, (enable == WHD_TRUE) ? true : false); + cyhal_gpio_enable_event(config->host_oob_pin, event, config->intr_priority, (enable == WHD_TRUE) ? true : false); #else - const cyhal_gpio_irq_event_t event = - (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + const cyhal_gpio_irq_event_t event = + (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; - cyhal_gpio_irq_enable(config->host_oob_pin, event, (enable == WHD_TRUE) ? true : false); + cyhal_gpio_irq_enable(config->host_oob_pin, event, (enable == WHD_TRUE) ? true : false); #endif - return WHD_SUCCESS; + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_init_oob_intr(whd_driver_t whd_driver) { - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; - uint8_t sepintpol; - - /* OOB isn't configured so bail */ - if (config->host_oob_pin == CYHAL_NC_PIN_VALUE) - return WHD_SUCCESS; - - /* Choose out-of-band interrupt polarity */ - if (config->is_falling_edge == WHD_FALSE) { - sepintpol = SEP_INTR_CTL_POL; - } - else { - sepintpol = 0; - } - - /* Set OOB interrupt to the correct WLAN GPIO pin (default to GPIO0) */ - if (config->dev_gpio_sel) - CHECK_RETURN(whd_bus_sdio_set_oob_interrupt(whd_driver, config->dev_gpio_sel)); - - /* Enable out-of-band interrupt on the device */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_SEP_INT_CTL, (uint8_t)1, - SEP_INTR_CTL_MASK | SEP_INTR_CTL_EN | sepintpol)); - - /* Register and enable OOB */ - /* XXX Remove this when BSP377 is implemented */ - CHECK_RETURN(whd_bus_sdio_register_oob_intr(whd_driver)); - CHECK_RETURN(whd_bus_sdio_enable_oob_intr(whd_driver, WHD_TRUE)); - - return WHD_SUCCESS; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + uint8_t sepintpol; + + /* OOB isn't configured so bail */ + if (config->host_oob_pin == CYHAL_NC_PIN_VALUE) + return WHD_SUCCESS; + + /* Choose out-of-band interrupt polarity */ + if (config->is_falling_edge == WHD_FALSE) + { + sepintpol = SEP_INTR_CTL_POL; + } + else + { + sepintpol = 0; + } + + /* Set OOB interrupt to the correct WLAN GPIO pin (default to GPIO0) */ + if (config->dev_gpio_sel) + CHECK_RETURN(whd_bus_sdio_set_oob_interrupt(whd_driver, config->dev_gpio_sel) ); + + /* Enable out-of-band interrupt on the device */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_SEP_INT_CTL, (uint8_t)1, + SEP_INTR_CTL_MASK | SEP_INTR_CTL_EN | sepintpol) ); + + /* Register and enable OOB */ + /* XXX Remove this when BSP377 is implemented */ + CHECK_RETURN(whd_bus_sdio_register_oob_intr(whd_driver) ); + CHECK_RETURN(whd_bus_sdio_enable_oob_intr(whd_driver, WHD_TRUE) ); + + return WHD_SUCCESS; } static whd_result_t whd_bus_sdio_deinit_oob_intr(whd_driver_t whd_driver) { - const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; + const whd_oob_config_t *config = &whd_driver->bus_priv->sdio_config.oob_config; - if (config->host_oob_pin != CYHAL_NC_PIN_VALUE) { - CHECK_RETURN(whd_bus_sdio_enable_oob_intr(whd_driver, WHD_FALSE)); - CHECK_RETURN(whd_bus_sdio_unregister_oob_intr(whd_driver)); - } + if (config->host_oob_pin != CYHAL_NC_PIN_VALUE) + { + CHECK_RETURN(whd_bus_sdio_enable_oob_intr(whd_driver, WHD_FALSE) ); + CHECK_RETURN(whd_bus_sdio_unregister_oob_intr(whd_driver) ); + } - return WHD_SUCCESS; + return WHD_SUCCESS; } -static whd_result_t whd_bus_sdio_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, - whd_bool_t direct_resource, uint32_t address, uint32_t image_size) +#ifdef BLHS_SUPPORT +static whd_result_t whd_bus_sdio_blhs_read_h2d(whd_driver_t whd_driver, uint32_t *val) { - whd_result_t result = WHD_SUCCESS; - uint8_t *image; - uint32_t blocks_count = 0; - uint32_t i; - uint32_t size_out; - uint32_t reset_instr = 0; - - result = whd_get_resource_no_of_blocks(whd_driver, resource, &blocks_count); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Fatal error: download_resource blocks count not known, %s failed at line %d \n", __func__, - __LINE__)); - goto exit; - } - - for (i = 0; i < blocks_count; i++) { - CHECK_RETURN(whd_get_resource_block(whd_driver, resource, i, (const uint8_t **)&image, &size_out)); - if ((resource == WHD_RESOURCE_WLAN_FIRMWARE) && (reset_instr == 0)) { - /* Copy the starting address of the firmware into a global variable */ - reset_instr = *((uint32_t *)(&image[0])); - } - result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_WRITE, address, size_out, &image[0]); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Failed to write firmware image\n", __FUNCTION__)); - goto exit; - } - address += size_out; - } - - /* Below part of the code is applicable to arm_CR4 type chips only - * The CR4 chips by default firmware is not loaded at 0. So we need - * load the first 32 bytes with the offset of the firmware load address - * which is been copied before during the firmware download - */ - if ((address != 0) && (reset_instr != 0)) { - /* write address 0 with reset instruction */ - result = whd_bus_write_backplane_value(whd_driver, 0, sizeof(reset_instr), reset_instr); + return whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_REG_DAR_H2D_MSG_0, 1, (uint8_t *)val); +} + +static whd_result_t whd_bus_sdio_blhs_write_h2d(whd_driver_t whd_driver, uint32_t val) +{ + return whd_bus_sdio_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_REG_DAR_H2D_MSG_0, + (uint8_t)1, val); +} + +static whd_result_t whd_bus_sdio_blhs_wait_d2h(whd_driver_t whd_driver, uint16_t state) +{ + uint16_t byte_data = 0; + uint32_t loop_count = 0; + whd_result_t result; +#ifdef DM_43022C1 + uint8_t no_of_bytes = 2; +#else + uint8_t no_of_bytes = 1; +#endif + + while ( ( (result = + whd_bus_sdio_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_REG_DAR_D2H_MSG_0, (uint8_t)no_of_bytes, + (uint8_t*)&byte_data) ) == WHD_SUCCESS ) && + ( (byte_data & state) == 0 ) && + (loop_count < SDIO_BLHS_D2H_TIMEOUT_MS) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)10 ); + loop_count += 10; + } + + if (loop_count >= SDIO_BLHS_D2H_TIMEOUT_MS) + { + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Read D2H message failed\n") ); + } + else + { + WPRINT_WHD_ERROR( ("Timeout while waiting for D2H_MSG(0x%x) expected 0x%x\n", byte_data, state) ); + } + return WHD_TIMEOUT; + } + + return WHD_SUCCESS; +} - if (result == WHD_SUCCESS) { - uint32_t tmp; +static whd_result_t whd_bus_sdio_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage) +{ + uint32_t val = 0; +#ifdef DM_43022C1 + uint32_t loop = 0; + uint32_t value = 0; +#endif - /* verify reset instruction value */ - result = whd_bus_read_backplane_value(whd_driver, 0, sizeof(tmp), (uint8_t *)&tmp); + /* Skip bootloader handshake if it is not need */ - if ((result == WHD_SUCCESS) && (tmp != reset_instr)) { - WPRINT_WHD_ERROR(("%s: Failed to write 0x%08" PRIx32 " to addr 0\n", __FUNCTION__, reset_instr)); - WPRINT_WHD_ERROR(("%s: contents of addr 0 is 0x%08" PRIx32 "\n", __FUNCTION__, tmp)); - return WHD_WLAN_SDIO_ERROR; + switch (stage) + { + case CHK_BL_INIT: + WPRINT_WHD_DEBUG(("CHK_BL_INIT \n")); +#ifdef DM_43022C1 + CHECK_RETURN(whd_bus_sdio_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_REG_DAR_H2D_MSG_0, + (uint8_t)4, SDIO_BLHS_H2D_BL_INIT)); +#else + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_BL_INIT) ); +#endif + CHECK_RETURN(whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_READY) ); + break; + case PREP_FW_DOWNLOAD: + WPRINT_WHD_DEBUG(("PREP_FW_DOWNLOAD!! \n")); + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_DL_FW_START) ); + break; + case POST_FW_DOWNLOAD: + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_DL_FW_DONE) ); + WPRINT_WHD_DEBUG(("POST_FW_DOWNLOAD \n")); + +#ifdef DM_43022C1 + + if (whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_BP_CLK_DIS_REQ) != WHD_SUCCESS) + { + whd_wifi_print_whd_log(whd_driver); + whd_bus_sdio_blhs_read_h2d(whd_driver, &val); + whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_BL_RESET_ON_ERROR) ); + return WHD_BLHS_VALIDATE_FAILED; + } + else + { + WPRINT_WHD_DEBUG(("Received SDIO_BLHS_D2H_BP_CLK_DIS_REQ from Dongle!! \n")); + whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_BP_CLK_DIS_ACK); + WPRINT_WHD_DEBUG(("SDIO_BLHS_H2D_BP_CLK_DIS_ACK \n")); + } + + /* Check for any interrupt pending. Here Interrupt pending will be treated as HS bit + * to know that the backplane is enabled. Interrupt pending register is chosen here + * because the backplane will be disabled and this is the only tested register which + * is accessible while backplane is disabled + */ + for (loop = 0; loop < 80000; loop++) { + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_INTPEND, (uint8_t)4, (uint8_t *)&value)); + if (value & SDIOD_CCCR_INTPEND_INT1) { + WPRINT_WHD_DEBUG(("%s: Backplane enabled.\n", __func__)); + break; + } } - } - } + + /* Bootloader hung after backplane disable */ + if (loop == 80000) { + WPRINT_WHD_ERROR(("%s: Device hung, return failure.\n", __func__)); + return WHD_BLHS_VALIDATE_FAILED; + } +#else + if (whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_TRXHDR_PARSE_DONE) != WHD_SUCCESS) + { + whd_wifi_print_whd_log(whd_driver); + whd_bus_sdio_blhs_read_h2d(whd_driver, &val); + whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_BL_RESET_ON_ERROR) ); + return WHD_BLHS_VALIDATE_FAILED; + } + else + { + WPRINT_WHD_DEBUG(("Received TRX parsing Succeed MSG from Dongle \n")); + } +#endif /* DM_43022C1 */ + break; + case CHK_FW_VALIDATION: + WPRINT_WHD_DEBUG(("CHK_FW_VALIDATION \n")); + if ( (whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_VALDN_DONE) != WHD_SUCCESS) || + (whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_VALDN_RESULT) != WHD_SUCCESS) ) + { + whd_wifi_print_whd_log(whd_driver); + whd_bus_sdio_blhs_read_h2d(whd_driver, &val); + whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_BL_RESET_ON_ERROR) ); + return WHD_BLHS_VALIDATE_FAILED; + } + break; +#ifdef DM_43022C1 + case PREP_NVRAM_DOWNLOAD: + WPRINT_WHD_DEBUG(("PREP_NVRAM_DOWNLOAD \n")); + CHECK_RETURN(whd_bus_sdio_blhs_read_h2d(whd_driver, &val) ); + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_DL_NVRAM_START) ) ); + break; +#endif + case POST_NVRAM_DOWNLOAD: + WPRINT_WHD_DEBUG(("POST_NVRAM_DOWNLOAD \n")); + CHECK_RETURN(whd_bus_sdio_blhs_read_h2d(whd_driver, &val) ); + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_DL_NVRAM_DONE) ) ); +#ifdef DM_43022C1 + /* For chip 43022(DM), NVRAM is downloaded at 512KB region and BL moves the NVRAM at the RAM end portion and gives ACK(SDIO_BLHS_D2H_NVRAM_DONE) */ + if (whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_NVRAM_MV_DONE) != WHD_SUCCESS) + { + whd_wifi_print_whd_log(whd_driver); + whd_bus_sdio_blhs_read_h2d(whd_driver, &val); + whd_bus_sdio_blhs_write_h2d(whd_driver, (val | SDIO_BLHS_H2D_BL_RESET_ON_ERROR) ); + return WHD_BLHS_VALIDATE_FAILED; + } +#endif + break; + case POST_WATCHDOG_RESET: + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_BL_INIT) ); + CHECK_RETURN(whd_bus_sdio_blhs_wait_d2h(whd_driver, SDIO_BLHS_D2H_READY) ); + default: + return WHD_BADARG; + } + + return WHD_SUCCESS; +} + +#endif + +#ifdef WPRINT_ENABLE_WHD_DEBUG +#define WHD_BLOCK_SIZE (1024) +static whd_result_t whd_bus_sdio_verify_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, uint32_t image_size) +{ + whd_result_t result = WHD_SUCCESS; + uint8_t *image; + uint8_t *cmd_img = NULL; + uint32_t blocks_count = 0; + uint32_t i; + uint32_t size_out; + + result = whd_get_resource_no_of_blocks(whd_driver, resource, &blocks_count); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource blocks count not known, %s failed at line %d \n", __func__, + __LINE__) ); + goto exit; + } + cmd_img = whd_mem_malloc(WHD_BLOCK_SIZE); + if (cmd_img != NULL) + { + for (i = 0; i < blocks_count; i++) + { + CHECK_RETURN(whd_get_resource_block(whd_driver, resource, i, (const uint8_t **)&image, &size_out) ); + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, size_out, cmd_img); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Failed to read firmware image\n", __FUNCTION__) ); + goto exit; + } + if (memcmp(cmd_img, &image[0], size_out) ) + { + WPRINT_WHD_ERROR( ("%s: Downloaded image is corrupted, address is %d, len is %d, resource is %d \n", + __FUNCTION__, (int)address, (int)size_out, (int)resource) ); + } + address += size_out; + } + } exit: - return result; + if (cmd_img) + whd_mem_free(cmd_img); + return WHD_SUCCESS; +} + +#endif + +static whd_result_t whd_bus_sdio_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, uint32_t image_size) +{ + +#ifdef DM_43022C1 +#define TRX_HDR_START_ADDR 0x7fd4c /* TRX header start address */ +#endif + + whd_result_t result = WHD_SUCCESS; + uint8_t *image; + uint32_t blocks_count = 0; + uint32_t i; + uint32_t size_out; + uint32_t reset_instr = 0; +#ifdef WPRINT_ENABLE_WHD_DEBUG + uint32_t pre_addr = address; +#endif + + result = whd_get_resource_no_of_blocks(whd_driver, resource, &blocks_count); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource blocks count not known, %s failed at line %d \n", __func__, + __LINE__) ); + goto exit; + } + + for (i = 0; i < blocks_count && image_size > 0; i++) + { + CHECK_RETURN(whd_get_resource_block(whd_driver, resource, i, (const uint8_t **)&image, &size_out) ); + if (resource == WHD_RESOURCE_WLAN_FIRMWARE) + { +#ifdef BLHS_SUPPORT + trx_header_t *trx; + if (i == 0) + { +#ifndef DM_43022C1 + trx = (trx_header_t *)&image[0]; +#else +#ifndef WLAN_MFG_FIRMWARE + trx = (trx_header_t *)&wifi_firmware_image_data; +#else + trx = (trx_header_t *)&wifi_mfg_firmware_image_data; +#endif /* WLAN_MFG_FIRMWARE */ +#endif /* DM_43022C1 */ + + if (trx->magic == TRX_MAGIC) + { + +#ifdef DM_43022C1 + /* For 43022DM, Reading the trx header and writing at 512KB area */ + whd_bus_transfer_backplane_bytes(whd_driver, BUS_WRITE, TRX_HDR_START_ADDR, sizeof(*trx), (uint8_t*)trx); +#else + image_size = trx->len; + address -= sizeof(*trx); +#endif /* DM_43022C1 */ + +#ifdef WPRINT_ENABLE_WHD_DEBUG + pre_addr = address; +#endif + } + else + { + result = WHD_BADARG; + WPRINT_WHD_ERROR( ("%s: TRX header mismatch\n", __FUNCTION__) ); + goto exit; + } + } +#endif + if (size_out > image_size) + { + size_out = image_size; + image_size = 0; + } + else + { + image_size -= size_out; + } + if (reset_instr == 0) + { + /* Copy the starting address of the firmware into a global variable */ + reset_instr = *( (uint32_t *)(&image[0]) ); + } + } + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_WRITE, address, size_out, &image[0]); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Failed to write firmware image\n", __FUNCTION__) ); + goto exit; + } + address += size_out; + } +#ifdef WPRINT_ENABLE_WHD_DEBUG + whd_bus_sdio_verify_resource(whd_driver, resource, direct_resource, pre_addr, image_size); +#endif + /* Below part of the code is applicable to arm_CR4 type chips only + * The CR4 chips by default firmware is not loaded at 0. So we need + * load the first 32 bytes with the offset of the firmware load address + * which is been copied before during the firmware download + */ +#ifndef BLHS_SUPPORT + if ( (address != 0) && (reset_instr != 0) ) + { + /* write address 0 with reset instruction */ + result = whd_bus_write_backplane_value(whd_driver, 0, sizeof(reset_instr), reset_instr); + + if (result == WHD_SUCCESS) + { + uint32_t tmp; + + /* verify reset instruction value */ + result = whd_bus_read_backplane_value(whd_driver, 0, sizeof(tmp), (uint8_t *)&tmp); + + if ( (result == WHD_SUCCESS) && (tmp != reset_instr) ) + { + WPRINT_WHD_ERROR( ("%s: Failed to write 0x%08" PRIx32 " to addr 0\n", __FUNCTION__, reset_instr) ); + WPRINT_WHD_ERROR( ("%s: contents of addr 0 is 0x%08" PRIx32 "\n", __FUNCTION__, tmp) ); + return WHD_WLAN_SDIO_ERROR; + } + } + } +#endif +exit: return result; } static whd_result_t whd_bus_sdio_write_wifi_nvram_image(whd_driver_t whd_driver) { - uint32_t img_base; - uint32_t img_end; - uint32_t image_size; + uint32_t img_base; + uint32_t img_end; + uint32_t image_size; - /* Get the size of the variable image */ - CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_NVRAM, &image_size)); +#if defined(BLHS_SUPPORT) && defined(DM_43022C1) + CHECK_RETURN(whd_bus_common_blhs(whd_driver, PREP_NVRAM_DOWNLOAD) ); +#endif /* defined(BLHS_SUPPORT) && defined(DM_43022C1) */ - /* Round up the size of the image */ - image_size = ROUND_UP(image_size, 4); + /* Get the size of the variable image */ + CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_NVRAM, &image_size) ); - /* Write image */ - img_end = GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; - img_base = (img_end - image_size); - img_base += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + /* Round up the size of the image */ + image_size = ROUND_UP(image_size, NVM_IMAGE_SIZE_ALIGNMENT); - CHECK_RETURN(whd_bus_sdio_download_resource(whd_driver, WHD_RESOURCE_WLAN_NVRAM, WHD_FALSE, img_base, image_size)); + /* Write image */ - /* Write the variable image size at the end */ - image_size = (~(image_size / 4) << 16) | (image_size / 4); +#ifndef DM_43022C1 + img_end = GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; +#else + /* 43022DM - NVRAM is downloaded at 512KB region, + later will be moved to RAM END region by Bootloader */ + img_end = GET_C_VAR(whd_driver, NVRAM_DNLD_ADDR) - 4; +#endif + + img_base = (img_end - image_size); + img_base += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + + CHECK_RETURN(whd_bus_sdio_download_resource(whd_driver, WHD_RESOURCE_WLAN_NVRAM, WHD_FALSE, img_base, image_size) ); + + /* Write the variable image size at the end */ + image_size = (~(image_size / 4) << 16) | (image_size / 4); + + img_end += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)img_end, 4, image_size) ); - img_end += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); +#ifdef BLHS_SUPPORT + CHECK_RETURN(whd_bus_common_blhs(whd_driver, POST_NVRAM_DOWNLOAD) ); +#endif /* BLHS_SUPPORT */ - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)img_end, 4, image_size)); - return WHD_SUCCESS; + return WHD_SUCCESS; } /* @@ -1546,61 +2150,122 @@ static whd_result_t whd_bus_sdio_write_wifi_nvram_image(whd_driver_t whd_driver) */ whd_result_t whd_bus_sdio_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *curbase) { - whd_result_t result = WHD_BUS_WRITE_REGISTER_ERROR; - uint32_t base = addr & ((uint32_t)~BACKPLANE_ADDRESS_MASK); - const uint32_t upper_32bit_mask = 0xFF000000; - const uint32_t upper_middle_32bit_mask = 0x00FF0000; - const uint32_t lower_middle_32bit_mask = 0x0000FF00; - - if (base == *curbase) { - return WHD_SUCCESS; - } - if ((base & upper_32bit_mask) != (*curbase & upper_32bit_mask)) { - if (WHD_SUCCESS != - (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_HIGH, - (uint8_t)1, (base >> 24)))) { - WPRINT_WHD_ERROR(("Failed to write register value to the bus, %s failed at %d \n", __func__, - __LINE__)); - return result; - } - /* clear old */ - *curbase &= ~upper_32bit_mask; - /* set new */ - *curbase |= (base & upper_32bit_mask); - } - - if ((base & upper_middle_32bit_mask) != - (*curbase & upper_middle_32bit_mask)) { - if (WHD_SUCCESS != - (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_MID, - (uint8_t)1, (base >> 16)))) { - WPRINT_WHD_ERROR(("Failed to write register value to the bus, %s failed at %d \n", __func__, - __LINE__)); - return result; - } - /* clear old */ - *curbase &= ~upper_middle_32bit_mask; - /* set new */ - *curbase |= (base & upper_middle_32bit_mask); - } - - if ((base & lower_middle_32bit_mask) != - (*curbase & lower_middle_32bit_mask)) { - if (WHD_SUCCESS != - (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_LOW, - (uint8_t)1, (base >> 8)))) { - WPRINT_WHD_ERROR(("Failed to write register value to the bus, %s failed at %d \n", __func__, - __LINE__)); - return result; - } - - /* clear old */ - *curbase &= ~lower_middle_32bit_mask; - /* set new */ - *curbase |= (base & lower_middle_32bit_mask); - } - - return WHD_SUCCESS; + whd_result_t result = WHD_BUS_WRITE_REGISTER_ERROR; + uint32_t base = addr & ( (uint32_t) ~BACKPLANE_ADDRESS_MASK ); + const uint32_t upper_32bit_mask = 0xFF000000; + const uint32_t upper_middle_32bit_mask = 0x00FF0000; + const uint32_t lower_middle_32bit_mask = 0x0000FF00; + + if (base == *curbase) + { + return WHD_SUCCESS; + } + if ( (base & upper_32bit_mask) != (*curbase & upper_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_HIGH, + (uint8_t)1, (base >> 24) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + /* clear old */ + *curbase &= ~upper_32bit_mask; + /* set new */ + *curbase |= (base & upper_32bit_mask); + } + + if ( (base & upper_middle_32bit_mask) != + (*curbase & upper_middle_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_MID, + (uint8_t)1, (base >> 16) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + /* clear old */ + *curbase &= ~upper_middle_32bit_mask; + /* set new */ + *curbase |= (base & upper_middle_32bit_mask); + } + + if ( (base & lower_middle_32bit_mask) != + (*curbase & lower_middle_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_LOW, + (uint8_t)1, (base >> 8) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + + /* clear old */ + *curbase &= ~lower_middle_32bit_mask; + /* set new */ + *curbase |= (base & lower_middle_32bit_mask); + } + + return WHD_SUCCESS; +} + +whd_result_t whd_wlan_reset_sdio(whd_driver_t whd_driver) +{ + + CHECK_DRIVER_NULL(whd_driver); + +#ifdef BLHS_SUPPORT + uint8_t byte_data = 0; + uint8_t result = -1; + /* Host to Dongle Registers are initialized to zero */ + CHECK_RETURN(whd_bus_sdio_blhs_write_h2d(whd_driver, SDIO_BLHS_H2D_BL_INIT) ); + + if (whd_driver->chip_info.chipid_in_sdiocore == 1) + { + /* Option1 - Configure registers to trigger WLAN reset on "SDIO Soft Reset (Func0 RES bit)", + and set RES bit to trigger SDIO as well as WLAN reset (instead of using PMU/CC Watchdog register) */ + CHECK_RETURN(whd_bus_read_register_value (whd_driver, BUS_FUNCTION, SDIOD_CCCR_BRCM_CARDCTL, (uint8_t)1, + &byte_data) ); + + byte_data |= SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT; + + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_BRCM_CARDCTL, (uint8_t)1, + byte_data) ); + /* Option2 - To trigger only WLAN Reset the corresponding new bit in rev 31 */ + //CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOABORT, (uint8_t)1, + // IO_ABORT_RESET_ALL )); + return WHD_SUCCESS; + } + else + { + /* using PMU Watchdog register reset */ + uint32_t watchdog_reset = 0xFFFF; + + result = + whd_bus_write_backplane_value(whd_driver, (uint32_t)PMU_WATCHDOG( + whd_driver), (uint8_t)sizeof(watchdog_reset), + (uint8_t)watchdog_reset); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error: pmuwatchdog reset failed, result=%d \n", result) ); + return WHD_FALSE; + } + else + { + WPRINT_WHD_INFO( ("pmuwatchdog reset done\n") ); + return WHD_SUCCESS; + } + } +#else + WPRINT_WHD_INFO( ("Wifi Driver Deinit not implemented , %s failed at %d \n", __func__, + __LINE__) ); + return WHD_FALSE; +#endif } #endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.h b/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.h index 8a7de2a6..61bd89b1 100644 --- a/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.h +++ b/wi-fi/whd/bus_protocols/whd_bus_sdio_protocol.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,24 +28,18 @@ extern "C" { /****************************************************** * Macros ******************************************************/ -#define BIT_MASK(x) ((1 << x) - 1) +#define BIT_MASK(x) ( (1 << x) - 1 ) -#define WHD_BUS_HEADER_SIZE (0) +#define WHD_BUS_HEADER_SIZE (0) -#define WHD_BUS_SDIO_MAX_BACKPLANE_TRANSFER_SIZE (1536) -#define WHD_BUS_SDIO_BACKPLANE_READ_PADD_SIZE (0) +#define WHD_BUS_SDIO_MAX_BACKPLANE_TRANSFER_SIZE (1536) +#define WHD_BUS_SDIO_BACKPLANE_READ_PADD_SIZE (0) #define WHD_BUS_STATS_INCREMENT_VARIABLE(bus_priv, var) \ - do { \ - bus_priv->whd_bus_stats.var++; \ - } while (0) + do { bus_priv->whd_bus_stats.var++; } while (0) #define WHD_BUS_STATS_CONDITIONAL_INCREMENT_VARIABLE(bus_priv, condition, var) \ - do { \ - if (condition) { \ - bus_priv->whd_bus_stats.var++; \ - } \ - } while (0) + do { if (condition){ bus_priv->whd_bus_stats.var++; }} while (0) /****************************************************** * Structures @@ -53,114 +47,109 @@ extern "C" { #pragma pack(1) typedef struct { - unsigned char stuff_bits; - unsigned int ocr : 24; + unsigned char stuff_bits; + unsigned int ocr : 24; } sdio_cmd5_argument_t; typedef struct { - unsigned int _unique2 : 9; /* 0-8 */ - unsigned int register_address : 17; /* 9-25 */ - unsigned int _unique : 2; /* 26-27 */ - unsigned int function_number : 3; /* 28-30 */ - unsigned int rw_flag : 1; /* 31 */ + unsigned int _unique2 : 9; /* 0-8 */ + unsigned int register_address : 17; /* 9-25 */ + unsigned int _unique : 2; /* 26-27 */ + unsigned int function_number : 3; /* 28-30 */ + unsigned int rw_flag : 1; /* 31 */ } sdio_cmd5x_argument_t; typedef struct { - uint8_t write_data; /* 0 - 7 */ - unsigned int _stuff2 : 1; /* 8 */ - unsigned int register_address : 17; /* 9-25 */ - unsigned int _stuff : 1; /* 26 */ - unsigned int raw_flag : 1; /* 27 */ - unsigned int function_number : 3; /* 28-30 */ - unsigned int rw_flag : 1; /* 31 */ + uint8_t write_data; /* 0 - 7 */ + unsigned int _stuff2 : 1; /* 8 */ + unsigned int register_address : 17; /* 9-25 */ + unsigned int _stuff : 1; /* 26 */ + unsigned int raw_flag : 1; /* 27 */ + unsigned int function_number : 3; /* 28-30 */ + unsigned int rw_flag : 1; /* 31 */ } whd_bus_sdio_cmd52_argument_t; typedef struct { - unsigned int count : 9; /* 0-8 */ - unsigned int register_address : 17; /* 9-25 */ - unsigned int op_code : 1; /* 26 */ - unsigned int block_mode : 1; /* 27 */ - unsigned int function_number : 3; /* 28-30 */ - unsigned int rw_flag : 1; /* 31 */ + unsigned int count : 9; /* 0-8 */ + unsigned int register_address : 17; /* 9-25 */ + unsigned int op_code : 1; /* 26 */ + unsigned int block_mode : 1; /* 27 */ + unsigned int function_number : 3; /* 28-30 */ + unsigned int rw_flag : 1; /* 31 */ } whd_bus_sdio_cmd53_argument_t; -typedef union { - uint32_t value; - sdio_cmd5_argument_t cmd5; - sdio_cmd5x_argument_t cmd5x; - whd_bus_sdio_cmd52_argument_t cmd52; - whd_bus_sdio_cmd53_argument_t cmd53; +typedef union +{ + uint32_t value; + sdio_cmd5_argument_t cmd5; + sdio_cmd5x_argument_t cmd5x; + whd_bus_sdio_cmd52_argument_t cmd52; + whd_bus_sdio_cmd53_argument_t cmd53; } sdio_cmd_argument_t; typedef struct { - unsigned int ocr : 24; /* 0-23 */ - unsigned int stuff_bits : 3; /* 24-26 */ - unsigned int memory_present : 1; /* 27 */ - unsigned int function_count : 3; /* 28-30 */ - unsigned int c : 1; /* 31 */ + unsigned int ocr : 24; /* 0-23 */ + unsigned int stuff_bits : 3; /* 24-26 */ + unsigned int memory_present : 1; /* 27 */ + unsigned int function_count : 3; /* 28-30 */ + unsigned int c : 1; /* 31 */ } sdio_response4_t; typedef struct { - uint8_t data; /* 0-7 */ - uint8_t response_flags; /* 8-15 */ - uint16_t stuff; /* 16-31 */ + uint8_t data; /* 0-7 */ + uint8_t response_flags; /* 8-15 */ + uint16_t stuff; /* 16-31 */ } sdio_response5_t; typedef struct { - uint16_t card_status; /* 0-15 */ - uint16_t rca; /* 16-31 */ + uint16_t card_status; /* 0-15 */ + uint16_t rca; /* 16-31 */ } sdio_response6_t; -typedef union { - uint32_t value; - sdio_response4_t r4; - sdio_response5_t r5; - sdio_response6_t r6; +typedef union +{ + uint32_t value; + sdio_response4_t r4; + sdio_response5_t r5; + sdio_response6_t r6; } sdio_response_t; -typedef enum { - SDIO_BLOCK_MODE = (0 << 2), /* These are STM32 implementation specific */ - SDIO_BYTE_MODE = (1 << 2) /* These are STM32 implementation specific */ +typedef enum +{ + SDIO_BLOCK_MODE = (0 << 2), /* These are STM32 implementation specific */ + SDIO_BYTE_MODE = (1 << 2) /* These are STM32 implementation specific */ } sdio_transfer_mode_t; -typedef enum { - SDIO_1B_BLOCK = 1, - SDIO_2B_BLOCK = 2, - SDIO_4B_BLOCK = 4, - SDIO_8B_BLOCK = 8, - SDIO_16B_BLOCK = 16, - SDIO_32B_BLOCK = 32, - SDIO_64B_BLOCK = 64, - SDIO_128B_BLOCK = 128, - SDIO_256B_BLOCK = 256, - SDIO_512B_BLOCK = 512, - SDIO_1024B_BLOCK = 1024, - SDIO_2048B_BLOCK = 2048 +typedef enum +{ + SDIO_1B_BLOCK = 1, SDIO_2B_BLOCK = 2, SDIO_4B_BLOCK = 4, SDIO_8B_BLOCK = 8, SDIO_16B_BLOCK = 16, + SDIO_32B_BLOCK = 32, SDIO_64B_BLOCK = 64, SDIO_128B_BLOCK = 128, SDIO_256B_BLOCK = 256, SDIO_512B_BLOCK = 512, + SDIO_1024B_BLOCK = 1024, SDIO_2048B_BLOCK = 2048 } sdio_block_size_t; -typedef enum { - RESPONSE_NEEDED, - NO_RESPONSE +typedef enum +{ + RESPONSE_NEEDED, NO_RESPONSE } sdio_response_needed_t; typedef struct { - uint32_t cmd52; /* Number of cmd52 reads/writes issued */ - uint32_t cmd53_read; /* Number of cmd53 reads */ - uint32_t cmd53_write; /* Number of cmd53 writes */ - uint32_t cmd52_fail; /* Number of cmd52 read/write fails */ - uint32_t cmd53_read_fail; /* Number of cmd53 read fails */ - uint32_t cmd53_write_fail; /* Number of cmd53 write fails */ - uint32_t oob_intrs; /* Number of OOB interrupts generated by wlan chip */ - uint32_t sdio_intrs; /* Number of SDIO interrupts generated by wlan chip */ - uint32_t error_intrs; /* Number of SDIO error interrupts generated by wlan chip */ - uint32_t read_aborts; /* Number of times read aborts are called */ + uint32_t cmd52; /* Number of cmd52 reads/writes issued */ + uint32_t cmd53_read; /* Number of cmd53 reads */ + uint32_t cmd53_write; /* Number of cmd53 writes */ + uint32_t cmd52_fail; /* Number of cmd52 read/write fails */ + uint32_t cmd53_read_fail; /* Number of cmd53 read fails */ + uint32_t cmd53_write_fail; /* Number of cmd53 write fails */ + uint32_t oob_intrs; /* Number of OOB interrupts generated by wlan chip */ + uint32_t sdio_intrs; /* Number of SDIO interrupts generated by wlan chip */ + uint32_t error_intrs; /* Number of SDIO error interrupts generated by wlan chip */ + uint32_t read_aborts; /* Number of times read aborts are called */ } whd_bus_stats_t; #pragma pack() @@ -174,51 +163,51 @@ extern whd_result_t whd_bus_sdio_deinit(whd_driver_t whd_driver); /* Device register access functions */ extern whd_result_t whd_bus_sdio_write_backplane_value(whd_driver_t whd_driver, uint32_t address, - uint8_t register_length, uint32_t value); + uint8_t register_length, uint32_t value); extern whd_result_t whd_bus_sdio_read_backplane_value(whd_driver_t whd_driver, uint32_t address, - uint8_t register_length, uint8_t *value); + uint8_t register_length, uint8_t *value); extern whd_result_t whd_bus_sdio_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, - uint32_t address, uint8_t value_length, uint32_t value); + uint32_t address, uint8_t value_length, uint32_t value); extern whd_result_t whd_bus_sdio_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, - uint32_t address, uint8_t value_length, uint8_t *value); + uint32_t address, uint8_t value_length, uint8_t *value); /* Device data transfer functions */ extern whd_result_t whd_bus_sdio_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer); extern whd_result_t whd_bus_sdio_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, - whd_bus_function_t function, uint32_t address, uint16_t size, - whd_transfer_bytes_packet_t *data); + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *data); extern whd_result_t whd_bus_sdio_transfer_backplane_bytes(whd_driver_t whd_driver, - whd_bus_transfer_direction_t direction, uint32_t address, - uint32_t size, uint8_t *data); + whd_bus_transfer_direction_t direction, uint32_t address, + uint32_t size, uint8_t *data); /* Frame transfer function */ extern whd_result_t whd_bus_sdio_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer); extern whd_result_t whd_bus_sdio_poke_wlan(whd_driver_t whd_driver); -extern uint32_t whd_bus_sdio_packet_available_to_read(whd_driver_t whd_driver); +extern uint32_t whd_bus_sdio_packet_available_to_read(whd_driver_t whd_driver); extern whd_result_t whd_bus_sdio_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus); extern whd_result_t whd_bus_sdio_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *curbase); +extern whd_result_t whd_wlan_reset_sdio(whd_driver_t whd_driver); + extern void whd_delayed_bus_release_schedule_update(whd_driver_t whd_driver, whd_bool_t is_scheduled); #define DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, schedule) \ - do { \ - whd_delayed_bus_release_schedule_update(whd_driver, schedule); \ - } while (0) + do { whd_delayed_bus_release_schedule_update(whd_driver, schedule); } while (0) extern whd_bool_t whd_bus_sdio_wake_interrupt_present(whd_driver_t whd_driver); extern whd_result_t whd_bus_sdio_wakeup(whd_driver_t whd_driver); extern whd_result_t whd_bus_sdio_sleep(whd_driver_t whd_driver); -extern void whd_bus_sdio_init_stats(whd_driver_t whd_driver); +extern void whd_bus_sdio_init_stats(whd_driver_t whd_driver); extern whd_result_t whd_bus_sdio_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print); extern whd_result_t whd_bus_sdio_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware); uint8_t whd_bus_sdio_backplane_read_padd_size(whd_driver_t whd_driver); -extern whd_result_t whd_bus_sdio_wait_for_wlan_event(whd_driver_t whd_driver, - cy_semaphore_t *transceive_semaphore); +extern whd_result_t whd_bus_sdio_wait_for_wlan_event(whd_driver_t whd_driver, + cy_semaphore_t *transceive_semaphore); extern whd_bool_t whd_bus_sdio_use_status_report_scheme(whd_driver_t whd_driver); extern uint32_t whd_bus_sdio_get_max_transfer_size(whd_driver_t whd_driver); /****************************************************** diff --git a/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.c b/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.c new file mode 100644 index 00000000..cd3fcf6a --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.c @@ -0,0 +1,1378 @@ +/* + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * Broadcom WLAN SPI Protocol interface + * + * Implements the WHD Bus Protocol Interface for SPI + * Provides functions for initialising, de-intitialising 802.11 device, + * sending/receiving raw packets etc + */ + +#include /* For memcpy */ + +#include "cybsp.h" +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SPI_INTERFACE) + + +#include "cy_result.h" +#include "cyabs_rtos.h" +#include "cyhal_gpio.h" + +#include "whd_thread.h" +#include "whd_chip.h" +#include "whd_sdpcm.h" +#include "whd_chip_constants.h" +#include "whd_int.h" +#include "whd_bus_spi_protocol.h" +#include "whd_bus_common.h" +#include "whd_chip_reg.h" +#include "whd_debug.h" +#include "whd_bus.h" +#include "whd_spi.h" +#include "whd_sdio.h" +#include "whd_buffer_api.h" +#include "whd_debug.h" +#include "whd_types_int.h" +#include "whd_resource_if.h" +#include "whd_proto.h" +#include "whd_utils.h" + +/****************************************************** +* Constants +******************************************************/ + +#define F2_READY_TIMEOUT_MS (1000) +#define F2_READY_TIMEOUT_LOOPS (1000) +#define F1_READY_TIMEOUT_LOOPS (1000) +#define FEADBEAD_TIMEOUT_MS (500) +#define ALP_AVAIL_TIMEOUT_MS (100) + +/* function 1 OCP space */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ + +#define HT_AVAIL_TIMEOUT_MS (1000) + +/* Taken from FALCON_5_90_195_26 dhd/sys/dhd_sdio.c. For 43362, MUST be >= 8 and word-aligned otherwise dongle fw crashes */ +#define SPI_F2_WATERMARK (32) + +#define GSPI_PACKET_AVAILABLE (1 << 8) +#define GSPI_UNDERFLOW (1 << 1) + +#define SWAP32_16BIT_PARTS(val) ( (uint32_t)( ( ( (uint32_t)(val) ) >> 16 ) + \ + ( ( ( (uint32_t)(val) ) & 0xffff ) << 16 ) ) ) + +#define WHD_BUS_GSPI_PACKET_OVERHEAD (sizeof(whd_buffer_header_t) ) + +#define MAX_GSPI_TRANSFER_LEN 2048 + +#define H32TO16LE(x) ( ( uint32_t )( ( ( ( uint32_t )(x) & ( uint32_t )0x000000ffU ) << 8 ) | \ + ( ( ( uint32_t )(x) & ( uint32_t )0x0000ff00U ) >> 8 ) | \ + ( ( ( uint32_t )(x) & ( uint32_t )0x00ff0000U ) << 8 ) | \ + ( ( ( uint32_t )(x) & ( uint32_t )0xff000000U ) >> 8 ) ) ) + +#define WHD_THREAD_POLL_TIMEOUT (CY_RTOS_NEVER_TIMEOUT) + +#define WHD_THREAD_POKE_TIMEOUT (100) + +#define HOSTINTMASK (I_HMB_SW_MASK) + +#define BT_POLLING_TIME (100) +#define ALIGNED_ADDRESS ( (uint32_t)0x3 ) +typedef enum +{ + GSPI_INCREMENT_ADDRESS = 1, GSPI_FIXED_ADDRESS = 0 +} gspi_transfer_access_t; + +/****************************************************** +* Structures +******************************************************/ + +#pragma pack(1) + +typedef struct +{ + whd_bus_gspi_header_t header; + uint8_t response_delay[4]; +} gspi_backplane_f1_read_header_t; + +#pragma pack() + +typedef struct +{ + gspi_backplane_f1_read_header_t gspi_header; + uint32_t data[1]; +} gspi_backplane_f1_read_packet_t; + +/****************************************************** +* Static variables +******************************************************/ + +static const uint8_t whd_bus_gspi_command_mapping[] = { 0, 1 }; + +/****************************************************** +* Structures +******************************************************/ +struct whd_bus_priv +{ + whd_spi_config_t spi_config; + cyhal_spi_t *spi_obj; +}; + +/****************************************************** +* Variables +******************************************************/ + +/****************************************************** +* Static Function Declarations +******************************************************/ + +static whd_result_t whd_spi_download_firmware(whd_driver_t whd_driver); +static whd_result_t whd_bus_spi_transfer_buffer(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, whd_buffer_t buffer); +static whd_result_t whd_bus_spi_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage); +static whd_result_t whd_bus_spi_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, uint32_t image_size); +static whd_result_t whd_bus_spi_write_wifi_nvram_image(whd_driver_t whd_driver); +static whd_result_t whd_bus_spi_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *curbase); +/****************************************************** +* Global Function definitions +******************************************************/ +uint32_t whd_bus_spi_bt_packet_available_to_read(whd_driver_t whd_driver); + +whd_result_t whd_bus_spi_attach(whd_driver_t whd_driver, whd_spi_config_t *whd_spi_config, cyhal_spi_t *spi_obj) +{ + struct whd_bus_info *whd_bus_info; + + if (!whd_driver || !whd_spi_config) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + if (whd_spi_config->oob_config.host_oob_pin == CYHAL_NC_PIN_VALUE) + { + WPRINT_WHD_ERROR( ("OOB interrupt pin argument must be provided in %s\n", __FUNCTION__) ); + return WHD_BADARG; + } + + whd_bus_info = (whd_bus_info_t *)whd_mem_malloc(sizeof(whd_bus_info_t) ); + + if (whd_bus_info == NULL) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bus_info in %s\n", __FUNCTION__) ); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_bus_info, 0, sizeof(whd_bus_info_t) ); + + whd_driver->bus_if = whd_bus_info; + + whd_driver->bus_priv = (struct whd_bus_priv *)whd_mem_malloc(sizeof(struct whd_bus_priv) ); + + if (whd_driver->bus_priv == NULL) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for whd_bus_priv in %s\n", __FUNCTION__) ); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_driver->bus_priv, 0, sizeof(struct whd_bus_priv) ); + + /* Pass the SPI object to bus private spi_obj pointer */ + whd_driver->bus_priv->spi_obj = spi_obj; + whd_driver->bus_priv->spi_config = *whd_spi_config; + + whd_driver->proto_type = WHD_PROTO_BCDC; + + whd_bus_info->whd_bus_init_fptr = whd_bus_spi_init; + whd_bus_info->whd_bus_deinit_fptr = whd_bus_spi_deinit; + + whd_bus_info->whd_bus_write_backplane_value_fptr = whd_bus_spi_write_backplane_value; + whd_bus_info->whd_bus_read_backplane_value_fptr = whd_bus_spi_read_backplane_value; + whd_bus_info->whd_bus_write_register_value_fptr = whd_bus_spi_write_register_value; + whd_bus_info->whd_bus_read_register_value_fptr = whd_bus_spi_read_register_value; + + whd_bus_info->whd_bus_send_buffer_fptr = whd_bus_spi_send_buffer; + whd_bus_info->whd_bus_transfer_bytes_fptr = whd_bus_spi_transfer_bytes; + + whd_bus_info->whd_bus_read_frame_fptr = whd_bus_spi_read_frame; + + whd_bus_info->whd_bus_packet_available_to_read_fptr = whd_bus_spi_packet_available_to_read; + whd_bus_info->whd_bus_poke_wlan_fptr = whd_bus_spi_poke_wlan; + whd_bus_info->whd_bus_wait_for_wlan_event_fptr = whd_bus_spi_wait_for_wlan_event; + + whd_bus_info->whd_bus_ack_interrupt_fptr = whd_bus_spi_ack_interrupt; + whd_bus_info->whd_bus_wake_interrupt_present_fptr = whd_bus_spi_wake_interrupt_present; + + whd_bus_info->whd_bus_wakeup_fptr = whd_bus_spi_wakeup; + whd_bus_info->whd_bus_sleep_fptr = whd_bus_spi_sleep; + + whd_bus_info->whd_bus_backplane_read_padd_size_fptr = whd_bus_spi_backplane_read_padd_size; + whd_bus_info->whd_bus_use_status_report_scheme_fptr = whd_bus_spi_use_status_report_scheme; + + whd_bus_info->whd_bus_get_max_transfer_size_fptr = whd_bus_spi_get_max_transfer_size; + + whd_bus_info->whd_bus_init_stats_fptr = whd_bus_spi_init_stats; + whd_bus_info->whd_bus_print_stats_fptr = whd_bus_spi_print_stats; + whd_bus_info->whd_bus_reinit_stats_fptr = whd_bus_spi_reinit_stats; + whd_bus_info->whd_bus_irq_register_fptr = whd_bus_spi_irq_register; + whd_bus_info->whd_bus_irq_enable_fptr = whd_bus_spi_irq_enable; + whd_bus_info->whd_bus_blhs_fptr = whd_bus_spi_blhs; + whd_bus_info->whd_bus_download_resource_fptr = whd_bus_spi_download_resource; + whd_bus_info->whd_bus_set_backplane_window_fptr = whd_bus_spi_set_backplane_window; + + return WHD_SUCCESS; +} + +void whd_bus_spi_detach(whd_driver_t whd_driver) +{ + if (whd_driver->bus_if != NULL) + { + whd_mem_free(whd_driver->bus_if); + whd_driver->bus_if = NULL; + } + if (whd_driver->bus_priv != NULL) + { + whd_mem_free(whd_driver->bus_priv); + whd_driver->bus_priv = NULL; + } +} + +whd_result_t whd_bus_spi_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer) +{ + whd_result_t result = whd_bus_spi_transfer_buffer(whd_driver, BUS_WRITE, WLAN_FUNCTION, 0, buffer); + CHECK_RETURN(whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX) ); + if (result == WHD_SUCCESS) + { + DELAYED_BUS_RELEASE_SCHEDULE (whd_driver, WHD_TRUE); + } + CHECK_RETURN(result); + + return WHD_SUCCESS; +} + +/* + * Perform a transfer on the gSPI bus + * Prerequisites: length < MAX_GSPI_TRANSFER_LEN + */ +static whd_result_t whd_bus_spi_transfer_buffer(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, whd_buffer_t buffer) +{ + uint32_t *temp, addr; + whd_result_t result; + uint16_t newsize; + whd_buffer_header_t *header = (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + whd_buffer_header_t *aligned_header = (whd_buffer_header_t *)whd_driver->aligned_addr; + whd_bus_gspi_header_t *gspi_header; + size_t transfer_size; + + uint16_t size = ( uint16_t )(whd_buffer_get_current_piece_size(whd_driver, buffer) - sizeof(whd_buffer_header_t) ); + CHECK_PACKET_NULL(header, WHD_NO_REGISTER_FUNCTION_POINTER); + /* Round size up to 32-bit alignment */ + newsize = (uint16_t)ROUND_UP(size, 4); + + /* Send the data */ + if (direction == BUS_WRITE) + { + /* Wait for FIFO to be ready to accept data */ + if (function == WLAN_FUNCTION) + { + uint32_t whd_bus_gspi_status; + uint32_t loop_count = 0; + while ( ( (result = + whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_STATUS_REGISTER, (uint8_t)4, + (uint8_t *)&whd_bus_gspi_status) ) == WHD_SUCCESS ) && + ( (whd_bus_gspi_status & (1 << 5) ) == 0 ) && + (loop_count < ( uint32_t )F2_READY_TIMEOUT_LOOPS) ) + { + loop_count++; + } + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error reading register value, %s failed at %d \n", __func__, __LINE__) ); + return result; + } + if (loop_count >= ( uint32_t )F2_READY_TIMEOUT_LOOPS) + { + WPRINT_WHD_ERROR( ("Timeout waiting for data FIFO to be ready\n") ); + return WHD_TIMEOUT; + } + } + + } + + transfer_size = (size_t)(newsize + sizeof(whd_bus_gspi_header_t) ); + gspi_header = + (whd_bus_gspi_header_t *)( (char *)header->bus_header + MAX_BUS_HEADER_SIZE - + sizeof(whd_bus_gspi_header_t) ); + /* Form the gSPI header */ + addr = (uint32_t )header; + /* check 4byte alignment */ + if ( (addr & ALIGNED_ADDRESS) ) + { + if (aligned_header) + { + /* use memcpy to get aligned event message */ + memcpy(aligned_header, header, sizeof(*aligned_header) + size); + gspi_header = + (whd_bus_gspi_header_t *)( (char *)aligned_header->bus_header + MAX_BUS_HEADER_SIZE - + sizeof(whd_bus_gspi_header_t) ); + } + } + /* Form the gSPI header */ + *gspi_header = + ( whd_bus_gspi_header_t )( ( uint32_t )( (whd_bus_gspi_command_mapping[(int)direction] & 0x1) << 31 ) | + ( uint32_t )( (GSPI_INCREMENT_ADDRESS & 0x1) << 30 ) | + ( uint32_t )( (function & 0x3) << 28 ) | + ( uint32_t )( (address & 0x1FFFF) << 11 ) | ( uint32_t )( (size & 0x7FF) << 0 ) ); + + /* Reshuffle the bits if we're not in 32 bit mode */ + if (whd_driver->bus_gspi_32bit == WHD_FALSE) + { + /* Note: This typecast should always be valid if the buffer containing the GSpi packet has been correctly declared as 32-bit aligned */ + temp = (uint32_t *)gspi_header; + *temp = H32TO16LE(*temp); + } + + /* Send the data */ + if (direction == BUS_READ) + { + result = cyhal_spi_transfer(whd_driver->bus_priv->spi_obj, NULL, + sizeof(whd_bus_gspi_header_t), + (uint8_t *)gspi_header, + transfer_size, 0); + + } + else + { + result = cyhal_spi_transfer(whd_driver->bus_priv->spi_obj, (uint8_t *)gspi_header, transfer_size, NULL, + 0, 0); + } + + return result; +} + +whd_result_t whd_bus_spi_poke_wlan(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + +whd_result_t whd_bus_spi_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus) +{ + return whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SPI_INTERRUPT_REGISTER, (uint8_t)2, intstatus); +} + +uint32_t whd_bus_spi_bt_packet_available_to_read(whd_driver_t whd_driver) +{ + whd_bt_dev_t btdev = whd_driver->bt_dev; + uint32_t int_status = 0; + + if (btdev && btdev->bt_int_cb) + { + if (whd_bus_spi_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (uint8_t *)&int_status) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + int_status = 0; + } + + if ( (I_HMB_FC_CHANGE & int_status) != 0 ) + { + + if (whd_bus_spi_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + int_status & I_HMB_FC_CHANGE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error write interrupt status\n", __FUNCTION__) ); + int_status = 0; + } + btdev->bt_int_cb(btdev->bt_data); + } + } + + return 0; +} + +uint32_t whd_bus_spi_packet_available_to_read(whd_driver_t whd_driver) +{ + uint16_t interrupt_register; + uint32_t int_status = 0; + + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + + whd_bus_spi_bt_packet_available_to_read(whd_driver); + /* Read the interrupt register */ + if (whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_INTERRUPT_REGISTER, (uint8_t)2, + (uint8_t *)&interrupt_register) != WHD_SUCCESS) + { + goto return_with_error; + } + + if ( (interrupt_register & 0x0086) != 0 ) /* This should be 0x87, but occasional "data not available" errors are flagged seemingly for no reason */ + { + /* Error condition detected */ + WPRINT_WHD_DEBUG( ("Bus error condition detected\n") ); + } + /* Read the IntStatus */ + if (whd_bus_spi_read_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + (uint8_t *)&int_status) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + int_status = 0; + goto return_with_error; + } + + if ( (HOSTINTMASK & int_status) != 0 ) + { + if (whd_bus_spi_write_backplane_value(whd_driver, (uint32_t)SDIO_INT_STATUS(whd_driver), (uint8_t)4, + int_status & HOSTINTMASK) != WHD_SUCCESS) + { + int_status = 0; + goto return_with_error; + } + + } + /* Clear interrupt register */ + if (interrupt_register != 0) + { + if (whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_INTERRUPT_REGISTER, (uint8_t)2, + interrupt_register) != WHD_SUCCESS) + { + goto return_with_error; + } + } + + return ( uint32_t )( (interrupt_register) & (F2_PACKET_AVAILABLE) ); + +return_with_error: whd_assert("Error accessing backplane", 0 != 0); + return 0; +} + +whd_result_t whd_bus_spi_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer) +{ + uint32_t whd_bus_gspi_status; + whd_result_t result; + uint32_t whd_gspi_bytes_pending; + + /* Ensure the wlan backplane bus is up */ + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver) ); + + do + { + result = whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_STATUS_REGISTER, (uint8_t)4, + (uint8_t *)&whd_bus_gspi_status); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error reading register value, %s failed at %d \n", __func__, __LINE__) ); + return result; + } + } while (whd_bus_gspi_status == 0xFFFFFFFF); + + if ( (whd_bus_gspi_status & GSPI_PACKET_AVAILABLE) != 0 ) + { + if ( ( ( (whd_bus_gspi_status >> 9) & 0x7FF ) == 0 ) || + ( ( (whd_bus_gspi_status >> 9) & 0x7FF ) > (WHD_LINK_MTU - WHD_BUS_GSPI_PACKET_OVERHEAD) ) || + (whd_bus_gspi_status & GSPI_UNDERFLOW) ) + { + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, SPI_FRAME_CONTROL, 1, + (1 << 0) ) ); + return WHD_NO_PACKET_TO_RECEIVE; + } + } + + whd_gspi_bytes_pending = 0; + + if ( (whd_bus_gspi_status & GSPI_PACKET_AVAILABLE) != 0 ) + { + whd_gspi_bytes_pending = ( (whd_bus_gspi_status >> 9) & 0x7FF ); + } + + if (whd_gspi_bytes_pending == 0) + { + return WHD_NO_PACKET_TO_RECEIVE; + } + + /* Allocate a suitable buffer */ + result = whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_RX, + (uint16_t)(whd_gspi_bytes_pending + WHD_BUS_GSPI_PACKET_OVERHEAD), + (whd_sdpcm_has_tx_packet(whd_driver) ? 0 : WHD_RX_BUF_TIMEOUT) ); + + if (result != WHD_SUCCESS) + { + /* Read out the first 12 bytes to get the bus credit information */ + uint8_t temp_buffer[12 + MAX_BUS_HEADER_SIZE]; + CHECK_RETURN(whd_bus_spi_transfer_bytes(whd_driver, BUS_READ, WLAN_FUNCTION, 0, 12, + (whd_transfer_bytes_packet_t *)temp_buffer) ); + + /* Abort the transfer to force the packet to be dropped */ + if (whd_gspi_bytes_pending > 12) + { + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, SPI_FRAME_CONTROL, 1, + (1 << 0) ) ); + } + + /* Process bus data credit information */ + whd_sdpcm_update_credit(whd_driver, (uint8_t *)(temp_buffer + sizeof(whd_bus_header_t) ) ); + WPRINT_WHD_ERROR( ("Packet buffer allocation failed in %s at %d \n", __func__, __LINE__) ); + return result; + } + + result = whd_bus_spi_transfer_buffer(whd_driver, BUS_READ, WLAN_FUNCTION, 0, *buffer); + if (result != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, *buffer, WHD_NETWORK_RX) ); + WPRINT_WHD_ERROR( ("SPI buffer transfer failed in %s at %d \n", __func__, __LINE__) ); + return result; + } + + DELAYED_BUS_RELEASE_SCHEDULE (whd_driver, WHD_TRUE); + return WHD_SUCCESS; +} + +whd_result_t whd_bus_spi_init(whd_driver_t whd_driver) +{ + uint32_t data = 0; + uint32_t whd_bus_gspi_status; + uint16_t data16 = 0; + uint32_t loop_count; + whd_result_t result; + uint8_t init_data[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint32_t interrupt_polarity = 0; + uint16_t chip_id; + size_t transfer_size = 12; + uint8_t *aligned_addr = NULL; + whd_oob_config_t *config = &whd_driver->bus_priv->spi_config.oob_config; + + whd_driver->bus_gspi_32bit = WHD_FALSE; + + if (config->is_falling_edge == WHD_FALSE) + interrupt_polarity = INTERRUPT_POLARITY_HIGH; + + whd_bus_init_backplane_window(whd_driver); + + whd_bus_gspi_header_t *gspi_header = (whd_bus_gspi_header_t *)init_data; + + /* Due to an chip issue, the first transfer will be corrupted. + * This means a repeated safe read of a known value register is required until + * the correct value is returned - signalling the bus is running. + * This known value register must be accessed using fixed (non-incrementing) address + * mode, hence a custom packet header must be constructed + * Due to the chip issue, the data received could be left shifted by one bit. + */ + loop_count = 0; + do + { + /* Header needs to calculated every time as init_data gets modified in cyhal_spi_transfer() */ + *gspi_header = + ( whd_bus_gspi_header_t )SWAP32_16BIT_PARTS(SWAP32( (uint32_t)( (whd_bus_gspi_command_mapping[(int)BUS_READ] + & 0x1) << 31 ) | + (uint32_t)( (GSPI_FIXED_ADDRESS & 0x1) << 30 ) | + (uint32_t)( (BUS_FUNCTION & 0x3) << 28 ) | + (uint32_t)( (SPI_READ_TEST_REGISTER & 0x1FFFFu) << + 11 ) | + (uint32_t)( (4u /*size*/ & 0x7FFu) << 0 ) ) ); + CHECK_RETURN(cyhal_spi_transfer(whd_driver->bus_priv->spi_obj, NULL, sizeof(whd_bus_gspi_header_t), + init_data, transfer_size, 0) ); + loop_count++; + } while ( (NULL == memchr(&init_data[4], SPI_READ_TEST_REG_LSB, (size_t)8) ) && + (NULL == memchr(&init_data[4], SPI_READ_TEST_REG_LSB_SFT1, (size_t)8) ) && + (NULL == memchr(&init_data[4], SPI_READ_TEST_REG_LSB_SFT2, (size_t)8) ) && + (NULL == memchr(&init_data[4], SPI_READ_TEST_REG_LSB_SFT3, (size_t)8) ) && + (loop_count < ( uint32_t )FEADBEAD_TIMEOUT_MS) && + (cy_rtos_delay_milliseconds( (uint32_t)1 ), (1 == 1) ) ); + + /* Register interrupt handler */ + whd_bus_spi_irq_register(whd_driver); + /* Enable SPI IRQ */ + whd_bus_spi_irq_enable(whd_driver, WHD_TRUE); + + /* Keep/reset defaults for registers 0x0-0x4 except for, 0x0: Change word length to 32bit, + * set endianness, enable wakeup. 0x2: enable interrupt with status. */ +#if defined(IL_BIGENDIAN) + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, (uint8_t)4, + (uint32_t)(WORD_LENGTH_32 | (0 & ENDIAN_BIG) | + (interrupt_polarity & INTERRUPT_POLARITY_HIGH) | WAKE_UP | + (0x4 << (8 * SPI_RESPONSE_DELAY) ) | + ( (0 & STATUS_ENABLE) << (8 * SPI_STATUS_ENABLE) ) | + (INTR_WITH_STATUS << (8 * SPI_STATUS_ENABLE) ) ) ) ); +#else + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, (uint8_t)4, + ( uint32_t )(WORD_LENGTH_32 | ENDIAN_BIG | + (interrupt_polarity & INTERRUPT_POLARITY_HIGH) | + WAKE_UP | (0x4 << (8 * SPI_RESPONSE_DELAY) ) | + ( (0 & STATUS_ENABLE) << (8 * SPI_STATUS_ENABLE) ) | + (INTR_WITH_STATUS << (8 * SPI_STATUS_ENABLE) ) ) ) ); +#endif + whd_driver->bus_gspi_32bit = WHD_TRUE; + CHECK_RETURN(whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, (uint8_t)4, + (uint8_t *)&data) ); + + if (whd_driver->bus_priv->spi_config.is_spi_normal_mode) + { + /* Reset host SPI interface to re-sync */ + /*host_platform_bus_init( );*/ + } + + /* Check feedbead can be read - i.e. the device is alive */ + data = 0; + CHECK_RETURN(whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_READ_TEST_REGISTER, (uint8_t)4, + (uint8_t *)&data) ); + + if (data != SPI_READ_TEST_REGISTER_VALUE) + { + WPRINT_WHD_ERROR( ("Read %x, instead of 0xFEEDBEAD from the WLAN chip\n", (unsigned int)data) ); + return WHD_SPI_ID_READ_FAIL; + } + + /* Make sure error interrupt bits are clear */ + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_INTERRUPT_REGISTER, (uint8_t)1, + ( uint32_t )(DATA_UNAVAILABLE | COMMAND_ERROR | DATA_ERROR | + F1_OVERFLOW) ) ); + + /* Enable a selection of interrupts */ + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_INTERRUPT_ENABLE_REGISTER, (uint8_t)2, + ( uint32_t )(F2_F3_FIFO_RD_UNDERFLOW | F2_F3_FIFO_WR_OVERFLOW | + COMMAND_ERROR | DATA_ERROR | F2_PACKET_AVAILABLE | + F1_OVERFLOW) ) ); + + /* Request ALP */ + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + SBSDIO_ALP_AVAIL_REQ) ); + + /* Wait until ALP is available */ + loop_count = 0; + while ( ( (result = whd_bus_spi_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)2, + (uint8_t *)&data16) ) == WHD_SUCCESS ) && + ( (data16 & SBSDIO_ALP_AVAIL) == 0 ) && + (loop_count < ( uint32_t )ALP_AVAIL_TIMEOUT_MS) ) + { + cy_rtos_delay_milliseconds( (uint32_t)1 ); + loop_count++; + } + if (loop_count >= ( uint32_t )ALP_AVAIL_TIMEOUT_MS) + { + WPRINT_WHD_ERROR( ("ALP Clock timeout\n") ); + return WHD_TIMEOUT; + } + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Can't read SDIO_CHIP_CLOCK_CSR\n") ); + return result; + } + + /* Clear request for ALP */ + CHECK_RETURN(whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + (uint32_t)0) ); + + /* Read the chip id */ + CHECK_RETURN(whd_bus_spi_read_backplane_value(whd_driver, CHIPCOMMON_BASE_ADDRESS, 2, (uint8_t *)&chip_id) ); + whd_chip_set_chip_id(whd_driver, chip_id); + + /* Download the firmware */ + result = whd_spi_download_firmware(whd_driver); + + /* user abort */ + if (result == WHD_UNFINISHED) + { + /* host_platform_reset_wifi (WHD_TRUE); */ + /* host_platform_power_wifi (WHD_FALSE); */ + WPRINT_WHD_ERROR( ("User aborted download of firmware\n") ); + return result; + } + + /* non user abort error */ + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not download firmware\n") ); + return result; + } + /* else, successfully downloaded the firmware; continue with waiting for WIFi to live */ + + /* Wait for F2 to be ready */ + loop_count = 0; + while ( ( (result = whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_STATUS_REGISTER, (uint8_t)4, + (uint8_t *)&whd_bus_gspi_status) ) == WHD_SUCCESS ) && + ( (whd_bus_gspi_status & (1 << 5) ) == 0 ) && + (loop_count < ( uint32_t )F2_READY_TIMEOUT_MS) ) + { + cy_rtos_delay_milliseconds( (uint32_t)1 ); + loop_count++; + } + if (loop_count >= ( uint32_t )F2_READY_TIMEOUT_MS) + { + /* If your system fails here, it could be due to incorrect NVRAM variables. + * Check which 'wifi_nvram_image.h' file your platform is using, and + * check that it matches the WLAN device on your platform, including the + * crystal frequency. + */ + WPRINT_WHD_ERROR( ("Timeout while waiting for function 2 to be ready\n") ); + return WHD_TIMEOUT; + } + if (whd_driver->aligned_addr == NULL) + { + if ( (aligned_addr = whd_mem_malloc(WHD_LINK_MTU) ) == NULL ) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for aligned_addr in %s \n", __FUNCTION__) ); + return WHD_MALLOC_FAILURE; + } + whd_driver->aligned_addr = aligned_addr; + } + result = whd_chip_specific_init(whd_driver); + if (result != WHD_SUCCESS) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + CHECK_RETURN(result); + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + CHECK_RETURN(result); + + return result; +} + +whd_result_t whd_bus_spi_deinit(whd_driver_t whd_driver) +{ + CHECK_RETURN(whd_allow_wlan_bus_to_sleep(whd_driver) ); + + /* put device in reset. */ + //host_platform_reset_wifi (WHD_TRUE); + if (whd_driver->aligned_addr) + { + whd_mem_free(whd_driver->aligned_addr); + whd_driver->aligned_addr = NULL; + } + whd_bus_set_resource_download_halt(whd_driver, WHD_FALSE); + DELAYED_BUS_RELEASE_SCHEDULE (whd_driver, WHD_FALSE); + return WHD_SUCCESS; +} + +whd_bool_t whd_bus_spi_wake_interrupt_present(whd_driver_t whd_driver) +{ + /* functionality is only currently needed and present on SDIO */ + return WHD_FALSE; +} + +whd_result_t whd_bus_spi_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore) +{ + whd_result_t result = WHD_SUCCESS; + uint32_t timeout_ms = 1; + whd_bt_dev_t btdev = whd_driver->bt_dev; + uint32_t delayed_release_timeout_ms; + + REFERENCE_DEBUG_ONLY_VARIABLE(result); + + delayed_release_timeout_ms = whd_bus_handle_delayed_release(whd_driver); + if (delayed_release_timeout_ms != 0) + { + timeout_ms = delayed_release_timeout_ms; + } + else if ( (btdev && !btdev->intr) ) + { + timeout_ms = BT_POLLING_TIME; + whd_driver->thread_info.bus_interrupt = WHD_TRUE; + } + else + { + result = whd_allow_wlan_bus_to_sleep(whd_driver); + whd_assert("Error setting wlan sleep", (result == WHD_SUCCESS) || (result == WHD_PENDING) ); + + if (result == WHD_SUCCESS) + { + timeout_ms = CY_RTOS_NEVER_TIMEOUT; + } + } + + /* Check if we have run out of bus credits */ + if (whd_sdpcm_get_available_credits(whd_driver) == 0) + { + /* Keep poking the WLAN until it gives us more credits */ + result = whd_bus_spi_poke_wlan(whd_driver); + whd_assert("Poking failed!", result == WHD_SUCCESS); + + result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, + WHD_THREAD_POKE_TIMEOUT), WHD_FALSE); + } + else + { + result = cy_rtos_get_semaphore(transceive_semaphore, (uint32_t)MIN_OF(timeout_ms, + WHD_THREAD_POLL_TIMEOUT), WHD_FALSE); + } + whd_assert("Could not get whd sleep semaphore\n", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT) ); + + return result; +} + +/****************************************************** +* Function definitions for Protocol Common +******************************************************/ + +/* + * Write a value to a register NOT on the backplane + * Prerequisites: value_length <= 4 + */ +whd_result_t whd_bus_spi_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, + uint8_t value_length, uint32_t value) +{ + char gspi_internal_buffer[MAX_BUS_HEADER_SIZE + sizeof(uint32_t) + sizeof(uint32_t)] = {0}; + whd_transfer_bytes_packet_t *internal_gspi_packet = (whd_transfer_bytes_packet_t *)gspi_internal_buffer; + + /* Flip the bytes if we're not in 32 bit mode */ + if (whd_driver->bus_gspi_32bit == WHD_FALSE) + { + value = H32TO16LE(value); + } + /* Write the value and value_length into the packet */ + internal_gspi_packet->data[0] = value; + + /* Send it off */ + return whd_bus_spi_transfer_bytes(whd_driver, BUS_WRITE, function, address, value_length, internal_gspi_packet); +} + +/* + * Read the value of a register NOT on the backplane + * Prerequisites: value_length <= 4 + */ +whd_result_t whd_bus_spi_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, uint32_t address, + uint8_t value_length, uint8_t *value) +{ + uint32_t *data_ptr; + whd_result_t result; + uint8_t padding = 0; + + char gspi_internal_buffer[MAX_BUS_HEADER_SIZE + sizeof(uint32_t) + sizeof(uint32_t)] = {0}; + + /* Clear the receiving part of memory and set the value_length */ + if (function == BACKPLANE_FUNCTION) + { + gspi_backplane_f1_read_packet_t *pkt = + (gspi_backplane_f1_read_packet_t *)(gspi_internal_buffer + MAX_BUS_HEADER_SIZE - + sizeof(whd_bus_gspi_header_t) ); + data_ptr = pkt->data; + padding = 4; /* Add response delay */ + } + else + { + whd_transfer_bytes_packet_t *pkt = (whd_transfer_bytes_packet_t *)gspi_internal_buffer; + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + data_ptr = pkt->data; + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + } + + *data_ptr = 0; + result = + whd_bus_spi_transfer_bytes(whd_driver, BUS_READ, function, address, ( uint16_t )(value_length + padding), + (whd_transfer_bytes_packet_t *)gspi_internal_buffer); + + memcpy(value, data_ptr, value_length); + + return result; +} + +/* + * Write a value to a register on the backplane + * Prerequisites: value_length <= 4 + */ +whd_result_t whd_bus_spi_write_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, + uint32_t value) +{ + CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address) ); + + address &= SBSDIO_SB_OFT_ADDR_MASK; + + if (register_length == 4) + address |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + return whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, address, register_length, value); +} + +/* + * Read the value of a register on the backplane + * Prerequisites: value_length <= 4 + */ +whd_result_t whd_bus_spi_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, + uint8_t *value) +{ + *value = 0; + CHECK_RETURN(whd_bus_set_backplane_window(whd_driver, address) ); + + address &= SBSDIO_SB_OFT_ADDR_MASK; + + if (register_length == 4) + address |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + return whd_bus_spi_read_register_value(whd_driver, BACKPLANE_FUNCTION, address, register_length, value); +} + +whd_result_t whd_bus_spi_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *packet) +{ + uint32_t *temp; + whd_result_t result; + uint16_t newsize; + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + whd_bus_gspi_header_t *gspi_header = + (whd_bus_gspi_header_t *)( (char *)packet->data - sizeof(whd_bus_gspi_header_t) ); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + size_t transfer_size; + + *gspi_header = + ( whd_bus_gspi_header_t )( ( uint32_t )( (whd_bus_gspi_command_mapping[(int)direction] & 0x1) << 31 ) | + ( uint32_t )( (GSPI_INCREMENT_ADDRESS & 0x1) << 30 ) | + ( uint32_t )( (function & 0x3) << 28 ) | + ( uint32_t )( (address & 0x1FFFF) << 11 ) | ( uint32_t )( (size & 0x7FF) << 0 ) ); + + /* Reshuffle the bits if we're not in 32 bit mode */ + if (whd_driver->bus_gspi_32bit == WHD_FALSE) + { + /* Note: This typecast should always be valid if the buffer + * containing the GSpi packet has been correctly declared as 32-bit aligned */ + temp = (uint32_t *)gspi_header; + *temp = H32TO16LE(*temp); + } + + /* Round size up to 32-bit alignment */ + newsize = (uint16_t)ROUND_UP(size, 4); + + /* Ensure we are clear to write */ + if ( (direction == BUS_WRITE) && (function == WLAN_FUNCTION) ) + { + uint32_t whd_bus_gspi_status; + uint32_t loop_count = 0; + + /* Verify the SDPCM size and stated size match */ + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + uint16_t *frametag_ptr = (uint16_t *)&packet->data; + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + if (size != *frametag_ptr) + { + WPRINT_WHD_DEBUG( ("Error - gSPI size does not match SDPCM size!\n") ); + return WHD_SPI_SIZE_MISMATCH; + } + + /* Wait for WLAN FIFO to be ready to accept data */ + while ( ( (result = + whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_STATUS_REGISTER, (uint8_t)4, + (uint8_t *)&whd_bus_gspi_status) ) == WHD_SUCCESS ) && + ( (whd_bus_gspi_status & (1 << 5) ) == 0 ) && + (loop_count < ( uint32_t )F2_READY_TIMEOUT_LOOPS) ) + { + ++loop_count; + } + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to read SPI register value in %s at %d \n", __func__, __LINE__) ); + return result; + } + + if (loop_count >= ( uint32_t )F2_READY_TIMEOUT_LOOPS) + { + WPRINT_WHD_DEBUG( ("Timeout waiting for data FIFO to be ready\n") ); + return WHD_TIMEOUT; + } + + } + + transfer_size = (size_t)(newsize + sizeof(whd_bus_gspi_header_t) ); + + /* Send the data */ + if (direction == BUS_READ) + { + result = cyhal_spi_transfer(whd_driver->bus_priv->spi_obj, NULL, + sizeof(whd_bus_gspi_header_t), + (uint8_t *)gspi_header, + transfer_size, 0); + } + else + { + result = cyhal_spi_transfer(whd_driver->bus_priv->spi_obj, (uint8_t *)gspi_header, transfer_size, NULL, + 0, 0); + } + + CHECK_RETURN(result); + return WHD_SUCCESS; +} + +/****************************************************** +* Static Function definitions +******************************************************/ + +static whd_result_t whd_spi_download_firmware(whd_driver_t whd_driver) +{ + uint8_t csr_val; + whd_result_t result; + uint32_t loop_count = 0; + + CHECK_RETURN(whd_disable_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE) ); + CHECK_RETURN(whd_disable_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE) ); + CHECK_RETURN(whd_reset_device_core(whd_driver, SOCRAM_CORE, WLAN_CORE_FLAG_NONE) ); + + CHECK_RETURN(whd_chip_specific_socsram_init(whd_driver) ); + + CHECK_RETURN(whd_bus_write_wifi_firmware_image(whd_driver) ); + CHECK_RETURN(whd_bus_spi_write_wifi_nvram_image(whd_driver) ); + + /* Take the ARM core out of reset */ + CHECK_RETURN(whd_reset_device_core(whd_driver, WLAN_ARM_CORE, WLAN_CORE_FLAG_NONE) ); + result = whd_device_core_is_up(whd_driver, WLAN_ARM_CORE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not bring ARM core up\n") ); + return result; + } + + /* Wait until the HT clock is available */ + while ( ( (result = + whd_bus_spi_read_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_CHIP_CLOCK_CSR, (uint8_t)1, + &csr_val) ) == WHD_SUCCESS ) && + ( (csr_val & SBSDIO_HT_AVAIL) == 0 ) && + (loop_count < ( uint32_t )HT_AVAIL_TIMEOUT_MS) ) + { + cy_rtos_delay_milliseconds( (uint32_t)1 ); + loop_count++; + } + if (loop_count >= ( uint32_t )HT_AVAIL_TIMEOUT_MS) + { + return WHD_TIMEOUT; + } + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("HT clock not available\n") ); + return result; + } + + /* Set up the interrupt mask and enable interrupts */ + CHECK_RETURN(whd_bus_spi_write_backplane_value(whd_driver, SDIO_INT_HOST_MASK( + whd_driver), (uint8_t)4, I_HMB_SW_MASK) ); + + /* Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped. */ + return whd_bus_spi_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_FUNCTION2_WATERMARK, (uint8_t)1, + ( uint32_t )SPI_F2_WATERMARK); +} + +whd_result_t whd_bus_spi_wakeup(whd_driver_t whd_driver) +{ + uint32_t spi_bus_reg_value; + + /* Wake up WLAN SPI interface module */ + CHECK_RETURN(whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, sizeof(uint32_t), + (uint8_t *)&spi_bus_reg_value) ); + spi_bus_reg_value |= ( uint32_t )(WAKE_UP); + return whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, sizeof(uint32_t), + spi_bus_reg_value); +} + +whd_result_t whd_bus_spi_sleep(whd_driver_t whd_driver) +{ + uint32_t spi_bus_reg_value; + + /* Put SPI interface block to sleep */ + CHECK_RETURN(whd_bus_spi_read_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, sizeof(uint32_t), + (uint8_t *)&spi_bus_reg_value) ); + spi_bus_reg_value &= ~( uint32_t )(WAKE_UP); + return whd_bus_spi_write_register_value(whd_driver, BUS_FUNCTION, SPI_BUS_CONTROL, sizeof(uint32_t), + spi_bus_reg_value); +} + +void whd_bus_spi_init_stats(whd_driver_t whd_driver) +{ + whd_bt_dev_t btdev = whd_driver->bt_dev; + + if (btdev && btdev->intr) + { + whd_result_t res; + /* Enable F1 INT in order to receive interrupt from BT FW with HMB_FC_CHANGED in SPI */ + res = whd_bus_write_register_value(whd_driver, BUS_FUNCTION, (uint32_t)SPI_INTERRUPT_ENABLE_REGISTER, + (uint8_t)2, + ( uint32_t )(F1_INTR | F2_F3_FIFO_RD_UNDERFLOW | F2_F3_FIFO_WR_OVERFLOW | + COMMAND_ERROR | DATA_ERROR | F2_PACKET_AVAILABLE | + F1_OVERFLOW) ); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("spi interrupt register failed to enable\n") ); + } + + res = whd_bus_spi_write_backplane_value(whd_driver, SDIO_INT_HOST_MASK( + whd_driver), (uint8_t)4, I_HMB_FC_CHANGE); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("sdio int host mask failed to enable\n") ); + } + } +} + +whd_result_t whd_bus_spi_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) +{ + return WHD_TRUE; +} + +/* Waking the firmware up from Deep Sleep */ +whd_result_t whd_bus_spi_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware) +{ + return WHD_TRUE; +} + +uint8_t whd_bus_spi_backplane_read_padd_size(whd_driver_t whd_driver) +{ + return WHD_BUS_SPI_BACKPLANE_READ_PADD_SIZE; +} + +whd_bool_t whd_bus_spi_use_status_report_scheme(whd_driver_t whd_driver) +{ + return WHD_FALSE; +} + +uint32_t whd_bus_spi_get_max_transfer_size(whd_driver_t whd_driver) +{ + return WHD_BUS_SPI_MAX_BACKPLANE_TRANSFER_SIZE; +} + +#if (CYHAL_API_VERSION >= 2) +static void whd_bus_spi_oob_irq_handler(void *arg, cyhal_gpio_event_t event) +#else +static void whd_bus_spi_oob_irq_handler(void *arg, cyhal_gpio_irq_event_t event) +#endif +{ + whd_driver_t whd_driver = (whd_driver_t)arg; + const whd_oob_config_t *config = &whd_driver->bus_priv->spi_config.oob_config; +#if (CYHAL_API_VERSION >= 2) + const cyhal_gpio_event_t expected_event = (config->is_falling_edge == WHD_TRUE) + ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; +#else + const cyhal_gpio_irq_event_t expected_event = (config->is_falling_edge == WHD_TRUE) + ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; +#endif + if (event != expected_event) + { + WPRINT_WHD_ERROR( ("Unexpected interrupt event %d\n", event) ); + + return; + } + + /* call thread notify to wake up WHD thread */ + whd_thread_notify_irq(whd_driver); +} + +/* XXX FIXME */ +#define WLAN_INTR_PRIORITY 1 +whd_result_t whd_bus_spi_irq_register(whd_driver_t whd_driver) +{ + const whd_oob_config_t *config = &whd_driver->bus_priv->spi_config.oob_config; + + cyhal_gpio_init(config->host_oob_pin, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_ANALOG, + (config->is_falling_edge == WHD_TRUE) ? 1 : 0); +#if (CYHAL_API_VERSION >= 2) + static cyhal_gpio_callback_data_t cbdata; + cbdata.callback = whd_bus_spi_oob_irq_handler; + cbdata.callback_arg = whd_driver; + cyhal_gpio_register_callback(config->host_oob_pin, &cbdata); +#else + cyhal_gpio_register_irq(config->host_oob_pin, WLAN_INTR_PRIORITY, whd_bus_spi_oob_irq_handler, + whd_driver); +#endif + return WHD_TRUE; +} + +whd_result_t whd_bus_spi_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + const whd_oob_config_t *config = &whd_driver->bus_priv->spi_config.oob_config; +#if (CYHAL_API_VERSION >= 2) + const cyhal_gpio_event_t event = + (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + + cyhal_gpio_enable_event(config->host_oob_pin, event, WLAN_INTR_PRIORITY, (enable == WHD_TRUE) ? true : false); +#else + const cyhal_gpio_irq_event_t event = + (config->is_falling_edge == WHD_TRUE) ? CYHAL_GPIO_IRQ_FALL : CYHAL_GPIO_IRQ_RISE; + + cyhal_gpio_irq_enable(config->host_oob_pin, event, (enable == WHD_TRUE) ? true : false); +#endif + return WHD_TRUE; +} + +static whd_result_t whd_bus_spi_blhs(whd_driver_t whd_driver, whd_bus_blhs_stage_t stage) +{ + return WHD_SUCCESS; +} + +static whd_result_t whd_bus_spi_download_resource(whd_driver_t whd_driver, whd_resource_type_t resource, + whd_bool_t direct_resource, uint32_t address, uint32_t image_size) +{ + whd_result_t result = WHD_SUCCESS; + uint8_t *image; + uint32_t blocks_count = 0; + uint32_t i; + uint32_t size_out; + uint32_t reset_instr = 0; + + result = whd_get_resource_no_of_blocks(whd_driver, resource, &blocks_count); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource blocks count not known, %s failed at line %d \n", __func__, + __LINE__) ); + goto exit; + } + + for (i = 0; i < blocks_count; i++) + { + CHECK_RETURN(whd_get_resource_block(whd_driver, resource, i, (const uint8_t **)&image, &size_out) ); + if ( (resource == WHD_RESOURCE_WLAN_FIRMWARE) && (reset_instr == 0) ) + { + /* Copy the starting address of the firmware into a global variable */ + reset_instr = *( (uint32_t *)(&image[0]) ); + } + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_WRITE, address, size_out, &image[0]); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Failed to write firmware image\n", __FUNCTION__) ); + goto exit; + } + address += size_out; + } + + /* Below part of the code is applicable to arm_CR4 type chips only + * The CR4 chips by default firmware is not loaded at 0. So we need + * load the first 32 bytes with the offset of the firmware load address + * which is been copied before during the firmware download + */ + if ( (address != 0) && (reset_instr != 0) ) + { + /* write address 0 with reset instruction */ + result = whd_bus_write_backplane_value(whd_driver, 0, sizeof(reset_instr), reset_instr); + + if (result == WHD_SUCCESS) + { + uint32_t tmp; + + /* verify reset instruction value */ + result = whd_bus_read_backplane_value(whd_driver, 0, sizeof(tmp), (uint8_t *)&tmp); + + if ( (result == WHD_SUCCESS) && (tmp != reset_instr) ) + { + WPRINT_WHD_ERROR( ("%s: Failed to write 0x%08" PRIx32 " to addr 0\n", __FUNCTION__, reset_instr) ); + WPRINT_WHD_ERROR( ("%s: contents of addr 0 is 0x%08" PRIx32 "\n", __FUNCTION__, tmp) ); + return WHD_WLAN_SDIO_ERROR; + } + } + } +exit: return result; +} + +static whd_result_t whd_bus_spi_write_wifi_nvram_image(whd_driver_t whd_driver) +{ + uint32_t img_base; + uint32_t img_end; + uint32_t image_size; + + /* Get the size of the variable image */ + CHECK_RETURN(whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_NVRAM, &image_size) ); + + /* Round up the size of the image */ + image_size = ROUND_UP(image_size, 4); + + /* Write image */ + img_end = GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; + img_base = (img_end - image_size); + img_base += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + + CHECK_RETURN(whd_bus_spi_download_resource(whd_driver, WHD_RESOURCE_WLAN_NVRAM, WHD_FALSE, img_base, image_size) ); + + /* Write the variable image size at the end */ + image_size = (~(image_size / 4) << 16) | (image_size / 4); + + img_end += GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)img_end, 4, image_size) ); + return WHD_SUCCESS; +} + +/* + * Update the backplane window registers + */ +static whd_result_t whd_bus_spi_set_backplane_window(whd_driver_t whd_driver, uint32_t addr, uint32_t *curbase) +{ + whd_result_t result = WHD_BUS_WRITE_REGISTER_ERROR; + uint32_t base = addr & ( (uint32_t) ~BACKPLANE_ADDRESS_MASK ); + const uint32_t upper_32bit_mask = 0xFF000000; + const uint32_t upper_middle_32bit_mask = 0x00FF0000; + const uint32_t lower_middle_32bit_mask = 0x0000FF00; + + if (base == *curbase) + { + return WHD_SUCCESS; + } + if ( (base & upper_32bit_mask) != (*curbase & upper_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_HIGH, + (uint8_t)1, (base >> 24) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + /* clear old */ + *curbase &= ~upper_32bit_mask; + /* set new */ + *curbase |= (base & upper_32bit_mask); + } + + if ( (base & upper_middle_32bit_mask) != + (*curbase & upper_middle_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_MID, + (uint8_t)1, (base >> 16) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + /* clear old */ + *curbase &= ~upper_middle_32bit_mask; + /* set new */ + *curbase |= (base & upper_middle_32bit_mask); + } + + if ( (base & lower_middle_32bit_mask) != + (*curbase & lower_middle_32bit_mask) ) + { + if (WHD_SUCCESS != + (result = whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_BACKPLANE_ADDRESS_LOW, + (uint8_t)1, (base >> 8) ) ) ) + { + WPRINT_WHD_ERROR( ("Failed to write register value to the bus, %s failed at %d \n", __func__, + __LINE__) ); + return result; + } + + /* clear old */ + *curbase &= ~lower_middle_32bit_mask; + /* set new */ + *curbase |= (base & lower_middle_32bit_mask); + } + + return WHD_SUCCESS; +} + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SPI_INTERFACE) */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.h b/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.h new file mode 100644 index 00000000..579a04b9 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_spi_protocol.h @@ -0,0 +1,103 @@ +/* + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "whd.h" +#include "whd_bus_protocol_interface.h" +#include "cy_result.h" +#include "cyhal_spi.h" + +#ifndef INCLUDED_SPI_WHD_BUS_PROTOCOL_H +#define INCLUDED_SPI_WHD_BUS_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** +* Constants +******************************************************/ + +/****************************************************** +* Structures +******************************************************/ + +typedef uint32_t whd_bus_gspi_header_t; + +#pragma pack(1) + +typedef struct +{ + whd_bus_gspi_header_t gspi_header; +} whd_bus_header_t; + +#pragma pack() + +#define WHD_BUS_SPI_HEADER_SIZE (sizeof(whd_bus_header_t) ) + +#define WHD_BUS_SPI_USE_STATUS_REPORT_SCHEME (1 == 1) + +#define WHD_BUS_SPI_MAX_BACKPLANE_TRANSFER_SIZE (64) /* Max packet size on F1 */ +#define WHD_BUS_SPI_BACKPLANE_READ_PADD_SIZE (4) + +/****************************************************** +* Function declarations +******************************************************/ +extern whd_result_t whd_bus_spi_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer); +extern whd_result_t whd_bus_spi_poke_wlan(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus); +extern uint32_t whd_bus_spi_packet_available_to_read(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_read_frame(whd_driver_t whd_driver, whd_buffer_t *buffer); +extern whd_result_t whd_bus_spi_init(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_deinit(whd_driver_t whd_driver); +extern whd_bool_t whd_bus_spi_wake_interrupt_present(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_wait_for_wlan_event(whd_driver_t whd_driver, + cy_semaphore_t *transceive_semaphore); +extern whd_result_t whd_bus_spi_write_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint32_t value); +extern whd_result_t whd_bus_spi_read_register_value(whd_driver_t whd_driver, whd_bus_function_t function, + uint32_t address, uint8_t value_length, uint8_t *value); +extern whd_result_t whd_bus_spi_write_backplane_value(whd_driver_t whd_driver, uint32_t address, + uint8_t register_length, uint32_t value); +extern whd_result_t whd_bus_spi_read_backplane_value(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, + uint8_t *value); +extern whd_result_t whd_bus_spi_transfer_bytes(whd_driver_t whd_driver, whd_bus_transfer_direction_t direction, + whd_bus_function_t function, uint32_t address, uint16_t size, + whd_transfer_bytes_packet_t *packet); +extern whd_result_t whd_bus_spi_wakeup(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_sleep(whd_driver_t whd_driver); +extern void whd_bus_spi_init_stats(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print); +extern whd_result_t whd_bus_spi_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware); +extern uint8_t whd_bus_spi_backplane_read_padd_size(whd_driver_t whd_driver); +extern whd_bool_t whd_bus_spi_use_status_report_scheme(whd_driver_t whd_driver); +extern uint32_t whd_bus_spi_get_max_transfer_size(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_irq_register(whd_driver_t whd_driver); +extern whd_result_t whd_bus_spi_irq_enable(whd_driver_t whd_driver, whd_bool_t enable); +#if (CYHAL_API_VERSION >= 2) +extern void whd_bus_spi_irq_handler(void *handler_arg, cyhal_spi_event_t event); +#else +extern void whd_bus_spi_irq_handler(void *handler_arg, cyhal_spi_irq_event_t event); +#endif +/****************************************************** +* Global variables +******************************************************/ + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +#endif /* ifndef INCLUDED_SPI_WHD_BUS_PROTOCOL_H */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.c b/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.c new file mode 100644 index 00000000..8e7d6657 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.c @@ -0,0 +1,874 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * Broadcom WLAN USB Protocol interface + * + * Implements the WHD Bus Protocol Interface for USB + * Provides functions for initializing, de-intitializing 802.11 device, + * sending/receiving raw packets etc + * + */ + +#include "cybsp.h" + +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) + +#include "cyabs_rtos.h" +#include "cyhal_usb.h" +#include "whd_buffer_api.h" +#include "whd_cdc_bdc.h" +#include "whd_utils.h" + +#include +#include + +#include "whd_bus_usb_protocol.h" + +#define WHD_BUS_USB_RX_QUEUE_SIZE 16 +#define WHD_BUS_USB_RX_THREAD_STACK_SIZE 2048 +#define WHD_BUS_USB_N_CONSECUTIVE_FAILS 10 + + +/****************************************************** + * Structures + ******************************************************/ +struct whd_bus_priv { + void *usb_obj; +}; + +struct rdl_state_le +{ + uint32_t state; + uint32_t bytes; +}; + + +/* SDIO bus specific header - Software header */ +typedef struct { + uint8_t sequence; /* Rx/Tx sequence number */ + uint8_t channel_and_flags; /* 4 MSB Channel number, 4 LSB arbitrary flag */ + uint8_t next_length; /* Length of next data frame, reserved for Tx */ + uint8_t header_length; /* Data offset */ + uint8_t wireless_flow_control; /* Flow control bits, reserved for Tx */ + uint8_t bus_data_credit; /* Maximum Sequence number allowed by firmware for Tx */ + uint8_t _reserved[2]; /* Reserved */ +} __attribute__((packed)) sdpcm_sw_header_t; + +/* SDPCM header definitions */ +typedef struct { + uint16_t frametag[2]; + sdpcm_sw_header_t sw_header; +} __attribute__((packed)) sdpcm_header_t; + + +static struct { + uint32_t chipid; + whd_usb_config_t config; + + struct { + cy_queue_t queue; + cy_semaphore_t semaphore; + cy_thread_t thread; + bool failed; + } rx; +} whd_bus_usb_common; + + +/****************************************************** +* Static Function Declarations +******************************************************/ + +static bool whd_bus_usb_dl_needed(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_resetcfg(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_download_firmware(whd_driver_t whd_driver); +static whd_bool_t whd_bus_usb_wake_interrupt_present(whd_driver_t whd_driver); +static uint32_t whd_bus_usb_packet_available_to_read(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_start_rx(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_stop_rx(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_rx_queue_enqueue(whd_buffer_t *data); +static whd_result_t whd_bus_usb_rx_queue_dequeue(whd_buffer_t *data); +static void whd_usb_rx_thread_notify(void); + +whd_result_t whd_bus_usb_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer); +whd_result_t whd_bus_usb_read_frame(whd_driver_t whd_driver, whd_buffer_t* buffer); +static whd_result_t whd_bus_usb_irq_enable(whd_driver_t whd_driver, whd_bool_t enable); +static whd_result_t whd_bus_usb_irq_register(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware); +static whd_result_t whd_bus_usb_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print); +static void whd_bus_usb_init_stats(whd_driver_t whd_driver); +static uint32_t whd_bus_usb_get_max_transfer_size(whd_driver_t whd_driver); +static whd_bool_t whd_bus_usb_use_status_report_scheme(whd_driver_t whd_driver); +static uint8_t whd_bus_usb_backplane_read_padd_size(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus); +static whd_result_t whd_bus_usb_poke_wlan(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_wakeup(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_sleep(whd_driver_t whd_driver); +static whd_result_t whd_bus_usb_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore); + + +/* ------------------------------------------------------------------------------------- */ +uint32_t whd_bus_usb_attach(whd_driver_t whd_driver, whd_usb_config_t *config, cyhal_usb_t *usb_obj) +{ + struct whd_bus_info* whd_bus_info; + + whd_bus_info = (whd_bus_info_t *)malloc(sizeof(whd_bus_info_t)); + + if (whd_bus_info == NULL) + { + WPRINT_WHD_ERROR(("Memory allocation failed for whd_bus_info in %s\n", __FUNCTION__)); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_bus_info, 0, sizeof(whd_bus_info_t)); + + whd_driver->bus_if = whd_bus_info; + + whd_driver->bus_priv = (struct whd_bus_priv *)malloc(sizeof(struct whd_bus_priv)); + + if (whd_driver->bus_priv == NULL) + { + WPRINT_WHD_ERROR(("Memory allocation failed for whd_bus_priv in %s\n", __FUNCTION__)); + return WHD_BUFFER_UNAVAILABLE_PERMANENT; + } + memset(whd_driver->bus_priv, 0, sizeof(struct whd_bus_priv)); + + whd_driver->bus_priv->usb_obj = usb_obj; + memcpy(&whd_bus_usb_common.config, config, sizeof(*config)); + + whd_bus_info->whd_bus_init_fptr = whd_bus_usb_init; + whd_bus_info->whd_bus_deinit_fptr = whd_bus_usb_deinit; + + whd_bus_info->whd_bus_send_buffer_fptr = whd_bus_usb_send_buffer; + whd_bus_info->whd_bus_read_frame_fptr = whd_bus_usb_read_frame; + + whd_bus_info->whd_bus_packet_available_to_read_fptr = whd_bus_usb_packet_available_to_read; + whd_bus_info->whd_bus_poke_wlan_fptr = whd_bus_usb_poke_wlan; + whd_bus_info->whd_bus_wait_for_wlan_event_fptr = whd_bus_usb_wait_for_wlan_event; + + whd_bus_info->whd_bus_ack_interrupt_fptr = whd_bus_usb_ack_interrupt; + whd_bus_info->whd_bus_wake_interrupt_present_fptr = whd_bus_usb_wake_interrupt_present; + + whd_bus_info->whd_bus_wakeup_fptr = whd_bus_usb_wakeup; + whd_bus_info->whd_bus_sleep_fptr = whd_bus_usb_sleep; + + whd_bus_info->whd_bus_backplane_read_padd_size_fptr = whd_bus_usb_backplane_read_padd_size; + whd_bus_info->whd_bus_use_status_report_scheme_fptr = whd_bus_usb_use_status_report_scheme; + + whd_bus_info->whd_bus_get_max_transfer_size_fptr = whd_bus_usb_get_max_transfer_size; + + whd_bus_info->whd_bus_init_stats_fptr = whd_bus_usb_init_stats; + whd_bus_info->whd_bus_print_stats_fptr = whd_bus_usb_print_stats; + whd_bus_info->whd_bus_reinit_stats_fptr = whd_bus_usb_reinit_stats; + whd_bus_info->whd_bus_irq_register_fptr = whd_bus_usb_irq_register; + whd_bus_info->whd_bus_irq_enable_fptr = whd_bus_usb_irq_enable; + + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_detach + **************************************************************************************************/ +void whd_bus_usb_detach(whd_driver_t whd_driver) +{ + whd_bus_usb_deinit(whd_driver); + if (whd_driver->bus_if != NULL) { + free(whd_driver->bus_if); + whd_driver->bus_if = NULL; + } + if (whd_driver->bus_priv != NULL) { + free(whd_driver->bus_priv); + whd_driver->bus_priv = NULL; + } +} + + +static whd_result_t whd_bus_usb_wait_and_init_device(whd_driver_t whd_driver) +{ + cy_rslt_t result; + + result = cyhal_usb_wait_state(whd_bus_usb_common.config.path, true); + if (result != CY_RSLT_SUCCESS) { + return WHD_HAL_ERROR; + } + + result = cyhal_usb_init(whd_driver->bus_priv->usb_obj, whd_bus_usb_common.config.path); + return result == CY_RSLT_SUCCESS ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +/*************************************************************************************************** + * whd_bus_usb_init + **************************************************************************************************/ +whd_result_t whd_bus_usb_init(whd_driver_t whd_driver) +{ + whd_result_t result; + + result = whd_bus_usb_wait_and_init_device(whd_driver); + if (result != WHD_SUCCESS) { + whd_bus_usb_deinit(whd_driver); + return result; + } + + if (whd_bus_usb_dl_needed(whd_driver)) { + WPRINT_WHD_DEBUG(("Download needed, downloading firmware\n")); + (void)whd_bus_usb_download_firmware(whd_driver); + + /* re-initialize USB as it's re-enumerated */ + (void)cyhal_usb_wait_state(whd_bus_usb_common.config.path, false); + (void)cyhal_usb_free(whd_driver->bus_priv->usb_obj); + result = whd_bus_usb_wait_and_init_device(whd_driver); + if (result != WHD_SUCCESS) { + whd_bus_usb_deinit(whd_driver); + return result; + } + } + + whd_bus_set_state(whd_driver, true); + + result = whd_bus_usb_start_rx(whd_driver); + if (result != WHD_SUCCESS) { + whd_bus_usb_deinit(whd_driver); + return result; + } + + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_deinit + **************************************************************************************************/ +whd_result_t whd_bus_usb_deinit(whd_driver_t whd_driver) +{ + whd_bus_set_state(whd_driver, WHD_FALSE); + cy_rslt_t cy_result = cyhal_usb_free(whd_driver->bus_priv->usb_obj); + whd_result_t whd_result = whd_bus_usb_stop_rx(whd_driver); + return ((whd_result == WHD_SUCCESS) && (cy_result == CY_RSLT_SUCCESS)) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +static bool whd_bus_rx_queue_is_full(void) +{ + size_t spaces; + (void)cy_rtos_queue_space(&whd_bus_usb_common.rx.queue, &spaces); + return spaces == 0; +} + + +static inline whd_result_t whd_bus_usb_handle_rx(whd_driver_t whd_driver, whd_buffer_t buffer) +{ + cy_rslt_t result; + uint8_t *data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + size_t size = WHD_USB_MAX_RECEIVE_BUF_SIZE; + + result = cyhal_usb_bulk_receive(whd_driver->bus_priv->usb_obj, data, &size); + if (result == CY_RSLT_SUCCESS) { + /* Set final size of received packet */ + whd_buffer_set_size(whd_driver, buffer, size); + (void)whd_bus_usb_rx_queue_enqueue(&buffer); + } + else { + return WHD_HAL_ERROR; + } + + return WHD_SUCCESS; +} + + +static void whd_bus_usb_rx_thread(cy_thread_arg_t arg) +{ + whd_driver_t whd_driver = arg; + whd_buffer_t buffer = NULL; + int consecutive_fails_cnt = 0; + + WPRINT_WHD_DEBUG(("whd_bus_usb_rx_thread started\n")); + + for (;;) { + if (!(whd_bus_is_up(whd_driver) == WHD_TRUE)) { + cy_rtos_delay_milliseconds(10); + continue; + } + + if (!whd_bus_rx_queue_is_full()) { + if (whd_host_buffer_get(whd_driver, &buffer, WHD_NETWORK_RX, WHD_USB_MAX_RECEIVE_BUF_SIZE, CY_RTOS_NEVER_TIMEOUT) != WHD_SUCCESS) { + WPRINT_WHD_ERROR(("whd_host_buffer_get failed\n")); + cy_rtos_delay_milliseconds(10); + continue; + } + + if (whd_bus_usb_handle_rx(whd_driver, buffer) != WHD_SUCCESS) { + whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + consecutive_fails_cnt++; + if (consecutive_fails_cnt > WHD_BUS_USB_N_CONSECUTIVE_FAILS) { + WPRINT_WHD_ERROR(("%s: handle RX failed\n", __FUNCTION__)); + whd_bus_usb_common.rx.failed = true; + whd_thread_notify(whd_driver); + break; + } + cy_rtos_delay_milliseconds(10); + } + else { + consecutive_fails_cnt = 0; + } + } + else { + WPRINT_WHD_INFO(("whd queue is full, going to sleep\n")); + whd_thread_notify(whd_driver); + cy_rtos_get_semaphore(&whd_bus_usb_common.rx.semaphore, CY_RTOS_NEVER_TIMEOUT, false /* ignored */); + } + + whd_thread_notify(whd_driver); + } + + cy_rtos_exit_thread(); +} + + +static whd_result_t whd_bus_usb_start_rx(whd_driver_t whd_driver) +{ + cy_rslt_t result; + + result = cy_rtos_init_semaphore(&whd_bus_usb_common.rx.semaphore, 1, 0); + if (result != CY_RSLT_SUCCESS) { + WPRINT_WHD_ERROR(("USB Bus: failed to init semaphore\n")); + return WHD_RTOS_ERROR; + } + + result = cy_rtos_queue_init(&whd_bus_usb_common.rx.queue, WHD_BUS_USB_RX_QUEUE_SIZE, sizeof(whd_buffer_t)); + if (result != CY_RSLT_SUCCESS) { + WPRINT_WHD_ERROR(("USB Bus: failed to init queue\n")); + return WHD_RTOS_ERROR; + } + + result = cy_rtos_create_thread(&whd_bus_usb_common.rx.thread, whd_bus_usb_rx_thread, "whd_bus_usb_rx_thread", + NULL, WHD_BUS_USB_RX_THREAD_STACK_SIZE, max(whd_driver->thread_info.thread_priority - 1, 0), whd_driver); + if (result != CY_RSLT_SUCCESS) { + WPRINT_WHD_ERROR(("USB Bus: failed to create RX thread\n")); + return WHD_RTOS_ERROR; + } + + return WHD_SUCCESS; +} + + +static whd_result_t whd_bus_usb_stop_rx(whd_driver_t whd_driver) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + whd_usb_rx_thread_notify(); + whd_thread_notify(whd_driver); + result |= cy_rtos_join_thread(&whd_bus_usb_common.rx.thread); + result |= cy_rtos_queue_deinit(&whd_bus_usb_common.rx.queue); + result |= cy_rtos_deinit_semaphore(&whd_bus_usb_common.rx.semaphore); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_RTOS_ERROR; +} + + +/*************************************************************************************************** + * whd_bus_usb_dl_needed + **************************************************************************************************/ +static bool whd_bus_usb_dl_needed(whd_driver_t whd_driver) +{ + struct bootrom_id_le id; + + if (whd_driver == NULL) + { + return false; + } + + /* Check if firmware is already downloaded by querying runtime ID */ + id.chip = 0xDEAD; + cy_rslt_t result = whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_GETVER, &id, sizeof(id)); + + WPRINT_WHD_INFO(("Chip %x rev 0x%x, result=%u\n", id.chip, id.chiprev, result)); + + if (id.chip == WHD_USB_POSTBOOT_ID) + { + WPRINT_WHD_INFO(("Firmware already downloaded\n")); + + if (whd_bus_usb_common.chipid != 0) { + whd_chip_set_chip_id(whd_driver, whd_bus_usb_common.chipid); + } + + whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_RESETCFG, &id, sizeof(id)); + return false; + } + else { + whd_bus_usb_common.chipid = id.chip; + whd_chip_set_chip_id(whd_driver, id.chip); + } + + return true; +} + + +/*************************************************************************************************** + * whd_bus_usb_resetcfg + **************************************************************************************************/ +static whd_result_t whd_bus_usb_resetcfg(whd_driver_t whd_driver) +{ + whd_result_t result; + struct bootrom_id_le id; + uint32_t loop_cnt = 0; + + do + { + cy_rtos_delay_milliseconds(WHD_USB_RESET_GETVER_SPINWAIT); + loop_cnt++; + + /* Check if after firmware download we get runtime ID */ + id.chip = 0xDEAD; + result = whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_GETVER, &id, sizeof(id)); + if (result != WHD_SUCCESS) + { + return result; + } + + if (id.chip == WHD_USB_POSTBOOT_ID) + { + break; + } + } while (loop_cnt < WHD_USB_RESET_GETVER_LOOP_CNT); + + if (id.chip == WHD_USB_POSTBOOT_ID) { + (void)whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_RESETCFG, &id, sizeof(id)); + cy_rtos_delay_milliseconds(1000); + return 0; + } + else { + WPRINT_WHD_ERROR(("%s: Cannot talk to Dongle. Firmware is not UP, %u ms\n", __FUNCTION__, WHD_USB_RESET_GETVER_SPINWAIT * loop_cnt)); + return 1; + } +} + + +/*************************************************************************************************** + * whd_bus_usb_download_firmware + **************************************************************************************************/ +static whd_result_t whd_bus_usb_download_firmware(whd_driver_t whd_driver) +{ + whd_result_t result; + + uint32_t image_size; + uint32_t size; + uint32_t sent = 0; + static uint8_t buff[WHD_USB_TRX_RDL_CHUNK]; + + struct rdl_state_le state; + + WPRINT_WHD_INFO(("\n\rStart FW download\n\r")); + + result = whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, &image_size); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Fatal error: download_resource doesn't exist, %s failed at line %d \n", + __func__, __LINE__)); + } + + if (image_size <= 0) + { + WPRINT_WHD_ERROR(("Fatal error: download_resource can't load with invalid size," + "%s failed at line %d \n", __func__, __LINE__)); + result = WHD_BADARG; + } + + /* Prepare USB boot loader for runtime image and check we are in the + * Waiting state */ + result = whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_START, &state, sizeof(state)); + if ((result != WHD_SUCCESS) || (state.state != WHD_USB_DL_WAITING)) + { + WPRINT_WHD_ERROR(("%s: Failed to DL_START\n", __FUNCTION__)); + return 1; + } + + /* Download firmware */ + while (state.bytes != image_size) + { + /* Wait until the usb device reports it received all + * the bytes we sent */ + if ((state.bytes == sent) && (state.bytes != image_size)) + { + #if 0 + if ((image_size - sent) < WHD_USB_TRX_RDL_CHUNK) + { + size = image_size - sent; + } + else + { + size = WHD_USB_TRX_RDL_CHUNK; + } + #endif + + /* Read resource */ + CHECK_RETURN(whd_resource_read(whd_driver, WHD_RESOURCE_WLAN_FIRMWARE, + /* offset */ state.bytes, + /* size */ WHD_USB_TRX_RDL_CHUNK, + /* size */ &size, + /* buffer */ buff)); + + /* Simply avoid having to send a ZLP by ensuring we never have an even multiple of 64 */ + if (size % 64 == 0) { + size -= 4; + } + + /* Send data by USB Bulk */ + result = whd_bus_usb_bulk_send(whd_driver, (uint8_t*)buff, size); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("%s: Failed to write firmware image\n", __FUNCTION__)); + } + + sent += size; + } + + /* Read the status and restart if an error is reported */ + result = whd_bus_usb_dl_cmd(whd_driver, WHD_USB_DL_GETSTATE, &state, sizeof(state)); + if (result) + { + WPRINT_WHD_ERROR(("%s: DL_GETSTATE Failed\n", __FUNCTION__)); + return 1; + } + + if ((state.state == WHD_USB_DL_BAD_HDR) || (state.state == WHD_USB_DL_BAD_CRC)) { + WPRINT_WHD_ERROR(("%s: Bad Hdr or Bad CRC state %u\n\n", __FUNCTION__, state.state)); + return 1; + } + } + WPRINT_WHD_INFO(("FW download complete, wrote %u bytes\n\r", state.bytes)); + + /* Start the image */ + WPRINT_WHD_INFO(("\n\rStart the FW image \n\r")); + if (state.state == WHD_USB_DL_RUNNABLE) { + whd_bus_usb_dl_cmd(whd_driver, CYHAL_USB_DL_CMD_GO, NULL, 0); + if (whd_bus_usb_resetcfg(whd_driver) != 0) { + return 1; + } + } + else { + WPRINT_WHD_ERROR(("%s: Dongle not runnable\n", __FUNCTION__)); + return 1; + } + + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_wake_interrupt_present + **************************************************************************************************/ +static whd_bool_t whd_bus_usb_wake_interrupt_present(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_packet_available_to_read + **************************************************************************************************/ +static uint32_t whd_bus_usb_packet_available_to_read(whd_driver_t whd_driver) +{ + if (whd_bus_usb_common.rx.failed) { + return WHD_BUS_FAIL; + } + + size_t count; + (void)cy_rtos_queue_count(&whd_bus_usb_common.rx.queue, &count); + return count; +} + + +/*************************************************************************************************** + * whd_bus_usb_send_buffer + **************************************************************************************************/ +whd_result_t whd_bus_usb_send_buffer(whd_driver_t whd_driver, whd_buffer_t buffer) +{ + whd_result_t status = WHD_SUCCESS; + + uint8_t *data = (uint8_t *)((whd_transfer_bytes_packet_t *)(whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + sizeof(whd_buffer_t)))->data; + uint16_t size = (uint16_t)(whd_buffer_get_current_piece_size(whd_driver, buffer) - sizeof(whd_buffer_t)); + + /* The packet to sent has sdpcm header, so cast to sdpcm_header_t + * to check packet type */ + sdpcm_header_t* sdpcm_header = (sdpcm_header_t*)data; + uint32_t sdpcm_header_size = sdpcm_header->sw_header.header_length; + + /* Check the SDPCM channel to decide what to do with packet. */ + switch (sdpcm_header->sw_header.channel_and_flags & 0x0f) + { + case DATA_HEADER: + { + /* We need to send only BDC header + data, so find offset without sdpcm_header_t */ + bdc_header_t* bdc_header = (bdc_header_t*)(data + sdpcm_header_size); + uint32_t bdc_size = size - sdpcm_header_size; + + WPRINT_WHD_DEBUG(("BULK: sending packet of size %u:\n", bdc_size - 4)); + + status = whd_bus_usb_bulk_send(whd_driver, bdc_header, bdc_size - 4 /* TODO: add define for -4 */); + break; + } + + case CONTROL_HEADER: /* Sent IOCTL/IOVAR packet (CDC packet) */ + { + whd_buffer_t rec_buffer = NULL; + + /* We need to send only CDC header + data, so find offset without sdpcm_header_t */ + cdc_header_t* cdc_header = (cdc_header_t*)(data + sdpcm_header_size); + uint32_t cdc_size = size - sdpcm_header_size; + + /* Send control request */ + CHECK_RETURN(whd_bus_usb_send_ctrl(whd_driver, cdc_header, &cdc_size)); + + /* Receive control response */ + CHECK_RETURN(whd_bus_usb_receive_ctrl_buffer(whd_driver, &rec_buffer)); + + if (rec_buffer != NULL) { + (void)whd_buffer_set_size(whd_driver, rec_buffer, cdc_size - 4); + } + + /* Process CDC data... */ + whd_process_cdc(whd_driver, rec_buffer); + break; + } + + default: + whd_minor_assert("whd_bus_usb_send_buffer: SDPCM packet of unknown channel received - dropping packet", 0 != 0); + break; + } + + whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); + + return status; +} + + +/*************************************************************************************************** + * whd_bus_usb_read_frame + **************************************************************************************************/ +whd_result_t whd_bus_usb_read_frame(whd_driver_t whd_driver, whd_buffer_t* buffer) +{ + /* Ensure the wlan backplane bus is up */ + CHECK_RETURN(whd_ensure_wlan_bus_is_up(whd_driver)); + + /* Check if we have something in rx_queue */ + if (whd_bus_usb_packet_available_to_read(whd_driver) != 0) { + /* Take queue data */ + return whd_bus_usb_rx_queue_dequeue(buffer); + } + + return 1; +} + + +whd_result_t whd_bus_usb_dl_cmd(whd_driver_t whd_driver, uint8_t cmd, void *buffer, uint32_t buflen) +{ + cy_rslt_t result = cyhal_usb_dl_cmd(whd_driver->bus_priv->usb_obj, cmd, buffer, buflen); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +whd_result_t whd_bus_usb_bulk_send(whd_driver_t whd_driver, void *buffer, int len) +{ + size_t buflen = len; + cy_rslt_t result = cyhal_usb_bulk_send(whd_driver->bus_priv->usb_obj, buffer, &buflen); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +whd_result_t whd_bus_usb_bulk_receive(whd_driver_t whd_driver, void *buffer, int len) +{ + size_t buflen = len; + cy_rslt_t result = cyhal_usb_bulk_receive(whd_driver->bus_priv->usb_obj, buffer, &buflen); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +whd_result_t whd_bus_usb_send_ctrl(whd_driver_t whd_driver, void *buffer, uint32_t *len) +{ + size_t buflen = *len; + cy_rslt_t result = cyhal_usb_ctrl_send(whd_driver->bus_priv->usb_obj, buffer, &buflen); + *len = buflen; + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +whd_result_t whd_bus_usb_receive_ctrl_buffer(whd_driver_t whd_driver, whd_buffer_t *buffer) +{ + if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_RX, + (unsigned short)(WHD_USB_MAX_RECEIVE_BUF_SIZE + (uint16_t)sizeof(whd_buffer_header_t)), + (whd_sdpcm_has_tx_packet(whd_driver) ? 0 : WHD_RX_BUF_TIMEOUT)) != WHD_SUCCESS) { + return WHD_BUFFER_ALLOC_FAIL; + } + + void *data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + size_t buflen = WHD_USB_MAX_RECEIVE_BUF_SIZE; + cy_rslt_t result = cyhal_usb_ctrl_receive(whd_driver->bus_priv->usb_obj, data, &buflen); + + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +/* Adds an element to the end of the queue */ +static whd_result_t whd_bus_usb_rx_queue_enqueue(whd_buffer_t *data) +{ + cy_rslt_t result = cy_rtos_queue_put(&whd_bus_usb_common.rx.queue, data); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_QUEUE_ERROR; +} + + +/* Removes an element from the front of the queue */ +static whd_result_t whd_bus_usb_rx_queue_dequeue(whd_buffer_t *data) +{ + cy_rslt_t result = cy_rtos_queue_get(&whd_bus_usb_common.rx.queue, data); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_QUEUE_ERROR; +} + + +/*************************************************************************************************** + * whd_bus_usb_irq_enable + **************************************************************************************************/ +static whd_result_t whd_bus_usb_irq_enable(whd_driver_t whd_driver, whd_bool_t enable) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_irq_register + **************************************************************************************************/ +static whd_result_t whd_bus_usb_irq_register(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_reinit_stats + **************************************************************************************************/ +static whd_result_t whd_bus_usb_reinit_stats(whd_driver_t whd_driver, whd_bool_t wake_from_firmware) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_print_stats + **************************************************************************************************/ +static whd_result_t whd_bus_usb_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_init_stats + **************************************************************************************************/ +static void whd_bus_usb_init_stats(whd_driver_t whd_driver) +{ +} + + +/*************************************************************************************************** + * whd_bus_usb_get_max_transfer_size + **************************************************************************************************/ +static uint32_t whd_bus_usb_get_max_transfer_size(whd_driver_t whd_driver) +{ + return WHD_USB_MAX_BULK_TRANSFER_SIZE; +} + + +/*************************************************************************************************** + * whd_bus_usb_use_status_report_scheme + **************************************************************************************************/ +static whd_bool_t whd_bus_usb_use_status_report_scheme(whd_driver_t whd_driver) +{ + return true; +} + + +/*************************************************************************************************** + * whd_bus_usb_backplane_read_padd_size + **************************************************************************************************/ +static uint8_t whd_bus_usb_backplane_read_padd_size(whd_driver_t whd_driver) +{ + return 0; +} + + +/*************************************************************************************************** + * whd_bus_usb_ack_interrupt + **************************************************************************************************/ +static whd_result_t whd_bus_usb_ack_interrupt(whd_driver_t whd_driver, uint32_t intstatus) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_poke_wlan + **************************************************************************************************/ +static whd_result_t whd_bus_usb_poke_wlan(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_wakeup + **************************************************************************************************/ +static whd_result_t whd_bus_usb_wakeup(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_bus_usb_sleep + **************************************************************************************************/ +static whd_result_t whd_bus_usb_sleep(whd_driver_t whd_driver) +{ + return WHD_SUCCESS; +} + + +/*************************************************************************************************** + * whd_usb_rx_thread_notify + **************************************************************************************************/ +void whd_usb_rx_thread_notify(void) +{ + (void)cy_rtos_set_semaphore(&whd_bus_usb_common.rx.semaphore, false /* ignored */); +} + + +/*************************************************************************************************** + * whd_bus_usb_wait_for_wlan_event + **************************************************************************************************/ +static whd_result_t whd_bus_usb_wait_for_wlan_event(whd_driver_t whd_driver, cy_semaphore_t *transceive_semaphore) +{ + cy_rslt_t result; + + whd_usb_rx_thread_notify(); + + if (whd_bus_usb_packet_available_to_read(whd_driver) != 0) { + return WHD_SUCCESS; + } + + result = cy_rtos_get_semaphore(transceive_semaphore, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + return (result == CY_RSLT_SUCCESS) ? WHD_SUCCESS : WHD_HAL_ERROR; +} + + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) */ diff --git a/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.h b/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.h new file mode 100644 index 00000000..657a8cdc --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_bus_usb_protocol.h @@ -0,0 +1,139 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "whd.h" +#include "bus_protocols/whd_bus_protocol_interface.h" + +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) + +#include "cyabs_rtos.h" +#include "whd_bus.h" +#include "whd_bus_common.h" +#include "whd_chip_reg.h" +#include "whd_chip_constants.h" +#include "whd_int.h" +#include "whd_chip.h" +#include "whd_sdpcm.h" +#include "whd_debug.h" +#include "whd_sdio.h" +#include "whd_buffer_api.h" +#include "whd_resource_if.h" +#include "whd_types_int.h" +#include "whd_types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** +* Macros +******************************************************/ + +/* Control messages: bRequest values */ +#define WHD_USB_DL_GETSTATE 0x0 /* returns the rdl_state_t struct */ +#define WHD_USB_DL_CHECK_CRC 0x1 /* currently unused */ +#define WHD_USB_DL_GO 0x2 /* execute downloaded image */ +#define WHD_USB_DL_START 0x3 /* initialize dl state */ +#define WHD_USB_DL_REBOOT 0x4 /* reboot the device in 2 seconds */ +#define WHD_USB_DL_GETVER 0x5 /* returns the bootrom_id_t struct */ +#define WHD_USB_DL_GO_PROTECTED 0x6 /* execute the downloaded code and set reset + * event to occur in 2 seconds. It is the + * responsibility of the downloaded code to + * clear this event */ +#define WHD_USB_DL_EXEC 0x7 /* jump to a supplied address */ +#define WHD_USB_DL_RESETCFG 0x8 /* To support single enum on dongle + * - Not used by bootloader */ +#define WHD_USB_DL_DEFER_RESP_OK 0x9 /* Potentially defer the response to setup + * if resp unavailable */ +#define WHD_USB_DL_RDHW 0x10 /* Read a hardware address (Ctl-in) */ +#define WHD_USB_DL_RDHW32 0x10 /* Read a 32 bit word */ +#define WHD_USB_DL_RDHW16 0x11 /* Read 16 bits */ +#define WHD_USB_DL_RDHW8 0x12 /* Read an 8 bit byte */ +#define WHD_USB_DL_WRHW 0x14 /* Write a hardware address (Ctl-out) */ +#define WHD_USB_DL_WRHW_BLK 0x13 /* Block write to hardware access */ + +/* States */ +#define WHD_USB_DL_WAITING 0 /* waiting to rx first pkt */ +#define WHD_USB_DL_READY 1 /* hdr was good, waiting for more of the + * compressed image */ +#define WHD_USB_DL_BAD_HDR 2 /* hdr was corrupted */ +#define WHD_USB_DL_BAD_CRC 3 /* compressed image was corrupted */ +#define WHD_USB_DL_RUNNABLE 4 /* download was successful,waiting for go cmd */ +#define WHD_USB_DL_START_FAIL 5 /* failed to initialize correctly */ +#define WHD_USB_DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM + * value */ +#define WHD_USB_DL_IMAGE_TOOBIG 7 /* firmware image too big */ + + +#define WHD_USB_POSTBOOT_ID (0xA123) /* ID to detect if dongle has boot up */ +#define WHD_USB_TRX_RDL_CHUNK (1500) + +#define WHD_USB_RESET_GETVER_SPINWAIT (10) /* in unit of ms */ +#define WHD_USB_RESET_GETVER_LOOP_CNT (10) + + +#define BCM_MSG_IFNAME_MAX (16) /** Maximum length of an interface name in a + wl_event_msg_t structure*/ + +#define WHD_USB_MAX_BULK_TRANSFER_SIZE (512) + +/* Define max buffer size for receive packet */ +#ifndef WHD_USB_MAX_RECEIVE_BUF_SIZE + #if defined (WLAN_MFG_FIRMWARE) + #define WHD_USB_MAX_RECEIVE_BUF_SIZE (WHD_USB_MAX_BULK_TRANSFER_SIZE * 10) + #else + #define WHD_USB_MAX_RECEIVE_BUF_SIZE (WHD_USB_MAX_BULK_TRANSFER_SIZE * 4) + #endif /* */ +#endif /* WHD_USB_MAX_RECEIVE_BUFFER_SIZE */ + +/****************************************************** +* Structures +******************************************************/ +struct bootrom_id_le +{ + uint32_t chip; /* Chip id */ + uint32_t chiprev; /* Chip rev */ + uint32_t ramsize; /* Size of RAM */ + uint32_t remapbase; /* Current remap base address */ + uint32_t boardtype; /* Type of board */ + uint32_t boardrev; /* Board revision */ +}; + + +/****************************************************** +* Function declarations +******************************************************/ + +whd_result_t whd_bus_usb_init(whd_driver_t whd_driver); +whd_result_t whd_bus_usb_deinit(whd_driver_t whd_driver); + +uint32_t whd_bus_usb_attach(whd_driver_t whd_driver, whd_usb_config_t *config, cyhal_usb_t *usb_obj); +void whd_bus_usb_detach(whd_driver_t whd_driver); + +whd_result_t whd_bus_usb_dl_cmd(whd_driver_t whd_driver, uint8_t cmd, void *buffer, uint32_t buflen); + +whd_result_t whd_bus_usb_bulk_send(whd_driver_t whd_driver, void *buffer, int len); +whd_result_t whd_bus_usb_bulk_receive(whd_driver_t whd_driver, void *buffer, int len); + +whd_result_t whd_bus_usb_send_ctrl(whd_driver_t whd_driver, void *buffer, uint32_t *len); +whd_result_t whd_bus_usb_receive_ctrl_buffer(whd_driver_t whd_driver, whd_buffer_t *buffer); +#ifdef __cplusplus +} /*extern "C" */ +#endif + +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) */ diff --git a/wi-fi/whd/bus_protocols/whd_chip_reg.h b/wi-fi/whd/bus_protocols/whd_chip_reg.h index 672221d0..6b9098d9 100644 --- a/wi-fi/whd/bus_protocols/whd_chip_reg.h +++ b/wi-fi/whd/bus_protocols/whd_chip_reg.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,78 +27,84 @@ extern "C" { ******************************************************/ /* D11 registers and SHM */ -#define D11_BASE_ADDR 0x18001000 -#define D11_AXI_BASE_ADDR 0xE8000000 -#define D11_SHM_BASE_ADDR (D11_AXI_BASE_ADDR + 0x4000) +#define D11_BASE_ADDR 0x18001000 +#define D11_AXI_BASE_ADDR 0xE8000000 +#define D11_SHM_BASE_ADDR (D11_AXI_BASE_ADDR + 0x4000) -#define D11REG_ADDR(offset) (D11_BASE_ADDR + offset) -#define D11IHR_ADDR(offset) (D11_AXI_BASE_ADDR + 0x400 + (2 * offset)) -#define D11SHM_ADDR(offset) (D11_SHM_BASE_ADDR + offset) +#define D11REG_ADDR(offset) (D11_BASE_ADDR + offset) +#define D11IHR_ADDR(offset) (D11_AXI_BASE_ADDR + 0x400 + (2 * offset) ) +#define D11SHM_ADDR(offset) (D11_SHM_BASE_ADDR + offset) -#define M_DS1_CTRL_STATUS (0xe0b * 2) +//#define M_DS1_CTRL_STATUS (0xe0b * 2) /* RMC operational modes */ -enum ds1_ctrl_status { - DS1_SLEEP = 0, /* DS1_SLEEP */ - MAC_ON = 1, /* MAC_ON */ - RADIO_PHY_ON = 2, /* RADIO_PHY_ON */ - DS1_EXIT = 3 /* DS1_EXIT.*/ +enum ds1_ctrl_status +{ + DS1_SLEEP = 0, /* DS1_SLEEP */ + MAC_ON = 1, /* MAC_ON */ + RADIO_PHY_ON = 2, /* RADIO_PHY_ON */ + DS1_EXIT = 3 /* DS1_EXIT.*/ }; -#define M_DS1_CTRL_SDIO (0xe0c * 2) - -#define C_DS1_CTRL_SDIO_DS1_SLEEP (1 << 0) -#define C_DS1_CTRL_SDIO_MAC_ON (1 << 1) -#define C_DS1_CTRL_SDIO_RADIO_PHY_ON (1 << 2) -#define C_DS1_CTRL_SDIO_DS1_EXIT (1 << 3) -#define C_DS1_CTRL_PROC_DONE (1 << 8) -#define C_DS1_CTRL_REQ_VALID (1 << 9) +//#define M_DS1_CTRL_SDIO (0xe0c * 2) +#define M_DS1_CTRL_STATUS (0x1c4c) +#define M_DS1_CTRL_SDIO (0x1c4e) +#define M_WAKEEVENT_IND (0xd6) +#define M_ULP_WAKE_IND (0x1580) + +#define C_DS1_CTRL_SDIO_DS1_SLEEP (1 << 0) +#define C_DS1_CTRL_SDIO_MAC_ON (1 << 1) +#define C_DS1_CTRL_SDIO_RADIO_PHY_ON (1 << 2) +#define C_DS1_CTRL_SDIO_DS1_EXIT (1 << 3) +#define C_DS1_CTRL_PROC_DONE (1 << 8) +#define C_DS1_CTRL_REQ_VALID (1 << 9) /* MacControl register */ -#define D11_MACCONTROL_REG D11REG_ADDR(0x120) -#define D11_MACCONTROL_REG_SIZE 4 -#define D11_MACCONTROL_REG_WAKE (1 << 26) -#define D11_MACCONTROL_CLEAR_WAKE (0xFBFFFFFF) -#define PMU_MINRESMASK (PMU_BASE_ADDRESS + 0x618) -#define DEFAULT_43012_MIN_RES_MASK 0x0f8bfe77 +#define D11_MACCONTROL_REG D11REG_ADDR(0x120) +#define D11_MACCONTROL_REG_SIZE 4 +#define D11_MACCONTROL_REG_WAKE (1 << 26) +#define D11_MACCONTROL_CLEAR_WAKE (0xFBFFFFFF) +#define PMU_MINRESMASK (PMU_BASE_ADDRESS + 0x618) +#define DEFAULT_43012_MIN_RES_MASK 0x0f8bfe77 /* Backplane architecture */ -#define CHIPCOMMON_BASE_ADDRESS 0x18000000 /* Chipcommon core register region */ -#define I2S0_BASE_ADDRESS 0x18001000 /* I2S0 core register region */ -#define I2S1_BASE_ADDRESS 0x18002000 /* I2S1 core register region */ -#define APPS_ARMCR4_BASE_ADDRESS 0x18003000 /* Apps Cortex-R4 core register region */ -#define DMA_BASE_ADDRESS 0x18004000 /* DMA core register region */ -#define GMAC_BASE_ADDRESS 0x18005000 /* GMAC core register region */ -#define USB20H0_BASE_ADDRESS 0x18006000 /* USB20H0 core register region */ -#define USB20D_BASE_ADDRESS 0x18007000 /* USB20D core register region */ -#define SDIOH_BASE_ADDRESS 0x18008000 /* SDIOH Device core register region */ +#define CHIPCOMMON_BASE_ADDRESS 0x18000000 /* Chipcommon core register region */ +#define I2S0_BASE_ADDRESS 0x18001000 /* I2S0 core register region */ +#define I2S1_BASE_ADDRESS 0x18002000 /* I2S1 core register region */ +#define APPS_ARMCR4_BASE_ADDRESS 0x18003000 /* Apps Cortex-R4 core register region */ +#define DMA_BASE_ADDRESS 0x18004000 /* DMA core register region */ +#define GMAC_BASE_ADDRESS 0x18005000 /* GMAC core register region */ +#define USB20H0_BASE_ADDRESS 0x18006000 /* USB20H0 core register region */ +#define USB20D_BASE_ADDRESS 0x18007000 /* USB20D core register region */ +#define SDIOH_BASE_ADDRESS 0x18008000 /* SDIOH Device core register region */ #define DOT11MAC_BASE_ADDRESS 0x18001000 -#define BACKPLANE_ADDRESS_MASK 0x7FFF -#define BACKPLANE_WINDOW_SIZE (BACKPLANE_ADDRESS_MASK + 1) +#define BACKPLANE_ADDRESS_MASK 0x7FFF +#define BACKPLANE_WINDOW_SIZE (BACKPLANE_ADDRESS_MASK + 1) -#define CHIP_STA_INTERFACE 0 -#define CHIP_AP_INTERFACE 1 -#define CHIP_P2P_INTERFACE 2 +#define CHIP_STA_INTERFACE 0 +#define CHIP_AP_INTERFACE 1 +#define CHIP_P2P_INTERFACE 2 /* Chipcommon registers */ -#define CHIPCOMMON_CORE_CAPEXT_ADDR ((uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x64c)) -#define CHIPCOMMON_CORE_CAPEXT_SR_SUPPORTED ((uint32_t)(1 << 1)) -#define CHIPCOMMON_CORE_RCTL_LOGIC_DISABLE ((uint32_t)(1 << 27)) -#define CHIPCOMMON_CORE_RCTL_MACPHY_DISABLE ((uint32_t)(1 << 26)) -#define CHIPCOMMON_CORE_RETENTION_CTL ((uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x670)) +#define CHIPCOMMON_CORE_CAPEXT_ADDR ( (uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x64c) ) +#define CHIPCOMMON_CORE_CAPEXT_SR_SUPPORTED ( (uint32_t)(1 << 1) ) +#define CHIPCOMMON_CORE_RCTL_LOGIC_DISABLE ( (uint32_t)(1 << 27) ) +#define CHIPCOMMON_CORE_RCTL_MACPHY_DISABLE ( (uint32_t)(1 << 26) ) +#define CHIPCOMMON_CORE_RETENTION_CTL ( (uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x670) ) -#define CHIPCOMMON_GPIO_CONTROL ((uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x6C)) -#define CHIPCOMMON_SR_CONTROL0 ((uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x504)) -#define CHIPCOMMON_SR_CONTROL1 ((uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x508)) +#define CHIPCOMMON_GPIO_CONTROL ( (uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x6C) ) +#define CHIPCOMMON_SR_CONTROL0 ( (uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x504) ) +#define CHIPCOMMON_SR_CONTROL1 ( (uint32_t)(CHIPCOMMON_BASE_ADDRESS + 0x508) ) /* SOCSRAM core registers */ -#define SOCSRAM_BANKX_INDEX(wd) ((uint32_t)(GET_C_VAR(wd, SOCSRAM_BASE_ADDRESS) + 0x10)) -#define SOCSRAM_BANKX_PDA(wd) ((uint32_t)(GET_C_VAR(wd, SOCSRAM_BASE_ADDRESS) + 0x44)) +#define SOCSRAM_BANKX_INDEX(wd) ( (uint32_t)(GET_C_VAR(wd, SOCSRAM_BASE_ADDRESS) + 0x10) ) +#define SOCSRAM_BANKX_PDA(wd) ( (uint32_t)(GET_C_VAR(wd, SOCSRAM_BASE_ADDRESS) + 0x44) ) /* PMU core registers */ -#define RETENTION_CTL(wd) ((uint32_t)(GET_C_VAR(wd, PMU_BASE_ADDRESS) + 0x670)) -#define RCTL_MACPHY_DISABLE ((uint32_t)(1 << 26)) -#define RCTL_LOGIC_DISABLE ((uint32_t)(1 << 27)) +#define RETENTION_CTL(wd) ( (uint32_t)(GET_C_VAR(wd, PMU_BASE_ADDRESS) + 0x670) ) +#define PMU_WATCHDOG(wd) ( (uint32_t)(GET_C_VAR(wd, PMU_BASE_ADDRESS) + 0x634) ) +#define RCTL_MACPHY_DISABLE ( (uint32_t)(1 << 26) ) +#define RCTL_LOGIC_DISABLE ( (uint32_t)(1 << 27) ) #ifdef __cplusplus } /* extern "C" */ diff --git a/wi-fi/whd/bus_protocols/whd_m2m.h b/wi-fi/whd/bus_protocols/whd_m2m.h new file mode 100644 index 00000000..34f04aed --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_m2m.h @@ -0,0 +1,114 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_M2M_H_ +#define INCLUDED_WHD_M2M_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * M2M Constants + ******************************************************/ +// GCI Registers +#define GCI_INT_MASK_REG 0x4fe40018 /* When the31st bit of this Reg is set, Doorbell Interrupts to the IP(BT/WLAN) are enabled */ +#define GCI_INT_STATUS_REG 0x4fe40014 /* Read Only Reg - 31st bit indicates a DB Interrupt to the BT is pending.If it is set, Indicates a WL2BT Doorbell Interrupt is pending */ +#define GCI_DB_INT_STATUS_REG 0x4fe4063c /* To check which DB interrupt is triggered by WLAN */ +#define GCI_DB_INT_MASK_REG 0x4fe40640 /* This register is writable by BT only and readable by both WLAN and BT. This register resets with BT reset */ + +/* DB Bits for Doorbell Interrupt Mask Register(GCI_DB_INT_MASK_REG) */ +#define GCI_H2D_SET_BIT_DB0 0x0001 +#define GCI_H2D_SET_BIT_DB1 0x0002 +#define GCI_H2D_SET_BIT_DB2 0x0004 +#define GCI_H2D_SET_BIT_DB3 0x0008 +#define GCI_H2D_SET_BIT_DB4 0x0010 +#define GCI_H2D_SET_BIT_DB5 0x0020 +#define GCI_H2D_SET_BIT_DB6 0x0040 +#define GCI_H2D_SET_BIT_DB7 0x0080 +#define GCI_H2D_SET_ALL_DB (GCI_H2D_SET_BIT_DB0 | GCI_H2D_SET_BIT_DB1 | GCI_H2D_SET_BIT_DB2 | \ + GCI_H2D_SET_BIT_DB3 | \ + GCI_H2D_SET_BIT_DB4 | GCI_H2D_SET_BIT_DB5 | GCI_H2D_SET_BIT_DB6 | \ + GCI_H2D_SET_BIT_DB7) + +/* These registers are writable by BT only and readable by both WLAN and BT. These registers reset with BT reset */ +#define GCI_BT2WL_DB0_REG 0x4fe4066c +#define GCI_BT2WL_DB1_REG 0x4fe40670 +#define GCI_BT2WL_DB2_REG 0x4fe40674 +#define GCI_BT2WL_DB3_REG 0x4fe40678 +#define GCI_BT2WL_DB4_REG 0x4fe4067c +#define GCI_BT2WL_DB5_REG 0x4fe40680 +#define GCI_BT2WL_DB6_REG 0x4fe40684 +#define GCI_BT2WL_DB7_REG 0x4fe40688 + +/* These registers are writable by WLAN only and readable by both WLAN and BT. These registers reset with WLAN reset */ +#define GCI_WL2BT_DB0_REG 0x4fe40644 +#define GCI_WL2BT_DB1_REG 0x4fe40648 +#define GCI_WL2BT_DB2_REG 0x4fe4064c +#define GCI_WL2BT_DB3_REG 0x4fe40650 +#define GCI_WL2BT_DB4_REG 0x4fe40654 +#define GCI_WL2BT_DB5_REG 0x4fe40658 +#define GCI_WL2BT_DB6_REG 0x4fe4065c +#define GCI_WL2BT_DB7_REG 0x4fe40660 + +/* These register readable by both WLAN and BT. These registers reset with WLAN reset. */ +#define GCI_WL2BT_CLOCK_CSR 0x4fe406A0 + +/* These register readable by both WLAN and BT. These registers reset with BT reset. */ +#define GCI_BT2WL_CLOCK_CSR 0x4fe406A4 + +/* The final control value is OR of individual values from each IP's register */ +#define GCI_CTSS_CLOCK_CSR 0x4fe40700 + +/* GCI_CHIP_CLOCK_CSR Bits */ +#define GCI_FORCE_ALP ( (uint32_t)0x01 ) /* Force ALP request to backplane */ +#define GCI_FORCE_HT ( (uint32_t)0x02 ) /* Force HT request to backplane */ +#define GCI_FORCE_ILP ( (uint32_t)0x04 ) /* Force ILP request to backplane */ +#define GCI_ALP_AVAIL_REQ ( (uint32_t)0x08 ) /* Make ALP ready (power up xtal) */ +#define GCI_HT_AVAIL_REQ ( (uint32_t)0x10 ) /* Make HT ready (power up PLL) */ +#define GCI_FORCE_HW_CLKREQ_OFF ( (uint32_t)0x20 ) /* Squelch clock requests from HW */ +#define GCI_ALP_AVAIL ( (uint32_t)0x10000 ) /* Status: ALP is ready */ +#define GCI_HT_AVAIL ( (uint32_t)0x20000 ) /* Status: HT is ready */ +#define GCI_BT_ON_ALP ( (uint32_t)0x40000 ) +#define GCI_BT_ON_HT ( (uint32_t)0x80000 ) + +/* Hatchet1-CP(through GCI) Security Handshake Register */ +#define M2M_REG_DAR_H2D_MSG_0 0x4fe40634 +#define M2M_REG_DAR_D2H_MSG_0 0x4fe4062c +#define M2M_REG_DAR_SC0_MSG_0 0x4fe40628 + +/* Bootloader handshake flags - dongle to host */ +#define M2M_BLHS_D2H_START (1 << 0) +#define M2M_BLHS_D2H_READY (1 << 1) +#define M2M_BLHS_D2H_STEADY (1 << 2) +#define M2M_BLHS_D2H_TRXHDR_PARSE_DONE (1 << 3) +#define M2M_BLHS_D2H_VALDN_START (1 << 4) +#define M2M_BLHS_D2H_VALDN_RESULT (1 << 5) +#define M2M_BLHS_D2H_VALDN_DONE (1 << 6) + +/* Bootloader handshake flags - host to dongle */ +#define M2M_BLHS_H2D_BL_INIT 0 +#define M2M_BLHS_H2D_DL_FW_START (1 << 0) +#define M2M_BLHS_H2D_DL_FW_DONE (1 << 1) +#define M2M_BLHS_H2D_DL_NVRAM_DONE (1 << 2) +#define M2M_BLHS_H2D_BL_RESET_ON_ERROR (1 << 3) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef INCLUDED_WHD_M2M_H_ */ diff --git a/wi-fi/whd/bus_protocols/whd_sdio.h b/wi-fi/whd/bus_protocols/whd_sdio.h index ad940df9..b004e111 100644 --- a/wi-fi/whd/bus_protocols/whd_sdio.h +++ b/wi-fi/whd/bus_protocols/whd_sdio.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,64 +28,65 @@ extern "C" { /* CurrentSdiodProgGuide r23 */ /* Base registers */ -#define SDIO_CORE(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x00)) -#define SDIO_INT_STATUS(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x20)) -#define SDIO_TO_SB_MAILBOX(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x40)) -#define SDIO_TO_SB_MAILBOX_DATA(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x48)) -#define SDIO_TO_HOST_MAILBOX_DATA(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x4C)) -#define SDIO_INT_HOST_MASK(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x24)) -#define SDIO_FUNCTION_INT_MASK(wd) ((uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x34)) +#define SDIO_CORE(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x00) ) +#define SDIO_INT_STATUS(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x20) ) +#define SDIO_TO_SB_MAILBOX(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x40) ) +#define SDIO_TO_SB_MAILBOX_DATA(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x48) ) +#define SDIO_TO_HOST_MAILBOX_DATA(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x4C) ) +#define SDIO_INT_HOST_MASK(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x24) ) +#define SDIO_FUNCTION_INT_MASK(wd) ( (uint32_t)(GET_C_VAR(wd, SDIOD_CORE_BASE_ADDRESS) + 0x34) ) /* SDIO Function 0 (SDIO Bus) register addresses */ /* SDIO Device CCCR (Card Common Control Register) offsets */ /* CCCR accesses do not require backpane clock */ -#define SDIOD_CCCR_REV ((uint32_t)0x00) /* CCCR/SDIO Revision */ -#define SDIOD_CCCR_SDREV ((uint32_t)0x01) /* SD Revision */ -#define SDIOD_CCCR_IOEN ((uint32_t)0x02) /* I/O Enable */ -#define SDIOD_CCCR_IORDY ((uint32_t)0x03) /* I/O Ready */ -#define SDIOD_CCCR_INTEN ((uint32_t)0x04) /* Interrupt Enable */ -#define SDIOD_CCCR_INTPEND ((uint32_t)0x05) /* Interrupt Pending */ -#define SDIOD_CCCR_IOABORT ((uint32_t)0x06) /* I/O Abort */ -#define SDIOD_CCCR_BICTRL ((uint32_t)0x07) /* Bus Interface control */ -#define SDIOD_CCCR_CAPABLITIES ((uint32_t)0x08) /* Card Capabilities */ -#define SDIOD_CCCR_CISPTR_0 ((uint32_t)0x09) /* Common CIS Base Address Pointer Register 0 (LSB) */ -#define SDIOD_CCCR_CISPTR_1 ((uint32_t)0x0A) /* Common CIS Base Address Pointer Register 1 */ -#define SDIOD_CCCR_CISPTR_2 ((uint32_t)0x0B) /* Common CIS Base Address Pointer Register 2 (MSB - only bit 1 valid)*/ -#define SDIOD_CCCR_BUSSUSP ((uint32_t)0x0C) /* Bus Suspend. Valid only if SBS is set */ -#define SDIOD_CCCR_FUNCSEL ((uint32_t)0x0D) /* Function Select. Valid only if SBS is set */ -#define SDIOD_CCCR_EXECFLAGS ((uint32_t)0x0E) /* Exec Flags. Valid only if SBS is set */ -#define SDIOD_CCCR_RDYFLAGS ((uint32_t)0x0F) /* Ready Flags. Valid only if SBS is set */ -#define SDIOD_CCCR_BLKSIZE_0 ((uint32_t)0x10) /* Function 0 (Bus) SDIO Block Size Register 0 (LSB) */ -#define SDIOD_CCCR_BLKSIZE_1 ((uint32_t)0x11) /* Function 0 (Bus) SDIO Block Size Register 1 (MSB) */ -#define SDIOD_CCCR_POWER_CONTROL ((uint32_t)0x12) /* Power Control */ -#define SDIOD_CCCR_SPEED_CONTROL ((uint32_t)0x13) /* Bus Speed Select (control device entry into high-speed clocking mode) */ -#define SDIOD_CCCR_UHS_I ((uint32_t)0x14) /* UHS-I Support */ -#define SDIOD_CCCR_DRIVE ((uint32_t)0x15) /* Drive Strength */ -#define SDIOD_CCCR_INTEXT ((uint32_t)0x16) /* Interrupt Extension */ -#define SDIOD_CCCR_BRCM_CARDCAP ((uint32_t)0xF0) /* Brcm Card Capability */ -#define SDIOD_SEP_INT_CTL ((uint32_t)0xF2) /* Separate Interrupt Control*/ -#define SDIOD_CCCR_F1INFO ((uint32_t)0x100) /* Function 1 (Backplane) Info */ -#define SDIOD_CCCR_F1HP ((uint32_t)0x102) /* Function 1 (Backplane) High Power */ -#define SDIOD_CCCR_F1CISPTR_0 ((uint32_t)0x109) /* Function 1 (Backplane) CIS Base Address Pointer Register 0 (LSB) */ -#define SDIOD_CCCR_F1CISPTR_1 ((uint32_t)0x10A) /* Function 1 (Backplane) CIS Base Address Pointer Register 1 */ -#define SDIOD_CCCR_F1CISPTR_2 ((uint32_t)0x10B) /* Function 1 (Backplane) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ -#define SDIOD_CCCR_F1BLKSIZE_0 ((uint32_t)0x110) /* Function 1 (Backplane) SDIO Block Size Register 0 (LSB) */ -#define SDIOD_CCCR_F1BLKSIZE_1 ((uint32_t)0x111) /* Function 1 (Backplane) SDIO Block Size Register 1 (MSB) */ -#define SDIOD_CCCR_F2INFO ((uint32_t)0x200) /* Function 2 (WLAN Data FIFO) Info */ -#define SDIOD_CCCR_F2HP ((uint32_t)0x202) /* Function 2 (WLAN Data FIFO) High Power */ -#define SDIOD_CCCR_F2CISPTR_0 ((uint32_t)0x209) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 0 (LSB) */ -#define SDIOD_CCCR_F2CISPTR_1 ((uint32_t)0x20A) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 1 */ -#define SDIOD_CCCR_F2CISPTR_2 ((uint32_t)0x20B) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ -#define SDIOD_CCCR_F2BLKSIZE_0 ((uint32_t)0x210) /* Function 2 (WLAN Data FIFO) SDIO Block Size Register 0 (LSB) */ -#define SDIOD_CCCR_F2BLKSIZE_1 ((uint32_t)0x211) /* Function 2 (WLAN Data FIFO) SDIO Block Size Register 1 (MSB) */ -#define SDIOD_CCCR_F3INFO ((uint32_t)0x300) /* Function 3 (Bluetooth Data FIFO) Info */ -#define SDIOD_CCCR_F3HP ((uint32_t)0x302) /* Function 3 (Bluetooth Data FIFO) High Power */ -#define SDIOD_CCCR_F3CISPTR_0 ((uint32_t)0x309) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 0 (LSB) */ -#define SDIOD_CCCR_F3CISPTR_1 ((uint32_t)0x30A) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 1 */ -#define SDIOD_CCCR_F3CISPTR_2 ((uint32_t)0x30B) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ -#define SDIOD_CCCR_F3BLKSIZE_0 ((uint32_t)0x310) /* Function 3 (Bluetooth Data FIFO) SDIO Block Size Register 0 (LSB) */ -#define SDIOD_CCCR_F3BLKSIZE_1 ((uint32_t)0x311) /* Function 3 (Bluetooth Data FIFO) SDIO Block Size Register 1 (MSB) */ +#define SDIOD_CCCR_REV ( (uint32_t)0x00 ) /* CCCR/SDIO Revision */ +#define SDIOD_CCCR_SDREV ( (uint32_t)0x01 ) /* SD Revision */ +#define SDIOD_CCCR_IOEN ( (uint32_t)0x02 ) /* I/O Enable */ +#define SDIOD_CCCR_IORDY ( (uint32_t)0x03 ) /* I/O Ready */ +#define SDIOD_CCCR_INTEN ( (uint32_t)0x04 ) /* Interrupt Enable */ +#define SDIOD_CCCR_INTPEND ( (uint32_t)0x05 ) /* Interrupt Pending */ +#define SDIOD_CCCR_IOABORT ( (uint32_t)0x06 ) /* I/O Abort */ +#define SDIOD_CCCR_BICTRL ( (uint32_t)0x07 ) /* Bus Interface control */ +#define SDIOD_CCCR_CAPABLITIES ( (uint32_t)0x08 ) /* Card Capabilities */ +#define SDIOD_CCCR_CISPTR_0 ( (uint32_t)0x09 ) /* Common CIS Base Address Pointer Register 0 (LSB) */ +#define SDIOD_CCCR_CISPTR_1 ( (uint32_t)0x0A ) /* Common CIS Base Address Pointer Register 1 */ +#define SDIOD_CCCR_CISPTR_2 ( (uint32_t)0x0B ) /* Common CIS Base Address Pointer Register 2 (MSB - only bit 1 valid)*/ +#define SDIOD_CCCR_BUSSUSP ( (uint32_t)0x0C ) /* Bus Suspend. Valid only if SBS is set */ +#define SDIOD_CCCR_FUNCSEL ( (uint32_t)0x0D ) /* Function Select. Valid only if SBS is set */ +#define SDIOD_CCCR_EXECFLAGS ( (uint32_t)0x0E ) /* Exec Flags. Valid only if SBS is set */ +#define SDIOD_CCCR_RDYFLAGS ( (uint32_t)0x0F ) /* Ready Flags. Valid only if SBS is set */ +#define SDIOD_CCCR_BLKSIZE_0 ( (uint32_t)0x10 ) /* Function 0 (Bus) SDIO Block Size Register 0 (LSB) */ +#define SDIOD_CCCR_BLKSIZE_1 ( (uint32_t)0x11 ) /* Function 0 (Bus) SDIO Block Size Register 1 (MSB) */ +#define SDIOD_CCCR_POWER_CONTROL ( (uint32_t)0x12 ) /* Power Control */ +#define SDIOD_CCCR_SPEED_CONTROL ( (uint32_t)0x13 ) /* Bus Speed Select (control device entry into high-speed clocking mode) */ +#define SDIOD_CCCR_UHS_I ( (uint32_t)0x14 ) /* UHS-I Support */ +#define SDIOD_CCCR_DRIVE ( (uint32_t)0x15 ) /* Drive Strength */ +#define SDIOD_CCCR_INTEXT ( (uint32_t)0x16 ) /* Interrupt Extension */ +#define SDIOD_CCCR_BRCM_CARDCAP ( (uint32_t)0xF0 ) /* Brcm Card Capability */ +#define SDIOD_CCCR_BRCM_CARDCTL ( (uint32_t)0xF1 ) /* Brcm Card Control */ +#define SDIOD_SEP_INT_CTL ( (uint32_t)0xF2 ) /* Separate Interrupt Control*/ +#define SDIOD_CCCR_F1INFO ( (uint32_t)0x100 ) /* Function 1 (Backplane) Info */ +#define SDIOD_CCCR_F1HP ( (uint32_t)0x102 ) /* Function 1 (Backplane) High Power */ +#define SDIOD_CCCR_F1CISPTR_0 ( (uint32_t)0x109 ) /* Function 1 (Backplane) CIS Base Address Pointer Register 0 (LSB) */ +#define SDIOD_CCCR_F1CISPTR_1 ( (uint32_t)0x10A ) /* Function 1 (Backplane) CIS Base Address Pointer Register 1 */ +#define SDIOD_CCCR_F1CISPTR_2 ( (uint32_t)0x10B ) /* Function 1 (Backplane) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ +#define SDIOD_CCCR_F1BLKSIZE_0 ( (uint32_t)0x110 ) /* Function 1 (Backplane) SDIO Block Size Register 0 (LSB) */ +#define SDIOD_CCCR_F1BLKSIZE_1 ( (uint32_t)0x111 ) /* Function 1 (Backplane) SDIO Block Size Register 1 (MSB) */ +#define SDIOD_CCCR_F2INFO ( (uint32_t)0x200 ) /* Function 2 (WLAN Data FIFO) Info */ +#define SDIOD_CCCR_F2HP ( (uint32_t)0x202 ) /* Function 2 (WLAN Data FIFO) High Power */ +#define SDIOD_CCCR_F2CISPTR_0 ( (uint32_t)0x209 ) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 0 (LSB) */ +#define SDIOD_CCCR_F2CISPTR_1 ( (uint32_t)0x20A ) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 1 */ +#define SDIOD_CCCR_F2CISPTR_2 ( (uint32_t)0x20B ) /* Function 2 (WLAN Data FIFO) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ +#define SDIOD_CCCR_F2BLKSIZE_0 ( (uint32_t)0x210 ) /* Function 2 (WLAN Data FIFO) SDIO Block Size Register 0 (LSB) */ +#define SDIOD_CCCR_F2BLKSIZE_1 ( (uint32_t)0x211 ) /* Function 2 (WLAN Data FIFO) SDIO Block Size Register 1 (MSB) */ +#define SDIOD_CCCR_F3INFO ( (uint32_t)0x300 ) /* Function 3 (Bluetooth Data FIFO) Info */ +#define SDIOD_CCCR_F3HP ( (uint32_t)0x302 ) /* Function 3 (Bluetooth Data FIFO) High Power */ +#define SDIOD_CCCR_F3CISPTR_0 ( (uint32_t)0x309 ) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 0 (LSB) */ +#define SDIOD_CCCR_F3CISPTR_1 ( (uint32_t)0x30A ) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 1 */ +#define SDIOD_CCCR_F3CISPTR_2 ( (uint32_t)0x30B ) /* Function 3 (Bluetooth Data FIFO) CIS Base Address Pointer Register 2 (MSB - only bit 1 valid) */ +#define SDIOD_CCCR_F3BLKSIZE_0 ( (uint32_t)0x310 ) /* Function 3 (Bluetooth Data FIFO) SDIO Block Size Register 0 (LSB) */ +#define SDIOD_CCCR_F3BLKSIZE_1 ( (uint32_t)0x311 ) /* Function 3 (Bluetooth Data FIFO) SDIO Block Size Register 1 (MSB) */ /* SDIO Function 1 (Backplane) register addresses */ @@ -94,143 +95,207 @@ extern "C" { * registers relating to backplane access, and do not require a backpane * clock to access them */ -#define SDIO_GPIO_SELECT ((uint32_t)0x10005) -#define SDIO_GPIO_OUTPUT ((uint32_t)0x10006) -#define SDIO_GPIO_ENABLE ((uint32_t)0x10007) -#define SDIO_FUNCTION2_WATERMARK ((uint32_t)0x10008) -#define SDIO_DEVICE_CONTROL ((uint32_t)0x10009) -#define SDIO_BACKPLANE_ADDRESS_LOW ((uint32_t)0x1000A) -#define SDIO_BACKPLANE_ADDRESS_MID ((uint32_t)0x1000B) -#define SDIO_BACKPLANE_ADDRESS_HIGH ((uint32_t)0x1000C) -#define SDIO_FRAME_CONTROL ((uint32_t)0x1000D) -#define SDIO_CHIP_CLOCK_CSR ((uint32_t)0x1000E) -#define SDIO_PULL_UP ((uint32_t)0x1000F) -#define SDIO_READ_FRAME_BC_LOW ((uint32_t)0x1001B) -#define SDIO_READ_FRAME_BC_HIGH ((uint32_t)0x1001C) -#define SDIO_WAKEUP_CTRL ((uint32_t)0x1001E) -#define SDIO_SLEEP_CSR ((uint32_t)0x1001F) -#define I_HMB_SW_MASK ((uint32_t)0x000000F0) -#define I_HMB_FRAME_IND (1 << 6) -#define I_HMB_HOST_INT (1 << 7) -#define I_HMB_FC_CHANGE (1 << 5) -#define FRAME_AVAILABLE_MASK I_HMB_SW_MASK +#define SDIO_GPIO_SELECT ( (uint32_t)0x10005 ) +#define SDIO_GPIO_OUTPUT ( (uint32_t)0x10006 ) +#define SDIO_GPIO_ENABLE ( (uint32_t)0x10007 ) +#define SDIO_FUNCTION2_WATERMARK ( (uint32_t)0x10008 ) +#define SDIO_DEVICE_CONTROL ( (uint32_t)0x10009 ) +#define SDIO_BACKPLANE_ADDRESS_LOW ( (uint32_t)0x1000A ) +#define SDIO_BACKPLANE_ADDRESS_MID ( (uint32_t)0x1000B ) +#define SDIO_BACKPLANE_ADDRESS_HIGH ( (uint32_t)0x1000C ) +#define SDIO_FRAME_CONTROL ( (uint32_t)0x1000D ) +#define SDIO_CHIP_CLOCK_CSR ( (uint32_t)0x1000E ) +#define SDIO_PULL_UP ( (uint32_t)0x1000F ) +#define SDIO_READ_FRAME_BC_LOW ( (uint32_t)0x1001B ) +#define SDIO_READ_FRAME_BC_HIGH ( (uint32_t)0x1001C ) +#define SDIO_WAKEUP_CTRL ( (uint32_t)0x1001E ) +#define SDIO_SLEEP_CSR ( (uint32_t)0x1001F ) +#define I_HMB_SW_MASK ( (uint32_t)0x000000F0 ) + +#define I_HMB_FC_STATE (1 << 4) +#define I_HMB_FC_CHANGE (1 << 5) +#define I_HMB_FRAME_IND (1 << 6) +#define I_HMB_HOST_INT (1 << 7) + +#define FRAME_AVAILABLE_MASK I_HMB_SW_MASK + +#define SDIOD_CCCR_INTPEND_INT1 0x02 /****************************************************** * Bit Masks ******************************************************/ /* SDIOD_CCCR_REV Bits */ -#define SDIO_REV_SDIOID_MASK ((uint32_t)0xF0) /* SDIO spec revision number */ -#define SDIO_REV_CCCRID_MASK ((uint32_t)0x0F) /* CCCR format version number */ +#define SDIO_REV_SDIOID_MASK ( (uint32_t)0xF0 ) /* SDIO spec revision number */ +#define SDIO_REV_CCCRID_MASK ( (uint32_t)0x0F ) /* CCCR format version number */ /* SDIOD_CCCR_SDREV Bits */ -#define SD_REV_PHY_MASK ((uint32_t)0x0F) /* SD format version number */ +#define SD_REV_PHY_MASK ( (uint32_t)0x0F ) /* SD format version number */ /* SDIOD_CCCR_IOEN Bits */ -#define SDIO_FUNC_ENABLE_1 ((uint32_t)0x02) /* function 1 I/O enable */ -#define SDIO_FUNC_ENABLE_2 ((uint32_t)0x04) /* function 2 I/O enable */ -#define SDIO_FUNC_ENABLE_3 ((uint32_t)0x08) /* function 3 I/O enable */ +#define SDIO_FUNC_ENABLE_1 ( (uint32_t)0x02 ) /* function 1 I/O enable */ +#define SDIO_FUNC_ENABLE_2 ( (uint32_t)0x04 ) /* function 2 I/O enable */ +#define SDIO_FUNC_ENABLE_3 ( (uint32_t)0x08 ) /* function 3 I/O enable */ /* SDIOD_CCCR_IORDY Bits */ -#define SDIO_FUNC_READY_1 ((uint32_t)0x02) /* function 1 I/O ready */ -#define SDIO_FUNC_READY_2 ((uint32_t)0x04) /* function 2 I/O ready */ -#define SDIO_FUNC_READY_3 ((uint32_t)0x08) /* function 3 I/O ready */ +#define SDIO_FUNC_READY_1 ( (uint32_t)0x02 ) /* function 1 I/O ready */ +#define SDIO_FUNC_READY_2 ( (uint32_t)0x04 ) /* function 2 I/O ready */ +#define SDIO_FUNC_READY_3 ( (uint32_t)0x08 ) /* function 3 I/O ready */ /* SDIOD_CCCR_INTEN Bits */ -#define INTR_CTL_MASTER_EN ((uint32_t)0x01) /* interrupt enable master */ -#define INTR_CTL_FUNC1_EN ((uint32_t)0x02) /* interrupt enable for function 1 */ -#define INTR_CTL_FUNC2_EN ((uint32_t)0x04) /* interrupt enable for function 2 */ +#define INTR_CTL_MASTER_EN ( (uint32_t)0x01 ) /* interrupt enable master */ +#define INTR_CTL_FUNC1_EN ( (uint32_t)0x02 ) /* interrupt enable for function 1 */ +#define INTR_CTL_FUNC2_EN ( (uint32_t)0x04 ) /* interrupt enable for function 2 */ /* SDIOD_SEP_INT_CTL Bits */ -#define SEP_INTR_CTL_MASK ((uint32_t)0x01) /* out-of-band interrupt mask */ -#define SEP_INTR_CTL_EN ((uint32_t)0x02) /* out-of-band interrupt output enable */ -#define SEP_INTR_CTL_POL ((uint32_t)0x04) /* out-of-band interrupt polarity */ +#define SEP_INTR_CTL_MASK ( (uint32_t)0x01 ) /* out-of-band interrupt mask */ +#define SEP_INTR_CTL_EN ( (uint32_t)0x02 ) /* out-of-band interrupt output enable */ +#define SEP_INTR_CTL_POL ( (uint32_t)0x04 ) /* out-of-band interrupt polarity */ /* SDIOD_CCCR_INTPEND Bits */ -#define INTR_STATUS_FUNC1 ((uint32_t)0x02) /* interrupt pending for function 1 */ -#define INTR_STATUS_FUNC2 ((uint32_t)0x04) /* interrupt pending for function 2 */ -#define INTR_STATUS_FUNC3 ((uint32_t)0x08) /* interrupt pending for function 3 */ +#define INTR_STATUS_FUNC1 ( (uint32_t)0x02 ) /* interrupt pending for function 1 */ +#define INTR_STATUS_FUNC2 ( (uint32_t)0x04 ) /* interrupt pending for function 2 */ +#define INTR_STATUS_FUNC3 ( (uint32_t)0x08 ) /* interrupt pending for function 3 */ /* SDIOD_CCCR_IOABORT Bits */ #define IO_ABORT_RESET_ALL ((uint32_t)0x08) /* I/O card reset */ #define IO_ABORT_FUNC_MASK ((uint32_t)0x07) /* abort selection: function x */ /* SDIOD_CCCR_BICTRL Bits */ -#define BUS_CARD_DETECT_DIS ((uint32_t)0x80) /* Card Detect disable */ -#define BUS_SPI_CONT_INTR_CAP ((uint32_t)0x40) /* support continuous SPI interrupt */ -#define BUS_SPI_CONT_INTR_EN ((uint32_t)0x20) /* continuous SPI interrupt enable */ -#define BUS_SD_DATA_WIDTH_MASK ((uint32_t)0x03) /* bus width mask */ -#define BUS_SD_DATA_WIDTH_4BIT ((uint32_t)0x02) /* bus width 4-bit mode */ -#define BUS_SD_DATA_WIDTH_1BIT ((uint32_t)0x00) /* bus width 1-bit mode */ +#define BUS_CARD_DETECT_DIS ( (uint32_t)0x80 ) /* Card Detect disable */ +#define BUS_SPI_CONT_INTR_CAP ( (uint32_t)0x40 ) /* support continuous SPI interrupt */ +#define BUS_SPI_CONT_INTR_EN ( (uint32_t)0x20 ) /* continuous SPI interrupt enable */ +#define BUS_SD_DATA_WIDTH_MASK ( (uint32_t)0x03 ) /* bus width mask */ +#define BUS_SD_DATA_WIDTH_4BIT ( (uint32_t)0x02 ) /* bus width 4-bit mode */ +#define BUS_SD_DATA_WIDTH_1BIT ( (uint32_t)0x00 ) /* bus width 1-bit mode */ /* SDIOD_CCCR_CAPABLITIES Bits */ -#define SDIO_CAP_4BLS ((uint32_t)0x80) /* 4-bit support for low speed card */ -#define SDIO_CAP_LSC ((uint32_t)0x40) /* low speed card */ -#define SDIO_CAP_E4MI ((uint32_t)0x20) /* enable interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_S4MI ((uint32_t)0x10) /* support interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_SBS ((uint32_t)0x08) /* support suspend/resume */ -#define SDIO_CAP_SRW ((uint32_t)0x04) /* support read wait */ -#define SDIO_CAP_SMB ((uint32_t)0x02) /* support multi-block transfer */ -#define SDIO_CAP_SDC ((uint32_t)0x01) /* Support Direct commands during multi-byte transfer */ +#define SDIO_CAP_4BLS ( (uint32_t)0x80 ) /* 4-bit support for low speed card */ +#define SDIO_CAP_LSC ( (uint32_t)0x40 ) /* low speed card */ +#define SDIO_CAP_E4MI ( (uint32_t)0x20 ) /* enable interrupt between block of data in 4-bit mode */ +#define SDIO_CAP_S4MI ( (uint32_t)0x10 ) /* support interrupt between block of data in 4-bit mode */ +#define SDIO_CAP_SBS ( (uint32_t)0x08 ) /* support suspend/resume */ +#define SDIO_CAP_SRW ( (uint32_t)0x04 ) /* support read wait */ +#define SDIO_CAP_SMB ( (uint32_t)0x02 ) /* support multi-block transfer */ +#define SDIO_CAP_SDC ( (uint32_t)0x01 ) /* Support Direct commands during multi-byte transfer */ /* SDIOD_CCCR_POWER_CONTROL Bits */ -#define SDIO_POWER_SMPC ((uint32_t)0x01) /* supports master power control (RO) */ -#define SDIO_POWER_EMPC ((uint32_t)0x02) /* enable master power control (allow > 200mA) (RW) */ +#define SDIO_POWER_SMPC ( (uint32_t)0x01 ) /* supports master power control (RO) */ +#define SDIO_POWER_EMPC ( (uint32_t)0x02 ) /* enable master power control (allow > 200mA) (RW) */ /* SDIOD_CCCR_SPEED_CONTROL Bits */ -#define SDIO_SPEED_SHS ((uint32_t)0x01) /* supports high-speed [clocking] mode (RO) */ -#define SDIO_SPEED_EHS ((uint32_t)0x02) /* enable high-speed [clocking] mode (RW) */ +#define SDIO_SPEED_SHS ( (uint32_t)0x01 ) /* supports high-speed [clocking] mode (RO) */ +#define SDIO_SPEED_EHS ( (uint32_t)0x02 ) /* enable high-speed [clocking] mode (RW) */ /* SDIOD_CCCR_BRCM_CARDCAP Bits */ -#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT ((uint32_t)0x02) /* Supports CMD14 */ -#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT ((uint32_t)0x04) /* CMD14 is allowed in FSM command state */ -#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC ((uint32_t)0x08) /* sdiod_aos does not decode any command */ +#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT ( (uint32_t)0x02 ) /* Supports CMD14 */ +#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT ( (uint32_t)0x04 ) /* CMD14 is allowed in FSM command state */ +#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC ( (uint32_t)0x08 ) /* sdiod_aos does not decode any command */ +#define SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE ( (uint32_t)0x80 ) /* Supports bootloader security */ +#define SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT ( (uint32_t)0x40 ) /* Supports Chip ID Read from SDIO Core */ + +#define SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT ( (uint32_t)0x02 ) /* SDIO_FUNCTION_INT_MASK Bits*/ -#define SDIO_FUNC_MASK_F1 ((uint32_t)0x01) /* interrupt mask enable for function 1 */ -#define SDIO_FUNC_MASK_F2 ((uint32_t)0x02) /* interrupt mask enable for function 2 */ +#define SDIO_FUNC_MASK_F1 ( (uint32_t)0x01 ) /* interrupt mask enable for function 1 */ +#define SDIO_FUNC_MASK_F2 ( (uint32_t)0x02 ) /* interrupt mask enable for function 2 */ /* SDIO_DEVICE_CONTROL Bits */ -#define SDIO_DATA_PAD_ISO ((uint32_t)0x08) /* isolate internal SDIO data bus signals */ +#define SDIO_DATA_PAD_ISO ( (uint32_t)0x08 ) /* isolate internal SDIO data bus signals */ + +/* SDIO CORE CHIPID REGISTER */ +#define SDIO_CORE_CHIPID_REG ( (uint32_t)0x330 ) /* SDIO_CHIP_CLOCK_CSR Bits */ -#define SBSDIO_FORCE_ALP ((uint32_t)0x01) /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT ((uint32_t)0x02) /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP ((uint32_t)0x04) /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ ((uint32_t)0x08) /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ ((uint32_t)0x10) /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF ((uint32_t)0x20) /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL ((uint32_t)0x40) /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL ((uint32_t)0x80) /* Status: HT is ready */ -#define SBSDIO_Rev8_HT_AVAIL ((uint32_t)0x40) -#define SBSDIO_Rev8_ALP_AVAIL ((uint32_t)0x80) +#define SBSDIO_FORCE_ALP ( (uint32_t)0x01 ) /* Force ALP request to backplane */ +#define SBSDIO_FORCE_HT ( (uint32_t)0x02 ) /* Force HT request to backplane */ +#define SBSDIO_FORCE_ILP ( (uint32_t)0x04 ) /* Force ILP request to backplane */ +#define SBSDIO_ALP_AVAIL_REQ ( (uint32_t)0x08 ) /* Make ALP ready (power up xtal) */ +#define SBSDIO_HT_AVAIL_REQ ( (uint32_t)0x10 ) /* Make HT ready (power up PLL) */ +#define SBSDIO_FORCE_HW_CLKREQ_OFF ( (uint32_t)0x20 ) /* Squelch clock requests from HW */ +#define SBSDIO_ALP_AVAIL ( (uint32_t)0x40 ) /* Status: ALP is ready */ +#define SBSDIO_HT_AVAIL ( (uint32_t)0x80 ) /* Status: HT is ready */ +#define SBSDIO_Rev8_HT_AVAIL ( (uint32_t)0x40 ) +#define SBSDIO_Rev8_ALP_AVAIL ( (uint32_t)0x80 ) + +#define SBSDIO_FUNC1_SBADDRLOW ( (uint32_t)0x1000A ) /* SB Address Window Low (b15) */ +#define SBSDIO_FUNC1_SBADDRMID ( (uint32_t)0x1000B ) /* SB Address Window Mid (b23:b16) */ +#define SBSDIO_FUNC1_SBADDRHIGH ( (uint32_t)0x1000C ) /* SB Address Window High (b31:b24) */ +#define SBSDIO_DEVICE_CTL ( (uint32_t)0x10009 ) /* control busy signal generation */ +#define SBSDIO_DEVCTL_ADDR_RST ( (uint32_t)0x40 ) /* Reset SB Address to default value */ /* SDIO_FRAME_CONTROL Bits */ -#define SFC_RF_TERM ((uint32_t)(1 << 0)) /* Read Frame Terminate */ -#define SFC_WF_TERM ((uint32_t)(1 << 1)) /* Write Frame Terminate */ -#define SFC_CRC4WOOS ((uint32_t)(1 << 2)) /* HW reports CRC error for write out of sync */ -#define SFC_ABORTALL ((uint32_t)(1 << 3)) /* Abort cancels all in-progress frames */ +#define SFC_RF_TERM ( (uint32_t)(1 << 0) ) /* Read Frame Terminate */ +#define SFC_WF_TERM ( (uint32_t)(1 << 1) ) /* Write Frame Terminate */ +#define SFC_CRC4WOOS ( (uint32_t)(1 << 2) ) /* HW reports CRC error for write out of sync */ +#define SFC_ABORTALL ( (uint32_t)(1 << 3) ) /* Abort cancels all in-progress frames */ /* SDIO_TO_SB_MAILBOX bits corresponding to intstatus bits */ -#define SMB_NAK ((uint32_t)(1 << 0)) /* To SB Mailbox Frame NAK */ -#define SMB_INT_ACK ((uint32_t)(1 << 1)) /* To SB Mailbox Host Interrupt ACK */ -#define SMB_USE_OOB ((uint32_t)(1 << 2)) /* To SB Mailbox Use OOB Wakeup */ -#define SMB_DEV_INT ((uint32_t)(1 << 3)) /* To SB Mailbox Miscellaneous Interrupt */ +#define SMB_NAK ( (uint32_t)(1 << 0) ) /* To SB Mailbox Frame NAK */ +#define SMB_INT_ACK ( (uint32_t)(1 << 1) ) /* To SB Mailbox Host Interrupt ACK */ +#define SMB_USE_OOB ( (uint32_t)(1 << 2) ) /* To SB Mailbox Use OOB Wakeup */ +#define SMB_DEV_INT ( (uint32_t)(1 << 3) ) /* To SB Mailbox Miscellaneous Interrupt */ /* SDIO_WAKEUP_CTRL bits */ -#define SBSDIO_WCTRL_WAKE_TILL_ALP_AVAIL ((uint32_t)(1 << 0)) /* WakeTillAlpAvail bit */ -#define SBSDIO_WCTRL_WAKE_TILL_HT_AVAIL ((uint32_t)(1 << 1)) /* WakeTillHTAvail bit */ +#define SBSDIO_WCTRL_WL_WAKE_TILL_ALP_AVAIL ( (uint32_t)(1 << 0) ) /* WL_WakeTillAlpAvail bit */ +#define SBSDIO_WCTRL_WL_WAKE_TILL_HT_AVAIL ( (uint32_t)(1 << 1) ) /* WL_WakeTillHTAvail bit */ +/* Additional Bits in case of sdiorev31 */ +#define SBSDIO_WCTRL_BT_WAKE_TILL_ALP_AVAIL ( (uint32_t)(1 << 2) ) /* BT_WakeTillAlpAvail bit */ +#define SBSDIO_WCTRL_BT_WAKE_TILL_HT_AVAIL ( (uint32_t)(1 << 3) ) /* BT_WakeTillHTAvail bit */ +#define SBSDIO_WCTRL_WL_DISABLE_AUTOSET_KSO ( (uint32_t)(1 << 4) ) /* WL_DisableKSOAutoSet bit */ +#define SBSDIO_WCTRL_BT_DISABLE_AUTOSET_KSO ( (uint32_t)(1 << 5) ) /* BT_DisableKSOAutoSet bit */ /* SDIO_SLEEP_CSR bits */ -#define SBSDIO_SLPCSR_KEEP_SDIO_ON ((uint32_t)(1 << 0)) /* KeepSdioOn bit */ -#define SBSDIO_SLPCSR_DEVICE_ON ((uint32_t)(1 << 1)) /* DeviceOn bit */ +#define SBSDIO_SLPCSR_KEEP_WL_KSO ( (uint32_t)(1 << 0) ) +#define SBSDIO_SLPCSR_WL_DEVON ( (uint32_t)(1 << 1) ) +/* Additional Bits in case of sdiorev31 */ +#define SBSDIO_SLPCSR_KEEP_BT_KSO ( (uint32_t)(1 << 2) ) +#define SBSDIO_SLPCSR_BT_DEVON ( (uint32_t)(1 << 3) ) + +/* Sdio rev 27 only */ +#define SBSDIO_FUNC1_SECURE_MODE 0x10001 /* To read secure-mode bit */ /* To hostmail box data */ -#define I_HMB_DATA_NAKHANDLED 0x0001 /* retransmit NAK'd frame */ -#define I_HMB_DATA_DEVREADY 0x0002 /* talk to host after enable */ -#define I_HMB_DATA_FC 0x0004 /* per prio flowcontrol update flag */ -#define I_HMB_DATA_FWREADY 0x0008 /* fw ready for protocol activity */ -#define I_HMB_DATA_FWHALT 0x0010 /* firmware halted */ +#define I_HMB_DATA_NAKHANDLED 0x0001 /* retransmit NAK'd frame */ +#define I_HMB_DATA_DEVREADY 0x0002 /* talk to host after enable */ +#define I_HMB_DATA_FC 0x0004 /* per prio flowcontrol update flag */ +#define I_HMB_DATA_FWREADY 0x0008 /* fw ready for protocol activity */ +#define I_HMB_DATA_FWHALT 0x0010 /* firmware halted */ + +/* SDIO Security Handshake Register */ +#ifndef DM_43022C1 +#define SDIO_REG_DAR_H2D_MSG_0 0x10030 +#define SDIO_REG_DAR_D2H_MSG_0 0x10038 +#else +#define SDIO_REG_DAR_H2D_MSG_0 ( 0x18002000 + 0x48 ) +#define SDIO_REG_DAR_D2H_MSG_0 ( 0x18002000 + 0x4C ) +#endif + +#define SDIO_BLHS_D2H_TIMEOUT_MS 500 + +/* Bootloader handshake flags - dongle to host */ +#define SDIO_BLHS_D2H_START (1 << 0) +#define SDIO_BLHS_D2H_READY (1 << 1) +#define SDIO_BLHS_D2H_STEADY (1 << 2) +#define SDIO_BLHS_D2H_TRXHDR_PARSE_DONE (1 << 3) +#define SDIO_BLHS_D2H_VALDN_START (1 << 4) +#define SDIO_BLHS_D2H_VALDN_RESULT (1 << 5) +#define SDIO_BLHS_D2H_VALDN_DONE (1 << 6) +#define SDIO_BLHS_D2H_NVRAM_MV_DONE (1 << 7) +#ifdef DM_43022C1 +#define SDIO_BLHS_D2H_BP_CLK_DIS_REQ (1 << 8) +#endif + +/* Bootloader handshake flags - host to dongle */ +#define SDIO_BLHS_H2D_BL_INIT 0 +#define SDIO_BLHS_H2D_DL_FW_START (1 << 0) +#define SDIO_BLHS_H2D_DL_FW_DONE (1 << 1) +#define SDIO_BLHS_H2D_DL_NVRAM_DONE (1 << 2) +#define SDIO_BLHS_H2D_BL_RESET_ON_ERROR (1 << 3) +#ifdef DM_43022C1 +#define SDIO_BLHS_H2D_DL_NVRAM_START (1 << 4) +#define SDIO_BLHS_H2D_BP_CLK_DIS_ACK (1 << 5) +#endif #ifdef __cplusplus } /* extern "C" */ diff --git a/wi-fi/whd/bus_protocols/whd_spi.h b/wi-fi/whd/bus_protocols/whd_spi.h new file mode 100644 index 00000000..e86fa292 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_spi.h @@ -0,0 +1,121 @@ +/* + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_SPI_H_ +#define INCLUDED_WHD_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** +* SPI Constants +******************************************************/ +/* GSPI v1 */ +#define SPI_FRAME_CONTROL ( (uint32_t)0x1000D ) + +/* Register addresses */ +#define SPI_BUS_CONTROL ( (uint32_t)0x0000 ) +#define SPI_RESPONSE_DELAY ( (uint32_t)0x0001 ) +#define SPI_STATUS_ENABLE ( (uint32_t)0x0002 ) +#define SPI_RESET_BP ( (uint32_t)0x0003 ) /* (corerev >= 1) */ +#define SPI_INTERRUPT_REGISTER ( (uint32_t)0x0004 ) /* 16 bits - Interrupt status */ +#define SPI_INTERRUPT_ENABLE_REGISTER ( (uint32_t)0x0006 ) /* 16 bits - Interrupt mask */ +#define SPI_STATUS_REGISTER ( (uint32_t)0x0008 ) /* 32 bits */ +#define SPI_FUNCTION1_INFO ( (uint32_t)0x000C ) /* 16 bits */ +#define SPI_FUNCTION2_INFO ( (uint32_t)0x000E ) /* 16 bits */ +#define SPI_FUNCTION3_INFO ( (uint32_t)0x0010 ) /* 16 bits */ +#define SPI_READ_TEST_REGISTER ( (uint32_t)0x0014 ) /* 32 bits */ +#define SPI_RESP_DELAY_F0 ( (uint32_t)0x001c ) /* 8 bits (corerev >= 3) */ +#define SPI_RESP_DELAY_F1 ( (uint32_t)0x001d ) /* 8 bits (corerev >= 3) */ +#define SPI_RESP_DELAY_F2 ( (uint32_t)0x001e ) /* 8 bits (corerev >= 3) */ +#define SPI_RESP_DELAY_F3 ( (uint32_t)0x001f ) /* 8 bits (corerev >= 3) */ + +/****************************************************** +* Bit Masks +******************************************************/ + +/* GSPI */ +#define SPI_READ_TEST_REGISTER_VALUE ( (uint32_t)0xFEEDBEAD ) +#define SPI_READ_TEST_REG_LSB ( ( (SPI_READ_TEST_REGISTER_VALUE) ) & 0xff ) +#define SPI_READ_TEST_REG_LSB_SFT1 ( ( (SPI_READ_TEST_REGISTER_VALUE << 1) ) & 0xff ) +#define SPI_READ_TEST_REG_LSB_SFT2 ( ( (SPI_READ_TEST_REGISTER_VALUE << 1) + 1 ) & 0xff ) +#define SPI_READ_TEST_REG_LSB_SFT3 ( ( (SPI_READ_TEST_REGISTER_VALUE + 1) << 1 ) & 0xff ) + +/* SPI_BUS_CONTROL Bits */ +#define WORD_LENGTH_32 ( (uint32_t)0x01 ) /* 0/1 16/32 bit word length */ +#define ENDIAN_BIG ( (uint32_t)0x02 ) /* 0/1 Little/Big Endian */ +#define CLOCK_PHASE ( (uint32_t)0x04 ) /* 0/1 clock phase delay */ +#define CLOCK_POLARITY ( (uint32_t)0x08 ) /* 0/1 Idle state clock polarity is low/high */ +#define HIGH_SPEED_MODE ( (uint32_t)0x10 ) /* 1/0 High Speed mode / Normal mode */ +#define INTERRUPT_POLARITY_HIGH ( (uint32_t)0x20 ) /* 1/0 Interrupt active polarity is high/low */ +#define WAKE_UP ( (uint32_t)0x80 ) /* 0/1 Wake-up command from Host to WLAN */ + +/* SPI_RESPONSE_DELAY Bit mask */ +#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */ + +/* SPI_STATUS_ENABLE Bits */ +#define STATUS_ENABLE ( (uint32_t)0x01 ) /* 1/0 Status sent/not sent to host after read/write */ +#define INTR_WITH_STATUS ( (uint32_t)0x02 ) /* 0/1 Do-not / do-interrupt if status is sent */ +#define RESP_DELAY_ALL ( (uint32_t)0x04 ) /* Applicability of resp delay to F1 or all func's read */ +#define DWORD_PKT_LEN_EN ( (uint32_t)0x08 ) /* Packet len denoted in dwords instead of bytes */ +#define CMD_ERR_CHK_EN ( (uint32_t)0x20 ) /* Command error check enable */ +#define DATA_ERR_CHK_EN ( (uint32_t)0x40 ) /* Data error check enable */ + +/* SPI_RESET_BP Bits*/ +#define RESET_ON_WLAN_BP_RESET ( (uint32_t)0x04 ) /* enable reset for WLAN backplane */ +#define RESET_SPI ( (uint32_t)0x80 ) /* reset the above enabled logic */ + +/* SPI_INTERRUPT_REGISTER and SPI_INTERRUPT_ENABLE_REGISTER Bits */ +#define DATA_UNAVAILABLE ( (uint32_t)0x0001 ) /* Requested data not available; Clear by writing a "1" */ +#define F2_F3_FIFO_RD_UNDERFLOW ( (uint32_t)0x0002 ) +#define F2_F3_FIFO_WR_OVERFLOW ( (uint32_t)0x0004 ) +#define COMMAND_ERROR ( (uint32_t)0x0008 ) /* Cleared by writing 1 */ +#define DATA_ERROR ( (uint32_t)0x0010 ) /* Cleared by writing 1 */ +#define F2_PACKET_AVAILABLE ( (uint32_t)0x0020 ) +#define F3_PACKET_AVAILABLE ( (uint32_t)0x0040 ) +#define F1_OVERFLOW ( (uint32_t)0x0080 ) /* Due to last write. Bkplane has pending write requests */ +#define MISC_INTR0 ( (uint32_t)0x0100 ) +#define MISC_INTR1 ( (uint32_t)0x0200 ) +#define MISC_INTR2 ( (uint32_t)0x0400 ) +#define MISC_INTR3 ( (uint32_t)0x0800 ) +#define MISC_INTR4 ( (uint32_t)0x1000 ) +#define F1_INTR ( (uint32_t)0x2000 ) +#define F2_INTR ( (uint32_t)0x4000 ) +#define F3_INTR ( (uint32_t)0x8000 ) + +/* SPI_STATUS_REGISTER Bits */ +#define STATUS_DATA_NOT_AVAILABLE ( (uint32_t)0x00000001 ) +#define STATUS_UNDERFLOW ( (uint32_t)0x00000002 ) +#define STATUS_OVERFLOW ( (uint32_t)0x00000004 ) +#define STATUS_F2_INTR ( (uint32_t)0x00000008 ) +#define STATUS_F3_INTR ( (uint32_t)0x00000010 ) +#define STATUS_F2_RX_READY ( (uint32_t)0x00000020 ) +#define STATUS_F3_RX_READY ( (uint32_t)0x00000040 ) +#define STATUS_HOST_CMD_DATA_ERR ( (uint32_t)0x00000080 ) +#define STATUS_F2_PKT_AVAILABLE ( (uint32_t)0x00000100 ) +#define STATUS_F2_PKT_LEN_MASK ( (uint32_t)0x000FFE00 ) +#define STATUS_F2_PKT_LEN_SHIFT ( (uint32_t)9 ) +#define STATUS_F3_PKT_AVAILABLE ( (uint32_t)0x00100000 ) +#define STATUS_F3_PKT_LEN_MASK ( (uint32_t)0xFFE00000 ) +#define STATUS_F3_PKT_LEN_SHIFT ( (uint32_t)21 ) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef INCLUDED_WHD_SPI_H_ */ diff --git a/wi-fi/whd/bus_protocols/whd_trxhdr.h b/wi-fi/whd/bus_protocols/whd_trxhdr.h new file mode 100644 index 00000000..602ba0a4 --- /dev/null +++ b/wi-fi/whd/bus_protocols/whd_trxhdr.h @@ -0,0 +1,89 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_TRXHDR_H_ +#define INCLUDED_WHD_TRXHDR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef TRXV5 + +#else +/* Bootloader makes special use of trx header "offsets" array */ +enum +{ + TRX_V4_OFFS_SIGN_INFO_IDX = 0, + TRX_V4_OFFS_DATA_FOR_SIGN1_IDX = 1, + TRX_V4_OFFS_DATA_FOR_SIGN2_IDX = 2, + TRX_V4_OFFS_ROOT_MODULUS_IDX = 3, + TRX_V4_OFFS_ROOT_EXPONENT_IDX = 67, + TRX_V4_OFFS_CONT_MODULUS_IDX = 68, + TRX_V4_OFFS_CONT_EXPONENT_IDX = 132, + TRX_V4_OFFS_HASH_FW_IDX = 133, + TRX_V4_OFFS_FW_LEN_IDX = 149, + TRX_V4_OFFS_TR_RST_IDX = 150, + TRX_V4_OFFS_FW_VER_FOR_ANTIROOLBACK_IDX = 151, + TRX_V4_OFFS_IV_IDX = 152, + TRX_V4_OFFS_NONCE_IDX = 160, + TRX_V4_OFFS_SIGN_INFO2_IDX = 168, + TRX_V4_OFFS_MAX_IDX +}; +#endif +/****************************************************** +* TRX header Constants +******************************************************/ + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ + +#ifdef TRXV5 +#define TRX_VERSION 5 /* Version trxv5 */ +#else +#define TRX_VERSION 4 /* Version trxv4 */ +#define TRX_MAX_OFFSET TRX_V4_OFFS_MAX_IDX /* Max number of file offsets for trxv4 */ +#endif +/****************************************************** +* Structures +******************************************************/ +#ifdef TRXV5 +typedef struct +{ + uint32_t magic; /* "HDR0" */ + uint32_t len; /* Length of file including header */ + uint32_t crc32; /* CRC from flag_version to end of file */ + uint32_t flag_version; /* 0:15 flags, 16:31 version */ + uint32_t offsets[4]; /* Offsets of partitions */ +} trx_header_t; +#else +typedef struct +{ + uint32_t magic; /* "HDR0" */ + uint32_t len; /* Length of file including header */ + uint32_t crc32; /* CRC from flag_version to end of file */ + uint32_t flag_version; /* 0:15 flags, 16:31 version */ + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions */ +} trx_header_t; +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef INCLUDED_WHD_TRXHDR_H_ */ diff --git a/wi-fi/whd/whd.h b/wi-fi/whd/whd.h index 95b87b9f..81e75b54 100644 --- a/wi-fi/whd/whd.h +++ b/wi-fi/whd/whd.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,8 @@ #define INCLUDED_WHD_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /** diff --git a/wi-fi/whd/whd_ap.c b/wi-fi/whd/whd_ap.c index 51e9b8c0..d4d9128e 100644 --- a/wi-fi/whd/whd_ap.c +++ b/wi-fi/whd/whd_ap.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,11 @@ #include "bus_protocols/whd_chip_reg.h" #include "whd_chip_constants.h" #include "whd_chip.h" +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" +#else +#include "whd_msgbuf.h" +#endif /* PROTO_MSGBUF */ #include "whd_thread_internal.h" #include "whd_events_int.h" #include "whd_int.h" @@ -31,32 +35,34 @@ #include "whd_wifi_api.h" #include "whd_buffer_api.h" #include "whd_wlioctl.h" +#include "whd_proto.h" /****************************************************** ** @cond Constants *******************************************************/ -#define WLC_EVENT_MSG_LINK (0x01) -#define RATE_SETTING_11_MBPS (11000000 / 500000) -#define AMPDU_AP_DEFAULT_BA_WSIZE 8 -#define AMPDU_STA_DEFAULT_BA_WSIZE 8 -#define AMPDU_STA_DEFAULT_MPDU 4 /* STA default num MPDU per AMPDU */ - +#define WLC_EVENT_MSG_LINK (0x01) +#define RATE_SETTING_11_MBPS (11000000 / 500000) +#define AMPDU_AP_DEFAULT_BA_WSIZE 8 +#define AMPDU_STA_DEFAULT_BA_WSIZE 8 +#define AMPDU_STA_DEFAULT_MPDU 4 /* STA default num MPDU per AMPDU */ +#define PWE_LOOP_COUNT 5 /****************************************************** ** Enumerations *******************************************************/ -typedef enum { - BSS_AP = 3, - BSS_STA = 2, - BSS_UP = 1, - BSS_DOWN = 0 +typedef enum +{ + BSS_AP = 3, + BSS_STA = 2, + BSS_UP = 1, + BSS_DOWN = 0 } bss_arg_option_t; /****************************************************** * * Function Declarations * ******************************************************/ static void *whd_handle_apsta_event(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); /****************************************************** * Variables Definitions @@ -68,55 +74,59 @@ static const whd_event_num_t apsta_events[] = { WLC_E_IF, WLC_E_LINK, WLC_E_NONE void whd_ap_info_init(whd_driver_t whd_driver) { - whd_driver->ap_info.ap_is_up = WHD_FALSE; - whd_driver->ap_info.is_waiting_event = WHD_FALSE; + whd_driver->ap_info.ap_is_up = WHD_FALSE; + whd_driver->ap_info.is_waiting_event = WHD_FALSE; } void whd_wifi_set_ap_is_up(whd_driver_t whd_driver, whd_bool_t new_state) { - if (whd_driver->ap_info.ap_is_up != new_state) { - whd_driver->ap_info.ap_is_up = new_state; - } + if (whd_driver->ap_info.ap_is_up != new_state) + { + whd_driver->ap_info.ap_is_up = new_state; + } } whd_bool_t whd_wifi_get_ap_is_up(whd_driver_t whd_driver) { - return whd_driver->ap_info.ap_is_up; + return whd_driver->ap_info.ap_is_up; } whd_result_t whd_wifi_set_block_ack_window_size_common(whd_interface_t ifp, uint16_t ap_win_size, uint16_t sta_win_size) { - whd_result_t retval; - uint16_t block_ack_window_size = ap_win_size; + whd_result_t retval; + uint16_t block_ack_window_size = ap_win_size; - /* If the AP interface is already up then don't change the Block Ack window size */ - if (ifp->role == WHD_AP_ROLE) { - return WHD_SUCCESS; - } + /* If the AP interface is already up then don't change the Block Ack window size */ + if (ifp->role == WHD_AP_ROLE) + { + return WHD_SUCCESS; + } - if (ifp->role == WHD_STA_ROLE) { - block_ack_window_size = sta_win_size; - } + if (ifp->role == WHD_STA_ROLE) + { + block_ack_window_size = sta_win_size; + } - retval = whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_BA_WINDOW_SIZE, (uint32_t)block_ack_window_size); + retval = whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_BA_WINDOW_SIZE, ( uint32_t )block_ack_window_size); - whd_assert("set_block_ack_window_size: Failed to set block ack window size\r\n", retval == WHD_SUCCESS); + whd_assert("set_block_ack_window_size: Failed to set block ack window size\r\n", retval == WHD_SUCCESS); - return retval; + return retval; } whd_result_t whd_wifi_set_ampdu_parameters_common(whd_interface_t ifp, uint8_t ba_window_size, int8_t ampdu_mpdu, - uint8_t rx_factor) + uint8_t rx_factor) { - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_BA_WINDOW_SIZE, ba_window_size)); + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_BA_WINDOW_SIZE, ba_window_size) ); - /* Set number of MPDUs available for AMPDU */ - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_MPDU, (uint32_t)ampdu_mpdu)); + /* Set number of MPDUs available for AMPDU */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_MPDU, ( uint32_t )ampdu_mpdu) ); - if (rx_factor != AMPDU_RX_FACTOR_INVALID) { - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_RX_FACTOR, rx_factor)); - } - return WHD_SUCCESS; + if (rx_factor != AMPDU_RX_FACTOR_INVALID) + { + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_AMPDU_RX_FACTOR, rx_factor) ); + } + return WHD_SUCCESS; } /** Sets the chip specific AMPDU parameters for AP and STA @@ -124,481 +134,597 @@ whd_result_t whd_wifi_set_ampdu_parameters_common(whd_interface_t ifp, uint8_t b */ whd_result_t whd_wifi_set_ampdu_parameters(whd_interface_t ifp) { - whd_driver_t whd_driver = ifp->whd_driver; - /* Get the chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - if ((wlan_chip_id == 43012) || (wlan_chip_id == 0x4373)) { - return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_MPDU_AUTO, - AMPDU_RX_FACTOR_64K); - } - else if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_MPDU_AUTO, - AMPDU_RX_FACTOR_INVALID); - } - else { - return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_STA_DEFAULT_MPDU, - AMPDU_RX_FACTOR_8K); - } + whd_driver_t whd_driver = ifp->whd_driver; + /* Get the chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) ) + { + return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_MPDU_AUTO, + AMPDU_RX_FACTOR_64K); + } + else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_MPDU_AUTO, + AMPDU_RX_FACTOR_INVALID); + } + else + { + return whd_wifi_set_ampdu_parameters_common(ifp, AMPDU_STA_DEFAULT_BA_WSIZE, AMPDU_STA_DEFAULT_MPDU, + AMPDU_RX_FACTOR_8K); + } } /* All chips */ static void *whd_handle_apsta_event(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, void *handler_user_data) + const uint8_t *event_data, void *handler_user_data) { - whd_driver_t whd_driver = ifp->whd_driver; - whd_ap_int_info_t *ap; - - UNUSED_PARAMETER(event_header); - UNUSED_PARAMETER(event_data); - UNUSED_PARAMETER(handler_user_data); - - ap = &whd_driver->ap_info; - - if (ap->is_waiting_event == WHD_TRUE) { - if ((event_header->event_type == (whd_event_num_t)WLC_E_LINK) || - (event_header->event_type == WLC_E_IF)) { - whd_result_t result; - result = cy_rtos_set_semaphore(&ap->whd_wifi_sleep_flag, WHD_FALSE); - WPRINT_WHD_DEBUG(("%s failed to post AP link semaphore at %d\n", __func__, __LINE__)); - REFERENCE_DEBUG_ONLY_VARIABLE(result); - } - } - return handler_user_data; + whd_driver_t whd_driver = ifp->whd_driver; + whd_ap_int_info_t *ap; + + UNUSED_PARAMETER(event_header); + UNUSED_PARAMETER(event_data); + UNUSED_PARAMETER(handler_user_data); + + ap = &whd_driver->ap_info; + + if (ap->is_waiting_event == WHD_TRUE) + { + if ( (event_header->event_type == (whd_event_num_t)WLC_E_LINK) || + (event_header->event_type == WLC_E_IF) ) + { + whd_result_t result; + result = cy_rtos_set_semaphore(&ap->whd_wifi_sleep_flag, WHD_FALSE); + WPRINT_WHD_DEBUG( ("%s failed to post AP link semaphore at %d\n", __func__, __LINE__) ); + REFERENCE_DEBUG_ONLY_VARIABLE(result); + } + } + return handler_user_data; } /* All chips */ -uint32_t whd_wifi_init_ap(whd_interface_t ifp, whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length, uint8_t channel) +whd_result_t whd_wifi_init_ap(whd_interface_t ifp, whd_ssid_t *ssid, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length, uint16_t chanspec) +{ + whd_driver_t whd_driver; + whd_bool_t wait_for_interface = WHD_FALSE; + whd_result_t result; + whd_buffer_t response; + whd_buffer_t buffer; + whd_interface_t prim_ifp; + whd_ap_int_info_t *ap; + uint32_t *data; + uint32_t bss_index; + uint16_t wlan_chip_id; + uint32_t auth_mfp = WL_MFP_NONE; + uint16_t event_entry = (uint16_t)0xFF; + + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Get the Chip Number */ + wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if ( (auth_type & WEP_ENABLED) != 0 ) + { + WPRINT_WHD_ERROR( ("WEP auth type is not allowed , %s failed at line %d \n", __func__, __LINE__) ); + return WHD_WEP_NOT_ALLOWED; + } + + if ( (auth_type & WPA3_SECURITY) && + ( (wlan_chip_id == 43430) || (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) || + (wlan_chip_id == 43012) ) ) + { + WPRINT_WHD_ERROR( ("WPA3 is not supported, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_UNSUPPORTED; + } + + if ( (wlan_chip_id == 43022) && + ( (auth_type & TKIP_ENABLED) || (auth_type & WPA_SECURITY) ) ) + { + WPRINT_WHD_ERROR( ("WPA and TKIP are not supported, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_UNSUPPORTED; + } + + ap = &whd_driver->ap_info; + + prim_ifp = whd_get_primary_interface(whd_driver); + if (prim_ifp == NULL) + { + WPRINT_WHD_ERROR( ("%s failed at %d \n", __func__, __LINE__) ); + return WHD_UNKNOWN_INTERFACE; + } + + if (ssid->length > (size_t)SSID_NAME_SIZE) + { + WPRINT_WHD_ERROR( ("%s: failure: SSID length(%u) error\n", __func__, ssid->length) ); + return WHD_WLAN_BADSSIDLEN; + } + + /* Turn off APSTA when creating AP mode on primary interface */ + if (ifp == prim_ifp) + { + CHECK_RETURN(whd_wifi_set_ioctl_buffer(prim_ifp, WLC_DOWN, NULL, 0) ); + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_APSTA); + CHECK_IOCTL_BUFFER(data); + *data = 0; + result = whd_proto_set_iovar(ifp, buffer, 0); + if ( (result != WHD_SUCCESS) && (result != WHD_WLAN_UNSUPPORTED) ) + { + WPRINT_WHD_ERROR( ("Could not turn off apsta\n") ); + return result; + } + CHECK_RETURN(whd_wifi_set_ioctl_buffer(prim_ifp, WLC_UP, NULL, 0) ); + } + + bss_index = ifp->bsscfgidx; + + ifp->role = WHD_AP_ROLE; + + if ( ( (auth_type == WHD_SECURITY_WPA_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA2_AES_PSK) || + (auth_type == WHD_SECURITY_WPA2_MIXED_PSK) ) && + ( (key_length < (uint8_t)WSEC_MIN_PSK_LEN) || (key_length > (uint8_t)WSEC_MAX_PSK_LEN) ) ) + { + WPRINT_WHD_ERROR( ("Error: WPA security key length must be between %d and %d\n", WSEC_MIN_PSK_LEN, + WSEC_MAX_PSK_LEN) ); + return WHD_WPA_KEYLEN_BAD; + } + + if ( (whd_wifi_get_ap_is_up(whd_driver) == WHD_TRUE) ) + { + WPRINT_WHD_ERROR( ("Error: Soft AP or Wi-Fi Direct group owner already up\n") ); + return WHD_AP_ALREADY_UP; + } + + /* Query bss state (does it exist? if so is it UP?) */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_BSS); + CHECK_IOCTL_BUFFER(data); + + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *data = htod32( (uint32_t)CHIP_AP_INTERFACE ); + } + else + { + *data = htod32( (uint32_t)bss_index ); + } + + if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + if (whd_proto_get_iovar(ifp, buffer, &response) != WHD_SUCCESS) + { + /* Note: We don't need to release the response packet since the iovar failed */ + wait_for_interface = WHD_TRUE; + } + else + { + /* Check if the BSS is already UP, if so return */ + uint32_t *data2 = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data2, WHD_NO_REGISTER_FUNCTION_POINTER); + *data2 = dtoh32 (*data2); + if (*data2 == (uint32_t)BSS_UP) + { + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); + ap->is_waiting_event = WHD_FALSE; + return WHD_SUCCESS; + } + else + { + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + } + } + + if (whd_proto_get_iovar(prim_ifp, buffer, &response) != WHD_SUCCESS) + { + /* Note: We don't need to release the response packet since the iovar failed */ + wait_for_interface = WHD_TRUE; + } + else + { + /* Check if the BSS is already UP, if so return */ + uint32_t *data2 = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data2, WHD_NO_REGISTER_FUNCTION_POINTER); + *data2 = dtoh32 (*data2); + if (*data2 == (uint32_t)BSS_UP) + { + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); + ap->is_waiting_event = WHD_FALSE; + return WHD_SUCCESS; + } + else + { + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + } + + CHECK_RETURN(cy_rtos_init_semaphore(&ap->whd_wifi_sleep_flag, 1, 0) ); + + ap->is_waiting_event = WHD_TRUE; + /* Register for interested events */ + CHECK_RETURN_WITH_SEMAPHORE(whd_management_set_event_handler(ifp, apsta_events, whd_handle_apsta_event, + NULL, &event_entry), &ap->whd_wifi_sleep_flag); + if (event_entry >= WHD_EVENT_HANDLER_LIST_SIZE) + { + WPRINT_WHD_DEBUG( ("Event handler registration failed for AP events in function %s and line %d\n", + __func__, __LINE__) ); + return WHD_UNFINISHED; + } + ifp->event_reg_list[WHD_AP_EVENT_ENTRY] = event_entry; + + if (wait_for_interface == WHD_TRUE) + { + CHECK_RETURN_WITH_SEMAPHORE(cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, + WHD_FALSE), &ap->whd_wifi_sleep_flag); + } + ap->is_waiting_event = WHD_FALSE; + + if (prim_ifp == ifp) + { + /* Set AP mode */ + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + *data = 1; /* Turn on AP */ + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_ioctl(ifp, WLC_SET_AP, buffer, 0), + &ap->whd_wifi_sleep_flag); + } + + if (NULL_MAC(ifp->mac_addr.octet) ) + { + /* Change the AP MAC address to be different from STA MAC */ + if ( (result = whd_wifi_get_mac_address(prim_ifp, &ifp->mac_addr) ) != WHD_SUCCESS ) + { + WPRINT_WHD_INFO ( (" Get STA MAC address failed result=%" PRIu32 "\n", result) ); + return result; + } + else + { + WPRINT_WHD_INFO ( (" Get STA MAC address success\n") ); + } + } + + if ( (result = whd_wifi_set_mac_address(ifp, ifp->mac_addr) ) != WHD_SUCCESS ) + { + WPRINT_WHD_INFO ( (" Set AP MAC address failed result=%" PRIu32 "\n", result) ); + return result; + } + + /* Set the SSID */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)40, "bsscfg:" IOVAR_STR_SSID); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + if (wlan_chip_id == 4334) + { + data[0] = htod32( (uint32_t)CHIP_AP_INTERFACE ); /* Set the bsscfg index */ + } + else + { + data[0] = htod32(bss_index); /* Set the bsscfg index */ + } + data[1] = htod32(ssid->length); /* Set the ssid length */ + memcpy(&data[2], (uint8_t *)ssid->value, ssid->length); + if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(ifp, buffer, 0), &ap->whd_wifi_sleep_flag); + } + else + { + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(prim_ifp, buffer, 0), &ap->whd_wifi_sleep_flag); + } + + /* Set the chanspec */ + CHECK_RETURN_WITH_SEMAPHORE(whd_wifi_set_chanspec(ifp, CH20MHZ_CHSPEC(chanspec) ), &ap->whd_wifi_sleep_flag); + + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WSEC); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + data[0] = htod32( (uint32_t)CHIP_AP_INTERFACE ); + } + else + { + data[0] = htod32(bss_index); + } + if ( (auth_type & WPS_ENABLED) != 0 ) + { + data[1] = htod32( (uint32_t)( (auth_type & (~WPS_ENABLED) ) | SES_OW_ENABLED ) ); + } + else + { + data[1] = htod32( (uint32_t)auth_type & 0xFF ); + } + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(prim_ifp, buffer, 0), &ap->whd_wifi_sleep_flag); + if (auth_type == WHD_SECURITY_WPA3_SAE) + { + auth_mfp = WL_MFP_REQUIRED; + + } + else if (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) + { + auth_mfp = WL_MFP_CAPABLE; + } + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_MFP, auth_mfp) ); + + if (wlan_chip_id == 4334) + { + if (auth_type != WHD_SECURITY_OPEN) + { + wsec_pmk_t *psk; + + /* Set the wpa auth */ + data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WPA_AUTH); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + data[0] = htod32( (uint32_t)CHIP_AP_INTERFACE ); + data[1] = htod32( (uint32_t)(auth_type == WHD_SECURITY_WPA_TKIP_PSK) ? + (WPA_AUTH_PSK) : (WPA2_AUTH_PSK | WPA_AUTH_PSK) ); + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(prim_ifp, buffer, 0), &ap->whd_wifi_sleep_flag); + + /* Set the passphrase */ + psk = (wsec_pmk_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t) ); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(psk, &ap->whd_wifi_sleep_flag); + memcpy(psk->key, security_key, key_length); + psk->key_len = htod16(key_length); + psk->flags = htod16( (uint16_t)WSEC_PASSPHRASE ); + CHECK_RETURN(cy_rtos_delay_milliseconds(1) ); + /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_ioctl(ifp, WLC_SET_WSEC_PMK, buffer, 0), + &ap->whd_wifi_sleep_flag); + } + } + else + { + wsec_pmk_t *psk; + + /* Set the wpa auth */ + data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WPA_AUTH); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + data[0] = htod32( (uint32_t)CHIP_AP_INTERFACE ); + } + else + { + data[0] = htod32(bss_index); + } + if (auth_type == WHD_SECURITY_OPEN) + { + data[1] = WHD_SECURITY_OPEN; + } + else if ( (auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) ) + { + data[1] = + htod32( (uint32_t)( (auth_type == + WHD_SECURITY_WPA3_SAE) ? (WPA3_AUTH_SAE_PSK) : (WPA3_AUTH_SAE_PSK | + WPA2_AUTH_PSK) ) ); + } + else + { + data[1] = + htod32( (uint32_t)(auth_type == + WHD_SECURITY_WPA_TKIP_PSK) ? (WPA_AUTH_PSK) : (WPA2_AUTH_PSK | WPA_AUTH_PSK) ); + } + if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(ifp, buffer, 0), &ap->whd_wifi_sleep_flag); + } + else + { + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(prim_ifp, buffer, 0), + &ap->whd_wifi_sleep_flag); + } + if (auth_type != WHD_SECURITY_OPEN) + { + if ( (auth_type == WHD_SECURITY_WPA3_SAE) && (whd_driver->chip_info.fwcap_flags & (1 << WHD_FWCAP_SAE) ) ) + { + whd_wifi_sae_password(ifp, security_key, key_length); + } + else + { + if ( (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) && + (whd_driver->chip_info.fwcap_flags & (1 << WHD_FWCAP_SAE) ) ) + { + whd_wifi_sae_password(ifp, security_key, key_length); + } + /* Set the passphrase */ + psk = (wsec_pmk_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t) ); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(psk, &ap->whd_wifi_sleep_flag); + memcpy(psk->key, security_key, key_length); + psk->key_len = htod16(key_length); + psk->flags = htod16( (uint16_t)WSEC_PASSPHRASE ); + CHECK_RETURN(cy_rtos_delay_milliseconds(1) ); + /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_ioctl(ifp, WLC_SET_WSEC_PMK, buffer, + 0), &ap->whd_wifi_sleep_flag); + } + } + } + + /* Adjust PWE Loop Count(WPA3-R1 Compatibility Issue) */ + if (auth_type & WPA3_SECURITY) + { + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_SAE_PWE_LOOP); + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)PWE_LOOP_COUNT ); + if (whd_proto_set_iovar(ifp, buffer, NULL) != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("Some chipsets might not support PWE_LOOP_CNT..Ignore result\n") ); + } + } + + if (CHSPEC_IS2G(chanspec)) { - whd_driver_t whd_driver; - whd_bool_t wait_for_interface = WHD_FALSE; - whd_result_t result; - whd_buffer_t response; - whd_buffer_t buffer; - whd_interface_t prim_ifp; - whd_ap_int_info_t *ap; - uint32_t *data; - uint32_t bss_index; - uint16_t wlan_chip_id; - uint16_t event_entry = (uint16_t)0xFF; - - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - if ((auth_type & WEP_ENABLED) != 0) { - WPRINT_WHD_ERROR(("WEP auth type is not allowed , %s failed at line %d \n", __func__, __LINE__)); - return WHD_WEP_NOT_ALLOWED; - } - - ap = &whd_driver->ap_info; - - prim_ifp = whd_get_primary_interface(whd_driver); - if (prim_ifp == NULL) { - WPRINT_WHD_ERROR(("%s failed at %d \n", __func__, __LINE__)); - return WHD_UNKNOWN_INTERFACE; - } - - if (ssid->length > (size_t)SSID_NAME_SIZE) { - WPRINT_WHD_ERROR(("%s: failure: SSID length(%u) error\n", __func__, ssid->length)); - return WHD_WLAN_BADSSIDLEN; - } - - /* Turn off APSTA when creating AP mode on primary interface */ - if (ifp == prim_ifp) { - CHECK_RETURN(whd_wifi_set_ioctl_buffer(prim_ifp, WLC_DOWN, NULL, 0)); - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_APSTA); - CHECK_IOCTL_BUFFER(data); - *data = 0; - result = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - if ((result != WHD_SUCCESS) && (result != WHD_WLAN_UNSUPPORTED)) { - WPRINT_WHD_ERROR(("Could not turn off apsta\n")); - return result; - } - CHECK_RETURN(whd_wifi_set_ioctl_buffer(prim_ifp, WLC_UP, NULL, 0)); - } - - bss_index = ifp->bsscfgidx; - /* Get the Chip Number */ - wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - ifp->role = WHD_AP_ROLE; - - if (((auth_type == WHD_SECURITY_WPA_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA2_AES_PSK) || - (auth_type == WHD_SECURITY_WPA2_MIXED_PSK)) && - ((key_length < (uint8_t)8) || (key_length > (uint8_t)64))) { - WPRINT_WHD_INFO(("Error: WPA security key length must be between 8 and 64\n")); - return WHD_WPA_KEYLEN_BAD; - } - - if ((whd_wifi_get_ap_is_up(whd_driver) == WHD_TRUE)) { - WPRINT_WHD_INFO(("Error: Soft AP or Wi-Fi Direct group owner already up\n")); - return WHD_AP_ALREADY_UP; - } - - /* Query bss state (does it exist? if so is it UP?) */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_BSS); - CHECK_IOCTL_BUFFER(data); - - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *data = htod32((uint32_t)CHIP_AP_INTERFACE); - } - else { - *data = htod32((uint32_t)bss_index); - } - - if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - if (whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response) != WHD_SUCCESS) { - /* Note: We don't need to release the response packet since the iovar failed */ - wait_for_interface = WHD_TRUE; - } - else { - /* Check if the BSS is already UP, if so return */ - uint32_t *data2 = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data2, WHD_NO_REGISTER_FUNCTION_POINTER); - *data2 = dtoh32(*data2); - if (*data2 == (uint32_t)BSS_UP) { - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); - ap->is_waiting_event = WHD_FALSE; - return WHD_SUCCESS; - } - else { - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } - } - } - - if (whd_cdc_send_iovar(prim_ifp, CDC_GET, buffer, &response) != WHD_SUCCESS) { - /* Note: We don't need to release the response packet since the iovar failed */ - wait_for_interface = WHD_TRUE; - } - else { - /* Check if the BSS is already UP, if so return */ - uint32_t *data2 = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data2, WHD_NO_REGISTER_FUNCTION_POINTER); - *data2 = dtoh32(*data2); - if (*data2 == (uint32_t)BSS_UP) { - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); - ap->is_waiting_event = WHD_FALSE; - return WHD_SUCCESS; - } - else { - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } - } - - CHECK_RETURN(cy_rtos_init_semaphore(&ap->whd_wifi_sleep_flag, 1, 0)); - - ap->is_waiting_event = WHD_TRUE; - /* Register for interested events */ - CHECK_RETURN_WITH_SEMAPHORE(whd_management_set_event_handler(ifp, apsta_events, whd_handle_apsta_event, - NULL, &event_entry), - &ap->whd_wifi_sleep_flag); - if (event_entry >= WHD_EVENT_HANDLER_LIST_SIZE) { - WPRINT_WHD_DEBUG(("Event handler registration failed for AP events in function %s and line %d\n", - __func__, __LINE__)); - return WHD_UNFINISHED; - } - ifp->event_reg_list[WHD_AP_EVENT_ENTRY] = event_entry; - - if (wait_for_interface == WHD_TRUE) { - CHECK_RETURN_WITH_SEMAPHORE(cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, - WHD_FALSE), - &ap->whd_wifi_sleep_flag); - } - ap->is_waiting_event = WHD_FALSE; - - if (prim_ifp == ifp) { - /* Set AP mode */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - *data = 1; /* Turn on AP */ - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_AP, buffer, 0), - &ap->whd_wifi_sleep_flag); - } - - if (NULL_MAC(ifp->mac_addr.octet)) { - /* Change the AP MAC address to be different from STA MAC */ - if ((result = whd_wifi_get_mac_address(prim_ifp, &ifp->mac_addr)) != WHD_SUCCESS) { - WPRINT_WHD_INFO((" Get STA MAC address failed result=%" PRIu32 "\n", result)); - return result; - } - else { - WPRINT_WHD_INFO((" Get STA MAC address success\n")); - } - } - - if ((result = whd_wifi_set_mac_address(ifp, ifp->mac_addr)) != WHD_SUCCESS) { - WPRINT_WHD_INFO((" Set AP MAC address failed result=%" PRIu32 "\n", result)); - return result; - } - - /* Set the SSID */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)40, "bsscfg:" IOVAR_STR_SSID); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - if (wlan_chip_id == 4334) { - data[0] = htod32((uint32_t)CHIP_AP_INTERFACE); /* Set the bsscfg index */ - } - else { - data[0] = htod32(bss_index); /* Set the bsscfg index */ - } - data[1] = htod32(ssid->length); /* Set the ssid length */ - memcpy(&data[2], (uint8_t *)ssid->value, ssid->length); - if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); - } - else { - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); - } - - /* Set the channel */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - *data = htod32(channel); - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_CHANNEL, buffer, 0), - &ap->whd_wifi_sleep_flag); - - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WSEC); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - data[0] = htod32((uint32_t)CHIP_AP_INTERFACE); - } - else { - data[0] = htod32(bss_index); - } - if ((auth_type & WPS_ENABLED) != 0) { - data[1] = htod32((uint32_t)((auth_type & (~WPS_ENABLED)) | SES_OW_ENABLED)); - } - else { - data[1] = htod32((uint32_t)auth_type); - } - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); - if (wlan_chip_id == 4334) { - if (auth_type != WHD_SECURITY_OPEN) { - wsec_pmk_t *psk; - - /* Set the wpa auth */ - data = - (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WPA_AUTH); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - data[0] = htod32((uint32_t)CHIP_AP_INTERFACE); - data[1] = htod32((uint32_t)(auth_type == WHD_SECURITY_WPA_TKIP_PSK) ? - (WPA_AUTH_PSK) : - (WPA2_AUTH_PSK | WPA_AUTH_PSK)); - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); - - /* Set the passphrase */ - psk = (wsec_pmk_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t)); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(psk, &ap->whd_wifi_sleep_flag); - memcpy(psk->key, security_key, key_length); - psk->key_len = htod16(key_length); - psk->flags = htod16((uint16_t)WSEC_PASSPHRASE); - CHECK_RETURN(cy_rtos_delay_milliseconds(1)); - /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_WSEC_PMK, buffer, 0), - &ap->whd_wifi_sleep_flag); - } - } - else { - if (auth_type != WHD_SECURITY_OPEN) { - wsec_pmk_t *psk; - - /* Set the wpa auth */ - data = - (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WPA_AUTH); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - data[0] = htod32((uint32_t)CHIP_AP_INTERFACE); - } - else { - data[0] = htod32(bss_index); - } - data[1] = - htod32((uint32_t)(auth_type == - WHD_SECURITY_WPA_TKIP_PSK) ? - (WPA_AUTH_PSK) : - (WPA2_AUTH_PSK | WPA_AUTH_PSK)); - if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); - } - else { - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0), - &ap->whd_wifi_sleep_flag); - } - - /* Set the passphrase */ - psk = (wsec_pmk_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t)); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(psk, &ap->whd_wifi_sleep_flag); - memcpy(psk->key, security_key, key_length); - psk->key_len = htod16(key_length); - psk->flags = htod16((uint16_t)WSEC_PASSPHRASE); - CHECK_RETURN(cy_rtos_delay_milliseconds(1)); - /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_WSEC_PMK, buffer, - 0), - &ap->whd_wifi_sleep_flag); - } - } - - /* Set the multicast transmission rate to 11 Mbps rather than the default 1 Mbps */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_2G_MULTICAST_RATE); - CHECK_IOCTL_BUFFER(data); - *data = htod32((uint32_t)RATE_SETTING_11_MBPS); - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - result = whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); - whd_assert("start_ap: Failed to set multicast transmission rate\r\n", result == WHD_SUCCESS); - } - else { - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL), &ap->whd_wifi_sleep_flag); - } - - return WHD_SUCCESS; + /* Set the multicast transmission rate to 11 Mbps rather than the default 1 Mbps */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_2G_MULTICAST_RATE); + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)RATE_SETTING_11_MBPS ); + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + result = whd_proto_set_iovar(ifp, buffer, NULL); + whd_assert("start_ap: Failed to set multicast transmission rate\r\n", result == WHD_SUCCESS); + } + else + { + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(ifp, buffer, NULL), &ap->whd_wifi_sleep_flag); + } +} + + return WHD_SUCCESS; } -uint32_t whd_wifi_start_ap(whd_interface_t ifp) +whd_result_t whd_wifi_start_ap(whd_interface_t ifp) { - whd_buffer_t buffer; - uint32_t *data; - whd_ap_int_info_t *ap; - whd_interface_t prim_ifp; - whd_driver_t whd_driver; + whd_buffer_t buffer; + uint32_t *data; + whd_ap_int_info_t *ap; + whd_interface_t prim_ifp; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; - CHECK_DRIVER_NULL(whd_driver); + CHECK_DRIVER_NULL(whd_driver); - prim_ifp = whd_get_primary_interface(whd_driver); + prim_ifp = whd_get_primary_interface(whd_driver); - if (prim_ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } + if (prim_ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } - ap = &whd_driver->ap_info; - ap->is_waiting_event = WHD_TRUE; - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, IOVAR_STR_BSS); - CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); - data[0] = htod32(ifp->bsscfgidx); - data[1] = htod32((uint32_t)BSS_UP); - CHECK_RETURN_WITH_SEMAPHORE(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0), &ap->whd_wifi_sleep_flag); + ap = &whd_driver->ap_info; + ap->is_waiting_event = WHD_TRUE; + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, IOVAR_STR_BSS); + CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(data, &ap->whd_wifi_sleep_flag); + data[0] = htod32(ifp->bsscfgidx); + data[1] = htod32( (uint32_t)BSS_UP ); + CHECK_RETURN_WITH_SEMAPHORE(whd_proto_set_iovar(prim_ifp, buffer, 0), &ap->whd_wifi_sleep_flag); - /* Wait until AP is brought up */ - CHECK_RETURN_WITH_SEMAPHORE(cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, - WHD_FALSE), - &ap->whd_wifi_sleep_flag); - ap->is_waiting_event = WHD_FALSE; + /* Wait until AP is brought up */ + CHECK_RETURN_WITH_SEMAPHORE(cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, + WHD_FALSE), &ap->whd_wifi_sleep_flag); + ap->is_waiting_event = WHD_FALSE; - whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); - return WHD_SUCCESS; + whd_wifi_set_ap_is_up(whd_driver, WHD_TRUE); + return WHD_SUCCESS; } -uint32_t whd_wifi_stop_ap(whd_interface_t ifp) +whd_result_t whd_wifi_stop_ap(whd_interface_t ifp) { - uint32_t *data; - whd_buffer_t buffer; - whd_buffer_t response; - whd_result_t result; - whd_result_t result2; - whd_interface_t prim_ifp; - whd_driver_t whd_driver; - whd_ap_int_info_t *ap; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - ap = &whd_driver->ap_info; - - prim_ifp = whd_get_primary_interface(whd_driver); - - if (prim_ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - /* Get Chip Number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - /* Query bss state (does it exist? if so is it UP?) */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_BSS); - CHECK_IOCTL_BUFFER(data); - *data = ifp->bsscfgidx; - - result = whd_cdc_send_iovar(prim_ifp, CDC_GET, buffer, &response); - if (result == WHD_WLAN_NOTFOUND) { - /* AP interface does not exist - i.e. it is down */ - whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); - return WHD_SUCCESS; - } - - CHECK_RETURN(result); - - *data = dtoh32(*(uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response)); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - if (data[0] != (uint32_t)BSS_UP) { - /* AP interface indicates it is not up - i.e. it is down */ - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); - return WHD_SUCCESS; - } - - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - - ap->is_waiting_event = WHD_TRUE; - /* set BSS down */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, IOVAR_STR_BSS); - CHECK_IOCTL_BUFFER(data); - data[0] = htod32(ifp->bsscfgidx); - data[1] = htod32((uint32_t)BSS_DOWN); - CHECK_RETURN(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0)); - - /* Wait until AP is brought down */ - result = cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__)); - goto sema_fail; - } - - /* Disable AP mode only if AP is on primary interface */ - if (prim_ifp == ifp) { - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER(data); - *data = 0; - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_AP, buffer, 0)); - if ((wlan_chip_id != 43430) && (wlan_chip_id != 43439) && - (wlan_chip_id != 43909) && (wlan_chip_id != 43907) && - (wlan_chip_id != 54907)) { - result = cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__)); - goto sema_fail; - } - } - } + uint32_t *data; + whd_buffer_t buffer; + whd_buffer_t response; + whd_result_t result; + whd_result_t result2; + whd_interface_t prim_ifp; + whd_driver_t whd_driver; + whd_ap_int_info_t *ap; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + ap = &whd_driver->ap_info; + + prim_ifp = whd_get_primary_interface(whd_driver); + + if (prim_ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + /* Get Chip Number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + /* Query bss state (does it exist? if so is it UP?) */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_BSS); + CHECK_IOCTL_BUFFER(data); + *data = ifp->bsscfgidx; + + result = whd_proto_get_iovar(prim_ifp, buffer, &response); + if (result == WHD_WLAN_NOTFOUND) + { + /* AP interface does not exist - i.e. it is down */ + whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); + return WHD_SUCCESS; + } + + CHECK_RETURN(result); + + *data = dtoh32(*(uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response) ); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + if (data[0] != (uint32_t)BSS_UP) + { + /* AP interface indicates it is not up - i.e. it is down */ + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); + return WHD_SUCCESS; + } + + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + ap->is_waiting_event = WHD_TRUE; + /* set BSS down */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, IOVAR_STR_BSS); + CHECK_IOCTL_BUFFER(data); + data[0] = htod32(ifp->bsscfgidx); + data[1] = htod32( (uint32_t)BSS_DOWN ); + CHECK_RETURN(whd_proto_set_iovar(prim_ifp, buffer, 0) ); + + /* Wait until AP is brought down */ + result = cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__) ); + goto sema_fail; + } + + /* Disable AP mode only if AP is on primary interface */ + if (prim_ifp == ifp) + { + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + CHECK_IOCTL_BUFFER(data); + *data = 0; + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SET_AP, buffer, 0) ); + if ( (wlan_chip_id != 43430) && (wlan_chip_id != 43439) && + (wlan_chip_id != 43909) && (wlan_chip_id != 43907) && + (wlan_chip_id != 54907) ) + { + result = cy_rtos_get_semaphore(&ap->whd_wifi_sleep_flag, (uint32_t)10000, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__) ); + goto sema_fail; + } + } + } sema_fail: - ap->is_waiting_event = WHD_FALSE; - result2 = cy_rtos_deinit_semaphore(&ap->whd_wifi_sleep_flag); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__)); - return result; - } - if (result2 != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error deleting semaphore, %s failed at %d \n", __func__, __LINE__)); - return result2; - } - - CHECK_RETURN(whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_AP_EVENT_ENTRY])); - ifp->event_reg_list[WHD_AP_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); - - ifp->role = WHD_INVALID_ROLE; - return WHD_SUCCESS; + ap->is_waiting_event = WHD_FALSE; + result2 = cy_rtos_deinit_semaphore(&ap->whd_wifi_sleep_flag); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error getting a semaphore, %s failed at %d \n", __func__, __LINE__) ); + return result; + } + if (result2 != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error deleting semaphore, %s failed at %d \n", __func__, __LINE__) ); + return result2; + } + + CHECK_RETURN(whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_AP_EVENT_ENTRY]) ); + ifp->event_reg_list[WHD_AP_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + whd_wifi_set_ap_is_up(whd_driver, WHD_FALSE); + + ifp->role = WHD_INVALID_ROLE; + return WHD_SUCCESS; } diff --git a/wi-fi/whd/whd_ap.h b/wi-fi/whd/whd_ap.h index 31710e94..96a36c37 100644 --- a/wi-fi/whd/whd_ap.h +++ b/wi-fi/whd/whd_ap.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,50 +31,43 @@ extern "C" { /****************************************************** * Macros ******************************************************/ -#define AMPDU_RX_FACTOR_8K 0 /* max receive AMPDU length is 8kb */ -#define AMPDU_RX_FACTOR_16K 1 /* max receive AMPDU length is 16kb */ -#define AMPDU_RX_FACTOR_32K 2 /* max receive AMPDU length is 32kb */ -#define AMPDU_RX_FACTOR_64K 3 /* max receive AMPDU length is 64kb */ -#define AMPDU_RX_FACTOR_INVALID 0xff /* invalid rx factor; ignore */ -#define AMPDU_MPDU_AUTO (-1) /* Auto number of mpdu in ampdu */ +#define AMPDU_RX_FACTOR_8K 0 /* max receive AMPDU length is 8kb */ +#define AMPDU_RX_FACTOR_16K 1 /* max receive AMPDU length is 16kb */ +#define AMPDU_RX_FACTOR_32K 2 /* max receive AMPDU length is 32kb */ +#define AMPDU_RX_FACTOR_64K 3 /* max receive AMPDU length is 64kb */ +#define AMPDU_RX_FACTOR_INVALID 0xff /* invalid rx factor; ignore */ +#define AMPDU_MPDU_AUTO (-1) /* Auto number of mpdu in ampdu */ -#define BANDWIDTH_20MHZ (20) /* 802.11n, 802.11ac 20Mhz Bandwidth */ -#define BANDWIDTH_40MHZ (40) /* 802.11n, 802.11ac 40Mhz Bandwidth */ -#define BANDWIDTH_80MHZ (80) /* 802.11ac 80Mhz Bandwidth */ +#define BANDWIDTH_20MHZ (20) /* 802.11n, 802.11ac 20Mhz Bandwidth */ +#define BANDWIDTH_40MHZ (40) /* 802.11n, 802.11ac 40Mhz Bandwidth */ +#define BANDWIDTH_80MHZ (80) /* 802.11ac 80Mhz Bandwidth */ #define WHD_WIFI_CONFIG_AP_MAX_ASSOC 5 #define CHECK_IOCTL_BUFFER_WITH_SEMAPHORE(buff, \ - sema) \ - if (buff == \ - NULL) { \ - WPRINT_WHD_ERROR(("Buffer alloc failed in %s at %d \n", \ - __func__, __LINE__)); \ - whd_assert("Buffer alloc failed\n", 0 == 1); \ - (void)cy_rtos_deinit_semaphore(sema); \ - return WHD_BUFFER_ALLOC_FAIL; \ - } - -#define CHECK_RETURN_WITH_SEMAPHORE(expr, sema) \ - { \ - whd_result_t check_res = (expr); \ - if (check_res != WHD_SUCCESS) { \ - WPRINT_WHD_ERROR(("Command failed in %s at %d \n", __func__, \ - __LINE__)); \ - whd_assert("Command failed\n", 0 == 1); \ - (void)cy_rtos_deinit_semaphore(sema); \ - return check_res; \ - } \ - } + sema) if (buff == \ + NULL){ WPRINT_WHD_ERROR( ("Buffer alloc failed in %s at %d \n", \ + __func__, __LINE__) ); \ + whd_assert("Buffer alloc failed\n", 0 == 1); \ + (void)cy_rtos_deinit_semaphore(sema); \ + return WHD_BUFFER_ALLOC_FAIL; } + +#define CHECK_RETURN_WITH_SEMAPHORE(expr, sema) { whd_result_t check_res = (expr); if (check_res != WHD_SUCCESS) \ + { WPRINT_WHD_ERROR( ("Command failed in %s at %d \n", __func__, \ + __LINE__) ); \ + whd_assert("Command failed\n", 0 == 1); \ + (void)cy_rtos_deinit_semaphore(sema); \ + return check_res; } } /****************************************************** * Structures ******************************************************/ -typedef struct whd_ap_int_info { - whd_bool_t ap_is_up; - whd_bool_t is_waiting_event; - cy_semaphore_t whd_wifi_sleep_flag; +typedef struct whd_ap_int_info +{ + whd_bool_t ap_is_up; + whd_bool_t is_waiting_event; + cy_semaphore_t whd_wifi_sleep_flag; } whd_ap_int_info_t; @@ -82,9 +75,9 @@ typedef struct whd_ap_int_info { * Function prototypes ******************************************************/ extern whd_result_t whd_wifi_set_block_ack_window_size_common(whd_interface_t interface, uint16_t ap_win_size, - uint16_t sta_win_size); + uint16_t sta_win_size); extern whd_result_t whd_wifi_set_ampdu_parameters_common(whd_interface_t interface, uint8_t ba_window_size, - int8_t ampdu_mpdu, uint8_t rx_factor); + int8_t ampdu_mpdu, uint8_t rx_factor); extern void whd_wifi_set_ap_is_up(whd_driver_t whd_driver, whd_bool_t new_state); extern whd_bool_t whd_wifi_get_ap_is_up(whd_driver_t whd_driver); void whd_ap_info_init(whd_driver_t whd_driver); diff --git a/wi-fi/whd/whd_buffer_api.c b/wi-fi/whd/whd_buffer_api.c index 5cb7261f..2f9955d8 100644 --- a/wi-fi/whd/whd_buffer_api.c +++ b/wi-fi/whd/whd_buffer_api.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -61,16 +61,18 @@ * */ whd_result_t whd_host_buffer_get(whd_driver_t whd_driver, whd_buffer_t *buffer, whd_buffer_dir_t direction, - uint16_t size, uint32_t timeout_ms) + uint16_t size, uint32_t timeout_ms) { - if (whd_driver->buffer_if->whd_host_buffer_get) { - return whd_driver->buffer_if->whd_host_buffer_get(buffer, direction, size, timeout_ms); - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->buffer_if->whd_host_buffer_get) + { + return whd_driver->buffer_if->whd_host_buffer_get(buffer, direction, size, timeout_ms); + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } /** Releases a packet buffer @@ -90,15 +92,17 @@ whd_result_t whd_host_buffer_get(whd_driver_t whd_driver, whd_buffer_t *buffer, */ whd_result_t whd_buffer_release(whd_driver_t whd_driver, whd_buffer_t buffer, whd_buffer_dir_t direction) { - if (whd_driver->buffer_if->whd_buffer_release) { - whd_driver->buffer_if->whd_buffer_release(buffer, direction); - return WHD_SUCCESS; - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->buffer_if->whd_buffer_release) + { + whd_driver->buffer_if->whd_buffer_release(buffer, direction); + return WHD_SUCCESS; + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } /** Retrieves the current pointer of a packet buffer @@ -115,14 +119,16 @@ whd_result_t whd_buffer_release(whd_driver_t whd_driver, whd_buffer_t buffer, wh */ uint8_t *whd_buffer_get_current_piece_data_pointer(whd_driver_t whd_driver, whd_buffer_t buffer) { - if (whd_driver->buffer_if->whd_buffer_get_current_piece_data_pointer) { - return whd_driver->buffer_if->whd_buffer_get_current_piece_data_pointer(buffer); - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return NULL; + if (whd_driver->buffer_if->whd_buffer_get_current_piece_data_pointer) + { + return whd_driver->buffer_if->whd_buffer_get_current_piece_data_pointer(buffer); + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return NULL; } /** Retrieves the size of a packet buffer @@ -140,14 +146,16 @@ uint8_t *whd_buffer_get_current_piece_data_pointer(whd_driver_t whd_driver, whd_ */ uint16_t whd_buffer_get_current_piece_size(whd_driver_t whd_driver, whd_buffer_t buffer) { - if (whd_driver->buffer_if->whd_buffer_get_current_piece_size) { - return whd_driver->buffer_if->whd_buffer_get_current_piece_size(buffer); - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return 0; + if (whd_driver->buffer_if->whd_buffer_get_current_piece_size) + { + return whd_driver->buffer_if->whd_buffer_get_current_piece_size(buffer); + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return 0; } /** Sets the current size of a WHD packet @@ -164,14 +172,16 @@ uint16_t whd_buffer_get_current_piece_size(whd_driver_t whd_driver, whd_buffer_t */ whd_result_t whd_buffer_set_size(whd_driver_t whd_driver, whd_buffer_t buffer, uint16_t size) { - if (whd_driver->buffer_if->whd_buffer_set_size) { - return whd_driver->buffer_if->whd_buffer_set_size(buffer, size); - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->buffer_if->whd_buffer_set_size) + { + return whd_driver->buffer_if->whd_buffer_set_size(buffer, size); + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } /** Moves the current pointer of a packet buffer @@ -196,12 +206,14 @@ whd_result_t whd_buffer_set_size(whd_driver_t whd_driver, whd_buffer_t buffer, u */ whd_result_t whd_buffer_add_remove_at_front(whd_driver_t whd_driver, whd_buffer_t *buffer, int32_t add_remove_amount) { - if (whd_driver->buffer_if->whd_buffer_add_remove_at_front) { - return whd_driver->buffer_if->whd_buffer_add_remove_at_front(buffer, add_remove_amount); - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->buffer_if->whd_buffer_add_remove_at_front) + { + return whd_driver->buffer_if->whd_buffer_add_remove_at_front(buffer, add_remove_amount); + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } diff --git a/wi-fi/whd/whd_buffer_api.h b/wi-fi/whd/whd_buffer_api.h index 1ed19d13..8b6ddf4a 100644 --- a/wi-fi/whd/whd_buffer_api.h +++ b/wi-fi/whd/whd_buffer_api.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,8 @@ #include "whd_int.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -59,7 +60,7 @@ extern "C" { * */ whd_result_t whd_host_buffer_get(whd_driver_t whd_driver, whd_buffer_t *buffer, whd_buffer_dir_t direction, - uint16_t size, uint32_t timeout_ms); + uint16_t size, uint32_t timeout_ms); /** Releases a packet buffer * diff --git a/wi-fi/whd/whd_cdc_bdc.c b/wi-fi/whd/whd_cdc_bdc.c index 0401f80e..d7519f80 100644 --- a/wi-fi/whd/whd_cdc_bdc.c +++ b/wi-fi/whd/whd_cdc_bdc.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,6 +15,7 @@ * limitations under the License. */ +#ifndef PROTO_MSGBUF #include #include "whd_int.h" #include "whd_cdc_bdc.h" @@ -26,25 +27,28 @@ #include "whd_thread_internal.h" #include "whd_buffer_api.h" #include "whd_network_if.h" +#include "whd_proto.h" +#include "whd_utils.h" /****************************************************** * Constants ******************************************************/ -#define BDC_PROTO_VER (2) /** Version number of BDC header */ -#define BDC_FLAG_VER_SHIFT (4) /** Number of bits to shift BDC version number in the flags field */ -#define BDC_FLAG2_IF_MASK (0x0f) +#define BDC_PROTO_VER (2) /** Version number of BDC header */ +#define BDC_FLAG_VER_SHIFT (4) /** Number of bits to shift BDC version number in the flags field */ +#define BDC_FLAG2_IF_MASK (0x0f) -#define ETHER_TYPE_BRCM (0x886C) /** Broadcom Ethertype for identifying event packets - Copied from DHD include/proto/ethernet.h */ -#define BRCM_OUI "\x00\x10\x18" /** Broadcom OUI (Organizationally Unique Identifier): Used in the proprietary(221) IE (Information Element) in all Broadcom devices */ +#define ETHER_TYPE_BRCM (0x886C) /** Broadcom Ethertype for identifying event packets - Copied from DHD include/proto/ethernet.h */ +#define BRCM_OUI "\x00\x10\x18" /** Broadcom OUI (Organizationally Unique Identifier): Used in the proprietary(221) IE (Information Element) in all Broadcom devices */ /* QoS related definitions (type of service) */ -#define IPV4_DSCP_OFFSET (15) /** Offset for finding the DSCP field in an IPv4 header */ +#define IPV4_DSCP_OFFSET (15) /** Offset for finding the DSCP field in an IPv4 header */ -#define IOCTL_OFFSET (sizeof(whd_buffer_header_t) + 12 + 16) -#define WHD_IOCTL_PACKET_TIMEOUT (0xFFFFFFFF) -#define WHD_IOCTL_TIMEOUT_MS (5000) /** Need to give enough time for coming out of Deep sleep (was 400) */ -#define WHD_IOCTL_MAX_TX_PKT_LEN (1500) +#define IOCTL_OFFSET (sizeof(whd_buffer_header_t) + 12 + 16) +#define WHD_IOCTL_PACKET_TIMEOUT (0xFFFFFFFF) +#define WHD_IOCTL_TIMEOUT_MS (5000) /** Need to give enough time for coming out of Deep sleep (was 400) */ +#define WHD_IOCTL_MAX_TX_PKT_LEN (1500) +#define ALIGNED_ADDRESS ( (uint32_t)0x3 ) /****************************************************** * Macros @@ -58,23 +62,23 @@ * Static Variables ******************************************************/ -static const uint8_t dscp_to_wmm_qos[] = { - 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ - 1, 1, 1, 1, 1, 1, 1, /* 8 - 14 */ - 1, 1, 1, 1, 1, 1, 1, /* 15 - 21 */ - 1, 1, 0, 0, 0, 0, 0, /* 22 - 28 */ - 0, 0, 0, 5, 5, 5, 5, /* 29 - 35 */ - 5, 5, 5, 5, 5, 5, 5, /* 36 - 42 */ - 5, 5, 5, 5, 5, 7, 7, /* 43 - 49 */ - 7, 7, 7, 7, 7, 7, 7, /* 50 - 56 */ - 7, 7, 7, 7, 7, 7, 7, /* 57 - 63 */ +static const uint8_t dscp_to_wmm_qos[] = +{ 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ + 1, 1, 1, 1, 1, 1, 1, /* 8 - 14 */ + 1, 1, 1, 1, 1, 1, 1, /* 15 - 21 */ + 1, 1, 0, 0, 0, 0, 0, /* 22 - 28 */ + 0, 0, 0, 5, 5, 5, 5, /* 29 - 35 */ + 5, 5, 5, 5, 5, 5, 5, /* 36 - 42 */ + 5, 5, 5, 5, 5, 7, 7, /* 43 - 49 */ + 7, 7, 7, 7, 7, 7, 7, /* 50 - 56 */ + 7, 7, 7, 7, 7, 7, 7, /* 57 - 63 */ }; /****************************************************** * Static Function Prototypes ******************************************************/ -static uint8_t whd_map_dscp_to_priority(whd_driver_t whd_driver, uint8_t dscp_val); +static uint8_t whd_map_dscp_to_priority(whd_driver_t whd_driver, uint8_t dscp_val); /****************************************************** * Static Functions @@ -89,77 +93,37 @@ static uint8_t whd_map_dscp_to_priority(whd_driver_t whd_driver, uint8_t dscp_va */ static uint8_t whd_map_dscp_to_priority(whd_driver_t whd_driver, uint8_t val) { - uint8_t dscp_val = (uint8_t)(val >> 2); /* DSCP field is the high 6 bits of the second byte of an IPv4 header */ + uint8_t dscp_val = (uint8_t)(val >> 2); /* DSCP field is the high 6 bits of the second byte of an IPv4 header */ - return dscp_to_wmm_qos[dscp_val]; + return dscp_to_wmm_qos[dscp_val]; } -void whd_cdc_bdc_info_deinit(whd_driver_t whd_driver) +static whd_result_t whd_cdc_set_ioctl(whd_interface_t ifp, uint32_t command, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) { - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - whd_error_info_t *error_info = &whd_driver->error_info; - - /* Delete the sleep mutex */ - (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_sleep); - - /* Delete the queue mutex. */ - (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); + return whd_cdc_send_ioctl(ifp, CDC_SET, command, send_buffer_hnd, response_buffer_hnd); +} - /* Delete the event list management mutex */ - (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->event_list_mutex); +static whd_result_t whd_cdc_get_ioctl(whd_interface_t ifp, uint32_t command, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return whd_cdc_send_ioctl(ifp, CDC_GET, command, send_buffer_hnd, response_buffer_hnd); +} - /* Delete the error list management mutex */ - (void)cy_rtos_deinit_semaphore(&error_info->event_list_mutex); +static whd_result_t whd_cdc_set_iovar(whd_interface_t ifp, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return whd_cdc_send_iovar(ifp, CDC_SET, send_buffer_hnd, response_buffer_hnd); } -whd_result_t whd_cdc_bdc_info_init(whd_driver_t whd_driver) +static whd_result_t whd_cdc_get_iovar(whd_interface_t ifp, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) { - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - whd_error_info_t *error_info = &whd_driver->error_info; - - /* Create the mutex protecting the packet send queue */ - if (cy_rtos_init_semaphore(&cdc_bdc_info->ioctl_mutex, 1, 0) != WHD_SUCCESS) { - return WHD_SEMAPHORE_ERROR; - } - if (cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } - - /* Create the event flag which signals the whd thread needs to wake up */ - if (cy_rtos_init_semaphore(&cdc_bdc_info->ioctl_sleep, 1, 0) != WHD_SUCCESS) { - cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); - return WHD_SEMAPHORE_ERROR; - } - - /* Create semaphore to protect event list management */ - if (cy_rtos_init_semaphore(&cdc_bdc_info->event_list_mutex, 1, 0) != WHD_SUCCESS) { - cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_sleep); - cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); - return WHD_SEMAPHORE_ERROR; - } - if (cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } - - /* Initialise the list of event handler functions */ - memset(cdc_bdc_info->whd_event_list, 0, sizeof(cdc_bdc_info->whd_event_list)); - - /* Create semaphore to protect event list management */ - if (cy_rtos_init_semaphore(&error_info->event_list_mutex, 1, 0) != WHD_SUCCESS) { - return WHD_SEMAPHORE_ERROR; - } - - if (cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } - - /* Initialise the list of error handler functions */ - memset(error_info->whd_event_list, 0, sizeof(error_info->whd_event_list)); - - return WHD_SUCCESS; + return whd_cdc_send_iovar(ifp, CDC_GET, send_buffer_hnd, response_buffer_hnd); } /** Sends an IOCTL command @@ -183,124 +147,136 @@ whd_result_t whd_cdc_bdc_info_init(whd_driver_t whd_driver) * @return WHD result code */ whd_result_t whd_cdc_send_ioctl(whd_interface_t ifp, cdc_command_type_t type, uint32_t command, - whd_buffer_t send_buffer_hnd, - whd_buffer_t *response_buffer_hnd) + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) { - uint32_t data_length; - uint32_t flags; - uint32_t requested_ioctl_id; - uint32_t status; - whd_result_t retval; - control_header_t *send_packet; - cdc_header_t *cdc_header; - uint32_t bss_index = ifp->bsscfgidx; - whd_driver_t whd_driver = ifp->whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - - /* Validate the command value */ - if (command > INT_MAX) { - WPRINT_WHD_ERROR(("The ioctl command value is invalid\n")); - return WHD_BADARG; - } - - /* Acquire mutex which prevents multiple simultaneous IOCTLs */ - retval = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - if (retval != WHD_SUCCESS) { - CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX)); - return retval; - } - - /* Count request ioctl ID after acquiring ioctl mutex */ - requested_ioctl_id = (uint32_t)(++cdc_bdc_info->requested_ioctl_id); - - /* Get the data length and cast packet to a CDC BUS header */ - data_length = - (uint32_t)(whd_buffer_get_current_piece_size(whd_driver, - send_buffer_hnd) - - sizeof(bus_common_header_t) - - sizeof(cdc_header_t)); - - send_packet = (control_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, send_buffer_hnd); - CHECK_PACKET_NULL(send_packet, WHD_NO_REGISTER_FUNCTION_POINTER); - WHD_IOCTL_LOG_ADD(ifp->whd_driver, command, send_buffer_hnd); - - /* Check if IOCTL is actually IOVAR */ - if ((command == WLC_SET_VAR) || (command == WLC_GET_VAR)) { - uint8_t *data = (uint8_t *)DATA_AFTER_HEADER(send_packet); - uint8_t *ptr = data; - - /* Calculate the offset added to compensate for IOVAR string creating unaligned data section */ - while (*ptr == 0) { - ptr++; - } - if (data != ptr) { - data_length -= (uint32_t)(ptr - data); - memmove(data, ptr, data_length); - CHECK_RETURN(whd_buffer_set_size(whd_driver, send_buffer_hnd, - (uint16_t)(data_length + sizeof(bus_common_header_t) + - sizeof(cdc_header_t)))); - } - } - - /* Prepare the CDC header */ - send_packet->cdc_header.cmd = htod32(command); - send_packet->cdc_header.len = htod32(data_length); - - send_packet->cdc_header.flags = ((requested_ioctl_id << CDCF_IOC_ID_SHIFT) & CDCF_IOC_ID_MASK) | type | bss_index << CDCF_IOC_IF_SHIFT; - send_packet->cdc_header.flags = htod32(send_packet->cdc_header.flags); - - send_packet->cdc_header.status = 0; - - /* Manufacturing test can receive big buffers, but sending big buffers causes a wlan firmware error */ - /* Even though data portion needs to be truncated, cdc_header should have the actual length of the ioctl packet */ - if (whd_buffer_get_current_piece_size(whd_driver, send_buffer_hnd) > WHD_IOCTL_MAX_TX_PKT_LEN) { - CHECK_RETURN(whd_buffer_set_size(whd_driver, send_buffer_hnd, WHD_IOCTL_MAX_TX_PKT_LEN)); - } - - /* Store the length of the data and the IO control header and pass "down" */ - CHECK_RETURN(whd_send_to_bus(whd_driver, send_buffer_hnd, CONTROL_HEADER, 0)); - - - /* Wait till response has been received */ - retval = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_sleep, (uint32_t)WHD_IOCTL_TIMEOUT_MS, WHD_FALSE); - if (retval != WHD_SUCCESS) { - /* Release the mutex since ioctl response will no longer be referenced. */ - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE)); - return retval; - } - - cdc_header = (cdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, cdc_bdc_info->ioctl_response); - CHECK_PACKET_NULL(cdc_header, WHD_NO_REGISTER_FUNCTION_POINTER); - flags = dtoh32(cdc_header->flags); - status = dtoh32(cdc_header->status); - /* Check if the caller wants the response */ - if (response_buffer_hnd != NULL) { - *response_buffer_hnd = cdc_bdc_info->ioctl_response; - CHECK_RETURN(whd_buffer_add_remove_at_front(whd_driver, response_buffer_hnd, sizeof(cdc_header_t))); - } - else { - CHECK_RETURN(whd_buffer_release(whd_driver, cdc_bdc_info->ioctl_response, WHD_NETWORK_RX)); - } - - cdc_bdc_info->ioctl_response = NULL; - - /* Release the mutex since ioctl response will no longer be referenced. */ - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE)); - - /* Check whether the IOCTL response indicates it failed. */ - if ((flags & CDCF_IOC_ERROR) != 0) { - if (response_buffer_hnd != NULL) { - CHECK_RETURN(whd_buffer_release(whd_driver, *response_buffer_hnd, WHD_NETWORK_RX)); - *response_buffer_hnd = NULL; - } - if (status) - return WHD_RESULT_CREATE((WLAN_ENUM_OFFSET - status)); - else - return WHD_IOCTL_FAIL; - } - - return WHD_SUCCESS; + uint32_t data_length; + uint32_t flags; + uint32_t requested_ioctl_id; + uint32_t status; + whd_result_t retval; + control_header_t *send_packet; + cdc_header_t *cdc_header; + uint32_t bss_index = ifp->bsscfgidx; + whd_driver_t whd_driver = ifp->whd_driver; + whd_cdc_bdc_info_t *cdc_bdc_info = whd_driver->proto->pd; + + /* Validate the command value */ + if (command > INT_MAX) + { + WPRINT_WHD_ERROR( ("The ioctl command value is invalid\n") ); + return WHD_BADARG; + } + + /* Acquire mutex which prevents multiple simultaneous IOCTLs */ + retval = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX) ); + return retval; + } + + /* Count request ioctl ID after acquiring ioctl mutex */ + requested_ioctl_id = (uint32_t)(++cdc_bdc_info->requested_ioctl_id); + + /* Get the data length and cast packet to a CDC BUS header */ + data_length = + (uint32_t)(whd_buffer_get_current_piece_size(whd_driver, + send_buffer_hnd) - sizeof(bus_common_header_t) - + sizeof(cdc_header_t) ); + + send_packet = (control_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, send_buffer_hnd); + CHECK_PACKET_NULL(send_packet, WHD_NO_REGISTER_FUNCTION_POINTER); + WHD_IOCTL_LOG_ADD(ifp->whd_driver, command, send_buffer_hnd); + + /* Check if IOCTL is actually IOVAR */ + if ( (command == WLC_SET_VAR) || (command == WLC_GET_VAR) ) + { + uint8_t *data = (uint8_t *)DATA_AFTER_HEADER(send_packet); + uint8_t *ptr = data; + + /* Calculate the offset added to compensate for IOVAR string creating unaligned data section */ + while (*ptr == 0) + { + ptr++; + } + if (data != ptr) + { + data_length -= (uint32_t)(ptr - data); + memmove(data, ptr, data_length); + CHECK_RETURN(whd_buffer_set_size(whd_driver, send_buffer_hnd, + (uint16_t)(data_length + sizeof(bus_common_header_t) + + sizeof(cdc_header_t) ) ) ); + } + } + + /* Prepare the CDC header */ + send_packet->cdc_header.cmd = htod32(command); + send_packet->cdc_header.len = htod32(data_length); + + send_packet->cdc_header.flags = ( (requested_ioctl_id << CDCF_IOC_ID_SHIFT) + & CDCF_IOC_ID_MASK ) | type | bss_index << CDCF_IOC_IF_SHIFT; + send_packet->cdc_header.flags = htod32(send_packet->cdc_header.flags); + + send_packet->cdc_header.status = 0; + + /* Manufacturing test can receive big buffers, but sending big buffers causes a wlan firmware error */ + /* Even though data portion needs to be truncated, cdc_header should have the actual length of the ioctl packet */ + if (whd_buffer_get_current_piece_size(whd_driver, send_buffer_hnd) > WHD_IOCTL_MAX_TX_PKT_LEN) + { + CHECK_RETURN(whd_buffer_set_size(whd_driver, send_buffer_hnd, WHD_IOCTL_MAX_TX_PKT_LEN) ); + } + + /* Store the length of the data and the IO control header and pass "down" */ + CHECK_RETURN(whd_send_to_bus(whd_driver, send_buffer_hnd, CONTROL_HEADER, 8) ); + + + /* Wait till response has been received */ + retval = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_sleep, (uint32_t)WHD_IOCTL_TIMEOUT_MS, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + /* Release the mutex since ioctl response will no longer be referenced. */ + WPRINT_WHD_DEBUG(("Release the mutex since ioctl response will no longer be referenced !\n")); + CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE) ); + return retval; + } + + cdc_header = (cdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, cdc_bdc_info->ioctl_response); + CHECK_PACKET_NULL(cdc_header, WHD_NO_REGISTER_FUNCTION_POINTER); + flags = dtoh32(cdc_header->flags); + status = dtoh32(cdc_header->status); + /* Check if the caller wants the response */ + if (response_buffer_hnd != NULL) + { + *response_buffer_hnd = cdc_bdc_info->ioctl_response; + CHECK_RETURN(whd_buffer_add_remove_at_front(whd_driver, response_buffer_hnd, sizeof(cdc_header_t) ) ); + } + else + { + CHECK_RETURN(whd_buffer_release(whd_driver, cdc_bdc_info->ioctl_response, WHD_NETWORK_RX) ); + } + + cdc_bdc_info->ioctl_response = NULL; + + /* Release the mutex since ioctl response will no longer be referenced. */ + CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE) ); + + /* Check whether the IOCTL response indicates it failed. */ + if ( (flags & CDCF_IOC_ERROR) != 0 ) + { + if (response_buffer_hnd != NULL) + { + CHECK_RETURN(whd_buffer_release(whd_driver, *response_buffer_hnd, WHD_NETWORK_RX) ); + *response_buffer_hnd = NULL; + } + if (status) + return WHD_RESULT_CREATE( (WLAN_ENUM_OFFSET - status) ); + else + return WHD_IOCTL_FAIL; + } + + return WHD_SUCCESS; } /** Sets/Gets an I/O Variable (IOVar) @@ -320,15 +296,17 @@ whd_result_t whd_cdc_send_ioctl(whd_interface_t ifp, cdc_command_type_t type, ui * @return WHD result code */ whd_result_t whd_cdc_send_iovar(whd_interface_t ifp, cdc_command_type_t type, - whd_buffer_t send_buffer_hnd, - whd_buffer_t *response_buffer_hnd) + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) { - if (type == CDC_SET) { - return whd_cdc_send_ioctl(ifp, CDC_SET, (uint32_t)WLC_SET_VAR, send_buffer_hnd, response_buffer_hnd); - } - else { - return whd_cdc_send_ioctl(ifp, CDC_GET, (uint32_t)WLC_GET_VAR, send_buffer_hnd, response_buffer_hnd); - } + if (type == CDC_SET) + { + return whd_cdc_send_ioctl(ifp, CDC_SET, (uint32_t)WLC_SET_VAR, send_buffer_hnd, response_buffer_hnd); + } + else + { + return whd_cdc_send_ioctl(ifp, CDC_GET, (uint32_t)WLC_GET_VAR, send_buffer_hnd, response_buffer_hnd); + } } /** A helper function to easily acquire and initialise a buffer destined for use as an iovar @@ -340,27 +318,57 @@ whd_result_t whd_cdc_send_iovar(whd_interface_t ifp, cdc_command_type_t type, * @return A pointer to the start of user data with data_length space available */ void *whd_cdc_get_iovar_buffer(whd_driver_t whd_driver, - whd_buffer_t *buffer, - uint16_t data_length, - const char *name) + whd_buffer_t *buffer, + uint16_t data_length, + const char *name) +{ + uint32_t name_length = (uint32_t)strlen(name) + 1; /* + 1 for terminating null */ + uint32_t name_length_alignment_offset = (64 - name_length) % sizeof(uint32_t); + + if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, + (uint16_t)(IOCTL_OFFSET + data_length + name_length + name_length_alignment_offset), + (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) + { + uint8_t *data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + CHECK_PACKET_NULL(data, NULL); + data = data + IOCTL_OFFSET; + memset(data, 0, name_length_alignment_offset); + memcpy(data + name_length_alignment_offset, name, name_length); + return (data + name_length + name_length_alignment_offset); + } + else + { + WPRINT_WHD_ERROR( ("Error - failed to allocate a packet buffer for IOVAR\n") ); + return NULL; + } +} + +/** A helper function to easily acquire and initialise a buffer destined for use as an ioctl + * + * @param buffer : A pointer to a whd_buffer_t object where the created buffer will be stored + * @param data_length : The length of space reserved for user data + * + * @return A pointer to the start of user data with data_length space available + */ +void *whd_cdc_get_ioctl_buffer(whd_driver_t whd_driver, + whd_buffer_t *buffer, + uint16_t data_length) { - uint32_t name_length = (uint32_t)strlen(name) + 1; /* + 1 for terminating null */ - uint32_t name_length_alignment_offset = (64 - name_length) % sizeof(uint32_t); - - if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, - (uint16_t)(IOCTL_OFFSET + data_length + name_length + name_length_alignment_offset), - (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) { - uint8_t *data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); - CHECK_PACKET_NULL(data, NULL); - data = data + IOCTL_OFFSET; - memset(data, 0, name_length_alignment_offset); - memcpy(data + name_length_alignment_offset, name, name_length); - return (data + name_length + name_length_alignment_offset); - } - else { - WPRINT_WHD_ERROR(("Error - failed to allocate a packet buffer for IOVAR\n")); - return NULL; - } + if ( (uint32_t)IOCTL_OFFSET + data_length > USHRT_MAX ) + { + WPRINT_WHD_ERROR( ("The reserved ioctl buffer length is over %u\n", USHRT_MAX) ); + return NULL; + } + if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, (uint16_t)(IOCTL_OFFSET + data_length), + (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) + { + return (whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer) + IOCTL_OFFSET); + } + else + { + WPRINT_WHD_ERROR( ("Error - failed to allocate a packet buffer for IOCTL\n") ); + return NULL; + } } /** Sends a data packet. @@ -375,96 +383,171 @@ void *whd_cdc_get_iovar_buffer(whd_driver_t whd_driver, * * @return WHD result code */ -whd_result_t whd_network_send_ethernet_data(whd_interface_t ifp, whd_buffer_t buffer) +whd_result_t whd_cdc_tx_queue_data(whd_interface_t ifp, whd_buffer_t buffer) +{ + data_header_t *packet; + whd_result_t result; + uint8_t *dscp = NULL; + uint8_t priority = 0; + uint8_t whd_tos_map[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; + whd_driver_t whd_driver = ifp->whd_driver; + ethernet_header_t *ethernet_header = (ethernet_header_t *)whd_buffer_get_current_piece_data_pointer( + whd_driver, buffer); + uint16_t ether_type; + CHECK_PACKET_NULL(ethernet_header, WHD_NO_REGISTER_FUNCTION_POINTER); + ether_type = ntoh16(ethernet_header->ethertype); + if ( (ether_type == WHD_ETHERTYPE_IPv4) || (ether_type == WHD_ETHERTYPE_DOT1AS) ) + { + dscp = (uint8_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + IPV4_DSCP_OFFSET; + } + + WPRINT_WHD_DATA_LOG( ("Wcd:> DATA pkt 0x%08lX len %d\n", (unsigned long)buffer, + (int)whd_buffer_get_current_piece_size(whd_driver, buffer) ) ); + + + /* Add link space at front of packet */ + result = whd_buffer_add_remove_at_front(whd_driver, &buffer, -(int)(sizeof(data_header_t) ) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("Unable to adjust header space\n") ); + result = whd_buffer_release(ifp->whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_BUFFER_ALLOC_FAIL; + } + + packet = (data_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); + if (ifp->bsscfgidx > WHD_INTERFACE_MAX) + { + WPRINT_WHD_DEBUG( ("No interface for packet send\n") ); + result = whd_buffer_release(ifp->whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_UNKNOWN_INTERFACE; + } + + /* Prepare the BDC header */ + packet->bdc_header.flags = 0; + packet->bdc_header.flags = (uint8_t)(BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); + /* If it's an IPv4 packet set the BDC header priority based on the DSCP field */ + if ( ( (ether_type == WHD_ETHERTYPE_IPv4) || (ether_type == WHD_ETHERTYPE_DOT1AS) ) && (dscp != NULL) ) + { + if (*dscp != 0) /* If it's equal 0 then it's best effort traffic and nothing needs to be done */ + { + priority = whd_map_dscp_to_priority(whd_driver, *dscp); + } + } + + /* If STA interface, re-map prio to the prio allowed by the AP, regardless of whether it's an IPv4 packet */ + if (ifp->role == WHD_STA_ROLE) + { + packet->bdc_header.priority = whd_tos_map[priority]; + } + else + { + packet->bdc_header.priority = priority; + } + + packet->bdc_header.flags2 = ifp->bsscfgidx; + packet->bdc_header.data_offset = 0; + + /* Add the length of the BDC header and pass "down" */ + return whd_send_to_bus(whd_driver, buffer, DATA_HEADER, packet->bdc_header.priority); + +} + +void whd_cdc_bdc_info_deinit(whd_driver_t whd_driver) { - data_header_t *packet; - whd_result_t result; - uint8_t *dscp = NULL; - uint8_t priority = 0; - uint8_t whd_tos_map[8] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; - whd_driver_t whd_driver = ifp->whd_driver; - ethernet_header_t *ethernet_header = (ethernet_header_t *)whd_buffer_get_current_piece_data_pointer( - whd_driver, buffer); - uint16_t ether_type; - CHECK_PACKET_NULL(ethernet_header, WHD_NO_REGISTER_FUNCTION_POINTER); - ether_type = ntoh16(ethernet_header->ethertype); - if ((ether_type == WHD_ETHERTYPE_IPv4) || (ether_type == WHD_ETHERTYPE_DOT1AS)) { - dscp = (uint8_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + IPV4_DSCP_OFFSET; - } - - WPRINT_WHD_DATA_LOG(("Wcd:> DATA pkt 0x%08lX len %d\n", (unsigned long)buffer, - (int)whd_buffer_get_current_piece_size(whd_driver, buffer))); - - - /* Add link space at front of packet */ - result = whd_buffer_add_remove_at_front(whd_driver, &buffer, -(int)(sizeof(data_header_t))); - if (result != WHD_SUCCESS) { - WPRINT_WHD_DEBUG(("Unable to adjust header space\n")); - result = whd_buffer_release(ifp->whd_driver, buffer, WHD_NETWORK_TX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return WHD_BUFFER_ALLOC_FAIL; - } - - packet = (data_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); - if (ifp->bsscfgidx > WHD_INTERFACE_MAX) { - WPRINT_WHD_DEBUG(("No interface for packet send\n")); - result = whd_buffer_release(ifp->whd_driver, buffer, WHD_NETWORK_TX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return WHD_UNKNOWN_INTERFACE; - } - - /* Prepare the BDC header */ - packet->bdc_header.flags = 0; - packet->bdc_header.flags = (uint8_t)(BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - /* If it's an IPv4 packet set the BDC header priority based on the DSCP field */ - if (((ether_type == WHD_ETHERTYPE_IPv4) || (ether_type == WHD_ETHERTYPE_DOT1AS)) && (dscp != NULL)) { - if (*dscp != 0) /* If it's equal 0 then it's best effort traffic and nothing needs to be done */ - { - priority = whd_map_dscp_to_priority(whd_driver, *dscp); - } - } - - /* If STA interface, re-map prio to the prio allowed by the AP, regardless of whether it's an IPv4 packet */ - if (ifp->role == WHD_STA_ROLE) { - packet->bdc_header.priority = whd_tos_map[priority]; - } - else { - packet->bdc_header.priority = priority; - } - - packet->bdc_header.flags2 = ifp->bsscfgidx; - packet->bdc_header.data_offset = 0; - - /* Add the length of the BDC header and pass "down" */ - return whd_send_to_bus(whd_driver, buffer, DATA_HEADER, packet->bdc_header.priority); + whd_cdc_bdc_info_t *cdc_bdc_info = whd_driver->proto->pd; + whd_error_info_t *error_info = &whd_driver->error_info; + + /* Delete the sleep mutex */ + (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_sleep); + + /* Delete the queue mutex. */ + (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); + + /* Delete the event list management mutex */ + (void)cy_rtos_deinit_semaphore(&cdc_bdc_info->event_list_mutex); + + whd_driver->proto->pd = NULL; + whd_mem_free(cdc_bdc_info); + + /* Delete the error list management mutex */ + (void)cy_rtos_deinit_semaphore(&error_info->event_list_mutex); } -/** A helper function to easily acquire and initialise a buffer destined for use as an ioctl - * - * @param buffer : A pointer to a whd_buffer_t object where the created buffer will be stored - * @param data_length : The length of space reserved for user data - * - * @return A pointer to the start of user data with data_length space available - */ -void *whd_cdc_get_ioctl_buffer(whd_driver_t whd_driver, - whd_buffer_t *buffer, - uint16_t data_length) +whd_result_t whd_cdc_bdc_info_init(whd_driver_t whd_driver) { - if ((uint32_t)IOCTL_OFFSET + data_length > USHRT_MAX) { - WPRINT_WHD_ERROR(("The reserved ioctl buffer length is over %u\n", USHRT_MAX)); - return NULL; - } - if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, (uint16_t)(IOCTL_OFFSET + data_length), - (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) { - return (whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer) + IOCTL_OFFSET); - } - else { - WPRINT_WHD_ERROR(("Error - failed to allocate a packet buffer for IOCTL\n")); - return NULL; - } + whd_cdc_bdc_info_t *cdc_bdc_info; + whd_error_info_t *error_info = &whd_driver->error_info; + + cdc_bdc_info = (whd_cdc_bdc_info_t *)whd_mem_malloc(sizeof(whd_cdc_bdc_info_t) ); + if (!cdc_bdc_info) + { + return WHD_MALLOC_FAILURE; + } + + /* Create the mutex protecting the packet send queue */ + if (cy_rtos_init_semaphore(&cdc_bdc_info->ioctl_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Create the event flag which signals the whd thread needs to wake up */ + if (cy_rtos_init_semaphore(&cdc_bdc_info->ioctl_sleep, 1, 0) != WHD_SUCCESS) + { + cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); + return WHD_SEMAPHORE_ERROR; + } + + /* Create semaphore to protect event list management */ + if (cy_rtos_init_semaphore(&cdc_bdc_info->event_list_mutex, 1, 0) != WHD_SUCCESS) + { + cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_sleep); + cy_rtos_deinit_semaphore(&cdc_bdc_info->ioctl_mutex); + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Initialise the list of event handler functions */ + memset(cdc_bdc_info->whd_event_list, 0, sizeof(cdc_bdc_info->whd_event_list) ); + + /* Create semaphore to protect event list management */ + if (cy_rtos_init_semaphore(&error_info->event_list_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + + if (cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Initialise the list of error handler functions */ + memset(error_info->whd_event_list, 0, sizeof(error_info->whd_event_list) ); + + whd_driver->proto->get_ioctl_buffer = whd_cdc_get_ioctl_buffer; + whd_driver->proto->get_iovar_buffer = whd_cdc_get_iovar_buffer; + whd_driver->proto->set_ioctl = whd_cdc_set_ioctl; + whd_driver->proto->get_ioctl = whd_cdc_get_ioctl; + whd_driver->proto->set_iovar = whd_cdc_set_iovar; + whd_driver->proto->get_iovar = whd_cdc_get_iovar; + whd_driver->proto->tx_queue_data = whd_cdc_tx_queue_data; + whd_driver->proto->pd = cdc_bdc_info; + + return WHD_SUCCESS; } /** Processes CDC header information received in the RX packet and sets IOCTL response buffer @@ -475,47 +558,53 @@ void *whd_cdc_get_ioctl_buffer(whd_driver_t whd_driver, void whd_process_cdc(whd_driver_t whd_driver, whd_buffer_t buffer) { - uint32_t flags; - uint16_t id; - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - whd_result_t result; - cdc_header_t *cdc_header = (cdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - whd_result_t ioctl_mutex_res; - CHECK_PACKET_WITH_NULL_RETURN(cdc_header); - flags = dtoh32(cdc_header->flags); - id = (uint16_t)((flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT); - - /* Validate request ioctl ID and check if whd_cdc_send_ioctl is still waiting for response*/ - if (((ioctl_mutex_res = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_mutex, 0, WHD_FALSE)) != WHD_SUCCESS) && - (id == cdc_bdc_info->requested_ioctl_id)) { - /* Save the response packet in a variable */ - cdc_bdc_info->ioctl_response = buffer; - - WPRINT_WHD_DATA_LOG(("Wcd:< Procd pkt 0x%08lX: IOCTL Response\n", (unsigned long)buffer)); - - /* Wake the thread which sent the IOCTL/IOVAR so that it will resume */ - result = cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_sleep, WHD_FALSE); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - } - else { - WPRINT_WHD_ERROR(("Received buffer request ID: %d (expectation: %d)\n", - id, cdc_bdc_info->requested_ioctl_id)); - if (ioctl_mutex_res == WHD_SUCCESS) { - WPRINT_WHD_ERROR(("whd_cdc_send_ioctl is already timed out, drop the buffer\n")); - result = cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - } - } - else { - WPRINT_WHD_ERROR(("Received a response for a different IOCTL - retry\n")); - } - - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - } + uint32_t flags; + uint16_t id; + whd_cdc_bdc_info_t *cdc_bdc_info = whd_driver->proto->pd; + whd_result_t result; + cdc_header_t *cdc_header = (cdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + whd_result_t ioctl_mutex_res; + CHECK_PACKET_WITH_NULL_RETURN(cdc_header); + flags = dtoh32(cdc_header->flags); + id = (uint16_t)( (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT ); + + /* Validate request ioctl ID and check if whd_cdc_send_ioctl is still waiting for response*/ + if ( ( (ioctl_mutex_res = cy_rtos_get_semaphore(&cdc_bdc_info->ioctl_mutex, 0, WHD_FALSE) ) != WHD_SUCCESS ) && + (id == cdc_bdc_info->requested_ioctl_id) ) + { + /* Save the response packet in a variable */ + cdc_bdc_info->ioctl_response = buffer; + + WPRINT_WHD_DATA_LOG( ("Wcd:< Procd pkt 0x%08lX: IOCTL Response\n", (unsigned long)buffer) ); + + /* Wake the thread which sent the IOCTL/IOVAR so that it will resume */ + result = cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_sleep, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + } + else + { + WPRINT_WHD_ERROR( ("Received buffer request ID: %d (expectation: %d)\n", + id, cdc_bdc_info->requested_ioctl_id) ); + if (ioctl_mutex_res == WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_cdc_send_ioctl is already timed out, drop the buffer\n") ); + result = cy_rtos_set_semaphore(&cdc_bdc_info->ioctl_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + } + else + { + WPRINT_WHD_ERROR( ("Received a response for a different IOCTL - retry\n") ); + } + + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + } } /** Processes BDC header information received in the RX packet and sends data to network stack @@ -526,43 +615,45 @@ void whd_process_cdc(whd_driver_t whd_driver, whd_buffer_t buffer) void whd_process_bdc(whd_driver_t whd_driver, whd_buffer_t buffer) { - int32_t headers_len_below_payload; - uint32_t ip_data_start_add; - uint32_t bssid_index; - whd_interface_t ifp; - whd_result_t result; - bdc_header_t *bdc_header = (bdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - CHECK_PACKET_WITH_NULL_RETURN(bdc_header); - /* Calculate where the payload is */ - headers_len_below_payload = - (int32_t)((int32_t)BDC_HEADER_LEN + (int32_t)(bdc_header->data_offset << 2)); - - /* Move buffer pointer past gSPI, BUS, BCD headers and padding, + int32_t headers_len_below_payload; + uint32_t ip_data_start_add; + uint32_t bssid_index; + whd_interface_t ifp; + whd_result_t result; + bdc_header_t *bdc_header = (bdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_WITH_NULL_RETURN(bdc_header); + /* Calculate where the payload is */ + headers_len_below_payload = + (int32_t)( (int32_t)BDC_HEADER_LEN + (int32_t)(bdc_header->data_offset << 2) ); + + /* Move buffer pointer past gSPI, BUS, BCD headers and padding, * so that the network stack or 802.11 monitor sees only the payload */ - if (WHD_SUCCESS != whd_buffer_add_remove_at_front(whd_driver, &buffer, headers_len_below_payload)) { - WPRINT_WHD_ERROR(("No space for headers without chaining. this should never happen\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - - return; - } - - /* It is preferable to have IP data at address aligned to 4 bytes. IP data startes after ethernet header */ - ip_data_start_add = - (uint32_t)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + WHD_ETHERNET_SIZE; - if (((ip_data_start_add >> 2) << 2) != ip_data_start_add) { - WPRINT_WHD_DATA_LOG(("IP data not aligned to 4 bytes %lx\n", ip_data_start_add)); - } - - WPRINT_WHD_DATA_LOG(("Wcd:< Procd pkt 0x%08lX\n", (unsigned long)buffer)); - bssid_index = (uint32_t)(bdc_header->flags2 & BDC_FLAG2_IF_MASK); - ifp = whd_driver->iflist[bssid_index]; - - /* Send packet to bottom of network stack */ - result = whd_network_process_ethernet_data(ifp, buffer); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("%s failed at %d \n", __func__, __LINE__)); + if (WHD_SUCCESS != whd_buffer_add_remove_at_front(whd_driver, &buffer, headers_len_below_payload) ) + { + WPRINT_WHD_ERROR( ("No space for headers without chaining. this should never happen\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + return; + } + + /* It is preferable to have IP data at address aligned to 4 bytes. IP data startes after ethernet header */ + ip_data_start_add = + (uint32_t )whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + WHD_ETHERNET_SIZE; + if ( ( (ip_data_start_add >> 2) << 2 ) != ip_data_start_add ) + { + WPRINT_WHD_DATA_LOG( ("IP data not aligned to 4 bytes %lx\n", ip_data_start_add) ); + } + + WPRINT_WHD_DATA_LOG( ("Wcd:< Procd pkt 0x%08lX\n", (unsigned long)buffer) ); + bssid_index = (uint32_t)(bdc_header->flags2 & BDC_FLAG2_IF_MASK); + ifp = whd_driver->iflist[bssid_index]; + + /* Send packet to bottom of network stack */ + result = whd_network_process_ethernet_data(ifp, buffer); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("%s failed at %d \n", __func__, __LINE__) ); } /** Processes BDC header information and extracts the event packets @@ -575,130 +666,146 @@ void whd_process_bdc(whd_driver_t whd_driver, whd_buffer_t buffer) */ void whd_process_bdc_event(whd_driver_t whd_driver, whd_buffer_t buffer, uint16_t size) { - uint16_t ether_type; - whd_event_header_t *whd_event; - whd_event_t *event, *aligned_event = (whd_event_t *)whd_driver->aligned_addr; - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - whd_result_t result; - bdc_header_t *bdc_header = (bdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - uint16_t i; - uint16_t j; - uint32_t datalen; - - CHECK_PACKET_WITH_NULL_RETURN(bdc_header); - event = (whd_event_t *)&bdc_header[bdc_header->data_offset + 1]; - - ether_type = ntoh16(event->eth.ethertype); - - /* If frame is truly an event, it should have EtherType equal to the Broadcom type. */ - if (ether_type != (uint16_t)ETHER_TYPE_BRCM) { - WPRINT_WHD_DEBUG(("Error - received a channel 1 packet which was not BRCM ethertype\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return; - } - - /* If ethertype is correct, the contents of the ethernet packet + uint16_t ether_type; + whd_event_header_t *whd_event; + whd_event_t *event, *aligned_event = (whd_event_t *)whd_driver->aligned_addr; + whd_cdc_bdc_info_t *cdc_bdc_info = whd_driver->proto->pd; + whd_result_t result; + bdc_header_t *bdc_header = (bdc_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + uint16_t i; + uint16_t j; + uint32_t datalen, addr; + + CHECK_PACKET_WITH_NULL_RETURN(bdc_header); + event = (whd_event_t *)&bdc_header[bdc_header->data_offset + 1]; + + ether_type = ntoh16(event->eth.ethertype); + + /* If frame is truly an event, it should have EtherType equal to the Broadcom type. */ + if (ether_type != (uint16_t)ETHER_TYPE_BRCM) + { + WPRINT_WHD_DEBUG( ("Error - received a channel 1 packet which was not BRCM ethertype\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* If ethertype is correct, the contents of the ethernet packet * are a structure of type bcm_event_t */ - /* Check that the OUI matches the Broadcom OUI */ - if (0 != memcmp(BRCM_OUI, &event->eth_evt_hdr.oui[0], (size_t)DOT11_OUI_LEN)) { - WPRINT_WHD_DEBUG(("Event OUI mismatch\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return; - } + /* Check that the OUI matches the Broadcom OUI */ + if (0 != memcmp(BRCM_OUI, &event->eth_evt_hdr.oui[0], (size_t)DOT11_OUI_LEN) ) + { + WPRINT_WHD_DEBUG( ("Event OUI mismatch\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } - whd_event = &event->whd_event; + whd_event = &event->whd_event; - /* Search for the event type in the list of event handler functions + /* Search for the event type in the list of event handler functions * event data is stored in network endianness */ - whd_event->flags = ntoh16(whd_event->flags); - whd_event->event_type = (whd_event_num_t)ntoh32(whd_event->event_type); - whd_event->status = (whd_event_status_t)ntoh32(whd_event->status); - whd_event->reason = (whd_event_reason_t)ntoh32(whd_event->reason); - whd_event->auth_type = ntoh32(whd_event->auth_type); - whd_event->datalen = ntoh32(whd_event->datalen); - - /* Ensure data length is correct */ - if (whd_event->datalen > - (uint32_t)(size - ((char *)DATA_AFTER_HEADER(event) - (char *)bdc_header))) { - WPRINT_WHD_ERROR(( - "Error - (data length received [%d] > expected data length [%d]). Bus header packet size = [%d]. Ignoring the packet\n", - (int)whd_event->datalen, - size - ((char *)DATA_AFTER_HEADER(event) - (char *)bdc_header), - size)); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - - return; - } - - /* This is necessary because people who defined event statuses and reasons overlapped values. */ - if (whd_event->event_type == WLC_E_PSK_SUP) { - whd_event->status = (whd_event_status_t)((int)whd_event->status + WLC_SUP_STATUS_OFFSET); - whd_event->reason = (whd_event_reason_t)((int)whd_event->reason + WLC_E_SUP_REASON_OFFSET); - } - else if (whd_event->event_type == WLC_E_PRUNE) { - whd_event->reason = (whd_event_reason_t)((int)whd_event->reason + WLC_E_PRUNE_REASON_OFFSET); - } - else if ((whd_event->event_type == WLC_E_DISASSOC) || (whd_event->event_type == WLC_E_DEAUTH)) { - whd_event->status = (whd_event_status_t)((int)whd_event->status + WLC_DOT11_SC_STATUS_OFFSET); - whd_event->reason = (whd_event_reason_t)((int)whd_event->reason + WLC_E_DOT11_RC_REASON_OFFSET); - } - - /* do any needed debug logging of event */ - WHD_IOCTL_LOG_ADD_EVENT(whd_driver, whd_event->event_type, whd_event->status, - whd_event->reason); - - if (cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) { - WPRINT_WHD_DEBUG(("Failed to obtain mutex for event list access!\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return; - } - - datalen = whd_event->datalen; - /* use memcpy to get aligned event message */ - if (aligned_event) { - memcpy(aligned_event, event, sizeof(*event) + datalen); - } - else { - aligned_event = event; - } - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - if (cdc_bdc_info->whd_event_list[i].event_set) { - for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; ++j) { - if ((cdc_bdc_info->whd_event_list[i].events[j] == whd_event->event_type) && - (cdc_bdc_info->whd_event_list[i].ifidx == whd_event->ifidx)) { - /* Correct event type has been found - call the handler function and exit loop */ - cdc_bdc_info->whd_event_list[i].handler_user_data = - cdc_bdc_info->whd_event_list[i].handler(whd_driver->iflist[whd_event->bsscfgidx], - whd_event, - (uint8_t *)DATA_AFTER_HEADER( - aligned_event), - cdc_bdc_info->whd_event_list[i].handler_user_data); - break; - } - } - } - } - - result = cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - - WPRINT_WHD_DATA_LOG(("Wcd:< Procd pkt 0x%08lX: Evnt %d (%d bytes)\n", (unsigned long)buffer, - (int)whd_event->event_type, size)); - - /* Release the event packet buffer */ - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); + whd_event->flags = ntoh16(whd_event->flags); + whd_event->event_type = (whd_event_num_t)ntoh32(whd_event->event_type); + whd_event->status = (whd_event_status_t)ntoh32(whd_event->status); + whd_event->reason = (whd_event_reason_t)ntoh32(whd_event->reason); + whd_event->auth_type = ntoh32(whd_event->auth_type); + whd_event->datalen = ntoh32(whd_event->datalen); + + /* Ensure data length is correct */ + if (whd_event->datalen > + (uint32_t)(size - ( (char *)DATA_AFTER_HEADER(event) - (char *)bdc_header ) ) ) + { + WPRINT_WHD_ERROR( ( + "Error - (data length received [%d] > expected data length [%d]). Bus header packet size = [%d]. Ignoring the packet\n", + (int)whd_event->datalen, + size - ( (char *)DATA_AFTER_HEADER(event) - (char *)bdc_header ), + size) ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + return; + } + + /* This is necessary because people who defined event statuses and reasons overlapped values. */ + if (whd_event->event_type == WLC_E_PSK_SUP) + { + whd_event->status = (whd_event_status_t)( (int)whd_event->status + WLC_SUP_STATUS_OFFSET ); + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_SUP_REASON_OFFSET ); + } + else if (whd_event->event_type == WLC_E_PRUNE) + { + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_PRUNE_REASON_OFFSET ); + } + else if ( (whd_event->event_type == WLC_E_DISASSOC) || (whd_event->event_type == WLC_E_DEAUTH) ) + { + whd_event->status = (whd_event_status_t)( (int)whd_event->status + WLC_DOT11_SC_STATUS_OFFSET ); + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_DOT11_RC_REASON_OFFSET ); + } + + /* do any needed debug logging of event */ + WHD_IOCTL_LOG_ADD_EVENT(whd_driver, whd_event->event_type, whd_event->status, + whd_event->reason); + + if (cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("Failed to obtain mutex for event list access!\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + datalen = whd_event->datalen; + /* use memcpy to get aligned event message */ + addr = (uint32_t )DATA_AFTER_HEADER(event); + if (aligned_event && (addr & ALIGNED_ADDRESS) ) + { + memcpy(aligned_event, (whd_event_t *)addr, datalen); + } + else + { + aligned_event = (whd_event_t *)addr; + } + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + if (cdc_bdc_info->whd_event_list[i].event_set) + { + for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; ++j) + { + if ( (cdc_bdc_info->whd_event_list[i].events[j] == whd_event->event_type) && + (cdc_bdc_info->whd_event_list[i].ifidx == whd_event->ifidx) ) + { + /* Correct event type has been found - call the handler function and exit loop */ + cdc_bdc_info->whd_event_list[i].handler_user_data = + cdc_bdc_info->whd_event_list[i].handler(whd_driver->iflist[whd_event->bsscfgidx], + whd_event, + (uint8_t *)aligned_event, + cdc_bdc_info->whd_event_list[i].handler_user_data); + break; + } + } + } + } + + result = cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + WPRINT_WHD_DATA_LOG( ("Wcd:< Procd pkt 0x%08lX: Evnt %d (%d bytes)\n", (unsigned long)buffer, + (int)whd_event->event_type, size) ); + + /* Release the event packet buffer */ + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + } + +#endif /* PROTO_MSGBUF */ diff --git a/wi-fi/whd/whd_cdc_bdc.h b/wi-fi/whd/whd_cdc_bdc.h index 3f3fc41d..c48b9626 100644 --- a/wi-fi/whd/whd_cdc_bdc.h +++ b/wi-fi/whd/whd_cdc_bdc.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,13 +18,15 @@ #ifndef INCLUDED_WHD_CDC_BDC_H #define INCLUDED_WHD_CDC_BDC_H +#ifndef PROTO_MSGBUF #include "whd.h" #include "cyabs_rtos.h" #include "whd_events_int.h" #include "whd_types_int.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -32,28 +34,29 @@ extern "C" { ******************************************************/ /* CDC flag definition taken from bcmcdc.h */ -#define CDCF_IOC_SET (0x02) /** 0=get, 1=set cmd */ -#define WHD_EVENT_HANDLER_LIST_SIZE (5) /** Maximum number of simultaneously registered event handlers */ -#define WHD_SDALIGN 32 +#define CDCF_IOC_SET (0x02) /** 0=get, 1=set cmd */ +#define WHD_EVENT_HANDLER_LIST_SIZE (5) /** Maximum number of simultaneously registered event handlers */ +#define WHD_SDALIGN 32 /* CDC flag definitions taken from bcmcdc.h */ -#define CDCF_IOC_ERROR (0x01) /** 0=success, 1=ioctl cmd failed */ -#define CDCF_IOC_IF_MASK (0xF000) /** I/F index */ -#define CDCF_IOC_IF_SHIFT (12) /** # of bits of shift for I/F Mask */ -#define CDCF_IOC_ID_MASK (0xFFFF0000) /** used to uniquely id an ioctl req/resp pairing */ -#define CDCF_IOC_ID_SHIFT (16) /** # of bits of shift for ID Mask */ +#define CDCF_IOC_ERROR (0x01) /** 0=success, 1=ioctl cmd failed */ +#define CDCF_IOC_IF_MASK (0xF000) /** I/F index */ +#define CDCF_IOC_IF_SHIFT (12) /** # of bits of shift for I/F Mask */ +#define CDCF_IOC_ID_MASK (0xFFFF0000) /** used to uniquely id an ioctl req/resp pairing */ +#define CDCF_IOC_ID_SHIFT (16) /** # of bits of shift for ID Mask */ -#define DATA_AFTER_HEADER(x) ((void *)(&x[1])) +#define DATA_AFTER_HEADER(x) ( (void *)(&x[1]) ) -#define BDC_HEADER_LEN (4) +#define BDC_HEADER_LEN (4) /****************************************************** * Enumerations ******************************************************/ -typedef enum sdpcm_command_type_enum { - CDC_GET = 0x00, - CDC_SET = CDCF_IOC_SET +typedef enum sdpcm_command_type_enum +{ + CDC_GET = 0x00, + CDC_SET = CDCF_IOC_SET } cdc_command_type_t; /****************************************************** @@ -62,59 +65,46 @@ typedef enum sdpcm_command_type_enum { #pragma pack(1) typedef struct { - uint32_t cmd; /* ioctl command value */ - uint32_t len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ - uint32_t flags; /* flag defns given in bcmcdc.h */ - uint32_t status; /* status code returned from the device */ + uint32_t cmd; /* ioctl command value */ + uint32_t len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */ + uint32_t flags; /* flag defns given in bcmcdc.h */ + uint32_t status; /* status code returned from the device */ } cdc_header_t; typedef struct { - uint8_t flags; /* Flags */ - uint8_t priority; /* 802.1d Priority (low 3 bits) */ - uint8_t flags2; - uint8_t data_offset; /* Offset from end of BDC header to packet data, in 4-uint8_t words. + uint8_t flags; /* Flags */ + uint8_t priority; /* 802.1d Priority (low 3 bits) */ + uint8_t flags2; + uint8_t data_offset; /* Offset from end of BDC header to packet data, in 4-uint8_t words. * Leaves room for optional headers.*/ } bdc_header_t; typedef struct { - whd_mac_t destination_address; - whd_mac_t source_address; - uint16_t ethertype; + whd_mac_t destination_address; + whd_mac_t source_address; + uint16_t ethertype; } ethernet_header_t; #pragma pack() -/** Event list element structure - * - * events : A pointer to a whd_event_num_t array that is terminated with a WLC_E_NONE event - * handler: A pointer to the whd_event_handler_t function that will receive the event - * handler_user_data : User provided data that will be passed to the handler when a matching event occurs - */ -typedef struct -{ - whd_bool_t event_set; - whd_event_num_t events[WHD_MAX_EVENT_SUBSCRIPTION]; - whd_event_handler_t handler; - void *handler_user_data; - uint8_t ifidx; -} event_list_elem_t; - /** @endcond */ typedef struct whd_cdc_info { - /* Event list variables */ + /* Event list variables (Must be at the beginning) */ event_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; cy_semaphore_t event_list_mutex; - /* IOCTL variables*/ - uint16_t requested_ioctl_id; - cy_semaphore_t ioctl_mutex; - whd_buffer_t ioctl_response; - cy_semaphore_t ioctl_sleep; + /* IOCTL variables*/ + uint16_t requested_ioctl_id; + cy_semaphore_t ioctl_mutex; + whd_buffer_t ioctl_response; + cy_semaphore_t ioctl_sleep; } whd_cdc_bdc_info_t; + +#ifndef PROTO_MSGBUF /** Error list element structure * * events : set event of error type @@ -123,44 +113,45 @@ typedef struct whd_cdc_info { */ typedef struct { - whd_error_handler_t handler; - void *handler_user_data; - whd_bool_t event_set; - uint8_t events; + whd_error_handler_t handler; + void *handler_user_data; + whd_bool_t event_set; + uint8_t events; } error_list_elem_t; /** @endcond */ -typedef struct whd_error_info { - /* Event list variables */ - error_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; - cy_semaphore_t event_list_mutex; +typedef struct whd_error_info +{ + /* Event list variables */ + error_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; + cy_semaphore_t event_list_mutex; } whd_error_info_t; +#endif /****************************************************** * Function Declarations ******************************************************/ whd_result_t whd_cdc_bdc_info_init(whd_driver_t whd_driver); -void whd_cdc_bdc_info_deinit(whd_driver_t whd_driver); +void whd_cdc_bdc_info_deinit(whd_driver_t whd_driver); whd_result_t whd_cdc_send_iovar(whd_interface_t ifp, cdc_command_type_t type, - whd_buffer_t send_buffer_hnd, - whd_buffer_t *response_buffer_hnd); + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd); whd_result_t whd_cdc_send_ioctl(whd_interface_t ifp, cdc_command_type_t type, uint32_t command, - whd_buffer_t send_buffer_hnd, - whd_buffer_t *response_buffer_hnd); + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd); void *whd_cdc_get_iovar_buffer(whd_driver_t whd_driver, - whd_buffer_t *buffer, - uint16_t data_length, - const char *name); -whd_result_t whd_network_send_ethernet_data(whd_interface_t ifp, whd_buffer_t buffer); + whd_buffer_t *buffer, + uint16_t data_length, + const char *name); void *whd_cdc_get_ioctl_buffer(whd_driver_t whd_driver, - whd_buffer_t *buffer, - uint16_t data_length); + whd_buffer_t *buffer, + uint16_t data_length); void whd_process_cdc(whd_driver_t whd_driver, whd_buffer_t buffer); @@ -172,4 +163,6 @@ void whd_process_bdc_event(whd_driver_t whd_driver, whd_buffer_t buffer, uint16_ } /* extern "C" */ #endif +#endif /* PROTO_MSGBUF */ + #endif /* ifndef INCLUDED_WHD_CDC_BDC_H */ diff --git a/wi-fi/whd/whd_chip.c b/wi-fi/whd/whd_chip.c index 304a0a3e..9b2e946b 100644 --- a/wi-fi/whd/whd_chip.c +++ b/wi-fi/whd/whd_chip.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,13 +15,14 @@ * limitations under the License. */ -#include #include "bus_protocols/whd_chip_reg.h" #include "bus_protocols/whd_sdio.h" #include "bus_protocols/whd_bus_common.h" #include "bus_protocols/whd_bus_protocol_interface.h" #include "whd_chip_constants.h" +#ifndef PROTO_MSGBUF #include "whd_cdc_bdc.h" +#endif /* PROTO_MSGBUF */ #include "whd_thread_internal.h" #include "whd_buffer_api.h" #include "whd_debug.h" @@ -30,43 +31,52 @@ #include "whd_chip.h" #include "whd.h" #include "whd_wlioctl.h" - +#include "whd_proto.h" +#ifdef PROTO_MSGBUF +#include "whd_ring.h" +#endif /****************************************************** * Macros ******************************************************/ -#define SPINWAIT_POLL_PERIOD 10 - -#define SPINWAIT(exp, us) \ - { \ - uint countdown = (us) + (SPINWAIT_POLL_PERIOD - 1); \ - while ((exp) && (countdown >= SPINWAIT_POLL_PERIOD)) { \ - cy_rtos_delay_milliseconds(SPINWAIT_POLL_PERIOD); \ - countdown -= SPINWAIT_POLL_PERIOD; \ - } \ - } +#define SPINWAIT_POLL_PERIOD 10 + +#define SPINWAIT(exp, us) { \ + uint countdown = (us) + (SPINWAIT_POLL_PERIOD - 1); \ + while ( (exp) && (countdown >= SPINWAIT_POLL_PERIOD) ){ \ + cy_rtos_delay_milliseconds(SPINWAIT_POLL_PERIOD); \ + countdown -= SPINWAIT_POLL_PERIOD; \ + } \ +} /****************************************************** * Constants ******************************************************/ -#define PLATFORM_WLAN_RAM_BASE (0x0) -#define WLAN_BUS_UP_ATTEMPTS (1000) -#define HT_AVAIL_WAIT_MS (1) -#define KSO_WAIT_MS (1) -#define KSO_WAKE_MS (3) -#define MAX_KSO_ATTEMPTS (64) - -#define AI_IOCTRL_OFFSET (0x408) -#define SICF_FGC (0x0002) -#define SICF_CLOCK_EN (0x0001) -#define AI_RESETCTRL_OFFSET (0x800) -#define AI_RESETSTATUS_OFFSET (0x804) -#define AIRC_RESET (1) -#define WRAPPER_REGISTER_OFFSET (0x100000) - -#define WLAN_SHARED_VERSION_MASK (0x00ff) -#define WLAN_SHARED_VERSION (0x0001) +#define PLATFORM_WLAN_RAM_BASE (0x0) +#define WLAN_BUS_UP_ATTEMPTS (1000) +#define HT_AVAIL_WAIT_MS (1) +#define KSO_WAIT_MS (1) +#define KSO_WAKE_MS (3) +#define MAX_KSO_ATTEMPTS (64) +#define MAX_CAPS_BUFFER_SIZE (768) + +#define AI_IOCTRL_OFFSET (0x408) +#define SICF_FGC (0x0002) +#define SICF_CLOCK_EN (0x0001) +#define AI_RESETCTRL_OFFSET (0x800) +#define AI_RESETSTATUS_OFFSET (0x804) +#define AIRC_RESET (1) +#define WRAPPER_REGISTER_OFFSET (0x100000) + +#define WLAN_SHARED_VERSION_MASK (0x00ff) +#define WLAN_SHARED_VERSION (0x0003) #define WPRINT_WHD_DEBUG_DS(args) WPRINT_WHD_DEBUG(args) +#ifdef CYCFG_ULP_SUPPORT_ENABLED +#define WAKE_FROM_UCODE_TIMEOUT_MS (5000) //5000 ms +#define WAKE_FROM_UCODE_TIMEOUT_LOOPS (100) +#define WAKE_FROM_UCODE_CHECK_PER_LOOP (WAKE_FROM_UCODE_TIMEOUT_MS/WAKE_FROM_UCODE_TIMEOUT_LOOPS) //50 ms +#endif + /****************************************************** * Structures ******************************************************/ @@ -74,8 +84,13 @@ /****************************************************** * Variables ******************************************************/ - - +static const whd_fwcap_t whd_fwcap_map[] = +{ + {WHD_FWCAP_SAE, "sae "}, + {WHD_FWCAP_SAE_EXT, "sae_ext "}, + {WHD_FWCAP_OFFLOADS, "offloads "}, + {WHD_FWCAP_GCMP, "gcmp" }, +}; /****************************************************** * Static Function Declarations ******************************************************/ @@ -88,21 +103,40 @@ static whd_result_t whd_enable_save_restore(whd_driver_t whd_driver); /****************************************************** * Function definitions ******************************************************/ -void whd_internal_info_init(whd_driver_t whd_driver) +whd_result_t whd_internal_info_init(whd_driver_t whd_driver) +{ + whd_internal_info_t *internal_info = &whd_driver->internal_info; + + internal_info->whd_wlan_status.state = WLAN_OFF; + internal_info->whd_wlan_status.country_code = WHD_COUNTRY_AUSTRALIA; + internal_info->whd_wlan_status.aggregate_code = WHD_COUNTRY_AGGREGATE_XV_0; + internal_info->whd_wlan_status.keep_wlan_awake = 0; + internal_info->console_addr = 0; + internal_info->scan_result_callback = NULL; + internal_info->whd_scan_result_ptr = NULL; + internal_info->active_join_mutex_initted = WHD_FALSE; + internal_info->active_join_semaphore = NULL; + internal_info->con_lastpos = 0; + internal_info->whd_wifi_p2p_go_is_up = WHD_FALSE; + + /* Create the mutex protecting whd_log structure */ + if (cy_rtos_init_semaphore(&whd_driver->whd_log_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + return WHD_SUCCESS; +} + +whd_result_t whd_internal_info_deinit(whd_driver_t whd_driver) { - whd_internal_info_t *internal_info = &whd_driver->internal_info; - - internal_info->whd_wlan_status.state = WLAN_OFF; - internal_info->whd_wlan_status.country_code = WHD_COUNTRY_AUSTRALIA; - internal_info->whd_wlan_status.aggregate_code = WHD_COUNTRY_AGGREGATE_XV_0; - internal_info->whd_wlan_status.keep_wlan_awake = 0; - internal_info->console_addr = 0; - internal_info->scan_result_callback = NULL; - internal_info->whd_scan_result_ptr = NULL; - internal_info->active_join_mutex_initted = WHD_FALSE; - internal_info->active_join_semaphore = NULL; - internal_info->con_lastpos = 0; - internal_info->whd_wifi_p2p_go_is_up = WHD_FALSE; + /* Delete the whd_log mutex */ + (void)cy_rtos_deinit_semaphore(&whd_driver->whd_log_mutex); + return WHD_SUCCESS; } /* @@ -110,20 +144,25 @@ void whd_internal_info_init(whd_driver_t whd_driver) */ uint32_t whd_get_core_address(whd_driver_t whd_driver, device_core_t core_id) { - if (core_id == WLAN_ARM_CORE) { - return GET_C_VAR(whd_driver, ARM_CORE_BASE_ADDRESS); - } - else if (core_id == SOCRAM_CORE) { - return GET_C_VAR(whd_driver, SOCSRAM_WRAPPER_BASE_ADDRESS); - } - else if (core_id == SDIOD_CORE) { - return GET_C_VAR(whd_driver, SDIOD_CORE_BASE_ADDRESS); - } - else { - WPRINT_WHD_ERROR(("%s:%d Invalid core ID(%d)\n", __FUNCTION__, __LINE__, core_id)); - } + if (core_id == WLAN_ARM_CORE) + { + return GET_C_VAR(whd_driver, ARM_CORE_BASE_ADDRESS); + } + else if (core_id == SOCRAM_CORE) + { + return GET_C_VAR(whd_driver, SOCSRAM_WRAPPER_BASE_ADDRESS); + } + else if (core_id == SDIOD_CORE) + { + return GET_C_VAR(whd_driver, SDIOD_CORE_BASE_ADDRESS); + } + else + { + WPRINT_WHD_ERROR( ("%s:%d Invalid core ID(%d)\n", __FUNCTION__, __LINE__, core_id) ); + } + + return WHD_BADARG; - return WHD_BADARG; } /* @@ -131,35 +170,39 @@ uint32_t whd_get_core_address(whd_driver_t whd_driver, device_core_t core_id) */ whd_result_t whd_device_core_is_up(whd_driver_t whd_driver, device_core_t core_id) { - uint8_t regdata; - uint32_t base; - whd_result_t result; - - base = whd_get_core_address(whd_driver, core_id); - - /* Read the IO control register */ - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, ®data); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - /* Verify that the clock is enabled and something else is not on */ - if ((regdata & (SICF_FGC | SICF_CLOCK_EN)) != (uint8_t)SICF_CLOCK_EN) { - return WHD_CORE_CLOCK_NOT_ENABLED; - } - - /* Read the reset control and verify it is not in reset */ - result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - if ((regdata & AIRC_RESET) != 0) { - return WHD_CORE_IN_RESET; - } - - return WHD_SUCCESS; + uint8_t regdata; + uint32_t base; + whd_result_t result; + + base = whd_get_core_address(whd_driver, core_id); + + /* Read the IO control register */ + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, ®data); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + /* Verify that the clock is enabled and something else is not on */ + if ( (regdata & (SICF_FGC | SICF_CLOCK_EN) ) != ( uint8_t )SICF_CLOCK_EN ) + { + return WHD_CORE_CLOCK_NOT_ENABLED; + } + + /* Read the reset control and verify it is not in reset */ + result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + if ( (regdata & AIRC_RESET) != 0 ) + { + return WHD_CORE_IN_RESET; + } + + return WHD_SUCCESS; } /* @@ -167,67 +210,59 @@ whd_result_t whd_device_core_is_up(whd_driver_t whd_driver, device_core_t core_i */ whd_result_t whd_reset_core(whd_driver_t whd_driver, device_core_t core_id, uint32_t bits, uint32_t resetbits) { - uint32_t base = whd_get_core_address(whd_driver, core_id); - whd_result_t result; - uint8_t regdata; - uint32_t loop_counter = 10; - /* ensure there are no pending backplane operations */ - SPINWAIT((((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0), - 300); - - /* put core into reset state */ - result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, (uint32_t)AIRC_RESET); - (void)cy_rtos_delay_milliseconds((uint32_t)10); /* Ignore return - nothing can be done if it fails */ - - /* ensure there are no pending backplane operations */ - SPINWAIT((((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0), - 300); - - result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (bits | resetbits | SICF_FGC | SICF_CLOCK_EN)); - - /* ensure there are no pending backplane operations */ - SPINWAIT((((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0), - 300); - - while (((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0 && - --loop_counter != 0) { - /* ensure there are no pending backplane operations */ - SPINWAIT((((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0), - 300); - /* take core out of reset */ - result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, (uint32_t)0); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - /* ensure there are no pending backplane operations */ - SPINWAIT((((result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, - ®data)) == WHD_SUCCESS) && - regdata != 0), - 300); - } - - result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, (bits | SICF_CLOCK_EN)); - - (void)cy_rtos_delay_milliseconds((uint32_t)1); /* Ignore return - nothing can be done if it fails */ - - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - return WHD_SUCCESS; + uint32_t base = whd_get_core_address(whd_driver, core_id); + whd_result_t result; + uint8_t regdata; + uint32_t loop_counter = 10; + /* ensure there are no pending backplane operations */ + SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 ); + + /* put core into reset state */ + result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ( uint32_t )AIRC_RESET); + (void)cy_rtos_delay_milliseconds( (uint32_t)10 ); /* Ignore return - nothing can be done if it fails */ + + /* ensure there are no pending backplane operations */ + SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 ); + + result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + (bits | resetbits | SICF_FGC | SICF_CLOCK_EN) ); + + /* ensure there are no pending backplane operations */ + SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 ); + + while ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 && + --loop_counter != 0 ) + { + /* ensure there are no pending backplane operations */ + SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 ); + /* take core out of reset */ + result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, (uint32_t)0); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + /* ensure there are no pending backplane operations */ + SPINWAIT( ( ( (result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETSTATUS_OFFSET, (uint8_t)1, + ®data) ) == WHD_SUCCESS ) && regdata != 0 ), 300 ); + } + + result = whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, (bits | SICF_CLOCK_EN) ); + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); /* Ignore return - nothing can be done if it fails */ + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + return WHD_SUCCESS; } /* @@ -235,55 +270,61 @@ whd_result_t whd_reset_core(whd_driver_t whd_driver, device_core_t core_id, uint */ whd_result_t whd_disable_device_core(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag) { - uint32_t base = whd_get_core_address(whd_driver, core_id); - whd_result_t result; - uint8_t junk; - uint8_t regdata; - - /* Read the reset control */ - result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - /* Read the reset control and check if it is already in reset */ - result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - if ((regdata & AIRC_RESET) != 0) { - /* Core already in reset */ - return WHD_SUCCESS; - } - - /* Write 0 to the IO control and read it back */ - result = - whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, (uint32_t)AIRC_RESET); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - return result; + uint32_t base = whd_get_core_address(whd_driver, core_id); + whd_result_t result; + uint8_t junk; + uint8_t regdata; + + /* Read the reset control */ + result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + /* Read the reset control and check if it is already in reset */ + result = whd_bus_read_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ®data); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + if ( (regdata & AIRC_RESET) != 0 ) + { + /* Core already in reset */ + return WHD_SUCCESS; + } + + /* Write 0 to the IO control and read it back */ + result = + whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, ( uint32_t )AIRC_RESET); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + return result; } /* @@ -291,56 +332,62 @@ whd_result_t whd_disable_device_core(whd_driver_t whd_driver, device_core_t core */ whd_result_t whd_reset_device_core(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag) { - uint32_t base = whd_get_core_address(whd_driver, core_id); - whd_result_t result; - uint8_t junk; - - result = whd_disable_device_core(whd_driver, core_id, core_flag); - if (result != WHD_SUCCESS) { - return result; - } - - result = - whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (uint32_t)(SICF_FGC | SICF_CLOCK_EN | - ((core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0))); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - result = - whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (uint32_t)(SICF_CLOCK_EN | - ((core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0))); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)) - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - return result; + uint32_t base = whd_get_core_address(whd_driver, core_id); + whd_result_t result; + uint8_t junk; + + result = whd_disable_device_core(whd_driver, core_id, core_flag); + if (result != WHD_SUCCESS) + { + return result; + } + + result = + whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + ( uint32_t )(SICF_FGC | SICF_CLOCK_EN | + ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + result = + whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + ( uint32_t )(SICF_CLOCK_EN | + ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ) + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + return result; } /* @@ -348,167 +395,221 @@ whd_result_t whd_reset_device_core(whd_driver_t whd_driver, device_core_t core_i */ whd_result_t whd_wlan_armcore_run(whd_driver_t whd_driver, device_core_t core_id, wlan_core_flag_t core_flag) { - uint32_t base = whd_get_core_address(whd_driver, core_id); - whd_result_t result; - uint8_t junk; - - /* Only work for WLAN arm core! */ - if (WLAN_ARM_CORE != core_id) { - return WHD_UNSUPPORTED; - } - - result = - whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (uint32_t)(SICF_FGC | SICF_CLOCK_EN | - ((core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0))); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)) - return result; - } - - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)) - return result; - } - - result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)) - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - result = - whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, - (uint32_t)(SICF_CLOCK_EN | - ((core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0))); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - return result; - } - - (void)cy_rtos_delay_milliseconds((uint32_t)1); - - return result; + uint32_t base = whd_get_core_address(whd_driver, core_id); + whd_result_t result; + uint8_t junk; + + /* Only work for WLAN arm core! */ + if (WLAN_ARM_CORE != core_id) + { + return WHD_UNSUPPORTED; + } + + result = + whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + ( uint32_t )(SICF_FGC | SICF_CLOCK_EN | + ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ) + return result; + } + + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ) + return result; + } + + result = whd_bus_write_backplane_value(whd_driver, base + AI_RESETCTRL_OFFSET, (uint8_t)1, 0); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ) + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + result = + whd_bus_write_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, + ( uint32_t )(SICF_CLOCK_EN | + ( (core_flag == WLAN_CORE_FLAG_CPU_HALT) ? SICF_CPUHALT : 0 ) ) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + result = whd_bus_read_backplane_value(whd_driver, base + AI_IOCTRL_OFFSET, (uint8_t)1, &junk); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + return result; + } + + (void)cy_rtos_delay_milliseconds( (uint32_t)1 ); + + return result; } whd_result_t whd_wifi_read_wlan_log_unsafe(whd_driver_t whd_driver, uint32_t wlan_shared_address, char *buffer, - uint32_t buffer_size) + uint32_t buffer_size) { - char ch; - uint32_t n; - uint32_t index; - uint32_t address; - whd_result_t result = WHD_WLAN_ERROR; - whd_internal_info_t *internal_info = &whd_driver->internal_info; - wifi_console_t *c = internal_info->c; - - c = &internal_info->console; - - if (internal_info->console_addr == 0) { - uint shared_addr; - - address = wlan_shared_address; - result = whd_bus_read_backplane_value(whd_driver, address, 4, (uint8_t *)&shared_addr); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - goto done; - } - - result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, shared_addr, sizeof(wlan_shared_t), - (uint8_t *)&internal_info->sh); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__)); - goto done; - } - - internal_info->sh.flags = dtoh32(internal_info->sh.flags); - internal_info->sh.trap_addr = dtoh32(internal_info->sh.trap_addr); - internal_info->sh.assert_exp_addr = dtoh32(internal_info->sh.assert_exp_addr); - internal_info->sh.assert_file_addr = dtoh32(internal_info->sh.assert_file_addr); - internal_info->sh.assert_line = dtoh32(internal_info->sh.assert_line); - internal_info->sh.console_addr = dtoh32(internal_info->sh.console_addr); - internal_info->sh.msgtrace_addr = dtoh32(internal_info->sh.msgtrace_addr); - - if ((internal_info->sh.flags & WLAN_SHARED_VERSION_MASK) != WLAN_SHARED_VERSION) { - WPRINT_WHD_ERROR(("Readconsole: WLAN shared version is not valid sh.flags %x\n\r", - internal_info->sh.flags)); - result = WHD_WLAN_INVALID; - goto done; - } - internal_info->console_addr = internal_info->sh.console_addr; - } - - /* Read console log struct */ - address = internal_info->console_addr + offsetof(hnd_cons_t, log); - result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, sizeof(c->log), (uint8_t *)&c->log); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__)); - goto done; - } - - /* Allocate console buffer (one time only) */ - if (c->buf == NULL) { - c->bufsize = dtoh32(c->log.buf_size); - c->buf = malloc(c->bufsize); - if (c->buf == NULL) { - WPRINT_WHD_ERROR(("%s:%d c->buf IS null \n", __FUNCTION__, __LINE__)); - result = WHD_WLAN_NOMEM; - goto done; - } - } + char ch; + uint32_t n; + uint32_t index; + uint32_t address; + whd_result_t result = WHD_WLAN_ERROR; + whd_internal_info_t *internal_info = &whd_driver->internal_info; + wifi_console_t *c = internal_info->c; + + c = &internal_info->console; + + uint32_t shared_addr = 0; + + address = wlan_shared_address; + + /* Once the FW starts executing it will update the Shared region space(4Bytes) - wlan_shared_address with the shared structure address, + this shared structure address should be the address FW RAM address so we need the boundary check for this */ + while ( (shared_addr == 0) || (shared_addr <= GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) ) || + (shared_addr >= (GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) ) ) ) + { + result = whd_bus_read_backplane_value(whd_driver, address, 4, (uint8_t *)&shared_addr); + } + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + goto done; + } + +#ifndef PROTO_MSGBUF + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, shared_addr, sizeof(wlan_shared_t), + (uint8_t *)&internal_info->sh); +#else + result = whd_bus_mem_bytes(whd_driver, BUS_READ, TRANS_ADDR( + shared_addr), sizeof(internal_info->sh), (uint8_t *)&internal_info->sh); +#endif - /* Retrieve last read position */ - c->last = whd_driver->internal_info.con_lastpos; + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) ); + goto done; + } + + internal_info->sh.flags = dtoh32(internal_info->sh.flags); + internal_info->sh.trap_addr = dtoh32(internal_info->sh.trap_addr); + internal_info->sh.assert_exp_addr = dtoh32(internal_info->sh.assert_exp_addr); + internal_info->sh.assert_file_addr = dtoh32(internal_info->sh.assert_file_addr); + internal_info->sh.assert_line = dtoh32(internal_info->sh.assert_line); + internal_info->sh.console_addr = dtoh32(internal_info->sh.console_addr); + internal_info->sh.msgtrace_addr = dtoh32(internal_info->sh.msgtrace_addr); + +#ifndef PROTO_MSGBUF + if ( (internal_info->sh.flags & WLAN_SHARED_VERSION_MASK) > WLAN_SHARED_VERSION ) + { + WPRINT_WHD_ERROR( ("Readconsole: WLAN shared version is not valid sh.flags %x\n\r", + internal_info->sh.flags) ); + result = WHD_WLAN_INVALID; + goto done; + } +#else + if ( (internal_info->sh.flags & WLAN_M2M_SHARED_VERSION_MASK) > WLAN_M2M_SHARED_VERSION ) + { + WPRINT_WHD_ERROR( ("ReadShared: WLAN shared version is not valid sh.flags %x\n\r", internal_info->sh.flags) ); + result = WHD_WLAN_INVALID; + goto done; + } +#endif - index = dtoh32(c->log.idx); + internal_info->console_addr = internal_info->sh.console_addr; - /* Protect against corrupt value */ - if (index > c->bufsize) { - WPRINT_WHD_ERROR(("%s:%d index > c->bufsize \n", __FUNCTION__, __LINE__)); - result = WHD_WLAN_BUFTOOSHORT; - goto done; - } + /* Read console log struct */ + address = internal_info->console_addr + offsetof(hnd_cons_t, log); - /* Skip reading the console buffer if the index pointer has not moved */ - if (index == c->last) { - result = WHD_SUCCESS; - goto done; - } +#ifndef PROTO_MSGBUF + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, sizeof(c->log), (uint8_t *)&c->log); +#else + result = whd_bus_mem_bytes(whd_driver, BUS_READ, TRANS_ADDR(address), sizeof(c->log), (uint8_t *)&c->log); +#endif - /* Read the console buffer */ - /* xxx this could optimize and read only the portion of the buffer needed, but + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) ); + goto done; + } + + /* Allocate console buffer (one time only) */ + if (c->buf == NULL) + { + c->bufsize = dtoh32(c->log.buf_size); + c->buf = whd_mem_malloc(c->bufsize); + if (c->buf == NULL) + { + WPRINT_WHD_ERROR( ("%s:%d c->buf IS null \n", __FUNCTION__, __LINE__) ); + result = WHD_WLAN_NOMEM; + goto done; + } + } + + /* Retrieve last read position */ + c->last = whd_driver->internal_info.con_lastpos; + + index = dtoh32(c->log.idx); + + /* Protect against corrupt value */ + if (index > c->bufsize) + { + WPRINT_WHD_ERROR( ("%s:%d index > c->bufsize \n", __FUNCTION__, __LINE__) ); + result = WHD_WLAN_BUFTOOSHORT; + goto done; + } + + /* Skip reading the console buffer if the index pointer has not moved */ + if (index == c->last) + { + result = WHD_SUCCESS; + goto done; + } + + /* Read the console buffer */ + /* xxx this could optimize and read only the portion of the buffer needed, but * it would also have to handle wrap-around. */ - address = dtoh32(c->log.buf); - result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, c->bufsize, (uint8_t *)c->buf); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__)); - goto done; - } + address = dtoh32(c->log.buf); - while (c->last != index) { - for (n = 0; n < buffer_size - 2; n++) { - if (c->last == index) { - /* This would output a partial line. Instead, back up +#ifndef PROTO_MSGBUF + result = whd_bus_transfer_backplane_bytes(whd_driver, BUS_READ, address, c->bufsize, (uint8_t *)c->buf); +#else + result = whd_bus_mem_bytes(whd_driver, BUS_READ, TRANS_ADDR(address), c->bufsize, (uint8_t *)c->buf); +#endif + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_transfer_backplane_bytes failed\n", __FUNCTION__, __LINE__) ); + goto done; + } + + while (c->last != index) + { + for (n = 0; n < buffer_size - 2; n++) + { + if (c->last == index) + { + /* This would output a partial line. Instead, back up * the buffer pointer and output this line next time around. */ - if (c->last >= n) { - c->last -= n; - } - else { - c->last = c->bufsize - n; - } - /* Save last read position */ - whd_driver->internal_info.con_lastpos = c->last; + if (c->last >= n) + { + c->last -= n; + } + else + { + c->last = c->bufsize - n; + } + /* Save last read position */ + whd_driver->internal_info.con_lastpos = c->last; result = WHD_SUCCESS; goto done; @@ -524,816 +625,1191 @@ whd_result_t whd_wifi_read_wlan_log_unsafe(whd_driver_t whd_driver, uint32_t wla if (buffer[n - 1] == '\r') n--; buffer[n] = 0; - WPRINT_MACRO(("CONSOLE: %s\n", buffer)); + WPRINT_INFO(("CONSOLE: %s\n", buffer)); } } /* Save last read position */ whd_driver->internal_info.con_lastpos = c->last; result = WHD_SUCCESS; -done: - return result; +done: return result; } void whd_wifi_peek(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint8_t *value) { - uint8_t status; + uint8_t status; - WHD_WLAN_KEEP_AWAKE(whd_driver); + WHD_WLAN_KEEP_AWAKE(whd_driver); - status = whd_bus_read_backplane_value(whd_driver, address, register_length, value); + status = whd_bus_read_backplane_value(whd_driver, address, register_length, value); - if (status != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error reading interrupt status\n", __FUNCTION__)); - } + if (status != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error reading interrupt status\n", __FUNCTION__) ); + } - WHD_WLAN_LET_SLEEP(whd_driver); + WHD_WLAN_LET_SLEEP(whd_driver); } void whd_wifi_poke(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint32_t value) { - uint8_t status; + uint8_t status; - WHD_WLAN_KEEP_AWAKE(whd_driver); + WHD_WLAN_KEEP_AWAKE(whd_driver); - status = whd_bus_write_backplane_value(whd_driver, address, register_length, value); + status = whd_bus_write_backplane_value(whd_driver, address, register_length, value); - if (status != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: Error clearing the interrupt status\n", __FUNCTION__)); - } + if (status != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Error clearing the interrupt status\n", __FUNCTION__) ); + } - WHD_WLAN_LET_SLEEP(whd_driver); + WHD_WLAN_LET_SLEEP(whd_driver); } -void whd_ioctl_log_add(whd_driver_t whd_driver, uint32_t cmd, whd_buffer_t buffer) +whd_result_t whd_ioctl_log_add(whd_driver_t whd_driver, uint32_t cmd, whd_buffer_t buffer) { - uint8_t *data = NULL; - size_t data_size = whd_buffer_get_current_piece_size(whd_driver, buffer); - - data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - CHECK_PACKET_WITH_NULL_RETURN(data); - data = data + IOCTL_OFFSET; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 0; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size = MIN_OF( - WHD_MAX_DATA_SIZE, data_size); - memset(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, 0, - WHD_MAX_DATA_SIZE); - memcpy(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, data, - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size); - - whd_driver->whd_ioctl_log_index++; + uint8_t *data = NULL; + size_t data_size = whd_buffer_get_current_piece_size(whd_driver, buffer); + + data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_IOCTL_BUFFER(data); + CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) ); + data = data + IOCTL_OFFSET; + data_size = data_size - IOCTL_OFFSET; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 0; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size = MIN_OF( + WHD_MAX_DATA_SIZE, data_size); + memset(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, 0, + WHD_MAX_DATA_SIZE); + memcpy(whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data, data, + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].data_size); + + whd_driver->whd_ioctl_log_index++; + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) ); + return WHD_SUCCESS; } -void whd_ioctl_log_add_event(whd_driver_t whd_driver, uint32_t cmd, uint16_t flag, uint32_t reason) +whd_result_t whd_ioctl_log_add_event(whd_driver_t whd_driver, uint32_t cmd, uint16_t flag, uint32_t reason) { - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 1; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].flag = flag; - whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].reason = reason; - - whd_driver->whd_ioctl_log_index++; + CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) ); + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].is_this_event = 1; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].ioct_log = cmd; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].flag = flag; + whd_driver->whd_ioctl_log[whd_driver->whd_ioctl_log_index % WHD_IOCTL_LOG_SIZE].reason = reason; + + whd_driver->whd_ioctl_log_index++; + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) ); + return WHD_SUCCESS; } whd_result_t whd_ioctl_print(whd_driver_t whd_driver) { - int i; - uint8_t *data = NULL; - size_t iovar_string_size = 0; - - for (i = 0; i < WHD_IOCTL_LOG_SIZE; i++) { - char iovar[WHD_IOVAR_STRING_SIZE + 1] = { 0 }; - data = whd_driver->whd_ioctl_log[i].data; - - if ((whd_driver->whd_ioctl_log[i].ioct_log == WLC_SET_VAR) || - (whd_driver->whd_ioctl_log[i].ioct_log == WLC_GET_VAR)) { - while (!*data) { - whd_driver->whd_ioctl_log[i].data_size--; - data++; - } - - snprintf(iovar, sizeof(iovar), "%s", data); + int i; + uint8_t *data = NULL; + size_t iovar_string_size = 0; + + CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->whd_log_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) ); + for (i = 0; i < WHD_IOCTL_LOG_SIZE; i++) + { + char iovar[WHD_IOVAR_STRING_SIZE] = {0}; + data = whd_driver->whd_ioctl_log[i].data; + + if ( (whd_driver->whd_ioctl_log[i].ioct_log == WLC_SET_VAR) || + (whd_driver->whd_ioctl_log[i].ioct_log == WLC_GET_VAR) ) + { + /* refer to whd_cdc_get_iovar_buffer() */ + while (!*data) + { + whd_driver->whd_ioctl_log[i].data_size--; + data++; + } + + if (strlen((char *)data) <= WHD_IOVAR_STRING_SIZE) + strcpy(iovar, (char *)data); iovar_string_size = strlen((const char *)data); - data += iovar_string_size; - whd_driver->whd_ioctl_log[i].data_size -= iovar_string_size; + iovar[iovar_string_size] = '\0'; + data += (iovar_string_size + 1); + whd_driver->whd_ioctl_log[i].data_size -= (iovar_string_size + 1); } if (whd_driver->whd_ioctl_log[i].is_this_event == 1) { whd_event_info_to_string(whd_driver->whd_ioctl_log[i].ioct_log, whd_driver->whd_ioctl_log[i].flag, - whd_driver->whd_ioctl_log[i].reason, iovar, sizeof(iovar) - 1); - WPRINT_MACRO(("\n<- E:%" PRIu32 "\t\t\tS:%d\t\t\t\tR:%" PRIu32 "\n%s\n", - whd_driver->whd_ioctl_log[i].ioct_log, - whd_driver->whd_ioctl_log[i].flag, whd_driver->whd_ioctl_log[i].reason, iovar)); + whd_driver->whd_ioctl_log[i].reason, iovar, sizeof(iovar) - 1); + WPRINT_INFO(("\n<- E:%" PRIu32 "\t\t\tS:%d\t\t\t\tR:%" PRIu32 "\n%s\n", + whd_driver->whd_ioctl_log[i].ioct_log, + whd_driver->whd_ioctl_log[i].flag, whd_driver->whd_ioctl_log[i].reason, iovar)); } else if (whd_driver->whd_ioctl_log[i].ioct_log == WLC_SET_VAR) { - WPRINT_MACRO(("\n-> %s\n", iovar)); + WPRINT_INFO(("\n-> %s\n", iovar)); whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size); } else if (whd_driver->whd_ioctl_log[i].ioct_log == WLC_GET_VAR) { - WPRINT_MACRO(("\n<- %s\n", iovar)); + WPRINT_INFO(("\n<- %s\n", iovar)); whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size); } else if (whd_driver->whd_ioctl_log[i].ioct_log != 0) { whd_ioctl_info_to_string(whd_driver->whd_ioctl_log[i].ioct_log, iovar, sizeof(iovar) - 1); - WPRINT_MACRO(("\n%s:%" PRIu32 "\n", iovar, whd_driver->whd_ioctl_log[i].ioct_log)); + WPRINT_INFO(("\n%s:%" PRIu32 "\n", iovar, whd_driver->whd_ioctl_log[i].ioct_log)); whd_hexdump(data, whd_driver->whd_ioctl_log[i].data_size); } } - memset(whd_driver->whd_ioctl_log, 0, sizeof(whd_driver->whd_ioctl_log)); - whd_driver->whd_ioctl_log_index = 0; - return WHD_SUCCESS; + memset(whd_driver->whd_ioctl_log, 0, sizeof(whd_driver->whd_ioctl_log) ); + whd_driver->whd_ioctl_log_index = 0; + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->whd_log_mutex, WHD_FALSE) ); + return WHD_SUCCESS; } void whd_wifi_chip_info_init(whd_driver_t whd_driver) { - whd_driver->chip_info.save_restore_enable = WHD_FALSE; + whd_driver->chip_info.save_restore_enable = WHD_FALSE; } whd_result_t whd_wifi_set_custom_country_code(whd_interface_t ifp, const whd_country_info_t *country_code) { - whd_driver_t whd_driver = ifp->whd_driver; - - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - if (wlan_chip_id == 43362) { - whd_buffer_t buffer; - whd_result_t result; - whd_country_info_t *data; - data = (whd_country_info_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, - (uint16_t)sizeof(whd_country_info_t) + 10); - if (data == NULL) { - whd_assert("Could not get buffer for IOCTL", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - memcpy(data, country_code, sizeof(whd_country_info_t)); - result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_CUSTOM_COUNTRY, buffer, NULL); - return result; - } - else { - UNUSED_PARAMETER(country_code); - return WHD_UNSUPPORTED; - } + whd_driver_t whd_driver = ifp->whd_driver; + + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if (wlan_chip_id == 43362) + { + whd_buffer_t buffer; + whd_result_t result; + whd_country_info_t *data; + data = (whd_country_info_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, + (uint16_t)sizeof(whd_country_info_t) + 10); + if (data == NULL) + { + whd_assert("Could not get buffer for IOCTL", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + memcpy(data, country_code, sizeof(whd_country_info_t) ); + result = whd_proto_set_ioctl(ifp, WLC_SET_CUSTOM_COUNTRY, buffer, NULL); + return result; + } + else + { + UNUSED_PARAMETER(country_code); + return WHD_UNSUPPORTED; + } } whd_result_t whd_chip_specific_socsram_init(whd_driver_t whd_driver) { - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - if ((wlan_chip_id == 43430) || (wlan_chip_id == 43439)) { - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_INDEX(whd_driver), 4, 0x3)); - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_PDA(whd_driver), 4, 0)); - return WHD_SUCCESS; - } - else { - return WHD_SUCCESS; - } + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) ) + { + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_INDEX(whd_driver), 4, 0x3) ); + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, SOCSRAM_BANKX_PDA(whd_driver), 4, 0) ); + return WHD_SUCCESS; + } + else + { + return WHD_SUCCESS; + } } whd_result_t whd_chip_specific_init(whd_driver_t whd_driver) { - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43362)) { - return WHD_SUCCESS; - } - else { - return whd_enable_save_restore(whd_driver); - } + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43362) ) + { + return WHD_SUCCESS; + } + else + { + return whd_enable_save_restore(whd_driver); + } } whd_result_t whd_allow_wlan_bus_to_sleep(whd_driver_t whd_driver) { - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); -#if 0 - whd_bt_dev_t btdev = whd_driver->bt_dev; -#endif - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43362)) { - /* Clear HT clock request */ - if (whd_bus_is_up(whd_driver) == WHD_TRUE) { - whd_bus_set_state(whd_driver, WHD_FALSE); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, 0)); - /* Bus specific sleep routine */ - return whd_bus_sleep(whd_driver); - } - else { - return WHD_SUCCESS; - } - } - else { - /* Clear HT clock request */ - if (whd_bus_is_up(whd_driver) == WHD_TRUE) { - whd_bus_set_state(whd_driver, WHD_FALSE); - if (whd_driver->chip_info.save_restore_enable == WHD_FALSE) { - return whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, 0); - } - else { -#if 0 - if (btdev->bt_int_cb) { - return WHD_SUCCESS; - } -#endif - return whd_kso_enable(whd_driver, WHD_FALSE); - } - } - else { - return WHD_SUCCESS; - } - } + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + whd_bt_dev_t btdev = whd_driver->bt_dev; + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43362) ) + { + /* Clear HT clock request */ + if (whd_bus_is_up(whd_driver) == WHD_TRUE) + { + whd_bus_set_state(whd_driver, WHD_FALSE); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, 0) ); + /* Bus specific sleep routine */ + return whd_bus_sleep(whd_driver); + } + else + { + return WHD_SUCCESS; + } + } + else + { + /* Clear HT clock request */ + if (whd_bus_is_up(whd_driver) == WHD_TRUE) + { + whd_bus_set_state(whd_driver, WHD_FALSE); + if (whd_driver->chip_info.save_restore_enable == WHD_FALSE) + { + return whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, 0); + } + else + { + if (btdev && btdev->bt_int_cb) + { + return WHD_SUCCESS; + } + return whd_kso_enable(whd_driver, WHD_FALSE); + } + } + else + { + return WHD_SUCCESS; + } + } } whd_result_t whd_wifi_read_wlan_log(whd_driver_t whd_driver, char *buffer, uint32_t buffer_size) { - whd_result_t result; - uint32_t wlan_shared_address; - uint16_t wlan_chip_id = 0; - - CHECK_DRIVER_NULL(whd_driver); + whd_result_t result; + uint32_t wlan_shared_address; + uint16_t wlan_chip_id = 0; + + CHECK_DRIVER_NULL(whd_driver); + + WHD_IOCTL_PRINT(whd_driver); + + wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if (wlan_chip_id == 43362) + { + return whd_wifi_read_wlan_log_unsafe(whd_driver, ( (GET_C_VAR(whd_driver, CHIP_RAM_SIZE) + + PLATFORM_WLAN_RAM_BASE) - 4 ), buffer, buffer_size); + } + else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + return result; + } + result = whd_wifi_read_wlan_log_unsafe(whd_driver, ( (GET_C_VAR(whd_driver, CHIP_RAM_SIZE) + + GET_C_VAR(whd_driver, + ATCM_RAM_BASE_ADDRESS) ) - 4 ), buffer, + buffer_size); + whd_thread_notify(whd_driver); + return result; + } + else if ( (wlan_chip_id == 4334) || (wlan_chip_id == 4390) ) + { + return WHD_UNSUPPORTED; + } + else + { + /* Backplane access needs HT clock. So, disabling bus sleep */ + WHD_WLAN_KEEP_AWAKE(whd_driver); +#ifndef DM_43022C1 + /* FW populates the last word of RAM with wlan_shared_t struct address */ + wlan_shared_address = PLATFORM_WLAN_RAM_BASE + GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; +#else + /* FW populates the last word of RAM with wlan_shared_t struct address */ + wlan_shared_address = (PLATFORM_WLAN_RAM_BASE + GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + + GET_C_VAR(whd_driver, NVRAM_DNLD_ADDR) - 4); +#endif - WHD_IOCTL_PRINT(whd_driver); + if (!GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) && (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE) ) + { + wlan_shared_address -= GET_C_VAR(whd_driver, SOCRAM_SRMEM_SIZE); + } + result = whd_wifi_read_wlan_log_unsafe(whd_driver, wlan_shared_address, buffer, buffer_size); + WHD_WLAN_LET_SLEEP(whd_driver); + return result; + } - wlan_chip_id = whd_chip_get_chip_id(whd_driver); - if (wlan_chip_id == 43362) { - return whd_wifi_read_wlan_log_unsafe(whd_driver, ((GET_C_VAR(whd_driver, CHIP_RAM_SIZE) + PLATFORM_WLAN_RAM_BASE) - 4), buffer, buffer_size); - } - else if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - result = whd_ensure_wlan_bus_is_up(whd_driver); - if (result != WHD_SUCCESS) { - return result; - } - result = whd_wifi_read_wlan_log_unsafe(whd_driver, ((GET_C_VAR(whd_driver, CHIP_RAM_SIZE) + GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS)) - 4), buffer, - buffer_size); - whd_thread_notify(whd_driver); - return result; - } - else if ((wlan_chip_id == 4334) || (wlan_chip_id == 4390)) { - return WHD_UNSUPPORTED; - } - else { - /* Backplane access needs HT clock. So, disabling bus sleep */ - WHD_WLAN_KEEP_AWAKE(whd_driver); - /* FW populates the last word of RAM with wlan_shared_t struct address */ - wlan_shared_address = PLATFORM_WLAN_RAM_BASE + GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + - GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; - if (!GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) && (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE)) { - wlan_shared_address -= GET_C_VAR(whd_driver, SOCRAM_SRMEM_SIZE); - } - result = whd_wifi_read_wlan_log_unsafe(whd_driver, wlan_shared_address, buffer, buffer_size); - WHD_WLAN_LET_SLEEP(whd_driver); - return result; - } } -uint32_t whd_wifi_print_whd_log(whd_driver_t whd_driver) +whd_result_t whd_wifi_print_whd_log(whd_driver_t whd_driver) { - whd_result_t result; - char *buffer = NULL; - - CHECK_DRIVER_NULL(whd_driver); - - WHD_IOCTL_PRINT(whd_driver); - - if ((buffer = malloc(WLAN_LOG_BUF_LEN)) == NULL) { - WPRINT_WHD_ERROR(("Memory allocation failed for log buffer in %s \n", __FUNCTION__)); - return WHD_MALLOC_FAILURE; - } + whd_result_t result; + char *buffer = NULL; + + CHECK_DRIVER_NULL(whd_driver); + + WHD_IOCTL_PRINT(whd_driver); + + if ( (buffer = whd_mem_malloc(WLAN_LOG_BUF_LEN) ) == NULL ) + { + WPRINT_WHD_ERROR( ("Memory allocation failed for log buffer in %s \n", __FUNCTION__) ); + return WHD_MALLOC_FAILURE; + } + + result = whd_wifi_read_wlan_log(whd_driver, buffer, WLAN_LOG_BUF_LEN); + if (result == WHD_SUCCESS) + { + whd_print_logbuffer(); // This is not supported yet. + } + whd_mem_free(buffer); + CHECK_RETURN(result); + return result; +} - result = whd_wifi_read_wlan_log(whd_driver, buffer, WLAN_LOG_BUF_LEN); - if (result == WHD_SUCCESS) { - whd_print_logbuffer(); // This is not supported yet. - } - free(buffer); - CHECK_RETURN(result); - return result; +whd_result_t whd_wifi_read_fw_capabilities(whd_interface_t ifp) +{ + whd_result_t result; + char caps[MAX_CAPS_BUFFER_SIZE]; + whd_fwcap_id_t id; + + CHECK_IFP_NULL(ifp); + whd_driver_t whd_driver = ifp->whd_driver; + + result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_CAP, (uint8_t *)caps, sizeof(caps) ); + CHECK_RETURN(result); + + for (uint32_t i = 0; i < ARRAY_SIZE(whd_fwcap_map); i++) + { + if (strstr(caps, whd_fwcap_map[i].fwcap_name) ) + { + id = whd_fwcap_map[i].feature; + WPRINT_WHD_DEBUG( ("Enabling FW Capabilities: %s\n", whd_fwcap_map[i].fwcap_name) ); + whd_driver->chip_info.fwcap_flags |= (1 << id); + } + } + return WHD_SUCCESS; } whd_result_t whd_ensure_wlan_bus_is_up(whd_driver_t whd_driver) { - uint8_t csr = 0; - uint32_t attempts = (uint32_t)WLAN_BUS_UP_ATTEMPTS; - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - /* Ensure HT clock is up */ - if (whd_bus_is_up(whd_driver) == WHD_TRUE) { - return WHD_SUCCESS; - } - - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334)) { - /* Bus specific wakeup routine */ - CHECK_RETURN(whd_bus_wakeup(whd_driver)); - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ)); - do { - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, &csr)); - --attempts; - } while (((csr & SBSDIO_HT_AVAIL) == 0) && (attempts != 0) && - (cy_rtos_delay_milliseconds((uint32_t)1), 1 == 1)); - - if (attempts == 0) { - WPRINT_WHD_ERROR(("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_BUS_UP_FAIL; - } - else { - whd_bus_set_state(whd_driver, WHD_TRUE); - return WHD_SUCCESS; - } - } - else if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - //To-Do - /* M2M power save mode */ - //M2M_POWERSAVE_COMM_TX_BEGIN - return WHD_SUCCESS; - } - else { - if (whd_driver->chip_info.save_restore_enable == WHD_FALSE) { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ)); - do { - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)sizeof(csr), &csr)); - --attempts; - } while (((csr & SBSDIO_HT_AVAIL) == 0) && (attempts != 0) && - (cy_rtos_delay_milliseconds((uint32_t)HT_AVAIL_WAIT_MS), 1 == 1)); - - if (attempts == 0) { - WPRINT_WHD_ERROR(("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_BUS_UP_FAIL; - } - else { - whd_bus_set_state(whd_driver, WHD_TRUE); - return WHD_SUCCESS; - } - } - else { - if (whd_kso_enable(whd_driver, WHD_TRUE) == WHD_SUCCESS) { - whd_bus_set_state(whd_driver, WHD_TRUE); - return WHD_SUCCESS; - } - else { - WPRINT_WHD_ERROR(("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_BUS_UP_FAIL; - } - } - } + uint8_t csr = 0; + uint32_t attempts = ( uint32_t )WLAN_BUS_UP_ATTEMPTS; + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + /* Ensure HT clock is up */ + if (whd_bus_is_up(whd_driver) == WHD_TRUE) + { + return WHD_SUCCESS; + } + + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) ) + { + /* Bus specific wakeup routine */ + CHECK_RETURN(whd_bus_wakeup(whd_driver) ); + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ) ); + do + { + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, &csr) ); + --attempts; + } while ( ( (csr & SBSDIO_HT_AVAIL) == 0 ) && (attempts != 0) && + (cy_rtos_delay_milliseconds( (uint32_t)1 ), 1 == 1) ); + + if (attempts == 0) + { + WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_BUS_UP_FAIL; + } + else + { + whd_bus_set_state(whd_driver, WHD_TRUE); + return WHD_SUCCESS; + } + } + else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + //To-Do + /* M2M power save mode */ + //M2M_POWERSAVE_COMM_TX_BEGIN + return WHD_SUCCESS; + } +#ifdef PROTO_MSGBUF + else if ((wlan_chip_id == 55500) || (wlan_chip_id == 55900)) + { +#if 0 /* To be verified after TO */ + if (whd_bus_resume(whd_driver) == WHD_SUCCESS) + { + whd_bus_set_state(whd_driver, WHD_TRUE); + return WHD_SUCCESS; + } + else + { + WPRINT_WHD_ERROR( ("Bus failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_BUS_UP_FAIL; + } +#else + return WHD_SUCCESS; +#endif + } +#endif + else + { + if (whd_driver->chip_info.save_restore_enable == WHD_FALSE) + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, (uint32_t)SBSDIO_HT_AVAIL_REQ) ); + do + { + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)sizeof(csr), &csr) ); + --attempts; + } while ( ( (csr & SBSDIO_HT_AVAIL) == 0 ) && (attempts != 0) && + (cy_rtos_delay_milliseconds( ( uint32_t )HT_AVAIL_WAIT_MS ), 1 == 1) ); + + if (attempts == 0) + { + WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_BUS_UP_FAIL; + } + else + { + whd_bus_set_state(whd_driver, WHD_TRUE); + return WHD_SUCCESS; + } + } + else + { + if (whd_kso_enable(whd_driver, WHD_TRUE) == WHD_SUCCESS) + { + whd_bus_set_state(whd_driver, WHD_TRUE); + return WHD_SUCCESS; + } + else + { + WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_BUS_UP_FAIL; + } + } + } } static whd_bool_t whd_is_fw_sr_capable(whd_driver_t whd_driver) { - uint32_t core_capext; - uint32_t retention_ctl = 0; - uint32_t srctrl = 0; - whd_bool_t save_restore_capable = WHD_FALSE; - whd_result_t result = WHD_SUCCESS; - - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - if ((wlan_chip_id == 43430) || (wlan_chip_id == 43439)) { - /* check if fw initialized sr engine */ - if (whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_SR_CONTROL1, (uint8_t)4, - (uint8_t *)&srctrl) != WHD_SUCCESS) { - return WHD_FALSE; - } - if (srctrl != 0) { - return WHD_TRUE; - } - else { - return WHD_FALSE; - } - } - else if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - /* check if fw initialized sr engine */ - result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_CAPEXT_ADDR, (uint8_t)4, - (uint8_t *)&core_capext); - if (result != WHD_SUCCESS) { - return WHD_FALSE; - } - - if ((core_capext & CHIPCOMMON_CORE_CAPEXT_SR_SUPPORTED) != 0) { - result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_RETENTION_CTL, (uint8_t)4, - (uint8_t *)&retention_ctl); - if (result != WHD_SUCCESS) { - return WHD_FALSE; - } - if ((retention_ctl & (CHIPCOMMON_CORE_RCTL_MACPHY_DISABLE | CHIPCOMMON_CORE_RCTL_LOGIC_DISABLE)) == 0) { - save_restore_capable = WHD_TRUE; - } - } - return save_restore_capable; - } - else { - /* check if fw initialized sr engine */ - result = - whd_bus_read_backplane_value(whd_driver, (uint32_t)RETENTION_CTL(whd_driver), (uint8_t)sizeof(retention_ctl), - (uint8_t *)&retention_ctl); - if (result != WHD_SUCCESS) { - return WHD_FALSE; - } - if ((retention_ctl & (RCTL_MACPHY_DISABLE | RCTL_LOGIC_DISABLE)) == 0) { - save_restore_capable = WHD_TRUE; - } - return save_restore_capable; - } + uint32_t core_capext; + uint32_t retention_ctl = 0; + uint32_t srctrl = 0; + whd_bool_t save_restore_capable = WHD_FALSE; + whd_result_t result = WHD_SUCCESS; + + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) ) + { + /* check if fw initialized sr engine */ + if (whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_SR_CONTROL1, (uint8_t)4, + (uint8_t *)&srctrl) != WHD_SUCCESS) + { + return WHD_FALSE; + } + if (srctrl != 0) + { + return WHD_TRUE; + } + else + { + return WHD_FALSE; + } + } + else if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + /* check if fw initialized sr engine */ + result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_CAPEXT_ADDR, (uint8_t)4, + (uint8_t *)&core_capext); + if (result != WHD_SUCCESS) + { + return WHD_FALSE; + } + + if ( (core_capext & CHIPCOMMON_CORE_CAPEXT_SR_SUPPORTED) != 0 ) + { + result = whd_bus_read_backplane_value(whd_driver, (uint32_t)CHIPCOMMON_CORE_RETENTION_CTL, (uint8_t)4, + (uint8_t *)&retention_ctl); + if (result != WHD_SUCCESS) + { + return WHD_FALSE; + } + if ( (retention_ctl & (CHIPCOMMON_CORE_RCTL_MACPHY_DISABLE | CHIPCOMMON_CORE_RCTL_LOGIC_DISABLE) ) == 0 ) + { + save_restore_capable = WHD_TRUE; + } + } + return save_restore_capable; + } + else if (wlan_chip_id == 55560 || wlan_chip_id == 43022 || wlan_chip_id == 55500) + { + /*In hatchet Chips(DM) and 43022DM, the SR(SaveRestore) is always enabled. In DM mode(secure), host not + able to access PMU register(SR). So making save_restore_capable as default for Hatchet and 43022DM Chips */ + save_restore_capable = WHD_TRUE; + return save_restore_capable; + } + else + { + /* check if fw initialized sr engine */ + result = + whd_bus_read_backplane_value(whd_driver, (uint32_t)RETENTION_CTL( + whd_driver), (uint8_t)sizeof(retention_ctl), + (uint8_t *)&retention_ctl); + if (result != WHD_SUCCESS) + { + return WHD_FALSE; + } + if ( (retention_ctl & (RCTL_MACPHY_DISABLE | RCTL_LOGIC_DISABLE) ) == 0 ) + { + save_restore_capable = WHD_TRUE; + } + return save_restore_capable; + } } static whd_result_t whd_enable_save_restore(whd_driver_t whd_driver) { - uint8_t data; - /* Get chip number */ - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - if (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE) { - if ((wlan_chip_id == 43012) || (wlan_chip_id == 0x4373)) { - /* Configure WakeupCtrl register to set AlpAvail request bit in chipClockCSR register + uint8_t data; + /* Get chip number */ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if (whd_is_fw_sr_capable(whd_driver) == WHD_TRUE) + { + if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) || (wlan_chip_id == 55560) || (wlan_chip_id == 55500) || (wlan_chip_id == 43022) ) + { + /* Configure WakeupCtrl register to set AlpAvail request bit in chipClockCSR register * after the sdiod core is powered on. */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, - (uint8_t)sizeof(data), &data)); - data |= SBSDIO_WCTRL_WAKE_TILL_ALP_AVAIL; - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, - (uint8_t)sizeof(data), data)); - } - else { - /* Configure WakeupCtrl register to set HtAvail request bit in chipClockCSR register + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, + (uint8_t)sizeof(data), &data) ); + +#ifdef CP_OVER_SDIO + data |= SBSDIO_WCTRL_BT_WAKE_TILL_ALP_AVAIL; + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, + (uint8_t)sizeof(data), data) ); +#else + data |= SBSDIO_WCTRL_WL_WAKE_TILL_ALP_AVAIL; + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, + (uint8_t)sizeof(data), data) ); +#endif + + } + else + { + /* Configure WakeupCtrl register to set HtAvail request bit in chipClockCSR register * after the sdiod core is powered on. */ - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, - (uint8_t)1, &data)); - data |= SBSDIO_WCTRL_WAKE_TILL_HT_AVAIL; - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, - (uint8_t)1, data)); - } - - /* Set brcmCardCapability to noCmdDecode mode. + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, + (uint8_t)1, &data) ); + data |= SBSDIO_WCTRL_WL_WAKE_TILL_HT_AVAIL; + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_WAKEUP_CTRL, + (uint8_t)1, data) ); + } + + /* Set brcmCardCapability to noCmdDecode mode. * It makes sdiod_aos to wakeup host for any activity of cmd line, even though * module won't decode cmd or respond */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, (uint32_t)SDIOD_CCCR_BRCM_CARDCAP, - (uint8_t)1, SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC)); - if ((wlan_chip_id == 43012) || (wlan_chip_id == 0x4373)) { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, SBSDIO_HT_AVAIL_REQ)); - } - else { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, - (uint8_t)1, (uint32_t)SBSDIO_FORCE_HT)); - } - - /* Enable KeepSdioOn (KSO) bit for normal operation */ - if ((wlan_chip_id == 43012) || (wlan_chip_id == 0x4373)) { - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)sizeof(data), &data)); - } - else { - CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, &data)); - } - if ((data & SBSDIO_SLPCSR_KEEP_SDIO_ON) == 0) { - data |= SBSDIO_SLPCSR_KEEP_SDIO_ON; - if ((wlan_chip_id == 43012) || (wlan_chip_id == 0x4373)) { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)sizeof(data), data)); - } - else { - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, data)); - } - } - - /* SPI bus can be configured for sleep by default. + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, (uint32_t)SDIOD_CCCR_BRCM_CARDCAP, + (uint8_t)1, SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC) ); + if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) || (wlan_chip_id == 55560) || (wlan_chip_id == 55500) || (wlan_chip_id == 43022) ) + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, SBSDIO_HT_AVAIL_REQ) ); + } + else + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_CHIP_CLOCK_CSR, + (uint8_t)1, (uint32_t)SBSDIO_FORCE_HT) ); + } + + /* Enable KeepSdioOn (KSO) bit for normal operation */ + if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) || (wlan_chip_id == 55560) || (wlan_chip_id == 55500) || (wlan_chip_id == 43022) ) + { + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)sizeof(data), &data) ); + } + else + { + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, &data) ); + } + if ( (data & SBSDIO_SLPCSR_KEEP_WL_KSO) == 0 ) + { + data |= SBSDIO_SLPCSR_KEEP_WL_KSO; + if ( (wlan_chip_id == 43012) || (wlan_chip_id == 0x4373) || (wlan_chip_id == 55560) || (wlan_chip_id == 55500) || (wlan_chip_id == 43022) ) + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)sizeof(data), data) ); + } + else + { + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, data) ); + } + } + + /* SPI bus can be configured for sleep by default. * KSO bit solely controls the wlan chip sleep */ - CHECK_RETURN(whd_bus_sleep(whd_driver)); + CHECK_RETURN(whd_bus_sleep(whd_driver) ); - /* Put SPI interface block to sleep */ - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0xf)); + /* Put SPI interface block to sleep */ + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, SDIO_PULL_UP, (uint8_t)1, 0xf) ); - whd_driver->chip_info.save_restore_enable = WHD_TRUE; - } - else { - whd_driver->chip_info.save_restore_enable = WHD_FALSE; - } + whd_driver->chip_info.save_restore_enable = WHD_TRUE; + } + else + { + whd_driver->chip_info.save_restore_enable = WHD_FALSE; + } - return WHD_SUCCESS; + return WHD_SUCCESS; } static whd_result_t whd_kso_enable(whd_driver_t whd_driver, whd_bool_t enable) { - uint8_t write_value = 0; - uint8_t read_value = 0; - uint8_t compare_value; - uint8_t bmask; - uint32_t attempts = (uint32_t)MAX_KSO_ATTEMPTS; - whd_result_t result; - /* Get chip number */ - - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - if (enable == WHD_TRUE) { - write_value |= SBSDIO_SLPCSR_KEEP_SDIO_ON; - } - - /* 1st KSO write goes to AOS wake up core if device is asleep */ - /* Possibly device might not respond to this cmd. So, don't check return value here */ - if ((wlan_chip_id == 43430) || (wlan_chip_id == 43439) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - /* 2 Sequential writes to KSO bit are required for SR module to wakeup, both write can fail */ - CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, - write_value)); - CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, - write_value)); - if (enable == WHD_TRUE) { - /* device WAKEUP through KSO: + uint8_t write_value = 0; + uint8_t read_value = 0; + uint8_t compare_value; + uint8_t bmask; + uint32_t attempts = ( uint32_t )MAX_KSO_ATTEMPTS; + whd_result_t result; + /* Get chip number */ + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if (enable == WHD_TRUE) + { +#ifdef CP_OVER_SDIO + if (wlan_chip_id == 55500) + { + write_value |= SBSDIO_SLPCSR_KEEP_BT_KSO; + } +#else + write_value |= SBSDIO_SLPCSR_KEEP_WL_KSO; +#endif + } + + /* 1st KSO write goes to AOS wake up core if device is asleep */ + /* Possibly device might not respond to this cmd. So, don't check return value here */ + if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + /* 2 Sequential writes to KSO bit are required for SR module to wakeup, both write can fail */ + CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, + write_value) ); + CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, + write_value) ); + if (enable == WHD_TRUE) + { + /* device WAKEUP through KSO: * write bit 0 & read back until * both bits 0(kso bit) & 1 (dev on status) are set */ - compare_value = SBSDIO_SLPCSR_KEEP_SDIO_ON | SBSDIO_SLPCSR_DEVICE_ON; - bmask = compare_value; - } - else { - /* Put device to sleep, turn off KSO */ - compare_value = 0; - /* Check for bit0 only, bit1(devon status) may not get cleared right away */ - bmask = SBSDIO_SLPCSR_KEEP_SDIO_ON; - } - } - else { - CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, write_value)); - - /* In case of 43012 chip, the chip could go down immediately after KSO bit is cleared. + compare_value = SBSDIO_SLPCSR_KEEP_WL_KSO | SBSDIO_SLPCSR_WL_DEVON; + bmask = compare_value; + } + else + { + /* Put device to sleep, turn off KSO */ + compare_value = 0; + /* Check for bit0 only, bit1(devon status) may not get cleared right away */ + bmask = SBSDIO_SLPCSR_KEEP_WL_KSO; + } + } + else + { + CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, write_value) ); + + /* In case of 43012/555x0 chip, the chip could go down immediately after KSO bit is cleared. * So the further reads of KSO register could fail. Thereby just bailing out immediately * after clearing KSO bit, to avoid polling of KSO bit. */ - if (enable == WHD_FALSE) { - return WHD_SUCCESS; - } + if (enable == WHD_FALSE) + { + return WHD_SUCCESS; + } - /* 2 Sequential writes to KSO bit are required for SR module to wakeup */ - CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, write_value)); + /* 2 Sequential writes to KSO bit are required for SR module to wakeup */ + CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, write_value) ); - /* device WAKEUP through KSO: + /* device WAKEUP through KSO: * write bit 0 & read back until - * both bits 0(kso bit) & 1 (dev on status) are set + * both bits 0(kso bit) & 1 (dev on status) are set, + * For CP , enable BT KSO bits */ - compare_value = SBSDIO_SLPCSR_KEEP_SDIO_ON | SBSDIO_SLPCSR_DEVICE_ON; - bmask = compare_value; - } +#ifdef CP_OVER_SDIO + if (wlan_chip_id == 55500) + { + compare_value = SBSDIO_SLPCSR_KEEP_BT_KSO | SBSDIO_SLPCSR_BT_DEVON; + } +#else + compare_value = SBSDIO_SLPCSR_KEEP_WL_KSO | SBSDIO_SLPCSR_WL_DEVON; +#endif + bmask = compare_value; + } - while (attempts != 0) { - /* Reliable KSO bit set/clr: + while (attempts != 0) + { + /* Reliable KSO bit set/clr: * Sdiod sleep write access appears to be in sync with PMU 32khz clk * just one write attempt may fail,(same is with read ?) * in any case, read it back until it matches written value */ - result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, (uint8_t)1, - &read_value); - if (((read_value & bmask) == compare_value) && (result == WHD_SUCCESS) && (read_value != 0xFF)) { - break; - } - - cy_rtos_delay_milliseconds((uint32_t)KSO_WAIT_MS); - - CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, - (uint8_t)1, write_value)); - attempts--; - } - - if (attempts == 0) { - WPRINT_WHD_ERROR(("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__)); - return WHD_SDIO_BUS_UP_FAIL; - } - else { - return WHD_SUCCESS; - } + result = whd_bus_read_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, (uint8_t)1, + &read_value); + if ( ( (read_value & bmask) == compare_value ) && (result == WHD_SUCCESS) && (read_value != 0xFF) ) + { + break; + } + + cy_rtos_delay_milliseconds( ( uint32_t )KSO_WAIT_MS ); + + CHECK_RETURN_IGNORE(whd_bus_write_register_value(whd_driver, BACKPLANE_FUNCTION, (uint32_t)SDIO_SLEEP_CSR, + (uint8_t)1, write_value) ); + attempts--; + } + + if (attempts == 0) + { + WPRINT_WHD_ERROR( ("SDIO bus failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_SDIO_BUS_UP_FAIL; + } + else + { + return WHD_SUCCESS; + } } void whd_wlan_wake_from_host(whd_driver_t whd_driver); void whd_wlan_wake_from_host(whd_driver_t whd_driver) { - uint32_t val32 = 0; - whd_result_t result; - - result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)); - } - WPRINT_WHD_DEBUG(("%s: %d:before: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32)); - - val32 = val32 | D11_MACCONTROL_REG_WAKE; - result = whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, val32); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__)); - } - result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__)) - } - WPRINT_WHD_DEBUG(("%s: %d:after: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32)); + uint32_t val32 = 0; + whd_result_t result; + + result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ); + } + WPRINT_WHD_DEBUG( ("%s: %d:before: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32) ); + + val32 = val32 | D11_MACCONTROL_REG_WAKE; + result = whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, val32); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_write_backplane_value failed\n", __FUNCTION__, __LINE__) ); + } + result = whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, D11_MACCONTROL_REG_SIZE, (uint8_t *)&val32); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s:%d whd_bus_read_backplane_value failed\n", __FUNCTION__, __LINE__) ) + } + WPRINT_WHD_DEBUG( ("%s: %d:after: maccontrol: 0x%08x\n", __FUNCTION__, __LINE__, (unsigned int)val32) ); } - +#ifndef CYCFG_ULP_SUPPORT_ENABLED whd_result_t whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver, whd_bool_t wake_from_firmware, - uint32_t wake_event_indication_addr, uint32_t wake_indication_addr, - uint32_t sdio_control_addr) + uint32_t wake_event_indication_addr, uint32_t wake_indication_addr, + uint32_t sdio_control_addr) { - uint32_t val = 0; - uint32_t val1 = 0; - uint32_t count = 0; - int32_t timeout = 0; - /* Get chip number */ - - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - - if (wlan_chip_id == 43012) { - WPRINT_WHD_DEBUG_DS(("%s: enter: wake_fr_fw=%d\n", __func__, (int)wake_from_firmware)); - - /* Need to do for all wake causes */ - while (WHD_SUCCESS != - whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, SDIO_FUNC_ENABLE_1)) { - WPRINT_WHD_DEBUG(("Retry IOEN write\n")); - cy_rtos_delay_milliseconds(10); - } - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_event_indication_addr), 2, - (uint8_t *)&val)); - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_indication_addr), 2, (uint8_t *)&val)); - - if (WHD_TRUE == wake_from_firmware) { - WPRINT_WHD_DEBUG_DS(("%s: CCCR written\n", __func__)); - - /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX + uint32_t val = 0; + uint32_t val1 = 0; + uint32_t count = 0; + int32_t timeout = 0; + /* Get chip number */ + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if (wlan_chip_id == 43012) + { + WPRINT_WHD_DEBUG_DS( ("%s: enter: wake_fr_fw=%d\n", __func__, (int )wake_from_firmware) ); + + /* Need to do for all wake causes */ + while (WHD_SUCCESS != + whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, SDIO_FUNC_ENABLE_1) ) + { + WPRINT_WHD_DEBUG( ("Retry IOEN write\n") ); + cy_rtos_delay_milliseconds(10); + } + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_event_indication_addr), 2, + (uint8_t *)&val) ); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(wake_indication_addr), 2, (uint8_t *)&val) ); + + if (WHD_TRUE == wake_from_firmware) + { + WPRINT_WHD_DEBUG_DS( ("%s: CCCR written\n", __func__) ); + + /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX * For RX Cases , Value will be DS1_SLEEP * For TX Cases, Value will be MAC ON or RADIO_PHY_ON */ - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2, - (uint8_t *)&val)); - if (val == DS1_SLEEP) { - /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2, + (uint8_t *)&val) ); + if (val == DS1_SLEEP) + { + /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases * Simply update PMU Resource Mask and Re-download firmware for this case */ - WPRINT_WHD_DEBUG_DS(("%s: D11 wake detected\n", __func__)); - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, - DEFAULT_43012_MIN_RES_MASK)); - - return WHD_SUCCESS; - } - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2, - C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID)); - WPRINT_WHD_DEBUG_DS(("%s: SDIO ctl written\n", __func__)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, - (uint8_t *)&val)); - WPRINT_WHD_DEBUG_DS(("%s: M_DS1_CTRL_SDIO = [%x]\n", __func__, (int)val)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1)); - WPRINT_WHD_DEBUG_DS(("%s: before setting wake = [%x]\n", __func__, (int)val1)); - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, - val1 | D11_MACCONTROL_REG_WAKE)); - WPRINT_WHD_DEBUG_DS(("%s: After setting wake= [%x]\n", __func__, (int)val1)); - - while (!(val & C_DS1_CTRL_PROC_DONE)) { - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, - (uint8_t *)&val)); - count++; - if (count == 1000) { - WPRINT_WHD_ERROR(("%s: sdio timed out! Aborting\n", __func__)); - return WHD_TIMEOUT; - } - } - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, - (uint8_t *)&val)); - WPRINT_WHD_DEBUG_DS(("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __func__, (int)val)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1)); - WPRINT_WHD_DEBUG_DS(("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __func__, (int)val1)); - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, - val1 & D11_MACCONTROL_CLEAR_WAKE)); - WPRINT_WHD_DEBUG_DS(("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __func__, (int)val1)); - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK)); - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1)); - - WPRINT_WHD_DEBUG_DS(("%s: PMU_MINRESMASK = [%x]\n", __func__, (int)val1)); - } - else { - while (WHD_SUCCESS != whd_ensure_wlan_bus_is_up(whd_driver)) { - WPRINT_WHD_DEBUG_DS(("Retrying bus is up\n")); - } - - WPRINT_WHD_DEBUG_DS(("write backplane\n")); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val)); - - while (WHD_SUCCESS != - whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, - val | C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID)) { - WPRINT_WHD_DEBUG_DS(("Retrying backplane write; addr=%x\n", - (unsigned int)D11SHM_ADDR(sdio_control_addr))); - cy_rtos_delay_milliseconds(100); - } - - WPRINT_WHD_DEBUG_DS(("wake host\n")); - whd_wlan_wake_from_host(whd_driver); - - WPRINT_WHD_DEBUG_DS(("poll for timeout\n")); - /* Poll for PROC_DONE to be set by ucode; timeout after a good amount of time */ - for (timeout = WHD_WLAN_WAKE_TIMEOUT * 10, val = 0; timeout >= 0; - timeout -= WHD_SHARED_MEMORY_POLLING_DELAY) { - whd_result_t read_result = - whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val); - - if ((WHD_SUCCESS != read_result) || !((val)&C_DS1_CTRL_PROC_DONE)) { - cy_rtos_delay_milliseconds(WHD_SHARED_MEMORY_POLLING_DELAY); - } - else { - /* success! */ - WPRINT_WHD_DEBUG_DS(("Ucode has posted DONE\n")); - break; - } - } - - WPRINT_WHD_DEBUG_DS(("%s: %d: 0x%08x\n", __func__, __LINE__, (unsigned int)val)); - - if ((timeout < 0) && !(val & C_DS1_CTRL_PROC_DONE)) { - WPRINT_WHD_ERROR(("%s: Failed to enter DS1 Exit state!\n", __func__)); - return WHD_TIMEOUT; - } - } - WPRINT_WHD_DEBUG_DS(("successfully completed DS wake sequence\n")); - return WHD_SUCCESS; - } - else { - UNUSED_PARAMETER(wake_from_firmware); - UNUSED_PARAMETER(wake_event_indication_addr); - UNUSED_PARAMETER(wake_indication_addr); - UNUSED_PARAMETER(sdio_control_addr); - - WPRINT_WHD_DEBUG(("%s: enter\n", __FUNCTION__)); - - CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, - SDIO_FUNC_ENABLE_1)); - WPRINT_WHD_DEBUG(("%s: CCCR written\n", __FUNCTION__)); - - /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX + WPRINT_WHD_DEBUG_DS( ("%s: D11 wake detected\n", __func__) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, + DEFAULT_43012_MIN_RES_MASK) ); + + return WHD_SUCCESS; + } + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2, + C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) ); + WPRINT_WHD_DEBUG_DS( ("%s: SDIO ctl written\n", __func__) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO = [%x]\n", __func__, (int )val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG_DS( ("%s: before setting wake = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, + val1 | D11_MACCONTROL_REG_WAKE) ); + WPRINT_WHD_DEBUG_DS( ("%s: After setting wake= [%x]\n", __func__, (int )val1) ); + + while (!(val & C_DS1_CTRL_PROC_DONE) ) + { + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + count++; + if (count == 1000) + { + WPRINT_WHD_ERROR( ("%s: sdio timed out! Aborting\n", __func__) ); + return WHD_TIMEOUT; + } + } + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __func__, (int )val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, + val1 & D11_MACCONTROL_CLEAR_WAKE) ); + WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) ); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1) ); + + WPRINT_WHD_DEBUG_DS( ("%s: PMU_MINRESMASK = [%x]\n", __func__, (int )val1) ); + } + else + { + while (WHD_SUCCESS != whd_ensure_wlan_bus_is_up(whd_driver) ) + { + WPRINT_WHD_DEBUG_DS( ("Retrying bus is up\n") ); + } + + WPRINT_WHD_DEBUG_DS( ("write backplane\n") ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val) ); + + while (WHD_SUCCESS != + whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, + val | C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) ) + { + WPRINT_WHD_DEBUG_DS( ("Retrying backplane write; addr=%x\n", + (unsigned int )D11SHM_ADDR(sdio_control_addr) ) ); + cy_rtos_delay_milliseconds(100); + } + + WPRINT_WHD_DEBUG_DS( ("wake host\n") ); + whd_wlan_wake_from_host(whd_driver); + + WPRINT_WHD_DEBUG_DS( ("poll for timeout\n") ); + /* Poll for PROC_DONE to be set by ucode; timeout after a good amount of time */ + for (timeout = WHD_WLAN_WAKE_TIMEOUT * 10, val = 0; timeout >= 0; + timeout -= WHD_SHARED_MEMORY_POLLING_DELAY) + { + whd_result_t read_result = + whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(sdio_control_addr), 2, (uint8_t *)&val); + + if ( (WHD_SUCCESS != read_result) || !( (val) & C_DS1_CTRL_PROC_DONE ) ) + { + cy_rtos_delay_milliseconds (WHD_SHARED_MEMORY_POLLING_DELAY); + } + else + { + /* success! */ + WPRINT_WHD_DEBUG_DS( ("Ucode has posted DONE\n") ); + break; + } + } + + WPRINT_WHD_DEBUG_DS( ("%s: %d: 0x%08x\n", __func__, __LINE__, (unsigned int)val) ); + + if ( (timeout < 0) && !(val & C_DS1_CTRL_PROC_DONE) ) + { + WPRINT_WHD_ERROR( ("%s: Failed to enter DS1 Exit state!\n", __func__) ); + return WHD_TIMEOUT; + } + } + WPRINT_WHD_DEBUG_DS( ("successfully completed DS wake sequence\n") ); + return WHD_SUCCESS; + } + else + { + UNUSED_PARAMETER(wake_from_firmware); + UNUSED_PARAMETER(wake_event_indication_addr); + UNUSED_PARAMETER(wake_indication_addr); + UNUSED_PARAMETER(sdio_control_addr); + + WPRINT_WHD_DEBUG( ("%s: enter\n", __FUNCTION__) ); + + CHECK_RETURN(whd_bus_write_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, + SDIO_FUNC_ENABLE_1) ); + WPRINT_WHD_DEBUG( ("%s: CCCR written\n", __FUNCTION__) ); + + /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX * For RX Cases , Value will be DS1_SLEEP * For TX Cases, Value will be MAC ON or RADIO_PHY_ON */ - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2, - (uint8_t *)&val)); - if (val == DS1_SLEEP) { - /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2, + (uint8_t *)&val) ); + if (val == DS1_SLEEP) + { + /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases * Simply update PMU Resource Mask and Re-download firmware for this case */ - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK)); - return WHD_SUCCESS; - } - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2, - C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID)); - WPRINT_WHD_DEBUG(("%s: SDIO ctl written\n", __FUNCTION__)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val)); - WPRINT_WHD_DEBUG(("%s: M_DS1_CTRL_SDIO = [%x]\n", __FUNCTION__, (int)val)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1)); - WPRINT_WHD_DEBUG(("%s: before setting wake = [%x]\n", __FUNCTION__, (int)val1)); - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, - val1 | D11_MACCONTROL_REG_WAKE)); - WPRINT_WHD_DEBUG(("%s: After setting wake= [%x]\n", __FUNCTION__, (int)val1)); - - while (!(val & C_DS1_CTRL_PROC_DONE)) { - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, - (uint8_t *)&val)); - count++; - if (count == 1000) { - WPRINT_WHD_ERROR(("%s: sdio timed out! Aborting\n", __FUNCTION__)); - return WHD_TIMEOUT; - } - } - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val)); - WPRINT_WHD_DEBUG(("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __FUNCTION__, (int)val)); - - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1)); - WPRINT_WHD_DEBUG(("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __FUNCTION__, (int)val1)); - - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, - val1 & D11_MACCONTROL_CLEAR_WAKE)); - WPRINT_WHD_DEBUG(("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __FUNCTION__, (int)val1)); + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) ); + return WHD_SUCCESS; + } + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2, + C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) ); + WPRINT_WHD_DEBUG( ("%s: SDIO ctl written\n", __FUNCTION__) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR( + M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val) ); + WPRINT_WHD_DEBUG( ("%s: M_DS1_CTRL_SDIO = [%x]\n", __FUNCTION__, (int)val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG( ("%s: before setting wake = [%x]\n", __FUNCTION__, (int)val1) ); + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, + val1 | D11_MACCONTROL_REG_WAKE) ); + WPRINT_WHD_DEBUG( ("%s: After setting wake= [%x]\n", __FUNCTION__, (int)val1) ); + + while (!(val & C_DS1_CTRL_PROC_DONE) ) + { + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + count++; + if (count == 1000) + { + WPRINT_WHD_ERROR( ("%s: sdio timed out! Aborting\n", __FUNCTION__) ); + return WHD_TIMEOUT; + } + } + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR( + M_DS1_CTRL_SDIO), (uint8_t)2, (uint8_t *)&val) ); + WPRINT_WHD_DEBUG( ("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __FUNCTION__, (int)val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG( ("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __FUNCTION__, (int)val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, + val1 & D11_MACCONTROL_CLEAR_WAKE) ); + WPRINT_WHD_DEBUG( ("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __FUNCTION__, (int)val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK) ); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG( ("%s: PMU_MINRESMASK = [%x]\n", __FUNCTION__, (int)val1) ); + return WHD_SUCCESS; + } +} +#else +whd_result_t whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver, whd_bool_t wake_from_ucode ) +{ +#ifndef DM_43022C1 + uint32_t val; + uint32_t val1; + uint32_t count = 0; + uint32_t wake_event_ind = 0; + uint32_t ulp_wake_ind = 0; +#endif + uint8_t enb_rd = 0; + /* Get chip number */ + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + + if ((wlan_chip_id == 43012) || (wlan_chip_id == 43022)) + { + WPRINT_WHD_DEBUG_DS( ("%s: enter: wake_fr_fw=%d\n", __func__, (int )wake_from_ucode) ); + + whd_driver->ds_exit_in_progress = WHD_TRUE; + /* Release the transceive_semaphore, if acquired for some tx/rx operations */ + (void)cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_TRUE); + + whd_driver->internal_info.whd_wlan_status.state = WLAN_OFF; + + CHECK_RETURN(whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IOEN, (uint8_t)1, &enb_rd)) + + if(enb_rd == SDIO_FUNC_ENABLE_1) + { + WPRINT_WHD_DEBUG(("GOT UCODE INTERRUPT \n")); + +#ifndef DM_43022C1 + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_WAKEEVENT_IND), 4, + (uint8_t *)&wake_event_ind) ); + WPRINT_WHD_DEBUG(("M_WAKEEVENT_IND is 0x%x \n", wake_event_ind)); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_ULP_WAKE_IND), 4, (uint8_t *)&ulp_wake_ind) ); + WPRINT_WHD_DEBUG(("M_ULP_WAKE_IND is 0x%x \n", ulp_wake_ind)); + + if((M_WAKEEVENT_IND % 4)) + { + wake_event_ind = (wake_event_ind >> 16); + WPRINT_WHD_DEBUG(("M_WAKEEVENT_IND[MOD] is 0x%x \n", wake_event_ind)); + } + else + { + wake_event_ind = (wake_event_ind & 0x0000FFFF); + WPRINT_WHD_DEBUG(("M_WAKEEVENT_IND[MOD-1] is 0x%x \n", wake_event_ind)); + } + + if((M_ULP_WAKE_IND % 4)) + { + ulp_wake_ind = (ulp_wake_ind >> 16); + WPRINT_WHD_DEBUG(("M_ULP_WAKE_IND[MOD] is 0x%x \n", ulp_wake_ind)); + } + else + { + ulp_wake_ind = (ulp_wake_ind & 0x0000FFFF); + WPRINT_WHD_DEBUG(("M_ULP_WAKE_IND[MOD-1] is 0x%x \n", ulp_wake_ind)); + } + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 4, + DEFAULT_43012_MIN_RES_MASK) ); +#else + /* For 43022DM, host should not access any core other than SDIO, + it it access, it will end up in FW crash(intentional crash) */ + WPRINT_WHD_INFO( ("Successfully completed DS wake sequence\n") ); + return WHD_SUCCESS; +#endif /* DM_43022C1 */ + +#ifndef DM_43022C1 + if (wake_from_ucode == WHD_TRUE) + { + WPRINT_WHD_DEBUG_DS( ("%s: CCCR written\n", __func__) ); + + /* Read DS1 CTRL STATUS SHM to Check whether HOST MAIL BOX interrupt is triggered due to TX/RX + * For RX Cases , Value will be DS1_SLEEP + * For TX Cases, Value will be MAC ON or RADIO_PHY_ON + */ + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_STATUS), (uint8_t)2, + (uint8_t *)&val) ); + + WPRINT_WHD_DEBUG((" DS1 CTRL STATUS is 0x%x\n", val)); + + if ( (wake_event_ind > 0) || (ulp_wake_ind > 0) ) + { + /* HUDI communication to inform D11 to Process and Exit DS1 not required for D11 Wake cases + * Simply update PMU Resource Mask and Re-download firmware for this case + */ + WPRINT_WHD_DEBUG_DS( ("%s: D11 wake detected\n", __func__) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 4, + DEFAULT_43012_MIN_RES_MASK) ); + + } + else + { + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), 2, + C_DS1_CTRL_SDIO_DS1_EXIT | C_DS1_CTRL_REQ_VALID) ); + WPRINT_WHD_DEBUG_DS( ("%s: SDIO ctl written\n", __func__) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO = [%x]\n", __func__, (int )val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)4, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG_DS( ("%s: before setting wake = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 4, + val1 | D11_MACCONTROL_REG_WAKE) ); + WPRINT_WHD_DEBUG_DS( ("%s: After setting wake= [%x]\n", __func__, (int )val1) ); + + while (!(val & C_DS1_CTRL_PROC_DONE) ) + { + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + count++; + WPRINT_WHD_DEBUG(("PROC READ - 0x%x \t", val)); + if (count == 1000) + { + WPRINT_WHD_ERROR( ("%s: sdio timed out! Aborting\n", __func__) ); + return WHD_TIMEOUT; + } + } + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11SHM_ADDR(M_DS1_CTRL_SDIO), (uint8_t)2, + (uint8_t *)&val) ); + WPRINT_WHD_DEBUG_DS( ("%s: M_DS1_CTRL_SDIO after poll = [%x]\n", __func__, (int )val) ); + + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, D11_MACCONTROL_REG, (uint8_t)2, (uint8_t *)&val1) ); + WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG before Clear = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, D11_MACCONTROL_REG, 2, + val1 & D11_MACCONTROL_CLEAR_WAKE) ); + WPRINT_WHD_DEBUG_DS( ("%s: D11_MACCONTROL_REG after Clear = [%x]\n", __func__, (int )val1) ); + + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 4, DEFAULT_43012_MIN_RES_MASK) ); + CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)4, (uint8_t *)&val1) ); + + WPRINT_WHD_DEBUG_DS( ("%s: PMU_MINRESMASK = [%x]\n", __func__, (int )val1) ); + + } + WPRINT_WHD_INFO( ("successfully completed DS wake sequence\n") ); + return WHD_SUCCESS; + } +#endif /* DM_43022C1 */ + } + else + { + WPRINT_WHD_ERROR( ("SDIO I/O Enable Failed\n") ); + return WHD_BADARG; + } + } + + WPRINT_WHD_ERROR( ("Chip Doesn't support ULP Wake \n") ); + return WHD_BADARG; +} - CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, PMU_MINRESMASK, 1, DEFAULT_43012_MIN_RES_MASK)); - CHECK_RETURN(whd_bus_read_backplane_value(whd_driver, PMU_MINRESMASK, (uint8_t)1, (uint8_t *)&val1)); - WPRINT_WHD_DEBUG(("%s: PMU_MINRESMASK = [%x]\n", __FUNCTION__, (int)val1)); - return WHD_SUCCESS; - } +whd_result_t whd_ensure_wlan_bus_not_in_deep_sleep(whd_driver_t whd_driver) +{ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + uint8_t byte_data = 0; + int loop_count = 0; + + if ((wlan_chip_id == 43012) || (wlan_chip_id == 43022)) + { + /* Wait for F2 to be ready */ + while ( ( (whd_bus_read_register_value(whd_driver, BUS_FUNCTION, SDIOD_CCCR_IORDY, (uint8_t)1, &byte_data) ) != WHD_SUCCESS ) || + ( ( (byte_data & SDIO_FUNC_READY_2) == 0 ) && (loop_count < WAKE_FROM_UCODE_TIMEOUT_LOOPS) ) ) + { + (void)cy_rtos_delay_milliseconds( (uint32_t)WAKE_FROM_UCODE_CHECK_PER_LOOP ); /* Ignore return - nothing can be done if it fails */ + loop_count++; + } + + if (loop_count >= (uint32_t)WAKE_FROM_UCODE_TIMEOUT_LOOPS) + { + WPRINT_WHD_DEBUG( ("F2 ready timed out \n") ); + /* Reachable after hitting assert */ + return WHD_FALSE; + } + + } + return WHD_TRUE; } + +#endif /* CYCFG_ULP_SUPPORT_ENABLED */ diff --git a/wi-fi/whd/whd_chip.h b/wi-fi/whd/whd_chip.h index 18ffea77..fe2237de 100644 --- a/wi-fi/whd/whd_chip.h +++ b/wi-fi/whd/whd_chip.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,8 @@ #include "whd_wifi_api.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -42,87 +43,96 @@ extern "C" { * Enumerated list of aggregate codes and edit WHD_COUNTRY_AGGREGATE_CUSTOMER for supporting new aggregate * as per customer like XZ/278 */ -typedef enum { - WHD_COUNTRY_AGGREGATE_XA_0 = MK_CNTRY('X', 'A', 0), - WHD_COUNTRY_AGGREGATE_XT_0 = MK_CNTRY('X', 'T', 0), - WHD_COUNTRY_AGGREGATE_XV_0 = MK_CNTRY('X', 'V', 0), - WHD_COUNTRY_AGGREGATE_CUSTOMER = MK_CNTRY('X', 'Z', 278), +typedef enum +{ + WHD_COUNTRY_AGGREGATE_XA_0 = MK_CNTRY('X', 'A', 0), + WHD_COUNTRY_AGGREGATE_XT_0 = MK_CNTRY('X', 'T', 0), + WHD_COUNTRY_AGGREGATE_XV_0 = MK_CNTRY('X', 'V', 0), + WHD_COUNTRY_AGGREGATE_CUSTOMER = MK_CNTRY('X', 'Z', 278), } whd_aggregate_code_t; -typedef enum { - /* Note : If changing this, core_base_address must be changed also */ - WLAN_ARM_CORE = 0, - SOCRAM_CORE = 1, - SDIOD_CORE = 2 +typedef enum +{ + /* Note : If changing this, core_base_address must be changed also */ + WLAN_ARM_CORE = 0, SOCRAM_CORE = 1, SDIOD_CORE = 2 } device_core_t; -typedef enum { - WLAN_DOWN, - WLAN_UP, - WLAN_OFF +typedef enum +{ + WLAN_DOWN, WLAN_UP, WLAN_OFF } wlan_state_t; -typedef enum { - WLAN_CORE_FLAG_NONE, - WLAN_CORE_FLAG_CPU_HALT, +typedef enum +{ + WLAN_CORE_FLAG_NONE, WLAN_CORE_FLAG_CPU_HALT, } wlan_core_flag_t; /** * Enumeration of AKM (authentication and key management) suites. Table 8-140 802.11mc D3.0. */ -typedef enum { - WHD_AKM_RESERVED = 0, - WHD_AKM_8021X = 1, /**< WPA2 enterprise */ - WHD_AKM_PSK = 2, /**< WPA2 PSK */ - WHD_AKM_FT_8021X = 3, /**< 802.11r Fast Roaming enterprise */ - WHD_AKM_FT_PSK = 4, /**< 802.11r Fast Roaming PSK */ - WHD_AKM_8021X_SHA256 = 5, - WHD_AKM_PSK_SHA256 = 6, - WHD_AKM_TDLS = 7, /**< Tunneled Direct Link Setup */ - WHD_AKM_SAE_SHA256 = 8, - WHD_AKM_FT_SAE_SHA256 = 9, - WHD_AKM_AP_PEER_KEY_SHA256 = 10, - WHD_AKM_SUITEB_8021X_HMAC_SHA256 = 11, - WHD_AKM_SUITEB_8021X_HMAC_SHA384 = 12, - WHD_AKM_SUITEB_FT_8021X_HMAC_SHA384 = 13, +typedef enum +{ + WHD_AKM_RESERVED = 0, + WHD_AKM_8021X = 1, /**< WPA2 enterprise */ + WHD_AKM_PSK = 2, /**< WPA2 PSK */ + WHD_AKM_FT_8021X = 3, /**< 802.11r Fast Roaming enterprise */ + WHD_AKM_FT_PSK = 4, /**< 802.11r Fast Roaming PSK */ + WHD_AKM_8021X_SHA256 = 5, + WHD_AKM_PSK_SHA256 = 6, + WHD_AKM_TDLS = 7, /**< Tunneled Direct Link Setup */ + WHD_AKM_SAE_SHA256 = 8, + WHD_AKM_FT_SAE_SHA256 = 9, + WHD_AKM_AP_PEER_KEY_SHA256 = 10, + WHD_AKM_SUITEB_8021X_HMAC_SHA256 = 11, + WHD_AKM_SUITEB_8021X_HMAC_SHA384 = 12, + WHD_AKM_SUITEB_FT_8021X_HMAC_SHA384 = 13, } whd_akm_suite_t; /** * Enumeration of cipher suites. Table 8-138 802.11mc D3.0. */ -typedef enum { - WHD_CIPHER_GROUP = 0, /**< Use group cipher suite */ - WHD_CIPHER_WEP_40 = 1, /**< WEP-40 */ - WHD_CIPHER_TKIP = 2, /**< TKIP */ - WHD_CIPHER_RESERVED = 3, /**< Reserved */ - WHD_CIPHER_CCMP_128 = 4, /**< CCMP-128 - default pairwise and group cipher suite in an RSNA */ - WHD_CIPHER_WEP_104 = 5, /**< WEP-104 - also known as WEP-128 */ - WHD_CIPHER_BIP_CMAC_128 = 6, /**< BIP-CMAC-128 - default management frame cipher suite */ - WHD_CIPHER_GROUP_DISALLOWED = 7, /**< Group address traffic not allowed */ - WHD_CIPHER_GCMP_128 = 8, /**< GCMP-128 - default for 60 GHz STAs */ - WHD_CIPHER_GCMP_256 = 9, /**< GCMP-256 - introduced for Suite B */ - WHD_CIPHER_CCMP_256 = 10, /**< CCMP-256 - introduced for suite B */ - WHD_CIPHER_BIP_GMAC_128 = 11, /**< BIP-GMAC-128 - introduced for suite B */ - WHD_CIPHER_BIP_GMAC_256 = 12, /**< BIP-GMAC-256 - introduced for suite B */ - WHD_CIPHER_BIP_CMAC_256 = 13, /**< BIP-CMAC-256 - introduced for suite B */ +typedef enum +{ + WHD_CIPHER_GROUP = 0, /**< Use group cipher suite */ + WHD_CIPHER_WEP_40 = 1, /**< WEP-40 */ + WHD_CIPHER_TKIP = 2, /**< TKIP */ + WHD_CIPHER_RESERVED = 3, /**< Reserved */ + WHD_CIPHER_CCMP_128 = 4, /**< CCMP-128 - default pairwise and group cipher suite in an RSNA */ + WHD_CIPHER_WEP_104 = 5, /**< WEP-104 - also known as WEP-128 */ + WHD_CIPHER_BIP_CMAC_128 = 6, /**< BIP-CMAC-128 - default management frame cipher suite */ + WHD_CIPHER_GROUP_DISALLOWED = 7, /**< Group address traffic not allowed */ + WHD_CIPHER_GCMP_128 = 8, /**< GCMP-128 - default for 60 GHz STAs */ + WHD_CIPHER_GCMP_256 = 9, /**< GCMP-256 - introduced for Suite B */ + WHD_CIPHER_CCMP_256 = 10, /**< CCMP-256 - introduced for suite B */ + WHD_CIPHER_BIP_GMAC_128 = 11, /**< BIP-GMAC-128 - introduced for suite B */ + WHD_CIPHER_BIP_GMAC_256 = 12, /**< BIP-GMAC-256 - introduced for suite B */ + WHD_CIPHER_BIP_CMAC_256 = 13, /**< BIP-CMAC-256 - introduced for suite B */ } whd_80211_cipher_t; /****************************************************** * Structures ******************************************************/ -typedef struct whd_chip_info { - uint16_t chip_id; - whd_bool_t save_restore_enable; - +typedef struct whd_chip_info +{ + uint16_t chip_id; + uint8_t chipid_in_sdiocore; /* To check ChipId is present in SdioCore */ + whd_bool_t save_restore_enable; + uint32_t fwcap_flags; } whd_chip_info_t; +typedef struct whd_fwcap +{ + whd_fwcap_id_t feature; + const char *const fwcap_name; +} whd_fwcap_t; + typedef struct { - wlan_state_t state; - whd_country_code_t country_code; - whd_aggregate_code_t aggregate_code; - uint32_t keep_wlan_awake; + wlan_state_t state; + whd_country_code_t country_code; + whd_aggregate_code_t aggregate_code; + uint32_t keep_wlan_awake; } whd_wlan_status_t; #pragma pack(1) @@ -134,49 +144,49 @@ typedef struct typedef struct { - uint8_t first_chan_num; - uint8_t num_chans; - uint8_t max_tx_pwr_level; + uint8_t first_chan_num; + uint8_t num_chans; + uint8_t max_tx_pwr_level; } country_chan_info_t; /* Structures for TLVs with 8-bit type and 8-bit length */ typedef struct { - uint8_t type; - uint8_t length; + uint8_t type; + uint8_t length; } whd_tlv8_header_t; typedef struct { - uint8_t type; - uint8_t length; - uint8_t data[1]; + uint8_t type; + uint8_t length; + uint8_t data[1]; } whd_tlv8_data_t; typedef struct { - whd_tlv8_header_t tlv_header; /* id, length */ - char ccode[2]; /* dot11CountryString MIB octet 1~2, two letter country code */ - uint8_t env; /* dot11CountryString MIB octet 3, indicate indoor/outdoor environment */ - country_chan_info_t country_chan_info[1]; /* At least one country channel info triples */ + whd_tlv8_header_t tlv_header; /* id, length */ + char ccode[2]; /* dot11CountryString MIB octet 1~2, two letter country code */ + uint8_t env; /* dot11CountryString MIB octet 3, indicate indoor/outdoor environment */ + country_chan_info_t country_chan_info[1]; /* At least one country channel info triples */ } country_info_ie_fixed_portion_t; /* Robust Secure Network */ typedef struct { - whd_tlv8_header_t tlv_header; /* id, length */ - uint16_t version; - uint32_t group_key_suite; /* See whd_80211_cipher_t for values */ - uint16_t pairwise_suite_count; - uint32_t pairwise_suite_list[1]; + whd_tlv8_header_t tlv_header; /* id, length */ + uint16_t version; + uint32_t group_key_suite; /* See whd_80211_cipher_t for values */ + uint16_t pairwise_suite_count; + uint32_t pairwise_suite_list[1]; } rsn_ie_fixed_portion_t; #define RSN_IE_MINIMUM_LENGTH (8) typedef struct { - whd_tlv8_header_t tlv_header; /* id, length */ - uint8_t oui[4]; + whd_tlv8_header_t tlv_header; /* id, length */ + uint8_t oui[4]; } vendor_specific_ie_header_t; #define VENDOR_SPECIFIC_IE_MINIMUM_LENGTH (4) @@ -184,48 +194,58 @@ typedef struct /* WPA IE */ typedef struct { - vendor_specific_ie_header_t vendor_specific_header; - uint16_t version; - uint32_t multicast_suite; - uint16_t unicast_suite_count; - uint8_t unicast_suite_list[1][4]; + vendor_specific_ie_header_t vendor_specific_header; + uint16_t version; + uint32_t multicast_suite; + uint16_t unicast_suite_count; + uint8_t unicast_suite_list[1][4]; } wpa_ie_fixed_portion_t; #define WPA_IE_MINIMUM_LENGTH (12) typedef struct { - uint16_t akm_suite_count; - uint32_t akm_suite_list[1]; + uint16_t akm_suite_count; + uint32_t akm_suite_list[1]; } akm_suite_portion_t; +/* RSNX IE */ +typedef struct +{ + whd_tlv8_header_t tlv_header; /* id, length */ + uint8_t data[1]; +} rsnx_ie_t; + +#define DOT11_RSNX_CAP_LEN 1 /* Extended RSN Capabilities length in octets (1 octet) */ +#define DOT11_RSNX_SAE_H2E 5 /* Extended RSN Capabilities */ + typedef struct { - whd_tlv8_header_t tlv_header; /* id, length */ - uint16_t ht_capabilities_info; - uint8_t ampdu_parameters; - uint8_t rx_mcs[10]; - uint16_t rxhighest_supported_data_rate; - uint8_t tx_supported_mcs_set; - uint8_t tx_mcs_info[3]; - uint16_t ht_extended_capabilities; - uint32_t transmit_beam_forming_capabilities; - uint8_t antenna_selection_capabilities; + whd_tlv8_header_t tlv_header; /* id, length */ + uint16_t ht_capabilities_info; + uint8_t ampdu_parameters; + uint8_t rx_mcs[10]; + uint16_t rxhighest_supported_data_rate; + uint8_t tx_supported_mcs_set; + uint8_t tx_mcs_info[3]; + uint16_t ht_extended_capabilities; + uint32_t transmit_beam_forming_capabilities; + uint8_t antenna_selection_capabilities; } ht_capabilities_ie_t; -#define HT_CAPABILITIES_INFO_LDPC_CODING_CAPABILITY (1 << 0) -#define HT_CAPABILITIES_INFO_SUPPORTED_CHANNEL_WIDTH_SET (1 << 1) -#define HT_CAPABILITIES_INFO_SM_POWER_SAVE_OFFSET (1 << 2) -#define HT_CAPABILITIES_INFO_SM_POWER_SAVE_MASK (3 << 2) -#define HT_CAPABILITIES_INFO_HT_GREENFIELD (1 << 4) -#define HT_CAPABILITIES_INFO_SHORT_GI_FOR_20MHZ (1 << 5) -#define HT_CAPABILITIES_INFO_SHORT_GI_FOR_40MHZ (1 << 6) -#define HT_CAPABILITIES_INFO_TX_STBC (1 << 7) -#define HT_CAPABILITIES_INFO_RX_STBC_OFFSET (1 << 8) -#define HT_CAPABILITIES_INFO_RX_STBC_MASK (3 << 8) -#define HT_CAPABILITIES_INFO_HT_DELAYED_BLOCK_ACK (1 << 10) -#define HT_CAPABILITIES_INFO_MAXIMUM_A_MSDU_LENGTH (1 << 11) -#define HT_CAPABILITIES_INFO_DSSS_CCK_MODE_IN_40MHZ (1 << 12) +#define HT_CAPABILITIES_INFO_LDPC_CODING_CAPABILITY (1 << 0) +#define HT_CAPABILITIES_INFO_SUPPORTED_CHANNEL_WIDTH_SET (1 << 1) +#define HT_CAPABILITIES_INFO_SM_POWER_SAVE_OFFSET (1 << 2) +#define HT_CAPABILITIES_INFO_SM_POWER_SAVE_MASK (3 << 2) +#define HT_CAPABILITIES_INFO_HT_GREENFIELD (1 << 4) +#define HT_CAPABILITIES_INFO_SHORT_GI_FOR_20MHZ (1 << 5) +#define HT_CAPABILITIES_INFO_SHORT_GI_FOR_40MHZ (1 << 6) +#define HT_CAPABILITIES_INFO_TX_STBC (1 << 7) +#define HT_CAPABILITIES_INFO_RX_STBC_OFFSET (1 << 8) +#define HT_CAPABILITIES_INFO_RX_STBC_MASK (3 << 8) +#define HT_CAPABILITIES_INFO_HT_DELAYED_BLOCK_ACK (1 << 10) +#define HT_CAPABILITIES_INFO_MAXIMUM_A_MSDU_LENGTH (1 << 11) +#define HT_CAPABILITIES_INFO_DSSS_CCK_MODE_IN_40MHZ (1 << 12) /* bit 13 reserved */ #define HT_CAPABILITIES_INFO_40MHZ_INTOLERANT (1 << 14) #define HT_CAPABILITIES_INFO_L_SIG_TXOP_PROTECTION_SUPPORT (1 << 15) @@ -233,125 +253,142 @@ typedef struct typedef unsigned int uint; typedef struct { - uint buf; - uint buf_size; - uint idx; - uint out_idx; /* output index */ + uint buf; + uint buf_size; + uint idx; + uint out_idx; /* output index */ } hnd_log_t; #define CBUF_LEN 128 typedef struct { - /* Virtual UART + /* Virtual UART * When there is no UART (e.g. Quickturn), the host should write a complete * input line directly into cbuf and then write the length into vcons_in. * This may also be used when there is a real UART (at risk of conflicting with * the real UART). vcons_out is currently unused. */ - volatile uint vcons_in; - volatile uint vcons_out; + volatile uint vcons_in; + volatile uint vcons_out; - /* Output (logging) buffer + /* Output (logging) buffer * Console output is written to a ring buffer log_buf at index log_idx. * The host may read the output when it sees log_idx advance. * Output will be lost if the output wraps around faster than the host polls. */ - hnd_log_t log; + hnd_log_t log; - /* Console input line buffer + /* Console input line buffer * Characters are read one at a time into cbuf until is received, then * the buffer is processed as a command line. Also used for virtual UART. */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; + uint cbuf_idx; + char cbuf[CBUF_LEN]; } hnd_cons_t; -typedef struct wifi_console { - uint count; /* Poll interval msec counter */ - uint log_addr; /* Log struct address (fixed) */ - hnd_log_t log; /* Log struct (host copy) */ - uint bufsize; /* Size of log buffer */ - char *buf; /* Log buffer (host copy) */ - uint last; /* Last buffer read index */ +typedef struct wifi_console +{ + uint count; /* Poll interval msec counter */ + uint log_addr; /* Log struct address (fixed) */ + hnd_log_t log; /* Log struct (host copy) */ + uint bufsize; /* Size of log buffer */ + char *buf; /* Log buffer (host copy) */ + uint last; /* Last buffer read index */ } wifi_console_t; typedef struct { - uint flags; - uint trap_addr; - uint assert_exp_addr; - uint assert_file_addr; - uint assert_line; - uint console_addr; - uint msgtrace_addr; - uint fwid; + uint flags; + uint trap_addr; + uint assert_exp_addr; + uint assert_file_addr; + uint assert_line; + uint console_addr; + uint msgtrace_addr; + uint fwid; + uint total_lfrag_pktcount; + uint reserved; + uint reserved1; + uint h2d_mb_addr; + uint d2h_mb_addr; + uint ring_info_ptr; + uint scratch_mem_size; + uint scratch_mem_ptr_low; + uint scratch_mem_ptr_high; } wlan_shared_t; /* Buffer size to be allocated to read wlan log */ #define WLAN_LOG_BUF_LEN (4 * 1024) -#define WHD_IOCTL_LOG_SIZE 64 +#define WHD_IOCTL_LOG_SIZE 64 #define WHD_IOVAR_STRING_SIZE 128 -#define WHD_MAX_DATA_SIZE 64 +#define WHD_MAX_DATA_SIZE 64 typedef struct { - uint32_t ioct_log; - uint8_t is_this_event; - uint8_t data[WHD_MAX_DATA_SIZE]; - uint32_t data_size; - uint16_t flag; - uint32_t reason; -} whd_ioctl_log_t; + uint32_t ioct_log; + uint8_t is_this_event; + uint8_t data[WHD_MAX_DATA_SIZE]; + uint32_t data_size; + uint16_t flag; + uint32_t reason; +}whd_ioctl_log_t; -void whd_ioctl_log_add(whd_driver_t whd_driver, uint32_t cmd, whd_buffer_t buffer); -void whd_ioctl_log_add_event(whd_driver_t whd_driver, uint32_t cmd, uint16_t flag, uint32_t data); +whd_result_t whd_ioctl_log_add(whd_driver_t whd_driver, uint32_t cmd, whd_buffer_t buffer); +whd_result_t whd_ioctl_log_add_event(whd_driver_t whd_driver, uint32_t cmd, uint16_t flag, uint32_t data); whd_result_t whd_ioctl_print(whd_driver_t whd_driver); #pragma pack() -typedef struct whd_internal_info { - whd_wlan_status_t whd_wlan_status; - wifi_console_t *c; - wifi_console_t console; - wlan_shared_t sh; - uint32_t console_addr; - whd_scan_result_callback_t scan_result_callback; - whd_scan_result_t *whd_scan_result_ptr; - /* The semaphore used to wait for completion of a join; +typedef struct whd_internal_info +{ + whd_wlan_status_t whd_wlan_status; + wifi_console_t *c; + wifi_console_t console; + wlan_shared_t sh; + uint32_t console_addr; + whd_scan_result_callback_t scan_result_callback; + whd_scan_result_t *whd_scan_result_ptr; + /* The semaphore used to wait for completion of a join; * whd_wifi_join_halt uses this to release waiting threads (if any) */ - cy_semaphore_t *active_join_semaphore; - whd_bool_t active_join_mutex_initted; - cy_semaphore_t active_join_mutex; - uint con_lastpos; - whd_bool_t whd_wifi_p2p_go_is_up; - uint32_t whd_join_status[3]; - + cy_semaphore_t *active_join_semaphore; + whd_bool_t active_join_mutex_initted; + cy_semaphore_t active_join_mutex; + uint con_lastpos; + whd_bool_t whd_wifi_p2p_go_is_up; + uint32_t whd_join_status[3]; + whd_auth_result_callback_t auth_result_callback; } whd_internal_info_t; #pragma pack(1) typedef struct { - char abbrev[3]; - uint8_t rev; - uint8_t data[64]; + char abbrev[3]; + uint8_t rev; + uint8_t data[64]; } whd_country_info_t; #pragma pack() -void whd_internal_info_init(whd_driver_t whd_driver); +whd_result_t whd_internal_info_init(whd_driver_t whd_driver); +whd_result_t whd_internal_info_deinit(whd_driver_t whd_driver); /****************************************************** * Function Declarations ******************************************************/ extern void whd_wifi_chip_info_init(whd_driver_t whd_driver); +#ifndef CYCFG_ULP_SUPPORT_ENABLED extern whd_result_t whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver, whd_bool_t wake_from_firmware, - uint32_t wake_event_indication_addr, uint32_t wake_indication_addr, - uint32_t sdio_control_addr); + uint32_t wake_event_indication_addr, uint32_t wake_indication_addr, + uint32_t sdio_control_addr); +#else +whd_result_t whd_wlan_bus_complete_ds_wake(whd_driver_t whd_driver, whd_bool_t wake_from_ucode ); +whd_result_t whd_ensure_wlan_bus_not_in_deep_sleep(whd_driver_t whd_driver); +#endif extern whd_result_t whd_wifi_set_custom_country_code(whd_interface_t ifp, const whd_country_info_t *country_code); /* Device core control functions */ @@ -370,8 +407,8 @@ extern whd_result_t whd_chip_specific_socsram_init(whd_driver_t whd_driver); extern whd_result_t whd_wifi_read_wlan_log(whd_driver_t whd_driver, char *buffer, uint32_t buffer_size); extern whd_result_t whd_wifi_print_whd_log(whd_driver_t whd_driver); extern whd_result_t whd_wifi_read_wlan_log_unsafe(whd_driver_t whd_driver, uint32_t wlan_shared_address, char *buffer, - uint32_t buffer_size); - + uint32_t buffer_size); +extern whd_result_t whd_wifi_read_fw_capabilities(whd_interface_t ifp); extern void whd_wifi_peek(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint8_t *value); extern void whd_wifi_poke(whd_driver_t whd_driver, uint32_t address, uint8_t register_length, uint32_t value); extern uint32_t whd_wifi_get_btc_params(whd_driver_t whd_driver, uint32_t address, whd_interface_t interface); diff --git a/wi-fi/whd/whd_chip_constants.c b/wi-fi/whd/whd_chip_constants.c index c715ca07..292e4377 100644 --- a/wi-fi/whd/whd_chip_constants.c +++ b/wi-fi/whd/whd_chip_constants.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,377 +27,714 @@ uint32_t whd_chip_set_chip_id(whd_driver_t whd_driver, uint16_t id) { - whd_driver->chip_info.chip_id = id; + whd_driver->chip_info.chip_id = id; - return 0; + return 0; } uint16_t whd_chip_get_chip_id(whd_driver_t whd_driver) { - return whd_driver->chip_info.chip_id; + return whd_driver->chip_info.chip_id; +} + +whd_result_t whd_chip_get_chanspec_ctl_channel_num(whd_driver_t whd_driver, uint16_t chanspec, uint16_t *ctrl_ch_num) +{ + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + uint16_t bw = chanspec & get_whd_var(whd_driver, CHANSPEC_BW_MASK); + uint16_t sb = chanspec & get_whd_var(whd_driver, CHANSPEC_CTL_SB_MASK); + + *ctrl_ch_num = CHSPEC_CHANNEL(chanspec); + + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_SUCCESS; + } + else + { + if (bw == get_whd_var(whd_driver, CHANSPEC_BW_20) ) + { + return WHD_SUCCESS; + } + else if (bw == get_whd_var(whd_driver, CHANSPEC_BW_40) ) + { + if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_L) ) + *ctrl_ch_num -= CH_10MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_U) ) + *ctrl_ch_num += CH_10MHZ_APART; + else + { + WPRINT_WHD_ERROR( ("Error: Invalid chanspec 0x%04x\n", chanspec) ); + return WHD_BADARG; + } + } + else if (bw == get_whd_var(whd_driver, CHANSPEC_BW_80) ) + { + if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LL) ) + *ctrl_ch_num -= CH_30MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LU) ) + *ctrl_ch_num -= CH_10MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_UL) ) + *ctrl_ch_num += CH_10MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_UU) ) + *ctrl_ch_num += CH_30MHZ_APART; + else + { + WPRINT_WHD_ERROR( ("Error: Invalid chanspec 0x%04x\n", chanspec) ); + return WHD_BADARG; + } + } + else if (bw == get_whd_var(whd_driver, CHANSPEC_BW_160) ) + { + if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LLL) ) + *ctrl_ch_num -= CH_70MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LLU) ) + *ctrl_ch_num -= CH_50MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LUL) ) + *ctrl_ch_num -= CH_30MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_LUU) ) + *ctrl_ch_num -= CH_10MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_ULL) ) + *ctrl_ch_num += CH_10MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_ULU) ) + *ctrl_ch_num += CH_30MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_UUL) ) + *ctrl_ch_num += CH_50MHZ_APART; + else if (sb == get_whd_var(whd_driver, CHANSPEC_CTL_SB_UUU) ) + *ctrl_ch_num += CH_70MHZ_APART; + else + { + WPRINT_WHD_ERROR( ("Error: Invalid chanspec 0x%04x\n", chanspec) ); + return WHD_BADARG; + } + } + else + { + WPRINT_WHD_ERROR( ("Error: Invalid chanspec 0x%04x\n", chanspec) ); + return WHD_BADARG; + } + } + + return WHD_SUCCESS; } uint32_t get_whd_var(whd_driver_t whd_driver, chip_var_t var) { - uint32_t val = 0; - - uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); - switch (var) { - case ARM_CORE_BASE_ADDRESS: - CHECK_RETURN(get_arm_core_base_address(wlan_chip_id, &val)); - break; - case SOCSRAM_BASE_ADDRESS: - CHECK_RETURN(get_socsram_base_address(wlan_chip_id, &val, false)); - break; - case SOCSRAM_WRAPPER_BASE_ADDRESS: - CHECK_RETURN(get_socsram_base_address(wlan_chip_id, &val, true)); - break; - case SDIOD_CORE_BASE_ADDRESS: - CHECK_RETURN(get_sdiod_core_base_address(wlan_chip_id, &val)); - break; - case PMU_BASE_ADDRESS: - CHECK_RETURN(get_pmu_base_address(wlan_chip_id, &val)); - break; - case CHIP_RAM_SIZE: - CHECK_RETURN(get_chip_ram_size(wlan_chip_id, &val)); - break; - case ATCM_RAM_BASE_ADDRESS: - CHECK_RETURN(get_atcm_ram_base_address(wlan_chip_id, &val)); - break; - case SOCRAM_SRMEM_SIZE: - CHECK_RETURN(get_socsram_srmem_size(wlan_chip_id, &val)); - break; - case CHANSPEC_BAND_MASK: - CHECK_RETURN(get_wl_chanspec_band_mask(wlan_chip_id, &val)); - break; - case CHANSPEC_BAND_2G: - CHECK_RETURN(get_wl_chanspec_band_2G(wlan_chip_id, &val)); - break; - case CHANSPEC_BAND_5G: - CHECK_RETURN(get_wl_chanspec_band_5G(wlan_chip_id, &val)); - break; - case CHANSPEC_BAND_SHIFT: - CHECK_RETURN(get_wl_chanspec_band_shift(wlan_chip_id, &val)); - break; - case CHANSPEC_BW_10: - CHECK_RETURN(get_wl_chanspec_bw_10(wlan_chip_id, &val)); - break; - case CHANSPEC_BW_20: - CHECK_RETURN(get_wl_chanspec_bw_20(wlan_chip_id, &val)); - break; - case CHANSPEC_BW_40: - CHECK_RETURN(get_wl_chanspec_bw_40(wlan_chip_id, &val)); - break; - case CHANSPEC_BW_MASK: - CHECK_RETURN(get_wl_chanspec_bw_mask(wlan_chip_id, &val)); - break; - case CHANSPEC_BW_SHIFT: - CHECK_RETURN(get_wl_chanspec_bw_shift(wlan_chip_id, &val)); - break; - case CHANSPEC_CTL_SB_LOWER: - CHECK_RETURN(get_wl_chanspec_ctl_sb_lower(wlan_chip_id, &val)); - break; - case CHANSPEC_CTL_SB_UPPER: - CHECK_RETURN(get_wl_chanspec_ctl_sb_upper(wlan_chip_id, &val)); - break; - case CHANSPEC_CTL_SB_NONE: - CHECK_RETURN(get_wl_chanspec_ctl_sb_none(wlan_chip_id, &val)); - break; - case CHANSPEC_CTL_SB_MASK: - CHECK_RETURN(get_wl_chanspec_ctl_sb_mask(wlan_chip_id, &val)); - break; - default: - break; - } - return val; + uint32_t val = 0; + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + switch (var) + { + case ARM_CORE_BASE_ADDRESS: + CHECK_RETURN(get_arm_core_base_address(wlan_chip_id, &val) ); + break; + case SOCSRAM_BASE_ADDRESS: + CHECK_RETURN(get_socsram_base_address(wlan_chip_id, &val, WHD_FALSE) ); + break; + case SOCSRAM_WRAPPER_BASE_ADDRESS: + CHECK_RETURN(get_socsram_base_address(wlan_chip_id, &val, WHD_TRUE) ); + break; + case SDIOD_CORE_BASE_ADDRESS: + CHECK_RETURN(get_sdiod_core_base_address(wlan_chip_id, &val) ); + break; + case PMU_BASE_ADDRESS: + CHECK_RETURN(get_pmu_base_address(wlan_chip_id, &val) ); + break; + case CHIP_RAM_SIZE: + CHECK_RETURN(get_chip_ram_size(wlan_chip_id, &val) ); + break; + case ATCM_RAM_BASE_ADDRESS: + CHECK_RETURN(get_atcm_ram_base_address(wlan_chip_id, &val) ); + break; + case SOCRAM_SRMEM_SIZE: + CHECK_RETURN(get_socsram_srmem_size(wlan_chip_id, &val) ); + break; + case CHANSPEC_BAND_MASK: + CHECK_RETURN(get_wl_chanspec_band_mask(wlan_chip_id, &val) ); + break; + case CHANSPEC_BAND_2G: + CHECK_RETURN(get_wl_chanspec_band_2G(wlan_chip_id, &val) ); + break; + case CHANSPEC_BAND_5G: + CHECK_RETURN(get_wl_chanspec_band_5G(wlan_chip_id, &val) ); + break; + case CHANSPEC_BAND_6G: + CHECK_RETURN(get_wl_chanspec_band_6G(wlan_chip_id, &val) ); + break; + case CHANSPEC_BAND_SHIFT: + CHECK_RETURN(get_wl_chanspec_band_shift(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_10: + CHECK_RETURN(get_wl_chanspec_bw_10(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_20: + CHECK_RETURN(get_wl_chanspec_bw_20(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_40: + CHECK_RETURN(get_wl_chanspec_bw_40(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_80: + CHECK_RETURN(get_wl_chanspec_bw_80(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_160: + CHECK_RETURN(get_wl_chanspec_bw_160(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_MASK: + CHECK_RETURN(get_wl_chanspec_bw_mask(wlan_chip_id, &val) ); + break; + case CHANSPEC_BW_SHIFT: + CHECK_RETURN(get_wl_chanspec_bw_shift(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_NONE: + CHECK_RETURN(get_wl_chanspec_ctl_sb_none(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_LLL: + CHECK_RETURN(get_wl_chanspec_ctl_sb_LLL(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_LLU: + CHECK_RETURN(get_wl_chanspec_ctl_sb_LLU(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_LUL: + CHECK_RETURN(get_wl_chanspec_ctl_sb_LUL(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_LUU: + CHECK_RETURN(get_wl_chanspec_ctl_sb_LUU(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_ULL: + CHECK_RETURN(get_wl_chanspec_ctl_sb_ULL(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_ULU: + CHECK_RETURN(get_wl_chanspec_ctl_sb_ULU(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_UUL: + CHECK_RETURN(get_wl_chanspec_ctl_sb_UUL(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_UUU: + CHECK_RETURN(get_wl_chanspec_ctl_sb_UUU(wlan_chip_id, &val) ); + break; + case CHANSPEC_CTL_SB_MASK: + CHECK_RETURN(get_wl_chanspec_ctl_sb_mask(wlan_chip_id, &val) ); + break; + case NVRAM_DNLD_ADDR: + CHECK_RETURN(get_nvram_dwnld_start_address(wlan_chip_id, &val) ); + break; + default: + break; + } + return val; } whd_result_t get_arm_core_base_address(uint16_t wlan_chip_id, uint32_t *addr) { - switch (wlan_chip_id) { - case 0x4373: - *addr = 0x18002000 + WRAPPER_REGISTER_OFFSET; - break; - case 43012: - case 43430: - case 43439: - *addr = 0x18003000 + WRAPPER_REGISTER_OFFSET; - break; - case 43909: - case 43907: - case 54907: - *addr = 0x18011000 + WRAPPER_REGISTER_OFFSET; - break; - default: - return WHD_BADARG; - } - return WHD_SUCCESS; + switch (wlan_chip_id) + { + case 0x4373: + case 55560: + case 55500: + *addr = 0x18002000 + WRAPPER_REGISTER_OFFSET; + break; + case 43012: + case 43022: + case 43430: + case 43439: + *addr = 0x18003000 + WRAPPER_REGISTER_OFFSET; + break; + case 43909: + case 43907: + case 54907: + *addr = 0x18011000 + WRAPPER_REGISTER_OFFSET; + break; + default: + return WHD_BADARG; + } + return WHD_SUCCESS; } whd_result_t get_socsram_base_address(uint16_t wlan_chip_id, uint32_t *addr, whd_bool_t wrapper) { - uint32_t offset = 0; - if (wrapper) { - offset = WRAPPER_REGISTER_OFFSET; - } - switch (wlan_chip_id) { - case 43012: - case 43430: - case 43439: - *addr = 0x18004000 + offset; - break; - default: - return WHD_BADARG; - } - return WHD_SUCCESS; + uint32_t offset = 0; + if (wrapper) + { + offset = WRAPPER_REGISTER_OFFSET; + } + switch (wlan_chip_id) + { + case 43012: + case 43022: + case 43430: + case 43439: + *addr = 0x18004000 + offset; + break; + default: + return WHD_BADARG; + } + return WHD_SUCCESS; } whd_result_t get_sdiod_core_base_address(uint16_t wlan_chip_id, uint32_t *addr) { - switch (wlan_chip_id) { - case 0x4373: - *addr = 0x18005000; - break; - case 43012: - case 43430: - case 43439: - *addr = 0x18002000; - break; - default: - return WHD_BADARG; - } - return WHD_SUCCESS; + switch (wlan_chip_id) + { + case 55560: + *addr = 0x18004000; + break; + case 55500: + *addr = 0x18003000; + break; + case 0x4373: + *addr = 0x18005000; + break; + case 43012: + case 43022: + case 43430: + case 43439: + *addr = 0x18002000; + break; + default: + return WHD_BADARG; + } + return WHD_SUCCESS; } whd_result_t get_pmu_base_address(uint16_t wlan_chip_id, uint32_t *addr) { - switch (wlan_chip_id) { - case 0x4373: - case 43430: - case 43439: - *addr = CHIPCOMMON_BASE_ADDRESS; - break; - case 43012: - *addr = 0x18012000; - break; - case 43909: - case 43907: - case 54907: - *addr = 0x18011000; - break; - default: - return WHD_BADARG; - } - return WHD_SUCCESS; + switch (wlan_chip_id) + { + case 0x4373: + case 43430: + case 43439: + *addr = CHIPCOMMON_BASE_ADDRESS; + break; + case 43012: + case 43022: + case 55560: + case 55500: + *addr = 0x18012000; + break; + case 43909: + case 43907: + case 54907: + *addr = 0x18011000; + break; + default: + return WHD_BADARG; + } + return WHD_SUCCESS; } whd_result_t get_chip_ram_size(uint16_t wlan_chip_id, uint32_t *size) { - *size = 0; - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) || (wlan_chip_id == 43430) || - (wlan_chip_id == 43439)) { - *size = (512 * 1024); - } - else if ((wlan_chip_id == 43362) || (wlan_chip_id == 4390)) { - *size = 0x3C000; - } - else if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - *size = 0x90000; - } - else if (wlan_chip_id == 43012) { - *size = 0xA0000; - } - else if (wlan_chip_id == 0x4373) { - *size = 0xE0000; - } - else { - *size = 0x80000; - } - return WHD_SUCCESS; + *size = 0; + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) || (wlan_chip_id == 43430) || + (wlan_chip_id == 43439) ) + { + *size = (512 * 1024); + } + else if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4390) ) + { + *size = 0x3C000; + } + else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + *size = 0x90000; + } + else if ( (wlan_chip_id == 43012) || (wlan_chip_id == 43022) ) + { + *size = 0xA0000; + } + else if (wlan_chip_id == 0x4373) + { + *size = 0xE0000; + } + else if (wlan_chip_id == 55560) + { + *size = 0x150000 - 0x800 - 0x2b4; + } +#ifdef TRXV5 + else if ((wlan_chip_id == 55500) || (wlan_chip_id == 55900)) /* To be changed when CP is ROMed the ChipID is only 55900 */ + { + *size = 0xE0000 - 0x20; + } +#else + else if (wlan_chip_id == 55500) + { + *size = 0xE0000 - 0x800 - 0x2b4; + } +#endif + else + { + *size = 0x80000; + } + return WHD_SUCCESS; } whd_result_t get_atcm_ram_base_address(uint16_t wlan_chip_id, uint32_t *size) { - *size = 0; - if (wlan_chip_id == 0x4373) { - *size = 0x160000; - } - else if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - *size = 0x1B0000; - } - else { - *size = 0; - } - return WHD_SUCCESS; + *size = 0; + if (wlan_chip_id == 0x4373) + { + *size = 0x160000; + } + else if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + *size = 0x1B0000; + } + else if (wlan_chip_id == 55560) + { + *size = 0x370000 + 0x2b4 + 0x800; + } +#ifdef TRXV5 + else if ((wlan_chip_id == 55500) || (wlan_chip_id == 55900)) /* To be changed when CP is ROMed the ChipID is only 55900 */ + { + *size = 0x3a0000 + 0x20; + } +#else + else if (wlan_chip_id == 55500) + { + *size = 0x3a0000 + 0x2b4 + 0x800; + } +#endif + else + { + *size = 0; + } + return WHD_SUCCESS; } whd_result_t get_socsram_srmem_size(uint16_t wlan_chip_id, uint32_t *mem_size) { - *mem_size = 0; - if ((wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *mem_size = (32 * 1024); - } - else if ((wlan_chip_id == 43430) || (wlan_chip_id == 43439)) { - *mem_size = (64 * 1024); - } - else { - *mem_size = 0; - } - return WHD_SUCCESS; + *mem_size = 0; + if ( (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *mem_size = (32 * 1024); + } + else if ( (wlan_chip_id == 43430) || (wlan_chip_id == 43439) ) + { + *mem_size = (64 * 1024); + } + else + { + *mem_size = 0; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_band_mask(uint16_t wlan_chip_id, uint32_t *band_mask) { - *band_mask = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *band_mask = 0xf000; - } - else { - *band_mask = 0xc000; - } - return WHD_SUCCESS; + *band_mask = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *band_mask = 0xf000; + } + else + { + *band_mask = 0xc000; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_band_2G(uint16_t wlan_chip_id, uint32_t *band_2g) { - *band_2g = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *band_2g = 0x2000; - } - else { - *band_2g = 0x0000; - } - return WHD_SUCCESS; + *band_2g = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *band_2g = 0x2000; + } + else + { + *band_2g = 0x0000; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_band_5G(uint16_t wlan_chip_id, uint32_t *band_5g) { - *band_5g = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *band_5g = 0x1000; - } - else { - *band_5g = 0xc000; - } - return WHD_SUCCESS; + *band_5g = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *band_5g = 0x1000; + } + else + { + *band_5g = 0xc000; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_band_6G(uint16_t wlan_chip_id, uint32_t *band_6g) +{ + *band_6g = 0; + if ( (wlan_chip_id == 55500) || (wlan_chip_id == 55560) ) + { + *band_6g = 0x8000; + } + else + { + *band_6g = 0; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_band_shift(uint16_t wlan_chip_id, uint32_t *band_shift) { - *band_shift = 0; - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *band_shift = 12; - } - else { - *band_shift = 14; - } - return WHD_SUCCESS; + *band_shift = 0; + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *band_shift = 12; + } + else + { + *band_shift = 14; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_bw_10(uint16_t wlan_chip_id, uint32_t *bw_10) { - *bw_10 = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *bw_10 = 0x0400; - } - else { - *bw_10 = 0x0800; - } - return WHD_SUCCESS; + *bw_10 = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *bw_10 = 0x0400; + } + else + { + *bw_10 = 0x0800; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_bw_20(uint16_t wlan_chip_id, uint32_t *bw_20) { - *bw_20 = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *bw_20 = 0x0800; - } - else { - *bw_20 = 0x1000; - } - return WHD_SUCCESS; + *bw_20 = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *bw_20 = 0x0800; + } + else + { + *bw_20 = 0x1000; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_bw_40(uint16_t wlan_chip_id, uint32_t *bw_40) { - *bw_40 = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *bw_40 = 0x0C00; - } - else { - *bw_40 = 0x1800; - } - return WHD_SUCCESS; + *bw_40 = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *bw_40 = 0x0C00; + } + else + { + *bw_40 = 0x1800; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_bw_80(uint16_t wlan_chip_id, uint32_t *bw_80) +{ + *bw_80 = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *bw_80 = 0x2000; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_bw_160(uint16_t wlan_chip_id, uint32_t *bw_160) +{ + *bw_160 = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *bw_160 = 0x2800; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_bw_mask(uint16_t wlan_chip_id, uint32_t *bw_mask) { - *bw_mask = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *bw_mask = 0x0C00; - } - else { - *bw_mask = 0x3800; - } - return WHD_SUCCESS; + *bw_mask = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *bw_mask = 0x0C00; + } + else + { + *bw_mask = 0x3800; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_bw_shift(uint16_t wlan_chip_id, uint32_t *bw_shift) { - *bw_shift = 0; - if ((wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *bw_shift = 10; - } - else { - *bw_shift = 11; - } - return WHD_SUCCESS; + *bw_shift = 0; + if ( (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *bw_shift = 10; + } + else + { + *bw_shift = 11; + } + return WHD_SUCCESS; } -whd_result_t get_wl_chanspec_ctl_sb_lower(uint16_t wlan_chip_id, uint32_t *sb_lower) +whd_result_t get_wl_chanspec_ctl_sb_none(uint16_t wlan_chip_id, uint32_t *sb_none) { - *sb_lower = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *sb_lower = 0x0100; - } - else { - *sb_lower = WL_CHANSPEC_CTL_SB_LLL; - } - return WHD_SUCCESS; + *sb_none = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *sb_none = 0x0300; + } + else + { + *sb_none = WL_CHANSPEC_CTL_SB_LLL; + } + return WHD_SUCCESS; } -whd_result_t get_wl_chanspec_ctl_sb_upper(uint16_t wlan_chip_id, uint32_t *sb_upper) +whd_result_t get_wl_chanspec_ctl_sb_LLL(uint16_t wlan_chip_id, uint32_t *sb_lll) { - *sb_upper = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *sb_upper = 0x0200; - } - else { - *sb_upper = WL_CHANSPEC_CTL_SB_LLU; - } - return WHD_SUCCESS; + *sb_lll = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *sb_lll = 0x0100; + } + else + { + *sb_lll = WL_CHANSPEC_CTL_SB_LLL; + } + return WHD_SUCCESS; } -whd_result_t get_wl_chanspec_ctl_sb_none(uint16_t wlan_chip_id, uint32_t *sb_none) +whd_result_t get_wl_chanspec_ctl_sb_LLU(uint16_t wlan_chip_id, uint32_t *sb_llu) { - *sb_none = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *sb_none = 0x0300; - } - else { - *sb_none = WL_CHANSPEC_CTL_SB_LLL; - } - return WHD_SUCCESS; + *sb_llu = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *sb_llu = 0x0200; + } + else + { + *sb_llu = WL_CHANSPEC_CTL_SB_LLU; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_LUL(uint16_t wlan_chip_id, uint32_t *sb_lul) +{ + *sb_lul = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_lul = WL_CHANSPEC_CTL_SB_LUL; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_LUU(uint16_t wlan_chip_id, uint32_t *sb_luu) +{ + *sb_luu = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_luu = WL_CHANSPEC_CTL_SB_LUU; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_ULL(uint16_t wlan_chip_id, uint32_t *sb_ull) +{ + *sb_ull = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_ull = WL_CHANSPEC_CTL_SB_ULL; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_ULU(uint16_t wlan_chip_id, uint32_t *sb_ulu) +{ + *sb_ulu = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_ulu = WL_CHANSPEC_CTL_SB_ULU; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_UUL(uint16_t wlan_chip_id, uint32_t *sb_uul) +{ + *sb_uul = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_uul = WL_CHANSPEC_CTL_SB_UUL; + } + return WHD_SUCCESS; +} + +whd_result_t get_wl_chanspec_ctl_sb_UUU(uint16_t wlan_chip_id, uint32_t *sb_uuu) +{ + *sb_uuu = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + return WHD_UNSUPPORTED; + } + else + { + *sb_uuu = WL_CHANSPEC_CTL_SB_UUU; + } + return WHD_SUCCESS; } whd_result_t get_wl_chanspec_ctl_sb_mask(uint16_t wlan_chip_id, uint32_t *sb_mask) { - *sb_mask = 0; - if ((wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342)) { - *sb_mask = 0x0300; - } - else { - *sb_mask = 0x0700; - } - return WHD_SUCCESS; + *sb_mask = 0; + if ( (wlan_chip_id == 43362) || (wlan_chip_id == 4334) || (wlan_chip_id == 43340) || (wlan_chip_id == 43342) ) + { + *sb_mask = 0x0300; + } + else + { + *sb_mask = 0x0700; + } + return WHD_SUCCESS; +} + +whd_result_t get_nvram_dwnld_start_address(uint16_t wlan_chip_id, uint32_t *addr) +{ + switch (wlan_chip_id) + { + case 43022: + *addr = 0x80000; + break; + default: + return WHD_BADARG; + } + return WHD_SUCCESS; } diff --git a/wi-fi/whd/whd_chip_constants.h b/wi-fi/whd/whd_chip_constants.h index 7cc88c28..108e3cc6 100644 --- a/wi-fi/whd/whd_chip_constants.h +++ b/wi-fi/whd/whd_chip_constants.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,42 +24,77 @@ extern "C" { #endif -#define WRAPPER_REGISTER_OFFSET (0x100000) -typedef enum chip_var { - ARM_CORE_BASE_ADDRESS = 1, - SOCSRAM_BASE_ADDRESS, - SOCSRAM_WRAPPER_BASE_ADDRESS, - SDIOD_CORE_BASE_ADDRESS, - PMU_BASE_ADDRESS, - CHIP_RAM_SIZE, - ATCM_RAM_BASE_ADDRESS, - SOCRAM_SRMEM_SIZE, - CHANSPEC_BAND_MASK, - CHANSPEC_BAND_2G, - CHANSPEC_BAND_5G, - CHANSPEC_BAND_SHIFT, - CHANSPEC_BW_10, - CHANSPEC_BW_20, - CHANSPEC_BW_40, - CHANSPEC_BW_MASK, - CHANSPEC_BW_SHIFT, - CHANSPEC_CTL_SB_LOWER, - CHANSPEC_CTL_SB_UPPER, - CHANSPEC_CTL_SB_NONE, - CHANSPEC_CTL_SB_MASK +#define WRAPPER_REGISTER_OFFSET (0x100000) +typedef enum chip_var +{ + ARM_CORE_BASE_ADDRESS = 1, + SOCSRAM_BASE_ADDRESS, + SOCSRAM_WRAPPER_BASE_ADDRESS, + SDIOD_CORE_BASE_ADDRESS, + PMU_BASE_ADDRESS, + CHIP_RAM_SIZE, + ATCM_RAM_BASE_ADDRESS, + SOCRAM_SRMEM_SIZE, + CHANSPEC_BAND_MASK, + CHANSPEC_BAND_2G, + CHANSPEC_BAND_5G, + CHANSPEC_BAND_6G, + CHANSPEC_BAND_SHIFT, + CHANSPEC_BW_10, + CHANSPEC_BW_20, + CHANSPEC_BW_40, + CHANSPEC_BW_80, + CHANSPEC_BW_160, + CHANSPEC_BW_MASK, + CHANSPEC_BW_SHIFT, + CHANSPEC_CTL_SB_NONE, + CHANSPEC_CTL_SB_LLL, + CHANSPEC_CTL_SB_LLU, + CHANSPEC_CTL_SB_LUL, + CHANSPEC_CTL_SB_LUU, + CHANSPEC_CTL_SB_ULL, + CHANSPEC_CTL_SB_ULU, + CHANSPEC_CTL_SB_UUL, + CHANSPEC_CTL_SB_UUU, + CHANSPEC_CTL_SB_MASK, + NVRAM_DNLD_ADDR } chip_var_t; +#define CHANSPEC_CTL_SB_LL CHANSPEC_CTL_SB_LLL +#define CHANSPEC_CTL_SB_LU CHANSPEC_CTL_SB_LLU +#define CHANSPEC_CTL_SB_UL CHANSPEC_CTL_SB_LUL +#define CHANSPEC_CTL_SB_UU CHANSPEC_CTL_SB_LUU +#define CHANSPEC_CTL_SB_L CHANSPEC_CTL_SB_LLL +#define CHANSPEC_CTL_SB_U CHANSPEC_CTL_SB_LLU -#define VERIFY_RESULT(x) \ - { \ - whd_result_t verify_result = WHD_SUCCESS; \ - verify_result = (x); \ - if (verify_result != WHD_SUCCESS) { \ - WPRINT_WHD_ERROR(("Function %s failed at line %d \n", __func__, __LINE__)); \ - return verify_result; \ - } \ - } +#define VERIFY_RESULT(x) { whd_result_t verify_result = WHD_SUCCESS; verify_result = (x); \ + if (verify_result != WHD_SUCCESS){ \ + WPRINT_WHD_ERROR( ("Function %s failed at line %d \n", __func__, __LINE__) ); \ + return verify_result; } } #define GET_C_VAR(whd_driver, var) get_whd_var(whd_driver, var) +#define WL_CHANSPEC_CHAN_MASK (0x00ff) +#define CHSPEC_IS6G(chspec) ( (chspec & \ + GET_C_VAR(whd_driver, \ + CHANSPEC_BAND_MASK) ) == GET_C_VAR(whd_driver, CHANSPEC_BAND_6G) ) +#define CHSPEC_IS5G(chspec) ( (chspec & \ + GET_C_VAR(whd_driver, \ + CHANSPEC_BAND_MASK) ) == GET_C_VAR(whd_driver, CHANSPEC_BAND_5G) ) +#define CHSPEC_IS2G(chspec) ( (chspec & \ + GET_C_VAR(whd_driver, \ + CHANSPEC_BAND_MASK) ) == GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) ) +#define CHSPEC_CHANNEL(chspec) ( (chanspec_t)( (chspec) & WL_CHANSPEC_CHAN_MASK ) ) +#define CH20MHZ_CHSPEC(chspec) (chanspec_t)( (chanspec_t)CHSPEC_CHANNEL(chspec) | \ + GET_C_VAR(whd_driver, CHANSPEC_BW_20) | \ + GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) | \ + (((chspec)<=CH_MAX_2G_CHANNEL) ? GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) \ + :GET_C_VAR(whd_driver, CHANSPEC_BAND_5G))) +#define CH_70MHZ_APART 14 +#define CH_50MHZ_APART 10 +#define CH_30MHZ_APART 6 +#define CH_20MHZ_APART 4 +#define CH_10MHZ_APART 2 +#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ + uint32_t get_whd_var(whd_driver_t whd_driver, chip_var_t var); whd_result_t get_arm_core_base_address(uint16_t, uint32_t *); @@ -72,19 +107,30 @@ whd_result_t get_socsram_srmem_size(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_band_mask(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_band_2G(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_band_5G(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_band_6G(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_band_shift(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_bw_10(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_bw_20(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_bw_40(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_bw_80(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_bw_160(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_bw_mask(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_bw_shift(uint16_t, uint32_t *); -whd_result_t get_wl_chanspec_ctl_sb_lower(uint16_t, uint32_t *); -whd_result_t get_wl_chanspec_ctl_sb_upper(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_ctl_sb_none(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_LLL(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_LLU(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_LUL(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_LUU(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_ULL(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_ULU(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_UUL(uint16_t, uint32_t *); +whd_result_t get_wl_chanspec_ctl_sb_UUU(uint16_t, uint32_t *); whd_result_t get_wl_chanspec_ctl_sb_mask(uint16_t, uint32_t *); +whd_result_t get_nvram_dwnld_start_address(uint16_t wlan_chip_id, uint32_t *addr); uint32_t whd_chip_set_chip_id(whd_driver_t whd_driver, uint16_t id); uint16_t whd_chip_get_chip_id(whd_driver_t whd_driver); +whd_result_t whd_chip_get_chanspec_ctl_channel_num(whd_driver_t whd_driver, uint16_t chanspec, uint16_t *ctrl_ch_num); #undef CHIP_FIRMWARE_SUPPORTS_PM_LIMIT_IOVAR diff --git a/wi-fi/whd/whd_clm.c b/wi-fi/whd/whd_clm.c index db67ed5b..ec5fcd18 100644 --- a/wi-fi/whd/whd_clm.c +++ b/wi-fi/whd/whd_clm.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,16 +19,19 @@ * Provides generic clm blob file download functionality */ -#include #include "whd_clm.h" #include "whd_wlioctl.h" +#ifndef PROTO_MSGBUF #include "whd_cdc_bdc.h" +#endif /* PROTO_MSGBUF */ #include "whd_debug.h" #include "whd_int.h" #include "whd_buffer_api.h" #include "whd_resource_if.h" #include "whd_resource_api.h" #include "whd_types_int.h" +#include "whd_proto.h" +#include "whd_utils.h" /****************************************************** * @cond Constants @@ -39,107 +42,119 @@ */ static whd_result_t whd_download_wifi_clm_image(whd_interface_t ifp, const char *iovar, uint16_t flag, uint16_t dload_type, - unsigned char *dload_buf, uint32_t len) + unsigned char *dload_buf, uint32_t len) { - wl_dload_data_t *dload_ptr = (wl_dload_data_t *)dload_buf; - uint32_t dload_data_offset; - whd_buffer_t buffer; - uint8_t *iov_data; - whd_driver_t whd_driver = ifp->whd_driver; - - dload_data_offset = offsetof(wl_dload_data_t, data); - dload_ptr->flag = htod16((DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | flag); - dload_ptr->dload_type = htod16(dload_type); - dload_ptr->len = htod32(len - dload_data_offset); - - dload_ptr->crc = 0; - - whd_assert("dload buffer too large", len < 0xffffffff - 8); - len = len + 8 - (len % 8); - - iov_data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, iovar); - CHECK_IOCTL_BUFFER(iov_data); - memcpy(iov_data, (uint8_t *)dload_ptr, len); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); - return WHD_SUCCESS; + wl_dload_data_t *dload_ptr = (wl_dload_data_t *)dload_buf; + uint32_t dload_data_offset; + whd_buffer_t buffer; + uint8_t *iov_data; + whd_driver_t whd_driver = ifp->whd_driver; + + dload_data_offset = offsetof(wl_dload_data_t, data); + dload_ptr->flag = htod16( (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | flag ); + dload_ptr->dload_type = htod16(dload_type); + dload_ptr->len = htod32(len - dload_data_offset); + + dload_ptr->crc = 0; + + whd_assert("dload buffer too large", len < 0xffffffff - 8); + len = len + 8 - (len % 8); + + iov_data = (uint8_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, iovar); + CHECK_IOCTL_BUFFER(iov_data); + memcpy(iov_data, (uint8_t *)dload_ptr, len); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, NULL) ); + return WHD_SUCCESS; } whd_result_t whd_process_clm_data(whd_interface_t ifp) { - whd_result_t ret = WHD_SUCCESS; - uint32_t clm_blob_size; - uint32_t size2alloc, data_offset; - unsigned char *chunk_buf; - uint16_t dl_flag = DL_BEGIN; - uint32_t chunk_len; - uint32_t size_read; - uint8_t *image; - uint32_t blocks_count = 0; - uint16_t datalen = 0; - uint32_t i, j, num_buff; - uint32_t transfer_progress; - whd_driver_t whd_driver = ifp->whd_driver; - - /* clm file size is the initial datalen value which is decremented */ - ret = whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_CLM, &clm_blob_size); - - if (ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Fatal error: download_resource doesn't exist\n")); - return ret; - } - - ret = whd_get_resource_no_of_blocks(whd_driver, WHD_RESOURCE_WLAN_CLM, &blocks_count); - if (ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Fatal error: download_resource blocks count not know\n")); - return ret; - } - - data_offset = offsetof(wl_dload_data_t, data); - size2alloc = data_offset + BLOCK_SIZE; - - - if ((chunk_buf = (unsigned char *)malloc(size2alloc)) != NULL) { - memset(chunk_buf, 0, size2alloc); - transfer_progress = 0; - for (i = 0; i < blocks_count; i++) { - whd_get_resource_block(whd_driver, WHD_RESOURCE_WLAN_CLM, i, (const uint8_t **)&image, &size_read); - - num_buff = (size_read + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (blocks_count != 1) - transfer_progress = 0; - - for (j = 0; j < num_buff; j++) { - if (size_read >= BLOCK_SIZE) - chunk_len = BLOCK_SIZE; - else - chunk_len = size_read; - memcpy(chunk_buf + data_offset, &image[transfer_progress], chunk_len); - - if (datalen + chunk_len == clm_blob_size) { - dl_flag |= DL_END; - } - - ret = whd_download_wifi_clm_image(ifp, IOVAR_STR_CLMLOAD, dl_flag, DL_TYPE_CLM, chunk_buf, - data_offset + chunk_len); - dl_flag &= (uint16_t)~DL_BEGIN; - transfer_progress += chunk_len; - size_read = size_read - chunk_len; - datalen += chunk_len; - } - } - - free(chunk_buf); - if (ret != WHD_SUCCESS) { - whd_result_t ret_clmload_status; - whd_buffer_t buffer; - whd_buffer_t response; - void *data; + whd_result_t ret = WHD_SUCCESS; + uint32_t clm_blob_size; + uint32_t size2alloc, data_offset; + unsigned char *chunk_buf; + uint16_t dl_flag = DL_BEGIN; + uint32_t chunk_len; + uint32_t size_read; + uint8_t *image; + uint32_t blocks_count = 0; + uint16_t datalen = 0; + uint32_t i, j, num_buff; + uint32_t transfer_progress; + whd_driver_t whd_driver = ifp->whd_driver; + + /* clm file size is the initial datalen value which is decremented */ + ret = whd_resource_size(whd_driver, WHD_RESOURCE_WLAN_CLM, &clm_blob_size); + + if (ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource doesn't exist\n") ); + return ret; + } + else if (clm_blob_size == 0) + { + WPRINT_WHD_INFO( ("No loading CLM blob file\n") ); + return WHD_SUCCESS; + } + + ret = whd_get_resource_no_of_blocks(whd_driver, WHD_RESOURCE_WLAN_CLM, &blocks_count); + if (ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Fatal error: download_resource blocks count not know\n") ); + return ret; + } + + data_offset = offsetof(wl_dload_data_t, data); + size2alloc = data_offset + BLOCK_SIZE; + + + if ( (chunk_buf = (unsigned char *)whd_mem_malloc(size2alloc) ) != NULL ) + { + memset(chunk_buf, 0, size2alloc); + transfer_progress = 0; + for (i = 0; i < blocks_count; i++) + { + whd_get_resource_block(whd_driver, WHD_RESOURCE_WLAN_CLM, i, (const uint8_t **)&image, &size_read); + + num_buff = (size_read + BLOCK_SIZE - 1) / BLOCK_SIZE; + if (blocks_count != 1) + transfer_progress = 0; + + for (j = 0; j < num_buff; j++) + { + if (size_read >= BLOCK_SIZE) + chunk_len = BLOCK_SIZE; + else + chunk_len = size_read; + memcpy(chunk_buf + data_offset, &image[transfer_progress], chunk_len); + + if (datalen + chunk_len == clm_blob_size) + { + dl_flag |= DL_END; + } + + ret = whd_download_wifi_clm_image(ifp, IOVAR_STR_CLMLOAD, dl_flag, DL_TYPE_CLM, chunk_buf, + data_offset + chunk_len); + dl_flag &= (uint16_t) ~DL_BEGIN; + transfer_progress += chunk_len; + size_read = size_read - chunk_len; + datalen += chunk_len; + } + } + + whd_mem_free(chunk_buf); + if (ret != WHD_SUCCESS) + { + whd_result_t ret_clmload_status; + whd_buffer_t buffer; + whd_buffer_t response; + void *data; WPRINT_WHD_DEBUG(("clmload (%" PRIu32 " byte file) failed with return %" PRIu32 "; ", clm_blob_size, - ret)); - data = (int *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_CLMLOAD_STATUS); + ret)); + data = (int *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_CLMLOAD_STATUS); CHECK_IOCTL_BUFFER(data); - ret_clmload_status = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); + ret_clmload_status = whd_proto_get_iovar(ifp, buffer, &response); if (ret_clmload_status != WHD_SUCCESS) { WPRINT_WHD_DEBUG(("clmload_status failed with return %u\n", ret_clmload_status)); } @@ -157,5 +172,5 @@ whd_result_t whd_process_clm_data(whd_interface_t ifp) ret = WHD_MALLOC_FAILURE; } - return ret; + return ret; } diff --git a/wi-fi/whd/whd_clm.h b/wi-fi/whd/whd_clm.h index 5253b769..55f7e895 100644 --- a/wi-fi/whd/whd_clm.h +++ b/wi-fi/whd/whd_clm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/wi-fi/whd/whd_commonring.c b/wi-fi/whd/whd_commonring.c new file mode 100644 index 00000000..cfe9ac5f --- /dev/null +++ b/wi-fi/whd/whd_commonring.c @@ -0,0 +1,259 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * Provides generic COMMON RING functionality that chip specific files use + */ +#ifdef PROTO_MSGBUF + +#include "whd_debug.h" +#include "whd_commonring.h" +#include "whd_types_int.h" + +void whd_commonring_register_cb(struct whd_commonring *commonring, + int (*cr_ring_bell)(void *ctx), + int (*cr_update_rptr)(void *ctx), + int (*cr_update_wptr)(void *ctx), + int (*cr_write_rptr)(void *ctx), + int (*cr_write_wptr)(void *ctx), void *ctx) +{ + commonring->cr_ring_bell = cr_ring_bell; + commonring->cr_update_rptr = cr_update_rptr; + commonring->cr_update_wptr = cr_update_wptr; + commonring->cr_write_rptr = cr_write_rptr; + commonring->cr_write_wptr = cr_write_wptr; + commonring->cr_ctx = ctx; +} + +whd_result_t whd_commonring_config(struct whd_commonring *commonring, uint16_t depth, + uint16_t item_len, void *buf_addr) +{ + commonring->depth = depth; + commonring->item_len = item_len; + commonring->buf_addr = buf_addr; + if (!commonring->inited) + { + (void)cy_rtos_init_semaphore(&commonring->lock, 1, 0); + CHECK_RETURN(cy_rtos_set_semaphore(&commonring->lock, WHD_FALSE)); + commonring->inited = true; + } + commonring->r_ptr = 0; + if (commonring->cr_write_rptr) + commonring->cr_write_rptr(commonring->cr_ctx); + commonring->w_ptr = 0; + if (commonring->cr_write_wptr) + commonring->cr_write_wptr(commonring->cr_ctx); + commonring->f_ptr = 0; + + return 0; +} + +whd_result_t whd_commonring_lock(struct whd_commonring *commonring) +{ + uint32_t result; + result = cy_rtos_get_semaphore(&commonring->lock, (uint32_t)10000, + WHD_FALSE); + return result; +} + +void whd_commonring_unlock(struct whd_commonring *commonring) +{ + uint32_t result; + result = cy_rtos_set_semaphore(&commonring->lock, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); +} + +bool whd_commonring_write_available(struct whd_commonring *commonring) +{ + uint16_t available; + uint8_t retry = 1; + +again: + if (commonring->r_ptr <= commonring->w_ptr) + available = commonring->depth - commonring->w_ptr + + commonring->r_ptr; + else + available = commonring->r_ptr - commonring->w_ptr; + + if (available > 1) + { + if (!commonring->was_full) + return true; + if (available > commonring->depth / 8) + { + commonring->was_full = false; + return true; + } + if (retry) + { + if (commonring->cr_update_rptr) + commonring->cr_update_rptr(commonring->cr_ctx); + retry = false; + goto again; + } + return false; + } + + if (retry) + { + if (commonring->cr_update_rptr) + commonring->cr_update_rptr(commonring->cr_ctx); + retry = false; + goto again; + } + + commonring->was_full = true; + return false; +} + +void *whd_commonring_reserve_for_write(struct whd_commonring *commonring) +{ + void *ret_ptr; + uint16_t available; + uint8_t retry = true; + +again: + if (commonring->r_ptr <= commonring->w_ptr) + available = commonring->depth - commonring->w_ptr + + commonring->r_ptr; + else + available = commonring->r_ptr - commonring->w_ptr; + + WPRINT_WHD_DEBUG( ("Write Availability for the Ring - %d \n", available) ); + + if (available > 1) + { + WPRINT_WHD_DEBUG( ("%s: available more than 1 buf_addr - 0x%lx, w_ptr - 0x%x, item_len - 0x%x \n", __func__, + (uint32_t)commonring->buf_addr, commonring->w_ptr, commonring->item_len) ); + ret_ptr = (uint8_t *)commonring->buf_addr + + (commonring->w_ptr * commonring->item_len); + commonring->w_ptr++; + if (commonring->w_ptr == commonring->depth) + commonring->w_ptr = 0; + return ret_ptr; + } + + if (retry) + { + if (commonring->cr_update_rptr) + commonring->cr_update_rptr(commonring->cr_ctx); + retry = false; + goto again; + } + + commonring->was_full = true; + WPRINT_WHD_DEBUG( ("Error: CommonRing was Full!!! \n") ); + + return NULL; +} + +void * +whd_commonring_reserve_for_write_multiple(struct whd_commonring *commonring, + uint16_t n_items, uint16_t *allocated) +{ + void *ret_ptr; + uint16_t available; + uint8_t retry = true; + +again: + if (commonring->r_ptr <= commonring->w_ptr) + available = commonring->depth - commonring->w_ptr + + commonring->r_ptr; + else + available = commonring->r_ptr - commonring->w_ptr; + + if (available > 1) { + ret_ptr = (uint8_t *)commonring->buf_addr + + (commonring->w_ptr * commonring->item_len); + *allocated = MIN(n_items, available - 1); + if (*allocated + commonring->w_ptr > commonring->depth) + *allocated = commonring->depth - commonring->w_ptr; + commonring->w_ptr += *allocated; + if (commonring->w_ptr == commonring->depth) + commonring->w_ptr = 0; + return ret_ptr; + } + + if (retry) + { + if (commonring->cr_update_rptr) + commonring->cr_update_rptr(commonring->cr_ctx); + retry = false; + goto again; + } + + commonring->was_full = true; + return NULL; +} + +int whd_commonring_write_complete(struct whd_commonring *commonring) +{ + if (commonring->f_ptr > commonring->w_ptr) + commonring->f_ptr = 0; + + commonring->f_ptr = commonring->w_ptr; + + if (commonring->cr_write_wptr) + commonring->cr_write_wptr(commonring->cr_ctx); + if (commonring->cr_ring_bell) + return commonring->cr_ring_bell(commonring->cr_ctx); + + return -1; +} + +void whd_commonring_write_cancel(struct whd_commonring *commonring, + uint16_t n_items) +{ + if (commonring->w_ptr == 0) + commonring->w_ptr = commonring->depth - n_items; + else + commonring->w_ptr -= n_items; +} + +void *whd_commonring_get_read_ptr(struct whd_commonring *commonring, + uint16_t *n_items) +{ + if (commonring->cr_update_wptr) + commonring->cr_update_wptr(commonring->cr_ctx); + + *n_items = (commonring->w_ptr >= commonring->r_ptr) ? + (commonring->w_ptr - commonring->r_ptr) : + (commonring->depth - commonring->r_ptr); + + if (*n_items == 0) + return NULL; + + return (uint8_t *)commonring->buf_addr + + (commonring->r_ptr * commonring->item_len); +} + +int whd_commonring_read_complete(struct whd_commonring *commonring, + uint16_t n_items) +{ + commonring->r_ptr += n_items; + + if (commonring->r_ptr == commonring->depth) + commonring->r_ptr = 0; + + if (commonring->cr_write_rptr) + return commonring->cr_write_rptr(commonring->cr_ctx); + + return -1; +} + +#endif /* PROTO_MSGBUF */ diff --git a/wi-fi/whd/whd_commonring.h b/wi-fi/whd/whd_commonring.h new file mode 100644 index 00000000..4320f171 --- /dev/null +++ b/wi-fi/whd/whd_commonring.h @@ -0,0 +1,92 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_COMMONRING_H +#define INCLUDED_WHD_COMMONRING_H + +#include "cyabs_rtos.h" +#include "whd_debug.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef MIN +#define MIN(x, y) ( (x) < (y) ? (x) : (y) ) +#endif /* MIN */ + +#ifndef MAX +#define MAX(x, y) ( (x) > (y) ? (x) : (y) ) +#endif /* MAX */ + +struct whd_commonring +{ + uint16_t r_ptr; + uint16_t w_ptr; + uint16_t f_ptr; + uint16_t depth; + uint16_t item_len; + + void *buf_addr; + + int (*cr_ring_bell)(void *ctx); + int (*cr_update_rptr)(void *ctx); + int (*cr_update_wptr)(void *ctx); + int (*cr_write_rptr)(void *ctx); + int (*cr_write_wptr)(void *ctx); + + void *cr_ctx; + + cy_semaphore_t lock; + //unsigned long flags; + uint8_t inited; + uint8_t was_full; + + //atomic_t outstanding_tx; +}; + +void whd_commonring_register_cb(struct whd_commonring *commonring, + int (*cr_ring_bell)(void *ctx), + int (*cr_update_rptr)(void *ctx), + int (*cr_update_wptr)(void *ctx), + int (*cr_write_rptr)(void *ctx), + int (*cr_write_wptr)(void *ctx), void *ctx); +whd_result_t whd_commonring_config(struct whd_commonring *commonring, uint16_t depth, + uint16_t item_len, void *buf_addr); +whd_result_t whd_commonring_lock(struct whd_commonring *commonring); +void whd_commonring_unlock(struct whd_commonring *commonring); +bool whd_commonring_write_available(struct whd_commonring *commonring); +void *whd_commonring_reserve_for_write(struct whd_commonring *commonring); +void *whd_commonring_reserve_for_write_multiple(struct whd_commonring *commonring, + uint16_t n_items, uint16_t *allocated); +int whd_commonring_write_complete(struct whd_commonring *commonring); +void whd_commonring_write_cancel(struct whd_commonring *commonring, + uint16_t n_items); +void *whd_commonring_get_read_ptr(struct whd_commonring *commonring, + uint16_t *n_items); +int whd_commonring_read_complete(struct whd_commonring *commonring, + uint16_t n_items); + +#define whd_commonring_n_items(commonring) (commonring->depth) +#define whd_commonring_len_item(commonring) (commonring->item_len) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* INCLUDED_WHD_COMMONRING_H */ diff --git a/wi-fi/whd/whd_debug.c b/wi-fi/whd/whd_debug.c index 33d5c0fc..1ae502ee 100644 --- a/wi-fi/whd/whd_debug.c +++ b/wi-fi/whd/whd_debug.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,25 +36,26 @@ ******************************************************/ void whd_init_stats(whd_driver_t whd_driver) { - memset(&whd_driver->whd_stats, 0, sizeof(whd_driver->whd_stats)); + memset(&whd_driver->whd_stats, 0, sizeof(whd_driver->whd_stats) ); } -uint32_t whd_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) +whd_result_t whd_print_stats(whd_driver_t whd_driver, whd_bool_t reset_after_print) { - CHECK_DRIVER_NULL(whd_driver); - - WPRINT_MACRO(("WHD Stats.. \n" - "tx_total:%" PRIu32 ", rx_total:%" PRIu32 ", tx_no_mem:%" PRIu32 ", rx_no_mem:%" PRIu32 "\n" - "tx_fail:%" PRIu32 ", no_credit:%" PRIu32 ", flow_control:%" PRIu32 "\n", - whd_driver->whd_stats.tx_total, whd_driver->whd_stats.rx_total, - whd_driver->whd_stats.tx_no_mem, whd_driver->whd_stats.rx_no_mem, - whd_driver->whd_stats.tx_fail, whd_driver->whd_stats.no_credit, - whd_driver->whd_stats.flow_control)); - - if (reset_after_print == WHD_TRUE) { - memset(&whd_driver->whd_stats, 0, sizeof(whd_driver->whd_stats)); - } - - CHECK_RETURN(whd_bus_print_stats(whd_driver, reset_after_print)); - return WHD_SUCCESS; + CHECK_DRIVER_NULL(whd_driver); + + WPRINT_INFO(("WHD Stats.. \n" + "tx_total:%" PRIu32 ", rx_total:%" PRIu32 ", tx_no_mem:%" PRIu32 ", rx_no_mem:%" PRIu32 "\n" + "tx_fail:%" PRIu32 ", no_credit:%" PRIu32 ", flow_control:%" PRIu32 "\n", + whd_driver->whd_stats.tx_total, whd_driver->whd_stats.rx_total, + whd_driver->whd_stats.tx_no_mem, whd_driver->whd_stats.rx_no_mem, + whd_driver->whd_stats.tx_fail, whd_driver->whd_stats.no_credit, + whd_driver->whd_stats.flow_control)); + + if (reset_after_print == WHD_TRUE) + { + memset(&whd_driver->whd_stats, 0, sizeof(whd_driver->whd_stats) ); + } + + CHECK_RETURN(whd_bus_print_stats(whd_driver, reset_after_print) ); + return WHD_SUCCESS; } diff --git a/wi-fi/whd/whd_debug.h b/wi-fi/whd/whd_debug.h index 0c873caf..7c5f91ee 100644 --- a/wi-fi/whd/whd_debug.h +++ b/wi-fi/whd/whd_debug.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,17 +15,18 @@ * limitations under the License. */ -#include +#ifndef INCLUDED_WHD_DEBUG_H +#define INCLUDED_WHD_DEBUG_H + #include #include -#include "whd.h" -#include "cy_log.h" -#ifndef INCLUDED_WHD_DEBUG_H -#define INCLUDED_WHD_DEBUG_H +#include "cy_log.h" +#include "whd.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -41,23 +42,20 @@ extern "C" { #if defined(__GNUC__) #define WHD_TRIGGER_BREAKPOINT() \ do { \ - __asm__("bkpt"); \ + __asm__ volatile("bkpt"); \ } while (0) -#elif defined(__IAR_SYSTEMS_ICC__) -#define WHD_TRIGGER_BREAKPOINT() \ - do { \ - __asm("bkpt 0"); \ - } while (0) +#elif defined (__IAR_SYSTEMS_ICC__) +#define WHD_TRIGGER_BREAKPOINT( ) do { __asm("bkpt 0"); } while (0) #else -#define WHD_TRIGGER_BREAKPOINT() +#define WHD_TRIGGER_BREAKPOINT( ) #endif #ifdef WPRINT_ENABLE_ERROR #define WPRINT_ERROR(args) \ do { \ - WPRINT_MACRO(args); \ + WPRINT_ERROR(args); \ } while (0) #define whd_assert(error_string, assertion) \ do { \ @@ -66,17 +64,17 @@ extern "C" { } \ } while (0) #define whd_minor_assert(error_string, \ - assertion) \ + assertion) \ do { \ if (!(assertion)) \ - WPRINT_MACRO((error_string)); \ + WPRINT_ERROR((error_string)); \ } while (0) #else #define whd_assert(error_string, \ - assertion) \ + assertion) \ do { \ if (!(assertion)) { \ - WPRINT_MACRO((error_string)); \ + WPRINT_ERROR((error_string)); \ } \ } while (0) #define whd_minor_assert(error_string, assertion) \ @@ -96,39 +94,33 @@ extern "C" { #define WPRINT_MACRO(args) #else #if defined(WHD_LOGGING_BUFFER_ENABLE) -#define WPRINT_MACRO(args) \ - do { \ - whd_buffer_printf args; \ - } while (0 == 1) +#define WPRINT_MACRO(args) do { whd_buffer_printf args; } while (0 == 1) #else #define WLOG_INFO(fmt, ...) \ do { \ cy_log_msg(CYLF_DEF, CY_LOG_INFO, fmt, ##__VA_ARGS__); \ - } while (0 == 1) + } while (0) #define WLOG_DEBUG(fmt, ...) \ do { \ cy_log_msg(CYLF_DEF, CY_LOG_DEBUG, fmt, ##__VA_ARGS__); \ - } while (0 == 1) + } while (0) #define WLOG_ERROR(fmt, ...) \ do { \ cy_log_msg(CYLF_DEF, CY_LOG_ERR, fmt, ##__VA_ARGS__); \ - } while (0 == 1) + } while (0) + #define WPRINT_INFO(args) \ do { \ WLOG_INFO args; \ - } while (0 == 1) + } while (0) #define WPRINT_DEBUG(args) \ do { \ WLOG_DEBUG args; \ - } while (0 == 1) + } while (0) #define WPRINT_ERROR(args) \ do { \ WLOG_ERROR args; \ - } while (0 == 1) -#define WPRINT_MACRO(args) \ - do { \ - WLOG_INFO args; \ - } while (0 == 1) + } while (0) #endif #endif @@ -153,24 +145,18 @@ extern "C" { #endif #ifdef WPRINT_ENABLE_WHD_DATA_LOG -#define WPRINT_WHD_DATA_LOG(args) WPRINT_MACRO(args) +#define WPRINT_WHD_DATA_LOG(args) WPRINT_INFO(args) #else #define WPRINT_WHD_DATA_LOG(args) #endif #define WHD_STATS_INCREMENT_VARIABLE(whd_driver, var) \ - do { \ - whd_driver->whd_stats.var++; \ - } while (0) + do { whd_driver->whd_stats.var++; } while (0) #define WHD_STATS_CONDITIONAL_INCREMENT_VARIABLE(whd_driver, condition, var) \ - do { \ - if (condition) { \ - whd_driver->whd_stats.var++; \ - } \ - } while (0) + do { if (condition){ whd_driver->whd_stats.var++; }} while (0) -#if (defined(__GNUC__) && (__GNUC__ >= 6)) +#if (defined(__GNUC__) && (__GNUC__ >= 6) ) #define __FUNCTION__ __func__ #endif @@ -185,20 +171,20 @@ int whd_buffer_printf(const char *format, ...); typedef struct { - uint32_t buffer_write; - uint32_t buffer_read; - char buffer[LOGGING_BUFFER_SIZE + 1]; - whd_bool_t roll_over; - whd_bool_t over_write; + uint32_t buffer_write; + uint32_t buffer_read; + char buffer[LOGGING_BUFFER_SIZE + 1]; + whd_bool_t roll_over; + whd_bool_t over_write; } whd_logging_t; #else #define whd_print_logbuffer() #endif /* WHD_LOGGING_BUFFER_ENABLE */ #ifdef WHD_IOCTL_LOG_ENABLE -#define WHD_IOCTL_LOG_ADD(x, y, z) whd_ioctl_log_add(x, y, z) +#define WHD_IOCTL_LOG_ADD(x, y, z) whd_ioctl_log_add(x, y, z) #define WHD_IOCTL_LOG_ADD_EVENT(w, x, y, z) whd_ioctl_log_add_event(w, x, y, z) -#define WHD_IOCTL_PRINT(x) whd_ioctl_print(x) +#define WHD_IOCTL_PRINT(x) whd_ioctl_print(x) #else #define WHD_IOCTL_LOG_ADD(x, y, z) #define WHD_IOCTL_LOG_ADD_EVENT(w, x, y, z) diff --git a/wi-fi/whd/whd_endian.h b/wi-fi/whd/whd_endian.h index 893722ad..ca1f7293 100644 --- a/wi-fi/whd/whd_endian.h +++ b/wi-fi/whd/whd_endian.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,20 +25,21 @@ #define INCLUDED_WHD_ENDIAN_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Reverse the bytes in a 16-bit value */ #define SWAP16(val) \ - ((uint16_t)((((uint16_t)(val) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(val) & (uint16_t)0xff00U) >> 8))) + ( (uint16_t)( ( ( (uint16_t)(val) & (uint16_t)0x00ffU ) << 8 ) | \ + ( ( (uint16_t)(val) & (uint16_t)0xff00U ) >> 8 ) ) ) /* Reverse the bytes in a 32-bit value */ #define SWAP32(val) \ - ((uint32_t)((((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \ - (((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \ - (((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \ - (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24))) + ( (uint32_t)( ( ( (uint32_t)(val) & (uint32_t)0x000000ffU ) << 24 ) | \ + ( ( (uint32_t)(val) & (uint32_t)0x0000ff00U ) << 8 ) | \ + ( ( (uint32_t)(val) & (uint32_t)0x00ff0000U ) >> 8 ) | \ + ( ( (uint32_t)(val) & (uint32_t)0xff000000U ) >> 24 ) ) ) #ifdef IL_BIGENDIAN #define htod32(i) SWAP32(i) diff --git a/wi-fi/whd/whd_events.c b/wi-fi/whd/whd_events.c index 23da1a6b..96a98b14 100644 --- a/wi-fi/whd/whd_events.c +++ b/wi-fi/whd/whd_events.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,6 @@ */ #include "whd_int.h" -#include "whd_cdc_bdc.h" #include "whd_events_int.h" #include "cyabs_rtos.h" #include "whd_network_types.h" @@ -24,6 +23,8 @@ #include "whd_wlioctl.h" #include "whd_thread_internal.h" #include "whd_buffer_api.h" +#include "whd_proto.h" +#include "whd_utils.h" /****************************************************** * Constants @@ -31,16 +32,16 @@ /****************************************************** * Macros ******************************************************/ -/* bit map related macros */ -#define NBBY 8 /* 8 bits per byte */ -#define setbit(a, i) (((uint8_t *)a)[(int)(i) / (int)(NBBY)] |= (uint8_t)(1 << ((i) % NBBY))) -#define clrbit(a, i) (((uint8_t *)a)[(int)(i) / (int)(NBBY)] &= (uint8_t) ~(1 << ((i) % NBBY))) -#define isset(a, i) (((const uint8_t *)a)[(int)(i) / (int)(NBBY)] & (1 << ((i) % NBBY))) -#define isclr(a, i) ((((const uint8_t *)a)[(int)(i) / (int)(NBBY)] & (1 << ((i) % NBBY))) == 0) /****************************************************** * Local Structures ******************************************************/ +typedef struct whd_event_info +{ + /* Event list variables */ + event_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; + cy_semaphore_t event_list_mutex; +} whd_event_info_t; /****************************************************** * Static Variables @@ -59,16 +60,17 @@ static uint8_t whd_find_number_of_events(const whd_event_num_t *event_nums); static uint8_t whd_find_number_of_events(const whd_event_num_t *event_nums) { - uint8_t count = 0; + uint8_t count = 0; - while (*event_nums != WLC_E_NONE) { - count++; - event_nums++; + while (*event_nums != WLC_E_NONE) + { + count++; + event_nums++; - if (count >= WHD_MAX_EVENT_SUBSCRIPTION) - return 0; - } - return count + 1; + if (count >= WHD_MAX_EVENT_SUBSCRIPTION) + return 0; + } + return count + 1; } /** @@ -96,64 +98,72 @@ static uint8_t whd_find_number_of_events(const whd_event_num_t *event_nums) * @return WHD result code */ whd_result_t whd_management_set_event_handler_locally(whd_interface_t ifp, const whd_event_num_t *event_nums, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index) + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index) { - uint16_t entry = (uint16_t)0xFF; - uint16_t i; - whd_driver_t whd_driver = ifp->whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - uint8_t num_of_events; - num_of_events = whd_find_number_of_events(event_nums); - - if (num_of_events <= 1) { - WPRINT_WHD_ERROR(("Exceeded the maximum event subscription/no event subscribed\n")); - return WHD_UNFINISHED; - } - - /* Find an existing matching entry OR the next empty entry */ - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - /* Find a matching event list OR the first empty event entry */ - if (!(memcmp(cdc_bdc_info->whd_event_list[i].events, event_nums, - num_of_events * (sizeof(whd_event_num_t))))) { - /* Check if all the data already matches */ - if ((cdc_bdc_info->whd_event_list[i].handler == handler_func) && - (cdc_bdc_info->whd_event_list[i].handler_user_data == handler_user_data) && - (cdc_bdc_info->whd_event_list[i].ifidx == ifp->ifidx)) { - /* send back the entry where the handler is added */ - *event_index = i; - return WHD_SUCCESS; - } - } - else if ((entry == (uint16_t)0xFF) && (cdc_bdc_info->whd_event_list[i].event_set == WHD_FALSE)) { - entry = i; - } - } - - /* Check if handler function was provided */ - if (handler_func != NULL) { - /* Check if an empty entry was not found */ - if (entry == (uint16_t)0xFF) { - WPRINT_WHD_DEBUG(("Out of space in event handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n")); - return WHD_OUT_OF_EVENT_HANDLER_SPACE; - } - - /* Add the new handler in at the free space */ - memcpy(cdc_bdc_info->whd_event_list[entry].events, event_nums, num_of_events * (sizeof(whd_event_num_t))); - cdc_bdc_info->whd_event_list[entry].handler = handler_func; - cdc_bdc_info->whd_event_list[entry].handler_user_data = handler_user_data; - cdc_bdc_info->whd_event_list[entry].ifidx = ifp->ifidx; - cdc_bdc_info->whd_event_list[entry].event_set = WHD_TRUE; - - /* send back the entry where the handler is added */ - *event_index = entry; - } - else { - WPRINT_WHD_ERROR(("Event handler callback function is NULL/not provided to register\n")); - return WHD_BADARG; - } - - return WHD_SUCCESS; + uint16_t entry = (uint16_t)0xFF; + uint16_t i; + whd_driver_t whd_driver = ifp->whd_driver; + uint8_t num_of_events; + num_of_events = whd_find_number_of_events(event_nums); + whd_event_info_t *event_info = (whd_event_info_t *)whd_driver->proto->pd; + + if (num_of_events <= 1) + { + WPRINT_WHD_ERROR( ("Exceeded the maximum event subscription/no event subscribed\n") ); + return WHD_UNFINISHED; + } + + /* Find an existing matching entry OR the next empty entry */ + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + /* Find a matching event list OR the first empty event entry */ + if (!(memcmp(event_info->whd_event_list[i].events, event_nums, + num_of_events * (sizeof(whd_event_num_t) ) ) ) ) + { + /* Check if all the data already matches */ + if ( (event_info->whd_event_list[i].handler == handler_func) && + (event_info->whd_event_list[i].handler_user_data == handler_user_data) && + (event_info->whd_event_list[i].ifidx == ifp->ifidx) ) + { + /* send back the entry where the handler is added */ + *event_index = i; + return WHD_SUCCESS; + } + } + else if ( (entry == (uint16_t)0xFF) && (event_info->whd_event_list[i].event_set == WHD_FALSE) ) + { + entry = i; + } + } + + /* Check if handler function was provided */ + if (handler_func != NULL) + { + /* Check if an empty entry was not found */ + if (entry == (uint16_t)0xFF) + { + WPRINT_WHD_DEBUG( ("Out of space in event handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n") ); + return WHD_OUT_OF_EVENT_HANDLER_SPACE; + } + + /* Add the new handler in at the free space */ + memcpy (event_info->whd_event_list[entry].events, event_nums, num_of_events * (sizeof(whd_event_num_t) ) ); + event_info->whd_event_list[entry].handler = handler_func; + event_info->whd_event_list[entry].handler_user_data = handler_user_data; + event_info->whd_event_list[entry].ifidx = ifp->ifidx; + event_info->whd_event_list[entry].event_set = WHD_TRUE; + + /* send back the entry where the handler is added */ + *event_index = entry; + } + else + { + WPRINT_WHD_ERROR( ("Event handler callback function is NULL/not provided to register\n") ); + return WHD_BADARG; + } + + return WHD_SUCCESS; } /* Registers locally a handler to receive error callbacks. @@ -179,122 +189,139 @@ whd_result_t whd_management_set_event_handler_locally(whd_interface_t ifp, const * @return WHD result code */ whd_result_t whd_set_error_handler_locally(whd_driver_t whd_driver, const uint8_t *error_nums, - whd_error_handler_t handler_func, - void *handler_user_data, uint16_t *error_index) + whd_error_handler_t handler_func, + void *handler_user_data, uint16_t *error_index) { - uint16_t entry = (uint16_t)0xFF; - uint16_t i; - whd_result_t res; - whd_error_info_t *error_info = &whd_driver->error_info; - - - /* Find an existing matching entry OR the next empty entry */ - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - uint8_t events = error_info->whd_event_list[i].events; - /* Find a matching event list OR the first empty event entry */ - if (events & *error_nums) { - /* Check if all the data already matches */ - if (error_info->whd_event_list[i].handler != NULL) { - handler_func = error_info->whd_event_list[i].handler; - handler_user_data = error_info->whd_event_list[i].handler_user_data; - res = cy_rtos_get_semaphore(&error_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - if (res != WHD_SUCCESS) { - return res; - } - handler_func(whd_driver, error_nums, NULL, handler_user_data); - CHECK_RETURN(cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE)); - return WHD_SUCCESS; - } - } - else if ((entry == (uint16_t)0xFF) && (error_info->whd_event_list[i].event_set == WHD_FALSE)) { - entry = i; - } - } - /* Check if handler function was provided */ - if (handler_func != NULL) { - /* Check if an empty entry was not found */ - if (entry == (uint16_t)0xFF) { - WPRINT_WHD_DEBUG(("Out of space in error handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n")); - return WHD_OUT_OF_EVENT_HANDLER_SPACE; - } - /* Add the new handler in at the free space */ - error_info->whd_event_list[entry].events = *error_nums; - error_info->whd_event_list[entry].handler = handler_func; - error_info->whd_event_list[entry].handler_user_data = handler_user_data; - error_info->whd_event_list[entry].event_set = WHD_TRUE; - /* send back the entry where the handler is added */ - *error_index = entry; - } - else { - WPRINT_WHD_ERROR(("Error handler callback function is NULL/not provided to register\n")); - return WHD_BADARG; - } - - return WHD_SUCCESS; + uint16_t entry = (uint16_t)0xFF; + uint16_t i; + whd_result_t res; + whd_error_info_t *error_info = &whd_driver->error_info; + + + /* Find an existing matching entry OR the next empty entry */ + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + uint8_t events = error_info->whd_event_list[i].events; + /* Find a matching event list OR the first empty event entry */ + if (events & *error_nums) + { + /* Check if all the data already matches */ + if (error_info->whd_event_list[i].handler != NULL) + { + handler_func = error_info->whd_event_list[i].handler; + handler_user_data = error_info->whd_event_list[i].handler_user_data; + res = cy_rtos_get_semaphore(&error_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (res != WHD_SUCCESS) + { + return res; + } + handler_func(whd_driver, error_nums, NULL, handler_user_data); + CHECK_RETURN(cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE) ); + return WHD_SUCCESS; + } + } + else if ( (entry == (uint16_t)0xFF) && (error_info->whd_event_list[i].event_set == WHD_FALSE) ) + { + entry = i; + } + } + /* Check if handler function was provided */ + if (handler_func != NULL) + { + /* Check if an empty entry was not found */ + if (entry == (uint16_t)0xFF) + { + WPRINT_WHD_DEBUG( ("Out of space in error handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n") ); + return WHD_OUT_OF_EVENT_HANDLER_SPACE; + } + /* Add the new handler in at the free space */ + error_info->whd_event_list[entry].events = *error_nums; + error_info->whd_event_list[entry].handler = handler_func; + error_info->whd_event_list[entry].handler_user_data = handler_user_data; + error_info->whd_event_list[entry].event_set = WHD_TRUE; + /* send back the entry where the handler is added */ + *error_index = entry; + } + else + { + WPRINT_WHD_ERROR( ("Error handler callback function is NULL/not provided to register\n") ); + return WHD_BADARG; + } + + return WHD_SUCCESS; } /* allocates memory for the needed iovar and returns a pointer to the event mask */ static uint8_t *whd_management_alloc_event_msgs_buffer(whd_interface_t ifp, whd_buffer_t *buffer) { - uint16_t i; - uint16_t j; - whd_bool_t use_extended_evt = WHD_FALSE; - uint32_t max_event = 0; - eventmsgs_ext_t *eventmsgs_ext_data = NULL; - uint32_t *data = NULL; - whd_driver_t whd_driver = ifp->whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info; - - /* Check to see if event that's set requires more than 128 bit */ - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - if (cdc_bdc_info->whd_event_list[i].event_set) { - for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) { - uint32_t event_value = cdc_bdc_info->whd_event_list[i].events[j]; - if (event_value > 127) { - use_extended_evt = WHD_TRUE; - if (event_value > max_event) { - max_event = event_value; - } - /* keep going to get highest value */ - } - } - } - } - - if (WHD_FALSE == use_extended_evt) { - /* use old iovar for backwards compat */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, buffer, (uint16_t)WL_EVENTING_MASK_LEN + 4, - "bsscfg:" IOVAR_STR_EVENT_MSGS); - - if (NULL == data) { - return NULL; - } - - data[0] = ifp->bsscfgidx; - - return (uint8_t *)&data[1]; - } - else { - uint8_t mask_len = (uint8_t)((max_event + 8) / 8); - data = - (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, buffer, - (uint16_t)(sizeof(eventmsgs_ext_t) + mask_len + 4), - "bsscfg:" IOVAR_STR_EVENT_MSGS_EXT); - - if (NULL == data) { - return NULL; - } - - data[0] = ifp->bsscfgidx; - - eventmsgs_ext_data = (eventmsgs_ext_t *)&data[1]; - - memset(eventmsgs_ext_data, 0, sizeof(*eventmsgs_ext_data)); - eventmsgs_ext_data->ver = EVENTMSGS_VER; - eventmsgs_ext_data->command = EVENTMSGS_SET_MASK; - eventmsgs_ext_data->len = mask_len; - return eventmsgs_ext_data->mask; - } + uint16_t i; + uint16_t j; + whd_bool_t use_extended_evt = WHD_FALSE; + uint32_t max_event = 0; + eventmsgs_ext_t *eventmsgs_ext_data = NULL; + uint32_t *data = NULL; + whd_driver_t whd_driver = ifp->whd_driver; + whd_event_info_t *event_info = (whd_event_info_t *)whd_driver->proto->pd; + + /* Check to see if event that's set requires more than 128 bit */ + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + if (event_info->whd_event_list[i].event_set) + { + for (j = 0; event_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) + { + uint32_t event_value = event_info->whd_event_list[i].events[j]; + if (event_value > 127) + { + use_extended_evt = WHD_TRUE; + if (event_value > max_event) + { + max_event = event_value; + } + /* keep going to get highest value */ + } + } + } + } + + if (WHD_FALSE == use_extended_evt) + { + /* use old iovar for backwards compat */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, buffer, (uint16_t)WL_EVENTING_MASK_LEN + 4, + "bsscfg:" IOVAR_STR_EVENT_MSGS); + + if (NULL == data) + { + return NULL; + } + + data[0] = ifp->bsscfgidx; + + return (uint8_t *)&data[1]; + } + else + { + uint8_t mask_len = (uint8_t)( (max_event + 8) / 8 ); + data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, buffer, + (uint16_t)(sizeof(eventmsgs_ext_t) + mask_len + 4), + "bsscfg:" IOVAR_STR_EVENT_MSGS_EXT); + + if (NULL == data) + { + return NULL; + } + + data[0] = ifp->bsscfgidx; + + eventmsgs_ext_data = (eventmsgs_ext_t *)&data[1]; + + memset(eventmsgs_ext_data, 0, sizeof(*eventmsgs_ext_data) ); + eventmsgs_ext_data->ver = EVENTMSGS_VER; + eventmsgs_ext_data->command = EVENTMSGS_SET_MASK; + eventmsgs_ext_data->len = mask_len; + return eventmsgs_ext_data->mask; + } } /** @@ -319,168 +346,193 @@ static uint8_t *whd_management_alloc_event_msgs_buffer(whd_interface_t ifp, whd_ * @return WHD result code */ whd_result_t whd_management_set_event_handler(whd_interface_t ifp, const whd_event_num_t *event_nums, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index) + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index) { - whd_buffer_t buffer; - uint8_t *event_mask; - uint16_t i; - uint16_t j; - whd_result_t res; - whd_driver_t whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info; - whd_interface_t prim_ifp; - - if (ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - if (!event_nums || !event_index) { - WPRINT_WHD_ERROR(("Event list to be registered is NULL/Event index is NULL")); - return WHD_BADARG; - } - - whd_driver = ifp->whd_driver; - cdc_bdc_info = &whd_driver->cdc_bdc_info; - prim_ifp = whd_get_primary_interface(whd_driver); - - if (prim_ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - /* Acquire mutex preventing multiple threads accessing the handler at the same time */ - res = cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - if (res != WHD_SUCCESS) { - return res; - } - - /* Set event handler locally */ - res = whd_management_set_event_handler_locally(ifp, event_nums, handler_func, handler_user_data, event_index); - if (res != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__)); - goto set_event_handler_exit; - } - - /* Send the new event mask value to the wifi chip */ - event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer); - - if (NULL == event_mask) { - res = WHD_BUFFER_UNAVAILABLE_PERMANENT; - WPRINT_WHD_ERROR(("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__)); - goto set_event_handler_exit; - } - - /* Keep the wlan awake while we set the event_msgs */ - WHD_WLAN_KEEP_AWAKE(whd_driver); - - /* Set the event bits for each event from every handler */ - memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - if (cdc_bdc_info->whd_event_list[i].event_set) { - for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) { - setbit(event_mask, cdc_bdc_info->whd_event_list[i].events[j]); - } - } - } - - /* set the event_list_mutex from calling thread before sending iovar - * as the RX thread also waits on this Mutex when an ASYNC Event received - * causing deadlock + whd_buffer_t buffer; + uint8_t *event_mask; + uint16_t i; + uint16_t j; + whd_result_t res; + whd_driver_t whd_driver; + whd_interface_t prim_ifp; + + if (ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + if (!event_nums || !event_index) + { + WPRINT_WHD_ERROR( ("Event list to be registered is NULL/Event index is NULL") ); + return WHD_BADARG; + } + + whd_driver = ifp->whd_driver; + prim_ifp = whd_get_primary_interface(whd_driver); + whd_event_info_t *event_info = (whd_event_info_t *)whd_driver->proto->pd; + + if (prim_ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + /* Acquire mutex preventing multiple threads accessing the handler at the same time */ + res = cy_rtos_get_semaphore(&event_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (res != WHD_SUCCESS) + { + return res; + } + + /* Set event handler locally */ + res = whd_management_set_event_handler_locally(ifp, event_nums, handler_func, handler_user_data, event_index); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) ); + goto set_event_handler_exit; + } + + /* Send the new event mask value to the wifi chip */ + event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer); + + if (NULL == event_mask) + { + res = WHD_BUFFER_UNAVAILABLE_PERMANENT; + WPRINT_WHD_ERROR( ("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__) ); + goto set_event_handler_exit; + } + + /* Keep the wlan awake while we set the event_msgs */ + WHD_WLAN_KEEP_AWAKE(whd_driver); + + /* Set the event bits for each event from every handler */ + memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + if (event_info->whd_event_list[i].event_set) + { + for (j = 0; event_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) + { + setbit(event_mask, event_info->whd_event_list[i].events[j]); + } + } + } + + res = whd_proto_set_iovar(prim_ifp, buffer, 0); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: send event_msgs(iovar) failed\n", __func__) ); + goto set_event_handler_exit; + } + + /* set the event_list_mutex here after sending iovar. + * we get event_list_mutex -> ioctl_mutex, make sure we didn't have any thread, having ioctl_mutex -> event_list_mutex path. + * Otherwise it may cause deadlock */ - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE)); - - CHECK_RETURN(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0)); + CHECK_RETURN(cy_rtos_set_semaphore(&event_info->event_list_mutex, WHD_FALSE) ); - /* The wlan chip can sleep from now on */ - WHD_WLAN_LET_SLEEP(whd_driver); - return WHD_SUCCESS; + /* The wlan chip can sleep from now on */ + WHD_WLAN_LET_SLEEP(whd_driver); + return WHD_SUCCESS; set_event_handler_exit: - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE)); - return res; + CHECK_RETURN(cy_rtos_set_semaphore(&event_info->event_list_mutex, WHD_FALSE) ); + return res; } whd_result_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index) + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index) { - whd_buffer_t buffer; - uint8_t *event_mask; - uint16_t i; - uint16_t j; - whd_result_t res; - whd_driver_t whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info; - whd_interface_t prim_ifp; - - if (ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - if (!event_type || !event_index) { - WPRINT_WHD_ERROR(("Event list to be registered is NULL/Event index is NULL")); - return WHD_BADARG; - } - - whd_driver = ifp->whd_driver; - cdc_bdc_info = &whd_driver->cdc_bdc_info; - prim_ifp = whd_get_primary_interface(whd_driver); - - if (prim_ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - /* Acquire mutex preventing multiple threads accessing the handler at the same time */ - res = cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - if (res != WHD_SUCCESS) { - return res; - } - - /* Set event handler locally */ - res = whd_management_set_event_handler_locally(ifp, (whd_event_num_t *)event_type, handler_func, handler_user_data, - event_index); - if (res != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__)); - goto set_event_handler_exit; - } - - /* Send the new event mask value to the wifi chip */ - event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer); - - if (NULL == event_mask) { - res = WHD_BUFFER_UNAVAILABLE_PERMANENT; - WPRINT_WHD_ERROR(("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__)); - goto set_event_handler_exit; - } - - /* Keep the wlan awake while we set the event_msgs */ - WHD_WLAN_KEEP_AWAKE(whd_driver); - - /* Set the event bits for each event from every handler */ - memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); - for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) { - if (cdc_bdc_info->whd_event_list[i].event_set) { - for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) { - setbit(event_mask, cdc_bdc_info->whd_event_list[i].events[j]); - } - } - } - - /* set the event_list_mutex from calling thread before sending iovar - * as the RX thread also waits on this Mutex when an ASYNC Event received - * causing deadlock + whd_buffer_t buffer; + uint8_t *event_mask; + uint16_t i; + uint16_t j; + whd_result_t res; + whd_driver_t whd_driver; + whd_interface_t prim_ifp; + + if (ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + if (!event_type || !event_index) + { + WPRINT_WHD_ERROR( ("Event list to be registered is NULL/Event index is NULL") ); + return WHD_BADARG; + } + + whd_driver = ifp->whd_driver; + prim_ifp = whd_get_primary_interface(whd_driver); + whd_event_info_t *event_info = (whd_event_info_t *)whd_driver->proto->pd; + + if (prim_ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + /* Acquire mutex preventing multiple threads accessing the handler at the same time */ + res = cy_rtos_get_semaphore(&event_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (res != WHD_SUCCESS) + { + return res; + } + + /* Set event handler locally */ + res = whd_management_set_event_handler_locally(ifp, (whd_event_num_t *)event_type, handler_func, handler_user_data, + event_index); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) ); + goto set_event_handler_exit; + } + + /* Send the new event mask value to the wifi chip */ + event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer); + + if (NULL == event_mask) + { + res = WHD_BUFFER_UNAVAILABLE_PERMANENT; + WPRINT_WHD_ERROR( ("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__) ); + goto set_event_handler_exit; + } + + /* Keep the wlan awake while we set the event_msgs */ + WHD_WLAN_KEEP_AWAKE(whd_driver); + + /* Set the event bits for each event from every handler */ + memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + if (event_info->whd_event_list[i].event_set) + { + for (j = 0; event_info->whd_event_list[i].events[j] != WLC_E_NONE; j++) + { + setbit(event_mask, event_info->whd_event_list[i].events[j]); + } + } + } + + res = whd_proto_set_iovar(prim_ifp, buffer, 0); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: send event_msgs(iovar) failed\n", __func__) ); + } + + /* set the event_list_mutex here after sending iovar. + * we get event_list_mutex -> ioctl_mutex, make sure we didn't have any thread, having ioctl_mutex -> event_list_mutex path. + * Otherwise it may cause deadlock */ - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE)); + CHECK_RETURN(cy_rtos_set_semaphore(&event_info->event_list_mutex, WHD_FALSE) ); - CHECK_RETURN(whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0)); - - /* The wlan chip can sleep from now on */ - WHD_WLAN_LET_SLEEP(whd_driver); - return WHD_SUCCESS; + /* The wlan chip can sleep from now on */ + WHD_WLAN_LET_SLEEP(whd_driver); + return WHD_SUCCESS; set_event_handler_exit: - CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE)); - return res; + CHECK_RETURN(cy_rtos_set_semaphore(&event_info->event_list_mutex, WHD_FALSE) ); + return res; } /** @@ -504,90 +556,101 @@ whd_result_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *eve * @return WHD result code */ whd_result_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_nums, - whd_error_handler_t handler_func, - void *handler_user_data, uint16_t *error_index) + whd_error_handler_t handler_func, + void *handler_user_data, uint16_t *error_index) { - whd_result_t res; - whd_driver_t whd_driver; - whd_interface_t prim_ifp; - if (ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - if (!error_nums || !error_index) { - WPRINT_WHD_ERROR(("Error list to be registered is NULL/Error index is NULL \n")); - return WHD_BADARG; - } - - whd_driver = ifp->whd_driver; - prim_ifp = whd_get_primary_interface(whd_driver); - if (prim_ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - /* Set event handler locally */ - res = whd_set_error_handler_locally(whd_driver, error_nums, handler_func, handler_user_data, - error_index); - if (res != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__)); - return res; - } - - - return WHD_SUCCESS; + whd_result_t res; + whd_driver_t whd_driver; + whd_interface_t prim_ifp; + if (ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + if (!error_nums || !error_index) + { + WPRINT_WHD_ERROR( ("Error list to be registered is NULL/Error index is NULL \n") ); + return WHD_BADARG; + } + + whd_driver = ifp->whd_driver; + prim_ifp = whd_get_primary_interface(whd_driver); + if (prim_ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + /* Set event handler locally */ + res = whd_set_error_handler_locally(whd_driver, error_nums, handler_func, handler_user_data, + error_index); + if (res != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) ); + return res; + } + + + return WHD_SUCCESS; + } -uint32_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index) +whd_result_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index) { - whd_driver_t whd_driver; - whd_cdc_bdc_info_t *cdc_bdc_info; - - if (ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - whd_driver = ifp->whd_driver; - cdc_bdc_info = &whd_driver->cdc_bdc_info; - - if (event_index < WHD_EVENT_HANDLER_LIST_SIZE) { - memset(cdc_bdc_info->whd_event_list[event_index].events, 0xFF, - (sizeof(cdc_bdc_info->whd_event_list[event_index].events))); - cdc_bdc_info->whd_event_list[event_index].handler = NULL; - cdc_bdc_info->whd_event_list[event_index].handler_user_data = NULL; - cdc_bdc_info->whd_event_list[event_index].event_set = WHD_FALSE; - return WHD_SUCCESS; - } - if (event_index == 0xFF) { - WPRINT_WHD_INFO(("Event handler not registered \n")); - return WHD_SUCCESS; - } - WPRINT_WHD_DEBUG(("Invalid event index received to deregister the event handler \n")); - return WHD_BADARG; + whd_driver_t whd_driver; + + if (ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + whd_driver = ifp->whd_driver; + + whd_event_info_t *event_info = (whd_event_info_t *)whd_driver->proto->pd; + + if (event_index < WHD_EVENT_HANDLER_LIST_SIZE) + { + memset(event_info->whd_event_list[event_index].events, 0xFF, + (sizeof(event_info->whd_event_list[event_index].events) ) ); + event_info->whd_event_list[event_index].handler = NULL; + event_info->whd_event_list[event_index].handler_user_data = NULL; + event_info->whd_event_list[event_index].event_set = WHD_FALSE; + return WHD_SUCCESS; + } + if (event_index == 0xFF) + { + WPRINT_WHD_INFO( ("Event handler not registered \n") ); + return WHD_SUCCESS; + } + WPRINT_WHD_DEBUG( ("Invalid event index received to deregister the event handler \n") ); + return WHD_BADARG; } -uint32_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index) +whd_result_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index) { - whd_driver_t whd_driver; - whd_error_info_t *error_info; - - if (ifp == NULL) { - return WHD_UNKNOWN_INTERFACE; - } - - whd_driver = ifp->whd_driver; - error_info = &whd_driver->error_info; - - if (error_index < WHD_EVENT_HANDLER_LIST_SIZE) { - error_info->whd_event_list[error_index].events = 0; - error_info->whd_event_list[error_index].handler = NULL; - error_info->whd_event_list[error_index].handler_user_data = NULL; - error_info->whd_event_list[error_index].event_set = WHD_FALSE; - return WHD_SUCCESS; - } - if (error_index == 0xFF) { - WPRINT_WHD_INFO(("Error handler not registered \n")); - return WHD_SUCCESS; - } - WPRINT_WHD_DEBUG(("Invalid error index received to deregister the event handler \n")); - return WHD_BADARG; + whd_driver_t whd_driver; + whd_error_info_t *error_info; + + if (ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + whd_driver = ifp->whd_driver; + error_info = &whd_driver->error_info; + + if (error_index < WHD_EVENT_HANDLER_LIST_SIZE) + { + error_info->whd_event_list[error_index].events = 0; + error_info->whd_event_list[error_index].handler = NULL; + error_info->whd_event_list[error_index].handler_user_data = NULL; + error_info->whd_event_list[error_index].event_set = WHD_FALSE; + return WHD_SUCCESS; + } + if (error_index == 0xFF) + { + WPRINT_WHD_INFO( ("Error handler not registered \n") ); + return WHD_SUCCESS; + } + WPRINT_WHD_DEBUG( ("Invalid error index received to deregister the event handler \n") ); + return WHD_BADARG; } diff --git a/wi-fi/whd/whd_events.h b/wi-fi/whd/whd_events.h index c2c4c4c5..0cf5e034 100644 --- a/wi-fi/whd/whd_events.h +++ b/wi-fi/whd/whd_events.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,58 +27,62 @@ #include "whd.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* List of events */ -#define WLC_E_NONE (0x7FFFFFFE) /**< Indicates the end of the event array list */ +#define WLC_E_NONE (0x7FFFFFFE) /**< Indicates the end of the event array list */ -#define WLC_E_SET_SSID 0 /**< Indicates status of set SSID. This event occurs when STA tries to join the AP*/ -#define WLC_E_AUTH 3 /**< 802.11 AUTH request event occurs when STA tries to get authenticated with the AP */ -#define WLC_E_DEAUTH 5 /**< 802.11 DEAUTH request event occurs when the the SOFTAP is stopped to deuthenticate the connected stations*/ -#define WLC_E_DEAUTH_IND 6 /**< 802.11 DEAUTH indication event occurs when the STA gets deauthenticated by the AP */ -#define WLC_E_ASSOC 7 /**< 802.11 ASSOC request event occurs when STA joins the AP */ -#define WLC_E_ASSOC_IND 8 /**< 802.11 ASSOC indication occurs when a station joins the SOFTAP that is started */ -#define WLC_E_REASSOC 9 /**< 802.11 REASSOC request event when the STA again gets associated with the AP */ -#define WLC_E_REASSOC_IND 10 /**< 802.11 REASSOC indication occurs when a station again reassociates with the SOFTAP*/ -#define WLC_E_DISASSOC 11 /**< 802.11 DISASSOC request occurs when the STA the tries to leave the AP*/ -#define WLC_E_DISASSOC_IND 12 /**< 802.11 DISASSOC indication occurs when the connected station gets disassociates from SOFTAP, \ - also when STA gets diassociated by the AP*/ -#define WLC_E_LINK 16 /**< generic link indication */ -#define WLC_E_PROBREQ_MSG 44 /**< Indicates probe request received for the SOFTAP started*/ -#define WLC_E_PSK_SUP 46 /**< WPA Handshake fail during association*/ -#define WLC_E_ACTION_FRAME 59 /**< Indicates Action frame Rx */ -#define WLC_E_ACTION_FRAME_COMPLETE 60 /**< Indicates Action frame Tx complete */ -#define WLC_E_ESCAN_RESULT 69 /**< escan result event occurs when we scan for the networks */ +#define WLC_E_SET_SSID 0 /**< Indicates status of set SSID. This event occurs when STA tries to join the AP*/ +#define WLC_E_AUTH 3 /**< 802.11 AUTH request event occurs when STA tries to get authenticated with the AP */ +#define WLC_E_DEAUTH 5 /**< 802.11 DEAUTH request event occurs when the the SOFTAP is stopped to deuthenticate the connected stations*/ +#define WLC_E_DEAUTH_IND 6 /**< 802.11 DEAUTH indication event occurs when the STA gets deauthenticated by the AP */ +#define WLC_E_ASSOC 7 /**< 802.11 ASSOC request event occurs when STA joins the AP */ +#define WLC_E_ASSOC_IND 8 /**< 802.11 ASSOC indication occurs when a station joins the SOFTAP that is started */ +#define WLC_E_REASSOC 9 /**< 802.11 REASSOC request event when the STA again gets associated with the AP */ +#define WLC_E_REASSOC_IND 10 /**< 802.11 REASSOC indication occurs when a station again reassociates with the SOFTAP*/ +#define WLC_E_DISASSOC 11 /**< 802.11 DISASSOC request occurs when the STA the tries to leave the AP*/ +#define WLC_E_DISASSOC_IND 12 /**< 802.11 DISASSOC indication occurs when the connected station gets disassociates from SOFTAP, + also when STA gets diassociated by the AP*/ +#define WLC_E_LINK 16 /**< generic link indication */ +#define WLC_E_PROBREQ_MSG 44 /**< Indicates probe request received for the SOFTAP started*/ +#define WLC_E_PSK_SUP 46 /**< WPA Handshake fail during association*/ +#define WLC_E_ACTION_FRAME 59 /**< Indicates Action frame Rx */ +#define WLC_E_ACTION_FRAME_COMPLETE 60 /**< Indicates Action frame Tx complete */ +#define WLC_E_ESCAN_RESULT 69 /**< escan result event occurs when we scan for the networks */ +#define WLC_E_EXT_AUTH_REQ 187 /**< authentication request received */ +#define WLC_E_EXT_AUTH_FRAME_RX 188 /**< authentication request received */ +#define WLC_E_MGMT_FRAME_TXSTATUS 189 /**< mgmt frame Tx complete */ /* List of status codes - Applicable for any event type */ -#define WLC_E_STATUS_SUCCESS 0 /**< operation was successful */ -#define WLC_E_STATUS_FAIL 1 /**< operation failed */ -#define WLC_E_STATUS_TIMEOUT 2 /**< operation timed out */ -#define WLC_E_STATUS_NO_NETWORKS 3 /**< failed due to no matching network found */ -#define WLC_E_STATUS_ABORT 4 /**< operation was aborted */ -#define WLC_E_STATUS_NO_ACK 5 /**< protocol failure: packet not ack'd */ -#define WLC_E_STATUS_UNSOLICITED 6 /**< AUTH or ASSOC packet was unsolicited */ -#define WLC_E_STATUS_ATTEMPT 7 /**< attempt to assoc to an auto auth configuration */ -#define WLC_E_STATUS_PARTIAL 8 /**< scan results are incomplete */ -#define WLC_E_STATUS_NEWSCAN 9 /**< scan aborted by another scan */ -#define WLC_E_STATUS_NEWASSOC 10 /**< scan aborted due to assoc in progress */ -#define WLC_E_STATUS_11HQUIET 11 /**< 802.11h quiet period started */ -#define WLC_E_STATUS_SUPPRESS 12 /**< user disabled scanning (WLC_SET_SCANSUPPRESS) */ -#define WLC_E_STATUS_NOCHANS 13 /**< no allowable channels to scan */ -#define WLC_E_STATUS_CCXFASTRM 14 /**< scan aborted due to CCX fast roam */ -#define WLC_E_STATUS_CS_ABORT 15 /**< abort channel select */ -#define WLC_E_STATUS_ERROR 16 /**< request failed due to error */ -#define WLC_E_STATUS_INVALID 0xff /**< Invalid status code to init variables. */ +#define WLC_E_STATUS_SUCCESS 0 /**< operation was successful */ +#define WLC_E_STATUS_FAIL 1 /**< operation failed */ +#define WLC_E_STATUS_TIMEOUT 2 /**< operation timed out */ +#define WLC_E_STATUS_NO_NETWORKS 3 /**< failed due to no matching network found */ +#define WLC_E_STATUS_ABORT 4 /**< operation was aborted */ +#define WLC_E_STATUS_NO_ACK 5 /**< protocol failure: packet not ack'd */ +#define WLC_E_STATUS_UNSOLICITED 6 /**< AUTH or ASSOC packet was unsolicited */ +#define WLC_E_STATUS_ATTEMPT 7 /**< attempt to assoc to an auto auth configuration */ +#define WLC_E_STATUS_PARTIAL 8 /**< scan results are incomplete */ +#define WLC_E_STATUS_NEWSCAN 9 /**< scan aborted by another scan */ +#define WLC_E_STATUS_NEWASSOC 10 /**< scan aborted due to assoc in progress */ +#define WLC_E_STATUS_11HQUIET 11 /**< 802.11h quiet period started */ +#define WLC_E_STATUS_SUPPRESS 12 /**< user disabled scanning (WLC_SET_SCANSUPPRESS) */ +#define WLC_E_STATUS_NOCHANS 13 /**< no allowable channels to scan */ +#define WLC_E_STATUS_CCXFASTRM 14 /**< scan aborted due to CCX fast roam */ +#define WLC_E_STATUS_CS_ABORT 15 /**< abort channel select */ +#define WLC_E_STATUS_ERROR 16 /**< request failed due to error */ +#define WLC_E_STATUS_INVALID 0xff /**< Invalid status code to init variables. */ -#define WLC_SUP_STATUS_OFFSET (256) /**< Status offset added to the status codes to match the values from firmware. */ +#define WLC_SUP_STATUS_OFFSET (256) /**< Status offset added to the status codes to match the values from firmware. */ /** * @brief Status code for event WLC_E_PSK_SUP * * -Basic supplicant authentication states * - + WLC_SUP_DISCONNECTED + * + WLC_SUP_DISCONNECTED * + WLC_SUP_CONNECTING * + WLC_SUP_IDREQUIRED * + WLC_SUP_AUTHENTICATING @@ -87,7 +91,9 @@ extern "C" { * + WLC_SUP_KEYED * + WLC_SUP_TIMEOUT * + WLC_SUP_LAST_BASIC_STATE - * -Extended supplicant authentication states + * + * -Extended supplicant authentication states + * * + WLC_SUP_KEYXCHANGE_WAIT_M1 * + WLC_SUP_KEYXCHANGE_PREP_M2 * + WLC_SUP_KEYXCHANGE_WAIT_M3 @@ -95,63 +101,73 @@ extern "C" { * + WLC_SUP_KEYXCHANGE_WAIT_G1 * + WLC_SUP_KEYXCHANGE_PREP_G2 */ -typedef enum sup_auth_status { - WLC_SUP_DISCONNECTED = 0 + WLC_SUP_STATUS_OFFSET, /**< Disconnected */ - WLC_SUP_CONNECTING = 1 + WLC_SUP_STATUS_OFFSET, /**< Connecting */ - WLC_SUP_IDREQUIRED = 2 + WLC_SUP_STATUS_OFFSET, /**< ID Required */ - WLC_SUP_AUTHENTICATING = 3 + WLC_SUP_STATUS_OFFSET, /**< Authenticating */ - WLC_SUP_AUTHENTICATED = 4 + WLC_SUP_STATUS_OFFSET, /**< Authenticated */ - WLC_SUP_KEYXCHANGE = 5 + WLC_SUP_STATUS_OFFSET, /**< Key Exchange */ - WLC_SUP_KEYED = 6 + WLC_SUP_STATUS_OFFSET, /**< Key Exchanged */ - WLC_SUP_TIMEOUT = 7 + WLC_SUP_STATUS_OFFSET, /**< Timeout */ - WLC_SUP_LAST_BASIC_STATE = 8 + WLC_SUP_STATUS_OFFSET, /**< Last Basic State */ - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, /**< Waiting to receive handshake msg M1 */ - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, /**< Preparing to send handshake msg M2 */ - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, /**< Waiting to receive handshake msg M3 */ - WLC_SUP_KEYXCHANGE_PREP_M4 = 9 + WLC_SUP_STATUS_OFFSET, /**< Preparing to send handshake msg M4 */ - WLC_SUP_KEYXCHANGE_WAIT_G1 = 10 + WLC_SUP_STATUS_OFFSET, /**< Waiting to receive handshake msg G1 */ - WLC_SUP_KEYXCHANGE_PREP_G2 = 11 + WLC_SUP_STATUS_OFFSET /**< Preparing to send handshake msg G2 */ +typedef enum sup_auth_status +{ + WLC_SUP_DISCONNECTED = 0 + WLC_SUP_STATUS_OFFSET, /**< Disconnected */ + WLC_SUP_CONNECTING = 1 + WLC_SUP_STATUS_OFFSET, /**< Connecting */ + WLC_SUP_IDREQUIRED = 2 + WLC_SUP_STATUS_OFFSET, /**< ID Required */ + WLC_SUP_AUTHENTICATING = 3 + WLC_SUP_STATUS_OFFSET, /**< Authenticating */ + WLC_SUP_AUTHENTICATED = 4 + WLC_SUP_STATUS_OFFSET, /**< Authenticated */ + WLC_SUP_KEYXCHANGE = 5 + WLC_SUP_STATUS_OFFSET, /**< Key Exchange */ + WLC_SUP_KEYED = 6 + WLC_SUP_STATUS_OFFSET, /**< Key Exchanged */ + WLC_SUP_TIMEOUT = 7 + WLC_SUP_STATUS_OFFSET, /**< Timeout */ + WLC_SUP_LAST_BASIC_STATE = 8 + WLC_SUP_STATUS_OFFSET, /**< Last Basic State */ + WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, /**< Waiting to receive handshake msg M1 */ + WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, /**< Preparing to send handshake msg M2 */ + WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, /**< Waiting to receive handshake msg M3 */ + WLC_SUP_KEYXCHANGE_PREP_M4 = 9 + WLC_SUP_STATUS_OFFSET, /**< Preparing to send handshake msg M4 */ + WLC_SUP_KEYXCHANGE_WAIT_G1 = 10 + WLC_SUP_STATUS_OFFSET, /**< Waiting to receive handshake msg G1 */ + WLC_SUP_KEYXCHANGE_PREP_G2 = 11 + WLC_SUP_STATUS_OFFSET /**< Preparing to send handshake msg G2 */ } sup_auth_status_t; #define WHD_MSG_IFNAME_MAX 16 /**< Max length of Interface name */ +/* Reason codes for LINK */ +#define WLC_E_LINK_BCN_LOSS 1 /**< Link down because of beacon loss */ +#define WLC_E_LINK_DISASSOC 2 /**< Link down because of disassoc */ +#define WLC_E_LINK_ASSOC_REC 3 /**< Link down because assoc recreate failed */ +#define WLC_E_LINK_BSSCFG_DIS 4 /**< Link down due to bsscfg down */ + #pragma pack(1) /** * Structure to store ethernet header fields in event packets */ -typedef struct whd_event_eth_hdr { - uint16_t subtype; /**< Vendor specific..32769 */ - uint16_t length; /**< Length of ethernet header*/ - uint8_t version; /**< Version is 0 */ - uint8_t oui[3]; /**< Organizationally Unique Identifier */ - uint16_t usr_subtype; /**< User specific data */ +typedef struct whd_event_eth_hdr +{ + uint16_t subtype; /**< Vendor specific..32769 */ + uint16_t length; /**< Length of ethernet header*/ + uint8_t version; /**< Version is 0 */ + uint8_t oui[3]; /**< Organizationally Unique Identifier */ + uint16_t usr_subtype; /**< User specific data */ } whd_event_eth_hdr_t; /** * Structure to store ethernet destination, source and ethertype in event packets */ -typedef struct whd_event_ether_header { - whd_mac_t destination_address; /**< Ethernet destination address */ - whd_mac_t source_address; /**< Ethernet source address */ - uint16_t ethertype; /**< Ethertype for identifying event packets */ +typedef struct whd_event_ether_header +{ + whd_mac_t destination_address; /**< Ethernet destination address */ + whd_mac_t source_address; /**< Ethernet source address */ + uint16_t ethertype; /**< Ethertype for identifying event packets */ } whd_event_ether_header_t; /** * Structure to store fields after ethernet header in event message */ -struct whd_event_msg { - uint16_t version; /**< Version */ - uint16_t flags; /**< see flags below */ - uint32_t event_type; /**< Event type indicating a response from firmware for IOCTLs/IOVARs sent */ - uint32_t status; /**< Status code corresponding to any event type */ - uint32_t reason; /**< Reason code associated with the event occurred */ - uint32_t auth_type; /**< WLC_E_AUTH: 802.11 AUTH request */ - uint32_t datalen; /**< Length of data in event message */ - whd_mac_t addr; /**< Station address (if applicable) */ - char ifname[WHD_MSG_IFNAME_MAX]; /**< name of the incoming packet interface */ - uint8_t ifidx; /**< destination OS i/f index */ - uint8_t bsscfgidx; /**< source bsscfg index */ +struct whd_event_msg +{ + uint16_t version; /**< Version */ + uint16_t flags; /**< see flags below */ + uint32_t event_type; /**< Event type indicating a response from firmware for IOCTLs/IOVARs sent */ + uint32_t status; /**< Status code corresponding to any event type */ + uint32_t reason; /**< Reason code associated with the event occurred */ + uint32_t auth_type; /**< WLC_E_AUTH: 802.11 AUTH request */ + uint32_t datalen; /**< Length of data in event message */ + whd_mac_t addr; /**< Station address (if applicable) */ + char ifname[WHD_MSG_IFNAME_MAX]; /**< name of the incoming packet interface */ + uint8_t ifidx; /**< destination OS i/f index */ + uint8_t bsscfgidx; /**< source bsscfg index */ }; /** @@ -178,7 +194,7 @@ typedef struct whd_event { * @param handler_user_data semaphore data */ typedef void *(*whd_event_handler_t)(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); /** Error handler prototype definition * * @param whd_driver Pointer to handle instance of whd driver @@ -187,7 +203,7 @@ typedef void *(*whd_event_handler_t)(whd_interface_t ifp, const whd_event_header * @param handler_user_data semaphore data */ typedef void *(*whd_error_handler_t)(whd_driver_t whd_driver, const uint8_t *error_type, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); /* @} */ /** Registers a handler to receive event callbacks. * @@ -208,8 +224,8 @@ typedef void *(*whd_error_handler_t)(whd_driver_t whd_driver, const uint8_t *err * * @return WHD_SUCCESS or Error code */ -uint32_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type, whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index); +whd_result_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type, whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index); /** Registers a handler to receive error callbacks. * * This function registers a callback handler to be notified when @@ -229,8 +245,8 @@ uint32_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_t * * @return WHD_SUCCESS or Error code */ -uint32_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_nums, whd_error_handler_t handler_func, - void *handler_user_data, uint16_t *error_index); +whd_result_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_nums, whd_error_handler_t handler_func, + void *handler_user_data, uint16_t *error_index); /** Delete/Deregister the event entry where callback is registered * @@ -240,7 +256,7 @@ uint32_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_nu * @return WHD_SUCCESS or Error code */ -uint32_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index); +whd_result_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index); /** Delete/Deregister the error entry where callback is registered * * @param ifp Pointer to handle instance of whd interface @@ -249,7 +265,7 @@ uint32_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_i * @return WHD_SUCCESS or Error code */ -uint32_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index); +whd_result_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index); #ifdef __cplusplus } /* extern "C" */ diff --git a/wi-fi/whd/whd_events_int.h b/wi-fi/whd/whd_events_int.h index 327a0541..68255a12 100644 --- a/wi-fi/whd/whd_events_int.h +++ b/wi-fi/whd/whd_events_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,8 @@ #define INCLUDED_WHD_EVENTS_INT_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -186,17 +187,21 @@ typedef enum { WLC_E_RRM = 141, /* RRM Event */ WLC_E_ULP = 146, /* ULP entry event */ WLC_E_TKO = 151, /* TCP Keep Alive Offload Event */ - WLC_E_LAST = 152, /* highest val + 1 for range checking */ + WLC_E_EXT_AUTH_REQ = 187, /* authentication request received */ + WLC_E_EXT_AUTH_FRAME_RX = 188, /* authentication request received */ + WLC_E_MGMT_FRAME_TXSTATUS = 189, /* mgmt frame Tx complete */ + WLC_E_LAST = 190, /* highest val + 1 for range checking */ } whd_event_num_t; /** * Enumerated list of error types */ -typedef enum { - WLC_ERR_NONE = 0x00, - WLC_ERR_BUS = 0x01, /** indicates BUS got wrong */ - WLC_ERR_FW = 0x02, /** FW halt or crash */ -} whd_error_num_t; +typedef enum +{ + WLC_ERR_NONE = 0x00, + WLC_ERR_BUS = 0x01, /** indicates BUS got wrong */ + WLC_ERR_FW = 0x02, /** FW halt or crash */ +} whd_error_num_t; #define WLC_SUP_STATUS_OFFSET (256) #define WLC_DOT11_SC_STATUS_OFFSET (512) @@ -205,69 +210,66 @@ typedef enum { * @note : WLC_SUP values overlap other values, so it is necessary * to check the event type */ -typedef enum { - WLC_E_STATUS_SUCCESS = 0, /** operation was successful */ - WLC_E_STATUS_FAIL = 1, /** operation failed */ - WLC_E_STATUS_TIMEOUT = 2, /** operation timed out */ - WLC_E_STATUS_NO_NETWORKS = 3, /** failed due to no matching network found */ - WLC_E_STATUS_ABORT = 4, /** operation was aborted */ - WLC_E_STATUS_NO_ACK = 5, /** protocol failure: packet not ack'd */ - WLC_E_STATUS_UNSOLICITED = 6, /** AUTH or ASSOC packet was unsolicited */ - WLC_E_STATUS_ATTEMPT = 7, /** attempt to assoc to an auto auth configuration */ - WLC_E_STATUS_PARTIAL = 8, /** scan results are incomplete */ - WLC_E_STATUS_NEWSCAN = 9, /** scan aborted by another scan */ - WLC_E_STATUS_NEWASSOC = 10, /** scan aborted due to assoc in progress */ - WLC_E_STATUS_11HQUIET = 11, /** 802.11h quiet period started */ - WLC_E_STATUS_SUPPRESS = 12, /** user disabled scanning (WLC_SET_SCANSUPPRESS) */ - WLC_E_STATUS_NOCHANS = 13, /** no allowable channels to scan */ - WLC_E_STATUS_CCXFASTRM = 14, /** scan aborted due to CCX fast roam */ - WLC_E_STATUS_CS_ABORT = 15, /** abort channel select */ - - /* for WLC_SUP messages */ - WLC_SUP_DISCONNECTED = 0 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_CONNECTING = 1 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_IDREQUIRED = 2 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_AUTHENTICATING = 3 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_AUTHENTICATED = 4 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_KEYXCHANGE = 5 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_KEYED = 6 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_TIMEOUT = 7 + WLC_SUP_STATUS_OFFSET, - WLC_SUP_LAST_BASIC_STATE = 8 + WLC_SUP_STATUS_OFFSET, - /* Extended supplicant authentication states */ - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, /** Waiting to receive handshake msg M1 */ - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, /** Preparing to send handshake msg M2 */ - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, /** Waiting to receive handshake msg M3 */ - WLC_SUP_KEYXCHANGE_PREP_M4 = 9 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg M4 */ - WLC_SUP_KEYXCHANGE_WAIT_G1 = 10 + WLC_SUP_STATUS_OFFSET, /** Waiting to receive handshake msg G1 */ - WLC_SUP_KEYXCHANGE_PREP_G2 = 11 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg G2 */ - - WLC_DOT11_SC_SUCCESS = 0 + WLC_DOT11_SC_STATUS_OFFSET, /* Successful */ - WLC_DOT11_SC_FAILURE = 1 + WLC_DOT11_SC_STATUS_OFFSET, /* Unspecified failure */ - WLC_DOT11_SC_CAP_MISMATCH = 10 + WLC_DOT11_SC_STATUS_OFFSET, /* Cannot support all requested capabilities in the Capability Information field */ - WLC_DOT11_SC_REASSOC_FAIL = 11 + WLC_DOT11_SC_STATUS_OFFSET, /* Reassociation denied due to inability to confirm that association exists */ - WLC_DOT11_SC_ASSOC_FAIL = 12 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to reason outside the scope of this standard */ - WLC_DOT11_SC_AUTH_MISMATCH = 13 + WLC_DOT11_SC_STATUS_OFFSET, /* Responding station does not support the specified authentication algorithm */ - WLC_DOT11_SC_AUTH_SEQ = 14 + WLC_DOT11_SC_STATUS_OFFSET, /* Received an Authentication frame with authentication transaction sequence number out of expected sequence */ - WLC_DOT11_SC_AUTH_CHALLENGE_FAIL = 15 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected because of challenge failure */ - WLC_DOT11_SC_AUTH_TIMEOUT = 16 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected due to timeout waiting for next frame in sequence */ - WLC_DOT11_SC_ASSOC_BUSY_FAIL = 17 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because AP is unable to handle additional associated stations */ - WLC_DOT11_SC_ASSOC_RATE_MISMATCH = 18 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter */ - WLC_DOT11_SC_ASSOC_SHORT_REQUIRED = 19 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Preamble option */ - WLC_DOT11_SC_ASSOC_PBCC_REQUIRED = 20 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the PBCC Modulation option */ - WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED = 21 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Channel Agility option */ - WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED = 22 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because Spectrum Management capability is required. */ - WLC_DOT11_SC_ASSOC_BAD_POWER_CAP = 23 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Power Cap element is unacceptable. */ - WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS = 24 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Supported Channel element is unacceptable */ - WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED = 25 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Slot Time option */ - WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED = 26 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the ER-PBCC Modulation option */ - WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED = 27 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the DSS-OFDM option */ - WLC_DOT11_SC_DECLINED = 37 + WLC_DOT11_SC_STATUS_OFFSET, /* request declined */ - WLC_DOT11_SC_INVALID_PARAMS = 38 + WLC_DOT11_SC_STATUS_OFFSET, /* One or more params have invalid values */ - WLC_DOT11_SC_INVALID_AKMP = 43 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid AKMP */ - WLC_DOT11_SC_INVALID_MDID = 54 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid MDID */ - WLC_DOT11_SC_INVALID_FTIE = 55 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid FTIE */ - - WLC_E_STATUS_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */ +typedef enum +{ + WLC_E_STATUS_SUCCESS = 0, /** operation was successful */ + WLC_E_STATUS_FAIL = 1, /** operation failed */ + WLC_E_STATUS_TIMEOUT = 2, /** operation timed out */ + WLC_E_STATUS_NO_NETWORKS = 3, /** failed due to no matching network found */ + WLC_E_STATUS_ABORT = 4, /** operation was aborted */ + WLC_E_STATUS_NO_ACK = 5, /** protocol failure: packet not ack'd */ + WLC_E_STATUS_UNSOLICITED = 6, /** AUTH or ASSOC packet was unsolicited */ + WLC_E_STATUS_ATTEMPT = 7, /** attempt to assoc to an auto auth configuration */ + WLC_E_STATUS_PARTIAL = 8, /** scan results are incomplete */ + WLC_E_STATUS_NEWSCAN = 9, /** scan aborted by another scan */ + WLC_E_STATUS_NEWASSOC = 10, /** scan aborted due to assoc in progress */ + WLC_E_STATUS_11HQUIET = 11, /** 802.11h quiet period started */ + WLC_E_STATUS_SUPPRESS = 12, /** user disabled scanning (WLC_SET_SCANSUPPRESS) */ + WLC_E_STATUS_NOCHANS = 13, /** no allowable channels to scan */ + WLC_E_STATUS_CCXFASTRM = 14, /** scan aborted due to CCX fast roam */ + WLC_E_STATUS_CS_ABORT = 15, /** abort channel select */ + + /* for WLC_SUP messages */ + WLC_SUP_DISCONNECTED = 0 + WLC_SUP_STATUS_OFFSET, WLC_SUP_CONNECTING = 1 + WLC_SUP_STATUS_OFFSET, + WLC_SUP_IDREQUIRED = 2 + WLC_SUP_STATUS_OFFSET, WLC_SUP_AUTHENTICATING = 3 + WLC_SUP_STATUS_OFFSET, + WLC_SUP_AUTHENTICATED = 4 + WLC_SUP_STATUS_OFFSET, WLC_SUP_KEYXCHANGE = 5 + WLC_SUP_STATUS_OFFSET, + WLC_SUP_KEYED = 6 + WLC_SUP_STATUS_OFFSET, WLC_SUP_TIMEOUT = 7 + WLC_SUP_STATUS_OFFSET, + WLC_SUP_LAST_BASIC_STATE = 8 + WLC_SUP_STATUS_OFFSET, + /* Extended supplicant authentication states */ + WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, /** Waiting to receive handshake msg M1 */ + WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, /** Preparing to send handshake msg M2 */ + WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, /** Waiting to receive handshake msg M3 */ + WLC_SUP_KEYXCHANGE_PREP_M4 = 9 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg M4 */ + WLC_SUP_KEYXCHANGE_WAIT_G1 = 10 + WLC_SUP_STATUS_OFFSET, /** Waiting to receive handshake msg G1 */ + WLC_SUP_KEYXCHANGE_PREP_G2 = 11 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg G2 */ + + WLC_DOT11_SC_SUCCESS = 0 + WLC_DOT11_SC_STATUS_OFFSET, /* Successful */ + WLC_DOT11_SC_FAILURE = 1 + WLC_DOT11_SC_STATUS_OFFSET, /* Unspecified failure */ + WLC_DOT11_SC_CAP_MISMATCH = 10 + WLC_DOT11_SC_STATUS_OFFSET, /* Cannot support all requested capabilities in the Capability Information field */ + WLC_DOT11_SC_REASSOC_FAIL = 11 + WLC_DOT11_SC_STATUS_OFFSET, /* Reassociation denied due to inability to confirm that association exists */ + WLC_DOT11_SC_ASSOC_FAIL = 12 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to reason outside the scope of this standard */ + WLC_DOT11_SC_AUTH_MISMATCH = 13 + WLC_DOT11_SC_STATUS_OFFSET, /* Responding station does not support the specified authentication algorithm */ + WLC_DOT11_SC_AUTH_SEQ = 14 + WLC_DOT11_SC_STATUS_OFFSET, /* Received an Authentication frame with authentication transaction sequence number out of expected sequence */ + WLC_DOT11_SC_AUTH_CHALLENGE_FAIL = 15 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected because of challenge failure */ + WLC_DOT11_SC_AUTH_TIMEOUT = 16 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected due to timeout waiting for next frame in sequence */ + WLC_DOT11_SC_ASSOC_BUSY_FAIL = 17 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because AP is unable to handle additional associated stations */ + WLC_DOT11_SC_ASSOC_RATE_MISMATCH = 18 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter */ + WLC_DOT11_SC_ASSOC_SHORT_REQUIRED = 19 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Preamble option */ + WLC_DOT11_SC_ASSOC_PBCC_REQUIRED = 20 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the PBCC Modulation option */ + WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED = 21 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Channel Agility option */ + WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED = 22 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because Spectrum Management capability is required. */ + WLC_DOT11_SC_ASSOC_BAD_POWER_CAP = 23 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Power Cap element is unacceptable. */ + WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS = 24 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Supported Channel element is unacceptable */ + WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED = 25 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Slot Time option */ + WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED = 26 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the ER-PBCC Modulation option */ + WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED = 27 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the DSS-OFDM option */ + WLC_DOT11_SC_DECLINED = 37 + WLC_DOT11_SC_STATUS_OFFSET, /* request declined */ + WLC_DOT11_SC_INVALID_PARAMS = 38 + WLC_DOT11_SC_STATUS_OFFSET, /* One or more params have invalid values */ + WLC_DOT11_SC_INVALID_AKMP = 43 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid AKMP */ + WLC_DOT11_SC_INVALID_MDID = 54 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid MDID */ + WLC_DOT11_SC_INVALID_FTIE = 55 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid FTIE */ + + WLC_E_STATUS_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */ } whd_event_status_t; #define WLC_E_PRUNE_REASON_OFFSET (256) @@ -279,119 +281,122 @@ typedef enum { * @note : Several values overlap other values, so it is necessary * to check the event type */ -typedef enum { - /* roam reason codes */ - WLC_E_REASON_INITIAL_ASSOC = 0, /** initial assoc */ - WLC_E_REASON_LOW_RSSI = 1, /** roamed due to low RSSI */ - WLC_E_REASON_DEAUTH = 2, /** roamed due to DEAUTH indication */ - WLC_E_REASON_DISASSOC = 3, /** roamed due to DISASSOC indication */ - WLC_E_REASON_BCNS_LOST = 4, /** roamed due to lost beacons */ - WLC_E_REASON_FAST_ROAM_FAILED = 5, /** roamed due to fast roam failure */ - WLC_E_REASON_DIRECTED_ROAM = 6, /** roamed due to request by AP */ - WLC_E_REASON_TSPEC_REJECTED = 7, /** roamed due to TSPEC rejection */ - WLC_E_REASON_BETTER_AP = 8, /** roamed due to finding better AP */ - - /* NAN sub-events comes as a reason code with event as WLC_E_NAN */ - WLC_E_NAN_EVENT_STATUS_CHG = 9, /* generated on any change in nan_mac status */ - WLC_E_NAN_EVENT_MERGE = 10, /* Merged to a NAN cluster */ - WLC_E_NAN_EVENT_STOP = 11, /* NAN stopped */ - WLC_E_NAN_EVENT_P2P = 12, /* NAN P2P EVENT */ - - /* XXX: Dont use below four events: They will be cleanup, use WL_NAN_EVENT_POST_DISC */ - WLC_E_NAN_EVENT_WINDOW_BEGIN_P2P = 13, /* Event for begin of P2P further availability window */ - WLC_E_NAN_EVENT_WINDOW_BEGIN_MESH = 14, - WLC_E_NAN_EVENT_WINDOW_BEGIN_IBSS = 15, - WLC_E_NAN_EVENT_WINDOW_BEGIN_RANGING = 16, - WLC_E_NAN_EVENT_POST_DISC = 17, /* Event for post discovery data */ - WLC_E_NAN_EVENT_DATA_IF_ADD = 18, /* Event for Data IF add */ - WLC_E_NAN_EVENT_DATA_PEER_ADD = 19, /* Event for peer add */ - - /* nan 2.0 */ - WLC_E_NAN_EVENT_DATA_IND = 20, /* Data Indication to Host */ - WLC_E_NAN_EVENT_DATA_CONF = 21, /* Data Response to Host */ - WLC_E_NAN_EVENT_SDF_RX = 22, /* entire service discovery frame */ - WLC_E_NAN_EVENT_DATA_END = 23, - WLC_E_NAN_EVENT_BCN_RX = 24, /* received beacon payload */ - - /* prune reason codes */ - WLC_E_PRUNE_ENCR_MISMATCH = 1 + WLC_E_PRUNE_REASON_OFFSET, /** encryption mismatch */ - WLC_E_PRUNE_BCAST_BSSID = 2 + WLC_E_PRUNE_REASON_OFFSET, /** AP uses a broadcast BSSID */ - WLC_E_PRUNE_MAC_DENY = 3 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is in AP's MAC deny list */ - WLC_E_PRUNE_MAC_NA = 4 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is not in AP's MAC allow list */ - WLC_E_PRUNE_REG_PASSV = 5 + WLC_E_PRUNE_REASON_OFFSET, /** AP not allowed due to regulatory restriction */ - WLC_E_PRUNE_SPCT_MGMT = 6 + WLC_E_PRUNE_REASON_OFFSET, /** AP does not support STA locale spectrum mgmt */ - WLC_E_PRUNE_RADAR = 7 + WLC_E_PRUNE_REASON_OFFSET, /** AP is on a radar channel of STA locale */ - WLC_E_RSN_MISMATCH = 8 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support AP's RSN */ - WLC_E_PRUNE_NO_COMMON_RATES = 9 + WLC_E_PRUNE_REASON_OFFSET, /** No rates in common with AP */ - WLC_E_PRUNE_BASIC_RATES = 10 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support all basic rates of BSS */ - WLC_E_PRUNE_CCXFAST_PREVAP = 11 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune previous AP */ - WLC_E_PRUNE_CIPHER_NA = 12 + WLC_E_PRUNE_REASON_OFFSET, /** BSS's cipher not supported */ - WLC_E_PRUNE_KNOWN_STA = 13 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a STA */ - WLC_E_PRUNE_CCXFAST_DROAM = 14 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune unqualified AP */ - WLC_E_PRUNE_WDS_PEER = 15 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a WDS peer */ - WLC_E_PRUNE_QBSS_LOAD = 16 + WLC_E_PRUNE_REASON_OFFSET, /** QBSS LOAD - AAC is too low */ - WLC_E_PRUNE_HOME_AP = 17 + WLC_E_PRUNE_REASON_OFFSET, /** prune home AP */ - WLC_E_PRUNE_AP_BLOCKED = 18 + WLC_E_PRUNE_REASON_OFFSET, /** prune blocked AP */ - WLC_E_PRUNE_NO_DIAG_SUPPORT = 19 + WLC_E_PRUNE_REASON_OFFSET, /** prune due to diagnostic mode not supported */ - - /* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ - WLC_E_SUP_OTHER = 0 + WLC_E_SUP_REASON_OFFSET, /** Other reason */ - WLC_E_SUP_DECRYPT_KEY_DATA = 1 + WLC_E_SUP_REASON_OFFSET, /** Decryption of key data failed */ - WLC_E_SUP_BAD_UCAST_WEP128 = 2 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP128 */ - WLC_E_SUP_BAD_UCAST_WEP40 = 3 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP40 */ - WLC_E_SUP_UNSUP_KEY_LEN = 4 + WLC_E_SUP_REASON_OFFSET, /** Unsupported key length */ - WLC_E_SUP_PW_KEY_CIPHER = 5 + WLC_E_SUP_REASON_OFFSET, /** Unicast cipher mismatch in pairwise key */ - WLC_E_SUP_MSG3_TOO_MANY_IE = 6 + WLC_E_SUP_REASON_OFFSET, /** WPA IE contains > 1 RSN IE in key msg 3 */ - WLC_E_SUP_MSG3_IE_MISMATCH = 7 + WLC_E_SUP_REASON_OFFSET, /** WPA IE mismatch in key message 3 */ - WLC_E_SUP_NO_INSTALL_FLAG = 8 + WLC_E_SUP_REASON_OFFSET, /** INSTALL flag unset in 4-way msg */ - WLC_E_SUP_MSG3_NO_GTK = 9 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from msg 3 */ - WLC_E_SUP_GRP_KEY_CIPHER = 10 + WLC_E_SUP_REASON_OFFSET, /** Multicast cipher mismatch in group key */ - WLC_E_SUP_GRP_MSG1_NO_GTK = 11 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from group msg 1 */ - WLC_E_SUP_GTK_DECRYPT_FAIL = 12 + WLC_E_SUP_REASON_OFFSET, /** GTK decrypt failure */ - WLC_E_SUP_SEND_FAIL = 13 + WLC_E_SUP_REASON_OFFSET, /** message send failure */ - WLC_E_SUP_DEAUTH = 14 + WLC_E_SUP_REASON_OFFSET, /** received FC_DEAUTH */ - WLC_E_SUP_WPA_PSK_TMO = 15 + WLC_E_SUP_REASON_OFFSET, /** WPA PSK 4-way handshake timeout */ - - DOT11_RC_RESERVED = 0 + WLC_E_DOT11_RC_REASON_OFFSET, /* d11 RC reserved */ - DOT11_RC_UNSPECIFIED = 1 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unspecified reason */ - DOT11_RC_AUTH_INVAL = 2 + WLC_E_DOT11_RC_REASON_OFFSET, /* Previous authentication no longer valid */ - DOT11_RC_DEAUTH_LEAVING = 3 + WLC_E_DOT11_RC_REASON_OFFSET, /* Deauthenticated because sending station is leaving (or has left) IBSS or ESS */ - DOT11_RC_INACTIVITY = 4 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated due to inactivity */ - DOT11_RC_BUSY = 5 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because AP is unable to handle all currently associated stations */ - DOT11_RC_INVAL_CLASS_2 = 6 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 2 frame received from nonauthenticated station */ - DOT11_RC_INVAL_CLASS_3 = 7 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 3 frame received from nonassociated station */ - DOT11_RC_DISASSOC_LEAVING = 8 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because sending station is leaving (or has left) BSS */ - DOT11_RC_NOT_AUTH = 9 + WLC_E_DOT11_RC_REASON_OFFSET, /* Station requesting (re)association is not * authenticated with responding station */ - DOT11_RC_BAD_PC = 10 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable power capability element */ - DOT11_RC_BAD_CHANNELS = 11 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable supported channels element */ - /* 12 is unused */ - /* XXX 13-23 are WPA/802.11i reason codes defined in proto/wpa.h */ - /* 32-39 are QSTA specific reasons added in 11e */ - DOT11_RC_UNSPECIFIED_QOS = 32 + WLC_E_DOT11_RC_REASON_OFFSET, /* unspecified QoS-related reason */ - DOT11_RC_INSUFFCIENT_BW = 33 + WLC_E_DOT11_RC_REASON_OFFSET, /* QAP lacks sufficient bandwidth */ - DOT11_RC_EXCESSIVE_FRAMES = 34 + WLC_E_DOT11_RC_REASON_OFFSET, /* excessive number of frames need ack */ - DOT11_RC_TX_OUTSIDE_TXOP = 35 + WLC_E_DOT11_RC_REASON_OFFSET, /* transmitting outside the limits of txop */ - DOT11_RC_LEAVING_QBSS = 36 + WLC_E_DOT11_RC_REASON_OFFSET, /* QSTA is leaving the QBSS (or restting) */ - DOT11_RC_BAD_MECHANISM = 37 + WLC_E_DOT11_RC_REASON_OFFSET, /* does not want to use the mechanism */ - DOT11_RC_SETUP_NEEDED = 38 + WLC_E_DOT11_RC_REASON_OFFSET, /* mechanism needs a setup */ - DOT11_RC_TIMEOUT = 39 + WLC_E_DOT11_RC_REASON_OFFSET, /* timeout */ - DOT11_RC_MAX = 23 + WLC_E_DOT11_RC_REASON_OFFSET, /* Reason codes > 23 are reserved */ - - WLC_E_REASON_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */ +typedef enum +{ + /* roam reason codes */ + WLC_E_REASON_INITIAL_ASSOC = 0, /** initial assoc */ + WLC_E_REASON_LOW_RSSI = 1, /** roamed due to low RSSI */ + WLC_E_REASON_DEAUTH = 2, /** roamed due to DEAUTH indication */ + WLC_E_REASON_DISASSOC = 3, /** roamed due to DISASSOC indication */ + WLC_E_REASON_BCNS_LOST = 4, /** roamed due to lost beacons */ + WLC_E_REASON_FAST_ROAM_FAILED = 5, /** roamed due to fast roam failure */ + WLC_E_REASON_DIRECTED_ROAM = 6, /** roamed due to request by AP */ + WLC_E_REASON_TSPEC_REJECTED = 7, /** roamed due to TSPEC rejection */ + WLC_E_REASON_BETTER_AP = 8, /** roamed due to finding better AP */ + + /* NAN sub-events comes as a reason code with event as WLC_E_NAN */ + WLC_E_NAN_EVENT_STATUS_CHG = 9, /* generated on any change in nan_mac status */ + WLC_E_NAN_EVENT_MERGE = 10, /* Merged to a NAN cluster */ + WLC_E_NAN_EVENT_STOP = 11, /* NAN stopped */ + WLC_E_NAN_EVENT_P2P = 12, /* NAN P2P EVENT */ + + /* XXX: Dont use below four events: They will be cleanup, use WL_NAN_EVENT_POST_DISC */ + WLC_E_NAN_EVENT_WINDOW_BEGIN_P2P = 13, /* Event for begin of P2P further availability window */ + WLC_E_NAN_EVENT_WINDOW_BEGIN_MESH = 14, WLC_E_NAN_EVENT_WINDOW_BEGIN_IBSS = 15, + WLC_E_NAN_EVENT_WINDOW_BEGIN_RANGING = 16, WLC_E_NAN_EVENT_POST_DISC = 17, /* Event for post discovery data */ + WLC_E_NAN_EVENT_DATA_IF_ADD = 18, /* Event for Data IF add */ + WLC_E_NAN_EVENT_DATA_PEER_ADD = 19, /* Event for peer add */ + + /* nan 2.0 */ + WLC_E_NAN_EVENT_DATA_IND = 20, /* Data Indication to Host */ + WLC_E_NAN_EVENT_DATA_CONF = 21, /* Data Response to Host */ + WLC_E_NAN_EVENT_SDF_RX = 22, /* entire service discovery frame */ + WLC_E_NAN_EVENT_DATA_END = 23, WLC_E_NAN_EVENT_BCN_RX = 24, /* received beacon payload */ + + /* prune reason codes */ + WLC_E_PRUNE_ENCR_MISMATCH = 1 + WLC_E_PRUNE_REASON_OFFSET, /** encryption mismatch */ + WLC_E_PRUNE_BCAST_BSSID = 2 + WLC_E_PRUNE_REASON_OFFSET, /** AP uses a broadcast BSSID */ + WLC_E_PRUNE_MAC_DENY = 3 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is in AP's MAC deny list */ + WLC_E_PRUNE_MAC_NA = 4 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is not in AP's MAC allow list */ + WLC_E_PRUNE_REG_PASSV = 5 + WLC_E_PRUNE_REASON_OFFSET, /** AP not allowed due to regulatory restriction */ + WLC_E_PRUNE_SPCT_MGMT = 6 + WLC_E_PRUNE_REASON_OFFSET, /** AP does not support STA locale spectrum mgmt */ + WLC_E_PRUNE_RADAR = 7 + WLC_E_PRUNE_REASON_OFFSET, /** AP is on a radar channel of STA locale */ + WLC_E_RSN_MISMATCH = 8 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support AP's RSN */ + WLC_E_PRUNE_NO_COMMON_RATES = 9 + WLC_E_PRUNE_REASON_OFFSET, /** No rates in common with AP */ + WLC_E_PRUNE_BASIC_RATES = 10 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support all basic rates of BSS */ + WLC_E_PRUNE_CCXFAST_PREVAP = 11 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune previous AP */ + WLC_E_PRUNE_CIPHER_NA = 12 + WLC_E_PRUNE_REASON_OFFSET, /** BSS's cipher not supported */ + WLC_E_PRUNE_KNOWN_STA = 13 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a STA */ + WLC_E_PRUNE_CCXFAST_DROAM = 14 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune unqualified AP */ + WLC_E_PRUNE_WDS_PEER = 15 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a WDS peer */ + WLC_E_PRUNE_QBSS_LOAD = 16 + WLC_E_PRUNE_REASON_OFFSET, /** QBSS LOAD - AAC is too low */ + WLC_E_PRUNE_HOME_AP = 17 + WLC_E_PRUNE_REASON_OFFSET, /** prune home AP */ + WLC_E_PRUNE_AP_BLOCKED = 18 + WLC_E_PRUNE_REASON_OFFSET, /** prune blocked AP */ + WLC_E_PRUNE_NO_DIAG_SUPPORT = 19 + WLC_E_PRUNE_REASON_OFFSET, /** prune due to diagnostic mode not supported */ + + /* WPA failure reason codes carried in the WLC_E_PSK_SUP event */ + WLC_E_SUP_OTHER = 0 + WLC_E_SUP_REASON_OFFSET, /** Other reason */ + WLC_E_SUP_DECRYPT_KEY_DATA = 1 + WLC_E_SUP_REASON_OFFSET, /** Decryption of key data failed */ + WLC_E_SUP_BAD_UCAST_WEP128 = 2 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP128 */ + WLC_E_SUP_BAD_UCAST_WEP40 = 3 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP40 */ + WLC_E_SUP_UNSUP_KEY_LEN = 4 + WLC_E_SUP_REASON_OFFSET, /** Unsupported key length */ + WLC_E_SUP_PW_KEY_CIPHER = 5 + WLC_E_SUP_REASON_OFFSET, /** Unicast cipher mismatch in pairwise key */ + WLC_E_SUP_MSG3_TOO_MANY_IE = 6 + WLC_E_SUP_REASON_OFFSET, /** WPA IE contains > 1 RSN IE in key msg 3 */ + WLC_E_SUP_MSG3_IE_MISMATCH = 7 + WLC_E_SUP_REASON_OFFSET, /** WPA IE mismatch in key message 3 */ + WLC_E_SUP_NO_INSTALL_FLAG = 8 + WLC_E_SUP_REASON_OFFSET, /** INSTALL flag unset in 4-way msg */ + WLC_E_SUP_MSG3_NO_GTK = 9 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from msg 3 */ + WLC_E_SUP_GRP_KEY_CIPHER = 10 + WLC_E_SUP_REASON_OFFSET, /** Multicast cipher mismatch in group key */ + WLC_E_SUP_GRP_MSG1_NO_GTK = 11 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from group msg 1 */ + WLC_E_SUP_GTK_DECRYPT_FAIL = 12 + WLC_E_SUP_REASON_OFFSET, /** GTK decrypt failure */ + WLC_E_SUP_SEND_FAIL = 13 + WLC_E_SUP_REASON_OFFSET, /** message send failure */ + WLC_E_SUP_DEAUTH = 14 + WLC_E_SUP_REASON_OFFSET, /** received FC_DEAUTH */ + WLC_E_SUP_WPA_PSK_TMO = 15 + WLC_E_SUP_REASON_OFFSET, /** WPA PSK 4-way handshake timeout */ + + DOT11_RC_RESERVED = 0 + WLC_E_DOT11_RC_REASON_OFFSET, /* d11 RC reserved */ + DOT11_RC_UNSPECIFIED = 1 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unspecified reason */ + DOT11_RC_AUTH_INVAL = 2 + WLC_E_DOT11_RC_REASON_OFFSET, /* Previous authentication no longer valid */ + DOT11_RC_DEAUTH_LEAVING = 3 + WLC_E_DOT11_RC_REASON_OFFSET, /* Deauthenticated because sending station is leaving (or has left) IBSS or ESS */ + DOT11_RC_INACTIVITY = 4 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated due to inactivity */ + DOT11_RC_BUSY = 5 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because AP is unable to handle all currently associated stations */ + DOT11_RC_INVAL_CLASS_2 = 6 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 2 frame received from nonauthenticated station */ + DOT11_RC_INVAL_CLASS_3 = 7 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 3 frame received from nonassociated station */ + DOT11_RC_DISASSOC_LEAVING = 8 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because sending station is leaving (or has left) BSS */ + DOT11_RC_NOT_AUTH = 9 + WLC_E_DOT11_RC_REASON_OFFSET, /* Station requesting (re)association is not * authenticated with responding station */ + DOT11_RC_BAD_PC = 10 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable power capability element */ + DOT11_RC_BAD_CHANNELS = 11 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable supported channels element */ + /* 12 is unused */ + /* XXX 13-23 are WPA/802.11i reason codes defined in proto/wpa.h */ + /* 32-39 are QSTA specific reasons added in 11e */ + DOT11_RC_UNSPECIFIED_QOS = 32 + WLC_E_DOT11_RC_REASON_OFFSET, /* unspecified QoS-related reason */ + DOT11_RC_INSUFFCIENT_BW = 33 + WLC_E_DOT11_RC_REASON_OFFSET, /* QAP lacks sufficient bandwidth */ + DOT11_RC_EXCESSIVE_FRAMES = 34 + WLC_E_DOT11_RC_REASON_OFFSET, /* excessive number of frames need ack */ + DOT11_RC_TX_OUTSIDE_TXOP = 35 + WLC_E_DOT11_RC_REASON_OFFSET, /* transmitting outside the limits of txop */ + DOT11_RC_LEAVING_QBSS = 36 + WLC_E_DOT11_RC_REASON_OFFSET, /* QSTA is leaving the QBSS (or restting) */ + DOT11_RC_BAD_MECHANISM = 37 + WLC_E_DOT11_RC_REASON_OFFSET, /* does not want to use the mechanism */ + DOT11_RC_SETUP_NEEDED = 38 + WLC_E_DOT11_RC_REASON_OFFSET, /* mechanism needs a setup */ + DOT11_RC_TIMEOUT = 39 + WLC_E_DOT11_RC_REASON_OFFSET, /* timeout */ + DOT11_RC_MAX = 23 + WLC_E_DOT11_RC_REASON_OFFSET, /* Reason codes > 23 are reserved */ + + WLC_E_REASON_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */ } whd_event_reason_t; -typedef enum { - WLC_E_NAN_EVENT_START = 1, /* NAN cluster started */ - WLC_E_NAN_EVENT_JOIN = 2, /* Joined to a NAN cluster */ - WLC_E_NAN_EVENT_ROLE = 3, /* Role or State changed */ - WLC_E_NAN_EVENT_SCAN_COMPLETE = 4, - WLC_E_NAN_EVENT_DISCOVERY_RESULT = 5, - WLC_E_NAN_EVENT_REPLIED = 6, - WLC_E_NAN_EVENT_TERMINATED = 7, /* the instance ID will be present in the ev data */ - WLC_E_NAN_EVENT_RECEIVE = 8 +typedef enum +{ + WLC_E_NAN_EVENT_START = 1, /* NAN cluster started */ + WLC_E_NAN_EVENT_JOIN = 2, /* Joined to a NAN cluster */ + WLC_E_NAN_EVENT_ROLE = 3, /* Role or State changed */ + WLC_E_NAN_EVENT_SCAN_COMPLETE = 4, WLC_E_NAN_EVENT_DISCOVERY_RESULT = 5, WLC_E_NAN_EVENT_REPLIED = 6, + WLC_E_NAN_EVENT_TERMINATED = 7, /* the instance ID will be present in the ev data */ + WLC_E_NAN_EVENT_RECEIVE = 8 } whd_nan_events_t; +/* Reason codes for LINK */ +#define WLC_E_LINK_BCN_LOSS 1 /** Link down because of beacon loss */ +#define WLC_E_LINK_DISASSOC 2 /** Link down because of disassoc */ +#define WLC_E_LINK_ASSOC_REC 3 /** Link down because assoc recreate failed */ +#define WLC_E_LINK_BSSCFG_DIS 4 /** Link down due to bsscfg down */ + /** * Event handler prototype definition * @@ -400,7 +405,7 @@ typedef enum { * @param[out] handler_user_data : semaphore data */ typedef void *(*whd_event_handler_t)(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); /** @endcond */ /** @@ -411,39 +416,39 @@ typedef void *(*whd_event_handler_t)(whd_interface_t ifp, const whd_event_header * @param[out] handler_user_data : semaphore data */ typedef void *(*whd_error_handler_t)(whd_driver_t whd_driver, const uint8_t *error_type, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); /** @endcond */ extern whd_result_t whd_management_set_event_handler_locally(whd_interface_t ifp, - const whd_event_num_t *event_nums, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index); + const whd_event_num_t *event_nums, + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index); extern whd_result_t whd_management_set_event_handler(whd_interface_t ifp, const whd_event_num_t *event_nums, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index); + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index); -extern uint32_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type, - whd_event_handler_t handler_func, - void *handler_user_data, uint16_t *event_index); +extern whd_result_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type, + whd_event_handler_t handler_func, + void *handler_user_data, uint16_t *event_index); -extern uint32_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index); +extern whd_result_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index); extern whd_result_t whd_set_error_handler_locally(whd_driver_t whd_driver, const uint8_t *error_nums, - whd_error_handler_t handler_func, - void *handler_user_data, uint16_t *error_index); + whd_error_handler_t handler_func, + void *handler_user_data, uint16_t *error_index); extern whd_result_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_type, - whd_error_handler_t handler_func, - void *handler_user_data, uint16_t *error_index); + whd_error_handler_t handler_func, + void *handler_user_data, uint16_t *error_index); -extern uint32_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index); +extern whd_result_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index); /** @cond */ //extern void* whd_rrm_report_handler( const whd_event_header_t* event_header, const uint8_t* event_data, void* handler_user_data ); extern void *whd_nan_scan_handler(const whd_event_header_t *event_header, const uint8_t *event_data, - void *handler_user_data); + void *handler_user_data); #define WHD_MSG_IFNAME_MAX 16 @@ -452,53 +457,74 @@ extern void *whd_nan_scan_handler(const whd_event_header_t *event_header, const #define WHD_EVENT_NOT_REGISTERED 0xFF /* Enum to index and find the entry of paricular event registered */ -typedef enum { - WHD_SCAN_EVENT_ENTRY = 0, - WHD_JOIN_EVENT_ENTRY, - WHD_AP_EVENT_ENTRY, - WHD_P2P_EVENT_ENTRY, - WHD_EVENT_ENTRY_MAX +typedef enum +{ + WHD_SCAN_EVENT_ENTRY = 0, + WHD_JOIN_EVENT_ENTRY, + WHD_AP_EVENT_ENTRY, + WHD_P2P_EVENT_ENTRY, + WHD_AUTH_EVENT_ENTRY, + WHD_EVENT_ENTRY_MAX } whd_event_entry_t; #pragma pack(1) -typedef struct whd_event_eth_hdr { - uint16_t subtype; /** Vendor specific..32769 */ - uint16_t length; - uint8_t version; /** Version is 0 */ - uint8_t oui[3]; /** OUI */ - uint16_t usr_subtype; /** user specific Data */ +typedef struct whd_event_eth_hdr +{ + uint16_t subtype; /** Vendor specific..32769 */ + uint16_t length; + uint8_t version; /** Version is 0 */ + uint8_t oui[3]; /** OUI */ + uint16_t usr_subtype; /** user specific Data */ } whd_event_eth_hdr_t; -typedef struct whd_event_ether_header { - whd_mac_t destination_address; - whd_mac_t source_address; - uint16_t ethertype; +typedef struct whd_event_ether_header +{ + whd_mac_t destination_address; + whd_mac_t source_address; + uint16_t ethertype; } whd_event_ether_header_t; -struct whd_event_msg { - uint16_t version; - uint16_t flags; /* see flags below */ - uint32_t event_type; /* Message (see below) */ - uint32_t status; /* Status code (see below) */ - uint32_t reason; /* Reason code (if applicable) */ - uint32_t auth_type; /* WLC_E_AUTH */ - uint32_t datalen; /* data buf */ - whd_mac_t addr; /* Station address (if applicable) */ - char ifname[WHD_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ - uint8_t ifidx; /* destination OS i/f index */ - uint8_t bsscfgidx; /* source bsscfg index */ +struct whd_event_msg +{ + uint16_t version; + uint16_t flags; /* see flags below */ + uint32_t event_type; /* Message (see below) */ + uint32_t status; /* Status code (see below) */ + uint32_t reason; /* Reason code (if applicable) */ + uint32_t auth_type; /* WLC_E_AUTH */ + uint32_t datalen; /* data buf */ + whd_mac_t addr; /* Station address (if applicable) */ + char ifname[WHD_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ + uint8_t ifidx; /* destination OS i/f index */ + uint8_t bsscfgidx; /* source bsscfg index */ }; /* used by driver msgs */ -typedef struct whd_event { - whd_event_ether_header_t eth; - whd_event_eth_hdr_t eth_evt_hdr; - whd_event_header_t whd_event; - /* data portion follows */ +typedef struct whd_event +{ + whd_event_ether_header_t eth; + whd_event_eth_hdr_t eth_evt_hdr; + whd_event_header_t whd_event; + /* data portion follows */ } whd_event_t; #pragma pack() +/** Event list element structure + * + * events : A pointer to a whd_event_num_t array that is terminated with a WLC_E_NONE event + * handler: A pointer to the whd_event_handler_t function that will receive the event + * handler_user_data : User provided data that will be passed to the handler when a matching event occurs + */ +typedef struct +{ + whd_bool_t event_set; + whd_event_num_t events[WHD_MAX_EVENT_SUBSCRIPTION]; + whd_event_handler_t handler; + void *handler_user_data; + uint8_t ifidx; +} event_list_elem_t; + /** @endcond */ /** @} */ diff --git a/wi-fi/whd/whd_flowring.c b/wi-fi/whd/whd_flowring.c new file mode 100644 index 00000000..602e36e8 --- /dev/null +++ b/wi-fi/whd/whd_flowring.c @@ -0,0 +1,317 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef PROTO_MSGBUF + +#include "whd_flowring.h" +#include "whd_buffer_api.h" +#include "whd_utils.h" + +#define WHD_FLOWRING_HIGH 1024 +#define WHD_FLOWRING_LOW (WHD_FLOWRING_HIGH - 256) +#define WHD_FLOWRING_INVALID_IFIDX 0xff + +#define WHD_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] * 2 + fifo + ifidx * 16) +#define WHD_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16) + +static const uint8_t whd_flowring_prio2fifo[] = +{ + 0, + 1, + 1, + 0, + 2, + 2, + 3, + 3 +}; + +static const uint8_t ALLFFMAC[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static uint8_t whd_flowring_is_tdls_mac(struct whd_flowring *flow, uint8_t mac[ETHER_ADDR_LEN]) +{ + struct whd_flowring_tdls_entry *search; + + search = flow->tdls_entry; + + while (search) + { + if (memcmp(search->mac, mac, ETHER_ADDR_LEN) == 0) + return 1; + search = search->next; + } + + return 0; +} + +uint32_t whd_flowring_lookup(struct whd_flowring *flow, uint8_t da[ETHER_ADDR_LEN], uint8_t prio, uint8_t ifidx) +{ + struct whd_flowring_hash *hash; + uint16_t hash_idx; + uint32_t i; + uint8_t found; + uint8_t sta; + uint8_t fifo; + uint8_t *mac; + + fifo = whd_flowring_prio2fifo[prio]; + sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT); + mac = da; + if ( (!sta) && (is_multicast_ether_addr(da) ) ) + { + mac = (uint8_t *)ALLFFMAC; + fifo = 0; + } + + if ( (sta) && (flow->tdls_active) && + (whd_flowring_is_tdls_mac(flow, da) ) ) + { + sta = 0; + } + + hash_idx = sta ? WHD_FLOWRING_HASH_STA(fifo, ifidx) : + WHD_FLOWRING_HASH_AP(mac, fifo, ifidx); + hash_idx &= (WHD_FLOWRING_HASHSIZE - 1); + found = 0; + hash = flow->hash; + for (i = 0; i < WHD_FLOWRING_HASHSIZE; i++) + { + if ( (sta || (memcmp(hash[hash_idx].mac, mac, ETHER_ADDR_LEN) == 0) ) && + (hash[hash_idx].fifo == fifo) && + (hash[hash_idx].ifidx == ifidx) ) + { + found = 1; + break; + } + hash_idx++; + hash_idx &= (WHD_FLOWRING_HASHSIZE - 1); + } + if (found) + return hash[hash_idx].flowid; + + return WHD_FLOWRING_INVALID_ID; +} + +uint32_t whd_flowring_create(struct whd_flowring *flow, uint8_t da[ETHER_ADDR_LEN], + uint8_t prio, uint8_t ifidx) +{ + struct whd_flowring_ring *ring; + struct whd_flowring_hash *hash; + uint16_t hash_idx; + uint32_t i; + uint8_t found; + uint8_t fifo; + uint8_t sta; + uint8_t *mac; + + fifo = whd_flowring_prio2fifo[prio]; + sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT); + mac = da; + if ( (!sta) && (is_multicast_ether_addr(da) ) ) + { + mac = (uint8_t *)ALLFFMAC; + fifo = 0; + } + + if ( (sta) && (flow->tdls_active) && + (whd_flowring_is_tdls_mac(flow, da) ) ) + { + sta = 0; + } + + hash_idx = sta ? WHD_FLOWRING_HASH_STA(fifo, ifidx) : + WHD_FLOWRING_HASH_AP(mac, fifo, ifidx); + hash_idx &= (WHD_FLOWRING_HASHSIZE - 1); + found = 0; + hash = flow->hash; + + for (i = 0; i < WHD_FLOWRING_HASHSIZE; i++) + { + if (hash[hash_idx].ifidx == WHD_FLOWRING_INVALID_IFIDX) + { + found = 1; + break; + } + hash_idx++; + hash_idx &= (WHD_FLOWRING_HASHSIZE - 1); + } + + if (found) + { + + for (i = 0; i < flow->nrofrings; i++) + { + if (flow->rings[i] == NULL) + break; + } + + if (i == flow->nrofrings) + return -1; + + ring = whd_mem_malloc(sizeof(*ring) ); + if (!ring) + return -1; + + memcpy(hash[hash_idx].mac, mac, ETHER_ADDR_LEN); + hash[hash_idx].fifo = fifo; + hash[hash_idx].ifidx = ifidx; + hash[hash_idx].flowid = i; + + ring->hash_id = hash_idx; + ring->status = RING_CLOSED; + whd_msgbuf_txflow_init(&ring->txflow_queue); + flow->rings[i] = ring; + + return i; + } + + return WHD_FLOWRING_INVALID_ID; +} + +void whd_flowring_delete(struct whd_flowring *flow, uint16_t flowid) +{ + whd_result_t result; + whd_driver_t whd_driver = flow->dev; + struct whd_flowring_ring *ring; + uint16_t hash_idx; + whd_buffer_t skb; + + ring = flow->rings[flowid]; + if (!ring) + return; + + hash_idx = ring->hash_id; + flow->hash[hash_idx].ifidx = WHD_FLOWRING_INVALID_IFIDX; + memset(flow->hash[hash_idx].mac, 0, WHD_ETHER_ADDR_LEN); + + (void)whd_msgbuf_txflow_dequeue(whd_driver, &skb, flowid); + while (skb) + { + result = whd_buffer_release(whd_driver, skb, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + (void)whd_msgbuf_txflow_dequeue(whd_driver, &skb, flowid); + } + + whd_mem_free(ring); + flow->rings[flowid] = NULL; + return; +} + +uint8_t whd_flowring_tid(struct whd_flowring *flow, uint16_t flowid) +{ + struct whd_flowring_ring *ring; + + ring = flow->rings[flowid]; + + return flow->hash[ring->hash_id].fifo; +} + +uint32_t whd_flowring_qlen(struct whd_flowring *flow, uint16_t flowid) +{ + struct whd_flowring_ring *ring; + + ring = flow->rings[flowid]; + if (!ring) + return 0; + + if (ring->status != RING_OPEN) + return 0; + + return ring->txflow_queue.npkt_in_q; +} + +uint8_t whd_flowring_ifidx_get(struct whd_flowring *flow, uint16_t flowid) +{ + struct whd_flowring_ring *ring; + uint16_t hash_idx; + + ring = flow->rings[flowid]; + hash_idx = ring->hash_id; + + return flow->hash[hash_idx].ifidx; +} + +void whd_flowring_detach(struct whd_flowring *flow) +{ + whd_driver_t whd_driver = flow->dev; + struct whd_flowring_tdls_entry *search; + struct whd_flowring_tdls_entry *remove; + uint16_t flowid; + + for (flowid = 0; flowid < flow->nrofrings; flowid++) + { + if (flow->rings[flowid]) + whd_msgbuf_delete_flowring(whd_driver, flowid); + } + + search = flow->tdls_entry; + while (search) + { + remove = search; + search = search->next; + whd_mem_free(remove); + } + whd_mem_free(flow->rings); + whd_mem_free(flow); +} + +struct whd_flowring *whd_flowring_attach(struct whd_driver *dev, uint16_t nrofrings) +{ + struct whd_flowring *flow; + uint32_t i; + + flow = whd_mem_malloc(sizeof(*flow) ); + + if (flow) + { + memset(flow, 0, sizeof(*flow)); + flow->dev = dev; + flow->nrofrings = nrofrings; + + for (i = 0; i < WHD_MAX_IFS; i++) + flow->addr_mode[i] = ADDR_INDIRECT; + for (i = 0; i < WHD_FLOWRING_HASHSIZE; i++) + flow->hash[i].ifidx = WHD_FLOWRING_INVALID_IFIDX; + + flow->rings = whd_mem_calloc(nrofrings, sizeof(*flow->rings) ); + + if (!flow->rings) + { + whd_mem_free(flow); + flow = NULL; + } + + } + + return flow; +} + +void whd_flowring_open(struct whd_flowring *flow, uint16_t flowid) +{ + struct whd_flowring_ring *ring; + + ring = flow->rings[flowid]; + if (!ring) + { + WPRINT_WHD_DEBUG( ("Ring NULL, for flowid %d\n", flowid) ); + return; + } + + ring->status = RING_OPEN; +} + +#endif /* PROTO_MSGBUF */ \ No newline at end of file diff --git a/wi-fi/whd/whd_flowring.h b/wi-fi/whd/whd_flowring.h new file mode 100644 index 00000000..e8726b1a --- /dev/null +++ b/wi-fi/whd/whd_flowring.h @@ -0,0 +1,108 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_FLOWRING_H +#define INCLUDED_WHD_FLOWRING_H + +#include "stdlib.h" +#include "whd_msgbuf.h" +#include "whd_int.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define WHD_FLOWRING_HASHSIZE 512 /* has to be 2^x */ +#define WHD_FLOWRING_INVALID_ID 0xFFFFFFFF + +enum proto_addr_mode +{ + ADDR_INDIRECT = 0, + ADDR_DIRECT +}; + +static inline int is_multicast_ether_addr(const uint8_t *a) +{ + return a[0] & 0x01; +} + +#define WHD_MAX_IFS 2 //todo_check + +struct list_head +{ + struct list_head *next, *prev; +}; + +struct whd_flowring_hash +{ + uint8_t mac[WHD_ETHER_ADDR_LEN]; + uint8_t fifo; + uint8_t ifidx; + uint16_t flowid; +}; + +enum ring_status +{ + RING_CLOSED, + RING_CLOSING, + RING_OPEN +}; + +struct whd_flowring_ring +{ + uint16_t hash_id; + uint8_t blocked; + enum ring_status status; + whd_msgbuftx_info_t txflow_queue; +}; + +struct whd_flowring_tdls_entry +{ + uint8_t mac[WHD_ETHER_ADDR_LEN]; + struct whd_flowring_tdls_entry *next; +}; + +struct whd_flowring +{ + struct whd_driver *dev; + struct whd_flowring_hash hash[WHD_FLOWRING_HASHSIZE]; + struct whd_flowring_ring **rings; + uint8_t block_lock; + enum proto_addr_mode addr_mode[WHD_MAX_IFS]; + uint16_t nrofrings; + uint8_t tdls_active; + struct whd_flowring_tdls_entry *tdls_entry; +}; + +extern uint32_t whd_flowring_lookup(struct whd_flowring *flow, uint8_t da[ETHER_ADDR_LEN], uint8_t prio, uint8_t ifidx); +extern uint32_t whd_flowring_create(struct whd_flowring *flow, uint8_t da[ETHER_ADDR_LEN], + uint8_t prio, uint8_t ifidx); +extern void whd_flowring_delete(struct whd_flowring *flow, uint16_t flowid); +extern uint8_t whd_flowring_tid(struct whd_flowring *flow, uint16_t flowid); +extern uint32_t whd_flowring_qlen(struct whd_flowring *flow, uint16_t flowid); +extern uint8_t whd_flowring_ifidx_get(struct whd_flowring *flow, uint16_t flowid); +extern void whd_flowring_detach(struct whd_flowring *flow); +extern struct whd_flowring *whd_flowring_attach(struct whd_driver *dev, uint16_t nrofrings); +extern void whd_flowring_open(struct whd_flowring *flow, uint16_t flowid); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/wi-fi/whd/whd_int.h b/wi-fi/whd/whd_int.h index 9d6b122e..142b62e3 100644 --- a/wi-fi/whd/whd_int.h +++ b/wi-fi/whd/whd_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,101 +23,143 @@ #define INCLUDED_WHD_INT_H #include "whd_thread.h" +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" #include "whd_cdc_bdc.h" +#else +#include "whd_msgbuf.h" +#endif /* PROTO_MSGBUF */ #include "whd_chip.h" #include "whd_ap.h" #include "whd_debug.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif +/* Forward declarations */ +struct whd_proto; /* device communication protocol info */ +struct whd_ram_shared_info; /* device ram shared info */ +struct whd_msgbuf; /* device msg buffer info */ + typedef struct { - uint32_t tx_total; /* Total number of TX packets sent from WHD */ - uint32_t rx_total; /* Total number of RX packets received at WHD */ - uint32_t tx_no_mem; /* Number of times WHD could not send due to no buffer */ - uint32_t rx_no_mem; /* Number of times WHD could not receive due to no buffer */ - uint32_t tx_fail; /* Number of times TX packet failed */ - uint32_t no_credit; /* Number of times WHD could not send due to no credit */ - uint32_t flow_control; /* Number of times WHD Flow control is enabled */ - uint32_t internal_host_buffer_fail_with_timeout; /* Internal host buffer get failed after timeout */ + uint32_t tx_total; /* Total number of TX packets sent from WHD */ + uint32_t rx_total; /* Total number of RX packets received at WHD */ + uint32_t tx_no_mem; /* Number of times WHD could not send due to no buffer */ + uint32_t rx_no_mem; /* Number of times WHD could not receive due to no buffer */ + uint32_t tx_fail; /* Number of times TX packet failed */ + uint32_t no_credit; /* Number of times WHD could not send due to no credit */ + uint32_t flow_control; /* Number of times WHD Flow control is enabled */ + uint32_t internal_host_buffer_fail_with_timeout; /* Internal host buffer get failed after timeout */ } whd_stats_t; #define WHD_INTERFACE_MAX 3 -typedef enum { - WHD_INVALID_ROLE = 0, - WHD_STA_ROLE = 1, /**< STA or Client Interface */ - WHD_AP_ROLE = 2, /**< softAP Interface */ - WHD_P2P_ROLE = 3, /**< P2P Interface */ +typedef enum +{ + WHD_INVALID_ROLE = 0, + WHD_STA_ROLE = 1, /**< STA or Client Interface */ + WHD_AP_ROLE = 2, /**< softAP Interface */ + WHD_P2P_ROLE = 3, /**< P2P Interface */ } whd_interface_role_t; +/* The level of bus communication with the dongle */ +typedef enum +{ + WHD_PROTO_BCDC, + WHD_PROTO_MSGBUF, +} whd_bus_protocol_type_t; -struct whd_interface { - whd_driver_t whd_driver; - uint8_t ifidx; - uint8_t bsscfgidx; - - char if_name[WHD_MSG_IFNAME_MAX]; - whd_interface_role_t role; - whd_mac_t mac_addr; - uint8_t event_reg_list[WHD_EVENT_ENTRY_MAX]; - whd_bool_t state; +struct whd_interface +{ + whd_driver_t whd_driver; + uint8_t ifidx; + uint8_t bsscfgidx; + + char if_name[WHD_MSG_IFNAME_MAX]; + whd_interface_role_t role; + whd_mac_t mac_addr; + uint8_t event_reg_list[WHD_EVENT_ENTRY_MAX]; + whd_bool_t state; }; -struct whd_bt_dev { - void *bt_data; - void (*bt_int_cb)(void *data); - uint32_t bt_use_count; - whd_bool_t intr; +struct whd_bt_dev +{ + void *bt_data; + void (*bt_int_cb)(void *data); + uint32_t bt_use_count; + whd_bool_t intr; }; -struct whd_bt_info { - uint32_t bt_buf_reg_addr; - uint32_t host_ctrl_reg_addr; - uint32_t bt_ctrl_reg_addr; - uint32_t wlan_buf_addr; +struct whd_bt_info +{ + uint32_t bt_buf_reg_addr; + uint32_t host_ctrl_reg_addr; + uint32_t bt_ctrl_reg_addr; + uint32_t wlan_buf_addr; }; -struct whd_driver { - whd_interface_t iflist[WHD_INTERFACE_MAX]; - uint8_t if2ifp[WHD_INTERFACE_MAX]; - - /* Bus variables */ - struct whd_bus_info *bus_if; - struct whd_bus_priv *bus_priv; - struct whd_bus_common_info *bus_common_info; - whd_bt_dev_t bt_dev; - - whd_buffer_funcs_t *buffer_if; - whd_netif_funcs_t *network_if; - whd_resource_source_t *resource_if; - uint8_t *aligned_addr; - - whd_bool_t bus_gspi_32bit; - - whd_thread_info_t thread_info; - whd_cdc_bdc_info_t cdc_bdc_info; - whd_error_info_t error_info; - whd_sdpcm_info_t sdpcm_info; - whd_internal_info_t internal_info; - whd_ap_int_info_t ap_info; - whd_chip_info_t chip_info; - - whd_stats_t whd_stats; - whd_country_code_t country; - - whd_ioctl_log_t whd_ioctl_log[WHD_IOCTL_LOG_SIZE]; - int whd_ioctl_log_index; +struct whd_driver +{ + whd_interface_t iflist[WHD_INTERFACE_MAX]; + uint8_t if2ifp[WHD_INTERFACE_MAX]; + + /* Bus variables */ + struct whd_bus_info *bus_if; + struct whd_bus_priv *bus_priv; + struct whd_bus_common_info *bus_common_info; + struct whd_proto *proto; + whd_bt_dev_t bt_dev; + + whd_buffer_funcs_t *buffer_if; + whd_netif_funcs_t *network_if; + whd_resource_source_t *resource_if; + uint8_t *aligned_addr; + + whd_bool_t bus_gspi_32bit; + + whd_bus_protocol_type_t proto_type; + whd_thread_info_t thread_info; + whd_error_info_t error_info; +#ifndef PROTO_MSGBUF + whd_sdpcm_info_t sdpcm_info; +#endif /* PROTO_MSGBUF */ + whd_internal_info_t internal_info; + whd_ap_int_info_t ap_info; + whd_chip_info_t chip_info; + + whd_stats_t whd_stats; + whd_country_code_t country; + + whd_ioctl_log_t whd_ioctl_log[WHD_IOCTL_LOG_SIZE]; + int whd_ioctl_log_index; + cy_semaphore_t whd_log_mutex; + + struct whd_ram_shared_info *ram_shared; + struct whd_msgbuf *msgbuf; + uint16_t (*read_ptr)(struct whd_driver *whd_driver, uint32_t mem_offset); + void (*write_ptr)(struct whd_driver *whd_driver, uint32_t mem_offset, uint16_t value); + cy_semaphore_t host_suspend_mutex; +#ifdef PROTO_MSGBUF + cy_event_t host_suspend_event_wait; +#endif + uint8_t host_trigger_suspend_flag; + uint8_t ack_d2h_suspend; /* 1: D3_ack_suspend(suspend from host), 0: Non D3_ack_suspend(suspend from WHD) */ + uint8_t dma_index_sz; +#ifdef CYCFG_ULP_SUPPORT_ENABLED + uint32_t ds_exit_in_progress; + deepsleep_cb_info_t ds_cb_info; +#endif }; whd_result_t whd_add_interface(whd_driver_t whd_driver, uint8_t bsscfgidx, uint8_t ifidx, - const char *name, whd_mac_t *mac_addr, whd_interface_t *ifpp); + const char *name, whd_mac_t *mac_addr, whd_interface_t *ifpp); whd_result_t whd_add_primary_interface(whd_driver_t whd_driver, whd_interface_t *ifpp); whd_interface_t whd_get_primary_interface(whd_driver_t whd_driver); +whd_interface_t whd_get_interface(whd_driver_t whd_driver, uint8_t ifidx); #ifdef __cplusplus } /* extern "C" */ diff --git a/wi-fi/whd/whd_logging.c b/wi-fi/whd/whd_logging.c index 87269139..8727b6db 100644 --- a/wi-fi/whd/whd_logging.c +++ b/wi-fi/whd/whd_logging.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,79 +24,88 @@ #ifndef LOGGING_BUFFER_SIZE #error LOGGING_BUFFER_SIZE is not defined -#endif /* LOGGING_BUFFER_SIZE */ +#endif /* LOGGING_BUFFER_SIZE */ whd_logging_t logbuf; int whd_buffer_printf(const char *format, ...) { - int potential_num_written = 0; - va_list args; - va_start(args, format); + int potential_num_written = 0; + va_list args; + va_start (args, format); - potential_num_written = vsnprintf(&(logbuf.buffer[logbuf.buffer_write]), - (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write)) + 1, format, args); + potential_num_written = vsnprintf (&(logbuf.buffer[logbuf.buffer_write]), + (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) + 1, format, args); - if (potential_num_written > (int)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write))) { - /* full print did not fit in buffer - wipe what was just written + if (potential_num_written > (int)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) ) + { + /* full print did not fit in buffer - wipe what was just written and reprint at start of buffer */ - memset(&(logbuf.buffer[logbuf.buffer_write]), 0xf, (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write))); - - logbuf.buffer_write = 0; - potential_num_written = vsnprintf(&(logbuf.buffer[logbuf.buffer_write]), - (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write)) + 1, format, args); - - logbuf.buffer_write += (unsigned)potential_num_written; - logbuf.buffer_write %= LOGGING_BUFFER_SIZE; - - if (logbuf.roll_over) - logbuf.over_write = WHD_TRUE; - - logbuf.roll_over = WHD_TRUE; - - if ((logbuf.roll_over) && (logbuf.buffer_read < (logbuf.buffer_write))) { - logbuf.buffer_read = logbuf.buffer_write; - } - if (logbuf.over_write && (logbuf.buffer_read != (logbuf.buffer_write))) { - logbuf.buffer_read = (logbuf.buffer_write); - } - } - else { - logbuf.buffer_write += (unsigned)potential_num_written; - - if ((logbuf.buffer_write) >= LOGGING_BUFFER_SIZE) { - logbuf.buffer_write %= LOGGING_BUFFER_SIZE; - - if (logbuf.roll_over) - logbuf.over_write = WHD_TRUE; - - logbuf.roll_over = WHD_TRUE; - } - - if (logbuf.roll_over && (logbuf.buffer_read < logbuf.buffer_write)) { - logbuf.buffer_read = logbuf.buffer_write; - } - if (logbuf.over_write && (logbuf.buffer_read != logbuf.buffer_write)) { - logbuf.buffer_read = logbuf.buffer_write; - } - } - - va_end(args); - return potential_num_written; + memset(&(logbuf.buffer[logbuf.buffer_write]), 0xf, (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) ); + + logbuf.buffer_write = 0; + potential_num_written = vsnprintf (&(logbuf.buffer[logbuf.buffer_write]), + (size_t)(LOGGING_BUFFER_SIZE - (logbuf.buffer_write) ) + 1, format, args); + + logbuf.buffer_write += (unsigned)potential_num_written; + logbuf.buffer_write %= LOGGING_BUFFER_SIZE; + + if (logbuf.roll_over) + logbuf.over_write = WHD_TRUE; + + logbuf.roll_over = WHD_TRUE; + + if ( (logbuf.roll_over) && (logbuf.buffer_read < (logbuf.buffer_write) ) ) + { + logbuf.buffer_read = logbuf.buffer_write; + } + if (logbuf.over_write && (logbuf.buffer_read != (logbuf.buffer_write) ) ) + { + logbuf.buffer_read = (logbuf.buffer_write); + } + } + else + { + logbuf.buffer_write += (unsigned)potential_num_written; + + if ( (logbuf.buffer_write) >= LOGGING_BUFFER_SIZE ) + { + logbuf.buffer_write %= LOGGING_BUFFER_SIZE; + + if (logbuf.roll_over) + logbuf.over_write = WHD_TRUE; + + logbuf.roll_over = WHD_TRUE; + } + + if (logbuf.roll_over && (logbuf.buffer_read < logbuf.buffer_write) ) + { + logbuf.buffer_read = logbuf.buffer_write; + } + if (logbuf.over_write && (logbuf.buffer_read != logbuf.buffer_write) ) + { + logbuf.buffer_read = logbuf.buffer_write; + } + } + + va_end (args); + return potential_num_written; } void whd_print_logbuffer(void) { - while (logbuf.roll_over || logbuf.over_write || (logbuf.buffer_read != logbuf.buffer_write)) { - logbuf.roll_over = logbuf.over_write = WHD_FALSE; - - while (logbuf.buffer[logbuf.buffer_read] == 0xf) { - logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE; - } - - putchar(logbuf.buffer[logbuf.buffer_read]); - logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE; - } + while (logbuf.roll_over || logbuf.over_write || (logbuf.buffer_read != logbuf.buffer_write) ) + { + logbuf.roll_over = logbuf.over_write = WHD_FALSE; + + while (logbuf.buffer[logbuf.buffer_read] == 0xf) + { + logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE; + } + + putchar(logbuf.buffer[logbuf.buffer_read]); + logbuf.buffer_read = (logbuf.buffer_read + 1) % LOGGING_BUFFER_SIZE; + } } #endif /* ifdef WHD_LOGGING_BUFFER_ENABLE */ diff --git a/wi-fi/whd/whd_management.c b/wi-fi/whd/whd_management.c index 98682faa..572c7e5c 100644 --- a/wi-fi/whd/whd_management.c +++ b/wi-fi/whd/whd_management.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,7 +20,6 @@ * */ -#include #include #include "bus_protocols/whd_bus_common.h" #include "bus_protocols/whd_bus_protocol_interface.h" @@ -28,22 +27,30 @@ #include "whd_events_int.h" #include "whd_int.h" #include "whd_chip.h" +#include "whd_utils.h" +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" +#endif /* PROTO_MSGBUF */ #include "whd_wifi_api.h" #include "whd_clm.h" #include "whd_wlioctl.h" #include "whd_types_int.h" #include "whd_chip_constants.h" +#include "whd_proto.h" /****************************************************** * Constants ******************************************************/ -#define MAX_POST_SET_COUNTRY_RETRY 3 +#define MAX_POST_SET_COUNTRY_RETRY 3 -#define MINIMUM_WHD_STACK_SIZE (1024 + 1200 + 2500) +#define MINIMUM_WHD_STACK_SIZE (1024 + 1200 + 2500) -#define DEFAULT_PM2_SLEEP_RET_TIME 200 +#define DEFAULT_PM2_SLEEP_RET_TIME 200 + +#ifdef PROTO_MSGBUF +#define DMA_ALLOC_SIZE (40000) +#endif /****************************************************** * Static Variables ******************************************************/ @@ -52,148 +59,184 @@ * Function definitions ******************************************************/ whd_result_t whd_management_wifi_platform_init(whd_driver_t whd_driver, whd_country_code_t country, - whd_bool_t resume_after_deep_sleep); + whd_bool_t resume_after_deep_sleep); void whd_wifi_bus_irq_handle(void *handler_arg, uint32_t event); whd_interface_t whd_get_primary_interface(whd_driver_t whd_driver) { - if (whd_driver->iflist[0] != NULL) { - return whd_driver->iflist[0]; - } - return NULL; + if (whd_driver->iflist[0] != NULL) + { + return whd_driver->iflist[0]; + } + return NULL; } -whd_result_t whd_add_interface(whd_driver_t whd_driver, uint8_t bsscfgidx, uint8_t ifidx, - const char *name, whd_mac_t *mac_addr, whd_interface_t *ifpp) +whd_interface_t whd_get_interface(whd_driver_t whd_driver, uint8_t ifidx) { - whd_interface_t ifp; - - if (!whd_driver || !ifpp) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } + if (whd_driver->iflist[ifidx] != NULL) + { + return whd_driver->iflist[ifidx]; + } + return NULL; +} - if (bsscfgidx < WHD_INTERFACE_MAX) { - if (whd_driver->iflist[bsscfgidx] != NULL) { - *ifpp = whd_driver->iflist[bsscfgidx]; - return WHD_SUCCESS; - } - - if ((ifp = (whd_interface_t)malloc(sizeof(struct whd_interface))) != NULL) { - memset(ifp, 0, (sizeof(struct whd_interface))); - *ifpp = ifp; - ifp->whd_driver = whd_driver; - - /* Add a interface name */ - /* strncpy doesn't terminate with null if the src string is long */ - ifp->if_name[WHD_MSG_IFNAME_MAX - 1] = '\0'; - strncpy(ifp->if_name, name, sizeof(ifp->if_name) - 1); - memset(ifp->event_reg_list, WHD_EVENT_NOT_REGISTERED, sizeof(ifp->event_reg_list)); - /* Primary interface takes 0 as default */ - ifp->ifidx = ifidx; - ifp->bsscfgidx = bsscfgidx; - - if (mac_addr != NULL) - memcpy(ifp->mac_addr.octet, mac_addr->octet, sizeof(whd_mac_t)); - else - memset(ifp->mac_addr.octet, 0, sizeof(whd_mac_t)); - - whd_driver->iflist[bsscfgidx] = ifp; - whd_driver->if2ifp[ifidx] = bsscfgidx; - } - else { - return WHD_MALLOC_FAILURE; - } - - return WHD_SUCCESS; - } - return WHD_INVALID_INTERFACE; +whd_result_t whd_add_interface(whd_driver_t whd_driver, uint8_t bsscfgidx, uint8_t ifidx, + const char *name, whd_mac_t *mac_addr, whd_interface_t *ifpp) +{ + whd_interface_t ifp; + + if (!whd_driver || !ifpp) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + if (bsscfgidx < WHD_INTERFACE_MAX) + { + if (whd_driver->iflist[bsscfgidx] != NULL) + { + *ifpp = whd_driver->iflist[bsscfgidx]; + return WHD_SUCCESS; + } + + if ( (ifp = (whd_interface_t)whd_mem_malloc(sizeof(struct whd_interface) ) ) != NULL ) + { + memset(ifp, 0, (sizeof(struct whd_interface) ) ); + *ifpp = ifp; + ifp->whd_driver = whd_driver; + + /* Add a interface name */ + /* strncpy doesn't terminate with null if the src string is long */ + ifp->if_name[WHD_MSG_IFNAME_MAX - 1] = '\0'; + strncpy(ifp->if_name, name, sizeof(ifp->if_name) - 1); + memset(ifp->event_reg_list, WHD_EVENT_NOT_REGISTERED, sizeof(ifp->event_reg_list) ); + /* Primary interface takes 0 as default */ + ifp->ifidx = ifidx; + ifp->bsscfgidx = bsscfgidx; + + if (mac_addr != NULL) + memcpy(ifp->mac_addr.octet, mac_addr->octet, sizeof(whd_mac_t) ); + else + memset(ifp->mac_addr.octet, 0, sizeof(whd_mac_t) ); + + whd_driver->iflist[bsscfgidx] = ifp; + whd_driver->if2ifp[ifidx] = bsscfgidx; + } + else + { + return WHD_MALLOC_FAILURE; + } + + return WHD_SUCCESS; + } + return WHD_INVALID_INTERFACE; } whd_result_t whd_add_primary_interface(whd_driver_t whd_driver, whd_interface_t *ifpp) { - return whd_add_interface(whd_driver, 0, 0, "wlan0", NULL, ifpp); + return whd_add_interface(whd_driver, 0, 0, "wlan0", NULL, ifpp); } -uint32_t whd_add_secondary_interface(whd_driver_t whd_driver, whd_mac_t *mac_addr, whd_interface_t *ifpp) +whd_result_t whd_add_secondary_interface(whd_driver_t whd_driver, whd_mac_t *mac_addr, whd_interface_t *ifpp) { - return whd_add_interface(whd_driver, 1, 1, "wlan1", mac_addr, ifpp); + return whd_add_interface(whd_driver, 1, 1, "wlan1", mac_addr, ifpp); } -uint32_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_init_config, - whd_resource_source_t *resource_ops, whd_buffer_funcs_t *buffer_ops, - whd_netif_funcs_t *network_ops) +whd_result_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_init_config, + whd_resource_source_t *resource_ops, whd_buffer_funcs_t *buffer_ops, + whd_netif_funcs_t *network_ops) { - whd_driver_t whd_drv; - - if (!whd_driver_ptr || !buffer_ops || !network_ops || !resource_ops || !whd_init_config) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - if (whd_init_config->thread_stack_size < MINIMUM_WHD_STACK_SIZE) { - WPRINT_WHD_INFO(("Stack size is less than minimum stack size required.\n")); - return WHD_WLAN_BUFTOOSHORT; - } - - if ((whd_drv = (whd_driver_t)malloc(sizeof(struct whd_driver))) != NULL) { - memset(whd_drv, 0, sizeof(struct whd_driver)); - *whd_driver_ptr = whd_drv; - whd_drv->buffer_if = buffer_ops; - whd_drv->network_if = network_ops; - whd_drv->resource_if = resource_ops; - whd_bus_common_info_init(whd_drv); - whd_thread_info_init(whd_drv, whd_init_config); - whd_cdc_bdc_info_init(whd_drv); - whd_internal_info_init(whd_drv); - whd_ap_info_init(whd_drv); - //whd_wifi_sleep_info_init(whd_drv); - whd_wifi_chip_info_init(whd_drv); - - whd_drv->bus_gspi_32bit = WHD_FALSE; - - if (whd_init_config->country == 0) - whd_drv->country = WHD_COUNTRY_UNITED_STATES; - else - whd_drv->country = whd_init_config->country; - } - else { - return WHD_MALLOC_FAILURE; - } - return WHD_SUCCESS; + whd_driver_t whd_drv; + + if (!whd_driver_ptr || !buffer_ops || !network_ops || !resource_ops || !whd_init_config) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + if (whd_init_config->thread_stack_size < MINIMUM_WHD_STACK_SIZE) + { + WPRINT_WHD_INFO( ("Stack size is less than minimum stack size required.\n") ); + return WHD_WLAN_BUFTOOSHORT; + } + + if ( (whd_drv = (whd_driver_t)whd_mem_malloc(sizeof(struct whd_driver) ) ) != NULL ) + { + memset(whd_drv, 0, sizeof(struct whd_driver) ); + *whd_driver_ptr = whd_drv; + whd_drv->buffer_if = buffer_ops; + whd_drv->network_if = network_ops; + whd_drv->resource_if = resource_ops; + whd_bus_common_info_init(whd_drv); + whd_thread_info_init(whd_drv, whd_init_config); + whd_internal_info_init(whd_drv); + whd_ap_info_init(whd_drv); + //whd_wifi_sleep_info_init(whd_drv); + whd_wifi_chip_info_init(whd_drv); + +#ifdef PROTO_MSGBUF + /* Initialize pool for WLAN M2M DMA to access, WHD has to request pool memory + and open the access for WLAN through APIs(Secure Call in BTFW)*/ + whd_dmapool_init(DMA_ALLOC_SIZE); +#endif + + whd_drv->bus_gspi_32bit = WHD_FALSE; + + if (whd_init_config->country == 0) + whd_drv->country = WHD_COUNTRY_UNITED_STATES; + else + whd_drv->country = whd_init_config->country; + } + else + { + return WHD_MALLOC_FAILURE; + } + return WHD_SUCCESS; } -uint32_t whd_deinit(whd_interface_t ifp) +whd_result_t whd_deinit(whd_interface_t ifp) { - uint8_t i; - whd_driver_t whd_driver; + uint8_t i; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + whd_internal_info_t *internal_info = &whd_driver->internal_info; + wifi_console_t *c = internal_info->c; + c = &internal_info->console; - if (whd_driver->internal_info.whd_wlan_status.state != WLAN_OFF) { - WPRINT_WHD_ERROR(("Could not deinit whd because wifi power is on\n")); - return WHD_WLAN_NOTDOWN; - } + if (whd_driver->internal_info.whd_wlan_status.state != WLAN_OFF) + { + WPRINT_WHD_ERROR( ("Could not deinit whd because wifi power is on\n") ); + return WHD_WLAN_NOTDOWN; + } if ((whd_driver->bus_priv != NULL) || (whd_driver->bus_if != NULL)) { WPRINT_WHD_ERROR(("Could not deinit whd because bus is attached\n")); return WHD_WLAN_NOTDOWN; } - for (i = 0; i < WHD_INTERFACE_MAX; i++) { - if (whd_driver->iflist[i] != NULL) { - free(whd_driver->iflist[i]); - whd_driver->iflist[i] = NULL; - } - } + for (i = 0; i < WHD_INTERFACE_MAX; i++) + { + if (whd_driver->iflist[i] != NULL) + { + whd_mem_free(whd_driver->iflist[i]); + whd_driver->iflist[i] = NULL; + } + } + + /* Freeing the buffer allocated to read logs (whd_wifi_read_wlan_log_unsafe) */ + if (c->buf != NULL) + { + whd_mem_free(c->buf); + } - whd_cdc_bdc_info_deinit(whd_driver); - whd_bus_common_info_deinit(whd_driver); - free(whd_driver); + whd_internal_info_deinit(whd_driver); + whd_bus_common_info_deinit(whd_driver); + whd_mem_free(whd_driver); - return WHD_SUCCESS; + return WHD_SUCCESS; } /** @@ -209,37 +252,43 @@ uint32_t whd_deinit(whd_interface_t ifp) */ whd_result_t whd_management_wifi_platform_init(whd_driver_t whd_driver, whd_country_code_t country, - whd_bool_t resume_after_deep_sleep) + whd_bool_t resume_after_deep_sleep) { - whd_result_t retval; + whd_result_t retval; - whd_driver->internal_info.whd_wlan_status.country_code = country; + whd_driver->internal_info.whd_wlan_status.country_code = country; - if (resume_after_deep_sleep == WHD_TRUE) { - retval = (whd_result_t)whd_bus_resume_after_deep_sleep(whd_driver); - } - else { - whd_bus_init_stats(whd_driver); - retval = (whd_result_t)whd_bus_init(whd_driver); - } + if (resume_after_deep_sleep == WHD_TRUE) + { + retval = ( whd_result_t )whd_bus_resume_after_deep_sleep(whd_driver); + } + else + { + whd_bus_init_stats(whd_driver); + retval = ( whd_result_t )whd_bus_init(whd_driver); + } - if (retval != WHD_SUCCESS) { - /* May have been due to user abort */ - WPRINT_WHD_INFO(("Could not initialize bus\n")); - return retval; - } + if (retval != WHD_SUCCESS) + { + /* May have been due to user abort */ + WPRINT_WHD_INFO( ("Could not initialize bus\n") ); + return retval; + } - /* WLAN device is now powered up. Change state from OFF to DOWN */ - whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; + CHECK_RETURN(whd_proto_attach(whd_driver) ); + /* WLAN device is now powered up. Change state from OFF to DOWN */ + whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; - retval = whd_thread_init(whd_driver); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not initialize WHD thread\n")); - return retval; - } - return WHD_SUCCESS; + retval = whd_thread_init(whd_driver); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not initialize WHD thread\n") ); + return retval; + } + + return WHD_SUCCESS; } /** @@ -251,89 +300,110 @@ whd_result_t whd_management_wifi_platform_init(whd_driver_t whd_driver, whd_coun * * @return WHD_SUCCESS if initialization is successful, error code otherwise */ -uint32_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp) +whd_result_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp) { - wl_country_t *country_struct; - uint32_t *ptr; - whd_result_t retval; - whd_buffer_t buffer; - uint8_t *event_mask; - uint32_t *data; - uint32_t counter; - whd_interface_t ifp; - uint16_t wlan_chip_id = 0; - - if (!whd_driver || !ifpp) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - - if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) { - return WHD_SUCCESS; - } - - whd_init_stats(whd_driver); + wl_country_t *country_struct; + uint32_t *ptr; + whd_result_t retval; + whd_buffer_t buffer; + uint8_t *event_mask; + uint32_t *data; + uint32_t counter; + whd_interface_t ifp; + uint16_t wlan_chip_id = 0; + + if (!whd_driver || !ifpp) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) + { + return WHD_SUCCESS; + } + + whd_init_stats(whd_driver); whd_add_primary_interface(whd_driver, ifpp); ifp = *ifpp; - retval = whd_management_wifi_platform_init(whd_driver, whd_driver->country, WHD_FALSE); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_INFO(("Could not initialize wifi platform\n")); - return retval; - } + retval = whd_management_wifi_platform_init(whd_driver, whd_driver->country, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_INFO( ("Could not initialize wifi platform\n") ); + return retval; + } /* Download blob file if exists */ retval = whd_process_clm_data(ifp); if (retval != WHD_SUCCESS) { - WPRINT_MACRO(("****************************************************\n" + WPRINT_ERROR(("****************************************************\n" "** ERROR: WLAN: could not download clm_blob file\n" "** FATAL ERROR: system unusable, CLM blob file not found or corrupted.\n" "****************************************************\n")); return retval; } - retval = whd_bus_share_bt_init(whd_driver); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_INFO(("Shared bus for bt is fail\n")); - } - /* Turn off SDPCM TX Glomming */ - /* Note: This is only required for later chips. +#ifndef PROTO_MSGBUF + retval = whd_bus_share_bt_init(whd_driver); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_INFO( ("Shared bus for bt is fail\n") ); + } +#endif + + /* Get FW Capability */ + retval = whd_wifi_read_fw_capabilities(ifp); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_INFO( ("Get FW Capabilities Fail\n") ); + } + +#ifndef PROTO_MSGBUF /* This is needed for cdc/bcd - sdpcm protocol */ + /* Turn off SDPCM TX Glomming */ + /* Note: This is only required for later chips. * The 4319 has glomming off by default however the 43362 has it on by default. */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_TX_GLOM); - if (data == NULL) { - whd_assert("Could not get buffer for IOVAR", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - *data = 0; - retval = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - if ((retval != WHD_SUCCESS) && (retval != WHD_WLAN_UNSUPPORTED)) { - /* Note: System may time out here if bus interrupts are not working properly */ - WPRINT_WHD_ERROR(("Could not turn off TX glomming\n")); - return retval; - } - - /* Turn APSTA on */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(*data), IOVAR_STR_APSTA); - if (data == NULL) { - whd_assert("Could not get buffer for IOVAR", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - *data = htod32((uint32_t)1); - /* This will fail on manufacturing test build since it does not have APSTA available */ - retval = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - if (retval == WHD_WLAN_UNSUPPORTED) { - WPRINT_WHD_DEBUG(("Firmware does not support APSTA\n")); - } - else if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not turn on APSTA\n")); - return retval; - } - - /* Send set country command */ - /* This is the first time that the WLAN chip is required to respond + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)4, IOVAR_STR_TX_GLOM); + if (data == NULL) + { + whd_assert("Could not get buffer for IOVAR", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + *data = 0; + retval = whd_proto_set_iovar(ifp, buffer, 0); + if ( (retval != WHD_SUCCESS) && (retval != WHD_WLAN_UNSUPPORTED) ) + { + /* Note: System may time out here if bus interrupts are not working properly */ + WPRINT_WHD_ERROR( ("Could not turn off TX glomming\n") ); + return retval; + } +#endif + + /* Turn APSTA on */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(*data), IOVAR_STR_APSTA); + if (data == NULL) + { + whd_assert("Could not get buffer for IOVAR", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + *data = htod32( (uint32_t)1 ); + /* This will fail on manufacturing test build since it does not have APSTA available */ + retval = whd_proto_set_iovar(ifp, buffer, 0); + if (retval == WHD_WLAN_UNSUPPORTED) + { + WPRINT_WHD_DEBUG( ("Firmware does not support APSTA\n") ); + } + else if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not turn on APSTA\n") ); + return retval; + } + + /* Send set country command */ + /* This is the first time that the WLAN chip is required to respond * in it's normal run mode. * If you are porting a new system and it stalls here, it could * be one of the following problems: @@ -343,89 +413,133 @@ uint32_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp) * */ - country_struct = (wl_country_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(wl_country_t), - IOVAR_STR_COUNTRY); - if (country_struct == NULL) { - whd_assert("Could not get buffer for IOCTL", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - memset(country_struct, 0, sizeof(wl_country_t)); - - ptr = (uint32_t *)country_struct->ccode; - *ptr = (uint32_t)whd_driver->internal_info.whd_wlan_status.country_code & 0x0000ffff; - ptr = (uint32_t *)country_struct->country_abbrev; - *ptr = (uint32_t)whd_driver->internal_info.whd_wlan_status.country_code & 0x0000ffff; - country_struct->rev = (int32_t)((whd_driver->internal_info.whd_wlan_status.country_code & 0xffff0000) >> 16); - - /* if regrev is 0 then set regrev to -1 so the FW will use any NVRAM/OTP configured aggregate + country_struct = (wl_country_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(wl_country_t), + IOVAR_STR_COUNTRY); + if (country_struct == NULL) + { + whd_assert("Could not get buffer for IOCTL", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + memset(country_struct, 0, sizeof(wl_country_t) ); + + ptr = (uint32_t *)country_struct->ccode; + *ptr = (uint32_t)whd_driver->internal_info.whd_wlan_status.country_code & 0x0000ffff; + ptr = (uint32_t *)country_struct->country_abbrev; + *ptr = (uint32_t)whd_driver->internal_info.whd_wlan_status.country_code & 0x0000ffff; + country_struct->rev = (int32_t)( (whd_driver->internal_info.whd_wlan_status.country_code & 0xffff0000) >> 16 ); + + /* if regrev is 0 then set regrev to -1 so the FW will use any NVRAM/OTP configured aggregate * to choose the regrev. If there is no aggregate configured then the FW will try to use regrev 0. */ - if (country_struct->rev == 0) { - country_struct->rev = (int32_t)htod32(-1); - } - retval = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - if (retval != WHD_SUCCESS) { - /* Could not set wifi country */ - WPRINT_WHD_ERROR(("Could not set Country code\n")); - return retval; - } - - /* NOTE: The set country command requires time to process on the WLAN firmware and + if (country_struct->rev == 0) + { + country_struct->rev = (int32_t)htod32(-1); + } + retval = whd_proto_set_iovar(ifp, buffer, 0); + if (retval != WHD_SUCCESS) + { + /* Could not set wifi country */ + WPRINT_WHD_ERROR( ("Could not set Country code\n") ); + return retval; + } + + /* NOTE: The set country command requires time to process on the WLAN firmware and * the following IOCTL may fail on initial attempts therefore we try a few times */ - /* Set the event mask, indicating initially we do not want any asynchronous events */ - for (counter = 0, retval = WHD_PENDING; retval != WHD_SUCCESS && counter < (uint32_t)MAX_POST_SET_COUNTRY_RETRY; - ++counter) { - event_mask = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)WL_EVENTING_MASK_LEN, - IOVAR_STR_EVENT_MSGS); - if (event_mask == NULL) { - whd_assert("Could not get buffer for IOVAR", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); - retval = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - } - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not set Event mask\n")); - return retval; - } - - /* Send UP command */ - CHECK_RETURN(whd_wifi_set_up(ifp)); - - wlan_chip_id = whd_chip_get_chip_id(whd_driver); - /* WAR: Disable WLAN PM/mpc for 43907 low power issue */ - if ((wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907)) { - retval = whd_wifi_disable_powersave(ifp); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to disable PM for 43907\n")); - return retval; - } - retval = whd_wifi_set_iovar_value(ifp, IOVAR_STR_MPC, 0); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to disable mpc for 43907\n")); - return retval; - } - } - else { - whd_wifi_enable_powersave_with_throughput(ifp, DEFAULT_PM2_SLEEP_RET_TIME); - } - - /* Set the GMode */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - if (data == NULL) { - whd_assert("Could not get buffer for IOCTL", 0 != 0); - return WHD_BUFFER_ALLOC_FAIL; - } - *data = htod32((uint32_t)GMODE_AUTO); - retval = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_GMODE, buffer, 0); - if (retval != WHD_SUCCESS) { - /* Note: System may time out here if bus interrupts are not working properly */ - WPRINT_WHD_ERROR(("Error setting gmode\n")); - return retval; - } - - return WHD_SUCCESS; + /* Set the event mask, indicating initially we do not want any asynchronous events */ + for (counter = 0, retval = WHD_PENDING; retval != WHD_SUCCESS && counter < (uint32_t)MAX_POST_SET_COUNTRY_RETRY; + ++counter) + { + event_mask = (uint8_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)WL_EVENTING_MASK_LEN, + IOVAR_STR_EVENT_MSGS); + if (event_mask == NULL) + { + whd_assert("Could not get buffer for IOVAR", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN); + retval = whd_proto_set_iovar(ifp, buffer, 0); + } + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not set Event mask\n") ); + return retval; + } + + /* Send UP command */ + CHECK_RETURN(whd_wifi_set_up(ifp) ); + + if (whd_driver->chip_info.fwcap_flags & (1 << WHD_FWCAP_OFFLOADS) ) + { + retval = whd_wifi_offload_config(ifp, OFFLOAD_FEATURE, 0); + if (retval != WHD_SUCCESS) + { + /* Could not initialization offload config */ + WPRINT_WHD_ERROR( ("Could not init offload config\n") ); + return retval; + } + } + + wlan_chip_id = whd_chip_get_chip_id(whd_driver); + /* WAR: Disable WLAN PM/mpc for 43907 low power issue */ + if ( (wlan_chip_id == 43909) || (wlan_chip_id == 43907) || (wlan_chip_id == 54907) ) + { + retval = whd_wifi_disable_powersave(ifp); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to disable PM for 43907\n") ); + return retval; + } + retval = whd_wifi_set_iovar_value(ifp, IOVAR_STR_MPC, 0); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to disable mpc for 43907\n") ); + return retval; + } + } +#ifdef PROTO_MSGBUF /* To be reviewed once power save is done for H1-CP */ + else if((wlan_chip_id == 55500) || (wlan_chip_id == 55900)) + { + retval = whd_wifi_disable_powersave(ifp); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to disable PM for CP\n") ); + return retval; + } + } +#endif + else + { + whd_wifi_enable_powersave_with_throughput(ifp, DEFAULT_PM2_SLEEP_RET_TIME); + } + +#ifdef CYCFG_ULP_SUPPORT_ENABLED + /* Configuring OOB mode in fw */ + if(wlan_chip_id == 43022) + { + CHECK_RETURN_IGNORE(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ULP_HOST_INTR_MODE, ULP_OOB_INTR_MODE)); + } +#endif + +#ifndef PROTO_MSGBUF + /* Set the GMode */ + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + if (data == NULL) + { + whd_assert("Could not get buffer for IOCTL", 0 != 0); + return WHD_BUFFER_ALLOC_FAIL; + } + *data = htod32( (uint32_t)GMODE_AUTO ); + retval = whd_proto_set_ioctl(ifp, WLC_SET_GMODE, buffer, 0); + if (retval != WHD_SUCCESS) + { + /* Note: System may time out here if bus interrupts are not working properly */ + WPRINT_WHD_ERROR( ("Error setting gmode\n") ); + return retval; + } +#endif + + return WHD_SUCCESS; } /** @@ -439,36 +553,40 @@ uint32_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp) * * @return WHD_SUCCESS if deinitialization is successful, error code otherwise */ -uint32_t whd_wifi_off(whd_interface_t ifp) +whd_result_t whd_wifi_off(whd_interface_t ifp) { - whd_result_t retval; - whd_driver_t whd_driver; + whd_result_t retval; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; - if (whd_driver->internal_info.whd_wlan_status.state == WLAN_OFF) { - return WHD_SUCCESS; - } + whd_driver = ifp->whd_driver; + if (whd_driver->internal_info.whd_wlan_status.state == WLAN_OFF) + { + return WHD_SUCCESS; + } /* Set wlc down before turning off the device */ /* CHECK_RETURN(...) removed due to a bug: - * If `whd_wifi_set_ioctl_buffer` fails, then `whd_thread_quit` is not called, - * `whd_driver` is freed while used by `whd_thread_func`, what causes SEGFAULT. - */ - whd_wifi_set_ioctl_buffer(ifp, WLC_DOWN, NULL, 0); + * If `whd_wifi_set_ioctl_buffer` fails, then `whd_thread_quit` is not called, + * `whd_driver` is freed while used by `whd_thread_func`, what causes SEGFAULT. + */ + (void)whd_wifi_set_ioctl_buffer(ifp, WLC_DOWN, NULL, 0); whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; - /* Disable SDIO/SPI interrupt */ - whd_bus_irq_enable(whd_driver, WHD_FALSE); - whd_thread_quit(whd_driver); + /* Disable SDIO/SPI interrupt */ + whd_bus_irq_enable(whd_driver, WHD_FALSE); + whd_thread_quit(whd_driver); - retval = whd_bus_deinit(whd_driver); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_DEBUG(("Error de-initializing bus\n")); - return retval; - } + whd_proto_detach(whd_driver); + + retval = whd_bus_deinit(whd_driver); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("Error de-initializing bus\n") ); + return retval; + } - whd_driver->internal_info.whd_wlan_status.state = WLAN_OFF; - return WHD_SUCCESS; + whd_driver->internal_info.whd_wlan_status.state = WLAN_OFF; + return WHD_SUCCESS; } diff --git a/wi-fi/whd/whd_msgbuf.h b/wi-fi/whd/whd_msgbuf.h new file mode 100644 index 00000000..a02c95e7 --- /dev/null +++ b/wi-fi/whd/whd_msgbuf.h @@ -0,0 +1,415 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_WHD_MSGBUF_H +#define INCLUDED_WHD_MSGBUF_H + +#include "whd.h" +#include "whd_events_int.h" +#include "whd_network_types.h" +#include "whd_types_int.h" +#include "whd_wlioctl.h" +#include "whd_commonring.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/****************************************************** +* Constants +******************************************************/ +#define IOCTL_OFFSET (sizeof(whd_buffer_header_t) + 12 + 16) + +#define DATA_AFTER_HEADER(x) ( (void *)(&x[1]) ) + +#define WHD_IOCTL_PACKET_TIMEOUT (0xFFFFFFFF) +#define WHD_IOCTL_TIMEOUT_MS (5000) /** Need to give enough time for coming out of Deep sleep (was 400) */ + +#define MSGBUF_IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000) + +#define WHD_EVENT_HANDLER_LIST_SIZE (5) /** Maximum number of simultaneously registered event handlers */ + +#define MSGBUF_TYPE_GEN_STATUS 0x1 +#define MSGBUF_TYPE_RING_STATUS 0x2 +#define MSGBUF_TYPE_FLOW_RING_CREATE 0x3 +#define MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT 0x4 +#define MSGBUF_TYPE_FLOW_RING_DELETE 0x5 +#define MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT 0x6 +#define MSGBUF_TYPE_FLOW_RING_FLUSH 0x7 +#define MSGBUF_TYPE_FLOW_RING_FLUSH_CMPLT 0x8 +#define MSGBUF_TYPE_IOCTLPTR_REQ 0x9 +#define MSGBUF_TYPE_IOCTLPTR_REQ_ACK 0xA +#define MSGBUF_TYPE_IOCTLRESP_BUF_POST 0xB +#define MSGBUF_TYPE_IOCTL_CMPLT 0xC +#define MSGBUF_TYPE_EVENT_BUF_POST 0xD +#define MSGBUF_TYPE_WL_EVENT 0xE +#define MSGBUF_TYPE_TX_POST 0xF +#define MSGBUF_TYPE_TX_STATUS 0x10 +#define MSGBUF_TYPE_RXBUF_POST 0x11 +#define MSGBUF_TYPE_RX_CMPLT 0x12 +#define MSGBUF_TYPE_LPBK_DMAXFER 0x13 +#define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14 +#define MSGBUF_TYPE_H2D_MAILBOX_DATA 0x23 +#define MSGBUF_TYPE_D2H_MAILBOX_DATA 0x24 + +#define NR_TX_PKTIDS 256 +#define NR_RX_PKTIDS 128 + +#define WHD_IOCTL_REQ_PKTID 0xFFFE + +#define WHD_MSGBUF_IOCTL_MAX_TX_SIZE (1500) /* Should be less than 2KB(IOCTL inbut Buffer) */ +#define WHD_MSGBUF_IOCTL_MAX_RX_SIZE (1500) + +#define WHD_MSGBUF_DATA_MAX_RX_SIZE (2048 - sizeof(whd_buffer_header_t)) + +#define WHD_MSGBUF_RXBUFPOST_THRESHOLD 2 +#define WHD_MSGBUF_MAX_IOCTLRESPBUF_POST 5 +#define WHD_MSGBUF_MAX_EVENTBUF_POST 5 + +#define WHD_MSGBUF_PKT_FLAGS_FRAME_802_3 0x01 +#define WHD_MSGBUF_PKT_FLAGS_FRAME_802_11 0x02 +#define WHD_MSGBUF_PKT_FLAGS_FRAME_MASK 0x07 +#define WHD_MSGBUF_PKT_FLAGS_PRIO_SHIFT 5 + +#define WHD_MSGBUF_TX_FLUSH_CNT1 32 +#define WHD_MSGBUF_TX_FLUSH_CNT2 96 + +#define WHD_MSGBUF_DELAY_TXWORKER_THRS 96 +#define WHD_MSGBUF_TRICKLE_TXWORKER_THRS 32 +#define WHD_MSGBUF_UPDATE_RX_PTR_THRS 48 + +#define WHD_MAX_TXSTATUS_WAIT_RETRIES 10 + +#define WHD_EVENT_HANDLER_LIST_SIZE (5) /** Maximum number of simultaneously registered event handlers */ + +#define WHD_NROF_H2D_COMMON_MSGRINGS 2 +#define WHD_NROF_D2H_COMMON_MSGRINGS 3 +#define WHD_NROF_COMMON_MSGRINGS (WHD_NROF_H2D_COMMON_MSGRINGS + \ + WHD_NROF_D2H_COMMON_MSGRINGS) +#ifdef PROTO_MSGBUF +/** Error list element structure + * + * events : set event of error type + * handler: A pointer to the whd_error_handler_t function that will receive the event + * handler_user_data : User provided data that will be passed to the handler when a matching event occurs + */ +typedef struct +{ + whd_error_handler_t handler; + void *handler_user_data; + whd_bool_t event_set; + uint8_t events; +} error_list_elem_t; + +typedef struct whd_error_info +{ + /* Event list variables */ + error_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; + cy_semaphore_t event_list_mutex; +} whd_error_info_t; +#endif + +/* Forward declarations */ +struct whd_flowring; + +typedef struct whd_msgbuf_info { + /* Event list variables (Must be at the beginning) */ + event_list_elem_t whd_event_list[WHD_EVENT_HANDLER_LIST_SIZE]; + cy_semaphore_t event_list_mutex; + + /* IOCTL variables*/ + cy_semaphore_t ioctl_mutex; + whd_buffer_t ioctl_response; + cy_semaphore_t ioctl_sleep; + uint8_t ioctl_response_status; + uint32_t ioctl_response_length; + uint32_t ioctl_response_pktid; +} whd_msgbuf_info_t; + +typedef struct whd_msgbuftx_info +{ + /* Packet send queue variables */ + cy_semaphore_t send_queue_mutex; + whd_buffer_t send_queue_head; + whd_buffer_t send_queue_tail; + uint32_t npkt_in_q; +} whd_msgbuftx_info_t; + +typedef struct +{ + uint8_t destination_address[ETHER_ADDR_LEN]; + uint8_t source_address[ETHER_ADDR_LEN]; + uint16_t ethertype; +} ether_header_t; + +struct msg_buf_addr +{ + uint32_t low_addr; + uint32_t high_addr; +}; + +struct msgbuf_common_hdr +{ + uint8_t msgtype; + uint8_t ifidx; + uint8_t flags; + uint8_t rsvd0; + uint32_t request_ptr; +}; + +struct msgbuf_ioctl_req_hdr +{ + struct msgbuf_common_hdr msg; + uint32_t cmd; + uint16_t trans_id; + uint16_t input_buf_len; + uint16_t output_buf_len; + uint16_t rsvd0[3]; + struct msg_buf_addr req_buf_addr; + uint32_t rsvd1[2]; +}; + +struct msgbuf_tx_msghdr +{ + struct msgbuf_common_hdr msg; + uint8_t txhdr[WHD_ETHERNET_SIZE]; + uint8_t flags; + uint8_t seg_cnt; + struct msg_buf_addr metadata_buf_addr; + struct msg_buf_addr data_buf_addr; + uint16_t metadata_buf_len; + uint16_t data_len; + uint32_t rsvd0; +}; + +struct msgbuf_h2d_mbdata +{ + struct msgbuf_common_hdr msg; + uint32_t mbdata; + uint16_t rsvd0[7]; +}; + +struct msgbuf_rx_bufpost +{ + struct msgbuf_common_hdr msg; + uint16_t metadata_buf_len; + uint16_t data_buf_len; + uint32_t rsvd0; + struct msg_buf_addr metadata_buf_addr; + struct msg_buf_addr data_buf_addr; +}; + +struct msgbuf_rx_ioctl_resp_or_event +{ + struct msgbuf_common_hdr msg; + uint16_t host_buf_len; + uint16_t rsvd0[3]; + struct msg_buf_addr host_buf_addr; + uint32_t rsvd1[4]; +}; + +struct msgbuf_completion_hdr +{ + uint16_t status; + uint16_t flow_ring_id; +}; + +/* Data struct for the MSGBUF_TYPE_GEN_STATUS */ +struct msgbuf_gen_status +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t write_idx; + uint32_t rsvd0[3]; +}; + +/* Data struct for the MSGBUF_TYPE_RING_STATUS */ +struct msgbuf_ring_status +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t write_idx; + uint16_t rsvd0[5]; +}; + +struct msgbuf_rx_event +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t event_data_len; + uint16_t seqnum; + uint16_t rsvd0[4]; +}; + +struct msgbuf_ioctl_resp_hdr +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t resp_len; + uint16_t trans_id; + uint32_t cmd; + uint32_t rsvd0; +}; + +struct msgbuf_tx_status +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t metadata_len; + uint16_t tx_status; +}; + +struct msgbuf_rx_complete +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint16_t metadata_len; + uint16_t data_len; + uint16_t data_offset; + uint16_t flags; + uint32_t rx_status_0; + uint32_t rx_status_1; + uint32_t rsvd0; +}; + +struct msgbuf_tx_flowring_delete_req +{ + struct msgbuf_common_hdr msg; + uint16_t flow_ring_id; + uint16_t reason; + uint32_t rsvd0[7]; +}; + +struct msgbuf_tx_flowring_create_req +{ + struct msgbuf_common_hdr msg; + uint8_t da[ETHER_ADDR_LEN]; + uint8_t sa[ETHER_ADDR_LEN]; + uint8_t tid; + uint8_t if_flags; + uint16_t flow_ring_id; + uint8_t tc; + uint8_t priority; + uint16_t int_vector; + uint16_t max_items; + uint16_t len_item; + struct msg_buf_addr flow_ring_addr; +}; + +struct msgbuf_flowring_create_resp +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint32_t rsvd0[3]; +}; + +struct msgbuf_flowring_delete_resp +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint32_t rsvd0[3]; +}; + +struct msgbuf_flowring_flush_resp +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint32_t rsvd0[3]; +}; + +struct msgbuf_d2h_mailbox_data +{ + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + uint32_t mbdata; + uint32_t rsvd0[2]; +}; + +struct whd_msgbuf_work_item +{ + uint32_t flowid; + int ifidx; + uint8_t sa[ETHER_ADDR_LEN]; + uint8_t da[ETHER_ADDR_LEN]; +}; + +struct whd_msgbuf_pktid +{ + uint16_t allocated; + uint16_t data_offset; + whd_buffer_t skb; + uint32_t physaddr; +}; + +struct whd_msgbuf_pktids +{ + uint32_t array_size; + uint32_t last_allocated_idx; + struct whd_msgbuf_pktid *array; + cy_semaphore_t pktid_mutex; +}; + +struct whd_msgbuf +{ + struct whd_driver *drvr; + struct whd_commonring *commonrings[WHD_NROF_COMMON_MSGRINGS]; + struct whd_commonring **flowrings; + void *ioctbuf; + whd_buffer_t ioctl_queue; + whd_buffer_t ioctl_buffer; + uint32_t ioctl_cmd; + uint8_t ifidx; // used for ioctl to disguish which interface + uint8_t resrv[3]; + uint32_t ioctbuf_phys_hi; + uint32_t ioctbuf_phys_lo; + uint32_t *flowring_handle; + uint16_t max_flowrings; + uint16_t max_submissionrings; + uint16_t max_completionrings; + uint16_t rx_dataoffset; + uint32_t max_rxbufpost; + uint16_t rx_metadata_offset; + uint32_t rxbufpost; + uint32_t max_ioctlrespbuf; + uint32_t cur_ioctlrespbuf; + uint32_t max_eventbuf; + uint32_t cur_eventbuf; + uint32_t reqid; + struct whd_msgbuf_pktids *tx_pktids; + struct whd_msgbuf_pktids *rx_pktids; + struct whd_flowring *flow; + uint8_t *flow_map; + unsigned long *txstatus_done_map; + uint32_t priority; +}; + +extern int whd_msgbuf_send_mbdata(struct whd_driver *drvr, uint32_t mbdata); +extern int whd_msgbuf_ioctl_dequeue(struct whd_driver *whd_driver); +extern uint32_t whd_msgbuf_process_rx_packet(struct whd_driver *dev); +extern void whd_msgbuf_delete_flowring(struct whd_driver *drvr, uint16_t flowid); +extern whd_result_t whd_msgbuf_txflow(struct whd_driver *drvr, uint16_t flowid); +extern whd_result_t whd_msgbuf_txflow_dequeue(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t flowid); +extern whd_result_t whd_msgbuf_txflow_init(whd_msgbuftx_info_t *msgtx_info); +extern whd_result_t whd_msgbuf_info_init(whd_driver_t whd_driver); +extern void whd_msgbuf_info_deinit(whd_driver_t whd_driver); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/wi-fi/whd/whd_msgbuf_txrx.c b/wi-fi/whd/whd_msgbuf_txrx.c new file mode 100644 index 00000000..1dc3f1a0 --- /dev/null +++ b/wi-fi/whd/whd_msgbuf_txrx.c @@ -0,0 +1,2059 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef PROTO_MSGBUF + +#include "whd_buffer_api.h" +#include "whd_msgbuf.h" +#include "whd_flowring.h" +#include "whd_proto.h" +#include "whd_ring.h" +#include "whd_network_if.h" +#include "whd_utils.h" +#include "bus_protocols/whd_bus_m2m_protocol.h" + +#define WHD_RX_BUF_TIMEOUT (10) + +#define ETHER_TYPE_BRCM (0x886C) /** Broadcom Ethertype for identifying event packets - Copied from DHD include/proto/ethernet.h */ +#define BRCM_OUI "\x00\x10\x18" /** Broadcom OUI (Organizationally Unique Identifier): Used in the proprietary(221) IE (Information Element) in all Broadcom devices */ +#define ALIGNED_ADDRESS ( (uint32_t)0x3 ) + +/* QoS related definitions (type of service) */ +#define IPV4_DSCP_OFFSET (15) /** Offset for finding the DSCP field in an IPv4 header */ + +static const uint8_t dscp_to_wmm_qos[] = +{ 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ + 1, 1, 1, 1, 1, 1, 1, /* 8 - 14 */ + 1, 1, 1, 1, 1, 1, 1, /* 15 - 21 */ + 1, 1, 0, 0, 0, 0, 0, /* 22 - 28 */ + 0, 0, 0, 5, 5, 5, 5, /* 29 - 35 */ + 5, 5, 5, 5, 5, 5, 5, /* 36 - 42 */ + 5, 5, 5, 5, 5, 7, 7, /* 43 - 49 */ + 7, 7, 7, 7, 7, 7, 7, /* 50 - 56 */ + 7, 7, 7, 7, 7, 7, 7, /* 57 - 63 */ +}; + +static void whd_msgbuf_update_rxbufpost_count(struct whd_msgbuf *msgbuf, uint16_t rxcnt); +static void whd_msgbuf_rxbuf_ioctlresp_post(struct whd_msgbuf *msgbuf); +static void whd_msgbuf_set_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer, whd_buffer_t prev_buffer); +static void whd_msgbuf_rxbuf_event_post(struct whd_msgbuf *msgbuf); +static int whd_msgbuf_schedule_txdata(struct whd_msgbuf *msgbuf, uint32_t flowid, whd_bool_t force); + + +/** Map a DSCP value from an IP header to a WMM QoS priority + * + * @param dscp_val : DSCP value from IP header + * + * @return wmm_qos : WMM priority + * + */ +static uint8_t whd_map_dscp_to_priority(whd_driver_t whd_driver, uint8_t val) +{ + uint8_t dscp_val = (uint8_t)(val >> 2); /* DSCP field is the high 6 bits of the second byte of an IPv4 header */ + + return dscp_to_wmm_qos[dscp_val]; +} + +static void +whd_msgbuf_release_array(struct whd_driver *whd_driver, + struct whd_msgbuf_pktids *pktids, whd_buffer_dir_t direction) +{ + struct whd_msgbuf_pktid *array; + struct whd_msgbuf_pktid *pktid; + uint32_t result; + uint32_t count; + + array = pktids->array; + count = 0; + do + { + if (array[count].allocated == 1) + { + pktid = &array[count]; + result = whd_buffer_release(whd_driver, pktid->skb, direction); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + } + count++; + } while (count < pktids->array_size); + + whd_mem_free(array); + whd_mem_free(pktids); +} + +static void whd_msgbuf_release_pktids(struct whd_driver *whd_driver, struct whd_msgbuf *msgbuf) +{ + if (msgbuf->rx_pktids) + { + (void)cy_rtos_deinit_semaphore(&msgbuf->rx_pktids->pktid_mutex); + whd_msgbuf_release_array(whd_driver, msgbuf->rx_pktids, WHD_NETWORK_RX); + } + if (msgbuf->tx_pktids) + { + (void)cy_rtos_deinit_semaphore(&msgbuf->tx_pktids->pktid_mutex); + whd_msgbuf_release_array(whd_driver, msgbuf->tx_pktids, WHD_NETWORK_TX); + } +} + +static int +whd_msgbuf_alloc_pktid(struct whd_driver *whd_driver, + struct whd_msgbuf_pktids *pktids, + whd_buffer_t skb, uint16_t data_offset, + uint32_t *physaddr, uint32_t *idx) +{ + struct whd_msgbuf_pktid *array; + uint32_t count; + + array = pktids->array; + + *physaddr = (uint32_t)(whd_buffer_get_current_piece_data_pointer(whd_driver, skb) + data_offset); + *idx = pktids->last_allocated_idx; + + count = 0; + /* Acquire mutex which prevents race condition on pktid->allocated */ + (void)cy_rtos_get_semaphore(&pktids->pktid_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + do + { + (*idx)++; + if (*idx == pktids->array_size) + *idx = 0; + if (array[*idx].allocated == 0) + { + array[*idx].allocated = 1; + break; + } + count++; + } while (count < pktids->array_size); + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&pktids->pktid_mutex, WHD_FALSE); + + if (count == pktids->array_size) + return WHD_WLAN_NOMEM; + + array[*idx].data_offset = data_offset; + array[*idx].physaddr = *physaddr; + array[*idx].skb = skb; + + pktids->last_allocated_idx = *idx; + + return WHD_SUCCESS; +} + +static whd_buffer_t +whd_msgbuf_get_pktid(struct whd_driver *whd_driver, struct whd_msgbuf_pktids *pktids, + uint32_t idx) +{ + struct whd_msgbuf_pktid *pktid; + whd_buffer_t skb; + + if (idx >= pktids->array_size) + { + WPRINT_WHD_ERROR( ("Invalid packet id %u (max %u)\n", (unsigned int)idx, + (unsigned int)pktids->array_size) ); + return NULL; + } + + /* Acquire mutex which prevents race condition on pktid->allocated */ + (void)cy_rtos_get_semaphore(&pktids->pktid_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (pktids->array[idx].allocated == 1) + { + pktid = &pktids->array[idx]; + skb = pktid->skb; + pktid->allocated = 0; + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&pktids->pktid_mutex, WHD_FALSE); + return skb; + } + else + { + WPRINT_WHD_ERROR( ("Invalid packet id %u (not in use)\n", (unsigned int)idx) ); + } + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&pktids->pktid_mutex, WHD_FALSE); + + return NULL; +} + +/** A helper function to easily acquire and initialise a buffer destined for use as an iovar + * + * @param buffer : A pointer to a whd_buffer_t object where the created buffer will be stored + * @param data_length : The length of space reserved for user data + * @param name : The name of the iovar + * + * @return A pointer to the start of user data with data_length space available + */ +static void *whd_msgbuf_get_iovar_buffer(whd_driver_t whd_driver, + whd_buffer_t *buffer, + uint16_t data_length, + const char *name) +{ + uint32_t name_length = (uint32_t)strlen(name) + 1; /* + 1 for terminating null */ + + if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, + (uint16_t)(data_length + name_length), + (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) + { + uint8_t *data = whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + CHECK_PACKET_NULL(data, NULL); + memset(data, 0, (name_length + data_length)); + memcpy(data, name, name_length); + return (data + name_length); + } + else + { + WPRINT_WHD_ERROR( ("Error - failed to allocate a packet buffer for IOVAR\n") ); + return NULL; + } +} + +/** A helper function to easily acquire and initialise a buffer destined for use as an ioctl + * + * @param buffer : A pointer to a whd_buffer_t object where the created buffer will be stored + * @param data_length : The length of space reserved for user data + * + * @return A pointer to the start of user data with data_length space available + */ +static void *whd_msgbuf_get_ioctl_buffer(whd_driver_t whd_driver, + whd_buffer_t *buffer, + uint16_t data_length) +{ + + if (whd_host_buffer_get(whd_driver, buffer, WHD_NETWORK_TX, (uint16_t)(data_length), + (uint32_t)WHD_IOCTL_PACKET_TIMEOUT) == WHD_SUCCESS) + { + return (whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer) ); + } + else + { + WPRINT_WHD_ERROR( ("Error - failed to allocate a packet buffer for IOCTL\n") ); + return NULL; + } + +} + +int whd_msgbuf_send_mbdata(struct whd_driver *drvr, uint32_t mbdata) +{ + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)drvr->msgbuf; + struct whd_commonring *commonring; + struct msgbuf_h2d_mbdata *h2d_mbdata; + void *ret_ptr; + int err; + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_CONTROL_SUBMIT]; + whd_commonring_lock(commonring); + + ret_ptr = whd_commonring_reserve_for_write(commonring); + if (!ret_ptr) + { + WPRINT_WHD_ERROR( ("Memory Allocation Space at Common Ring Failed \n") ); + whd_commonring_unlock(commonring); + return WHD_UNFINISHED; + } + + h2d_mbdata = (struct msgbuf_h2d_mbdata *)ret_ptr; + memset(h2d_mbdata, 0, sizeof(*h2d_mbdata) ); + + h2d_mbdata->msg.msgtype = MSGBUF_TYPE_H2D_MAILBOX_DATA; + h2d_mbdata->mbdata = htod32(mbdata); + + err = whd_commonring_write_complete(commonring); + whd_commonring_unlock(commonring); + + return err; +} + +int whd_msgbuf_ioctl_dequeue(struct whd_driver *whd_driver) +{ + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)whd_driver->msgbuf; + struct whd_commonring *commonring; + struct msgbuf_ioctl_req_hdr *request; + uint32_t buf_len = 0, data_length = 0; + void *ret_ptr; + int retval; + uint8_t *ioctl_queue_buf = NULL; + + /* Get the data length */ + data_length = (uint32_t)(whd_buffer_get_current_piece_size(whd_driver, msgbuf->ioctl_queue) ); + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_CONTROL_SUBMIT]; + whd_commonring_lock(commonring); + ret_ptr = whd_commonring_reserve_for_write(commonring); + + if (!ret_ptr) + { + WPRINT_WHD_ERROR( ("Failed to reserve space in commonring\n") ); + whd_commonring_unlock(commonring); + CHECK_RETURN(whd_buffer_release(whd_driver, msgbuf->ioctl_queue, WHD_NETWORK_TX) ); + msgbuf->ioctl_queue = NULL; + return WHD_UNFINISHED; + } + + msgbuf->reqid++; + WPRINT_WHD_DEBUG( ("Interface Index is %d ret_ptr is 0x%lx cmd: %d \n", msgbuf->ifidx, (uint32_t)ret_ptr, + (unsigned int)msgbuf->ioctl_cmd) ); + request = (struct msgbuf_ioctl_req_hdr *)ret_ptr; + request->msg.msgtype = MSGBUF_TYPE_IOCTLPTR_REQ; + request->msg.ifidx = (uint8_t)msgbuf->ifidx; + request->msg.flags = 0; + request->msg.request_ptr = htod32(WHD_IOCTL_REQ_PKTID); + request->cmd = htod32(msgbuf->ioctl_cmd); + request->output_buf_len = htod16(data_length); + request->trans_id = htod16(msgbuf->reqid); + buf_len = MIN(data_length, WHD_MSGBUF_IOCTL_MAX_TX_SIZE); + request->input_buf_len = htod16(buf_len); + request->req_buf_addr.high_addr = htod32(msgbuf->ioctbuf_phys_hi); + request->req_buf_addr.low_addr = htod32(msgbuf->ioctbuf_phys_lo); + + if (msgbuf->ioctl_queue) + { + ioctl_queue_buf = whd_buffer_get_current_piece_data_pointer(whd_driver, (whd_buffer_t)msgbuf->ioctl_queue); + memcpy(msgbuf->ioctbuf, ioctl_queue_buf, buf_len); + CHECK_RETURN(whd_buffer_release(whd_driver, msgbuf->ioctl_queue, WHD_NETWORK_TX) ); + msgbuf->ioctl_queue = NULL; + } + else + { + memset(msgbuf->ioctbuf, 0, buf_len); + } + + retval = whd_commonring_write_complete(commonring); + + whd_commonring_unlock(commonring); + + return retval; +} + +static int whd_msgbuf_send_ioctl(whd_interface_t ifp, uint32_t cmd, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + whd_driver_t whd_driver = ifp->whd_driver; + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)whd_driver->msgbuf; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + int retval; + + /* Set send IOCTL buffer to ioctl_queuey. + Because we have ioctl_mutex, only one IOCTL buffer at one time. */ + msgbuf->ioctl_queue = send_buffer_hnd; + msgbuf->ifidx = ifp->ifidx; + msgbuf->ioctl_cmd = cmd; + + whd_thread_notify(whd_driver); + + /* Wait till response has been received */ + retval = cy_rtos_get_semaphore(&msgbuf_info->ioctl_sleep, (uint32_t)WHD_IOCTL_TIMEOUT_MS, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + /* Release the mutex since ioctl response will no longer be referenced. */ + CHECK_RETURN(cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE) ); + return retval; + } + msgbuf_info->ioctl_response = + whd_msgbuf_get_pktid(whd_driver, msgbuf->rx_pktids, msgbuf_info->ioctl_response_pktid); + + if (msgbuf_info->ioctl_response_length != 0) + { + if (!msgbuf_info->ioctl_response) + { + return WHD_BADARG; + } + } + + /* Check if the caller wants the response */ + if (response_buffer_hnd != NULL) + { + *response_buffer_hnd = msgbuf_info->ioctl_response; + } + else + { + CHECK_RETURN(whd_buffer_release(whd_driver, msgbuf_info->ioctl_response, WHD_NETWORK_RX) ); + } + + msgbuf_info->ioctl_response = NULL; + + /* Release the mutex since ioctl response will no longer be referenced. */ + CHECK_RETURN(cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE) ); + + /* Check whether the IOCTL response indicates it failed. */ + if (msgbuf_info->ioctl_response_status != WHD_SUCCESS) + { + if (response_buffer_hnd != NULL) + { + CHECK_RETURN(whd_buffer_release(whd_driver, *response_buffer_hnd, WHD_NETWORK_RX) ); + *response_buffer_hnd = NULL; + } + return WHD_RESULT_CREATE( (WLAN_ENUM_OFFSET - msgbuf_info->ioctl_response_status) ); + } + + return WHD_SUCCESS; +} + +static whd_result_t whd_msgbuf_set_ioctl(whd_interface_t ifp, uint32_t command, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + whd_driver_t whd_driver = ifp->whd_driver; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + whd_result_t retval = WHD_SUCCESS; + + /* Acquire mutex which prevents multiple simultaneous IOCTLs */ + retval = cy_rtos_get_semaphore(&msgbuf_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX) ); + return retval; + } + + retval = whd_msgbuf_send_ioctl(ifp, command, send_buffer_hnd, response_buffer_hnd); + + /* Release the mutex since ioctl response will no longer be referenced. */ + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE); + + return retval; +} + +static whd_result_t whd_msgbuf_get_ioctl(whd_interface_t ifp, uint32_t command, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + whd_driver_t whd_driver = ifp->whd_driver; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + whd_result_t retval = WHD_SUCCESS; + + /* Acquire mutex which prevents multiple simultaneous IOCTLs */ + retval = cy_rtos_get_semaphore(&msgbuf_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX) ); + return retval; + } + retval = whd_msgbuf_send_ioctl(ifp, command, send_buffer_hnd, response_buffer_hnd); + + /* Release the mutex since ioctl response will no longer be referenced. */ + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE); + + return retval; +} + +static whd_result_t whd_msgbuf_set_iovar(whd_interface_t ifp, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + whd_driver_t whd_driver = ifp->whd_driver; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + whd_result_t retval = WHD_SUCCESS; + + /* Acquire mutex which prevents multiple simultaneous IOCTLs */ + retval = cy_rtos_get_semaphore(&msgbuf_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX) ); + return retval; + } + retval = whd_msgbuf_send_ioctl(ifp, (uint32_t)WLC_SET_VAR, send_buffer_hnd, response_buffer_hnd); + + /* Release the mutex since ioctl response will no longer be referenced. */ + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE); + + return retval; +} + +static whd_result_t whd_msgbuf_get_iovar(whd_interface_t ifp, + whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + whd_driver_t whd_driver = ifp->whd_driver; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + whd_result_t retval = WHD_SUCCESS; + + /* Acquire mutex which prevents multiple simultaneous IOCTLs */ + retval = cy_rtos_get_semaphore(&msgbuf_info->ioctl_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (retval != WHD_SUCCESS) + { + CHECK_RETURN(whd_buffer_release(whd_driver, send_buffer_hnd, WHD_NETWORK_TX) ); + return retval; + } + retval = whd_msgbuf_send_ioctl(ifp, (uint32_t)WLC_GET_VAR, send_buffer_hnd, response_buffer_hnd); + + /* Release the mutex since ioctl response will no longer be referenced. */ + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE); + + return retval; +} + +static whd_result_t +whd_msgbuf_remove_flowring(struct whd_msgbuf *msgbuf, uint16_t flowid) +{ + + WPRINT_WHD_DEBUG( ("Removing flowring %d\n", flowid) ); + + CHECK_RETURN(whd_buffer_release(msgbuf->drvr, (whd_buffer_t)msgbuf->flowring_handle[flowid], WHD_NETWORK_TX)); + + whd_flowring_delete(msgbuf->flow, flowid); + + return WHD_SUCCESS; +} + +static void whd_msgbuf_process_gen_status(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_gen_status *gen_status = buf; + int err; + + err = dtoh16(gen_status->compl_hdr.status); + if (err) + WPRINT_WHD_ERROR( ("Firmware reported general error: %d\n", err) ); +} + +static void whd_msgbuf_process_ring_status(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_ring_status *ring_status = buf; + int err; + + err = dtoh16(ring_status->compl_hdr.status); + if (err) + { + WPRINT_WHD_ERROR( ("Firmware reported ring %d error: %d\n", dtoh16(ring_status->compl_hdr.flow_ring_id), err) ); + } +} + +static void +whd_msgbuf_process_flow_ring_create_response(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_flowring_create_resp *flowring_create_resp; + uint16_t status; + uint16_t flowid; + + flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf; + + flowid = dtoh16(flowring_create_resp->compl_hdr.flow_ring_id); + flowid -= WHD_H2D_MSGRING_FLOWRING_IDSTART; + status = dtoh16(flowring_create_resp->compl_hdr.status); + + if (status) + { + WPRINT_WHD_ERROR( ("Flowring creation failed, code %d\n", status) ); + whd_msgbuf_remove_flowring(msgbuf, flowid); + return; + } + WPRINT_WHD_DEBUG( ("Flowring %d Create response status %d\n", flowid, status) ); + + whd_flowring_open(msgbuf->flow, flowid); + + whd_msgbuf_schedule_txdata(msgbuf, flowid, WHD_TRUE); +} + +static void +whd_msgbuf_process_flow_ring_delete_response(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_flowring_delete_resp *flowring_delete_resp; + uint16_t status; + uint16_t flowid; + + flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf; + + flowid = dtoh16(flowring_delete_resp->compl_hdr.flow_ring_id); + flowid -= WHD_H2D_MSGRING_FLOWRING_IDSTART; + status = dtoh16(flowring_delete_resp->compl_hdr.status); + + if (status) + { + WPRINT_WHD_ERROR( ("Flowring deletion failed, code %d\n", status) ); + whd_flowring_delete(msgbuf->flow, flowid); + return; + } + WPRINT_WHD_DEBUG( ("Flowring %d Delete response status %d\n", flowid, status) ); + + whd_msgbuf_remove_flowring(msgbuf, flowid); +} + +static void +whd_msgbuf_process_ioctl_complete(whd_driver_t whd_driver, struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_ioctl_resp_hdr *ioctl_resp; + whd_result_t result; + whd_result_t ioctl_mutex_res; + + ioctl_resp = (struct msgbuf_ioctl_resp_hdr *)buf; + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + + /* Validate request ioctl ID and check if whd_bus_send_ioctl is still waiting for response*/ + if ( ( (ioctl_mutex_res = cy_rtos_get_semaphore(&msgbuf_info->ioctl_mutex, 0, WHD_FALSE) ) != WHD_SUCCESS ) ) + { + /* Save the response packet in a variable */ + msgbuf_info->ioctl_response_pktid = dtoh32(ioctl_resp->msg.request_ptr); + msgbuf_info->ioctl_response_length = dtoh16(ioctl_resp->resp_len); + msgbuf_info->ioctl_response_status = dtoh16(ioctl_resp->compl_hdr.status); + + WPRINT_WHD_DATA_LOG( ("Wcd:< Procd pkt 0x%08lX: IOCTL Response\n", + (unsigned long)msgbuf_info->ioctl_response) ); + + /* Wake the thread which sent the IOCTL/IOVAR so that it will resume */ + result = cy_rtos_set_semaphore(&msgbuf_info->ioctl_sleep, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + else + { + if (ioctl_mutex_res == WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_send_ioctl is already timed out, drop the buffer\n") ); + result = cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + } + else + { + WPRINT_WHD_ERROR( ("Received a response for a different IOCTL - retry\n") ); + } + + } + + if (msgbuf->cur_ioctlrespbuf) + msgbuf->cur_ioctlrespbuf--; + + whd_msgbuf_rxbuf_ioctlresp_post(msgbuf); +} + +static void whd_msgbuf_process_event_buffer(whd_driver_t whd_driver, whd_buffer_t buffer, uint16_t size) +{ + uint16_t ether_type; + whd_event_header_t *whd_event; + whd_event_t *event, *aligned_event = (whd_event_t *)whd_driver->aligned_addr; + struct whd_msgbuf_info *msgbuf_info = whd_driver->proto->pd; + whd_result_t result; + uint16_t i; + uint16_t j; + uint32_t datalen, addr; + + + if ( ( (uint32_t)whd_buffer_get_current_piece_size(whd_driver, + buffer) + WHD_ETHERNET_SIZE ) < sizeof(whd_event_t) ) + return; + + event = (whd_event_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_WITH_NULL_RETURN(event); + + ether_type = ntoh16(event->eth.ethertype); + + /* If frame is truly an event, it should have EtherType equal to the Broadcom type. */ + if (ether_type != (uint16_t)ETHER_TYPE_BRCM) + { + WPRINT_WHD_ERROR( ("Error - received a channel 1 packet which was not BRCM ethertype\n") ); + return; + } + + /* If ethertype is correct, the contents of the ethernet packet + * are a structure of type bcm_event_t + */ + + /* Check that the OUI matches the Broadcom OUI */ + if (0 != memcmp(BRCM_OUI, &event->eth_evt_hdr.oui[0], (size_t)DOT11_OUI_LEN) ) + { + WPRINT_WHD_ERROR( ("Event OUI mismatch\n") ); + return; + } + + whd_event = &event->whd_event; + + /* Search for the event type in the list of event handler functions + * event data is stored in network endianness + */ + whd_event->flags = ntoh16(whd_event->flags); + whd_event->event_type = (whd_event_num_t)ntoh32(whd_event->event_type); + whd_event->status = (whd_event_status_t)ntoh32(whd_event->status); + whd_event->reason = (whd_event_reason_t)ntoh32(whd_event->reason); + whd_event->auth_type = ntoh32(whd_event->auth_type); + whd_event->datalen = ntoh32(whd_event->datalen); + + /* Ensure data length is correct */ + if (whd_event->datalen + (sizeof(whd_event_t) ) >= (uint32_t)(size) ) + { + WPRINT_WHD_ERROR( ( + "Error - (data length received [%d], sizeof(whd_event_t)[%u]. Bus header packet size = [%d]. Ignoring the packet\n", + (int)whd_event->datalen, sizeof(whd_event_t), size) ); + return; + } + + if (whd_event->bsscfgidx >= WHD_INTERFACE_MAX) + { + WPRINT_WHD_ERROR( ("bsscfgidx is out of range\n") ); + return; + } + + /* This is necessary because people who defined event statuses and reasons overlapped values. */ + if (whd_event->event_type == WLC_E_PSK_SUP) + { + whd_event->status = (whd_event_status_t)( (int)whd_event->status + WLC_SUP_STATUS_OFFSET ); + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_SUP_REASON_OFFSET ); + } + else if (whd_event->event_type == WLC_E_PRUNE) + { + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_PRUNE_REASON_OFFSET ); + } + else if ( (whd_event->event_type == WLC_E_DISASSOC) || (whd_event->event_type == WLC_E_DEAUTH) ) + { + whd_event->status = (whd_event_status_t)( (int)whd_event->status + WLC_DOT11_SC_STATUS_OFFSET ); + whd_event->reason = (whd_event_reason_t)( (int)whd_event->reason + WLC_E_DOT11_RC_REASON_OFFSET ); + } + + /* do any needed debug logging of event */ + WHD_IOCTL_LOG_ADD_EVENT(whd_driver, whd_event->event_type, whd_event->status, + whd_event->reason); + + if (cy_rtos_get_semaphore(&msgbuf_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to obtain mutex for event list access!\n") ); + return; + } + + datalen = whd_event->datalen; + /* use memcpy to get aligned event message */ + addr = (uint32_t )DATA_AFTER_HEADER(event); + if (aligned_event && (addr & ALIGNED_ADDRESS) ) + { + memcpy(aligned_event, (whd_event_t *)addr, datalen); + } + else + { + aligned_event = (whd_event_t *)addr; + } + for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++) + { + if (msgbuf_info->whd_event_list[i].event_set) + { + for (j = 0; msgbuf_info->whd_event_list[i].events[j] != WLC_E_NONE; ++j) + { + if ( (msgbuf_info->whd_event_list[i].events[j] == whd_event->event_type) && + (msgbuf_info->whd_event_list[i].ifidx == whd_event->ifidx) ) + { + /* Correct event type has been found - call the handler function and exit loop */ + msgbuf_info->whd_event_list[i].handler_user_data = + msgbuf_info->whd_event_list[i].handler(whd_driver->iflist[whd_event->bsscfgidx], + whd_event, + (uint8_t *)aligned_event, + msgbuf_info->whd_event_list[i].handler_user_data); + break; + } + } + } + } + + result = cy_rtos_set_semaphore(&msgbuf_info->event_list_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + WPRINT_WHD_DATA_LOG( ("Wcd:< Procd pkt 0x%08lX: Evnt %d (%d bytes)\n", (unsigned long)buffer, + (int)whd_event->event_type, size) ); +} + +static void +whd_msgbuf_process_event(struct whd_msgbuf *msgbuf, void *buf) +{ + struct whd_driver *drvr = msgbuf->drvr; + struct msgbuf_rx_event *event; + uint32_t idx; + uint16_t buflen; + whd_buffer_t skb = NULL; + whd_interface_t ifp; + whd_result_t result; + + event = (struct msgbuf_rx_event *)buf; + idx = dtoh32(event->msg.request_ptr); + buflen = dtoh16(event->event_data_len); + + skb = whd_msgbuf_get_pktid(drvr, msgbuf->rx_pktids, idx); + if (!skb) + return; + + if (msgbuf->rx_dataoffset) + (void)whd_buffer_add_remove_at_front(drvr, &skb, msgbuf->rx_dataoffset); + + (void)whd_buffer_set_size(drvr, skb, buflen); + + ifp = whd_get_interface(msgbuf->drvr, event->msg.ifidx); + if (!ifp) + { + WPRINT_WHD_ERROR( ("Received pkt for invalid ifidx %d\n", + event->msg.ifidx) ); + goto exit; + } + + whd_msgbuf_process_event_buffer(drvr, skb, buflen); + +exit: + /* Release the event packet buffer */ + result = whd_buffer_release(drvr, skb, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + if (msgbuf->cur_eventbuf) + msgbuf->cur_eventbuf--; + whd_msgbuf_rxbuf_event_post(msgbuf); + +} + +static void +whd_msgbuf_process_txstatus(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_tx_status *tx_status; + uint16_t flowid; + uint32_t idx; + whd_buffer_t skb = NULL; + struct whd_driver *drvr = msgbuf->drvr; + whd_result_t result; + + tx_status = (struct msgbuf_tx_status *)buf; + flowid = dtoh16(tx_status->compl_hdr.flow_ring_id); + flowid -= WHD_H2D_MSGRING_FLOWRING_IDSTART; + idx = dtoh32(tx_status->msg.request_ptr) - 1; + skb = whd_msgbuf_get_pktid(drvr, msgbuf->tx_pktids, idx); + WPRINT_WHD_DEBUG( ("%s - tx_status - %d for FlowID is %d, skb:0x%lu\n", __func__, tx_status->compl_hdr.status, + flowid, (uint32_t)skb) ); + + result = whd_buffer_release(drvr, skb, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + return; +} + +static void +whd_msgbuf_process_rx_complete(struct whd_msgbuf *msgbuf, void *buf) +{ + WPRINT_WHD_DEBUG( ("%s: RECEIVED RX PACKETS \n", __func__) ); + + struct whd_driver *drvr = msgbuf->drvr; + struct msgbuf_rx_complete *rx_complete; + whd_interface_t ifp; + whd_result_t result; + whd_buffer_t skb = NULL; + uint16_t data_offset; + uint16_t buflen; + uint16_t flags; + uint32_t idx; + + WPRINT_WHD_DEBUG( ("%s : buf is 0x%lx \n", __func__, (uint32_t)buf) ); + + if (buf != NULL) + { + rx_complete = (struct msgbuf_rx_complete *)buf; + data_offset = dtoh16(rx_complete->data_offset); + buflen = dtoh16(rx_complete->data_len); + idx = dtoh32(rx_complete->msg.request_ptr); + flags = dtoh16(rx_complete->flags); + + skb = whd_msgbuf_get_pktid(drvr, msgbuf->rx_pktids, idx); + if (!skb) + return; + + if (data_offset) + (void)whd_buffer_add_remove_at_front(drvr, &skb, data_offset); + else if (msgbuf->rx_dataoffset) + (void)whd_buffer_add_remove_at_front(drvr, &skb, msgbuf->rx_dataoffset); + + (void)whd_buffer_set_size(drvr, skb, buflen); + + WPRINT_WHD_DEBUG( ("%s : buflen is %d , skb is 0x%lx\n", __func__, buflen, (uint32_t)skb) ); + + if ( (flags & WHD_MSGBUF_PKT_FLAGS_FRAME_MASK) == + WHD_MSGBUF_PKT_FLAGS_FRAME_802_11 ) + { + result = whd_buffer_release(drvr, skb, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + } + + ifp = (whd_interface_t)whd_get_interface(drvr, rx_complete->msg.ifidx); + if (!ifp) + { + WPRINT_WHD_ERROR( ("Received pkt for invalid ifidx %d\n", + rx_complete->msg.ifidx) ); + result = whd_buffer_release(drvr, skb, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* Send packet to bottom of network stack */ + result = whd_network_process_ethernet_data(ifp, skb); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("%s failed at %d \n", __func__, __LINE__) ); + } + else + WPRINT_WHD_DEBUG( ("%s : RECEIVED BUFFER IS NULL \n", __func__) ); + + whd_msgbuf_update_rxbufpost_count(msgbuf, 1); + + return; + +} + +static void +whd_msgbuf_process_d2h_mbdata(struct whd_msgbuf *msgbuf, void *buf) +{ + struct msgbuf_d2h_mailbox_data *d2h_mbdata; + + d2h_mbdata = (struct msgbuf_d2h_mailbox_data *)buf; + + if (!d2h_mbdata) + { + WPRINT_WHD_ERROR( ("d2h_mbdata is null\n") ); + return; + } + + whd_bus_handle_mb_data(msgbuf->drvr, d2h_mbdata->mbdata); +} + +static void whd_msgbuf_process_msgtype(struct whd_msgbuf *msgbuf, void *buf) +{ + struct whd_driver *drvr = msgbuf->drvr; + struct msgbuf_common_hdr *msg; + + msg = (struct msgbuf_common_hdr *)buf; + + WPRINT_WHD_DEBUG( ("Handling RX msgtype - %d \n", msg->msgtype) ); + + switch (msg->msgtype) + { + case MSGBUF_TYPE_GEN_STATUS: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_GEN_STATUS\n") ); + whd_msgbuf_process_gen_status(msgbuf, buf); + break; + case MSGBUF_TYPE_RING_STATUS: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_RING_STATUS\n") ); + whd_msgbuf_process_ring_status(msgbuf, buf); + break; + case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n") ); + whd_msgbuf_process_flow_ring_create_response(msgbuf, buf); + break; + case MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT\n") ); + whd_msgbuf_process_flow_ring_delete_response(msgbuf, buf); + break; + case MSGBUF_TYPE_IOCTLPTR_REQ_ACK: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_IOCTLPTR_REQ_ACK\n") ); + break; + case MSGBUF_TYPE_IOCTL_CMPLT: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_IOCTL_CMPLT\n") ); + whd_msgbuf_process_ioctl_complete(drvr, msgbuf, buf); + break; + case MSGBUF_TYPE_WL_EVENT: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_WL_EVENT\n") ); + whd_msgbuf_process_event(msgbuf, buf); + break; + case MSGBUF_TYPE_TX_STATUS: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_TX_STATUS\n") ); + whd_msgbuf_process_txstatus(msgbuf, buf); + break; + case MSGBUF_TYPE_RX_CMPLT: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_RX_CMPLT\n") ); + whd_msgbuf_process_rx_complete(msgbuf, buf); + break; + case MSGBUF_TYPE_D2H_MAILBOX_DATA: + WPRINT_WHD_DEBUG( ("MSGBUF_TYPE_D2H_MAILBOX_DATA\n") ); + whd_msgbuf_process_d2h_mbdata(msgbuf, buf); + break; + + default: + WPRINT_WHD_DEBUG( ("Unsupported msgtype %d\n", msg->msgtype) ); + break; + } +} + +static uint32_t whd_msgbuf_process_rx_buffer(struct whd_msgbuf *msgbuf, + struct whd_commonring *commonring) +{ + void *buf; + uint16_t count; + uint16_t processed; + +again: + buf = whd_commonring_get_read_ptr(commonring, &count); + + if (buf == NULL) + return 0; + else + WPRINT_WHD_DEBUG( ("<== %s: Received read pointer is NOT NULL \n", __func__) ); + + processed = 0; + while (count) + { + whd_msgbuf_process_msgtype(msgbuf, (uint8_t *)buf + msgbuf->rx_dataoffset); + buf = (uint8_t *)buf + whd_commonring_len_item(commonring); + processed++; + if (processed == WHD_MSGBUF_UPDATE_RX_PTR_THRS) + { + whd_commonring_read_complete(commonring, processed); + processed = 0; + } + count--; + } + if (processed) + whd_commonring_read_complete(commonring, processed); + + if (commonring->r_ptr == 0) + goto again; + + DELAYED_BUS_RELEASE_SCHEDULE(msgbuf->drvr, WHD_TRUE); + + return 1; +} + +uint32_t whd_msgbuf_process_rx_packet(struct whd_driver *dev) +{ + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)dev->msgbuf; + void *buf; + uint32_t result; + + buf = msgbuf->commonrings[WHD_D2H_MSGRING_RX_COMPLETE]; + result = whd_msgbuf_process_rx_buffer(msgbuf, buf); + buf = msgbuf->commonrings[WHD_D2H_MSGRING_TX_COMPLETE]; + result = whd_msgbuf_process_rx_buffer(msgbuf, buf); + buf = msgbuf->commonrings[WHD_D2H_MSGRING_CONTROL_COMPLETE]; + result = whd_msgbuf_process_rx_buffer(msgbuf, buf); + + return result; +} + +void whd_msgbuf_delete_flowring(struct whd_driver *drvr, uint16_t flowid) +{ + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)drvr->proto->pd; + struct msgbuf_tx_flowring_delete_req *delete; + struct whd_commonring *commonring; + struct whd_commonring *commonring_del = msgbuf->flowrings[flowid]; + struct whd_flowring *flow = msgbuf->flow; + void *ret_ptr; + uint8_t ifidx; + int err; + + /* make sure it is not in txflow */ + whd_commonring_lock(commonring_del); + flow->rings[flowid]->status = RING_CLOSING; + whd_commonring_unlock(commonring_del); + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_CONTROL_SUBMIT]; + whd_commonring_lock(commonring); + ret_ptr = whd_commonring_reserve_for_write(commonring); + if (!ret_ptr) + { + WPRINT_WHD_ERROR( ("FW unaware, flowring will be removed !!\n") ); + whd_commonring_unlock(commonring); + whd_msgbuf_remove_flowring(msgbuf, flowid); + return; + } + + delete = (struct msgbuf_tx_flowring_delete_req *)ret_ptr; + + ifidx = whd_flowring_ifidx_get(msgbuf->flow, flowid); + + delete->msg.msgtype = MSGBUF_TYPE_FLOW_RING_DELETE; + delete->msg.ifidx = ifidx; + delete->msg.request_ptr = 0; + + delete->flow_ring_id = htod16(flowid + + WHD_H2D_MSGRING_FLOWRING_IDSTART); + delete->reason = 0; + + WPRINT_WHD_DEBUG( ("Send Flow Delete Req flow ID %d, ifindex %d\n", + flowid, ifidx) ); + + err = whd_commonring_write_complete(commonring); + whd_commonring_unlock(commonring); + if (err) + { + WPRINT_WHD_ERROR( ("Failed to submit RING_DELETE, flowring will be removed\n") ); + whd_msgbuf_remove_flowring(msgbuf, flowid); + } +} + +static whd_result_t whd_msgbuf_txflow_reinsert(struct whd_flowring *flow, uint16_t flowid, + whd_buffer_t skb) +{ + struct whd_flowring_ring *ring = flow->rings[flowid]; + struct whd_driver *drvr = flow->dev; + whd_msgbuftx_info_t *msgtx_info = &ring->txflow_queue; + whd_result_t result; + + if (cy_rtos_get_semaphore(&msgtx_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + /* Could not obtain mutex */ + /* Fatal error */ + result = whd_buffer_release(drvr, skb, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + if ( (msgtx_info->send_queue_head == NULL) && (msgtx_info->send_queue_tail == NULL) ) + { + whd_msgbuf_set_next_buffer_in_queue(drvr, NULL, skb); + msgtx_info->send_queue_head = msgtx_info->send_queue_tail = skb; + } + else if (msgtx_info->send_queue_head != NULL) + { + whd_msgbuf_set_next_buffer_in_queue(drvr, msgtx_info->send_queue_head, skb); + msgtx_info->send_queue_head = skb; + } + else + { + WPRINT_WHD_ERROR( ("Error here %s at %d, head: 0x%x, tail: 0x%x\n", __func__, __LINE__, + (unsigned int)msgtx_info->send_queue_head, (unsigned int)msgtx_info->send_queue_tail) ); + } + msgtx_info->npkt_in_q++; + + result = cy_rtos_set_semaphore(&msgtx_info->send_queue_mutex, WHD_FALSE); + + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + return WHD_SUCCESS; +} + +whd_result_t whd_msgbuf_txflow(struct whd_driver *drvr, uint16_t flowid) +{ + struct whd_msgbuf *msgbuf = drvr->msgbuf; + struct whd_commonring *commonring; + void *ret_ptr; + struct msgbuf_tx_msghdr *tx_msghdr; + uint32_t address; + uint32_t count; + uint32_t physaddr; + uint32_t pktid; + whd_buffer_t skb; + whd_result_t result; + struct whd_flowring *flow = msgbuf->flow; + struct whd_flowring_ring *ring = flow->rings[flowid]; + + WPRINT_WHD_DEBUG( (" %s : Created Flow Id is %d \n", __func__, flowid) ); + + commonring = msgbuf->flowrings[flowid]; + if (!whd_commonring_write_available(commonring) ) + return WHD_BUS_MEM_RESERVE_FAIL; + + //whd_commonring_lock(commonring); //to be fixed + + count = WHD_MSGBUF_TX_FLUSH_CNT2 - WHD_MSGBUF_TX_FLUSH_CNT1; + while (whd_flowring_qlen(flow, flowid) ) + { + result = whd_msgbuf_txflow_dequeue(drvr, &skb, flowid); + if ( (result != WHD_SUCCESS) || (skb == NULL) ) + { + WPRINT_WHD_ERROR( ("No SKB, but qlen %u\n", (unsigned int)whd_flowring_qlen(flow, flowid) ) ); + break; + } + CHECK_RETURN(whd_buffer_add_remove_at_front(drvr, &skb, (int32_t)(sizeof(whd_buffer_header_t)) ) ); + + if (whd_msgbuf_alloc_pktid(drvr, msgbuf->tx_pktids, skb, WHD_ETHERNET_SIZE, + &physaddr, &pktid) ) + { + whd_msgbuf_txflow_reinsert(flow, flowid, skb); + WPRINT_WHD_ERROR( ("No PKTID available !!\n") ); + break; + } + + ret_ptr = whd_commonring_reserve_for_write(commonring); + WPRINT_WHD_DEBUG( ("TX flowring Reserve ptr is 0x%lx \n", (uint32_t)ret_ptr) ); + if (!ret_ptr) + { + whd_msgbuf_get_pktid(drvr, msgbuf->tx_pktids, pktid); + whd_msgbuf_txflow_reinsert(flow, flowid, skb); + WPRINT_WHD_ERROR( ("%s: ERROR in Reserving for Write \n", __func__) ); + break; + } + WPRINT_WHD_DATA_LOG( ("Wcd:> Sending pkt 0x%08lX\n", (unsigned long)skb) ); + WHD_STATS_INCREMENT_VARIABLE(drvr, tx_total); + count++; + + tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr; + + tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST; + tx_msghdr->msg.request_ptr = htod32(pktid + 1); + tx_msghdr->msg.ifidx = flow->hash[ring->hash_id].ifidx; + tx_msghdr->flags = WHD_MSGBUF_PKT_FLAGS_FRAME_802_3; + tx_msghdr->flags |= ((msgbuf->priority) & 0x07) << WHD_MSGBUF_PKT_FLAGS_PRIO_SHIFT; + tx_msghdr->seg_cnt = 1; + memcpy(tx_msghdr->txhdr, whd_buffer_get_current_piece_data_pointer(drvr, skb), WHD_ETHERNET_SIZE); + tx_msghdr->data_len = (whd_buffer_get_current_piece_size(drvr, skb) - htod16(WHD_ETHERNET_SIZE) ); + address = (uint32_t)physaddr; + tx_msghdr->data_buf_addr.high_addr = 0x0; + tx_msghdr->data_buf_addr.low_addr = htod32(address & 0xffffffff); + tx_msghdr->metadata_buf_len = 0; + tx_msghdr->metadata_buf_addr.high_addr = 0; + tx_msghdr->metadata_buf_addr.low_addr = 0; + if (count >= WHD_MSGBUF_TX_FLUSH_CNT2) + { + whd_commonring_write_complete(commonring); + count = 0; + } + } + + if (count) + whd_commonring_write_complete(commonring); + //whd_commonring_unlock(commonring); //to be fixed + + return WHD_SUCCESS; +} + +whd_result_t whd_msgbuf_txflow_init(whd_msgbuftx_info_t *msgtx_info) +{ + /* Create the sdpcm packet queue semaphore */ + if (cy_rtos_init_semaphore(&msgtx_info->send_queue_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&msgtx_info->send_queue_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + msgtx_info->send_queue_head = (whd_buffer_t)NULL; + msgtx_info->send_queue_tail = (whd_buffer_t)NULL; + msgtx_info->npkt_in_q = 0; + + return WHD_SUCCESS; +} + +void whd_msgbuf_txflow_deinit(whd_msgbuftx_info_t *msgtx_info) +{ + +} + +static void whd_msgbuf_set_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer, whd_buffer_t prev_buffer) +{ + whd_buffer_header_t *packet = + (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, prev_buffer); + packet->queue_next = buffer; +} + +static whd_buffer_t whd_msgbuf_get_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer) +{ + whd_buffer_header_t *packet = (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + return packet->queue_next; +} + +static int whd_msgbuf_schedule_txdata(struct whd_msgbuf *msgbuf, uint32_t flowid, + whd_bool_t force) +{ + whd_driver_t whd_driver = msgbuf->drvr; + setbit(msgbuf->flow_map, flowid); + + if (force == WHD_TRUE) + { + whd_thread_notify(whd_driver); + } + return 0; +} + +whd_result_t whd_msgbuf_txflow_dequeue(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t flowid) +{ + struct whd_flowring_ring *ring; + struct whd_msgbuf *msgbuf = whd_driver->msgbuf; + struct whd_flowring *flow = msgbuf->flow; + whd_result_t result; + + ring = flow->rings[flowid]; + whd_msgbuftx_info_t *msgtx_info = &ring->txflow_queue; + *buffer = NULL; + + if (ring->status != RING_OPEN) + { + WPRINT_WHD_ERROR( ("Flow Ring is not Opened, %s failed at %d\n", __func__, __LINE__) ); + return WHD_NO_REGISTER_FUNCTION_POINTER; + } + + if (msgtx_info->npkt_in_q == 0) + { + return WHD_NO_PACKET_TO_SEND; + } + + /* There is a packet waiting to be sent - send it then fix up queue and release packet */ + if (cy_rtos_get_semaphore(&msgtx_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + /* Could not obtain mutex, push back the flow control semaphore */ + WPRINT_WHD_ERROR( ("Error manipulating a semaphore, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Pop the head off and set the new send_queue head */ + WPRINT_WHD_DEBUG( ("Dequeuing --- \n") ); + *buffer = msgtx_info->send_queue_head; + msgtx_info->send_queue_head = whd_msgbuf_get_next_buffer_in_queue(whd_driver, *buffer); + + if (msgtx_info->send_queue_head == NULL) + { + msgtx_info->send_queue_tail = NULL; + } + + WPRINT_WHD_DEBUG(("Dequeue --> send_queue_head - %p\n", *buffer)); + msgtx_info->npkt_in_q--; + + result = cy_rtos_set_semaphore(&msgtx_info->send_queue_mutex, WHD_FALSE); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + + return WHD_SUCCESS; +} + +static whd_result_t whd_msgbuf_txflow_enqueue(whd_driver_t whd_driver, whd_buffer_t buffer, uint8_t prio, + uint8_t flowid) +{ + uint8_t *data = NULL; + whd_result_t result; + struct whd_msgbuf *msgbuf = whd_driver->msgbuf; + struct whd_flowring *flow = msgbuf->flow; + struct whd_flowring_ring *ring; + ring = flow->rings[flowid]; + whd_msgbuftx_info_t *msgtx_info = &ring->txflow_queue; + msgbuf->priority = prio; + + CHECK_PACKET_NULL(buffer, WHD_NO_REGISTER_FUNCTION_POINTER); + + data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + + if (cy_rtos_get_semaphore(&msgtx_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + /* Could not obtain mutex */ + /* Fatal error */ + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + WPRINT_WHD_DEBUG(("Enqueuing +++ \n")); + CHECK_RETURN(whd_buffer_add_remove_at_front(whd_driver, &buffer, -(int)(sizeof(whd_buffer_header_t)) ) ); + whd_msgbuf_set_next_buffer_in_queue(whd_driver, NULL, buffer); + if (msgtx_info->send_queue_tail != NULL) + { + whd_msgbuf_set_next_buffer_in_queue(whd_driver, buffer, msgtx_info->send_queue_tail); + } + + msgtx_info->send_queue_tail = buffer; + if (msgtx_info->send_queue_head == NULL) + { + msgtx_info->send_queue_head = buffer; + } + + WPRINT_WHD_DEBUG(("Enqueue <-- send_queue_head - %p\n", msgtx_info->send_queue_head)); + msgtx_info->npkt_in_q++; + + result = cy_rtos_set_semaphore(&msgtx_info->send_queue_mutex, WHD_FALSE); + + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + return WHD_SUCCESS; +} + +static uint32_t +whd_msgbuf_flowring_create_worker(struct whd_msgbuf *msgbuf, struct whd_msgbuf_work_item *work) +{ + struct msgbuf_tx_flowring_create_req *create; + struct whd_commonring *commonring; + void *ret_ptr; + uint32_t flowid; + uint32_t flow_sz; + uint32_t address; + int err; + + flowid = work->flowid; + flow_sz = WHD_H2D_TXFLOWRING_MAX_ITEM * WHD_H2D_TXFLOWRING_ITEMSIZE; + + msgbuf->flowring_handle[flowid] = (uint32_t)whd_dmapool_alloc(flow_sz); + + if (!(msgbuf->flowring_handle[flowid]) ) + { + WPRINT_WHD_ERROR( ("DMA Alloc for FlowRingfailed\n") ); + whd_flowring_delete(msgbuf->flow, flowid); + return WHD_FLOWRING_INVALID_ID; + } + + whd_commonring_config(msgbuf->flowrings[flowid], + WHD_H2D_TXFLOWRING_MAX_ITEM, + WHD_H2D_TXFLOWRING_ITEMSIZE, (void *)msgbuf->flowring_handle[flowid]); + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_CONTROL_SUBMIT]; + whd_commonring_lock(commonring); + ret_ptr = whd_commonring_reserve_for_write(commonring); + + if (!ret_ptr) + { + WPRINT_WHD_DEBUG( ("Failed to reserve space in commonring\n") ); + whd_commonring_unlock(commonring); + whd_msgbuf_remove_flowring(msgbuf, flowid); + return WHD_FLOWRING_INVALID_ID; + } + + create = (struct msgbuf_tx_flowring_create_req *)ret_ptr; + create->msg.msgtype = MSGBUF_TYPE_FLOW_RING_CREATE; + create->msg.ifidx = work->ifidx; + create->msg.request_ptr = 0; + create->tid = whd_flowring_tid(msgbuf->flow, flowid); + create->flow_ring_id = htod16(flowid + WHD_H2D_MSGRING_FLOWRING_IDSTART); + memcpy(create->sa, work->sa, ETHER_ADDR_LEN); + memcpy(create->da, work->da, ETHER_ADDR_LEN); + address = (uint32_t)msgbuf->flowring_handle[flowid]; + create->flow_ring_addr.high_addr = 0x0; + create->flow_ring_addr.low_addr = htod32(address & 0xffffffff); + create->max_items = htod16(WHD_H2D_TXFLOWRING_MAX_ITEM); + create->len_item = htod16(WHD_H2D_TXFLOWRING_ITEMSIZE); + + WPRINT_WHD_DEBUG( ("Send Flow Create Req flow ID %lu for peer(%x:%x:%x:%x:%x:%x) prio %u ifindex %d\n", + flowid, work->da[0], work->da[1], work->da[2], work->da[3], work->da[4], work->da[5], + create->tid, work->ifidx) ); + + err = whd_commonring_write_complete(commonring); + whd_commonring_unlock(commonring); + if (err) + { + WPRINT_WHD_DEBUG( ("Failed to write commonring\n") ); + whd_msgbuf_remove_flowring(msgbuf, flowid); + return WHD_FLOWRING_INVALID_ID; + } + + return flowid; +} + +static uint32_t whd_msgbuf_flowring_create(struct whd_msgbuf *msgbuf, int ifidx, void *skb, uint32_t prio) +{ + struct whd_msgbuf_work_item *create; + ether_header_t *eh = (ether_header_t *)whd_buffer_get_current_piece_data_pointer(msgbuf->drvr, skb); + uint32_t flowid; + + create = whd_mem_malloc(sizeof(*create) ); + if (create == NULL) + return WHD_FLOWRING_INVALID_ID; + + memset(create, 0, sizeof(*create) ); + + flowid = whd_flowring_create(msgbuf->flow, eh->destination_address, prio, ifidx); + + if (flowid == WHD_FLOWRING_INVALID_ID) + { + whd_mem_free(create); + return flowid; + } + + create->flowid = flowid; + create->ifidx = ifidx; + memcpy(create->sa, eh->source_address, ETHER_ADDR_LEN); + memcpy(create->da, eh->destination_address, ETHER_ADDR_LEN); + + if (whd_msgbuf_flowring_create_worker(msgbuf, create) == WHD_FLOWRING_INVALID_ID) + { + flowid = WHD_FLOWRING_INVALID_ID; + } + whd_mem_free(create); + + return flowid; +} + +whd_result_t whd_msgbuf_tx_queue_data(whd_interface_t ifp, whd_buffer_t buffer) +{ + uint8_t *dscp = NULL; + uint8_t priority = 0; + uint32_t flowid = -1; + whd_driver_t whd_driver = ifp->whd_driver; + uint16_t ether_type; + whd_result_t result = WHD_SUCCESS; + + struct whd_msgbuf *msgbuf = (struct whd_msgbuf *)whd_driver->msgbuf; + struct whd_flowring *flow = msgbuf->flow; + + ether_header_t *ethernet_header = (ether_header_t *)whd_buffer_get_current_piece_data_pointer( + whd_driver, buffer); + + CHECK_PACKET_NULL(ethernet_header, WHD_NO_REGISTER_FUNCTION_POINTER); + ether_type = ntoh16(ethernet_header->ethertype); + + if ( ( (ether_type == WHD_ETHERTYPE_IPv4) || (ether_type == WHD_ETHERTYPE_DOT1AS) ) ) + { + dscp = (uint8_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) + IPV4_DSCP_OFFSET; + + if (dscp != NULL) + { + if (*dscp != 0) /* If it's equal 0 then it's best effort traffic and nothing needs to be done */ + { + priority = whd_map_dscp_to_priority(whd_driver, *dscp); + } + } + + } + + flowid = whd_flowring_lookup(flow, ethernet_header->destination_address, priority, ifp->ifidx); + + if (flowid == WHD_FLOWRING_INVALID_ID) + { + flowid = whd_msgbuf_flowring_create(msgbuf, ifp->ifidx, buffer, priority); + + WPRINT_WHD_DEBUG( (" %s : Created Flow Id is %lu \n", __func__, flowid) ); + + if (flowid == WHD_FLOWRING_INVALID_ID) + { + WPRINT_WHD_ERROR( ("Created Flow Id Failed\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_BADARG; + } + else + { + whd_msgbuf_txflow_enqueue(whd_driver, buffer, priority, flowid); + return WHD_SUCCESS; + } + } + + whd_msgbuf_txflow_enqueue(whd_driver, buffer, priority, flowid); + + whd_msgbuf_schedule_txdata(msgbuf, flowid, WHD_TRUE); + return WHD_SUCCESS; +} + +static whd_result_t whd_msgbuf_rxbuf_data_post(struct whd_msgbuf *msgbuf, uint32_t count) +{ + struct whd_driver *drvr = msgbuf->drvr; + struct whd_commonring *commonring; + void *ret_ptr; + whd_buffer_t rx_databuf = NULL; + uint16_t allocated; + uint32_t pktlen = 0; + struct msgbuf_rx_bufpost *rx_bufpost; + uint32_t physaddr; + uint32_t address; + uint32_t pktid; + uint8_t i = 0, result = -1; + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_RXPOST_SUBMIT]; + + ret_ptr = whd_commonring_reserve_for_write_multiple(commonring, count, &allocated); + + WPRINT_WHD_DEBUG(("%s : Allocated is %d , count is %ld \n", __func__, allocated, count)); + + if (!ret_ptr) + { + WPRINT_WHD_DEBUG( ("Failed to reserve space in commonring\n") ); + return WHD_SUCCESS; + } + + for (i = 0; i < allocated; i++) { + rx_bufpost = (struct msgbuf_rx_bufpost *)ret_ptr; + memset(rx_bufpost, 0, sizeof(*rx_bufpost)); + + result = whd_host_buffer_get(drvr, &rx_databuf, WHD_NETWORK_RX, + (uint16_t)(WHD_MSGBUF_DATA_MAX_RX_SIZE + sizeof(whd_buffer_header_t)), WHD_RX_BUF_TIMEOUT); + + if (result != WHD_SUCCESS) { + WPRINT_WHD_ERROR(("%s : Allocation Failed \n", __func__)); + whd_commonring_write_cancel(commonring, allocated - i); + break; + } + /* Since the buffer to be given to WLAN DMA, Adding 2 bytes for DMA Alignment */ + CHECK_RETURN(whd_buffer_add_remove_at_front(drvr, &rx_databuf, (int)(sizeof(whd_buffer_header_t) + 2))); + + pktlen = whd_buffer_get_current_piece_size(drvr, rx_databuf); + + WPRINT_WHD_DEBUG( ("RX Buf Data Address is 0x%lx \n", (uint32_t)rx_databuf) ); + + if (whd_msgbuf_alloc_pktid(drvr, msgbuf->rx_pktids, rx_databuf, 0, &physaddr, &pktid)) { + result = whd_buffer_release(drvr, rx_databuf, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); + WPRINT_WHD_ERROR(("No PKTID available !!\n")); + whd_commonring_write_cancel(commonring, allocated - i); + break; + } + + if (msgbuf->rx_metadata_offset) + { + address = (uint32_t)rx_databuf; + rx_bufpost->metadata_buf_len = htod16(msgbuf->rx_metadata_offset); + rx_bufpost->metadata_buf_addr.high_addr = htod32(0); + rx_bufpost->metadata_buf_addr.low_addr = htod32(address & 0xffffffff); + pktlen = WHD_MSGBUF_DATA_MAX_RX_SIZE + msgbuf->rx_metadata_offset; //skb->len; //need to check + rx_databuf = (uint8_t *)rx_databuf + msgbuf->rx_metadata_offset; + } + rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST; + rx_bufpost->msg.request_ptr = htod32(pktid); + + address = (uint32_t)physaddr; + rx_bufpost->data_buf_len = htod16(pktlen); + rx_bufpost->data_buf_addr.high_addr = htod32(0); + rx_bufpost->data_buf_addr.low_addr = htod32(address & 0xffffffff); + + ret_ptr = (uint8_t *)ret_ptr + whd_commonring_len_item(commonring); + } + + if (i) + whd_commonring_write_complete(commonring); + + return i; +} + +static void +whd_msgbuf_rxbuf_data_fill(struct whd_msgbuf *msgbuf) +{ + uint32_t fillbufs; + uint32_t retcount; + + fillbufs = msgbuf->max_rxbufpost - msgbuf->rxbufpost; + + WPRINT_WHD_DEBUG( ("%s : fillbufs - %ld \n", __func__, fillbufs) ); + + while (fillbufs) + { + retcount = whd_msgbuf_rxbuf_data_post(msgbuf, fillbufs); + WPRINT_WHD_DEBUG( ("%s : retcount is %ld \n", __func__, retcount) ); + + if (!retcount) + break; + + msgbuf->rxbufpost += retcount; + fillbufs -= retcount; + } +} + +static void whd_msgbuf_update_rxbufpost_count(struct whd_msgbuf *msgbuf, uint16_t rxcnt) +{ + msgbuf->rxbufpost -= rxcnt; + if (msgbuf->rxbufpost <= (msgbuf->max_rxbufpost - WHD_MSGBUF_RXBUFPOST_THRESHOLD) ) + whd_msgbuf_rxbuf_data_fill(msgbuf); +} + +static uint32_t +whd_msgbuf_rxbuf_ctrl_post(struct whd_msgbuf *msgbuf, uint8_t event_buf, + uint32_t count) +{ + struct whd_driver *drvr = msgbuf->drvr; + struct whd_commonring *commonring; + void *ret_ptr = NULL; + whd_buffer_t rx_ctlbuf = NULL; + uint16_t allocated; + uint32_t pktlen = 0; + struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost = NULL; + uint32_t physaddr; + uint32_t address; + uint32_t pktid; + uint8_t i = 0, result = -1; + + commonring = msgbuf->commonrings[WHD_H2D_MSGRING_CONTROL_SUBMIT]; + whd_commonring_lock(commonring); + ret_ptr = whd_commonring_reserve_for_write_multiple(commonring, count, &allocated); + + if (!ret_ptr) + { + WPRINT_WHD_ERROR( ("Failed to reserve space in commonring\n") ); + whd_commonring_unlock(commonring); + return WHD_BUS_MEM_RESERVE_FAIL; + } + + WPRINT_WHD_DEBUG( ("%s - allocated is %d \n", __func__, allocated) ); + + for (i = 0; i < allocated; i++) + { + rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr; + memset(rx_bufpost, 0, sizeof(*rx_bufpost) ); + + result = whd_host_buffer_get(drvr, &rx_ctlbuf, WHD_NETWORK_RX, + (uint16_t)WHD_MSGBUF_IOCTL_MAX_RX_SIZE, WHD_RX_BUF_TIMEOUT); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s : Allocation Failed \n", __func__) ); + whd_commonring_write_cancel(commonring, allocated - i); + break; + } + pktlen = whd_buffer_get_current_piece_size(drvr, rx_ctlbuf); + + WPRINT_WHD_DEBUG( ("RX Buf CTL Address is 0x%lx \n", (uint32_t)rx_ctlbuf) ); + + if (whd_msgbuf_alloc_pktid(drvr, msgbuf->rx_pktids, rx_ctlbuf, 0, &physaddr, &pktid) ) + { + result = whd_buffer_release(drvr, rx_ctlbuf, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + WPRINT_WHD_ERROR( ("No PKTID available !!\n") ); + whd_commonring_write_cancel(commonring, allocated - i); + break; + } + + if (event_buf) + rx_bufpost->msg.msgtype = MSGBUF_TYPE_EVENT_BUF_POST; + else + rx_bufpost->msg.msgtype = MSGBUF_TYPE_IOCTLRESP_BUF_POST; + + rx_bufpost->msg.request_ptr = htod32(pktid); + + address = (uint32_t)physaddr; + rx_bufpost->host_buf_len = htod16( (uint16_t)pktlen ); + rx_bufpost->host_buf_addr.high_addr = htod32(0); + rx_bufpost->host_buf_addr.low_addr = htod32(address & 0xffffffff); + + ret_ptr = (uint8_t *)ret_ptr + whd_commonring_len_item(commonring); + } + + if (i) + { + whd_commonring_write_complete(commonring); + } + whd_commonring_unlock(commonring); + + return i; +} + +static void whd_msgbuf_rxbuf_ioctlresp_post(struct whd_msgbuf *msgbuf) +{ + uint32_t count; + + count = msgbuf->max_ioctlrespbuf - msgbuf->cur_ioctlrespbuf; + count = whd_msgbuf_rxbuf_ctrl_post(msgbuf, 0, count); + msgbuf->cur_ioctlrespbuf += count; +} + +static void whd_msgbuf_rxbuf_event_post(struct whd_msgbuf *msgbuf) +{ + uint32_t count; + + count = msgbuf->max_eventbuf - msgbuf->cur_eventbuf; + count = whd_msgbuf_rxbuf_ctrl_post(msgbuf, 1, count); + msgbuf->cur_eventbuf += count; +} + +static struct whd_msgbuf_pktids * +whd_msgbuf_init_pktids(uint32_t nr_array_entries) +{ + struct whd_msgbuf_pktid *array; + struct whd_msgbuf_pktids *pktids; + uint32_t i = 0; + + array = (struct whd_msgbuf_pktid *)whd_mem_malloc(nr_array_entries * sizeof(*array) ); + if (array == NULL) + { + WPRINT_WHD_DEBUG( ("array allocation failed \n") ); + return NULL; + } + memset(array, 0, sizeof(struct whd_msgbuf_pktid) ); + + for(i = 0; i < nr_array_entries; i++) + { + array[i].allocated = 0; + } + + pktids = (struct whd_msgbuf_pktids *)whd_mem_malloc(sizeof(*pktids) ); + if (pktids == NULL) + { + WPRINT_WHD_DEBUG( ("pktids allocation failed \n") ); + whd_mem_free(array); + return NULL; + } + memset(pktids, 0, sizeof(struct whd_msgbuf_pktids) ); + + pktids->array = array; + pktids->array_size = nr_array_entries; + + return pktids; +} + +static void whd_msgbuf_detach(struct whd_driver *whd_driver) +{ + struct whd_msgbuf *msgbuf; + + if (whd_driver->msgbuf) + { + msgbuf = (struct whd_msgbuf *)whd_driver->msgbuf; + + //whd_mem_free(msgbuf->txstatus_done_map); + whd_mem_free(msgbuf->flow_map); + + whd_flowring_detach(msgbuf->flow); + whd_buffer_release(whd_driver, msgbuf->ioctl_buffer, WHD_NETWORK_TX); + msgbuf->ioctbuf = NULL; + whd_mem_free(msgbuf->flowring_handle); + whd_mem_free(msgbuf->flowrings); + whd_msgbuf_release_pktids(whd_driver, msgbuf); + whd_mem_free(msgbuf); + } +} + +static whd_result_t whd_msgbuf_attach(struct whd_driver *whd_driver) +{ + struct whd_msgbuf *msgbuf; + struct whd_commonring **flowrings = NULL; + uint32_t address = 0, result = 0; + uint32_t i = 0, count = 0; + uint32_t *ioct_buf = NULL; + + WPRINT_WHD_DEBUG( ("Msgbuf Attach Start \n") ); + + msgbuf = (struct whd_msgbuf *)whd_mem_malloc(sizeof(*msgbuf) ); + if (msgbuf == NULL) + { + WPRINT_WHD_DEBUG( ("msgbuf allocation failed \n") ); + return WHD_MALLOC_FAILURE; + } + memset(msgbuf, 0, sizeof(struct whd_msgbuf) ); + + count = CEIL(whd_driver->ram_shared->max_flowrings, NBBY); + count = count * sizeof(uint8_t); + msgbuf->flow_map = whd_mem_malloc(count); + if (!msgbuf->flow_map) + { + WPRINT_WHD_ERROR( ("flow_map allocation failed \n") ); + goto fail; + } + memset(msgbuf->flow_map, 0, count); + + msgbuf->drvr = whd_driver; + + result = whd_host_buffer_get(whd_driver, (whd_buffer_t )&(msgbuf->ioctl_buffer), WHD_NETWORK_TX, + (uint16_t)WHD_MSGBUF_IOCTL_MAX_TX_SIZE, WHD_RX_BUF_TIMEOUT); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s : Allocation Failed \n", __func__) ); + return result; + } + + msgbuf->ioctbuf = whd_buffer_get_current_piece_data_pointer(whd_driver, (whd_buffer_t)msgbuf->ioctl_buffer); + + if (msgbuf->ioctbuf == NULL) + { + WPRINT_WHD_ERROR( ("Ioctbuf allocation failed \n") ); + goto fail; + } + + address = (uint32_t)msgbuf->ioctbuf; + msgbuf->ioctbuf_phys_hi = 0; + msgbuf->ioctbuf_phys_lo = address & 0xffffffff; + + /* hook the commonrings in the main msgbuf structure. */ + for (i = 0; i < WHD_NROF_COMMON_MSGRINGS; i++) + msgbuf->commonrings[i] = &whd_driver->ram_shared->commonrings[i]->commonring; + + WPRINT_WHD_DEBUG( ("msgbuf commonring pointer is 0x%lx \n", (uint32_t)msgbuf->commonrings) ); + + msgbuf->flowring_handle = whd_mem_malloc(sizeof(*msgbuf->flowring_handle) * whd_driver->ram_shared->max_flowrings); + if (msgbuf->flowring_handle == NULL) + { + WPRINT_WHD_ERROR( ("Flowring_handle allocation failed \n") ); + goto fail; + } + memset(msgbuf->flowring_handle, 0, sizeof(*msgbuf->flowring_handle) * whd_driver->ram_shared->max_flowrings); + + flowrings = whd_mem_malloc(sizeof(*flowrings) * whd_driver->ram_shared->max_flowrings); + if (flowrings == NULL) + { + WPRINT_WHD_ERROR( ("Flowring allocation failed \n") ); + goto fail; + } + + for (i = 0; i < whd_driver->ram_shared->max_flowrings; i++) + flowrings[i] = &whd_driver->ram_shared->flowrings[i].commonring; + + msgbuf->flowrings = flowrings; + msgbuf->rx_dataoffset = whd_driver->ram_shared->rx_dataoffset; + msgbuf->max_rxbufpost = whd_driver->ram_shared->max_rxbufpost; + +#if 0 /* Currently WLAN FW is returning the max flowring req count as 512, which needs to be fixed */ + msgbuf->max_flowrings = whd_driver->ram_shared->max_flowrings; +#else + msgbuf->max_flowrings = 8; +#endif + + msgbuf->max_ioctlrespbuf = WHD_MSGBUF_MAX_IOCTLRESPBUF_POST; + msgbuf->max_eventbuf = WHD_MSGBUF_MAX_EVENTBUF_POST; + + msgbuf->tx_pktids = whd_msgbuf_init_pktids(NR_TX_PKTIDS); + if (!msgbuf->tx_pktids) + goto fail; + /* Create the mutex protecting the packet send queue */ + if (cy_rtos_init_semaphore(&msgbuf->tx_pktids->pktid_mutex, 1, 0) != WHD_SUCCESS) + goto fail; + if (cy_rtos_set_semaphore(&msgbuf->tx_pktids->pktid_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + msgbuf->rx_pktids = whd_msgbuf_init_pktids(NR_RX_PKTIDS); + if (!msgbuf->rx_pktids) + goto fail; + /* Create the mutex protecting the packet send queue */ + if (cy_rtos_init_semaphore(&msgbuf->rx_pktids->pktid_mutex, 1, 0) != WHD_SUCCESS) + goto fail; + if (cy_rtos_set_semaphore(&msgbuf->rx_pktids->pktid_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + msgbuf->flow = whd_flowring_attach(whd_driver, whd_driver->ram_shared->max_flowrings); + if (!msgbuf->flow) + goto fail; + + whd_driver->msgbuf = msgbuf; + + whd_msgbuf_rxbuf_ioctlresp_post(msgbuf); + whd_msgbuf_rxbuf_event_post(msgbuf); + + count = 0; + do + { + whd_msgbuf_rxbuf_data_fill(msgbuf); + + if (msgbuf->max_rxbufpost != msgbuf->rxbufpost) + { + cy_rtos_delay_milliseconds(1); + } + else + { + break; + } + count++; + } while (count < 10); + + WPRINT_WHD_DEBUG( ("Msgbuf Attach End \n") ); + return WHD_SUCCESS; + +fail: + if (msgbuf) + { + if (msgbuf->flow_map) + whd_mem_free(msgbuf->flow_map); + msgbuf->flow_map = NULL; + if (msgbuf->ioctbuf) + whd_mem_free(msgbuf->ioctbuf); + msgbuf->ioctbuf = NULL; + if (msgbuf->flowring_handle) + whd_mem_free(msgbuf->flowring_handle); + msgbuf->flowring_handle = NULL; + if (flowrings) + whd_mem_free(flowrings); + msgbuf->flowrings = NULL; + whd_msgbuf_release_pktids(whd_driver, msgbuf); + whd_mem_free(msgbuf); + whd_driver->msgbuf = NULL; + } + return WHD_MALLOC_FAILURE; +} + +void whd_msgbuf_info_deinit(whd_driver_t whd_driver) +{ + whd_msgbuf_info_t *msgbuf_info = whd_driver->proto->pd; + whd_error_info_t *error_info = &whd_driver->error_info; + + /* Delete the sleep mutex */ + (void)cy_rtos_deinit_semaphore(&msgbuf_info->ioctl_sleep); + + /* Delete the queue mutex. */ + (void)cy_rtos_deinit_semaphore(&msgbuf_info->ioctl_mutex); + + /* Delete the event list management mutex */ + (void)cy_rtos_deinit_semaphore(&msgbuf_info->event_list_mutex); + + whd_msgbuf_detach(whd_driver); + + whd_driver->proto->pd = NULL; + whd_mem_free(msgbuf_info); + + /* Delete the error list management mutex */ + (void)cy_rtos_deinit_semaphore(&error_info->event_list_mutex); +} + +whd_result_t whd_msgbuf_info_init(whd_driver_t whd_driver) +{ + whd_msgbuf_info_t *msgbuf_info; + whd_error_info_t *error_info = &whd_driver->error_info; + + msgbuf_info = (whd_msgbuf_info_t *)whd_mem_malloc(sizeof(whd_msgbuf_info_t) ); + if (!msgbuf_info) + { + return WHD_MALLOC_FAILURE; + } + + /* Create the mutex protecting the packet send queue */ + if (cy_rtos_init_semaphore(&msgbuf_info->ioctl_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&msgbuf_info->ioctl_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Create the event flag which signals the whd thread needs to wake up */ + if (cy_rtos_init_semaphore(&msgbuf_info->ioctl_sleep, 1, 0) != WHD_SUCCESS) + { + cy_rtos_deinit_semaphore(&msgbuf_info->ioctl_sleep); + return WHD_SEMAPHORE_ERROR; + } + + /* Create semaphore to protect event list management */ + if (cy_rtos_init_semaphore(&msgbuf_info->event_list_mutex, 1, 0) != WHD_SUCCESS) + { + cy_rtos_deinit_semaphore(&msgbuf_info->ioctl_sleep); + cy_rtos_deinit_semaphore(&msgbuf_info->ioctl_mutex); + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&msgbuf_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Initialise the list of event handler functions */ + memset(msgbuf_info->whd_event_list, 0, sizeof(msgbuf_info->whd_event_list) ); + + /* Create semaphore to protect event list management */ + if (cy_rtos_init_semaphore(&error_info->event_list_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + + if (cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* Initialise the list of error handler functions */ + memset(error_info->whd_event_list, 0, sizeof(error_info->whd_event_list) ); + + whd_driver->proto->get_ioctl_buffer = whd_msgbuf_get_ioctl_buffer; + whd_driver->proto->get_iovar_buffer = whd_msgbuf_get_iovar_buffer; + whd_driver->proto->set_ioctl = whd_msgbuf_set_ioctl; + whd_driver->proto->get_ioctl = whd_msgbuf_get_ioctl; + whd_driver->proto->set_iovar = whd_msgbuf_set_iovar; + whd_driver->proto->get_iovar = whd_msgbuf_get_iovar; + whd_driver->proto->tx_queue_data = whd_msgbuf_tx_queue_data; + whd_driver->proto->pd = msgbuf_info; + + CHECK_RETURN(whd_msgbuf_attach(whd_driver) ); + + return WHD_SUCCESS; +} + +#endif /* PROTO_MSGBUF */ diff --git a/wi-fi/whd/whd_network_if.c b/wi-fi/whd/whd_network_if.c index 88867770..08fc4054 100644 --- a/wi-fi/whd/whd_network_if.c +++ b/wi-fi/whd/whd_network_if.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,6 +21,7 @@ #include "whd_debug.h" #include "whd_network_if.h" +#include "whd_proto.h" /****************************************************** * * @cond Constants @@ -70,13 +71,27 @@ */ whd_result_t whd_network_process_ethernet_data(whd_interface_t ifp, whd_buffer_t buffer) { - whd_driver_t whd_driver = ifp->whd_driver; - if (whd_driver->network_if->whd_network_process_ethernet_data) { - whd_driver->network_if->whd_network_process_ethernet_data(ifp, buffer); - return WHD_SUCCESS; - } - else { - WPRINT_WHD_INFO(("Function pointers not provided .\n")); - } - return WHD_WLAN_NOFUNCTION; + whd_driver_t whd_driver = ifp->whd_driver; + if (whd_driver->network_if->whd_network_process_ethernet_data) + { + whd_driver->network_if->whd_network_process_ethernet_data(ifp, buffer); + return WHD_SUCCESS; + } + else + { + WPRINT_WHD_INFO( ("Function pointers not provided .\n") ); + } + return WHD_WLAN_NOFUNCTION; +} + +/** Sends a data packet. + * + * @param buffer : The ethernet packet buffer to be sent + * @param interface : the interface over which to send the packet (AP or STA) + * + * @return WHD result code + */ +whd_result_t whd_network_send_ethernet_data(whd_interface_t ifp, whd_buffer_t buffer) +{ + return whd_proto_tx_queue_data(ifp, buffer); } diff --git a/wi-fi/whd/whd_network_if.h b/wi-fi/whd/whd_network_if.h index 67ddf96e..e7e3a883 100644 --- a/wi-fi/whd/whd_network_if.h +++ b/wi-fi/whd/whd_network_if.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,7 +25,8 @@ #include "whd_int.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** diff --git a/wi-fi/whd/whd_network_types.h b/wi-fi/whd/whd_network_types.h index a2576433..6c28909e 100644 --- a/wi-fi/whd/whd_network_types.h +++ b/wi-fi/whd/whd_network_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,8 @@ #define INC_WHD_NETWORK_TYPES_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -51,8 +52,9 @@ typedef enum { /** * Allows WHD to perform buffer related operations like, allocating, releasing, retrieving the current pointer of and size of a packet buffer. */ -struct whd_buffer_funcs { - /** Allocates a packet buffer +struct whd_buffer_funcs +{ + /** Allocates a packet buffer * * Implemented in the port layer interface which is specific to the * buffering scheme in use. @@ -73,10 +75,10 @@ struct whd_buffer_funcs { * @return WHD_SUCCESS or error code * */ - whd_result_t (*whd_host_buffer_get)(whd_buffer_t *buffer, whd_buffer_dir_t direction, unsigned short size, - unsigned long timeout_ms); + whd_result_t (*whd_host_buffer_get)(whd_buffer_t *buffer, whd_buffer_dir_t direction, uint16_t size, + uint32_t timeout_ms); - /** Releases a packet buffer + /** Releases a packet buffer * * Implemented in the port layer interface, which will be specific to the * buffering scheme in use. @@ -91,9 +93,9 @@ struct whd_buffer_funcs { * been used for. This might be needed if tx/rx pools are separate. * */ - void (*whd_buffer_release)(whd_buffer_t buffer, whd_buffer_dir_t direction); + void (*whd_buffer_release)(whd_buffer_t buffer, whd_buffer_dir_t direction); - /** Retrieves the current pointer of a packet buffer + /** Retrieves the current pointer of a packet buffer * * Implemented in the port layer interface which is specific to the * buffering scheme in use. @@ -105,9 +107,9 @@ struct whd_buffer_funcs { * * @return The packet buffer's current pointer. */ - uint8_t *(*whd_buffer_get_current_piece_data_pointer)(whd_buffer_t buffer); + uint8_t *(*whd_buffer_get_current_piece_data_pointer)(whd_buffer_t buffer); - /** Retrieves the size of a packet buffer + /** Retrieves the size of a packet buffer * * Implemented in the port layer interface which is specific to the * buffering scheme in use. @@ -120,9 +122,9 @@ struct whd_buffer_funcs { * * @return The size of the packet buffer. */ - uint16_t (*whd_buffer_get_current_piece_size)(whd_buffer_t buffer); + uint16_t (*whd_buffer_get_current_piece_size)(whd_buffer_t buffer); - /** Sets the current size of a WHD packet + /** Sets the current size of a WHD packet * * Implemented in the port layer interface which is specific to the * buffering scheme in use. @@ -133,9 +135,9 @@ struct whd_buffer_funcs { * * @return WHD_SUCCESS or error code */ - whd_result_t (*whd_buffer_set_size)(whd_buffer_t buffer, unsigned short size); + whd_result_t (*whd_buffer_set_size)(whd_buffer_t buffer, uint16_t size); - /** Moves the current pointer of a packet buffer + /** Moves the current pointer of a packet buffer * * Implemented in the port layer interface which is specific to the buffering scheme in use. * @@ -155,7 +157,7 @@ struct whd_buffer_funcs { * * @return WHD_SUCCESS or error code */ - whd_result_t (*whd_buffer_add_remove_at_front)(whd_buffer_t *buffer, int32_t add_remove_amount); + whd_result_t (*whd_buffer_add_remove_at_front)(whd_buffer_t *buffer, int32_t add_remove_amount); }; /* @} */ @@ -167,8 +169,9 @@ struct whd_buffer_funcs { /** * Contains functions which allows WHD to pass received data to the network stack, to send an ethernet frame to WHD, etc */ -struct whd_netif_funcs { - /** Called by WHD to pass received data to the network stack +struct whd_netif_funcs +{ + /** Called by WHD to pass received data to the network stack * * * Packets received from the Wi-Fi network by WHD are forwarded to by calling function ptr which @@ -195,7 +198,7 @@ struct whd_netif_funcs { * releasing this buffer is transferred from WHD at this point. * */ - void (*whd_network_process_ethernet_data)(whd_interface_t ifp, whd_buffer_t buffer); + void (*whd_network_process_ethernet_data)(whd_interface_t ifp, whd_buffer_t buffer); }; /** To send an ethernet frame to WHD (called by the Network Stack) diff --git a/wi-fi/whd/whd_poll.h b/wi-fi/whd/whd_poll.h index 93a20c77..5746aab8 100644 --- a/wi-fi/whd/whd_poll.h +++ b/wi-fi/whd/whd_poll.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,8 @@ #define INCLUDED_WHD_POLL_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** diff --git a/wi-fi/whd/whd_proto.c b/wi-fi/whd/whd_proto.c new file mode 100644 index 00000000..5ea14406 --- /dev/null +++ b/wi-fi/whd/whd_proto.c @@ -0,0 +1,100 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * + * Implements functions called by WHD user APIs, but not directly exposed to user + * + * This file provides functions which are not directly exposed to user but, called by end-user functions which allow actions such as + * setting the MAC address, getting channel info, etc + */ + +#include "whd_utils.h" +#include "whd_int.h" +#include "whd_proto.h" +#ifndef PROTO_MSGBUF +#include "whd_cdc_bdc.h" +#else +#include "whd_msgbuf.h" +#endif +#include "bus_protocols/whd_bus.h" + +/****************************************************** +* @cond Constants +******************************************************/ + +/****************************************************** +* Local Structures +******************************************************/ + + + +/****************************************************** +* Variables +******************************************************/ + +/****************************************************** +* Function definitions +******************************************************/ + +whd_result_t whd_proto_attach(whd_driver_t whd_driver) +{ + struct whd_proto *proto; + + proto = (struct whd_proto *)whd_mem_malloc(sizeof(struct whd_proto) ); + if (!proto) + { + return WHD_MALLOC_FAILURE; + } + whd_driver->proto = proto; + +#ifndef PROTO_MSGBUF + if (whd_cdc_bdc_info_init(whd_driver) != WHD_SUCCESS) + { + goto fail; + } +#else + if (whd_msgbuf_info_init(whd_driver) != WHD_SUCCESS) + { + goto fail; + } +#endif /* PROTO_MSGBUF */ + + return WHD_SUCCESS; + +fail: + WPRINT_WHD_ERROR( ("%s, proto type %d\n", __FUNCTION__, whd_driver->proto_type) ); + + whd_mem_free(proto); + whd_driver->proto = NULL; + return WHD_WLAN_NOMEM; +} + +whd_result_t whd_proto_detach(whd_driver_t whd_driver) +{ + if (whd_driver->proto) + { +#ifndef PROTO_MSGBUF + whd_cdc_bdc_info_deinit(whd_driver); +#else + whd_msgbuf_info_deinit(whd_driver); +#endif /* PROTO_MSGBUF */ + whd_mem_free(whd_driver->proto); + whd_driver->proto = NULL; + } + return WHD_SUCCESS; +} diff --git a/wi-fi/whd/whd_proto.h b/wi-fi/whd/whd_proto.h new file mode 100644 index 00000000..2879161e --- /dev/null +++ b/wi-fi/whd/whd_proto.h @@ -0,0 +1,97 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file WHD proto + * + * Utilities to help do specialized (not general purpose) WHD specific things + */ + +#ifndef INCLUDED_WHD_PROTO_H_ +#define INCLUDED_WHD_PROTO_H_ + +#include "whd_int.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** +* Structures +******************************************************/ +struct whd_proto +{ + void *(*get_ioctl_buffer)(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t data_length); + void *(*get_iovar_buffer)(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t data_length, const char *name); + whd_result_t (*set_ioctl)(whd_interface_t ifp, uint32_t command, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd); + whd_result_t (*get_ioctl)(whd_interface_t ifp, uint32_t command, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd); + whd_result_t (*set_iovar)(whd_interface_t ifp, whd_buffer_t send_buffer_hnd, whd_buffer_t *response_buffer_hnd); + whd_result_t (*get_iovar)(whd_interface_t ifp, whd_buffer_t send_buffer_hnd, whd_buffer_t *response_buffer_hnd); + whd_result_t (*tx_queue_data)(whd_interface_t ifp, whd_buffer_t buffer); + void *pd; +}; + +whd_result_t whd_proto_attach(whd_driver_t whd_driver); + +whd_result_t whd_proto_detach(whd_driver_t whd_driver); + +static inline void *whd_proto_get_ioctl_buffer(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t data_length) +{ + return whd_driver->proto->get_ioctl_buffer(whd_driver, buffer, data_length); +} + +static inline void *whd_proto_get_iovar_buffer(whd_driver_t whd_driver, whd_buffer_t *buffer, uint16_t data_length, + const char *name) +{ + return whd_driver->proto->get_iovar_buffer(whd_driver, buffer, data_length, name); +} + +static inline whd_result_t whd_proto_set_ioctl(whd_interface_t ifp, uint32_t command, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return ifp->whd_driver->proto->set_ioctl(ifp, command, send_buffer_hnd, response_buffer_hnd); +} + +static inline whd_result_t whd_proto_get_ioctl(whd_interface_t ifp, uint32_t command, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return ifp->whd_driver->proto->get_ioctl(ifp, command, send_buffer_hnd, response_buffer_hnd); +} + +static inline whd_result_t whd_proto_set_iovar(whd_interface_t ifp, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return ifp->whd_driver->proto->set_iovar(ifp, send_buffer_hnd, response_buffer_hnd); +} + +static inline whd_result_t whd_proto_get_iovar(whd_interface_t ifp, whd_buffer_t send_buffer_hnd, + whd_buffer_t *response_buffer_hnd) +{ + return ifp->whd_driver->proto->get_iovar(ifp, send_buffer_hnd, response_buffer_hnd); +} + +static inline whd_result_t whd_proto_tx_queue_data(whd_interface_t ifp, whd_buffer_t buffer) +{ + return ifp->whd_driver->proto->tx_queue_data(ifp, buffer); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif diff --git a/wi-fi/whd/whd_resource_api.h b/wi-fi/whd/whd_resource_api.h index 0e7acea2..083f3809 100644 --- a/wi-fi/whd/whd_resource_api.h +++ b/wi-fi/whd/whd_resource_api.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,10 +28,16 @@ #define INCLUDED_WHD_RESOURCE_API_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define BLOCK_SIZE 1024 /**< Size of the block */ + +#ifndef NVM_IMAGE_SIZE_ALIGNMENT +#define NVM_IMAGE_SIZE_ALIGNMENT 4 /**< The alignment size of NVRAM image */ +#endif + /** * Type of resources */ @@ -66,8 +72,9 @@ typedef enum { * the physical number of blocks in the data and each call to whd_get_resource_block will read data from the external memory * and make it available via an internal buffer. */ -struct whd_resource_source { - /** Gets the size of the resource for respective resource type +struct whd_resource_source +{ + /** Gets the size of the resource for respective resource type * * * @param whd_drv Pointer to handle instance of the driver @@ -77,9 +84,9 @@ struct whd_resource_source { * @return WHD_SUCCESS or error code * */ - uint32_t (*whd_resource_size)(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out); + uint32_t (*whd_resource_size)(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out); - /** Gets the resource block for specified resource type + /** Gets the resource block for specified resource type * * @param whd_drv Pointer to handle instance of the driver * @param type Type of resource - WHD_RESOURCE_WLAN_FIRMWARE, WHD_RESOURCE_WLAN_NVRAM, WHD_RESOURCE_WLAN_CLM @@ -90,10 +97,10 @@ struct whd_resource_source { * @return WHD_SUCCESS or error code * */ - uint32_t (*whd_get_resource_block)(whd_driver_t whd_drv, whd_resource_type_t type, - uint32_t blockno, const uint8_t **data, uint32_t *size_out); + uint32_t (*whd_get_resource_block)(whd_driver_t whd_drv, whd_resource_type_t type, + uint32_t blockno, const uint8_t **data, uint32_t *size_out); - /** Gets block count for the specified resource_type + /** Gets block count for the specified resource_type * * @param whd_drv Pointer to handle instance of the driver * @param type Type of resource - WHD_RESOURCE_WLAN_FIRMWARE, WHD_RESOURCE_WLAN_NVRAM, WHD_RESOURCE_WLAN_CLM @@ -102,9 +109,9 @@ struct whd_resource_source { * @return WHD_SUCCESS or error code * */ - uint32_t (*whd_get_resource_no_of_blocks)(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count); + uint32_t (*whd_get_resource_no_of_blocks)(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count); - /** Gets block size for the specified resource_type + /** Gets block size for the specified resource_type * * @param whd_drv Pointer to handle instance of the driver * @param type Type of resources - WHD_RESOURCE_WLAN_FIRMWARE, WHD_RESOURCE_WLAN_NVRAM, WHD_RESOURCE_WLAN_CLM @@ -113,9 +120,9 @@ struct whd_resource_source { * @return WHD_SUCCESS or error code * */ - uint32_t (*whd_get_resource_block_size)(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out); + uint32_t (*whd_get_resource_block_size)(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out); - /** Gets the resource for specified resource type + /** Gets the resource for specified resource type * * @param whd_drv Pointer to handle instance of the driver * @param type Type of resource - WHD_RESOURCE_WLAN_FIRMWARE, WHD_RESOURCE_WLAN_NVRAM, WHD_RESOURCE_WLAN_CLM @@ -127,8 +134,8 @@ struct whd_resource_source { * @return WHD_SUCCESS or error code * */ - uint32_t (*whd_resource_read)(whd_driver_t whd_drv, whd_resource_type_t type, - uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer); + uint32_t (*whd_resource_read)(whd_driver_t whd_drv, whd_resource_type_t type, + uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer); }; /** @} */ diff --git a/wi-fi/whd/whd_resource_if.c b/wi-fi/whd/whd_resource_if.c index 84d61e79..5d3bdab6 100644 --- a/wi-fi/whd/whd_resource_if.c +++ b/wi-fi/whd/whd_resource_if.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,64 +44,74 @@ ******************************************************/ uint32_t whd_resource_size(whd_driver_t whd_driver, whd_resource_type_t resource, uint32_t *size_out) { - if (whd_driver->resource_if->whd_resource_size) { - return whd_driver->resource_if->whd_resource_size(whd_driver, resource, size_out); - } - else { - WPRINT_WHD_ERROR(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->resource_if->whd_resource_size) + { + return whd_driver->resource_if->whd_resource_size(whd_driver, resource, size_out); + } + else + { + WPRINT_WHD_ERROR( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } uint32_t whd_get_resource_block_size(whd_driver_t whd_driver, whd_resource_type_t type, uint32_t *size_out) { - if (whd_driver->resource_if->whd_get_resource_block_size) { - return whd_driver->resource_if->whd_get_resource_block_size(whd_driver, type, size_out); - } - else { - WPRINT_WHD_ERROR(("Function pointers not provided .\n")); - } + if (whd_driver->resource_if->whd_get_resource_block_size) + { + return whd_driver->resource_if->whd_get_resource_block_size(whd_driver, type, size_out); + } + else + { + WPRINT_WHD_ERROR( ("Function pointers not provided .\n") ); + } - return WHD_WLAN_NOFUNCTION; + return WHD_WLAN_NOFUNCTION; } uint32_t whd_get_resource_no_of_blocks(whd_driver_t whd_driver, whd_resource_type_t type, uint32_t *block_count) { - if (whd_driver->resource_if->whd_get_resource_no_of_blocks) { - return whd_driver->resource_if->whd_get_resource_no_of_blocks(whd_driver, type, block_count); - } - else { - WPRINT_WHD_ERROR(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->resource_if->whd_get_resource_no_of_blocks) + { + return whd_driver->resource_if->whd_get_resource_no_of_blocks(whd_driver, type, block_count); + } + else + { + WPRINT_WHD_ERROR( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } uint32_t whd_get_resource_block(whd_driver_t whd_driver, whd_resource_type_t type, - uint32_t blockno, const uint8_t **data, uint32_t *size_out) + uint32_t blockno, const uint8_t **data, uint32_t *size_out) { - if (whd_driver->resource_if->whd_get_resource_block) { - return whd_driver->resource_if->whd_get_resource_block(whd_driver, type, blockno, data, size_out); - } - else { - WPRINT_WHD_ERROR(("Function pointers not provided .\n")); - } + if (whd_driver->resource_if->whd_get_resource_block) + { + return whd_driver->resource_if->whd_get_resource_block(whd_driver, type, blockno, data, size_out); + } + else + { + WPRINT_WHD_ERROR( ("Function pointers not provided .\n") ); + } - return WHD_WLAN_NOFUNCTION; + return WHD_WLAN_NOFUNCTION; } uint32_t whd_resource_read(whd_driver_t whd_driver, whd_resource_type_t type, uint32_t offset, - uint32_t size, uint32_t *size_out, void *buffer) + uint32_t size, uint32_t *size_out, void *buffer) { - if (whd_driver->resource_if->whd_resource_read) { - return whd_driver->resource_if->whd_resource_read(whd_driver, type, offset, size, size_out, buffer); - } - else { - WPRINT_WHD_ERROR(("Function pointers not provided .\n")); - } - - return WHD_WLAN_NOFUNCTION; + if (whd_driver->resource_if->whd_resource_read) + { + return whd_driver->resource_if->whd_resource_read(whd_driver, type, offset, size, size_out, buffer); + } + else + { + WPRINT_WHD_ERROR( ("Function pointers not provided .\n") ); + } + + return WHD_WLAN_NOFUNCTION; } diff --git a/wi-fi/whd/whd_resource_if.h b/wi-fi/whd/whd_resource_if.h index 9124621a..3e67a9f5 100644 --- a/wi-fi/whd/whd_resource_if.h +++ b/wi-fi/whd/whd_resource_if.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,7 +26,8 @@ #include "whd_resource_api.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -44,10 +45,10 @@ uint32_t whd_resource_size(whd_driver_t whd_driver, whd_resource_type_t resource uint32_t whd_get_resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out); uint32_t whd_get_resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count); uint32_t whd_get_resource_block(whd_driver_t whd_driver, whd_resource_type_t type, - uint32_t blockno, const uint8_t **data, uint32_t *size_out); + uint32_t blockno, const uint8_t **data, uint32_t *size_out); uint32_t whd_resource_read(whd_driver_t whd_driver, whd_resource_type_t type, uint32_t offset, - uint32_t size, uint32_t *size_out, void *buffer); + uint32_t size, uint32_t *size_out, void *buffer); #ifdef __cplusplus } /*extern "C" */ diff --git a/wi-fi/whd/whd_resources.c b/wi-fi/whd/whd_resources.c index 5a13a0e2..a1c45761 100644 --- a/wi-fi/whd/whd_resources.c +++ b/wi-fi/whd/whd_resources.c @@ -27,11 +27,23 @@ #include #include +#include "lwipopts.h" -#define AW_NM512_FIRMWARE_FILENAME "/firmware/43439A0.bin" -#define AW_NM512_CLM_FILENAME "/firmware/43439A0.clm_blob" -#define STERLING_LWB_FIRMWARE_FILENAME "/firmware/brcmfmac43430-sdio-prod.bin" -#define STERLING_LWB_CLM_FILENAME "/firmware/brcmfmac43430-sdio.clm_blob" +#ifndef WIFI_FIRMWARE_FILES_DIRECTORY_PATH +#define WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/firmware" +#endif + +#ifndef FIRMWARE_FILE_EXTENSION +#define FIRMWARE_FILE_EXTENSION ".bin" +#endif + +#ifndef CLM_FILE_EXTENSION +#define CLM_FILE_EXTENSION ".clm_blob" +#endif + +#define AW_NM512_FILENAME "43439A0" +#define STERLING_LWB_FILENAME "brcmfmac43430-sdio-prod" +#define STERLING_LWB5PLUS_FILENAME "4373A0" static uint8_t resource_buf[BLOCK_SIZE]; @@ -52,7 +64,7 @@ int read_file(const char *filename, off_t pos, size_t len, uint8_t *buf) FILE *file; size_t n; - file = fopen(filename, "r"); + file = fopen(filename, "rb"); if (!file) return -1; @@ -73,12 +85,18 @@ static const char *host_firmware_filename(whd_driver_t whd_drv) { uint16_t chip_id = whd_chip_get_chip_id(whd_drv); - if (chip_id == 43430) - return STERLING_LWB_FIRMWARE_FILENAME; - else if (chip_id == 43439) - return AW_NM512_FIRMWARE_FILENAME; - else + if (chip_id == 43430) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" STERLING_LWB_FILENAME FIRMWARE_FILE_EXTENSION; + } + else if (chip_id == 43439) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" AW_NM512_FILENAME FIRMWARE_FILE_EXTENSION; + } + else if (chip_id == 0x4373) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" STERLING_LWB5PLUS_FILENAME FIRMWARE_FILE_EXTENSION; + } + else { return NULL; + } } @@ -86,12 +104,18 @@ static const char *host_clm_filename(whd_driver_t whd_drv) { uint16_t chip_id = whd_chip_get_chip_id(whd_drv); - if (chip_id == 43430) - return STERLING_LWB_CLM_FILENAME; - else if (chip_id == 43439) - return AW_NM512_CLM_FILENAME; - else + if (chip_id == 43430) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" STERLING_LWB_FILENAME CLM_FILE_EXTENSION; + } + else if (chip_id == 43439) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" AW_NM512_FILENAME CLM_FILE_EXTENSION; + } + else if (chip_id == 0x4373) { + return WIFI_FIRMWARE_FILES_DIRECTORY_PATH "/" STERLING_LWB5PLUS_FILENAME CLM_FILE_EXTENSION; + } + else { return NULL; + } } @@ -99,12 +123,18 @@ static const char *host_nvram_image(whd_driver_t whd_drv) { uint16_t chip_id = whd_chip_get_chip_id(whd_drv); - if (chip_id == 43430) + if (chip_id == 43430) { return sterling_lwb_wifi_nvram_image; - else if (chip_id == 43439) + } + else if (chip_id == 43439) { return aw_nm512_wifi_nvram_image; - else + } + else if (chip_id == 0x4373) { + return sterling_lwb5plus_wifi_nvram_image; + } + else { return NULL; + } } @@ -112,12 +142,18 @@ static ssize_t host_nvram_size(whd_driver_t whd_drv) { uint16_t chip_id = whd_chip_get_chip_id(whd_drv); - if (chip_id == 43430) + if (chip_id == 43430) { return sizeof(sterling_lwb_wifi_nvram_image); - else if (chip_id == 43439) + } + else if (chip_id == 43439) { return sizeof(aw_nm512_wifi_nvram_image); - else + } + else if (chip_id == 0x4373) { + return sizeof(sterling_lwb5plus_wifi_nvram_image); + } + else { return -1; + } } @@ -231,9 +267,72 @@ uint32_t host_get_resource_block(whd_driver_t whd_drv, whd_resource_type_t type, } +uint32_t host_resource_read(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t offset, uint32_t size, uint32_t *size_out, void *buffer) +{ + const char *filename, *image; + uint32_t result, resource_size; + + result = host_resource_size(whd_drv, type, &resource_size); + if (result != WHD_SUCCESS) { + return result; + } + + if (offset >= resource_size) { + return WHD_BADARG; + } + + if (offset + size >= resource_size) { + size = resource_size - offset; + } + + memset(buffer, 0, size); + + switch (type) { + case WHD_RESOURCE_WLAN_FIRMWARE: + filename = host_firmware_filename(whd_drv); + if (filename == NULL) { + return WHD_HAL_ERROR; + } + + if (read_file(filename, offset, size, buffer) < 0) { + return WHD_HAL_ERROR; + } + break; + + case WHD_RESOURCE_WLAN_NVRAM: + image = host_nvram_image(whd_drv); + if (image == NULL) { + return WHD_HAL_ERROR; + } + + memcpy(buffer, image + offset, size); + break; + + case WHD_RESOURCE_WLAN_CLM: + filename = host_clm_filename(whd_drv); + if (filename == NULL) { + return WHD_HAL_ERROR; + } + + if (read_file(filename, offset, size, buffer) < 0) { + return WHD_HAL_ERROR; + } + break; + + default: + return WHD_BADARG; + } + + *size_out = size; + + return WHD_SUCCESS; +} + + whd_resource_source_t resource_ops = { .whd_resource_size = host_resource_size, .whd_get_resource_block_size = host_get_resource_block_size, .whd_get_resource_no_of_blocks = host_get_resource_no_of_blocks, - .whd_get_resource_block = host_get_resource_block + .whd_get_resource_block = host_get_resource_block, + .whd_resource_read = host_resource_read, }; diff --git a/wi-fi/whd/whd_ring.c b/wi-fi/whd/whd_ring.c new file mode 100644 index 00000000..9ffd974c --- /dev/null +++ b/wi-fi/whd/whd_ring.c @@ -0,0 +1,708 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @file + * Provides generic Ring functionality that chip specific files use + */ +#ifdef PROTO_MSGBUF + +#include "whd_utils.h" +#include "whd_int.h" +#include "whd_ring.h" +#include "whd_chip_constants.h" +#include "bus_protocols/whd_bus_protocol_interface.h" +#include "whd_oci.h" +#include "whd_buffer_api.h" + +#ifdef GCI_SECURE_ACCESS +#include "whd_hw.h" +#endif + +#define HT_AVAIL_WAIT_MS (1) +#define WLAN_BUS_UP_ATTEMPTS (1000) +#define WHD_HOST_TRIGGER_SUSPEND_TIMEOUT (WHD_MBDATA_TIMEOUT + 2 * 1000) +#define HOST_TRIGGER_SUSPEND_COMPLETE (1UL << 0) + +static int whd_ring_mb_ring_bell(void *ctx) +{ + WPRINT_WHD_DEBUG( ("RINGING !!!\n") ); + + /* Any arbitrary value will do, lets use 1 */ +#ifndef GCI_SECURE_ACCESS + struct whd_ringbuf *ring = (struct whd_ringbuf *)ctx; + whd_driver_t whd_driver = ring->whd_drv; + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_DB0_REG, 4, 0x01) ); +#else + CHECK_RETURN(whd_hw_generateBt2WlDbInterruptApi(0, 0x01)); +#endif + + return WHD_SUCCESS; +} + +static int whd_ring_mb_update_rptr(void *ctx) +{ + struct whd_ringbuf *ring = (struct whd_ringbuf *)ctx; + whd_driver_t whd_driver = ring->whd_drv; + struct whd_commonring *commonring = &ring->commonring; + + commonring->r_ptr = whd_driver->read_ptr(whd_driver, ring->r_idx_addr); + + WPRINT_WHD_DEBUG( ("<== R : r_ptr %d (%d), ring_id %d\n", commonring->r_ptr, + commonring->w_ptr, ring->id) ); + + return WHD_SUCCESS; +} + +static int whd_ring_mb_update_wptr(void *ctx) +{ + struct whd_ringbuf *ring = (struct whd_ringbuf *)ctx; + whd_driver_t whd_driver = ring->whd_drv; + struct whd_commonring *commonring = &ring->commonring; + + commonring->w_ptr = whd_driver->read_ptr(whd_driver, ring->w_idx_addr); + + WPRINT_WHD_DEBUG( ("<== R : w_ptr %d (%d), ring_id %d\n", commonring->w_ptr, + commonring->r_ptr, ring->id) ); + + return WHD_SUCCESS; +} + +static int whd_ring_mb_write_rptr(void *ctx) +{ + struct whd_ringbuf *ring = (struct whd_ringbuf *)ctx; + whd_driver_t whd_driver = ring->whd_drv; + struct whd_commonring *commonring = &ring->commonring; + + WPRINT_WHD_DEBUG( ("==> W: r_ptr %d (%d), ring_id %d, r_idx_addr 0x%lx \n", commonring->r_ptr, + commonring->w_ptr, ring->id, ring->r_idx_addr) ); + + whd_driver->write_ptr(whd_driver, ring->r_idx_addr, commonring->r_ptr); + + return WHD_SUCCESS; +} + +static int whd_ring_mb_write_wptr(void *ctx) +{ + struct whd_ringbuf *ring = (struct whd_ringbuf *)ctx; + whd_driver_t whd_driver = ring->whd_drv; + struct whd_commonring *commonring = &ring->commonring; + + WPRINT_WHD_DEBUG( ("==> W: w_ptr %d (%d), ring_id %d, w_idx_addr 0x%lx \n", commonring->w_ptr, + commonring->r_ptr, ring->id, ring->w_idx_addr) ); + + whd_driver->write_ptr(whd_driver, ring->w_idx_addr, commonring->w_ptr); + + return WHD_SUCCESS; +} + +static uint16_t whd_read_tcm16(whd_driver_t whd_driver, uint32_t mem_offset) +{ + uint32_t address = mem_offset; + + return REG16(TRANS_ADDR(address) ); +} + +static void whd_write_tcm16(whd_driver_t whd_driver, uint32_t mem_offset, uint16_t value) +{ + uint32_t address = mem_offset; + + REG16(TRANS_ADDR(address) ) = value; +} + +static void whd_write_tcm32(whd_driver_t whd_driver, uint32_t mem_offset, uint32_t value) +{ + uint32_t address = mem_offset; + + REG32(TRANS_ADDR(address) ) = value; +} + +void whd_bus_handle_mb_data(whd_driver_t whd_driver, uint32_t d2h_mb_data) +{ + WPRINT_WHD_DEBUG( ("D2H_MB_DATA: 0x%04x\n", (unsigned int)d2h_mb_data) ); + + if (d2h_mb_data & WHD_D2H_DEV_DS_ENTER_REQ) + { + WPRINT_WHD_DEBUG( ("D2H_MB_DATA: DEEP SLEEP REQ\n") ); + //whd_pcie_send_mb_data(devinfo, WHD_H2D_HOST_DS_ACK); + //WPRINT_WHD_DEBUG( ("D2H_MB_DATA: sent DEEP SLEEP ACK\n") ); + } + + if (d2h_mb_data & WHD_D2H_DEV_DS_EXIT_NOTE) + WPRINT_WHD_DEBUG( ("D2H_MB_DATA: DEEP SLEEP EXIT\n") ); + + if (d2h_mb_data & WHD_D2H_DEV_D3_ACK) + { + WPRINT_WHD_DEBUG( ("D2H_MB_DATA: D3 ACK\n") ); + + whd_driver->ack_d2h_suspend = 1; + + /* Disable WLAN force HT clock */ + CHECK_RETURN_IGNORE(whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_CLOCK_CSR, 4, 0) ); + + cy_rtos_setbits_event(&whd_driver->host_suspend_event_wait, (uint32_t)HOST_TRIGGER_SUSPEND_COMPLETE, false); + } + + if (d2h_mb_data & WHD_D2H_DEV_FWHALT) + { + WPRINT_WHD_DEBUG( ("D2H_MB_DATA: FW HALT\n") ); + //whd_fw_crashed(&devinfo->pdev->dev); + } +} + +whd_result_t whd_host_trigger_suspend(whd_driver_t whd_driver) +{ + uint32_t flags; + int retval; + + CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->host_suspend_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) ); + + /* Set flag to let WHD Thread, suspend is triggered by Host */ + whd_driver->host_trigger_suspend_flag = 1; + + cy_rtos_clearbits_event(&whd_driver->host_suspend_event_wait, (uint32_t)HOST_TRIGGER_SUSPEND_COMPLETE, false); + + /* Wake up whd thread to suspend */ + whd_thread_notify(whd_driver); + + /* Wait WHD thread return suspend is OK or not(need check system view logic) */ + flags = (uint32_t)HOST_TRIGGER_SUSPEND_COMPLETE; + retval = + cy_rtos_waitbits_event(&whd_driver->host_suspend_event_wait, &flags, true, false, + WHD_HOST_TRIGGER_SUSPEND_TIMEOUT); + + whd_driver->host_trigger_suspend_flag = 0; + + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->host_suspend_mutex, WHD_FALSE) ); + + if (CY_RTOS_TIMEOUT == retval) + { + WPRINT_WHD_ERROR( ("Timeout on response for host suspend(no D3_Ack on time)\n") ); + return CY_RTOS_TIMEOUT; + } + + return WHD_SUCCESS; +} + +whd_result_t whd_host_trigger_resume(whd_driver_t whd_driver) +{ + /* Do nothing, because other place will wake up whd thread if any tx/rx */ + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_suspend(whd_driver_t whd_driver) +{ + if (whd_bus_is_up(whd_driver) == WHD_FALSE) + { + WPRINT_WHD_ERROR( ("Bus is already in SUSPEND state.\n") ); + return WHD_SUCCESS; + } + + whd_bus_set_state(whd_driver, WHD_FALSE); + + /* Host trigger suspend or not */ + if (whd_driver->host_trigger_suspend_flag == 1) + { + whd_driver->host_trigger_suspend_flag = 0; + + whd_msgbuf_send_mbdata(whd_driver, WHD_H2D_HOST_D3_INFORM); + } + else + { + /* Disable WLAN force HT clock */ + CHECK_RETURN_IGNORE(whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_CLOCK_CSR, 4, 0) ); + } + + return WHD_SUCCESS; +} + +whd_result_t whd_bus_resume(whd_driver_t whd_driver) +{ + whd_result_t result = WHD_SUCCESS; + uint32_t csr = 0; + uint32_t attempts = 0; + + /* Check register “BT2WL Clock Request and Status Register (Offset 0x6A4)” + * if ALP or HT not available on WLAN backplane then set ALPAvailRequest (AQ) before accessing the TCM. + * Make sure ALPClockAvailable (AA) is available before accessing the TCM. */ + while ( ( (result = whd_bus_read_backplane_value(whd_driver, GCI_BT2WL_CLOCK_CSR, + (uint8_t)sizeof(csr), (uint8_t *)&csr) ) == WHD_SUCCESS ) && + ( (csr & (GCI_ALP_AVAIL | GCI_HT_AVAIL) ) == 0 ) && + (attempts < (uint32_t)WLAN_BUS_UP_ATTEMPTS) ) + { + CHECK_RETURN(whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_CLOCK_CSR, + (uint8_t)4, (uint32_t)GCI_ALP_AVAIL_REQ) ); + (void)cy_rtos_delay_milliseconds( (uint32_t)HT_AVAIL_WAIT_MS ); /* Ignore return - nothing can be done if it fails */ + attempts++; + } + + if (attempts >= (uint32_t)WLAN_BUS_UP_ATTEMPTS) + { + WPRINT_WHD_ERROR( ("WLAN bus HT Clock failed to come up , %s failed at %d \n", __func__, __LINE__) ); + return WHD_BUS_UP_FAIL; + } + + /* Host trigger suspend or not */ + if (whd_driver->ack_d2h_suspend == 1) + { + whd_driver->ack_d2h_suspend = 0; + /* If Resume from Host, send H1D DB1 to "WLAN FW" */ + WPRINT_WHD_DEBUG( ("Notify Firmware about HOST READY!!! \n") ); + result = whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_DB1_REG, 4, (1 << 9) ); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_write_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + } + } + + return WHD_SUCCESS; +} + +static struct whd_ringbuf *whd_allocate_ring_and_handle(whd_driver_t whd_driver, uint32_t ring_id, + uint32_t tcm_ring_phys_addr) +{ + uint32_t* ring_handle = NULL; + struct whd_ringbuf *ring; + uint32_t size; + uint32_t addr; + uint32_t ring_addr; + const uint32_t *ring_itemsize_array; + + if (whd_driver->ram_shared->version_new < WHD_PCIE_SHARED_VERSION_7) + ring_itemsize_array = whd_ring_itemsize_pre_v7; + else + ring_itemsize_array = whd_ring_itemsize; + + size = whd_ring_max_item[ring_id] * ring_itemsize_array[ring_id]; + + WPRINT_WHD_DEBUG( ("Allocate Ring Handle: %s\n", __func__) ); + ring_handle = whd_dmapool_alloc(size); + + if(ring_handle == NULL) + return NULL; + + ring_addr = (uint32_t)ring_handle; + + WPRINT_WHD_DEBUG( ("tcm_ring_phys_addr is 0x%lx, ring_addr is 0x%lx, ring_handle is 0x%lx \n", tcm_ring_phys_addr, + ring_addr, (uint32_t)ring_handle) ); + + whd_write_tcm32(whd_driver, tcm_ring_phys_addr + WHD_RING_MEM_BASE_ADDR_OFFSET, dtoh32(ring_addr & 0xffffffff) ); + whd_write_tcm32(whd_driver, tcm_ring_phys_addr + WHD_RING_MEM_BASE_ADDR_OFFSET + 4, 0); + + WPRINT_WHD_DEBUG( ("%s : Ring Handle Address For ring id[%lu] is 0x%lx\n", __func__, ring_id, + (uint32_t)ring_handle) ); + + WPRINT_WHD_DEBUG( ("Read the value at ringmem ptr[0x%lx] at TCM - 0x%lx \n", + (tcm_ring_phys_addr + WHD_RING_MEM_BASE_ADDR_OFFSET), + REG32(TRANS_ADDR(tcm_ring_phys_addr + WHD_RING_MEM_BASE_ADDR_OFFSET) ) ) ); + + addr = tcm_ring_phys_addr + WHD_RING_MAX_ITEM_OFFSET; + whd_write_tcm16(whd_driver, addr, whd_ring_max_item[ring_id]); + addr = tcm_ring_phys_addr + WHD_RING_LEN_ITEMS_OFFSET; + whd_write_tcm16(whd_driver, addr, ring_itemsize_array[ring_id]); + + ring = whd_mem_malloc(sizeof(*ring) ); + + if (!ring) + { + return NULL; + } + memset(ring, 0, sizeof(*ring) ); + whd_commonring_config(&ring->commonring, whd_ring_max_item[ring_id], + ring_itemsize_array[ring_id], (void*)ring_handle); + + ring->ring_handle = ring_handle; + ring->whd_drv = whd_driver; + + whd_commonring_register_cb(&ring->commonring, + whd_ring_mb_ring_bell, + whd_ring_mb_update_rptr, + whd_ring_mb_update_wptr, + whd_ring_mb_write_rptr, + whd_ring_mb_write_wptr, ring); + + return (ring); +} + +static whd_result_t whd_release_ringbuffer(whd_driver_t whd_driver, + struct whd_ringbuf *ring) +{ + void *dma_buf; + + if (!ring) + return WHD_BUFFER_ALLOC_FAIL; + + dma_buf = ring->commonring.buf_addr; + if (dma_buf) + { + whd_mem_free(ring->ring_handle); + } + whd_mem_free(ring); + + return WHD_SUCCESS; +} + +static void whd_release_ringbuffers(whd_driver_t whd_driver) +{ + uint32_t i; + + for (i = 0; i < WHD_NROF_COMMON_MSGRINGS; i++) + { + whd_release_ringbuffer(whd_driver, whd_driver->ram_shared->commonrings[i]); + whd_driver->ram_shared->commonrings[i] = NULL; + } + whd_mem_free(whd_driver->ram_shared->flowrings); + whd_driver->ram_shared->flowrings = NULL; +} + +uint32_t whd_bus_m2m_ring_init(whd_driver_t whd_driver) +{ + struct whd_dhi_ringinfo ringinfo; + whd_result_t result = WHD_SUCCESS; + struct whd_ringbuf *ring; + struct whd_ringbuf *rings; + uint32_t d2h_w_idx_ptr = 0; + uint32_t d2h_r_idx_ptr = 0; + uint32_t h2d_w_idx_ptr = 0; + uint32_t h2d_r_idx_ptr = 0; + uint32_t ring_mem_ptr = 0; + uint32_t i; + uint8_t idx_offset; + uint16_t max_flowrings; + uint16_t max_submissionrings; + uint16_t max_completionrings; + + result = whd_bus_mem_bytes(whd_driver, BUS_READ, TRANS_ADDR(whd_driver->ram_shared->ring_info_addr), + sizeof(ringinfo), (uint8_t *)&ringinfo); + if (result != 0) + { + WPRINT_WHD_ERROR( ("%s: Read Ring Info failed\n", __func__) ); + return result; + } + + if (whd_driver->ram_shared->version_new >= 6) + { + max_submissionrings = dtoh16(ringinfo.max_submissionrings); + max_flowrings = dtoh16(ringinfo.max_flowrings); + max_completionrings = dtoh16(ringinfo.max_completionrings); + } + else + { + max_submissionrings = dtoh16(ringinfo.max_flowrings); + max_flowrings = max_submissionrings - WHD_NROF_H2D_COMMON_MSGRINGS; + max_completionrings = WHD_NROF_D2H_COMMON_MSGRINGS; + } + + if (max_flowrings > 256) + { + WPRINT_WHD_ERROR( ("Invalid max_flowrings(%d)\n", max_flowrings) ); + return WHD_WLAN_BADARG; + } + + if (whd_driver->dma_index_sz == 0) + { + d2h_w_idx_ptr = dtoh32(ringinfo.d2h_w_idx_ptr); + d2h_r_idx_ptr = dtoh32(ringinfo.d2h_r_idx_ptr); + h2d_w_idx_ptr = dtoh32(ringinfo.h2d_w_idx_ptr); + h2d_r_idx_ptr = dtoh32(ringinfo.h2d_r_idx_ptr); + idx_offset = sizeof(uint32_t); + whd_driver->write_ptr = whd_write_tcm16; + whd_driver->read_ptr = whd_read_tcm16; + WPRINT_WHD_DEBUG( ("Using TCM indices\n") ); + WPRINT_WHD_DEBUG( ("d2h_w_idx_ptr - 0x%lx, d2h_r_idx_ptr - 0x%lx \n", d2h_w_idx_ptr, d2h_r_idx_ptr) ); + WPRINT_WHD_DEBUG( ("h2d_w_idx_ptr - 0x%lx, h2d_r_idx_ptr - 0x%lx \n", h2d_w_idx_ptr, h2d_r_idx_ptr) ); + } + else + { + WPRINT_WHD_ERROR( ("Host Indices Support is NOT IMPLEMENTED!!! \n") ); + } + + ring_mem_ptr = dtoh32(ringinfo.ringmem); + + for (i = 0; i < WHD_NROF_H2D_COMMON_MSGRINGS; i++) + { + ring = whd_allocate_ring_and_handle(whd_driver, i, ring_mem_ptr); + if (!ring) + goto fail; + ring->w_idx_addr = h2d_w_idx_ptr; + ring->r_idx_addr = h2d_r_idx_ptr; + ring->id = i; + whd_driver->ram_shared->commonrings[i] = ring; + + h2d_w_idx_ptr += idx_offset; + h2d_r_idx_ptr += idx_offset; + ring_mem_ptr += WHD_RING_MEM_SZ; + } + + for (i = WHD_NROF_H2D_COMMON_MSGRINGS; i < WHD_NROF_COMMON_MSGRINGS; i++) + { + ring = whd_allocate_ring_and_handle(whd_driver, i, ring_mem_ptr); + if (!ring) + goto fail; + ring->w_idx_addr = d2h_w_idx_ptr; + ring->r_idx_addr = d2h_r_idx_ptr; + ring->id = i; + whd_driver->ram_shared->commonrings[i] = ring; + + d2h_w_idx_ptr += idx_offset; + d2h_r_idx_ptr += idx_offset; + ring_mem_ptr += WHD_RING_MEM_SZ; + } + + whd_driver->ram_shared->max_flowrings = max_flowrings; + whd_driver->ram_shared->max_submissionrings = max_submissionrings; + whd_driver->ram_shared->max_completionrings = max_completionrings; + rings = whd_mem_malloc(max_flowrings * sizeof(*ring) ); + + if (!rings) + goto fail; + + WPRINT_WHD_DEBUG( ("Number of flowrings is %d\n", max_flowrings) ); + + for (i = 0; i < max_flowrings; i++) + { + ring = &rings[i]; + ring->whd_drv = whd_driver; + ring->id = i + WHD_H2D_MSGRING_FLOWRING_IDSTART; + whd_commonring_register_cb(&ring->commonring, + whd_ring_mb_ring_bell, + whd_ring_mb_update_rptr, + whd_ring_mb_update_wptr, + whd_ring_mb_write_rptr, + whd_ring_mb_write_wptr, + ring); + + ring->w_idx_addr = h2d_w_idx_ptr; + ring->r_idx_addr = h2d_r_idx_ptr; + h2d_w_idx_ptr += idx_offset; + h2d_r_idx_ptr += idx_offset; + } + whd_driver->ram_shared->flowrings = rings; + + WPRINT_WHD_DEBUG( ("CommonRings Init Done \n") ); + + WPRINT_WHD_DEBUG( ("Notify Firmware about HOST READY!!! \n") ); +#ifndef GCI_SECURE_ACCESS + result = whd_bus_write_backplane_value(whd_driver, (uint32_t)GCI_BT2WL_DB1_REG, 4, (1 << 9) ); +#else + result = whd_hw_generateBt2WlDbInterruptApi(1, (1 << 9)); +#endif + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_write_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + return result; + +fail: + WPRINT_WHD_ERROR( ("Allocating ring buffers failed\n") ); + whd_release_ringbuffers(whd_driver); + return WHD_WLAN_ERROR; + +} + +whd_result_t whd_bus_m2m_sharedmem_init(whd_driver_t whd_driver) +{ + uint32_t wlan_shared_address = 0; + whd_result_t result = WHD_SUCCESS; + uint32_t shared_addr = 0; + uint32_t addr = 0; + uint32_t host_capability = 0; + whd_internal_info_t internal_info; + + struct whd_ram_shared_info *ram_shared_info; + + ram_shared_info = (struct whd_ram_shared_info *)whd_mem_malloc(sizeof(struct whd_ram_shared_info) ); + if (!ram_shared_info) + { + return WHD_MALLOC_FAILURE; + } + memset(ram_shared_info, 0, sizeof(struct whd_ram_shared_info)); + + whd_driver->ram_shared = ram_shared_info; + + wlan_shared_address = GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) - 4; + + WPRINT_WHD_DEBUG( ("%s: WLAN Shared Area Space is 0x%lx\n", __func__, wlan_shared_address) ); + + WPRINT_WHD_DEBUG( ("Waiting for FW to update Shared Area\n") ); + + while ( (shared_addr == 0) || (shared_addr <= GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) ) || + (shared_addr >= (GET_C_VAR(whd_driver, ATCM_RAM_BASE_ADDRESS) + GET_C_VAR(whd_driver, CHIP_RAM_SIZE) ) ) ) + { + WPRINT_WHD_DEBUG( ("Value at Shared Space is 0x%lx \n", REG32(wlan_shared_address) ) ); + result = whd_bus_read_backplane_value(whd_driver, wlan_shared_address, 4, (uint8_t *)&shared_addr); + } + + WPRINT_WHD_DEBUG( ("%s: WLAN Shared Address is 0x%lx\n", __func__, shared_addr) ); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("%s: Shared Address Read Failed\n", __func__) ); + goto fail; + } + + result = whd_bus_mem_bytes(whd_driver, BUS_READ, TRANS_ADDR( + shared_addr), sizeof(internal_info.sh), (uint8_t *)&internal_info.sh); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Read Internal Info failed\n", __func__) ); + goto fail; + } + + internal_info.sh.flags = dtoh32(internal_info.sh.flags); + internal_info.sh.trap_addr = dtoh32(internal_info.sh.trap_addr); + internal_info.sh.assert_exp_addr = dtoh32(internal_info.sh.assert_exp_addr); + internal_info.sh.assert_file_addr = dtoh32(internal_info.sh.assert_file_addr); + internal_info.sh.assert_line = dtoh32(internal_info.sh.assert_line); + internal_info.sh.console_addr = dtoh32(internal_info.sh.console_addr); + internal_info.sh.msgtrace_addr = dtoh32(internal_info.sh.msgtrace_addr); + internal_info.sh.ring_info_ptr = dtoh32(internal_info.sh.ring_info_ptr); + internal_info.sh.fwid = dtoh32(internal_info.sh.fwid); + + host_capability = (dtoh32(internal_info.sh.flags) & WHD_PCIE_SHARED_VERSION_MASK); + + if ( (internal_info.sh.flags & WLAN_M2M_SHARED_VERSION_MASK) > WLAN_M2M_SHARED_VERSION ) + { + WPRINT_WHD_ERROR( ("ReadShared: WLAN shared version is not valid sh.flags %x\n\r", internal_info.sh.flags) ); + goto fail; + } + + WPRINT_WHD_DEBUG( ("FW Supported Flag Value is 0x%x \n", internal_info.sh.flags) ); + + if ( (internal_info.sh.flags & WHD_PCIE_SHARED_HOSTRDY_DB1) ) + { + WPRINT_WHD_DEBUG( ("HOST READY supported by dongle\n") ); + host_capability = host_capability | WHD_H2D_ENABLE_HOSTRDY; + } + + if ( (internal_info.sh.flags & WHD_PCIE_SHARED_USE_MAILBOX) ) + { + WPRINT_WHD_DEBUG( ("Shared Mailbox supported by dongle\n") ); + host_capability = host_capability | WHD_PCIE_SHARED_USE_MAILBOX; + } + + /* check firmware support dma indices */ + if (internal_info.sh.flags & WHD_PCIE_SHARED_DMA_INDEX) { + if (internal_info.sh.flags & WHD_PCIE_SHARED_DMA_2B_IDX) + whd_driver->dma_index_sz = sizeof(uint16_t); + else + whd_driver->dma_index_sz = sizeof(uint32_t); + } + + whd_driver->ram_shared->tcm_base_address = shared_addr; + whd_driver->ram_shared->version_new = internal_info.sh.flags & WLAN_M2M_SHARED_VERSION_MASK; + +#if 0 /* To be verified after TO for alignment issue */ + addr = shared_addr + WHD_SHARED_MAX_RXBUFPOST_OFFSET; + result = whd_bus_read_backplane_value(whd_driver, addr, 4, + (uint8_t *)&whd_driver->ram_shared->max_rxbufpost); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_read_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } +#endif + + if (whd_driver->ram_shared->max_rxbufpost == 0) + whd_driver->ram_shared->max_rxbufpost = WHD_DEF_MAX_RXBUFPOST; + + addr = shared_addr + WHD_SHARED_RX_DATAOFFSET_OFFSET; + result = whd_bus_read_backplane_value(whd_driver, addr, 4, + (uint8_t *)&whd_driver->ram_shared->rx_dataoffset); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_read_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } +#if 0 /* To be verified after TO for alignment issue */ + addr = shared_addr + WHD_SHARED_HTOD_MB_DATA_ADDR_OFFSET; + result = whd_bus_read_backplane_value(whd_driver, TRANS_ADDR(addr), 4, + (uint8_t *)&whd_driver->ram_shared->htod_mb_data_addr); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_read_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + addr = shared_addr + WHD_SHARED_DTOH_MB_DATA_ADDR_OFFSET; + result = whd_bus_read_backplane_value(whd_driver, addr, 4, + (uint8_t *)&whd_driver->ram_shared->dtoh_mb_data_addr); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_read_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } +#endif + addr = shared_addr + WHD_SHARED_RING_INFO_ADDR_OFFSET; + result = whd_bus_read_backplane_value(whd_driver, addr, 4, + (uint8_t *)&whd_driver->ram_shared->ring_info_addr); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_read_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + addr = shared_addr + WHD_SHARED_HOST_CAP_OFFSET; + result = whd_bus_write_backplane_value(whd_driver, addr, host_capability, 4); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_write_backplane_value failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + WPRINT_WHD_DEBUG( ("Firmware ID is 0x%x\n", internal_info.sh.fwid) ); + WPRINT_WHD_DEBUG( ("RingInfo Pointer is 0x%lx \n", whd_driver->ram_shared->ring_info_addr) ); + + result = whd_bus_m2m_ring_init(whd_driver); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("whd_bus_m2m_ring_init failed in %s at %d \n", __func__, __LINE__) ); + goto fail; + } + + /* Create the mutex protecting host suspend */ + if (cy_rtos_init_semaphore(&whd_driver->host_suspend_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&whd_driver->host_suspend_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + result = cy_rtos_init_event(&whd_driver->host_suspend_event_wait); + if (result != WHD_SUCCESS) + { + cy_rtos_deinit_semaphore(&whd_driver->host_suspend_mutex); + WPRINT_WHD_ERROR( ("Failed to initialize for host_suspend_event_wait event.\n") ); + goto fail; + } + + return result; + +fail: + WPRINT_WHD_DEBUG( ("%s, Initial whd_bus_m2m_sharedmem_init failed\n", __FUNCTION__) ); + whd_mem_free(ram_shared_info); + whd_driver->ram_shared = NULL; + return result; +} + +#endif /* PROTO_MSGBUF */ diff --git a/wi-fi/whd/whd_ring.h b/wi-fi/whd/whd_ring.h new file mode 100644 index 00000000..49a1bd37 --- /dev/null +++ b/wi-fi/whd/whd_ring.h @@ -0,0 +1,194 @@ +/* + * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company) + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file WHD ring + * + * Utilities to help do specialized (not general purpose) WHD specific things + */ +#ifndef INCLUDED_WHD_RING_H +#define INCLUDED_WHD_RING_H + +#include "whd.h" +#include "whd_commonring.h" +#include "whd_msgbuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Translated Address for CM33 to access CR4 memory */ +#define TRANS_ADDR(addr) ( (0x8F620000 - 0x003A0000) + addr ) + +#define WHD_RING_MEM_BASE_ADDR_OFFSET 8 +#define WHD_RING_MAX_ITEM_OFFSET 4 +#define WHD_RING_LEN_ITEMS_OFFSET 6 +#define WHD_RING_MEM_SZ 16 +#define WHD_RING_STATE_SZ 8 + +#define WHD_PCIE_SHARED_VERSION_6 6 +#define WHD_PCIE_SHARED_VERSION_7 7 +#define WHD_PCIE_MIN_SHARED_VERSION 5 +#define WHD_PCIE_MAX_SHARED_VERSION WHD_PCIE_SHARED_VERSION_7 +#define WHD_PCIE_SHARED_VERSION_MASK 0x00FF +#define WHD_PCIE_SHARED_DMA_INDEX 0x10000 +#define WHD_PCIE_SHARED_DMA_2B_IDX 0x100000 +#define WHD_PCIE_SHARED_USE_MAILBOX 0x2000000 +#define WHD_PCIE_SHARED_HOSTRDY_DB1 0x10000000 + +//Ram Shared Region Offsets +#define WHD_SHARED_MAX_RXBUFPOST_OFFSET 34 +#define WHD_SHARED_RING_BASE_OFFSET 52 +#define WHD_SHARED_RX_DATAOFFSET_OFFSET 36 +#define WHD_SHARED_CONSOLE_ADDR_OFFSET 20 +#define WHD_SHARED_HTOD_MB_DATA_ADDR_OFFSET 40 +#define WHD_SHARED_DTOH_MB_DATA_ADDR_OFFSET 44 +#define WHD_SHARED_RING_INFO_ADDR_OFFSET 48 +#define WHD_SHARED_DMA_SCRATCH_LEN_OFFSET 52 +#define WHD_SHARED_DMA_SCRATCH_ADDR_OFFSET 56 +#define WHD_SHARED_DMA_RINGUPD_LEN_OFFSET 64 +#define WHD_SHARED_DMA_RINGUPD_ADDR_OFFSET 68 +#define WHD_SHARED_HOST_CAP_OFFSET 84 + +#define WHD_H2D_ENABLE_HOSTRDY 0x400 + +#define WHD_DEF_MAX_RXBUFPOST 8 + +#define WLAN_M2M_SHARED_VERSION_MASK (0x00ff) +#define WLAN_M2M_SHARED_VERSION (0x0007) + +#define WHD_D2H_DEV_D3_ACK 0x00000001 +#define WHD_D2H_DEV_DS_ENTER_REQ 0x00000002 +#define WHD_D2H_DEV_DS_EXIT_NOTE 0x00000004 +#define WHD_D2H_DEV_FWHALT 0x10000000 + +#define WHD_H2D_HOST_D3_INFORM 0x00000001 +#define WHD_H2D_HOST_DS_ACK 0x00000002 +#define WHD_H2D_HOST_D0_INFORM_IN_USE 0x00000008 +#define WHD_H2D_HOST_D0_INFORM 0x00000010 + +#define WHD_MBDATA_TIMEOUT (2000) + +#define WHD_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 32 +#define WHD_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 128 +#define WHD_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 32 +#define WHD_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 128 +#define WHD_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 128 +#define WHD_H2D_TXFLOWRING_MAX_ITEM 128 + +/* Submit Itemsize for rings should match with FW item sizes */ +#define WHD_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40 +#define WHD_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE 32 +#define WHD_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE 24 +#define WHD_D2H_MSGRING_TX_COMPLETE_ITEMSIZE_PRE_V7 16 +#define WHD_D2H_MSGRING_TX_COMPLETE_ITEMSIZE 24 +#define WHD_D2H_MSGRING_RX_COMPLETE_ITEMSIZE_PRE_V7 32 +#define WHD_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 40 +#define WHD_H2D_TXFLOWRING_ITEMSIZE 48 + +/* IDs of the 6 default common rings of msgbuf protocol */ +#define WHD_H2D_MSGRING_CONTROL_SUBMIT 0 +#define WHD_H2D_MSGRING_RXPOST_SUBMIT 1 +#define WHD_H2D_MSGRING_FLOWRING_IDSTART 2 +#define WHD_D2H_MSGRING_CONTROL_COMPLETE 2 +#define WHD_D2H_MSGRING_TX_COMPLETE 3 +#define WHD_D2H_MSGRING_RX_COMPLETE 4 + +static const uint32_t whd_ring_max_item[WHD_NROF_COMMON_MSGRINGS] = { + WHD_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM, + WHD_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM, + WHD_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM, + WHD_D2H_MSGRING_TX_COMPLETE_MAX_ITEM, + WHD_D2H_MSGRING_RX_COMPLETE_MAX_ITEM +}; + +static const uint32_t whd_ring_itemsize_pre_v7[WHD_NROF_COMMON_MSGRINGS] = { + WHD_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE, + WHD_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE, + WHD_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE, + WHD_D2H_MSGRING_TX_COMPLETE_ITEMSIZE_PRE_V7, + WHD_D2H_MSGRING_RX_COMPLETE_ITEMSIZE_PRE_V7 +}; + +static const uint32_t whd_ring_itemsize[WHD_NROF_COMMON_MSGRINGS] = { + WHD_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE, + WHD_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE, + WHD_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE, + WHD_D2H_MSGRING_TX_COMPLETE_ITEMSIZE, + WHD_D2H_MSGRING_RX_COMPLETE_ITEMSIZE +}; + +struct whd_ringbuf +{ + struct whd_commonring commonring; + void *ring_handle; //ram_todo dma_handle + uint32_t w_idx_addr; + uint32_t r_idx_addr; + whd_driver_t whd_drv; + uint8_t id; +}; + +struct whd_dhi_ringinfo +{ + uint32_t ringmem; + uint32_t h2d_w_idx_ptr; + uint32_t h2d_r_idx_ptr; + uint32_t d2h_w_idx_ptr; + uint32_t d2h_r_idx_ptr; + struct msg_buf_addr h2d_w_idx_hostaddr; + struct msg_buf_addr h2d_r_idx_hostaddr; + struct msg_buf_addr d2h_w_idx_hostaddr; + struct msg_buf_addr d2h_r_idx_hostaddr; + uint32_t max_flowrings; + uint16_t max_submissionrings; + uint16_t max_completionrings; +}; + +struct whd_ram_shared_info +{ + uint32_t tcm_base_address; + uint32_t flags; + struct whd_ringbuf *commonrings[WHD_NROF_COMMON_MSGRINGS]; + struct whd_ringbuf *flowrings; + uint16_t max_rxbufpost; + uint16_t max_flowrings; + uint16_t max_submissionrings; + uint16_t max_completionrings; + uint32_t rx_dataoffset; + uint32_t htod_mb_data_addr; + uint32_t dtoh_mb_data_addr; + uint32_t ring_info_addr; + //struct brcmf_pcie_console console; + void *scratch; + //ram_check dma_addr_t scratch_dmahandle; + void *ringupd; + //ram_check dma_addr_t ringupd_dmahandle; + uint32_t version_new; +}; + +extern void whd_bus_handle_mb_data(whd_driver_t whd_driver, uint32_t d2h_mb_data); +extern whd_result_t whd_host_trigger_suspend(whd_driver_t whd_driver); +extern whd_result_t whd_host_trigger_resume(whd_driver_t whd_driver); +extern whd_result_t whd_bus_suspend(whd_driver_t whd_driver); +extern whd_result_t whd_bus_resume(whd_driver_t whd_driver); +extern whd_result_t whd_bus_m2m_sharedmem_init(whd_driver_t whd_driver); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* INCLUDED_WHD_RING_H */ diff --git a/wi-fi/whd/whd_sdpcm.c b/wi-fi/whd/whd_sdpcm.c index aa13ae36..7975dda5 100644 --- a/wi-fi/whd/whd_sdpcm.c +++ b/wi-fi/whd/whd_sdpcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,7 @@ * It is required when communicating with Broadcom 802.11 devices. * */ +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" #include "bus_protocols/whd_bus_protocol_interface.h" #include "whd_endian.h" @@ -41,20 +42,25 @@ * @cond Constants ******************************************************/ -#define ETHER_TYPE_BRCM (0x886C) /** Broadcom Ethertype for identifying event packets - Copied from DHD include/proto/ethernet.h */ -#define BRCM_OUI "\x00\x10\x18" /** Broadcom OUI (Organizationally Unique Identifier): Used in the proprietary(221) IE (Information Element) in all Broadcom devices */ -#define BCM_MSG_IFNAME_MAX (16) /** Maximum length of an interface name in a wl_event_msg_t structure*/ +#define ETHER_TYPE_BRCM (0x886C) /** Broadcom Ethertype for identifying event packets - Copied from DHD include/proto/ethernet.h */ +#define BRCM_OUI "\x00\x10\x18" /** Broadcom OUI (Organizationally Unique Identifier): Used in the proprietary(221) IE (Information Element) in all Broadcom devices */ +#define BCM_MSG_IFNAME_MAX (16) /** Maximum length of an interface name in a wl_event_msg_t structure*/ -#define BDC_FLAG2_IF_MASK (0x0f) +#define BDC_FLAG2_IF_MASK (0x0f) -#define SDPCM_HEADER_LEN (12) +#define SDPCM_HEADER_LEN (12) /* Event flags */ -#define WLC_EVENT_MSG_LINK (0x01) /** link is up */ -#define WLC_EVENT_MSG_FLUSHTXQ (0x02) /** flush tx queue on MIC error */ -#define WLC_EVENT_MSG_GROUP (0x04) /** group MIC error */ -#define WLC_EVENT_MSG_UNKBSS (0x08) /** unknown source bsscfg */ -#define WLC_EVENT_MSG_UNKIF (0x10) /** unknown source OS i/f */ +#define WLC_EVENT_MSG_LINK (0x01) /** link is up */ +#define WLC_EVENT_MSG_FLUSHTXQ (0x02) /** flush tx queue on MIC error */ +#define WLC_EVENT_MSG_GROUP (0x04) /** group MIC error */ +#define WLC_EVENT_MSG_UNKBSS (0x08) /** unknown source bsscfg */ +#define WLC_EVENT_MSG_UNKIF (0x10) /** unknown source OS i/f */ + +/* WMM constants */ +#define MAX_8021P_PRIO 8 +#define MAX_WMM_AC 4 +#define AC_QUEUE_SIZE 64 /****************************************************** * Macros @@ -78,13 +84,13 @@ */ typedef struct { - uint8_t sequence; /* Rx/Tx sequence number */ - uint8_t channel_and_flags; /* 4 MSB Channel number, 4 LSB arbitrary flag */ - uint8_t next_length; /* Length of next data frame, reserved for Tx */ - uint8_t header_length; /* Data offset */ - uint8_t wireless_flow_control; /* Flow control bits, reserved for Tx */ - uint8_t bus_data_credit; /* Maximum Sequence number allowed by firmware for Tx */ - uint8_t _reserved[2]; /* Reserved */ + uint8_t sequence; /* Rx/Tx sequence number */ + uint8_t channel_and_flags; /* 4 MSB Channel number, 4 LSB arbitrary flag */ + uint8_t next_length; /* Length of next data frame, reserved for Tx */ + uint8_t header_length; /* Data offset */ + uint8_t wireless_flow_control; /* Flow control bits, reserved for Tx */ + uint8_t bus_data_credit; /* Maximum Sequence number allowed by firmware for Tx */ + uint8_t _reserved[2]; /* Reserved */ } sdpcm_sw_header_t; /* @@ -92,44 +98,47 @@ typedef struct */ typedef struct { - uint16_t frametag[2]; - sdpcm_sw_header_t sw_header; + uint16_t frametag[2]; + sdpcm_sw_header_t sw_header; } sdpcm_header_t; -typedef struct bcmeth_hdr { - uint16_t subtype; /** Vendor specific..32769 */ - uint16_t length; - uint8_t version; /** Version is 0 */ - uint8_t oui[3]; /** Broadcom OUI */ - uint16_t usr_subtype; /** user specific Data */ +typedef struct bcmeth_hdr +{ + uint16_t subtype; /** Vendor specific..32769 */ + uint16_t length; + uint8_t version; /** Version is 0 */ + uint8_t oui[3]; /** Broadcom OUI */ + uint16_t usr_subtype; /** user specific Data */ } sdpcm_bcmeth_header_t; /* these fields are stored in network order */ typedef struct { - uint16_t version; /** Version 1 has fields up to ifname. + uint16_t version; /** Version 1 has fields up to ifname. * Version 2 has all fields including ifidx and bss_cfg_idx */ - uint16_t flags; /** see flags */ - uint32_t event_type; /** Message */ - uint32_t status; /** Status code */ - uint32_t reason; /** Reason code (if applicable) */ - uint32_t auth_type; /** WLC_E_AUTH */ - uint32_t datalen; /** data buf */ - whd_mac_t addr; /** Station address (if applicable) */ - char ifname[BCM_MSG_IFNAME_MAX]; /** name of the packet incoming interface */ - uint8_t ifidx; /** destination OS i/f index */ - uint8_t bss_cfg_idx; /** source bsscfg index */ + uint16_t flags; /** see flags */ + uint32_t event_type; /** Message */ + uint32_t status; /** Status code */ + uint32_t reason; /** Reason code (if applicable) */ + uint32_t auth_type; /** WLC_E_AUTH */ + uint32_t datalen; /** data buf */ + whd_mac_t addr; /** Station address (if applicable) */ + char ifname[BCM_MSG_IFNAME_MAX]; /** name of the packet incoming interface */ + uint8_t ifidx; /** destination OS i/f index */ + uint8_t bss_cfg_idx; /** source bsscfg index */ } sdpcm_raw_event_header_t; /* used by driver msgs */ -typedef struct bcm_event { - ethernet_header_t ether; - sdpcm_bcmeth_header_t bcmeth; - union { - whd_event_header_t whd; - sdpcm_raw_event_header_t raw; - } event; +typedef struct bcm_event +{ + ethernet_header_t ether; + sdpcm_bcmeth_header_t bcmeth; + union + { + whd_event_header_t whd; + sdpcm_raw_event_header_t raw; + } event; } sdpcm_bcm_event_t; #pragma pack() @@ -137,10 +146,15 @@ typedef struct bcm_event { /****************************************************** * Static Variables ******************************************************/ -/* Set the pkt threshold for each WMM categories - * BE:64 BK:128 VI:192 VO:256 +/** 802.1p Priority to WMM AC Mapping + * + * prio 0, 3: Background(0) + * prio 1, 2: Best Effor(1) + * prio 4, 5: Video(2) + * prio 6, 7: Voice(3) + * prio 8 : Control(4)(ex: IOVAR/IOCTL) */ -static const uint32_t prio_to_qthreshold[8] = { 64, 128, 128, 64, 192, 192, 256, 256 }; +static const uint8_t prio_to_ac[9] = {1, 0, 0, 1, 2, 2, 3, 3, 4}; /****************************************************** * SDPCM Logging @@ -155,7 +169,7 @@ static const uint32_t prio_to_qthreshold[8] = { 64, 128, 128, 64, 192, 192, 256, #if 0 -#define SDPCM_LOG_SIZE 30 +#define SDPCM_LOG_SIZE 30 #define SDPCM_LOG_HEADER_SIZE (0x60) typedef enum { UNUSED, LOG_TX, LOG_RX } sdpcm_log_direction_t; @@ -197,11 +211,11 @@ static void add_sdpcm_log_entry(sdpcm_log_direction_t dir, sdpcm_log_type_t type /****************************************************** * Static Function Prototypes ******************************************************/ -static whd_buffer_t whd_sdpcm_get_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer); -static void whd_sdpcm_set_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer, - whd_buffer_t prev_buffer); +static whd_buffer_t whd_sdpcm_get_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer); +static void whd_sdpcm_set_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer, + whd_buffer_t prev_buffer); extern void whd_wifi_log_event(whd_driver_t whd_driver, const whd_event_header_t *event_header, - const uint8_t *event_data); + const uint8_t *event_data); /****************************************************** * Function definitions ******************************************************/ @@ -217,35 +231,42 @@ extern void whd_wifi_log_event(whd_driver_t whd_driver, const whd_event_header_t whd_result_t whd_sdpcm_init(whd_driver_t whd_driver) { - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + int ac; - /* Create the sdpcm packet queue semaphore */ - if (cy_rtos_init_semaphore(&sdpcm_info->send_queue_mutex, 1, 0) != WHD_SUCCESS) { - return WHD_SEMAPHORE_ERROR; - } - if (cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } + /* Create the sdpcm packet queue semaphore */ + if (cy_rtos_init_semaphore(&sdpcm_info->send_queue_mutex, 1, 0) != WHD_SUCCESS) + { + return WHD_SEMAPHORE_ERROR; + } + if (cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } - /* Packet send queue variables */ - sdpcm_info->send_queue_head = (whd_buffer_t)NULL; - sdpcm_info->send_queue_tail = (whd_buffer_t)NULL; - sdpcm_info->npkt_in_q = 0; + /* Packet send queue variables */ + for (ac = 0; ac <= MAX_WMM_AC; ac++) + { + sdpcm_info->send_queue_head[ac] = (whd_buffer_t)NULL; + sdpcm_info->send_queue_tail[ac] = (whd_buffer_t)NULL; + sdpcm_info->npkt_in_q[ac] = 0; + } + sdpcm_info->totpkt_in_q = 0; - whd_sdpcm_bus_vars_init(whd_driver); + whd_sdpcm_bus_vars_init(whd_driver); - return WHD_SUCCESS; + return WHD_SUCCESS; } /* Re-initialize the bus variables after deep sleep */ void whd_sdpcm_bus_vars_init(whd_driver_t whd_driver) { - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; - /* Bus data credit variables */ - sdpcm_info->tx_seq = 0; - sdpcm_info->tx_max = (uint8_t)1; + /* Bus data credit variables */ + sdpcm_info->tx_seq = 0; + sdpcm_info->tx_max = (uint8_t)1; } /** Initialises the SDPCM protocol handler @@ -255,40 +276,48 @@ void whd_sdpcm_bus_vars_init(whd_driver_t whd_driver) */ void whd_sdpcm_quit(whd_driver_t whd_driver) { - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; - whd_result_t result; - - /* Delete the SDPCM queue mutex */ - (void)cy_rtos_deinit_semaphore(&sdpcm_info->send_queue_mutex); /* Ignore return - not much can be done about failure */ - - /* Free any left over packets in the queue */ - while (sdpcm_info->send_queue_head != NULL) { - whd_buffer_t buf = whd_sdpcm_get_next_buffer_in_queue(whd_driver, sdpcm_info->send_queue_head); - result = whd_buffer_release(whd_driver, sdpcm_info->send_queue_head, WHD_NETWORK_TX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - sdpcm_info->send_queue_head = buf; - } - sdpcm_info->npkt_in_q = 0; + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + whd_result_t result; + int ac; + + /* Delete the SDPCM queue mutex */ + (void)cy_rtos_deinit_semaphore(&sdpcm_info->send_queue_mutex); /* Ignore return - not much can be done about failure */ + + /* Free any left over packets in the queue */ + for (ac = 0; ac <= MAX_WMM_AC; ac++) + { + while (sdpcm_info->send_queue_head[ac] != NULL) + { + whd_buffer_t buf = whd_sdpcm_get_next_buffer_in_queue(whd_driver, sdpcm_info->send_queue_head[ac]); + result = whd_buffer_release(whd_driver, sdpcm_info->send_queue_head[ac], WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + sdpcm_info->send_queue_head[ac] = buf; + } + sdpcm_info->npkt_in_q[ac] = 0; + } + sdpcm_info->totpkt_in_q = 0; } void whd_sdpcm_update_credit(whd_driver_t whd_driver, uint8_t *data) { - sdpcm_sw_header_t *header = (sdpcm_sw_header_t *)(data + 4); - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; - uint8_t tx_seq_max; - - if ((header->channel_and_flags & 0x0f) < (uint8_t)3) { - tx_seq_max = header->bus_data_credit; - WPRINT_WHD_DATA_LOG(("credit update to %d\n ", tx_seq_max)); - if (tx_seq_max - sdpcm_info->tx_seq > 0x40) { - WPRINT_WHD_ERROR(("update credit error\n")); - tx_seq_max = sdpcm_info->tx_seq + 2; - } - sdpcm_info->tx_max = tx_seq_max; - } - - whd_bus_set_flow_control(whd_driver, header->wireless_flow_control); + sdpcm_sw_header_t *header = (sdpcm_sw_header_t *)(data + 4); + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + uint8_t tx_seq_max; + + if ( (header->channel_and_flags & 0x0f) < (uint8_t)3 ) + { + tx_seq_max = header->bus_data_credit; + WPRINT_WHD_DATA_LOG( ("credit update to %d\n ", tx_seq_max) ); + if (tx_seq_max - sdpcm_info->tx_seq > 0x40) + { + WPRINT_WHD_ERROR( ("update credit error\n") ); + tx_seq_max = sdpcm_info->tx_seq + 2; + } + sdpcm_info->tx_max = tx_seq_max; + } + + whd_bus_set_flow_control(whd_driver, header->wireless_flow_control); } /** Processes and directs incoming SDPCM packets @@ -304,188 +333,220 @@ void whd_sdpcm_update_credit(whd_driver_t whd_driver, uint8_t *data) */ void whd_sdpcm_process_rx_packet(whd_driver_t whd_driver, whd_buffer_t buffer) { - bus_common_header_t *packet; - uint16_t size; - uint16_t size_inv; - sdpcm_header_t sdpcm_header; - whd_result_t result; - - packet = (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - CHECK_PACKET_WITH_NULL_RETURN(packet); - memcpy(&sdpcm_header, packet->bus_header, BUS_HEADER_LEN); - - sdpcm_header.frametag[0] = dtoh16(sdpcm_header.frametag[0]); - sdpcm_header.frametag[1] = dtoh16(sdpcm_header.frametag[1]); - - /* Extract the total SDPCM packet size from the first two frametag bytes */ - size = sdpcm_header.frametag[0]; - - /* Check that the second two frametag bytes are the binary inverse of the size */ - size_inv = (uint16_t)~size; /* Separate variable due to GCC Bug 38341 */ - if (sdpcm_header.frametag[1] != size_inv) { - WPRINT_WHD_DEBUG(("Received a packet with a frametag which is wrong\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return; - } - - /* Check whether the packet is big enough to contain the SDPCM header (or) it's too big to handle */ - if ((size < (uint16_t)SDPCM_HEADER_LEN) || (size > whd_buffer_get_current_piece_size(whd_driver, buffer))) { - whd_minor_assert("Packet size invalid", 0 == 1); - WPRINT_WHD_DEBUG(( - "Received a packet that is too small to contain anything useful (or) too big. Packet Size = [%d]\n", - size)); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return; - } - - /* Get address of packet->sdpcm_header.frametag indirectly to avoid IAR's unaligned address warning */ - whd_sdpcm_update_credit(whd_driver, - (uint8_t *)&sdpcm_header.sw_header - sizeof(sdpcm_header.frametag)); - - if (size == (uint16_t)SDPCM_HEADER_LEN) { - /* This is a flow control update packet with no data - release it. */ - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - - return; - } - - /* Check the SDPCM channel to decide what to do with packet. */ - switch (sdpcm_header.sw_header.channel_and_flags & 0x0f) { - case CONTROL_HEADER: /* IOCTL/IOVAR reply packet */ - { - add_sdpcm_log_entry(LOG_RX, IOCTL, whd_buffer_get_current_piece_size(whd_driver, buffer), - (char *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer)); - - /* Check that packet size is big enough to contain the CDC header as well as the SDPCM header */ - if (sdpcm_header.frametag[0] < - (sizeof(sdpcm_header.frametag) + sizeof(sdpcm_sw_header_t) + sizeof(cdc_header_t))) { - /* Received a too-short SDPCM packet! */ - WPRINT_WHD_DEBUG(("Received a too-short SDPCM packet!\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - - break; - } - - /* Move SDPCM header and Buffer header to pass onto next layer */ - whd_buffer_add_remove_at_front(whd_driver, &buffer, - (int32_t)(sizeof(whd_buffer_header_t) + - sdpcm_header.sw_header.header_length)); - - whd_process_cdc(whd_driver, buffer); - } - - break; - - case DATA_HEADER: { - /* Check that the packet is big enough to contain SDPCM & BDC headers */ - if (sdpcm_header.frametag[0] <= - (sizeof(sdpcm_header.frametag) + sizeof(sdpcm_sw_header_t) + sizeof(bdc_header_t))) { - WPRINT_WHD_ERROR(("Packet too small to contain SDPCM + BDC headers\n")); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - - break; - } - - /* Move SDPCM header and Buffer header to pass onto next layer */ - whd_buffer_add_remove_at_front(whd_driver, &buffer, - (int32_t)(sizeof(whd_buffer_header_t) + - sdpcm_header.sw_header.header_length)); - - whd_process_bdc(whd_driver, buffer); - - } break; - - case ASYNCEVENT_HEADER: { - - /* Move SDPCM header and Buffer header to pass onto next layer */ - whd_buffer_add_remove_at_front(whd_driver, &buffer, - (int32_t)(sizeof(whd_buffer_header_t) + - sdpcm_header.sw_header.header_length)); - - whd_process_bdc_event(whd_driver, buffer, size); - } break; - - default: - whd_minor_assert("SDPCM packet of unknown channel received - dropping packet", 0 != 0); - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - break; - } + bus_common_header_t *packet; + uint16_t size; + uint16_t size_inv; + sdpcm_header_t sdpcm_header; + whd_result_t result; + + packet = (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_WITH_NULL_RETURN(packet); + memcpy(&sdpcm_header, packet->bus_header, BUS_HEADER_LEN); + + sdpcm_header.frametag[0] = dtoh16(sdpcm_header.frametag[0]); + sdpcm_header.frametag[1] = dtoh16(sdpcm_header.frametag[1]); + + /* Extract the total SDPCM packet size from the first two frametag bytes */ + size = sdpcm_header.frametag[0]; + + /* Check that the second two frametag bytes are the binary inverse of the size */ + size_inv = (uint16_t) ~size; /* Separate variable due to GCC Bug 38341 */ + if (sdpcm_header.frametag[1] != size_inv) + { + WPRINT_WHD_DEBUG( ("Received a packet with a frametag which is wrong\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* Check whether the packet is big enough to contain the SDPCM header (or) it's too big to handle */ + if ( (size < (uint16_t)SDPCM_HEADER_LEN) || (size > whd_buffer_get_current_piece_size(whd_driver, buffer) ) ) + { + whd_minor_assert("Packet size invalid", 0 == 1); + WPRINT_WHD_DEBUG( ( + "Received a packet that is too small to contain anything useful (or) too big. Packet Size = [%d]\n", + size) ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* Get address of packet->sdpcm_header.frametag indirectly to avoid IAR's unaligned address warning */ + whd_sdpcm_update_credit(whd_driver, + (uint8_t *)&sdpcm_header.sw_header - sizeof(sdpcm_header.frametag) ); + + if (size == (uint16_t)SDPCM_HEADER_LEN) + { + /* This is a flow control update packet with no data - release it. */ + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + return; + } + + /* Check the SDPCM channel to decide what to do with packet. */ + switch (sdpcm_header.sw_header.channel_and_flags & 0x0f) + { + case CONTROL_HEADER: /* IOCTL/IOVAR reply packet */ + { + add_sdpcm_log_entry(LOG_RX, IOCTL, whd_buffer_get_current_piece_size(whd_driver, buffer), + (char *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer) ); + + /* Check that packet size is big enough to contain the CDC header as well as the SDPCM header */ + if (sdpcm_header.frametag[0] < + (sizeof(sdpcm_header.frametag) + sizeof(sdpcm_sw_header_t) + sizeof(cdc_header_t) ) ) + { + /* Received a too-short SDPCM packet! */ + WPRINT_WHD_DEBUG( ("Received a too-short SDPCM packet!\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + break; + } + + /* Move SDPCM header and Buffer header to pass onto next layer */ + whd_buffer_add_remove_at_front(whd_driver, &buffer, + (int32_t)(sizeof(whd_buffer_header_t) + + sdpcm_header.sw_header.header_length) ); + + whd_process_cdc(whd_driver, buffer); + } + + break; + + case DATA_HEADER: + { + /* Check that the packet is big enough to contain SDPCM & BDC headers */ + if (sdpcm_header.frametag[0] <= + (sizeof(sdpcm_header.frametag) + sizeof(sdpcm_sw_header_t) + sizeof(bdc_header_t) ) ) + { + WPRINT_WHD_ERROR( ("Packet too small to contain SDPCM + BDC headers\n") ); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + + break; + } + + /* Move SDPCM header and Buffer header to pass onto next layer */ + whd_buffer_add_remove_at_front(whd_driver, &buffer, + (int32_t)(sizeof(whd_buffer_header_t) + + sdpcm_header.sw_header.header_length) ); + + whd_process_bdc(whd_driver, buffer); + + } + break; + + case ASYNCEVENT_HEADER: + { + + /* Move SDPCM header and Buffer header to pass onto next layer */ + whd_buffer_add_remove_at_front(whd_driver, &buffer, + (int32_t)(sizeof(whd_buffer_header_t) + + sdpcm_header.sw_header.header_length) ); + + whd_process_bdc_event(whd_driver, buffer, size); + } + break; + + default: + whd_minor_assert("SDPCM packet of unknown channel received - dropping packet", 0 != 0); + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_RX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + break; + } } whd_bool_t whd_sdpcm_has_tx_packet(whd_driver_t whd_driver) { - if (whd_driver->sdpcm_info.send_queue_head != NULL) { - return WHD_TRUE; - } + if (whd_driver->sdpcm_info.totpkt_in_q > 0) + { + return WHD_TRUE; + } - return WHD_FALSE; + return WHD_FALSE; } whd_result_t whd_sdpcm_get_packet_to_send(whd_driver_t whd_driver, whd_buffer_t *buffer) { - bus_common_header_t *packet; - sdpcm_header_t sdpcm_header; - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; - whd_result_t result; - - if (sdpcm_info->send_queue_head != NULL) { - /* Check if we're being flow controlled */ - if (whd_bus_is_flow_controlled(whd_driver) == WHD_TRUE) { - WHD_STATS_INCREMENT_VARIABLE(whd_driver, flow_control); - return WHD_FLOW_CONTROLLED; - } - - /* Check if we have enough bus data credits spare */ - if (((uint8_t)(sdpcm_info->tx_max - sdpcm_info->tx_seq) == 0) || - (((uint8_t)(sdpcm_info->tx_max - sdpcm_info->tx_seq) & 0x80) != 0)) { - WHD_STATS_INCREMENT_VARIABLE(whd_driver, no_credit); - return WHD_NO_CREDITS; - } - - /* There is a packet waiting to be sent - send it then fix up queue and release packet */ - if (cy_rtos_get_semaphore(&sdpcm_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) { - /* Could not obtain mutex, push back the flow control semaphore */ - WPRINT_WHD_ERROR(("Error manipulating a semaphore, %s failed at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } - - /* Pop the head off and set the new send_queue head */ - *buffer = sdpcm_info->send_queue_head; - sdpcm_info->send_queue_head = whd_sdpcm_get_next_buffer_in_queue(whd_driver, *buffer); - if (sdpcm_info->send_queue_head == NULL) { - sdpcm_info->send_queue_tail = NULL; - } - sdpcm_info->npkt_in_q--; - result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - - - /* Set the sequence number */ - packet = (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); - CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(&sdpcm_header, packet->bus_header, BUS_HEADER_LEN); - sdpcm_header.sw_header.sequence = sdpcm_info->tx_seq; - memcpy(packet->bus_header, &sdpcm_header, BUS_HEADER_LEN); - sdpcm_info->tx_seq++; - - return WHD_SUCCESS; - } - else { - return WHD_NO_PACKET_TO_SEND; - } + bus_common_header_t *packet; + sdpcm_header_t sdpcm_header; + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + whd_result_t result; + int ac; + + if (sdpcm_info->totpkt_in_q <= 0) + { + return WHD_NO_PACKET_TO_SEND; + } + +#if (CYBSP_WIFI_INTERFACE_TYPE != CYBSP_USB_INTERFACE) + /* Check if we're being flow controlled for Data packet only. */ + if ( (whd_bus_is_flow_controlled(whd_driver) == WHD_TRUE) && (sdpcm_info->npkt_in_q[MAX_WMM_AC] == 0) ) + { + WHD_STATS_INCREMENT_VARIABLE(whd_driver, flow_control); + return WHD_FLOW_CONTROLLED; + } + + /* Check if we have enough bus data credits spare */ + if ( ( (uint8_t)(sdpcm_info->tx_max - sdpcm_info->tx_seq) == 0 ) || + ( ( (uint8_t)(sdpcm_info->tx_max - sdpcm_info->tx_seq) & 0x80 ) != 0 ) ) + { + WHD_STATS_INCREMENT_VARIABLE(whd_driver, no_credit); + return WHD_NO_CREDITS; + } +#endif /* (CYBSP_WIFI_INTERFACE_TYPE != CYBSP_USB_INTERFACE) */ + + /* There is a packet waiting to be sent - send it then fix up queue and release packet */ + if (cy_rtos_get_semaphore(&sdpcm_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + /* Could not obtain mutex, push back the flow control semaphore */ + WPRINT_WHD_ERROR( ("Error manipulating a semaphore, %s failed at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + for (ac = MAX_WMM_AC; ac >= 0; ac--) + { + if (sdpcm_info->send_queue_head[ac] != NULL) + { + break; + } + } + if (ac < 0) + { + WPRINT_WHD_ERROR( ("NO pkt available in queue, %s failed at %d\n", __func__, __LINE__) ); + return WHD_NO_PACKET_TO_SEND; + } + /* Pop the head off and set the new send_queue head */ + *buffer = sdpcm_info->send_queue_head[ac]; + sdpcm_info->send_queue_head[ac] = whd_sdpcm_get_next_buffer_in_queue(whd_driver, *buffer); + if (sdpcm_info->send_queue_head[ac] == NULL) + { + sdpcm_info->send_queue_tail[ac] = NULL; + } + sdpcm_info->npkt_in_q[ac]--; + sdpcm_info->totpkt_in_q--; + result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + + /* Set the sequence number */ + packet = (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, *buffer); + CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(&sdpcm_header, packet->bus_header, BUS_HEADER_LEN); + sdpcm_header.sw_header.sequence = sdpcm_info->tx_seq; + memcpy(packet->bus_header, &sdpcm_header, BUS_HEADER_LEN); + sdpcm_info->tx_seq++; + + return WHD_SUCCESS; } /** Returns the number of bus credits available @@ -494,12 +555,13 @@ whd_result_t whd_sdpcm_get_packet_to_send(whd_driver_t whd_driver, whd_buffer_t */ uint8_t whd_sdpcm_get_available_credits(whd_driver_t whd_driver) { - uint8_t tx_max = whd_driver->sdpcm_info.tx_max; - uint8_t tx_seq = whd_driver->sdpcm_info.tx_seq; - if (((uint8_t)(tx_max - tx_seq) & 0x80) != 0) { - return 0; - } - return (uint8_t)(tx_max - tx_seq); + uint8_t tx_max = whd_driver->sdpcm_info.tx_max; + uint8_t tx_seq = whd_driver->sdpcm_info.tx_seq; + if ( ( (uint8_t)(tx_max - tx_seq) & 0x80 ) != 0 ) + { + return 0; + } + return (uint8_t)(tx_max - tx_seq); } /** Writes SDPCM headers and sends packet to WHD Thread @@ -515,80 +577,99 @@ uint8_t whd_sdpcm_get_available_credits(whd_driver_t whd_driver) * @return WHD result code */ whd_result_t whd_send_to_bus(whd_driver_t whd_driver, whd_buffer_t buffer, - sdpcm_header_type_t header_type, uint8_t prio) + sdpcm_header_type_t header_type, uint8_t prio) { - uint16_t size; - uint8_t *data = NULL; - bus_common_header_t *packet = - (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - sdpcm_header_t sdpcm_header; - whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; - whd_result_t result; - CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); - size = whd_buffer_get_current_piece_size(whd_driver, buffer); - - size = (uint16_t)(size - (uint16_t)sizeof(whd_buffer_header_t)); - - /* Prepare the SDPCM header */ - memset((uint8_t *)&sdpcm_header, 0, sizeof(sdpcm_header_t)); - sdpcm_header.sw_header.channel_and_flags = (uint8_t)header_type; - sdpcm_header.sw_header.header_length = - (header_type == DATA_HEADER) ? sizeof(sdpcm_header_t) + 2 : sizeof(sdpcm_header_t); - sdpcm_header.sw_header.sequence = 0; /* Note: The real sequence will be written later */ - sdpcm_header.frametag[0] = size; - sdpcm_header.frametag[1] = (uint16_t)~size; - - memcpy(packet->bus_header, &sdpcm_header, BUS_HEADER_LEN); - data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - add_sdpcm_log_entry(LOG_TX, (header_type == DATA_HEADER) ? DATA : (header_type == CONTROL_HEADER) ? IOCTL : EVENT, - whd_buffer_get_current_piece_size(whd_driver, buffer), - (char *)data); - - /* Add the length of the SDPCM header and pass "down" */ - if (cy_rtos_get_semaphore(&sdpcm_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) { - /* Could not obtain mutex */ - /* Fatal error */ - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - return WHD_SEMAPHORE_ERROR; - } - - /* The input priority should not higher than 7 */ - if (prio > 7) { - prio = 7; - } - - if ((header_type == DATA_HEADER) && (sdpcm_info->npkt_in_q > prio_to_qthreshold[prio])) { - result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("buffer release failed in %s at %d \n", __func__, __LINE__)); - } - result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - } - whd_thread_notify(whd_driver); - return WHD_BUFFER_ALLOC_FAIL; - } - - whd_sdpcm_set_next_buffer_in_queue(whd_driver, NULL, buffer); - if (sdpcm_info->send_queue_tail != NULL) { - whd_sdpcm_set_next_buffer_in_queue(whd_driver, buffer, sdpcm_info->send_queue_tail); - } - sdpcm_info->send_queue_tail = buffer; - if (sdpcm_info->send_queue_head == NULL) { - sdpcm_info->send_queue_head = buffer; - } - sdpcm_info->npkt_in_q++; - result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - - whd_thread_notify(whd_driver); - - return WHD_SUCCESS; + uint16_t size; + uint8_t *data = NULL; + bus_common_header_t *packet = + (bus_common_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + sdpcm_header_t sdpcm_header; + whd_sdpcm_info_t *sdpcm_info = &whd_driver->sdpcm_info; + whd_result_t result; + int ac; + +#ifdef CYCFG_ULP_SUPPORT_ENABLED + if(!(whd_ensure_wlan_bus_not_in_deep_sleep(whd_driver))) + { + WPRINT_WHD_DEBUG(("Could not send pkt - F2 is not ready\n")); + return WHD_BUS_FAIL; + } +#endif + + CHECK_PACKET_NULL(packet, WHD_NO_REGISTER_FUNCTION_POINTER); + size = whd_buffer_get_current_piece_size(whd_driver, buffer); + + size = (uint16_t)(size - (uint16_t)sizeof(whd_buffer_header_t) ); + + /* Prepare the SDPCM header */ + memset( (uint8_t *)&sdpcm_header, 0, sizeof(sdpcm_header_t) ); + sdpcm_header.sw_header.channel_and_flags = (uint8_t)header_type; + sdpcm_header.sw_header.header_length = + (header_type == DATA_HEADER) ? sizeof(sdpcm_header_t) + 2 : sizeof(sdpcm_header_t); + sdpcm_header.sw_header.sequence = 0; /* Note: The real sequence will be written later */ + sdpcm_header.frametag[0] = size; + sdpcm_header.frametag[1] = (uint16_t) ~size; + + memcpy(packet->bus_header, &sdpcm_header, BUS_HEADER_LEN); + data = whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + add_sdpcm_log_entry(LOG_TX, (header_type == DATA_HEADER) ? DATA : (header_type == CONTROL_HEADER) ? IOCTL : EVENT, + whd_buffer_get_current_piece_size(whd_driver, buffer), + (char *)data); + + /* Add the length of the SDPCM header and pass "down" */ + if (cy_rtos_get_semaphore(&sdpcm_info->send_queue_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE) != WHD_SUCCESS) + { + /* Could not obtain mutex */ + /* Fatal error */ + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + return WHD_SEMAPHORE_ERROR; + } + + /* The input priority should not higher than MAX_8021P_PRIO(7) */ + if (prio > MAX_8021P_PRIO) + { + prio = MAX_8021P_PRIO; + } + ac = prio_to_ac[prio]; + + if ( (header_type == DATA_HEADER) && (sdpcm_info->npkt_in_q[ac] > AC_QUEUE_SIZE) ) + { + result = whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("buffer release failed in %s at %d \n", __func__, __LINE__) ); + } + result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + whd_thread_notify(whd_driver); + return WHD_BUFFER_ALLOC_FAIL; + } + + whd_sdpcm_set_next_buffer_in_queue(whd_driver, NULL, buffer); + if (sdpcm_info->send_queue_tail[ac] != NULL) + { + whd_sdpcm_set_next_buffer_in_queue(whd_driver, buffer, sdpcm_info->send_queue_tail[ac]); + } + sdpcm_info->send_queue_tail[ac] = buffer; + if (sdpcm_info->send_queue_head[ac] == NULL) + { + sdpcm_info->send_queue_head[ac] = buffer; + } + sdpcm_info->npkt_in_q[ac]++; + sdpcm_info->totpkt_in_q++; + result = cy_rtos_set_semaphore(&sdpcm_info->send_queue_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + + whd_thread_notify(whd_driver); + + return WHD_SUCCESS; } /****************************************************** @@ -597,8 +678,8 @@ whd_result_t whd_send_to_bus(whd_driver_t whd_driver, whd_buffer_t buffer, static whd_buffer_t whd_sdpcm_get_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer) { - whd_buffer_header_t *packet = (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); - return packet->queue_next; + whd_buffer_header_t *packet = (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, buffer); + return packet->queue_next; } /** Sets the next buffer in the send queue @@ -612,7 +693,9 @@ static whd_buffer_t whd_sdpcm_get_next_buffer_in_queue(whd_driver_t whd_driver, */ static void whd_sdpcm_set_next_buffer_in_queue(whd_driver_t whd_driver, whd_buffer_t buffer, whd_buffer_t prev_buffer) { - whd_buffer_header_t *packet = - (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, prev_buffer); - packet->queue_next = buffer; + whd_buffer_header_t *packet = + (whd_buffer_header_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, prev_buffer); + packet->queue_next = buffer; } + +#endif /* PROTO_MSGBUF */ diff --git a/wi-fi/whd/whd_sdpcm.h b/wi-fi/whd/whd_sdpcm.h index 24f50ef8..9c5183fd 100644 --- a/wi-fi/whd/whd_sdpcm.h +++ b/wi-fi/whd/whd_sdpcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,7 @@ #ifndef INCLUDED_WHD_SDPCM_H #define INCLUDED_WHD_SDPCM_H +#ifndef PROTO_MSGBUF #include "whd.h" #include "whd_events_int.h" #include "cyabs_rtos.h" @@ -32,59 +33,63 @@ #include "whd_cdc_bdc.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** * Constants ******************************************************/ -typedef enum { - DATA_HEADER = 2, - ASYNCEVENT_HEADER = 1, - CONTROL_HEADER = 0 +typedef enum +{ + DATA_HEADER = 2, + ASYNCEVENT_HEADER = 1, + CONTROL_HEADER = 0 } sdpcm_header_type_t; /****************************************************** * Macros ******************************************************/ -#define BUS_HEADER_LEN (12) -#define IOCTL_OFFSET (sizeof(whd_buffer_header_t) + 12 + 16) +#define BUS_HEADER_LEN (12) +#define IOCTL_OFFSET (sizeof(whd_buffer_header_t) + 12 + 16) /****************************************************** * Structures ******************************************************/ -typedef struct whd_sdpcm_info { - /* Bus data credit variables */ - uint8_t tx_seq; - uint8_t tx_max; +typedef struct whd_sdpcm_info +{ + /* Bus data credit variables */ + uint8_t tx_seq; + uint8_t tx_max; /* Packet send queue variables */ cy_semaphore_t send_queue_mutex; - whd_buffer_t send_queue_head; - whd_buffer_t send_queue_tail; - uint32_t npkt_in_q; + whd_buffer_t send_queue_head[5]; + whd_buffer_t send_queue_tail[5]; + uint32_t npkt_in_q[5]; /** 4 AC queues + 1 Control queue(IOVAR/IOCTLs) */ + uint32_t totpkt_in_q; } whd_sdpcm_info_t; typedef struct { - whd_buffer_header_t buffer_header; - uint8_t bus_header[BUS_HEADER_LEN]; + whd_buffer_header_t buffer_header; + uint8_t bus_header[BUS_HEADER_LEN]; } bus_common_header_t; #pragma pack(1) typedef struct { - bus_common_header_t common; - cdc_header_t cdc_header; + bus_common_header_t common; + cdc_header_t cdc_header; } control_header_t; typedef struct { - bus_common_header_t common; - uint8_t _padding[2]; - bdc_header_t bdc_header; + bus_common_header_t common; + uint8_t _padding[2]; + bdc_header_t bdc_header; } data_header_t; #pragma pack() @@ -103,10 +108,10 @@ extern whd_result_t whd_sdpcm_get_packet_to_send(whd_driver_t whd_driver, whd_bu extern void whd_sdpcm_update_credit(whd_driver_t whd_driver, uint8_t *data); extern uint8_t whd_sdpcm_get_available_credits(whd_driver_t whd_driver); extern void whd_update_host_interface_to_bss_index_mapping(whd_driver_t whd_driver, whd_interface_t interface, - uint32_t bssid_index); + uint32_t bssid_index); extern whd_result_t whd_send_to_bus(whd_driver_t whd_driver, whd_buffer_t buffer, - sdpcm_header_type_t header_type, uint8_t prio); + sdpcm_header_type_t header_type, uint8_t prio); /****************************************************** * Global variables @@ -116,4 +121,6 @@ extern whd_result_t whd_send_to_bus(whd_driver_t whd_driver, whd_buffer_t buffer } /* extern "C" */ #endif +#endif /* PROTO_MSGBUF */ + #endif /* ifndef INCLUDED_WHD_SDPCM_H */ diff --git a/wi-fi/whd/whd_thread.c b/wi-fi/whd/whd_thread.c index 9c9321fd..4f4abe82 100644 --- a/wi-fi/whd/whd_thread.c +++ b/wi-fi/whd/whd_thread.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,7 +41,13 @@ #include "whd_int.h" #include "whd_chip.h" #include "whd_poll.h" +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" +#else +#include "whd_msgbuf.h" +#include "whd_ring.h" +#include "whd_utils.h" +#endif /* PROTO_MSGBUF */ #include "whd_buffer_api.h" #include "whd_chip_constants.h" @@ -55,10 +61,10 @@ static void whd_thread_func(cy_thread_arg_t thread_input); ******************************************************/ void whd_thread_info_init(whd_driver_t whd_driver, whd_init_config_t *whd_init_config) { - memset(&whd_driver->thread_info, 0, sizeof(whd_driver->thread_info)); - whd_driver->thread_info.thread_stack_start = whd_init_config->thread_stack_start; - whd_driver->thread_info.thread_stack_size = whd_init_config->thread_stack_size; - whd_driver->thread_info.thread_priority = (cy_thread_priority_t)whd_init_config->thread_priority; + memset(&whd_driver->thread_info, 0, sizeof(whd_driver->thread_info) ); + whd_driver->thread_info.thread_stack_start = whd_init_config->thread_stack_start; + whd_driver->thread_info.thread_stack_size = whd_init_config->thread_stack_size; + whd_driver->thread_info.thread_priority = (cy_thread_priority_t)whd_init_config->thread_priority; } /** Initialises the WHD Thread @@ -71,38 +77,41 @@ void whd_thread_info_init(whd_driver_t whd_driver, whd_init_config_t *whd_init_c */ whd_result_t whd_thread_init(whd_driver_t whd_driver) { - whd_result_t retval; - - retval = whd_sdpcm_init(whd_driver); - - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not initialize SDPCM codec\n")); - /* Lint: Reachable after hitting assert & globals not defined due to error */ - return retval; - } - - /* Create the event flag which signals the WHD thread needs to wake up */ - retval = cy_rtos_init_semaphore(&whd_driver->thread_info.transceive_semaphore, 1, 0); - if (retval != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Could not initialize WHD thread semaphore\n")); - /* Lint: Reachable after hitting assert & globals not defined due to error */ - return retval; - } - - retval = cy_rtos_create_thread(&whd_driver->thread_info.whd_thread, (cy_thread_entry_fn_t)whd_thread_func, - "WHD", whd_driver->thread_info.thread_stack_start, - whd_driver->thread_info.thread_stack_size, - whd_driver->thread_info.thread_priority, (cy_thread_arg_t)whd_driver); - if (retval != WHD_SUCCESS) { - /* Could not start WHD main thread */ - WPRINT_WHD_ERROR(("Could not start WHD thread\n")); - return retval; - } - - /* Ready now. Indicate it here and in thread, whatever be executed first. */ - whd_driver->thread_info.whd_inited = WHD_TRUE; - - return WHD_SUCCESS; + whd_result_t retval; + +#ifndef PROTO_MSGBUF + if ( (retval = whd_sdpcm_init(whd_driver) ) != WHD_SUCCESS ) + { + WPRINT_WHD_ERROR( ("Could not initialize SDPCM codec\n") ); + /* Lint: Reachable after hitting assert & globals not defined due to error */ + return retval; + } +#endif /* PROTO_MSGBUF */ + + /* Create the event flag which signals the WHD thread needs to wake up */ + retval = cy_rtos_init_semaphore(&whd_driver->thread_info.transceive_semaphore, 1, 0); + if (retval != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Could not initialize WHD thread semaphore\n") ); + /* Lint: Reachable after hitting assert & globals not defined due to error */ + return retval; + } + + retval = cy_rtos_create_thread(&whd_driver->thread_info.whd_thread, (cy_thread_entry_fn_t)whd_thread_func, + "WHD", whd_driver->thread_info.thread_stack_start, + whd_driver->thread_info.thread_stack_size, + whd_driver->thread_info.thread_priority, (cy_thread_arg_t)whd_driver); + if (retval != WHD_SUCCESS) + { + /* Could not start WHD main thread */ + WPRINT_WHD_ERROR( ("Could not start WHD thread\n") ); + return retval; + } + + /* Ready now. Indicate it here and in thread, whatever be executed first. */ + whd_driver->thread_info.whd_inited = WHD_TRUE; + + return WHD_SUCCESS; } /** Sends the first queued packet @@ -119,30 +128,74 @@ whd_result_t whd_thread_init(whd_driver_t whd_driver) */ int8_t whd_thread_send_one_packet(whd_driver_t whd_driver) { - whd_buffer_t tmp_buf_hnd = NULL; - whd_result_t result; - - if (whd_sdpcm_get_packet_to_send(whd_driver, &tmp_buf_hnd) != WHD_SUCCESS) { - /* Failed to get a packet */ - return 0; - } - - /* Ensure the wlan backplane bus is up */ - result = whd_ensure_wlan_bus_is_up(whd_driver); - if (result != WHD_SUCCESS) { - whd_assert("Could not bring bus back up", 0 != 0); - CHECK_RETURN(whd_buffer_release(whd_driver, tmp_buf_hnd, WHD_NETWORK_TX)); - return 0; - } - - WPRINT_WHD_DATA_LOG(("Wcd:> Sending pkt 0x%08lX\n", (unsigned long)tmp_buf_hnd)); - if (whd_bus_send_buffer(whd_driver, tmp_buf_hnd) != WHD_SUCCESS) { - WHD_STATS_INCREMENT_VARIABLE(whd_driver, tx_fail); - return 0; - } - - WHD_STATS_INCREMENT_VARIABLE(whd_driver, tx_total); - return (int8_t)1; + whd_result_t result; +#ifndef PROTO_MSGBUF + whd_buffer_t tmp_buf_hnd = NULL; + + if (whd_sdpcm_get_packet_to_send(whd_driver, &tmp_buf_hnd) != WHD_SUCCESS) + { + /* Failed to get a packet */ + return 0; + } + + /* Ensure the wlan backplane bus is up */ + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + whd_assert("Could not bring bus back up", 0 != 0); + CHECK_RETURN(whd_buffer_release(whd_driver, tmp_buf_hnd, WHD_NETWORK_TX) ); + return 0; + } + + WPRINT_WHD_DATA_LOG( ("Wcd:> Sending pkt 0x%08lX\n", (unsigned long)tmp_buf_hnd) ); + if (whd_bus_send_buffer(whd_driver, tmp_buf_hnd) != WHD_SUCCESS) + { + WHD_STATS_INCREMENT_VARIABLE(whd_driver, tx_fail); + return 0; + } + + WHD_STATS_INCREMENT_VARIABLE(whd_driver, tx_total); + + return (int8_t)1; +#else + uint16_t local_id = 0; + + /* Ensure the wlan backplane bus is up */ + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + whd_assert("Could not bring bus back up", 0 != 0); + return 0; + } + + /* Prefer to IOCTL Data than Tx Data */ + if (whd_driver->msgbuf->ioctl_queue) + { + WPRINT_WHD_DEBUG(("Wcd:> Sending pkt ioctl_queue - %p\n", whd_driver->msgbuf->ioctl_queue)); + (void)whd_msgbuf_ioctl_dequeue(whd_driver); + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); + } + + for (local_id = 0; local_id < whd_driver->ram_shared->max_flowrings; local_id++) + { + if (isset(whd_driver->msgbuf->flow_map, local_id) ) + { + WPRINT_WHD_DEBUG(("Wcd:> Sending Data pkt through Flowring\n")); + clrbit(whd_driver->msgbuf->flow_map, local_id); + whd_msgbuf_txflow(whd_driver, local_id); + DELAYED_BUS_RELEASE_SCHEDULE(whd_driver, WHD_TRUE); + } + } + + if (local_id == whd_driver->ram_shared->max_flowrings) + { + WPRINT_WHD_DEBUG(("Sending pkt failed - reached max flowring count\n")); + return 0; + } + /* In MSGBUF protocol case, all the queued packets + are sent through flowrings so, no need to check return 1 */ + return (int8_t)0; +#endif /* PROTO_MSGBUF */ } /** Receives a packet if one is waiting @@ -160,23 +213,63 @@ int8_t whd_thread_send_one_packet(whd_driver_t whd_driver) */ int8_t whd_thread_receive_one_packet(whd_driver_t whd_driver) { - /* Check if there is a packet ready to be received */ - whd_buffer_t recv_buffer; - if (whd_bus_read_frame(whd_driver, &recv_buffer) != WHD_SUCCESS) { - /* Failed to read a packet */ - return 0; - } +#ifndef PROTO_MSGBUF + /* Check if there is a packet ready to be received */ + whd_buffer_t recv_buffer; + if (whd_bus_read_frame(whd_driver, &recv_buffer) != WHD_SUCCESS) + { + /* Failed to read a packet */ + return 0; + } if (recv_buffer != NULL) /* Could be null if it was only a credit update */ { - WPRINT_WHD_DATA_LOG(("Wcd:< Rcvd pkt 0x%08lX\n", (unsigned long)recv_buffer)); WHD_STATS_INCREMENT_VARIABLE(whd_driver, rx_total); - /* Send received buffer up to SDPCM layer */ - whd_sdpcm_process_rx_packet(whd_driver, recv_buffer); - } - return (int8_t)1; +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) + uint8_t *data = whd_buffer_get_current_piece_data_pointer(whd_driver, recv_buffer); + + if (data[0] == 0x20) { + /* Check if receive bdc Event or Data pack */ + whd_event_t *event = (whd_event_t *)(data + sizeof(bdc_header_t)); + + if (ntoh16(event->eth.ethertype) == 0x886C /* <- ETHER_TYPE_BRCM */) + { + whd_process_bdc_event(whd_driver, recv_buffer, + whd_buffer_get_current_piece_size(whd_driver, recv_buffer)); + } + else + { + whd_process_bdc(whd_driver, recv_buffer); + } + } + else + { + whd_process_cdc(whd_driver, recv_buffer); + } +#else + /* Send received buffer up to SDPCM layer */ + whd_sdpcm_process_rx_packet(whd_driver, recv_buffer); +#endif /* (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) */ + } + + return (int8_t)1; +#else + whd_result_t result; + + /* Ensure the wlan backplane bus is up */ + result = whd_ensure_wlan_bus_is_up(whd_driver); + if (result != WHD_SUCCESS) + { + whd_assert("Could not bring bus back up", 0 != 0); + return 0; + } + + /* Send Received Information to the Rings */ + return whd_msgbuf_process_rx_packet(whd_driver); +#endif /* PROTO_MSGBUF */ + } /** Sends and Receives all waiting packets @@ -193,10 +286,10 @@ int8_t whd_thread_receive_one_packet(whd_driver_t whd_driver) */ int8_t whd_thread_poll_all(whd_driver_t whd_driver) { - int8_t result = 0; - result |= whd_thread_send_one_packet(whd_driver); - result |= whd_thread_receive_one_packet(whd_driver); - return result; + int8_t result = 0; + result |= whd_thread_send_one_packet(whd_driver); + result |= whd_thread_receive_one_packet(whd_driver); + return result; } /** Terminates the WHD Thread @@ -206,21 +299,22 @@ int8_t whd_thread_poll_all(whd_driver_t whd_driver) */ void whd_thread_quit(whd_driver_t whd_driver) { - whd_thread_info_t *thread_info = &whd_driver->thread_info; - whd_result_t result; - - /* signal main thread and wake it */ - thread_info->thread_quit_flag = WHD_TRUE; - result = cy_rtos_set_semaphore(&thread_info->transceive_semaphore, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Error setting semaphore in %s at %d \n", __func__, __LINE__)); - } - - /* Wait for the WHD thread to end */ - cy_rtos_join_thread(&thread_info->whd_thread); - /* Delete the semaphore */ - /* Ignore return - not much can be done about failure */ - (void)cy_rtos_deinit_semaphore(&thread_info->transceive_semaphore); + whd_thread_info_t *thread_info = &whd_driver->thread_info; + whd_result_t result; + + /* signal main thread and wake it */ + thread_info->thread_quit_flag = WHD_TRUE; + result = cy_rtos_set_semaphore(&thread_info->transceive_semaphore, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Error setting semaphore in %s at %d \n", __func__, __LINE__) ); + } + + /* Wait for the WHD thread to end */ + cy_rtos_join_thread(&thread_info->whd_thread); + /* Delete the semaphore */ + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_deinit_semaphore(&thread_info->transceive_semaphore); } /** @@ -234,21 +328,23 @@ void whd_thread_quit(whd_driver_t whd_driver) /* ignore failure since there is nothing that can be done about it in a ISR */ void whd_thread_notify_irq(whd_driver_t whd_driver) { - whd_driver->thread_info.bus_interrupt = WHD_TRUE; + whd_driver->thread_info.bus_interrupt = WHD_TRUE; - /* just wake up the main thread and let it deal with the data */ - if (whd_driver->thread_info.whd_inited == WHD_TRUE) { - (void)cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_TRUE); - } + /* just wake up the main thread and let it deal with the data */ + if (whd_driver->thread_info.whd_inited == WHD_TRUE) + { + (void)cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_TRUE); + } } void whd_thread_notify(whd_driver_t whd_driver) { - /* just wake up the main thread and let it deal with the data */ - if (whd_driver->thread_info.whd_inited == WHD_TRUE) { - /* Ignore return - not much can be done about failure */ - (void)cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_FALSE); - } + /* just wake up the main thread and let it deal with the data */ + if (whd_driver->thread_info.whd_inited == WHD_TRUE) + { + /* Ignore return - not much can be done about failure */ + (void)cy_rtos_set_semaphore(&whd_driver->thread_info.transceive_semaphore, WHD_FALSE); + } } /****************************************************** @@ -268,76 +364,90 @@ void whd_thread_notify(whd_driver_t whd_driver) */ static void whd_thread_func(cy_thread_arg_t thread_input) { - int8_t rx_status; - int8_t tx_status; - uint8_t rx_cnt, rx_over_bound = 0; - uint8_t bus_fail = 0; - uint8_t error_type; - uint32_t status; - - whd_driver_t whd_driver = (whd_driver_t)thread_input; - whd_thread_info_t *thread_info = &whd_driver->thread_info; - - WPRINT_WHD_DATA_LOG(("Started whd Thread\n")); - - /* Interrupts may be enabled inside thread. To make sure none lost set flag now. */ - thread_info->whd_inited = WHD_TRUE; - - while (thread_info->thread_quit_flag != WHD_TRUE) { - rx_cnt = 0; - /* Check if we were woken by interrupt */ - if ((thread_info->bus_interrupt == WHD_TRUE) || - (whd_bus_use_status_report_scheme(whd_driver))) { - thread_info->bus_interrupt = WHD_FALSE; - - /* Check if the interrupt indicated there is a packet to read */ - status = whd_bus_packet_available_to_read(whd_driver); - if (((status != 0) && (status != WHD_BUS_FAIL)) || rx_over_bound) { - rx_over_bound = 0; - /* Receive all available packets */ - do { - rx_status = whd_thread_receive_one_packet(whd_driver); - rx_cnt++; - } while (rx_status != 0 && rx_cnt < WHD_THREAD_RX_BOUND); - bus_fail = 0; - } - else { - if (status == WHD_BUS_FAIL) { - bus_fail++; - } - } - } - - /* Send all queued packets */ - do { - tx_status = whd_thread_send_one_packet(whd_driver); - } while (tx_status != 0); - - if (rx_cnt >= WHD_THREAD_RX_BOUND) { - thread_info->bus_interrupt = WHD_TRUE; - rx_over_bound = 1; - continue; - } - if (bus_fail > WHD_MAX_BUS_FAIL) { - WPRINT_WHD_ERROR(("%s: Error bus_fail over %d times\n", __FUNCTION__, WHD_MAX_BUS_FAIL)); - error_type = WLC_ERR_BUS; - whd_set_error_handler_locally(whd_driver, &error_type, NULL, NULL, NULL); - } - - /* Sleep till WLAN do something */ - whd_bus_wait_for_wlan_event(whd_driver, &thread_info->transceive_semaphore); - WPRINT_WHD_DATA_LOG(("whd Thread: Woke\n")); - } - - /* Set flag before releasing objects */ - thread_info->whd_inited = WHD_FALSE; - - /* Reset the quit flag */ - thread_info->thread_quit_flag = WHD_FALSE; - - whd_sdpcm_quit(whd_driver); - - WPRINT_WHD_DATA_LOG(("Stopped whd Thread\n")); + int8_t rx_status; + int8_t tx_status; + uint8_t rx_cnt, rx_over_bound = 0; + uint8_t bus_fail = 0; + uint32_t status; + + whd_driver_t whd_driver = ( whd_driver_t )thread_input; + whd_thread_info_t *thread_info = &whd_driver->thread_info; + + WPRINT_WHD_DATA_LOG( ("Started whd Thread\n") ); + + /* Interrupts may be enabled inside thread. To make sure none lost set flag now. */ + thread_info->whd_inited = WHD_TRUE; + + while (thread_info->thread_quit_flag != WHD_TRUE) + { + rx_cnt = 0; + /* Check if we were woken by interrupt */ + if ( (thread_info->bus_interrupt == WHD_TRUE) || + (whd_bus_use_status_report_scheme(whd_driver) ) ) + { + thread_info->bus_interrupt = WHD_FALSE; + + /* Check if the interrupt indicated there is a packet to read */ + status = whd_bus_packet_available_to_read(whd_driver); + if ( ( (status != 0) && (status != WHD_BUS_FAIL) ) || rx_over_bound ) + { + rx_over_bound = 0; + /* Receive all available packets */ + do + { + rx_status = whd_thread_receive_one_packet(whd_driver); + rx_cnt++; + } while (rx_status != 0 && rx_cnt < WHD_THREAD_RX_BOUND); + bus_fail = 0; + } + else + { + if (status == WHD_BUS_FAIL) + { + bus_fail++; + } + } + } + + /* Send all queued packets */ + do + { + tx_status = whd_thread_send_one_packet(whd_driver); + } while (tx_status != 0); + + if (rx_cnt >= WHD_THREAD_RX_BOUND) + { + thread_info->bus_interrupt = WHD_TRUE; + rx_over_bound = 1; + continue; + } + if (bus_fail > WHD_MAX_BUS_FAIL) + { + WPRINT_WHD_ERROR( ("%s: Error bus_fail over %d times, exiting\n", __FUNCTION__, WHD_MAX_BUS_FAIL) ); +#if 0 + uint8_t error_type = WLC_ERR_BUS; + whd_set_error_handler_locally(whd_driver, &error_type, NULL, NULL, NULL); +#else + break; +#endif + } + + /* Sleep till WLAN do something */ + whd_bus_wait_for_wlan_event(whd_driver, &thread_info->transceive_semaphore); + WPRINT_WHD_DATA_LOG( ("whd Thread: Woke\n") ); + } + + /* Set flag before releasing objects */ + thread_info->whd_inited = WHD_FALSE; + + /* Reset the quit flag */ + thread_info->thread_quit_flag = WHD_FALSE; + +#ifndef PROTO_MSGBUF + whd_sdpcm_quit(whd_driver); +#endif /* PROTO_MSGBUF */ + + WPRINT_WHD_DATA_LOG( ("Stopped whd Thread\n") ); /* Ignore return - not much can be done about failure */ cy_rtos_exit_thread(); diff --git a/wi-fi/whd/whd_thread.h b/wi-fi/whd/whd_thread.h index 932f3f92..9ee2c38b 100644 --- a/wi-fi/whd/whd_thread.h +++ b/wi-fi/whd/whd_thread.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -38,25 +38,27 @@ #define INCLUDED_WHD_THREAD_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** * Constants ******************************************************/ -#define WHD_THREAD_RX_BOUND (20) -#define WHD_MAX_BUS_FAIL (10) +#define WHD_THREAD_RX_BOUND (20) +#define WHD_MAX_BUS_FAIL (10) -typedef struct whd_thread_info { +typedef struct whd_thread_info +{ - volatile whd_bool_t thread_quit_flag; - volatile whd_bool_t whd_inited; - cy_thread_t whd_thread; - cy_semaphore_t transceive_semaphore; - volatile whd_bool_t bus_interrupt; - void *thread_stack_start; - uint32_t thread_stack_size; - cy_thread_priority_t thread_priority; + volatile whd_bool_t thread_quit_flag; + volatile whd_bool_t whd_inited; + cy_thread_t whd_thread; + cy_semaphore_t transceive_semaphore; + volatile whd_bool_t bus_interrupt; + void *thread_stack_start; + uint32_t thread_stack_size; + cy_thread_priority_t thread_priority; } whd_thread_info_t; diff --git a/wi-fi/whd/whd_thread_internal.h b/wi-fi/whd/whd_thread_internal.h index 191d042b..0b4769c2 100644 --- a/wi-fi/whd/whd_thread_internal.h +++ b/wi-fi/whd/whd_thread_internal.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,8 @@ #define INCLUDED_WHD_THREAD_INTERNAL_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include "whd_debug.h" @@ -30,21 +31,21 @@ extern "C" { ******************************************************/ #define WHD_WLAN_KEEP_AWAKE(whd_driver) \ - do { \ - whd_result_t verify_result; \ - whd_driver->internal_info.whd_wlan_status.keep_wlan_awake++; \ - verify_result = whd_ensure_wlan_bus_is_up(whd_driver); \ - whd_assert("Could not bring bus up", (verify_result == WHD_SUCCESS)); \ - } while (0) + do { \ + whd_result_t verify_result; \ + whd_driver->internal_info.whd_wlan_status.keep_wlan_awake++; \ + verify_result = whd_ensure_wlan_bus_is_up(whd_driver); \ + whd_assert("Could not bring bus up", (verify_result == WHD_SUCCESS) ); \ + } while (0) #define WHD_WLAN_LET_SLEEP(whd_driver) \ - do { \ - whd_driver->internal_info.whd_wlan_status.keep_wlan_awake--; \ - if (whd_driver->internal_info.whd_wlan_status.keep_wlan_awake == 0) \ - whd_thread_notify(whd_driver); \ - } while (0) + do { \ + whd_driver->internal_info.whd_wlan_status.keep_wlan_awake--; \ + if (whd_driver->internal_info.whd_wlan_status.keep_wlan_awake == 0) \ + whd_thread_notify(whd_driver); \ + } while (0) #define WHD_WLAN_MAY_SLEEP() \ - ((whd_driver->internal_info.whd_wlan_status.keep_wlan_awake == 0) && \ - (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP)) + ( (whd_driver->internal_info.whd_wlan_status.keep_wlan_awake == 0) && \ + (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) ) #ifdef __cplusplus } /* extern "C" */ diff --git a/wi-fi/whd/whd_types.h b/wi-fi/whd/whd_types.h index 4abb97cd..3fe6cb58 100644 --- a/wi-fi/whd/whd_types.h +++ b/wi-fi/whd/whd_types.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,61 +21,79 @@ */ #include -#include #include "cybsp.h" #include "cy_result.h" #include "cyhal_hw_types.h" +#include "cyhal_gpio.h" +#include "cyabs_rtos.h" #ifndef INCLUDED_WHD_TYPES_H_ #define INCLUDED_WHD_TYPES_H_ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** * Macros ******************************************************/ -#define SSID_NAME_SIZE (32) /**< SSID Length */ - -#define WEP_ENABLED 0x0001 /**< Flag to enable WEP Security */ -#define TKIP_ENABLED 0x0002 /**< Flag to enable TKIP Encryption */ -#define AES_ENABLED 0x0004 /**< Flag to enable AES Encryption */ -#define SHARED_ENABLED 0x00008000 /**< Flag to enable Shared key Security */ -#define WPA_SECURITY 0x00200000 /**< Flag to enable WPA Security */ -#define WPA2_SECURITY 0x00400000 /**< Flag to enable WPA2 Security */ -#define WPA3_SECURITY 0x01000000 /**< Flag to enable WPA3 PSK Security */ -#define SECURITY_MASK (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED) /**< Flag to Security mask */ - -#define ENTERPRISE_ENABLED 0x02000000 /**< Flag to enable Enterprise Security */ -#define WPS_ENABLED 0x10000000 /**< Flag to enable WPS Security */ -#define IBSS_ENABLED 0x20000000 /**< Flag to enable IBSS mode */ -#define FBT_ENABLED 0x40000000 /**< Flag to enable FBT */ - -#define PM1_POWERSAVE_MODE (1) /**< Powersave mode on specified interface without regard for throughput reduction */ -#define PM2_POWERSAVE_MODE (2) /**< Powersave mode on specified interface with High throughput */ -#define NO_POWERSAVE_MODE (0) /**< No Powersave mode */ +#define SSID_NAME_SIZE (32) /**< SSID Length */ + +#define WEP_ENABLED 0x0001 /**< Flag to enable WEP Security */ +#define TKIP_ENABLED 0x0002 /**< Flag to enable TKIP Encryption */ +#define AES_ENABLED 0x0004 /**< Flag to enable AES Encryption */ +#define SHARED_ENABLED 0x00008000 /**< Flag to enable Shared key Security */ +#define WPA_SECURITY 0x00200000 /**< Flag to enable WPA Security */ +#define WPA2_SECURITY 0x00400000 /**< Flag to enable WPA2 Security */ +#define WPA3_SECURITY 0x01000000 /**< Flag to enable WPA3 PSK Security */ +#define WPA3_OWE 0x80000000 /**< Flag to enable WPA3 OWE Security */ + +#define SECURITY_MASK (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED) /**< Flag to Security mask */ + +#define ENTERPRISE_ENABLED 0x02000000 /**< Flag to enable Enterprise Security */ +#define SHA256_1X 0x04000000 /**< Flag 1X with SHA256 key derivation */ +#define SUITE_B_SHA384 0x08000000 /**< Flag to enable Suite B-192 SHA384 Security */ +#define WPS_ENABLED 0x10000000 /**< Flag to enable WPS Security */ +#define IBSS_ENABLED 0x20000000 /**< Flag to enable IBSS mode */ +#define FBT_ENABLED 0x40000000 /**< Flag to enable FBT */ + +#define PM1_POWERSAVE_MODE (1) /**< Powersave mode on specified interface without regard for throughput reduction */ +#define PM2_POWERSAVE_MODE (2) /**< Powersave mode on specified interface with High throughput */ +#define NO_POWERSAVE_MODE (0) /**< No Powersave mode */ + +#define ULP_BUSWIDTH_INTR_MODE (0) /**< Use BUS Width Interrupt method, when device is in DS2 state Exit */ +#define ULP_OOB_INTR_MODE (1) /**< Use OOB interrupt method, when device is in DS2 state Exit */ +#define ULP_ASYNC_INTR_MODE (2) /**< Use Asynchronous method, when device is in DS2 state Exit */ + +#define PMKID_LEN (16) /**< PMKID LENGTH */ + +#define ULP_NO_SUPPORT (0) /**< Flag to disable ULP in 43022 */ +#define ULP_DS1_SUPPORT (1) /**< Flag to enable DS1 mode in 43022 */ +#define ULP_DS2_SUPPORT (2) /**< Flag to enable DS2 mode in 43022(Only supported in DM) */ +#define WHD_OOB_CONFIG_VERSION (2) /**< Indicate the version for whd_oob_config structure */ +#define WHD_SAP_USE_CHANSPEC (1) /**< Define this macro as any value indicate whd_wifi_init_ap api uses chanspec instead of channel */ /** * Suppress unused parameter warning */ #ifndef UNUSED_PARAMETER -#define UNUSED_PARAMETER(x) ((void)(x)) +#define UNUSED_PARAMETER(x) ( (void)(x) ) #endif /** * Suppress unused variable warning */ #ifndef UNUSED_VARIABLE -#define UNUSED_VARIABLE(x) ((void)(x)) +#define UNUSED_VARIABLE(x) ( (void)(x) ) #endif /** * Suppress unused variable warning occurring due to an assert which is disabled in release mode */ #ifndef REFERENCE_DEBUG_ONLY_VARIABLE -#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ((void)(x)) +#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ( (void)(x) ) #endif /****************************************************** @@ -90,59 +108,77 @@ typedef struct wl_pkt_filter_stats whd_pkt_filter_stats_t; typedef struct whd_tko_retry whd_tko_retry_t; typedef struct whd_tko_connect whd_tko_connect_t; typedef struct whd_tko_status whd_tko_status_t; +typedef struct whd_tko_auto_filter whd_tko_auto_filter_t; +typedef struct whd_tko_autoconnect whd_tko_autoconnect_t; +typedef struct tls_param_info tls_param_info_t; +typedef struct secure_sess_info secure_sess_info_t; /** @endcond */ /****************************************************** * Constants ******************************************************/ -#define WIFI_IE_OUI_LENGTH (3) /**< OUI length for Information Element */ -#define VNDR_IE_MAX_LEN 255 /**< vendor IE max length, without ID and len */ +#define WIFI_IE_OUI_LENGTH (3) /**< OUI length for Information Element */ +#define VNDR_IE_MAX_LEN 255 /**< vendor IE max length, without ID and len */ /* Below constants are used to allocate the buffer pool by the application */ -#define BDC_HEADER_WITH_PAD 6 /**< BDC Header with padding 4 + 2 */ +#define BDC_HEADER_WITH_PAD 6 /**< BDC Header with padding 4 + 2 */ + +#define MSGBUF_OVERHEAD_WITH_PAD 6 /**< Overhaed Space with padding 4 + 2 */ /** From bdc header, Ethernet data starts after an offset of (bdc_header->data_offset<<2). * It is variable, but usually 4. */ #define BDC_HEADER_OFFSET_TO_DATA 4 -#define SDPCM_HEADER (8 + 4) /**< SDPCM SW header + Frame tag */ +#define SDPCM_HEADER (8 + 4) /**< SDPCM SW header + Frame tag */ #if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) #define MAX_BUS_HEADER_SIZE 4 /**< Max bus header size for all bus types (sdio) */ #elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SPI_INTERFACE) #define MAX_BUS_HEADER_SIZE 4 /**< Max bus header size for all bus types (spi) */ +#elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) +#define MAX_BUS_HEADER_SIZE 4 /**< Max bus header size for all bus types (usb) */ #elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) #define MAX_BUS_HEADER_SIZE 8 /**< Max bus header size for all bus types (m2m) */ +#elif defined(COMPONENT_WIFI_INTERFACE_OCI) +#define MAX_BUS_HEADER_SIZE 8 /**< Max bus header size for all bus types (custom/oci) */ #else -#error "CYBSP_WIFI_INTERFACE_TYPE is not defined" +#error "CYBSP_WIFI_INTERFACE_TYPE or COMPONENT_WIFI_INTERFACE_OCI is not defined" #endif #define BUFFER_OVERHEAD 4 /**< Buffer overhead, sizeof(void *) */ +#ifndef PROTO_MSGBUF /** * The maximum space in bytes required for headers in front of the Ethernet header. * 6 + (8 + 4) + 4 + 4 + 4 = 30 bytes */ #define WHD_LINK_HEADER (BDC_HEADER_WITH_PAD + BDC_HEADER_OFFSET_TO_DATA + \ - SDPCM_HEADER + MAX_BUS_HEADER_SIZE + BUFFER_OVERHEAD) + SDPCM_HEADER + MAX_BUS_HEADER_SIZE + BUFFER_OVERHEAD) +#else +/* + * In nx_user.h NX_PHYSICAL_HEADER is (14(Ethernet) + 4(Overhaed) + 2(pad)), + * so we are doing the similar here -> 4(hedaer) + 2(pad) in front of ethernet header + */ +#define WHD_LINK_HEADER (MSGBUF_OVERHEAD_WITH_PAD) +#endif /* PROTO_MSGBUF */ /** * The size of an Ethernet header */ -#define WHD_ETHERNET_SIZE (14) +#define WHD_ETHERNET_SIZE (14) /** * The size in bytes of the Link layer header i.e. the whd specific headers and the Ethernet header */ -#define WHD_PHYSICAL_HEADER (WHD_LINK_HEADER + WHD_ETHERNET_SIZE) +#define WHD_PHYSICAL_HEADER (WHD_LINK_HEADER + WHD_ETHERNET_SIZE) /** * The maximum size in bytes of the data part of an Ethernet frame */ #ifndef WHD_PAYLOAD_MTU -#define WHD_PAYLOAD_MTU (1500) +#define WHD_PAYLOAD_MTU (1500) #endif /** @@ -152,7 +188,7 @@ typedef struct whd_tko_status whd_tko_status_t; * taken into account along with this during buffer pool creation. Also buffer pools needs alignment with * cache size of the platform for better performance */ -#define WHD_LINK_MTU (WHD_PAYLOAD_MTU + WHD_PHYSICAL_HEADER) +#define WHD_LINK_MTU (WHD_PAYLOAD_MTU + WHD_PHYSICAL_HEADER) /** @cond */ #ifdef __x86_64__ @@ -167,222 +203,267 @@ typedef uint32_t whd_thread_arg_t; /** * Enumeration of Dot11 Reason Codes */ -typedef enum { - WHD_DOT11_RC_RESERVED = 0, /**< Reserved */ - WHD_DOT11_RC_UNSPECIFIED = 1 /**< Unspecified */ +typedef enum +{ + WHD_DOT11_RC_RESERVED = 0, /**< Reserved */ + WHD_DOT11_RC_UNSPECIFIED = 1 /**< Unspecified */ } whd_dot11_reason_code_t; /** * Boolean values */ -typedef enum { - WHD_FALSE = 0, /**< Boolean True */ - WHD_TRUE = 1 /**< Boolean False */ +typedef enum +{ + WHD_FALSE = 0, /**< Boolean True */ + WHD_TRUE = 1 /**< Boolean False */ } whd_bool_t; /** * Transfer direction for the WHD platform bus interface */ -typedef enum { - /* If updating this enum, the bus_direction_mapping variable will also need to be updated */ - BUS_READ, /**< Specifies bus type and read direction */ - BUS_WRITE /**< Specifies bus type and write direction */ +typedef enum +{ + /* If updating this enum, the bus_direction_mapping variable will also need to be updated */ + BUS_READ, /**< Specifies bus type and read direction */ + BUS_WRITE /**< Specifies bus type and write direction */ } whd_bus_transfer_direction_t; /** * Enumeration of Wi-Fi security modes */ -typedef enum { - WHD_SECURITY_OPEN = 0, /**< Open security */ - WHD_SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP PSK Security with open authentication */ - WHD_SECURITY_WEP_SHARED = (WEP_ENABLED | SHARED_ENABLED), /**< WEP PSK Security with shared authentication */ - WHD_SECURITY_WPA_TKIP_PSK = (WPA_SECURITY | TKIP_ENABLED), /**< WPA PSK Security with TKIP */ - WHD_SECURITY_WPA_AES_PSK = (WPA_SECURITY | AES_ENABLED), /**< WPA PSK Security with AES */ - WHD_SECURITY_WPA_MIXED_PSK = (WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA PSK Security with AES & TKIP */ - WHD_SECURITY_WPA2_AES_PSK = (WPA2_SECURITY | AES_ENABLED), /**< WPA2 PSK Security with AES */ - WHD_SECURITY_WPA2_TKIP_PSK = (WPA2_SECURITY | TKIP_ENABLED), /**< WPA2 PSK Security with TKIP */ - WHD_SECURITY_WPA2_MIXED_PSK = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 PSK Security with AES & TKIP */ - WHD_SECURITY_WPA2_FBT_PSK = (WPA2_SECURITY | AES_ENABLED | FBT_ENABLED), /**< WPA2 FBT PSK Security with AES & TKIP */ - WHD_SECURITY_WPA3_SAE = (WPA3_SECURITY | AES_ENABLED), /**< WPA3 Security with AES */ - WHD_SECURITY_WPA2_WPA_AES_PSK = (WPA2_SECURITY | WPA_SECURITY | AES_ENABLED), /**< WPA2 WPA PSK Security with AES */ - WHD_SECURITY_WPA2_WPA_MIXED_PSK = (WPA2_SECURITY | WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 WPA PSK Security with AES & TKIP */ - - WHD_SECURITY_WPA3_WPA2_PSK = (WPA3_SECURITY | WPA2_SECURITY | AES_ENABLED), /**< WPA3 WPA2 PSK Security with AES */ - - WHD_SECURITY_WPA_TKIP_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | TKIP_ENABLED), /**< WPA Enterprise Security with TKIP */ - WHD_SECURITY_WPA_AES_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED), /**< WPA Enterprise Security with AES */ - WHD_SECURITY_WPA_MIXED_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA Enterprise Security with AES & TKIP */ - WHD_SECURITY_WPA2_TKIP_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | TKIP_ENABLED), /**< WPA2 Enterprise Security with TKIP */ - WHD_SECURITY_WPA2_AES_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED), /**< WPA2 Enterprise Security with AES */ - WHD_SECURITY_WPA2_MIXED_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 Enterprise Security with AES & TKIP */ - WHD_SECURITY_WPA2_FBT_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | FBT_ENABLED), /**< WPA2 Enterprise Security with AES & FBT */ - - WHD_SECURITY_IBSS_OPEN = (IBSS_ENABLED), /**< Open security on IBSS ad-hoc network */ - WHD_SECURITY_WPS_SECURE = AES_ENABLED, /**< WPS with AES security */ - - WHD_SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */ - - WHD_SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force whd_security_t type to 32 bits */ +typedef enum +{ + WHD_SECURITY_OPEN = 0, /**< Open security */ + WHD_SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP PSK Security with open authentication */ + WHD_SECURITY_WEP_SHARED = (WEP_ENABLED | SHARED_ENABLED), /**< WEP PSK Security with shared authentication */ + WHD_SECURITY_WPA_TKIP_PSK = (WPA_SECURITY | TKIP_ENABLED), /**< WPA PSK Security with TKIP */ + WHD_SECURITY_WPA_AES_PSK = (WPA_SECURITY | AES_ENABLED), /**< WPA PSK Security with AES */ + WHD_SECURITY_WPA_MIXED_PSK = (WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA PSK Security with AES & TKIP */ + WHD_SECURITY_WPA2_AES_PSK = (WPA2_SECURITY | AES_ENABLED), /**< WPA2 PSK Security with AES */ + WHD_SECURITY_WPA2_AES_PSK_SHA256 = (WPA2_SECURITY | SHA256_1X | AES_ENABLED), /**< WPA2 PSK SHA256 Security with AES */ + WHD_SECURITY_WPA2_TKIP_PSK = (WPA2_SECURITY | TKIP_ENABLED), /**< WPA2 PSK Security with TKIP */ + WHD_SECURITY_WPA2_MIXED_PSK = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 PSK Security with AES & TKIP */ + WHD_SECURITY_WPA2_FBT_PSK = (WPA2_SECURITY | AES_ENABLED | FBT_ENABLED), /**< WPA2 FBT PSK Security with AES & TKIP */ + WHD_SECURITY_WPA3_SAE = (WPA3_SECURITY | AES_ENABLED), /**< WPA3 Security with AES */ + WHD_SECURITY_WPA2_WPA_AES_PSK = (WPA2_SECURITY | WPA_SECURITY | AES_ENABLED), /**< WPA2 WPA PSK Security with AES */ + WHD_SECURITY_WPA2_WPA_MIXED_PSK = (WPA2_SECURITY | WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 WPA PSK Security with AES & TKIP */ + + WHD_SECURITY_WPA3_WPA2_PSK = (WPA3_SECURITY | WPA2_SECURITY | AES_ENABLED), /**< WPA3 WPA2 PSK Security with AES */ + + WHD_SECURITY_WPA_TKIP_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | TKIP_ENABLED), /**< WPA Enterprise Security with TKIP */ + WHD_SECURITY_WPA_AES_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED), /**< WPA Enterprise Security with AES */ + WHD_SECURITY_WPA_MIXED_ENT = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA Enterprise Security with AES & TKIP */ + WHD_SECURITY_WPA2_TKIP_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | TKIP_ENABLED), /**< WPA2 Enterprise Security with TKIP */ + WHD_SECURITY_WPA2_AES_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED), /**< WPA2 Enterprise Security with AES */ + WHD_SECURITY_WPA2_MIXED_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /**< WPA2 Enterprise Security with AES & TKIP */ + WHD_SECURITY_WPA2_FBT_ENT = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | FBT_ENABLED), /**< WPA2 Enterprise Security with AES & FBT */ + + WHD_SECURITY_WPA3_192BIT_ENT = (ENTERPRISE_ENABLED | WPA3_SECURITY | SUITE_B_SHA384 | AES_ENABLED),/**< WPA3 192-BIT Enterprise Security with AES */ + WHD_SECURITY_WPA3_ENT = (ENTERPRISE_ENABLED | WPA3_SECURITY | SHA256_1X | AES_ENABLED), /**< WPA3 Enterprise Security with AES */ + WHD_SECURITY_WPA3_ENT_AES_CCMP= (ENTERPRISE_ENABLED | WPA3_SECURITY | WPA2_SECURITY | SHA256_1X | AES_ENABLED),/**< WPA3 Enterprise transition Security with AES */ + + WHD_SECURITY_IBSS_OPEN = (IBSS_ENABLED), /**< Open security on IBSS ad-hoc network */ + WHD_SECURITY_WPS_SECURE = AES_ENABLED, /**< WPS with AES security */ + WHD_SECURITY_WPA3_OWE = (WPA3_SECURITY | AES_ENABLED | WPA3_OWE), /**< WPA3 Enhanced Open with AES security */ + + WHD_SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */ + + WHD_SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force whd_security_t type to 32 bits */ } whd_security_t; /** * Enumeration of methods of scanning */ -typedef enum { - WHD_SCAN_TYPE_ACTIVE = 0x00, /**< Actively scan a network by sending 802.11 probe(s) */ - WHD_SCAN_TYPE_PASSIVE = 0x01, /**< Passively scan a network by listening for beacons from APs */ - WHD_SCAN_TYPE_PNO = 0x02, /**< Use preferred network offload to detect an AP */ - WHD_SCAN_TYPE_PROHIBITED_CHANNELS = 0x04, /**< Permit (passively) scanning a channel that isn't valid for the current country */ - WHD_SCAN_TYPE_NO_BSSID_FILTER = 0x08 /**< Return a scan record for each beacon or probe response RX'ed */ +typedef enum +{ + WHD_SCAN_TYPE_ACTIVE = 0x00, /**< Actively scan a network by sending 802.11 probe(s) */ + WHD_SCAN_TYPE_PASSIVE = 0x01, /**< Passively scan a network by listening for beacons from APs */ + WHD_SCAN_TYPE_PNO = 0x02, /**< Use preferred network offload to detect an AP */ + WHD_SCAN_TYPE_PROHIBITED_CHANNELS = 0x04, /**< Permit (passively) scanning a channel that isn't valid for the current country */ + WHD_SCAN_TYPE_NO_BSSID_FILTER = 0x08 /**< Return a scan record for each beacon or probe response RX'ed */ } whd_scan_type_t; /** * Enumeration of network types */ -typedef enum { - WHD_BSS_TYPE_INFRASTRUCTURE = 0, /**< Denotes infrastructure network */ - WHD_BSS_TYPE_ADHOC = 1, /**< Denotes an 802.11 ad-hoc IBSS network */ - WHD_BSS_TYPE_ANY = 2, /**< Denotes either infrastructure or ad-hoc network */ - WHD_BSS_TYPE_MESH = 3, /**< Denotes 802.11 mesh network */ +typedef enum +{ + WHD_BSS_TYPE_INFRASTRUCTURE = 0, /**< Denotes infrastructure network */ + WHD_BSS_TYPE_ADHOC = 1, /**< Denotes an 802.11 ad-hoc IBSS network */ + WHD_BSS_TYPE_ANY = 2, /**< Denotes either infrastructure or ad-hoc network */ + WHD_BSS_TYPE_MESH = 3, /**< Denotes 802.11 mesh network */ - WHD_BSS_TYPE_UNKNOWN = -1 /**< May be returned by scan function if BSS type is unknown. Do not pass this to the Join function */ + WHD_BSS_TYPE_UNKNOWN = -1 /**< May be returned by scan function if BSS type is unknown. Do not pass this to the Join function */ } whd_bss_type_t; /** * Enumeration of 802.11 radio bands */ -typedef enum { - WHD_802_11_BAND_5GHZ = 0, /**< Denotes 5GHz radio band */ - WHD_802_11_BAND_2_4GHZ = 1 /**< Denotes 2.4GHz radio band */ +typedef enum +{ + WHD_802_11_BAND_5GHZ = 0, /**< Denotes 5GHz radio band */ + WHD_802_11_BAND_2_4GHZ = 1, /**< Denotes 2.4GHz radio band */ + WHD_802_11_BAND_6GHZ = 2 /**< Denotes 6GHz radio band */ } whd_802_11_band_t; /** * Enumeration of custom IE(Information Element) management actions */ -typedef enum { - WHD_ADD_CUSTOM_IE, /**< Add a custom IE(Information Element) */ - WHD_REMOVE_CUSTOM_IE /**< Remove a custom IE(Information Element) */ +typedef enum +{ + WHD_ADD_CUSTOM_IE, /**< Add a custom IE(Information Element) */ + WHD_REMOVE_CUSTOM_IE /**< Remove a custom IE(Information Element) */ } whd_custom_ie_action_t; /** * Enumeration of listen interval time unit types */ -typedef enum { - WHD_LISTEN_INTERVAL_TIME_UNIT_BEACON, /**< Time units specified in beacon periods */ - WHD_LISTEN_INTERVAL_TIME_UNIT_DTIM /**< Time units specified in DTIM periods */ +typedef enum +{ + WHD_LISTEN_INTERVAL_TIME_UNIT_BEACON, /**< Time units specified in beacon periods */ + WHD_LISTEN_INTERVAL_TIME_UNIT_DTIM /**< Time units specified in DTIM periods */ } whd_listen_interval_time_unit_t; /** * Structure for storing scan status */ -typedef enum { - WHD_SCAN_INCOMPLETE, /**< Denotes that scan is not finished */ - WHD_SCAN_COMPLETED_SUCCESSFULLY, /**< Successful completion of scan */ - WHD_SCAN_ABORTED, /**< Scan is aborted */ +typedef enum +{ + WHD_SCAN_INCOMPLETE, /**< Denotes that scan is not finished */ + WHD_SCAN_COMPLETED_SUCCESSFULLY, /**< Successful completion of scan */ + WHD_SCAN_ABORTED, /**< Scan is aborted */ } whd_scan_status_t; +/** + * Structure for storing status of auth event + */ +typedef enum +{ + WHD_AUTH_EXT_REQ, /**< Request authentication received */ + WHD_AUTH_EXT_FRAME_RX, /**< Authentication frame received */ +} whd_auth_status_t; + /** * Structure for storing radio band list information */ typedef struct { - int32_t number_of_bands; /**< Number of bands supported, currently 1 or 2 */ - int32_t current_band; /**< Current band type: WLC_BAND_2G or WLC_BAND_5G */ - int32_t other_band; /**< If value of number_of_bands parameter is 2, then this member specifies the 2nd band */ + int32_t number_of_bands; /**< Number of bands supported, currently 1 or 2 */ + int32_t current_band; /**< Current band type: WLC_BAND_2G or WLC_BAND_5G or WLC_BAND_6G */ + int32_t other_band[2]; /**< If value of number_of_bands parameter is 2, then this member specifies the 2nd band */ } whd_band_list_t; /** * Enumeration of scan result flags */ -typedef enum { - WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL = 0x01, /**< RSSI came from an off channel DSSS (1 or 1 Mb) Rx */ - WHD_SCAN_RESULT_FLAG_BEACON = 0x02 /**< Beacon (vs probe response) */ +typedef enum +{ + WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL = 0x01, /**< RSSI came from an off channel DSSS (1 or 1 Mb) Rx */ + WHD_SCAN_RESULT_FLAG_BEACON = 0x02, /**< Beacon (vs probe response) */ + WHD_SCAN_RESULT_FLAG_SAE_H2E = 0x04, /**< BSS is H2E(Hash-to-Element) */ } whd_scan_result_flag_t; /** * Protected Management Frame Capability */ -enum { - WL_MFP_NONE = 0, /**< Disables the client support for MFP. */ - WL_MFP_CAPABLE, /**< Allows both MFP-capable and clients that do not support MFP to join the network. */ - WL_MFP_REQUIRED /**< Clients are allowed to associate only if MFP is negotiated. */ +enum +{ + WL_MFP_NONE = 0, /**< Disables the client support for MFP. */ + WL_MFP_CAPABLE, /**< Allows both MFP-capable and clients that do not support MFP to join the network. */ + WL_MFP_REQUIRED /**< Clients are allowed to associate only if MFP is negotiated. */ }; /** * Enumeration of ioctl get */ -typedef enum { - WHD_IOCTL_GET_RATE = 12, - WHD_IOCTL_GET_COUNTRY = 83, - WHD_IOCTL_GET_CLK = 160, - WHD_IOCTL_GET_WSEC = 133, - WHD_IOCTL_GET_AUTH = 21, - WHD_IOCTL_GET_WPA_AUTH = 164, - WHD_IOCTL_GET_PM = 85, - WHD_IOCTL_GET_BSSID = 23, - WHD_IOCTL_GET_ASSOCLIST = 159, - WHD_IOCTL_GET_BSS_INFO = 136, - WHD_IOCTL_GET_CHANNEL = 29 +typedef enum +{ + WHD_IOCTL_GET_RATE = 12, + WHD_IOCTL_GET_COUNTRY = 83, + WHD_IOCTL_GET_CLK = 160, + WHD_IOCTL_GET_WSEC = 133, + WHD_IOCTL_GET_AUTH = 21, + WHD_IOCTL_GET_WPA_AUTH = 164, + WHD_IOCTL_GET_PM = 85, + WHD_IOCTL_GET_BSSID = 23, + WHD_IOCTL_GET_ASSOCLIST = 159, + WHD_IOCTL_GET_BSS_INFO = 136, + WHD_IOCTL_GET_CHANNEL = 29 } whd_usr_ioctl_get_list_t; /** * Enumeration of ioctl set */ -typedef enum { - WHD_IOCTL_SET_CHANNEL = 30, - WHD_IOCTL_SET_WSEC_PMK = 268, - WHD_IOCTL_SET_KEY = 45, - WHD_IOCTL_SET_WPA_AUTH = 165, - WHD_IOCTL_SCB_DEAUTHENTICATE_FOR_REASON = 201, - WHD_IOCTL_SET_PM = 86, - WHD_IOCTL_SET_SSID = 26, - WHD_IOCTL_SET_BCNPRD = 76, - WHD_IOCTL_SET_DTIMPRD = 78, - WHD_IOCTL_SET_WSEC = 134, - WHD_IOCTL_SET_INFRA = 20, - WHD_IOCTL_SET_AUTH = 22 +typedef enum +{ + WHD_IOCTL_SET_CHANNEL = 30, + WHD_IOCTL_SET_WSEC_PMK = 268, + WHD_IOCTL_SET_KEY = 45, + WHD_IOCTL_SET_WPA_AUTH = 165, + WHD_IOCTL_SCB_DEAUTHENTICATE_FOR_REASON = 201, + WHD_IOCTL_SET_PM = 86, + WHD_IOCTL_SET_SSID = 26, + WHD_IOCTL_SET_BCNPRD = 76, + WHD_IOCTL_SET_DTIMPRD = 78, + WHD_IOCTL_SET_WSEC = 134, + WHD_IOCTL_SET_INFRA = 20, + WHD_IOCTL_SET_AUTH = 22 } whd_usr_ioctl_set_list_t; /** * IOVAR set list */ -typedef enum { - WHD_IOVAR_SET_MFP = 0, - WHD_IOVAR_SET_MPC, - WHD_IOVAR_SET_AMPDU_BA_WINDOW_SIZE, - WHD_IOVAR_SET_AMPDU_MPDU, - WHD_IOVAR_SET_LISTEN_INTERVAL_BEACON, - WHD_IOVAR_SET_LISTEN_INTERVAL_DTIM, - WHD_IOVAR_SET_LISTEN_INTERVAL_ASSOC, +typedef enum +{ + WHD_IOVAR_SET_MFP = 0, + WHD_IOVAR_SET_MPC, + WHD_IOVAR_SET_AMPDU_BA_WINDOW_SIZE, + WHD_IOVAR_SET_AMPDU_MPDU, + WHD_IOVAR_SET_LISTEN_INTERVAL_BEACON, + WHD_IOVAR_SET_LISTEN_INTERVAL_DTIM, + WHD_IOVAR_SET_LISTEN_INTERVAL_ASSOC, } whd_usr_iovar_set_list_t; /** * IOVAR get list */ -typedef enum { - WHD_IOVAR_GET_MFP = 0, - WHD_IOVAR_GET_MPC, - WHD_IOVAR_GET_AMPDU_BA_WINDOW_SIZE, - WHD_IOVAR_GET_AMPDU_MPDU, - WHD_IOVAR_GET_LISTEN_INTERVAL, /**< Get Listen Interval value */ - WHD_IOVAR_GET_MAC_ADDRESS, /**< Get mac address */ +typedef enum +{ + WHD_IOVAR_GET_MFP = 0, + WHD_IOVAR_GET_MPC, + WHD_IOVAR_GET_AMPDU_BA_WINDOW_SIZE, + WHD_IOVAR_GET_AMPDU_MPDU, + WHD_IOVAR_GET_LISTEN_INTERVAL, /**< Get Listen Interval value */ + WHD_IOVAR_GET_MAC_ADDRESS, /**< Get mac address */ } whd_usr_iovar_get_list_t; /** * Enumeration of bus type */ -typedef enum { - WHD_BUS_SDIO = 0, - WHD_BUS_SPI, - WHD_BUS_M2M, - WHD_BUS_NO_DEFINE = 0xff, +typedef enum +{ + WHD_BUS_SDIO = 0, + WHD_BUS_SPI, + WHD_BUS_M2M, + WHD_BUS_NO_DEFINE = 0xff, } whd_bus_type_t; +/** + * Expand fw capabilities list to enumeration + */ +typedef enum +{ + WHD_FWCAP_SAE = 0, /**< Internal SAE */ + WHD_FWCAP_SAE_EXT = 1, /**< External SAE */ + WHD_FWCAP_OFFLOADS = 2, /**< Offload config */ + WHD_FWCAP_GCMP = 3, /**< GCMP */ +} whd_fwcap_id_t; + /****************************************************** * Type Definitions ******************************************************/ @@ -395,7 +476,7 @@ typedef struct whd_event_msg whd_event_header_t; */ typedef struct { - uint8_t octet[6]; /**< Unique 6-byte MAC address */ + uint8_t octet[6]; /**< Unique 6-byte MAC address */ } whd_mac_t; /** @@ -403,8 +484,8 @@ typedef struct */ typedef struct { - uint32_t count; - uint32_t element[1]; + uint32_t count; + uint32_t element[1]; } whd_list_t; /** @@ -412,8 +493,8 @@ typedef struct */ typedef struct { - uint8_t length; /**< SSID length */ - uint8_t value[SSID_NAME_SIZE]; /**< SSID name (AP name) */ + uint8_t length; /**< SSID length */ + uint8_t value[SSID_NAME_SIZE]; /**< SSID name (AP name) */ } whd_ssid_t; /**< @@ -439,256 +520,257 @@ typedef struct */ #ifdef IL_BIGENDIAN #define MK_CNTRY(a, b, \ - rev) (((unsigned char)(b)) + (((unsigned char)(a)) << 8) + \ - (((unsigned short)(rev)) << 16)) + rev) ( ( (unsigned char)(b) ) + ( ( (unsigned char)(a) ) << 8 ) + \ + ( ( (unsigned short)(rev) ) << 16 ) ) #else /* ifdef IL_BIGENDIAN */ #define MK_CNTRY(a, b, \ - rev) (((unsigned char)(a)) + (((unsigned char)(b)) << 8) + \ - (((unsigned short)(rev)) << 16)) + rev) ( ( (unsigned char)(a) ) + ( ( (unsigned char)(b) ) << 8 ) + \ + ( ( (unsigned short)(rev) ) << 16 ) ) #endif /* ifdef IL_BIGENDIAN */ /** @endcond */ /** * Enumerated list of country codes */ -typedef enum { - WHD_COUNTRY_AFGHANISTAN = MK_CNTRY('A', 'F', 0), /**< AF Afghanistan */ - WHD_COUNTRY_ALBANIA = MK_CNTRY('A', 'L', 0), /**< AL Albania */ - WHD_COUNTRY_ALGERIA = MK_CNTRY('D', 'Z', 0), /**< DZ Algeria */ - WHD_COUNTRY_AMERICAN_SAMOA = MK_CNTRY('A', 'S', 0), /**< AS American_Samoa */ - WHD_COUNTRY_ANGOLA = MK_CNTRY('A', 'O', 0), /**< AO Angola */ - WHD_COUNTRY_ANGUILLA = MK_CNTRY('A', 'I', 0), /**< AI Anguilla */ - WHD_COUNTRY_ANTIGUA_AND_BARBUDA = MK_CNTRY('A', 'G', 0), /**< AG Antigua_and_Barbuda */ - WHD_COUNTRY_ARGENTINA = MK_CNTRY('A', 'R', 0), /**< AR Argentina */ - WHD_COUNTRY_ARMENIA = MK_CNTRY('A', 'M', 0), /**< AM Armenia */ - WHD_COUNTRY_ARUBA = MK_CNTRY('A', 'W', 0), /**< AW Aruba */ - WHD_COUNTRY_AUSTRALIA = MK_CNTRY('A', 'U', 0), /**< AU Australia */ - WHD_COUNTRY_AUSTRIA = MK_CNTRY('A', 'T', 0), /**< AT Austria */ - WHD_COUNTRY_AZERBAIJAN = MK_CNTRY('A', 'Z', 0), /**< AZ Azerbaijan */ - WHD_COUNTRY_BAHAMAS = MK_CNTRY('B', 'S', 0), /**< BS Bahamas */ - WHD_COUNTRY_BAHRAIN = MK_CNTRY('B', 'H', 0), /**< BH Bahrain */ - WHD_COUNTRY_BAKER_ISLAND = MK_CNTRY('0', 'B', 0), /**< 0B Baker_Island */ - WHD_COUNTRY_BANGLADESH = MK_CNTRY('B', 'D', 0), /**< BD Bangladesh */ - WHD_COUNTRY_BARBADOS = MK_CNTRY('B', 'B', 0), /**< BB Barbados */ - WHD_COUNTRY_BELARUS = MK_CNTRY('B', 'Y', 0), /**< BY Belarus */ - WHD_COUNTRY_BELGIUM = MK_CNTRY('B', 'E', 0), /**< BE Belgium */ - WHD_COUNTRY_BELIZE = MK_CNTRY('B', 'Z', 0), /**< BZ Belize */ - WHD_COUNTRY_BENIN = MK_CNTRY('B', 'J', 0), /**< BJ Benin */ - WHD_COUNTRY_BERMUDA = MK_CNTRY('B', 'M', 0), /**< BM Bermuda */ - WHD_COUNTRY_BHUTAN = MK_CNTRY('B', 'T', 0), /**< BT Bhutan */ - WHD_COUNTRY_BOLIVIA = MK_CNTRY('B', 'O', 0), /**< BO Bolivia */ - WHD_COUNTRY_BOSNIA_AND_HERZEGOVINA = MK_CNTRY('B', 'A', 0), /**< BA Bosnia_and_Herzegovina */ - WHD_COUNTRY_BOTSWANA = MK_CNTRY('B', 'W', 0), /**< BW Botswana */ - WHD_COUNTRY_BRAZIL = MK_CNTRY('B', 'R', 0), /**< BR Brazil */ - WHD_COUNTRY_BRITISH_INDIAN_OCEAN_TERRITORY = MK_CNTRY('I', 'O', 0), /**< IO British_Indian_Ocean_Territory */ - WHD_COUNTRY_BRUNEI_DARUSSALAM = MK_CNTRY('B', 'N', 0), /**< BN Brunei_Darussalam */ - WHD_COUNTRY_BULGARIA = MK_CNTRY('B', 'G', 0), /**< BG Bulgaria */ - WHD_COUNTRY_BURKINA_FASO = MK_CNTRY('B', 'F', 0), /**< BF Burkina_Faso */ - WHD_COUNTRY_BURUNDI = MK_CNTRY('B', 'I', 0), /**< BI Burundi */ - WHD_COUNTRY_CAMBODIA = MK_CNTRY('K', 'H', 0), /**< KH Cambodia */ - WHD_COUNTRY_CAMEROON = MK_CNTRY('C', 'M', 0), /**< CM Cameroon */ - WHD_COUNTRY_CANADA = MK_CNTRY('C', 'A', 0), /**< CA Canada */ - WHD_COUNTRY_CANADA_REV950 = MK_CNTRY('C', 'A', 950), /**< CA Canada Revision 950 */ - WHD_COUNTRY_CAPE_VERDE = MK_CNTRY('C', 'V', 0), /**< CV Cape_Verde */ - WHD_COUNTRY_CAYMAN_ISLANDS = MK_CNTRY('K', 'Y', 0), /**< KY Cayman_Islands */ - WHD_COUNTRY_CENTRAL_AFRICAN_REPUBLIC = MK_CNTRY('C', 'F', 0), /**< CF Central_African_Republic */ - WHD_COUNTRY_CHAD = MK_CNTRY('T', 'D', 0), /**< TD Chad */ - WHD_COUNTRY_CHILE = MK_CNTRY('C', 'L', 0), /**< CL Chile */ - WHD_COUNTRY_CHINA = MK_CNTRY('C', 'N', 0), /**< CN China */ - WHD_COUNTRY_CHRISTMAS_ISLAND = MK_CNTRY('C', 'X', 0), /**< CX Christmas_Island */ - WHD_COUNTRY_COLOMBIA = MK_CNTRY('C', 'O', 0), /**< CO Colombia */ - WHD_COUNTRY_COMOROS = MK_CNTRY('K', 'M', 0), /**< KM Comoros */ - WHD_COUNTRY_CONGO = MK_CNTRY('C', 'G', 0), /**< CG Congo */ - WHD_COUNTRY_CONGO_THE_DEMOCRATIC_REPUBLIC_OF_THE = MK_CNTRY('C', 'D', 0), /**< CD Congo,_The_Democratic_Republic_Of_The */ - WHD_COUNTRY_COSTA_RICA = MK_CNTRY('C', 'R', 0), /**< CR Costa_Rica */ - WHD_COUNTRY_COTE_DIVOIRE = MK_CNTRY('C', 'I', 0), /**< CI Cote_D'ivoire */ - WHD_COUNTRY_CROATIA = MK_CNTRY('H', 'R', 0), /**< HR Croatia */ - WHD_COUNTRY_CUBA = MK_CNTRY('C', 'U', 0), /**< CU Cuba */ - WHD_COUNTRY_CYPRUS = MK_CNTRY('C', 'Y', 0), /**< CY Cyprus */ - WHD_COUNTRY_CZECH_REPUBLIC = MK_CNTRY('C', 'Z', 0), /**< CZ Czech_Republic */ - WHD_COUNTRY_DENMARK = MK_CNTRY('D', 'K', 0), /**< DK Denmark */ - WHD_COUNTRY_DJIBOUTI = MK_CNTRY('D', 'J', 0), /**< DJ Djibouti */ - WHD_COUNTRY_DOMINICA = MK_CNTRY('D', 'M', 0), /**< DM Dominica */ - WHD_COUNTRY_DOMINICAN_REPUBLIC = MK_CNTRY('D', 'O', 0), /**< DO Dominican_Republic */ - WHD_COUNTRY_DOWN_UNDER = MK_CNTRY('A', 'U', 0), /**< AU G'Day mate! */ - WHD_COUNTRY_ECUADOR = MK_CNTRY('E', 'C', 0), /**< EC Ecuador */ - WHD_COUNTRY_EGYPT = MK_CNTRY('E', 'G', 0), /**< EG Egypt */ - WHD_COUNTRY_EL_SALVADOR = MK_CNTRY('S', 'V', 0), /**< SV El_Salvador */ - WHD_COUNTRY_EQUATORIAL_GUINEA = MK_CNTRY('G', 'Q', 0), /**< GQ Equatorial_Guinea */ - WHD_COUNTRY_ERITREA = MK_CNTRY('E', 'R', 0), /**< ER Eritrea */ - WHD_COUNTRY_ESTONIA = MK_CNTRY('E', 'E', 0), /**< EE Estonia */ - WHD_COUNTRY_ETHIOPIA = MK_CNTRY('E', 'T', 0), /**< ET Ethiopia */ - WHD_COUNTRY_FALKLAND_ISLANDS_MALVINAS = MK_CNTRY('F', 'K', 0), /**< FK Falkland_Islands_(Malvinas) */ - WHD_COUNTRY_FAROE_ISLANDS = MK_CNTRY('F', 'O', 0), /**< FO Faroe_Islands */ - WHD_COUNTRY_FIJI = MK_CNTRY('F', 'J', 0), /**< FJ Fiji */ - WHD_COUNTRY_FINLAND = MK_CNTRY('F', 'I', 0), /**< FI Finland */ - WHD_COUNTRY_FRANCE = MK_CNTRY('F', 'R', 0), /**< FR France */ - WHD_COUNTRY_FRENCH_GUINA = MK_CNTRY('G', 'F', 0), /**< GF French_Guina */ - WHD_COUNTRY_FRENCH_POLYNESIA = MK_CNTRY('P', 'F', 0), /**< PF French_Polynesia */ - WHD_COUNTRY_FRENCH_SOUTHERN_TERRITORIES = MK_CNTRY('T', 'F', 0), /**< TF French_Southern_Territories */ - WHD_COUNTRY_GABON = MK_CNTRY('G', 'A', 0), /**< GA Gabon */ - WHD_COUNTRY_GAMBIA = MK_CNTRY('G', 'M', 0), /**< GM Gambia */ - WHD_COUNTRY_GEORGIA = MK_CNTRY('G', 'E', 0), /**< GE Georgia */ - WHD_COUNTRY_GERMANY = MK_CNTRY('D', 'E', 0), /**< DE Germany */ - WHD_COUNTRY_EUROPEAN_WIDE_REV895 = MK_CNTRY('E', '0', 895), /**< E0 European_Wide Revision 895 */ - WHD_COUNTRY_GHANA = MK_CNTRY('G', 'H', 0), /**< GH Ghana */ - WHD_COUNTRY_GIBRALTAR = MK_CNTRY('G', 'I', 0), /**< GI Gibraltar */ - WHD_COUNTRY_GREECE = MK_CNTRY('G', 'R', 0), /**< GR Greece */ - WHD_COUNTRY_GRENADA = MK_CNTRY('G', 'D', 0), /**< GD Grenada */ - WHD_COUNTRY_GUADELOUPE = MK_CNTRY('G', 'P', 0), /**< GP Guadeloupe */ - WHD_COUNTRY_GUAM = MK_CNTRY('G', 'U', 0), /**< GU Guam */ - WHD_COUNTRY_GUATEMALA = MK_CNTRY('G', 'T', 0), /**< GT Guatemala */ - WHD_COUNTRY_GUERNSEY = MK_CNTRY('G', 'G', 0), /**< GG Guernsey */ - WHD_COUNTRY_GUINEA = MK_CNTRY('G', 'N', 0), /**< GN Guinea */ - WHD_COUNTRY_GUINEA_BISSAU = MK_CNTRY('G', 'W', 0), /**< GW Guinea-bissau */ - WHD_COUNTRY_GUYANA = MK_CNTRY('G', 'Y', 0), /**< GY Guyana */ - WHD_COUNTRY_HAITI = MK_CNTRY('H', 'T', 0), /**< HT Haiti */ - WHD_COUNTRY_HOLY_SEE_VATICAN_CITY_STATE = MK_CNTRY('V', 'A', 0), /**< VA Holy_See_(Vatican_City_State) */ - WHD_COUNTRY_HONDURAS = MK_CNTRY('H', 'N', 0), /**< HN Honduras */ - WHD_COUNTRY_HONG_KONG = MK_CNTRY('H', 'K', 0), /**< HK Hong_Kong */ - WHD_COUNTRY_HUNGARY = MK_CNTRY('H', 'U', 0), /**< HU Hungary */ - WHD_COUNTRY_ICELAND = MK_CNTRY('I', 'S', 0), /**< IS Iceland */ - WHD_COUNTRY_INDIA = MK_CNTRY('I', 'N', 0), /**< IN India */ - WHD_COUNTRY_INDONESIA = MK_CNTRY('I', 'D', 0), /**< ID Indonesia */ - WHD_COUNTRY_IRAN_ISLAMIC_REPUBLIC_OF = MK_CNTRY('I', 'R', 0), /**< IR Iran,_Islamic_Republic_Of */ - WHD_COUNTRY_IRAQ = MK_CNTRY('I', 'Q', 0), /**< IQ Iraq */ - WHD_COUNTRY_IRELAND = MK_CNTRY('I', 'E', 0), /**< IE Ireland */ - WHD_COUNTRY_ISRAEL = MK_CNTRY('I', 'L', 0), /**< IL Israel */ - WHD_COUNTRY_ITALY = MK_CNTRY('I', 'T', 0), /**< IT Italy */ - WHD_COUNTRY_JAMAICA = MK_CNTRY('J', 'M', 0), /**< JM Jamaica */ - WHD_COUNTRY_JAPAN = MK_CNTRY('J', 'P', 0), /**< JP Japan */ - WHD_COUNTRY_JERSEY = MK_CNTRY('J', 'E', 0), /**< JE Jersey */ - WHD_COUNTRY_JORDAN = MK_CNTRY('J', 'O', 0), /**< JO Jordan */ - WHD_COUNTRY_KAZAKHSTAN = MK_CNTRY('K', 'Z', 0), /**< KZ Kazakhstan */ - WHD_COUNTRY_KENYA = MK_CNTRY('K', 'E', 0), /**< KE Kenya */ - WHD_COUNTRY_KIRIBATI = MK_CNTRY('K', 'I', 0), /**< KI Kiribati */ - WHD_COUNTRY_KOREA_REPUBLIC_OF = MK_CNTRY('K', 'R', 1), /**< KR Korea,_Republic_Of */ - WHD_COUNTRY_KOSOVO = MK_CNTRY('0', 'A', 0), /**< 0A Kosovo */ - WHD_COUNTRY_KUWAIT = MK_CNTRY('K', 'W', 0), /**< KW Kuwait */ - WHD_COUNTRY_KYRGYZSTAN = MK_CNTRY('K', 'G', 0), /**< KG Kyrgyzstan */ - WHD_COUNTRY_LAO_PEOPLES_DEMOCRATIC_REPUBIC = MK_CNTRY('L', 'A', 0), /**< LA Lao_People's_Democratic_Repubic */ - WHD_COUNTRY_LATVIA = MK_CNTRY('L', 'V', 0), /**< LV Latvia */ - WHD_COUNTRY_LEBANON = MK_CNTRY('L', 'B', 0), /**< LB Lebanon */ - WHD_COUNTRY_LESOTHO = MK_CNTRY('L', 'S', 0), /**< LS Lesotho */ - WHD_COUNTRY_LIBERIA = MK_CNTRY('L', 'R', 0), /**< LR Liberia */ - WHD_COUNTRY_LIBYAN_ARAB_JAMAHIRIYA = MK_CNTRY('L', 'Y', 0), /**< LY Libyan_Arab_Jamahiriya */ - WHD_COUNTRY_LIECHTENSTEIN = MK_CNTRY('L', 'I', 0), /**< LI Liechtenstein */ - WHD_COUNTRY_LITHUANIA = MK_CNTRY('L', 'T', 0), /**< LT Lithuania */ - WHD_COUNTRY_LUXEMBOURG = MK_CNTRY('L', 'U', 0), /**< LU Luxembourg */ - WHD_COUNTRY_MACAO = MK_CNTRY('M', 'O', 0), /**< MO Macao */ - WHD_COUNTRY_MACEDONIA_FORMER_YUGOSLAV_REPUBLIC_OF = MK_CNTRY('M', 'K', 0), /**< MK Macedonia,_Former_Yugoslav_Republic_Of */ - WHD_COUNTRY_MADAGASCAR = MK_CNTRY('M', 'G', 0), /**< MG Madagascar */ - WHD_COUNTRY_MALAWI = MK_CNTRY('M', 'W', 0), /**< MW Malawi */ - WHD_COUNTRY_MALAYSIA = MK_CNTRY('M', 'Y', 0), /**< MY Malaysia */ - WHD_COUNTRY_MALDIVES = MK_CNTRY('M', 'V', 0), /**< MV Maldives */ - WHD_COUNTRY_MALI = MK_CNTRY('M', 'L', 0), /**< ML Mali */ - WHD_COUNTRY_MALTA = MK_CNTRY('M', 'T', 0), /**< MT Malta */ - WHD_COUNTRY_MAN_ISLE_OF = MK_CNTRY('I', 'M', 0), /**< IM Man,_Isle_Of */ - WHD_COUNTRY_MARTINIQUE = MK_CNTRY('M', 'Q', 0), /**< MQ Martinique */ - WHD_COUNTRY_MAURITANIA = MK_CNTRY('M', 'R', 0), /**< MR Mauritania */ - WHD_COUNTRY_MAURITIUS = MK_CNTRY('M', 'U', 0), /**< MU Mauritius */ - WHD_COUNTRY_MAYOTTE = MK_CNTRY('Y', 'T', 0), /**< YT Mayotte */ - WHD_COUNTRY_MEXICO = MK_CNTRY('M', 'X', 0), /**< MX Mexico */ - WHD_COUNTRY_MICRONESIA_FEDERATED_STATES_OF = MK_CNTRY('F', 'M', 0), /**< FM Micronesia,_Federated_States_Of */ - WHD_COUNTRY_MOLDOVA_REPUBLIC_OF = MK_CNTRY('M', 'D', 0), /**< MD Moldova,_Republic_Of */ - WHD_COUNTRY_MONACO = MK_CNTRY('M', 'C', 0), /**< MC Monaco */ - WHD_COUNTRY_MONGOLIA = MK_CNTRY('M', 'N', 0), /**< MN Mongolia */ - WHD_COUNTRY_MONTENEGRO = MK_CNTRY('M', 'E', 0), /**< ME Montenegro */ - WHD_COUNTRY_MONTSERRAT = MK_CNTRY('M', 'S', 0), /**< MS Montserrat */ - WHD_COUNTRY_MOROCCO = MK_CNTRY('M', 'A', 0), /**< MA Morocco */ - WHD_COUNTRY_MOZAMBIQUE = MK_CNTRY('M', 'Z', 0), /**< MZ Mozambique */ - WHD_COUNTRY_MYANMAR = MK_CNTRY('M', 'M', 0), /**< MM Myanmar */ - WHD_COUNTRY_NAMIBIA = MK_CNTRY('N', 'A', 0), /**< NA Namibia */ - WHD_COUNTRY_NAURU = MK_CNTRY('N', 'R', 0), /**< NR Nauru */ - WHD_COUNTRY_NEPAL = MK_CNTRY('N', 'P', 0), /**< NP Nepal */ - WHD_COUNTRY_NETHERLANDS = MK_CNTRY('N', 'L', 0), /**< NL Netherlands */ - WHD_COUNTRY_NETHERLANDS_ANTILLES = MK_CNTRY('A', 'N', 0), /**< AN Netherlands_Antilles */ - WHD_COUNTRY_NEW_CALEDONIA = MK_CNTRY('N', 'C', 0), /**< NC New_Caledonia */ - WHD_COUNTRY_NEW_ZEALAND = MK_CNTRY('N', 'Z', 0), /**< NZ New_Zealand */ - WHD_COUNTRY_NICARAGUA = MK_CNTRY('N', 'I', 0), /**< NI Nicaragua */ - WHD_COUNTRY_NIGER = MK_CNTRY('N', 'E', 0), /**< NE Niger */ - WHD_COUNTRY_NIGERIA = MK_CNTRY('N', 'G', 0), /**< NG Nigeria */ - WHD_COUNTRY_NORFOLK_ISLAND = MK_CNTRY('N', 'F', 0), /**< NF Norfolk_Island */ - WHD_COUNTRY_NORTHERN_MARIANA_ISLANDS = MK_CNTRY('M', 'P', 0), /**< MP Northern_Mariana_Islands */ - WHD_COUNTRY_NORWAY = MK_CNTRY('N', 'O', 0), /**< NO Norway */ - WHD_COUNTRY_OMAN = MK_CNTRY('O', 'M', 0), /**< OM Oman */ - WHD_COUNTRY_PAKISTAN = MK_CNTRY('P', 'K', 0), /**< PK Pakistan */ - WHD_COUNTRY_PALAU = MK_CNTRY('P', 'W', 0), /**< PW Palau */ - WHD_COUNTRY_PANAMA = MK_CNTRY('P', 'A', 0), /**< PA Panama */ - WHD_COUNTRY_PAPUA_NEW_GUINEA = MK_CNTRY('P', 'G', 0), /**< PG Papua_New_Guinea */ - WHD_COUNTRY_PARAGUAY = MK_CNTRY('P', 'Y', 0), /**< PY Paraguay */ - WHD_COUNTRY_PERU = MK_CNTRY('P', 'E', 0), /**< PE Peru */ - WHD_COUNTRY_PHILIPPINES = MK_CNTRY('P', 'H', 0), /**< PH Philippines */ - WHD_COUNTRY_POLAND = MK_CNTRY('P', 'L', 0), /**< PL Poland */ - WHD_COUNTRY_PORTUGAL = MK_CNTRY('P', 'T', 0), /**< PT Portugal */ - WHD_COUNTRY_PUETO_RICO = MK_CNTRY('P', 'R', 0), /**< PR Pueto_Rico */ - WHD_COUNTRY_QATAR = MK_CNTRY('Q', 'A', 0), /**< QA Qatar */ - WHD_COUNTRY_REUNION = MK_CNTRY('R', 'E', 0), /**< RE Reunion */ - WHD_COUNTRY_ROMANIA = MK_CNTRY('R', 'O', 0), /**< RO Romania */ - WHD_COUNTRY_RUSSIAN_FEDERATION = MK_CNTRY('R', 'U', 0), /**< RU Russian_Federation */ - WHD_COUNTRY_RWANDA = MK_CNTRY('R', 'W', 0), /**< RW Rwanda */ - WHD_COUNTRY_SAINT_KITTS_AND_NEVIS = MK_CNTRY('K', 'N', 0), /**< KN Saint_Kitts_and_Nevis */ - WHD_COUNTRY_SAINT_LUCIA = MK_CNTRY('L', 'C', 0), /**< LC Saint_Lucia */ - WHD_COUNTRY_SAINT_PIERRE_AND_MIQUELON = MK_CNTRY('P', 'M', 0), /**< PM Saint_Pierre_and_Miquelon */ - WHD_COUNTRY_SAINT_VINCENT_AND_THE_GRENADINES = MK_CNTRY('V', 'C', 0), /**< VC Saint_Vincent_and_The_Grenadines */ - WHD_COUNTRY_SAMOA = MK_CNTRY('W', 'S', 0), /**< WS Samoa */ - WHD_COUNTRY_SANIT_MARTIN_SINT_MARTEEN = MK_CNTRY('M', 'F', 0), /**< MF Sanit_Martin_/_Sint_Marteen */ - WHD_COUNTRY_SAO_TOME_AND_PRINCIPE = MK_CNTRY('S', 'T', 0), /**< ST Sao_Tome_and_Principe */ - WHD_COUNTRY_SAUDI_ARABIA = MK_CNTRY('S', 'A', 0), /**< SA Saudi_Arabia */ - WHD_COUNTRY_SENEGAL = MK_CNTRY('S', 'N', 0), /**< SN Senegal */ - WHD_COUNTRY_SERBIA = MK_CNTRY('R', 'S', 0), /**< RS Serbia */ - WHD_COUNTRY_SEYCHELLES = MK_CNTRY('S', 'C', 0), /**< SC Seychelles */ - WHD_COUNTRY_SIERRA_LEONE = MK_CNTRY('S', 'L', 0), /**< SL Sierra_Leone */ - WHD_COUNTRY_SINGAPORE = MK_CNTRY('S', 'G', 0), /**< SG Singapore */ - WHD_COUNTRY_SLOVAKIA = MK_CNTRY('S', 'K', 0), /**< SK Slovakia */ - WHD_COUNTRY_SLOVENIA = MK_CNTRY('S', 'I', 0), /**< SI Slovenia */ - WHD_COUNTRY_SOLOMON_ISLANDS = MK_CNTRY('S', 'B', 0), /**< SB Solomon_Islands */ - WHD_COUNTRY_SOMALIA = MK_CNTRY('S', 'O', 0), /**< SO Somalia */ - WHD_COUNTRY_SOUTH_AFRICA = MK_CNTRY('Z', 'A', 0), /**< ZA South_Africa */ - WHD_COUNTRY_SPAIN = MK_CNTRY('E', 'S', 0), /**< ES Spain */ - WHD_COUNTRY_SRI_LANKA = MK_CNTRY('L', 'K', 0), /**< LK Sri_Lanka */ - WHD_COUNTRY_SURINAME = MK_CNTRY('S', 'R', 0), /**< SR Suriname */ - WHD_COUNTRY_SWAZILAND = MK_CNTRY('S', 'Z', 0), /**< SZ Swaziland */ - WHD_COUNTRY_SWEDEN = MK_CNTRY('S', 'E', 0), /**< SE Sweden */ - WHD_COUNTRY_SWITZERLAND = MK_CNTRY('C', 'H', 0), /**< CH Switzerland */ - WHD_COUNTRY_SYRIAN_ARAB_REPUBLIC = MK_CNTRY('S', 'Y', 0), /**< SY Syrian_Arab_Republic */ - WHD_COUNTRY_TAIWAN_PROVINCE_OF_CHINA = MK_CNTRY('T', 'W', 0), /**< TW Taiwan,_Province_Of_China */ - WHD_COUNTRY_TAJIKISTAN = MK_CNTRY('T', 'J', 0), /**< TJ Tajikistan */ - WHD_COUNTRY_TANZANIA_UNITED_REPUBLIC_OF = MK_CNTRY('T', 'Z', 0), /**< TZ Tanzania,_United_Republic_Of */ - WHD_COUNTRY_THAILAND = MK_CNTRY('T', 'H', 0), /**< TH Thailand */ - WHD_COUNTRY_TOGO = MK_CNTRY('T', 'G', 0), /**< TG Togo */ - WHD_COUNTRY_TONGA = MK_CNTRY('T', 'O', 0), /**< TO Tonga */ - WHD_COUNTRY_TRINIDAD_AND_TOBAGO = MK_CNTRY('T', 'T', 0), /**< TT Trinidad_and_Tobago */ - WHD_COUNTRY_TUNISIA = MK_CNTRY('T', 'N', 0), /**< TN Tunisia */ - WHD_COUNTRY_TURKEY = MK_CNTRY('T', 'R', 0), /**< TR Turkey */ - WHD_COUNTRY_TURKMENISTAN = MK_CNTRY('T', 'M', 0), /**< TM Turkmenistan */ - WHD_COUNTRY_TURKS_AND_CAICOS_ISLANDS = MK_CNTRY('T', 'C', 0), /**< TC Turks_and_Caicos_Islands */ - WHD_COUNTRY_TUVALU = MK_CNTRY('T', 'V', 0), /**< TV Tuvalu */ - WHD_COUNTRY_UGANDA = MK_CNTRY('U', 'G', 0), /**< UG Uganda */ - WHD_COUNTRY_UKRAINE = MK_CNTRY('U', 'A', 0), /**< UA Ukraine */ - WHD_COUNTRY_UNITED_ARAB_EMIRATES = MK_CNTRY('A', 'E', 0), /**< AE United_Arab_Emirates */ - WHD_COUNTRY_UNITED_KINGDOM = MK_CNTRY('G', 'B', 0), /**< GB United_Kingdom */ - WHD_COUNTRY_UNITED_STATES = MK_CNTRY('U', 'S', 0), /**< US United_States */ - WHD_COUNTRY_UNITED_STATES_REV4 = MK_CNTRY('U', 'S', 4), /**< US United_States Revision 4 */ - WHD_COUNTRY_UNITED_STATES_REV931 = MK_CNTRY('Q', '1', 931), /**< Q1 United_States Revision 931 */ - WHD_COUNTRY_UNITED_STATES_NO_DFS = MK_CNTRY('Q', '2', 0), /**< Q2 United_States_(No_DFS) */ - WHD_COUNTRY_UNITED_STATES_MINOR_OUTLYING_ISLANDS = MK_CNTRY('U', 'M', 0), /**< UM United_States_Minor_Outlying_Islands */ - WHD_COUNTRY_URUGUAY = MK_CNTRY('U', 'Y', 0), /**< UY Uruguay */ - WHD_COUNTRY_UZBEKISTAN = MK_CNTRY('U', 'Z', 0), /**< UZ Uzbekistan */ - WHD_COUNTRY_VANUATU = MK_CNTRY('V', 'U', 0), /**< VU Vanuatu */ - WHD_COUNTRY_VENEZUELA = MK_CNTRY('V', 'E', 0), /**< VE Venezuela */ - WHD_COUNTRY_VIET_NAM = MK_CNTRY('V', 'N', 0), /**< VN Viet_Nam */ - WHD_COUNTRY_VIRGIN_ISLANDS_BRITISH = MK_CNTRY('V', 'G', 0), /**< VG Virgin_Islands,_British */ - WHD_COUNTRY_VIRGIN_ISLANDS_US = MK_CNTRY('V', 'I', 0), /**< VI Virgin_Islands,_U.S. */ - WHD_COUNTRY_WALLIS_AND_FUTUNA = MK_CNTRY('W', 'F', 0), /**< WF Wallis_and_Futuna */ - WHD_COUNTRY_WEST_BANK = MK_CNTRY('0', 'C', 0), /**< 0C West_Bank */ - WHD_COUNTRY_WESTERN_SAHARA = MK_CNTRY('E', 'H', 0), /**< EH Western_Sahara */ - WHD_COUNTRY_WORLD_WIDE_XV_REV983 = MK_CNTRY('X', 'V', 983), /**< Worldwide Locale Revision 983 */ - WHD_COUNTRY_WORLD_WIDE_XX = MK_CNTRY('X', 'X', 0), /**< Worldwide Locale (passive Ch12-14) */ - WHD_COUNTRY_WORLD_WIDE_XX_REV17 = MK_CNTRY('X', 'X', 17), /**< Worldwide Locale (passive Ch12-14) Revision 17 */ - WHD_COUNTRY_YEMEN = MK_CNTRY('Y', 'E', 0), /**< YE Yemen */ - WHD_COUNTRY_ZAMBIA = MK_CNTRY('Z', 'M', 0), /**< ZM Zambia */ - WHD_COUNTRY_ZIMBABWE = MK_CNTRY('Z', 'W', 0), /**< ZW Zimbabwe */ +typedef enum +{ + WHD_COUNTRY_AFGHANISTAN = MK_CNTRY('A', 'F', 0), /**< AF Afghanistan */ + WHD_COUNTRY_ALBANIA = MK_CNTRY('A', 'L', 0), /**< AL Albania */ + WHD_COUNTRY_ALGERIA = MK_CNTRY('D', 'Z', 0), /**< DZ Algeria */ + WHD_COUNTRY_AMERICAN_SAMOA = MK_CNTRY('A', 'S', 0), /**< AS American_Samoa */ + WHD_COUNTRY_ANGOLA = MK_CNTRY('A', 'O', 0), /**< AO Angola */ + WHD_COUNTRY_ANGUILLA = MK_CNTRY('A', 'I', 0), /**< AI Anguilla */ + WHD_COUNTRY_ANTIGUA_AND_BARBUDA = MK_CNTRY('A', 'G', 0), /**< AG Antigua_and_Barbuda */ + WHD_COUNTRY_ARGENTINA = MK_CNTRY('A', 'R', 0), /**< AR Argentina */ + WHD_COUNTRY_ARMENIA = MK_CNTRY('A', 'M', 0), /**< AM Armenia */ + WHD_COUNTRY_ARUBA = MK_CNTRY('A', 'W', 0), /**< AW Aruba */ + WHD_COUNTRY_AUSTRALIA = MK_CNTRY('A', 'U', 0), /**< AU Australia */ + WHD_COUNTRY_AUSTRIA = MK_CNTRY('A', 'T', 0), /**< AT Austria */ + WHD_COUNTRY_AZERBAIJAN = MK_CNTRY('A', 'Z', 0), /**< AZ Azerbaijan */ + WHD_COUNTRY_BAHAMAS = MK_CNTRY('B', 'S', 0), /**< BS Bahamas */ + WHD_COUNTRY_BAHRAIN = MK_CNTRY('B', 'H', 0), /**< BH Bahrain */ + WHD_COUNTRY_BAKER_ISLAND = MK_CNTRY('0', 'B', 0), /**< 0B Baker_Island */ + WHD_COUNTRY_BANGLADESH = MK_CNTRY('B', 'D', 0), /**< BD Bangladesh */ + WHD_COUNTRY_BARBADOS = MK_CNTRY('B', 'B', 0), /**< BB Barbados */ + WHD_COUNTRY_BELARUS = MK_CNTRY('B', 'Y', 0), /**< BY Belarus */ + WHD_COUNTRY_BELGIUM = MK_CNTRY('B', 'E', 0), /**< BE Belgium */ + WHD_COUNTRY_BELIZE = MK_CNTRY('B', 'Z', 0), /**< BZ Belize */ + WHD_COUNTRY_BENIN = MK_CNTRY('B', 'J', 0), /**< BJ Benin */ + WHD_COUNTRY_BERMUDA = MK_CNTRY('B', 'M', 0), /**< BM Bermuda */ + WHD_COUNTRY_BHUTAN = MK_CNTRY('B', 'T', 0), /**< BT Bhutan */ + WHD_COUNTRY_BOLIVIA = MK_CNTRY('B', 'O', 0), /**< BO Bolivia */ + WHD_COUNTRY_BOSNIA_AND_HERZEGOVINA = MK_CNTRY('B', 'A', 0), /**< BA Bosnia_and_Herzegovina */ + WHD_COUNTRY_BOTSWANA = MK_CNTRY('B', 'W', 0), /**< BW Botswana */ + WHD_COUNTRY_BRAZIL = MK_CNTRY('B', 'R', 0), /**< BR Brazil */ + WHD_COUNTRY_BRITISH_INDIAN_OCEAN_TERRITORY = MK_CNTRY('I', 'O', 0), /**< IO British_Indian_Ocean_Territory */ + WHD_COUNTRY_BRUNEI_DARUSSALAM = MK_CNTRY('B', 'N', 0), /**< BN Brunei_Darussalam */ + WHD_COUNTRY_BULGARIA = MK_CNTRY('B', 'G', 0), /**< BG Bulgaria */ + WHD_COUNTRY_BURKINA_FASO = MK_CNTRY('B', 'F', 0), /**< BF Burkina_Faso */ + WHD_COUNTRY_BURUNDI = MK_CNTRY('B', 'I', 0), /**< BI Burundi */ + WHD_COUNTRY_CAMBODIA = MK_CNTRY('K', 'H', 0), /**< KH Cambodia */ + WHD_COUNTRY_CAMEROON = MK_CNTRY('C', 'M', 0), /**< CM Cameroon */ + WHD_COUNTRY_CANADA = MK_CNTRY('C', 'A', 0), /**< CA Canada */ + WHD_COUNTRY_CANADA_REV950 = MK_CNTRY('C', 'A', 950), /**< CA Canada Revision 950 */ + WHD_COUNTRY_CAPE_VERDE = MK_CNTRY('C', 'V', 0), /**< CV Cape_Verde */ + WHD_COUNTRY_CAYMAN_ISLANDS = MK_CNTRY('K', 'Y', 0), /**< KY Cayman_Islands */ + WHD_COUNTRY_CENTRAL_AFRICAN_REPUBLIC = MK_CNTRY('C', 'F', 0), /**< CF Central_African_Republic */ + WHD_COUNTRY_CHAD = MK_CNTRY('T', 'D', 0), /**< TD Chad */ + WHD_COUNTRY_CHILE = MK_CNTRY('C', 'L', 0), /**< CL Chile */ + WHD_COUNTRY_CHINA = MK_CNTRY('C', 'N', 0), /**< CN China */ + WHD_COUNTRY_CHRISTMAS_ISLAND = MK_CNTRY('C', 'X', 0), /**< CX Christmas_Island */ + WHD_COUNTRY_COLOMBIA = MK_CNTRY('C', 'O', 0), /**< CO Colombia */ + WHD_COUNTRY_COMOROS = MK_CNTRY('K', 'M', 0), /**< KM Comoros */ + WHD_COUNTRY_CONGO = MK_CNTRY('C', 'G', 0), /**< CG Congo */ + WHD_COUNTRY_CONGO_THE_DEMOCRATIC_REPUBLIC_OF_THE = MK_CNTRY('C', 'D', 0), /**< CD Congo,_The_Democratic_Republic_Of_The */ + WHD_COUNTRY_COSTA_RICA = MK_CNTRY('C', 'R', 0), /**< CR Costa_Rica */ + WHD_COUNTRY_COTE_DIVOIRE = MK_CNTRY('C', 'I', 0), /**< CI Cote_D'ivoire */ + WHD_COUNTRY_CROATIA = MK_CNTRY('H', 'R', 0), /**< HR Croatia */ + WHD_COUNTRY_CUBA = MK_CNTRY('C', 'U', 0), /**< CU Cuba */ + WHD_COUNTRY_CYPRUS = MK_CNTRY('C', 'Y', 0), /**< CY Cyprus */ + WHD_COUNTRY_CZECH_REPUBLIC = MK_CNTRY('C', 'Z', 0), /**< CZ Czech_Republic */ + WHD_COUNTRY_DENMARK = MK_CNTRY('D', 'K', 0), /**< DK Denmark */ + WHD_COUNTRY_DJIBOUTI = MK_CNTRY('D', 'J', 0), /**< DJ Djibouti */ + WHD_COUNTRY_DOMINICA = MK_CNTRY('D', 'M', 0), /**< DM Dominica */ + WHD_COUNTRY_DOMINICAN_REPUBLIC = MK_CNTRY('D', 'O', 0), /**< DO Dominican_Republic */ + WHD_COUNTRY_DOWN_UNDER = MK_CNTRY('A', 'U', 0), /**< AU G'Day mate! */ + WHD_COUNTRY_ECUADOR = MK_CNTRY('E', 'C', 0), /**< EC Ecuador */ + WHD_COUNTRY_EGYPT = MK_CNTRY('E', 'G', 0), /**< EG Egypt */ + WHD_COUNTRY_EL_SALVADOR = MK_CNTRY('S', 'V', 0), /**< SV El_Salvador */ + WHD_COUNTRY_EQUATORIAL_GUINEA = MK_CNTRY('G', 'Q', 0), /**< GQ Equatorial_Guinea */ + WHD_COUNTRY_ERITREA = MK_CNTRY('E', 'R', 0), /**< ER Eritrea */ + WHD_COUNTRY_ESTONIA = MK_CNTRY('E', 'E', 0), /**< EE Estonia */ + WHD_COUNTRY_ETHIOPIA = MK_CNTRY('E', 'T', 0), /**< ET Ethiopia */ + WHD_COUNTRY_FALKLAND_ISLANDS_MALVINAS = MK_CNTRY('F', 'K', 0), /**< FK Falkland_Islands_(Malvinas) */ + WHD_COUNTRY_FAROE_ISLANDS = MK_CNTRY('F', 'O', 0), /**< FO Faroe_Islands */ + WHD_COUNTRY_FIJI = MK_CNTRY('F', 'J', 0), /**< FJ Fiji */ + WHD_COUNTRY_FINLAND = MK_CNTRY('F', 'I', 0), /**< FI Finland */ + WHD_COUNTRY_FRANCE = MK_CNTRY('F', 'R', 0), /**< FR France */ + WHD_COUNTRY_FRENCH_GUINA = MK_CNTRY('G', 'F', 0), /**< GF French_Guina */ + WHD_COUNTRY_FRENCH_POLYNESIA = MK_CNTRY('P', 'F', 0), /**< PF French_Polynesia */ + WHD_COUNTRY_FRENCH_SOUTHERN_TERRITORIES = MK_CNTRY('T', 'F', 0), /**< TF French_Southern_Territories */ + WHD_COUNTRY_GABON = MK_CNTRY('G', 'A', 0), /**< GA Gabon */ + WHD_COUNTRY_GAMBIA = MK_CNTRY('G', 'M', 0), /**< GM Gambia */ + WHD_COUNTRY_GEORGIA = MK_CNTRY('G', 'E', 0), /**< GE Georgia */ + WHD_COUNTRY_GERMANY = MK_CNTRY('D', 'E', 0), /**< DE Germany */ + WHD_COUNTRY_EUROPEAN_WIDE_REV895 = MK_CNTRY('E', '0', 895), /**< E0 European_Wide Revision 895 */ + WHD_COUNTRY_GHANA = MK_CNTRY('G', 'H', 0), /**< GH Ghana */ + WHD_COUNTRY_GIBRALTAR = MK_CNTRY('G', 'I', 0), /**< GI Gibraltar */ + WHD_COUNTRY_GREECE = MK_CNTRY('G', 'R', 0), /**< GR Greece */ + WHD_COUNTRY_GRENADA = MK_CNTRY('G', 'D', 0), /**< GD Grenada */ + WHD_COUNTRY_GUADELOUPE = MK_CNTRY('G', 'P', 0), /**< GP Guadeloupe */ + WHD_COUNTRY_GUAM = MK_CNTRY('G', 'U', 0), /**< GU Guam */ + WHD_COUNTRY_GUATEMALA = MK_CNTRY('G', 'T', 0), /**< GT Guatemala */ + WHD_COUNTRY_GUERNSEY = MK_CNTRY('G', 'G', 0), /**< GG Guernsey */ + WHD_COUNTRY_GUINEA = MK_CNTRY('G', 'N', 0), /**< GN Guinea */ + WHD_COUNTRY_GUINEA_BISSAU = MK_CNTRY('G', 'W', 0), /**< GW Guinea-bissau */ + WHD_COUNTRY_GUYANA = MK_CNTRY('G', 'Y', 0), /**< GY Guyana */ + WHD_COUNTRY_HAITI = MK_CNTRY('H', 'T', 0), /**< HT Haiti */ + WHD_COUNTRY_HOLY_SEE_VATICAN_CITY_STATE = MK_CNTRY('V', 'A', 0), /**< VA Holy_See_(Vatican_City_State) */ + WHD_COUNTRY_HONDURAS = MK_CNTRY('H', 'N', 0), /**< HN Honduras */ + WHD_COUNTRY_HONG_KONG = MK_CNTRY('H', 'K', 0), /**< HK Hong_Kong */ + WHD_COUNTRY_HUNGARY = MK_CNTRY('H', 'U', 0), /**< HU Hungary */ + WHD_COUNTRY_ICELAND = MK_CNTRY('I', 'S', 0), /**< IS Iceland */ + WHD_COUNTRY_INDIA = MK_CNTRY('I', 'N', 0), /**< IN India */ + WHD_COUNTRY_INDONESIA = MK_CNTRY('I', 'D', 0), /**< ID Indonesia */ + WHD_COUNTRY_IRAN_ISLAMIC_REPUBLIC_OF = MK_CNTRY('I', 'R', 0), /**< IR Iran,_Islamic_Republic_Of */ + WHD_COUNTRY_IRAQ = MK_CNTRY('I', 'Q', 0), /**< IQ Iraq */ + WHD_COUNTRY_IRELAND = MK_CNTRY('I', 'E', 0), /**< IE Ireland */ + WHD_COUNTRY_ISRAEL = MK_CNTRY('I', 'L', 0), /**< IL Israel */ + WHD_COUNTRY_ITALY = MK_CNTRY('I', 'T', 0), /**< IT Italy */ + WHD_COUNTRY_JAMAICA = MK_CNTRY('J', 'M', 0), /**< JM Jamaica */ + WHD_COUNTRY_JAPAN = MK_CNTRY('J', 'P', 0), /**< JP Japan */ + WHD_COUNTRY_JERSEY = MK_CNTRY('J', 'E', 0), /**< JE Jersey */ + WHD_COUNTRY_JORDAN = MK_CNTRY('J', 'O', 0), /**< JO Jordan */ + WHD_COUNTRY_KAZAKHSTAN = MK_CNTRY('K', 'Z', 0), /**< KZ Kazakhstan */ + WHD_COUNTRY_KENYA = MK_CNTRY('K', 'E', 0), /**< KE Kenya */ + WHD_COUNTRY_KIRIBATI = MK_CNTRY('K', 'I', 0), /**< KI Kiribati */ + WHD_COUNTRY_KOREA_REPUBLIC_OF = MK_CNTRY('K', 'R', 1), /**< KR Korea,_Republic_Of */ + WHD_COUNTRY_KOSOVO = MK_CNTRY('0', 'A', 0), /**< 0A Kosovo */ + WHD_COUNTRY_KUWAIT = MK_CNTRY('K', 'W', 0), /**< KW Kuwait */ + WHD_COUNTRY_KYRGYZSTAN = MK_CNTRY('K', 'G', 0), /**< KG Kyrgyzstan */ + WHD_COUNTRY_LAO_PEOPLES_DEMOCRATIC_REPUBIC = MK_CNTRY('L', 'A', 0), /**< LA Lao_People's_Democratic_Repubic */ + WHD_COUNTRY_LATVIA = MK_CNTRY('L', 'V', 0), /**< LV Latvia */ + WHD_COUNTRY_LEBANON = MK_CNTRY('L', 'B', 0), /**< LB Lebanon */ + WHD_COUNTRY_LESOTHO = MK_CNTRY('L', 'S', 0), /**< LS Lesotho */ + WHD_COUNTRY_LIBERIA = MK_CNTRY('L', 'R', 0), /**< LR Liberia */ + WHD_COUNTRY_LIBYAN_ARAB_JAMAHIRIYA = MK_CNTRY('L', 'Y', 0), /**< LY Libyan_Arab_Jamahiriya */ + WHD_COUNTRY_LIECHTENSTEIN = MK_CNTRY('L', 'I', 0), /**< LI Liechtenstein */ + WHD_COUNTRY_LITHUANIA = MK_CNTRY('L', 'T', 0), /**< LT Lithuania */ + WHD_COUNTRY_LUXEMBOURG = MK_CNTRY('L', 'U', 0), /**< LU Luxembourg */ + WHD_COUNTRY_MACAO = MK_CNTRY('M', 'O', 0), /**< MO Macao */ + WHD_COUNTRY_MACEDONIA_FORMER_YUGOSLAV_REPUBLIC_OF = MK_CNTRY('M', 'K', 0), /**< MK Macedonia,_Former_Yugoslav_Republic_Of */ + WHD_COUNTRY_MADAGASCAR = MK_CNTRY('M', 'G', 0), /**< MG Madagascar */ + WHD_COUNTRY_MALAWI = MK_CNTRY('M', 'W', 0), /**< MW Malawi */ + WHD_COUNTRY_MALAYSIA = MK_CNTRY('M', 'Y', 0), /**< MY Malaysia */ + WHD_COUNTRY_MALDIVES = MK_CNTRY('M', 'V', 0), /**< MV Maldives */ + WHD_COUNTRY_MALI = MK_CNTRY('M', 'L', 0), /**< ML Mali */ + WHD_COUNTRY_MALTA = MK_CNTRY('M', 'T', 0), /**< MT Malta */ + WHD_COUNTRY_MAN_ISLE_OF = MK_CNTRY('I', 'M', 0), /**< IM Man,_Isle_Of */ + WHD_COUNTRY_MARTINIQUE = MK_CNTRY('M', 'Q', 0), /**< MQ Martinique */ + WHD_COUNTRY_MAURITANIA = MK_CNTRY('M', 'R', 0), /**< MR Mauritania */ + WHD_COUNTRY_MAURITIUS = MK_CNTRY('M', 'U', 0), /**< MU Mauritius */ + WHD_COUNTRY_MAYOTTE = MK_CNTRY('Y', 'T', 0), /**< YT Mayotte */ + WHD_COUNTRY_MEXICO = MK_CNTRY('M', 'X', 0), /**< MX Mexico */ + WHD_COUNTRY_MICRONESIA_FEDERATED_STATES_OF = MK_CNTRY('F', 'M', 0), /**< FM Micronesia,_Federated_States_Of */ + WHD_COUNTRY_MOLDOVA_REPUBLIC_OF = MK_CNTRY('M', 'D', 0), /**< MD Moldova,_Republic_Of */ + WHD_COUNTRY_MONACO = MK_CNTRY('M', 'C', 0), /**< MC Monaco */ + WHD_COUNTRY_MONGOLIA = MK_CNTRY('M', 'N', 0), /**< MN Mongolia */ + WHD_COUNTRY_MONTENEGRO = MK_CNTRY('M', 'E', 0), /**< ME Montenegro */ + WHD_COUNTRY_MONTSERRAT = MK_CNTRY('M', 'S', 0), /**< MS Montserrat */ + WHD_COUNTRY_MOROCCO = MK_CNTRY('M', 'A', 0), /**< MA Morocco */ + WHD_COUNTRY_MOZAMBIQUE = MK_CNTRY('M', 'Z', 0), /**< MZ Mozambique */ + WHD_COUNTRY_MYANMAR = MK_CNTRY('M', 'M', 0), /**< MM Myanmar */ + WHD_COUNTRY_NAMIBIA = MK_CNTRY('N', 'A', 0), /**< NA Namibia */ + WHD_COUNTRY_NAURU = MK_CNTRY('N', 'R', 0), /**< NR Nauru */ + WHD_COUNTRY_NEPAL = MK_CNTRY('N', 'P', 0), /**< NP Nepal */ + WHD_COUNTRY_NETHERLANDS = MK_CNTRY('N', 'L', 0), /**< NL Netherlands */ + WHD_COUNTRY_NETHERLANDS_ANTILLES = MK_CNTRY('A', 'N', 0), /**< AN Netherlands_Antilles */ + WHD_COUNTRY_NEW_CALEDONIA = MK_CNTRY('N', 'C', 0), /**< NC New_Caledonia */ + WHD_COUNTRY_NEW_ZEALAND = MK_CNTRY('N', 'Z', 0), /**< NZ New_Zealand */ + WHD_COUNTRY_NICARAGUA = MK_CNTRY('N', 'I', 0), /**< NI Nicaragua */ + WHD_COUNTRY_NIGER = MK_CNTRY('N', 'E', 0), /**< NE Niger */ + WHD_COUNTRY_NIGERIA = MK_CNTRY('N', 'G', 0), /**< NG Nigeria */ + WHD_COUNTRY_NORFOLK_ISLAND = MK_CNTRY('N', 'F', 0), /**< NF Norfolk_Island */ + WHD_COUNTRY_NORTHERN_MARIANA_ISLANDS = MK_CNTRY('M', 'P', 0), /**< MP Northern_Mariana_Islands */ + WHD_COUNTRY_NORWAY = MK_CNTRY('N', 'O', 0), /**< NO Norway */ + WHD_COUNTRY_OMAN = MK_CNTRY('O', 'M', 0), /**< OM Oman */ + WHD_COUNTRY_PAKISTAN = MK_CNTRY('P', 'K', 0), /**< PK Pakistan */ + WHD_COUNTRY_PALAU = MK_CNTRY('P', 'W', 0), /**< PW Palau */ + WHD_COUNTRY_PANAMA = MK_CNTRY('P', 'A', 0), /**< PA Panama */ + WHD_COUNTRY_PAPUA_NEW_GUINEA = MK_CNTRY('P', 'G', 0), /**< PG Papua_New_Guinea */ + WHD_COUNTRY_PARAGUAY = MK_CNTRY('P', 'Y', 0), /**< PY Paraguay */ + WHD_COUNTRY_PERU = MK_CNTRY('P', 'E', 0), /**< PE Peru */ + WHD_COUNTRY_PHILIPPINES = MK_CNTRY('P', 'H', 0), /**< PH Philippines */ + WHD_COUNTRY_POLAND = MK_CNTRY('P', 'L', 0), /**< PL Poland */ + WHD_COUNTRY_PORTUGAL = MK_CNTRY('P', 'T', 0), /**< PT Portugal */ + WHD_COUNTRY_PUETO_RICO = MK_CNTRY('P', 'R', 0), /**< PR Pueto_Rico */ + WHD_COUNTRY_QATAR = MK_CNTRY('Q', 'A', 0), /**< QA Qatar */ + WHD_COUNTRY_REUNION = MK_CNTRY('R', 'E', 0), /**< RE Reunion */ + WHD_COUNTRY_ROMANIA = MK_CNTRY('R', 'O', 0), /**< RO Romania */ + WHD_COUNTRY_RUSSIAN_FEDERATION = MK_CNTRY('R', 'U', 0), /**< RU Russian_Federation */ + WHD_COUNTRY_RWANDA = MK_CNTRY('R', 'W', 0), /**< RW Rwanda */ + WHD_COUNTRY_SAINT_KITTS_AND_NEVIS = MK_CNTRY('K', 'N', 0), /**< KN Saint_Kitts_and_Nevis */ + WHD_COUNTRY_SAINT_LUCIA = MK_CNTRY('L', 'C', 0), /**< LC Saint_Lucia */ + WHD_COUNTRY_SAINT_PIERRE_AND_MIQUELON = MK_CNTRY('P', 'M', 0), /**< PM Saint_Pierre_and_Miquelon */ + WHD_COUNTRY_SAINT_VINCENT_AND_THE_GRENADINES = MK_CNTRY('V', 'C', 0), /**< VC Saint_Vincent_and_The_Grenadines */ + WHD_COUNTRY_SAMOA = MK_CNTRY('W', 'S', 0), /**< WS Samoa */ + WHD_COUNTRY_SANIT_MARTIN_SINT_MARTEEN = MK_CNTRY('M', 'F', 0), /**< MF Sanit_Martin_/_Sint_Marteen */ + WHD_COUNTRY_SAO_TOME_AND_PRINCIPE = MK_CNTRY('S', 'T', 0), /**< ST Sao_Tome_and_Principe */ + WHD_COUNTRY_SAUDI_ARABIA = MK_CNTRY('S', 'A', 0), /**< SA Saudi_Arabia */ + WHD_COUNTRY_SENEGAL = MK_CNTRY('S', 'N', 0), /**< SN Senegal */ + WHD_COUNTRY_SERBIA = MK_CNTRY('R', 'S', 0), /**< RS Serbia */ + WHD_COUNTRY_SEYCHELLES = MK_CNTRY('S', 'C', 0), /**< SC Seychelles */ + WHD_COUNTRY_SIERRA_LEONE = MK_CNTRY('S', 'L', 0), /**< SL Sierra_Leone */ + WHD_COUNTRY_SINGAPORE = MK_CNTRY('S', 'G', 0), /**< SG Singapore */ + WHD_COUNTRY_SLOVAKIA = MK_CNTRY('S', 'K', 0), /**< SK Slovakia */ + WHD_COUNTRY_SLOVENIA = MK_CNTRY('S', 'I', 0), /**< SI Slovenia */ + WHD_COUNTRY_SOLOMON_ISLANDS = MK_CNTRY('S', 'B', 0), /**< SB Solomon_Islands */ + WHD_COUNTRY_SOMALIA = MK_CNTRY('S', 'O', 0), /**< SO Somalia */ + WHD_COUNTRY_SOUTH_AFRICA = MK_CNTRY('Z', 'A', 0), /**< ZA South_Africa */ + WHD_COUNTRY_SPAIN = MK_CNTRY('E', 'S', 0), /**< ES Spain */ + WHD_COUNTRY_SRI_LANKA = MK_CNTRY('L', 'K', 0), /**< LK Sri_Lanka */ + WHD_COUNTRY_SURINAME = MK_CNTRY('S', 'R', 0), /**< SR Suriname */ + WHD_COUNTRY_SWAZILAND = MK_CNTRY('S', 'Z', 0), /**< SZ Swaziland */ + WHD_COUNTRY_SWEDEN = MK_CNTRY('S', 'E', 0), /**< SE Sweden */ + WHD_COUNTRY_SWITZERLAND = MK_CNTRY('C', 'H', 0), /**< CH Switzerland */ + WHD_COUNTRY_SYRIAN_ARAB_REPUBLIC = MK_CNTRY('S', 'Y', 0), /**< SY Syrian_Arab_Republic */ + WHD_COUNTRY_TAIWAN_PROVINCE_OF_CHINA = MK_CNTRY('T', 'W', 0), /**< TW Taiwan,_Province_Of_China */ + WHD_COUNTRY_TAJIKISTAN = MK_CNTRY('T', 'J', 0), /**< TJ Tajikistan */ + WHD_COUNTRY_TANZANIA_UNITED_REPUBLIC_OF = MK_CNTRY('T', 'Z', 0), /**< TZ Tanzania,_United_Republic_Of */ + WHD_COUNTRY_THAILAND = MK_CNTRY('T', 'H', 0), /**< TH Thailand */ + WHD_COUNTRY_TOGO = MK_CNTRY('T', 'G', 0), /**< TG Togo */ + WHD_COUNTRY_TONGA = MK_CNTRY('T', 'O', 0), /**< TO Tonga */ + WHD_COUNTRY_TRINIDAD_AND_TOBAGO = MK_CNTRY('T', 'T', 0), /**< TT Trinidad_and_Tobago */ + WHD_COUNTRY_TUNISIA = MK_CNTRY('T', 'N', 0), /**< TN Tunisia */ + WHD_COUNTRY_TURKEY = MK_CNTRY('T', 'R', 0), /**< TR Turkey */ + WHD_COUNTRY_TURKMENISTAN = MK_CNTRY('T', 'M', 0), /**< TM Turkmenistan */ + WHD_COUNTRY_TURKS_AND_CAICOS_ISLANDS = MK_CNTRY('T', 'C', 0), /**< TC Turks_and_Caicos_Islands */ + WHD_COUNTRY_TUVALU = MK_CNTRY('T', 'V', 0), /**< TV Tuvalu */ + WHD_COUNTRY_UGANDA = MK_CNTRY('U', 'G', 0), /**< UG Uganda */ + WHD_COUNTRY_UKRAINE = MK_CNTRY('U', 'A', 0), /**< UA Ukraine */ + WHD_COUNTRY_UNITED_ARAB_EMIRATES = MK_CNTRY('A', 'E', 0), /**< AE United_Arab_Emirates */ + WHD_COUNTRY_UNITED_KINGDOM = MK_CNTRY('G', 'B', 0), /**< GB United_Kingdom */ + WHD_COUNTRY_UNITED_STATES = MK_CNTRY('U', 'S', 0), /**< US United_States */ + WHD_COUNTRY_UNITED_STATES_REV4 = MK_CNTRY('U', 'S', 4), /**< US United_States Revision 4 */ + WHD_COUNTRY_UNITED_STATES_REV931 = MK_CNTRY('Q', '1', 931), /**< Q1 United_States Revision 931 */ + WHD_COUNTRY_UNITED_STATES_NO_DFS = MK_CNTRY('Q', '2', 0), /**< Q2 United_States_(No_DFS) */ + WHD_COUNTRY_UNITED_STATES_MINOR_OUTLYING_ISLANDS = MK_CNTRY('U', 'M', 0), /**< UM United_States_Minor_Outlying_Islands */ + WHD_COUNTRY_URUGUAY = MK_CNTRY('U', 'Y', 0), /**< UY Uruguay */ + WHD_COUNTRY_UZBEKISTAN = MK_CNTRY('U', 'Z', 0), /**< UZ Uzbekistan */ + WHD_COUNTRY_VANUATU = MK_CNTRY('V', 'U', 0), /**< VU Vanuatu */ + WHD_COUNTRY_VENEZUELA = MK_CNTRY('V', 'E', 0), /**< VE Venezuela */ + WHD_COUNTRY_VIET_NAM = MK_CNTRY('V', 'N', 0), /**< VN Viet_Nam */ + WHD_COUNTRY_VIRGIN_ISLANDS_BRITISH = MK_CNTRY('V', 'G', 0), /**< VG Virgin_Islands,_British */ + WHD_COUNTRY_VIRGIN_ISLANDS_US = MK_CNTRY('V', 'I', 0), /**< VI Virgin_Islands,_U.S. */ + WHD_COUNTRY_WALLIS_AND_FUTUNA = MK_CNTRY('W', 'F', 0), /**< WF Wallis_and_Futuna */ + WHD_COUNTRY_WEST_BANK = MK_CNTRY('0', 'C', 0), /**< 0C West_Bank */ + WHD_COUNTRY_WESTERN_SAHARA = MK_CNTRY('E', 'H', 0), /**< EH Western_Sahara */ + WHD_COUNTRY_WORLD_WIDE_XV_REV983 = MK_CNTRY('X', 'V', 983), /**< Worldwide Locale Revision 983 */ + WHD_COUNTRY_WORLD_WIDE_XX = MK_CNTRY('X', 'X', 0), /**< Worldwide Locale (passive Ch12-14) */ + WHD_COUNTRY_WORLD_WIDE_XX_REV17 = MK_CNTRY('X', 'X', 17), /**< Worldwide Locale (passive Ch12-14) Revision 17 */ + WHD_COUNTRY_YEMEN = MK_CNTRY('Y', 'E', 0), /**< YE Yemen */ + WHD_COUNTRY_ZAMBIA = MK_CNTRY('Z', 'M', 0), /**< ZM Zambia */ + WHD_COUNTRY_ZIMBABWE = MK_CNTRY('Z', 'W', 0), /**< ZW Zimbabwe */ } whd_country_code_t; /** @@ -696,78 +778,86 @@ typedef enum { */ typedef struct { - int32_t number_of_probes_per_channel; /**< Number of probes to send on each channel */ - int32_t scan_active_dwell_time_per_channel_ms; /**< Period of time to wait on each channel when active scanning */ - int32_t scan_passive_dwell_time_per_channel_ms; /**< Period of time to wait on each channel when passive scanning */ - int32_t scan_home_channel_dwell_time_between_channels_ms; /**< Period of time to wait on the home channel when scanning. Only relevant if associated. */ + int32_t number_of_probes_per_channel; /**< Number of probes to send on each channel */ + int32_t scan_active_dwell_time_per_channel_ms; /**< Period of time to wait on each channel when active scanning */ + int32_t scan_passive_dwell_time_per_channel_ms; /**< Period of time to wait on each channel when passive scanning */ + int32_t scan_home_channel_dwell_time_between_channels_ms; /**< Period of time to wait on the home channel when scanning. Only relevant if associated. */ } whd_scan_extended_params_t; /** * Structure for storing scan results */ #pragma pack(1) -typedef struct whd_scan_result { - whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ - whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ - int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ - uint32_t max_data_rate; /**< Maximum data rate in kilobits/s */ - whd_bss_type_t bss_type; /**< Network type */ - whd_security_t security; /**< Security type */ - uint8_t channel; /**< Radio channel that the AP beacon was received on */ - whd_802_11_band_t band; /**< Radio band */ - uint8_t ccode[2]; /**< Two letter ISO country code from AP */ - uint8_t flags; /**< flags */ - struct whd_scan_result *next; /**< Pointer to the next scan result */ - uint8_t *ie_ptr; /**< Pointer to received Beacon/Probe Response IE(Information Element) */ - uint32_t ie_len; /**< Length of IE(Information Element) */ +typedef struct whd_scan_result +{ + whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ + whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ + int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ + uint32_t max_data_rate; /**< Maximum data rate in kilobits/s */ + whd_bss_type_t bss_type; /**< Network type */ + whd_security_t security; /**< Security type */ + uint8_t channel; /**< Radio channel that the AP beacon was received on */ + whd_802_11_band_t band; /**< Radio band */ + uint8_t ccode[2]; /**< Two letter ISO country code from AP */ + uint8_t flags; /**< flags */ + struct whd_scan_result *next; /**< Pointer to the next scan result */ + uint8_t *ie_ptr; /**< Pointer to received Beacon/Probe Response IE(Information Element) */ + uint32_t ie_len; /**< Length of IE(Information Element) */ } whd_scan_result_t; #pragma pack() /** * Structure to store scan result parameters for each AP */ -typedef struct whd_simple_scan_result { - whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ - whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ - int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ - whd_security_t security; /**< Security type */ - uint8_t channel; /**< Radio channel that the AP beacon was received on */ +typedef struct whd_simple_scan_result +{ + whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ + whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ + int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ + whd_security_t security; /**< Security type */ + uint8_t channel; /**< Radio channel that the AP beacon was received on */ } whd_sync_scan_result_t; -typedef uint16_t wl_chanspec_t; /**< Channel specified in uint16_t */ -#define MCSSET_LEN 16 /**< Maximum allowed mcs rate */ +typedef uint16_t wl_chanspec_t; /**< Channel specified in uint16_t */ +#define MCSSET_LEN 16 /**< Maximum allowed mcs rate */ /** BSS(Basic Service Set) information structure * * Applications MUST CHECK ie_offset field and length field to access IEs(Information Elements) and * next bss_info structure in a vector (in whd_sync_scan_result_t) */ -typedef struct wl_bss_info_struct { - uint32_t version; /**< version field */ - uint32_t length; /**< byte length of data in this record, starting at version and including IEs */ - whd_mac_t BSSID; /**< Unique 6-byte MAC address */ - uint16_t beacon_period; /**< Interval between two consecutive beacon frames. Units are Kusec */ - uint16_t capability; /**< Capability information */ - uint8_t SSID_len; /**< SSID length */ - uint8_t SSID[32]; /**< Array to store SSID */ - struct - { - uint32_t count; /**< Count of rates in this set */ - uint8_t rates[16]; /**< rates in 500kbps units, higher bit set if basic */ - } rateset; /**< supported rates */ - wl_chanspec_t chanspec; /**< Channel specification for basic service set */ - uint16_t atim_window; /**< Announcement traffic indication message window size. Units are Kusec */ - uint8_t dtim_period; /**< Delivery traffic indication message period */ - int16_t RSSI; /**< receive signal strength (in dBm) */ - int8_t phy_noise; /**< noise (in dBm) */ - - uint8_t n_cap; /**< BSS is 802.11N Capable */ - uint32_t nbss_cap; /**< 802.11N BSS Capabilities (based on HT_CAP_*) */ - uint8_t ctl_ch; /**< 802.11N BSS control channel number */ - uint32_t reserved32[1]; /**< Reserved for expansion of BSS properties */ - uint8_t flags; /**< flags */ - uint8_t reserved[3]; /**< Reserved for expansion of BSS properties */ - uint8_t basic_mcs[MCSSET_LEN]; /**< 802.11N BSS required MCS set */ +typedef struct wl_bss_info_struct +{ + uint32_t version; /**< version field */ + uint32_t length; /**< byte length of data in this record, starting at version and including IEs */ + whd_mac_t BSSID; /**< Unique 6-byte MAC address */ + uint16_t beacon_period; /**< Interval between two consecutive beacon frames. Units are Kusec */ + uint16_t capability; /**< Capability information */ + uint8_t SSID_len; /**< SSID length */ + uint8_t SSID[32]; /**< Array to store SSID */ + uint8_t reserved1[1]; /**< Reserved(padding) */ + struct + { + uint32_t count; /**< Count of rates in this set */ + uint8_t rates[16]; /**< rates in 500kbps units, higher bit set if basic */ + } rateset; /**< supported rates */ + wl_chanspec_t chanspec; /**< Channel specification for basic service set */ + uint16_t atim_window; /**< Announcement traffic indication message window size. Units are Kusec */ + uint8_t dtim_period; /**< Delivery traffic indication message period */ + uint8_t reserved2[1]; /**< Reserved(padding) */ + int16_t RSSI; /**< receive signal strength (in dBm) */ + int8_t phy_noise; /**< noise (in dBm) */ + + uint8_t n_cap; /**< BSS is 802.11N Capable */ + uint8_t reserved3[2]; /**< Reserved(padding) */ + uint32_t nbss_cap; /**< 802.11N BSS Capabilities (based on HT_CAP_*) */ + uint8_t ctl_ch; /**< 802.11N BSS control channel number */ + uint8_t reserved4[3]; /**< Reserved(padding) */ + uint32_t reserved32[1]; /**< Reserved for expansion of BSS properties */ + uint8_t flags; /**< flags */ + uint8_t vht_cap; /**< BSS is vht capable */ + uint8_t reserved5[2]; /**< Reserved(padding) */ + uint8_t basic_mcs[MCSSET_LEN]; /**< 802.11N BSS required MCS set */ uint16_t ie_offset; /**< offset at which IEs start, from beginning */ uint32_t ie_length; /**< byte length of Information Elements */ @@ -781,9 +871,9 @@ typedef struct wl_bss_info_struct { */ typedef struct { - uint8_t beacon; /**< Listen interval in beacon periods */ - uint8_t dtim; /**< Listen interval in DTIM periods */ - uint16_t assoc; /**< Listen interval as sent to APs */ + uint8_t beacon; /**< Listen interval in beacon periods */ + uint8_t dtim; /**< Listen interval in DTIM periods */ + uint16_t assoc; /**< Listen interval as sent to APs */ } whd_listen_interval_t; /** @@ -794,132 +884,136 @@ typedef uint32_t whd_result_t; /* whd_result_t error code format * |31-18 (14 bit) for module id|17-16 (2 bit) for result type|15-0 for whd error code| */ -#define WHD_RESULT_TYPE 0 /**< WHD Result type */ -#define WHD_RESULT_CREATE(x) CY_RSLT_CREATE(WHD_RESULT_TYPE, CY_RSLT_MODULE_DRIVERS_WHD_BASE, (x)) /**< Create a result value from the specified type, module, and result code */ - -#define WHD_SUCCESS CY_RSLT_SUCCESS /**< Success */ -#define WHD_PENDING WHD_RESULT_CREATE(1) /**< Pending */ -#define WHD_TIMEOUT WHD_RESULT_CREATE(2) /**< Timeout */ -#define WHD_BADARG WHD_RESULT_CREATE(5) /**< Bad Arguments */ -#define WHD_UNFINISHED WHD_RESULT_CREATE(10) /**< Operation not finished yet WHD_RESULT_CREATE(maybe aborted) */ - -#define WHD_PARTIAL_RESULTS WHD_RESULT_CREATE(1003) /**< Partial results */ -#define WHD_INVALID_KEY WHD_RESULT_CREATE(1004) /**< Invalid key */ -#define WHD_DOES_NOT_EXIST WHD_RESULT_CREATE(1005) /**< Does not exist */ -#define WHD_NOT_AUTHENTICATED WHD_RESULT_CREATE(1006) /**< Not authenticated */ -#define WHD_NOT_KEYED WHD_RESULT_CREATE(1007) /**< Not keyed */ -#define WHD_IOCTL_FAIL WHD_RESULT_CREATE(1008) /**< IOCTL fail */ -#define WHD_BUFFER_UNAVAILABLE_TEMPORARY WHD_RESULT_CREATE(1009) /**< Buffer unavailable temporarily */ -#define WHD_BUFFER_UNAVAILABLE_PERMANENT WHD_RESULT_CREATE(1010) /**< Buffer unavailable permanently */ -#define WHD_CONNECTION_LOST WHD_RESULT_CREATE(1012) /**< Connection lost */ -#define WHD_OUT_OF_EVENT_HANDLER_SPACE WHD_RESULT_CREATE(1013) /**< Cannot add extra event handler */ -#define WHD_SEMAPHORE_ERROR WHD_RESULT_CREATE(1014) /**< Error manipulating a semaphore */ -#define WHD_FLOW_CONTROLLED WHD_RESULT_CREATE(1015) /**< Packet retrieval cancelled due to flow control */ -#define WHD_NO_CREDITS WHD_RESULT_CREATE(1016) /**< Packet retrieval cancelled due to lack of bus credits */ -#define WHD_NO_PACKET_TO_SEND WHD_RESULT_CREATE(1017) /**< Packet retrieval cancelled due to no pending packets */ -#define WHD_CORE_CLOCK_NOT_ENABLED WHD_RESULT_CREATE(1018) /**< Core disabled due to no clock */ -#define WHD_CORE_IN_RESET WHD_RESULT_CREATE(1019) /**< Core disabled - in reset */ -#define WHD_UNSUPPORTED WHD_RESULT_CREATE(1020) /**< Unsupported function */ -#define WHD_BUS_WRITE_REGISTER_ERROR WHD_RESULT_CREATE(1021) /**< Error writing to WLAN register */ -#define WHD_SDIO_BUS_UP_FAIL WHD_RESULT_CREATE(1022) /**< SDIO bus failed to come up */ -#define WHD_JOIN_IN_PROGRESS WHD_RESULT_CREATE(1023) /**< Join not finished yet */ -#define WHD_NETWORK_NOT_FOUND WHD_RESULT_CREATE(1024) /**< Specified network was not found */ -#define WHD_INVALID_JOIN_STATUS WHD_RESULT_CREATE(1025) /**< Join status error */ -#define WHD_UNKNOWN_INTERFACE WHD_RESULT_CREATE(1026) /**< Unknown interface specified */ -#define WHD_SDIO_RX_FAIL WHD_RESULT_CREATE(1027) /**< Error during SDIO receive */ -#define WHD_HWTAG_MISMATCH WHD_RESULT_CREATE(1028) /**< Hardware tag header corrupt */ -#define WHD_RX_BUFFER_ALLOC_FAIL WHD_RESULT_CREATE(1029) /**< Failed to allocate a buffer to receive into */ -#define WHD_BUS_READ_REGISTER_ERROR WHD_RESULT_CREATE(1030) /**< Error reading a bus hardware register */ -#define WHD_THREAD_CREATE_FAILED WHD_RESULT_CREATE(1031) /**< Failed to create a new thread */ -#define WHD_QUEUE_ERROR WHD_RESULT_CREATE(1032) /**< Error manipulating a queue */ -#define WHD_BUFFER_POINTER_MOVE_ERROR WHD_RESULT_CREATE(1033) /**< Error moving the current pointer of a packet buffer */ -#define WHD_BUFFER_SIZE_SET_ERROR WHD_RESULT_CREATE(1034) /**< Error setting size of packet buffer */ -#define WHD_THREAD_STACK_NULL WHD_RESULT_CREATE(1035) /**< Null stack pointer passed when non null was reqired */ -#define WHD_THREAD_DELETE_FAIL WHD_RESULT_CREATE(1036) /**< Error deleting a thread */ -#define WHD_SLEEP_ERROR WHD_RESULT_CREATE(1037) /**< Error sleeping a thread */ -#define WHD_BUFFER_ALLOC_FAIL WHD_RESULT_CREATE(1038) /**< Failed to allocate a packet buffer */ -#define WHD_NO_PACKET_TO_RECEIVE WHD_RESULT_CREATE(1039) /**< No Packets waiting to be received */ -#define WHD_INTERFACE_NOT_UP WHD_RESULT_CREATE(1040) /**< Requested interface is not active */ -#define WHD_DELAY_TOO_LONG WHD_RESULT_CREATE(1041) /**< Requested delay is too long */ -#define WHD_INVALID_DUTY_CYCLE WHD_RESULT_CREATE(1042) /**< Duty cycle is outside limit 0 to 100 */ -#define WHD_PMK_WRONG_LENGTH WHD_RESULT_CREATE(1043) /**< Returned pmk was the wrong length */ -#define WHD_UNKNOWN_SECURITY_TYPE WHD_RESULT_CREATE(1044) /**< AP security type was unknown */ -#define WHD_WEP_NOT_ALLOWED WHD_RESULT_CREATE(1045) /**< AP not allowed to use WEP - it is not secure - use Open instead */ -#define WHD_WPA_KEYLEN_BAD WHD_RESULT_CREATE(1046) /**< WPA / WPA2 key length must be between 8 & 64 bytes */ -#define WHD_FILTER_NOT_FOUND WHD_RESULT_CREATE(1047) /**< Specified filter id not found */ -#define WHD_SPI_ID_READ_FAIL WHD_RESULT_CREATE(1048) /**< Failed to read 0xfeedbead SPI id from chip */ -#define WHD_SPI_SIZE_MISMATCH WHD_RESULT_CREATE(1049) /**< Mismatch in sizes between SPI header and SDPCM header */ -#define WHD_ADDRESS_ALREADY_REGISTERED WHD_RESULT_CREATE(1050) /**< Attempt to register a multicast address twice */ -#define WHD_SDIO_RETRIES_EXCEEDED WHD_RESULT_CREATE(1051) /**< SDIO transfer failed too many times. */ -#define WHD_NULL_PTR_ARG WHD_RESULT_CREATE(1052) /**< Null Pointer argument passed to function. */ -#define WHD_THREAD_FINISH_FAIL WHD_RESULT_CREATE(1053) /**< Error deleting a thread */ -#define WHD_WAIT_ABORTED WHD_RESULT_CREATE(1054) /**< Semaphore/mutex wait has been aborted */ -#define WHD_SET_BLOCK_ACK_WINDOW_FAIL WHD_RESULT_CREATE(1055) /**< Failed to set block ack window */ -#define WHD_DELAY_TOO_SHORT WHD_RESULT_CREATE(1056) /**< Requested delay is too short */ -#define WHD_INVALID_INTERFACE WHD_RESULT_CREATE(1057) /**< Invalid interface provided */ -#define WHD_WEP_KEYLEN_BAD WHD_RESULT_CREATE(1058) /**< WEP / WEP_SHARED key length must be 5 or 13 bytes */ -#define WHD_HANDLER_ALREADY_REGISTERED WHD_RESULT_CREATE(1059) /**< EAPOL handler already registered */ -#define WHD_AP_ALREADY_UP WHD_RESULT_CREATE(1060) /**< Soft AP or P2P group owner already up */ -#define WHD_EAPOL_KEY_PACKET_M1_TIMEOUT WHD_RESULT_CREATE(1061) /**< Timeout occurred while waiting for EAPOL packet M1 from AP */ -#define WHD_EAPOL_KEY_PACKET_M3_TIMEOUT WHD_RESULT_CREATE(1062) /**< Timeout occurred while waiting for EAPOL packet M3 from APwhich may indicate incorrect WPA2/WPA passphrase */ -#define WHD_EAPOL_KEY_PACKET_G1_TIMEOUT WHD_RESULT_CREATE(1063) /**< Timeout occurred while waiting for EAPOL packet G1 from AP */ -#define WHD_EAPOL_KEY_FAILURE WHD_RESULT_CREATE(1064) /**< Unknown failure occurred during the EAPOL key handshake */ -#define WHD_MALLOC_FAILURE WHD_RESULT_CREATE(1065) /**< Memory allocation failure */ -#define WHD_ACCESS_POINT_NOT_FOUND WHD_RESULT_CREATE(1066) /**< Access point not found */ -#define WHD_RTOS_ERROR WHD_RESULT_CREATE(1067) /**< RTOS operation failed */ -#define WHD_CLM_BLOB_DLOAD_ERROR WHD_RESULT_CREATE(1068) /**< CLM blob download failed */ -#define WHD_HAL_ERROR WHD_RESULT_CREATE(1069) /**< WHD HAL Error */ -#define WHD_RTOS_STATIC_MEM_LIMIT WHD_RESULT_CREATE(1070) /**< Exceeding the RTOS static objects memory */ -#define WHD_NO_REGISTER_FUNCTION_POINTER WHD_RESULT_CREATE(1071) /**< No register function pointer */ - -#define WLAN_ENUM_OFFSET 2000 /**< WLAN enum offset for WHD_WLAN error processing */ - -#define WHD_WLAN_ERROR WHD_RESULT_CREATE(2001) /**< Generic Error */ -#define WHD_WLAN_BADARG WHD_RESULT_CREATE(2002) /**< Bad Argument */ -#define WHD_WLAN_BADOPTION WHD_RESULT_CREATE(2003) /**< Bad option */ -#define WHD_WLAN_NOTUP WHD_RESULT_CREATE(2004) /**< Not up */ -#define WHD_WLAN_NOTDOWN WHD_RESULT_CREATE(2005) /**< Not down */ -#define WHD_WLAN_NOTAP WHD_RESULT_CREATE(2006) /**< Not AP */ -#define WHD_WLAN_NOTSTA WHD_RESULT_CREATE(2007) /**< Not STA */ -#define WHD_WLAN_BADKEYIDX WHD_RESULT_CREATE(2008) /**< BAD Key Index */ -#define WHD_WLAN_RADIOOFF WHD_RESULT_CREATE(2009) /**< Radio Off */ -#define WHD_WLAN_NOTBANDLOCKED WHD_RESULT_CREATE(2010) /**< Not band locked */ -#define WHD_WLAN_NOCLK WHD_RESULT_CREATE(2011) /**< No Clock */ -#define WHD_WLAN_BADRATESET WHD_RESULT_CREATE(2012) /**< BAD Rate valueset */ -#define WHD_WLAN_BADBAND WHD_RESULT_CREATE(2013) /**< BAD Band */ -#define WHD_WLAN_BUFTOOSHORT WHD_RESULT_CREATE(2014) /**< Buffer too short */ -#define WHD_WLAN_BUFTOOLONG WHD_RESULT_CREATE(2015) /**< Buffer too long */ -#define WHD_WLAN_BUSY WHD_RESULT_CREATE(2016) /**< Busy */ -#define WHD_WLAN_NOTASSOCIATED WHD_RESULT_CREATE(2017) /**< Not Associated */ -#define WHD_WLAN_BADSSIDLEN WHD_RESULT_CREATE(2018) /**< Bad SSID len */ -#define WHD_WLAN_OUTOFRANGECHAN WHD_RESULT_CREATE(2019) /**< Out of Range Channel */ -#define WHD_WLAN_BADCHAN WHD_RESULT_CREATE(2020) /**< Bad Channel */ -#define WHD_WLAN_BADADDR WHD_RESULT_CREATE(2021) /**< Bad Address */ -#define WHD_WLAN_NORESOURCE WHD_RESULT_CREATE(2022) /**< Not Enough Resources */ -#define WHD_WLAN_UNSUPPORTED WHD_RESULT_CREATE(2023) /**< Unsupported */ -#define WHD_WLAN_BADLEN WHD_RESULT_CREATE(2024) /**< Bad length */ -#define WHD_WLAN_NOTREADY WHD_RESULT_CREATE(2025) /**< Not Ready */ -#define WHD_WLAN_EPERM WHD_RESULT_CREATE(2026) /**< Not Permitted */ -#define WHD_WLAN_NOMEM WHD_RESULT_CREATE(2027) /**< No Memory */ -#define WHD_WLAN_ASSOCIATED WHD_RESULT_CREATE(2028) /**< Associated */ -#define WHD_WLAN_RANGE WHD_RESULT_CREATE(2029) /**< Not In Range */ -#define WHD_WLAN_NOTFOUND WHD_RESULT_CREATE(2030) /**< Not Found */ -#define WHD_WLAN_WME_NOT_ENABLED WHD_RESULT_CREATE(2031) /**< WME Not Enabled */ -#define WHD_WLAN_TSPEC_NOTFOUND WHD_RESULT_CREATE(2032) /**< TSPEC Not Found */ -#define WHD_WLAN_ACM_NOTSUPPORTED WHD_RESULT_CREATE(2033) /**< ACM Not Supported */ -#define WHD_WLAN_NOT_WME_ASSOCIATION WHD_RESULT_CREATE(2034) /**< Not WME Association */ -#define WHD_WLAN_SDIO_ERROR WHD_RESULT_CREATE(2035) /**< SDIO Bus Error */ -#define WHD_WLAN_WLAN_DOWN WHD_RESULT_CREATE(2036) /**< WLAN Not Accessible */ -#define WHD_WLAN_BAD_VERSION WHD_RESULT_CREATE(2037) /**< Incorrect version */ -#define WHD_WLAN_TXFAIL WHD_RESULT_CREATE(2038) /**< TX failure */ -#define WHD_WLAN_RXFAIL WHD_RESULT_CREATE(2039) /**< RX failure */ -#define WHD_WLAN_NODEVICE WHD_RESULT_CREATE(2040) /**< Device not present */ -#define WHD_WLAN_UNFINISHED WHD_RESULT_CREATE(2041) /**< To be finished */ -#define WHD_WLAN_NONRESIDENT WHD_RESULT_CREATE(2042) /**< access to nonresident overlay */ -#define WHD_WLAN_DISABLED WHD_RESULT_CREATE(2043) /**< Disabled in this build */ -#define WHD_WLAN_NOFUNCTION WHD_RESULT_CREATE(2044) /**< Function pointer not provided */ -#define WHD_WLAN_INVALID WHD_RESULT_CREATE(2045) /**< Not valid */ -#define WHD_WLAN_NOBAND WHD_RESULT_CREATE(2046) /**< No Band */ +#define WHD_RESULT_TYPE 0 /**< WHD Result type */ +#define WHD_RESULT_CREATE(x) CY_RSLT_CREATE(WHD_RESULT_TYPE, CY_RSLT_MODULE_DRIVERS_WHD_BASE, (x) ) /**< Create a result value from the specified type, module, and result code */ + +#define WHD_SUCCESS CY_RSLT_SUCCESS /**< Success */ +#define WHD_PENDING WHD_RESULT_CREATE(1) /**< Pending */ +#define WHD_TIMEOUT WHD_RESULT_CREATE(2) /**< Timeout */ +#define WHD_BADARG WHD_RESULT_CREATE(5) /**< Bad Arguments */ +#define WHD_UNFINISHED WHD_RESULT_CREATE(10) /**< Operation not finished yet WHD_RESULT_CREATE(maybe aborted) */ + +#define WHD_PARTIAL_RESULTS WHD_RESULT_CREATE(1003) /**< Partial results */ +#define WHD_INVALID_KEY WHD_RESULT_CREATE(1004) /**< Invalid key */ +#define WHD_DOES_NOT_EXIST WHD_RESULT_CREATE(1005) /**< Does not exist */ +#define WHD_NOT_AUTHENTICATED WHD_RESULT_CREATE(1006) /**< Not authenticated */ +#define WHD_NOT_KEYED WHD_RESULT_CREATE(1007) /**< Not keyed */ +#define WHD_IOCTL_FAIL WHD_RESULT_CREATE(1008) /**< IOCTL fail */ +#define WHD_BUFFER_UNAVAILABLE_TEMPORARY WHD_RESULT_CREATE(1009) /**< Buffer unavailable temporarily */ +#define WHD_BUFFER_UNAVAILABLE_PERMANENT WHD_RESULT_CREATE(1010) /**< Buffer unavailable permanently */ +#define WHD_CONNECTION_LOST WHD_RESULT_CREATE(1012) /**< Connection lost */ +#define WHD_OUT_OF_EVENT_HANDLER_SPACE WHD_RESULT_CREATE(1013) /**< Cannot add extra event handler */ +#define WHD_SEMAPHORE_ERROR WHD_RESULT_CREATE(1014) /**< Error manipulating a semaphore */ +#define WHD_FLOW_CONTROLLED WHD_RESULT_CREATE(1015) /**< Packet retrieval cancelled due to flow control */ +#define WHD_NO_CREDITS WHD_RESULT_CREATE(1016) /**< Packet retrieval cancelled due to lack of bus credits */ +#define WHD_NO_PACKET_TO_SEND WHD_RESULT_CREATE(1017) /**< Packet retrieval cancelled due to no pending packets */ +#define WHD_CORE_CLOCK_NOT_ENABLED WHD_RESULT_CREATE(1018) /**< Core disabled due to no clock */ +#define WHD_CORE_IN_RESET WHD_RESULT_CREATE(1019) /**< Core disabled - in reset */ +#define WHD_UNSUPPORTED WHD_RESULT_CREATE(1020) /**< Unsupported function */ +#define WHD_BUS_WRITE_REGISTER_ERROR WHD_RESULT_CREATE(1021) /**< Error writing to WLAN register */ +#define WHD_SDIO_BUS_UP_FAIL WHD_RESULT_CREATE(1022) /**< SDIO bus failed to come up */ +#define WHD_JOIN_IN_PROGRESS WHD_RESULT_CREATE(1023) /**< Join not finished yet */ +#define WHD_NETWORK_NOT_FOUND WHD_RESULT_CREATE(1024) /**< Specified network was not found */ +#define WHD_INVALID_JOIN_STATUS WHD_RESULT_CREATE(1025) /**< Join status error */ +#define WHD_UNKNOWN_INTERFACE WHD_RESULT_CREATE(1026) /**< Unknown interface specified */ +#define WHD_SDIO_RX_FAIL WHD_RESULT_CREATE(1027) /**< Error during SDIO receive */ +#define WHD_HWTAG_MISMATCH WHD_RESULT_CREATE(1028) /**< Hardware tag header corrupt */ +#define WHD_RX_BUFFER_ALLOC_FAIL WHD_RESULT_CREATE(1029) /**< Failed to allocate a buffer to receive into */ +#define WHD_BUS_READ_REGISTER_ERROR WHD_RESULT_CREATE(1030) /**< Error reading a bus hardware register */ +#define WHD_THREAD_CREATE_FAILED WHD_RESULT_CREATE(1031) /**< Failed to create a new thread */ +#define WHD_QUEUE_ERROR WHD_RESULT_CREATE(1032) /**< Error manipulating a queue */ +#define WHD_BUFFER_POINTER_MOVE_ERROR WHD_RESULT_CREATE(1033) /**< Error moving the current pointer of a packet buffer */ +#define WHD_BUFFER_SIZE_SET_ERROR WHD_RESULT_CREATE(1034) /**< Error setting size of packet buffer */ +#define WHD_THREAD_STACK_NULL WHD_RESULT_CREATE(1035) /**< Null stack pointer passed when non null was reqired */ +#define WHD_THREAD_DELETE_FAIL WHD_RESULT_CREATE(1036) /**< Error deleting a thread */ +#define WHD_SLEEP_ERROR WHD_RESULT_CREATE(1037) /**< Error sleeping a thread */ +#define WHD_BUFFER_ALLOC_FAIL WHD_RESULT_CREATE(1038) /**< Failed to allocate a packet buffer */ +#define WHD_NO_PACKET_TO_RECEIVE WHD_RESULT_CREATE(1039) /**< No Packets waiting to be received */ +#define WHD_INTERFACE_NOT_UP WHD_RESULT_CREATE(1040) /**< Requested interface is not active */ +#define WHD_DELAY_TOO_LONG WHD_RESULT_CREATE(1041) /**< Requested delay is too long */ +#define WHD_INVALID_DUTY_CYCLE WHD_RESULT_CREATE(1042) /**< Duty cycle is outside limit 0 to 100 */ +#define WHD_PMK_WRONG_LENGTH WHD_RESULT_CREATE(1043) /**< Returned pmk was the wrong length */ +#define WHD_UNKNOWN_SECURITY_TYPE WHD_RESULT_CREATE(1044) /**< AP security type was unknown */ +#define WHD_WEP_NOT_ALLOWED WHD_RESULT_CREATE(1045) /**< AP not allowed to use WEP - it is not secure - use Open instead */ +#define WHD_WPA_KEYLEN_BAD WHD_RESULT_CREATE(1046) /**< WPA / WPA2 key length must be between 8 & 64 bytes */ +#define WHD_FILTER_NOT_FOUND WHD_RESULT_CREATE(1047) /**< Specified filter id not found */ +#define WHD_SPI_ID_READ_FAIL WHD_RESULT_CREATE(1048) /**< Failed to read 0xfeedbead SPI id from chip */ +#define WHD_SPI_SIZE_MISMATCH WHD_RESULT_CREATE(1049) /**< Mismatch in sizes between SPI header and SDPCM header */ +#define WHD_ADDRESS_ALREADY_REGISTERED WHD_RESULT_CREATE(1050) /**< Attempt to register a multicast address twice */ +#define WHD_SDIO_RETRIES_EXCEEDED WHD_RESULT_CREATE(1051) /**< SDIO transfer failed too many times. */ +#define WHD_NULL_PTR_ARG WHD_RESULT_CREATE(1052) /**< Null Pointer argument passed to function. */ +#define WHD_THREAD_FINISH_FAIL WHD_RESULT_CREATE(1053) /**< Error deleting a thread */ +#define WHD_WAIT_ABORTED WHD_RESULT_CREATE(1054) /**< Semaphore/mutex wait has been aborted */ +#define WHD_SET_BLOCK_ACK_WINDOW_FAIL WHD_RESULT_CREATE(1055) /**< Failed to set block ack window */ +#define WHD_DELAY_TOO_SHORT WHD_RESULT_CREATE(1056) /**< Requested delay is too short */ +#define WHD_INVALID_INTERFACE WHD_RESULT_CREATE(1057) /**< Invalid interface provided */ +#define WHD_WEP_KEYLEN_BAD WHD_RESULT_CREATE(1058) /**< WEP / WEP_SHARED key length must be 5 or 13 bytes */ +#define WHD_HANDLER_ALREADY_REGISTERED WHD_RESULT_CREATE(1059) /**< EAPOL handler already registered */ +#define WHD_AP_ALREADY_UP WHD_RESULT_CREATE(1060) /**< Soft AP or P2P group owner already up */ +#define WHD_EAPOL_KEY_PACKET_M1_TIMEOUT WHD_RESULT_CREATE(1061) /**< Timeout occurred while waiting for EAPOL packet M1 from AP */ +#define WHD_EAPOL_KEY_PACKET_M3_TIMEOUT WHD_RESULT_CREATE(1062) /**< Timeout occurred while waiting for EAPOL packet M3 from APwhich may indicate incorrect WPA2/WPA passphrase */ +#define WHD_EAPOL_KEY_PACKET_G1_TIMEOUT WHD_RESULT_CREATE(1063) /**< Timeout occurred while waiting for EAPOL packet G1 from AP */ +#define WHD_EAPOL_KEY_FAILURE WHD_RESULT_CREATE(1064) /**< Unknown failure occurred during the EAPOL key handshake */ +#define WHD_MALLOC_FAILURE WHD_RESULT_CREATE(1065) /**< Memory allocation failure */ +#define WHD_ACCESS_POINT_NOT_FOUND WHD_RESULT_CREATE(1066) /**< Access point not found */ +#define WHD_RTOS_ERROR WHD_RESULT_CREATE(1067) /**< RTOS operation failed */ +#define WHD_CLM_BLOB_DLOAD_ERROR WHD_RESULT_CREATE(1068) /**< CLM blob download failed */ +#define WHD_HAL_ERROR WHD_RESULT_CREATE(1069) /**< WHD HAL Error */ +#define WHD_RTOS_STATIC_MEM_LIMIT WHD_RESULT_CREATE(1070) /**< Exceeding the RTOS static objects memory */ +#define WHD_NO_REGISTER_FUNCTION_POINTER WHD_RESULT_CREATE(1071) /**< No register function pointer */ +#define WHD_BLHS_VALIDATE_FAILED WHD_RESULT_CREATE(1072) /**< Bootloader handshake validation failed */ +#define WHD_BUS_UP_FAIL WHD_RESULT_CREATE(1073) /**< bus failed to come up */ +#define WHD_BUS_MEM_RESERVE_FAIL WHD_RESULT_CREATE(1074) /**< commonring reserve for write failed */ +#define WHD_NO_PKT_ID_AVAILABLE WHD_RESULT_CREATE(1075) /**< commonring reserve for write failed */ + +#define WLAN_ENUM_OFFSET 2000 /**< WLAN enum offset for WHD_WLAN error processing */ + +#define WHD_WLAN_ERROR WHD_RESULT_CREATE(2001) /**< Generic Error */ +#define WHD_WLAN_BADARG WHD_RESULT_CREATE(2002) /**< Bad Argument */ +#define WHD_WLAN_BADOPTION WHD_RESULT_CREATE(2003) /**< Bad option */ +#define WHD_WLAN_NOTUP WHD_RESULT_CREATE(2004) /**< Not up */ +#define WHD_WLAN_NOTDOWN WHD_RESULT_CREATE(2005) /**< Not down */ +#define WHD_WLAN_NOTAP WHD_RESULT_CREATE(2006) /**< Not AP */ +#define WHD_WLAN_NOTSTA WHD_RESULT_CREATE(2007) /**< Not STA */ +#define WHD_WLAN_BADKEYIDX WHD_RESULT_CREATE(2008) /**< BAD Key Index */ +#define WHD_WLAN_RADIOOFF WHD_RESULT_CREATE(2009) /**< Radio Off */ +#define WHD_WLAN_NOTBANDLOCKED WHD_RESULT_CREATE(2010) /**< Not band locked */ +#define WHD_WLAN_NOCLK WHD_RESULT_CREATE(2011) /**< No Clock */ +#define WHD_WLAN_BADRATESET WHD_RESULT_CREATE(2012) /**< BAD Rate valueset */ +#define WHD_WLAN_BADBAND WHD_RESULT_CREATE(2013) /**< BAD Band */ +#define WHD_WLAN_BUFTOOSHORT WHD_RESULT_CREATE(2014) /**< Buffer too short */ +#define WHD_WLAN_BUFTOOLONG WHD_RESULT_CREATE(2015) /**< Buffer too long */ +#define WHD_WLAN_BUSY WHD_RESULT_CREATE(2016) /**< Busy */ +#define WHD_WLAN_NOTASSOCIATED WHD_RESULT_CREATE(2017) /**< Not Associated */ +#define WHD_WLAN_BADSSIDLEN WHD_RESULT_CREATE(2018) /**< Bad SSID len */ +#define WHD_WLAN_OUTOFRANGECHAN WHD_RESULT_CREATE(2019) /**< Out of Range Channel */ +#define WHD_WLAN_BADCHAN WHD_RESULT_CREATE(2020) /**< Bad Channel */ +#define WHD_WLAN_BADADDR WHD_RESULT_CREATE(2021) /**< Bad Address */ +#define WHD_WLAN_NORESOURCE WHD_RESULT_CREATE(2022) /**< Not Enough Resources */ +#define WHD_WLAN_UNSUPPORTED WHD_RESULT_CREATE(2023) /**< Unsupported */ +#define WHD_WLAN_BADLEN WHD_RESULT_CREATE(2024) /**< Bad length */ +#define WHD_WLAN_NOTREADY WHD_RESULT_CREATE(2025) /**< Not Ready */ +#define WHD_WLAN_EPERM WHD_RESULT_CREATE(2026) /**< Not Permitted */ +#define WHD_WLAN_NOMEM WHD_RESULT_CREATE(2027) /**< No Memory */ +#define WHD_WLAN_ASSOCIATED WHD_RESULT_CREATE(2028) /**< Associated */ +#define WHD_WLAN_RANGE WHD_RESULT_CREATE(2029) /**< Not In Range */ +#define WHD_WLAN_NOTFOUND WHD_RESULT_CREATE(2030) /**< Not Found */ +#define WHD_WLAN_WME_NOT_ENABLED WHD_RESULT_CREATE(2031) /**< WME Not Enabled */ +#define WHD_WLAN_TSPEC_NOTFOUND WHD_RESULT_CREATE(2032) /**< TSPEC Not Found */ +#define WHD_WLAN_ACM_NOTSUPPORTED WHD_RESULT_CREATE(2033) /**< ACM Not Supported */ +#define WHD_WLAN_NOT_WME_ASSOCIATION WHD_RESULT_CREATE(2034) /**< Not WME Association */ +#define WHD_WLAN_SDIO_ERROR WHD_RESULT_CREATE(2035) /**< SDIO Bus Error */ +#define WHD_WLAN_WLAN_DOWN WHD_RESULT_CREATE(2036) /**< WLAN Not Accessible */ +#define WHD_WLAN_BAD_VERSION WHD_RESULT_CREATE(2037) /**< Incorrect version */ +#define WHD_WLAN_TXFAIL WHD_RESULT_CREATE(2038) /**< TX failure */ +#define WHD_WLAN_RXFAIL WHD_RESULT_CREATE(2039) /**< RX failure */ +#define WHD_WLAN_NODEVICE WHD_RESULT_CREATE(2040) /**< Device not present */ +#define WHD_WLAN_UNFINISHED WHD_RESULT_CREATE(2041) /**< To be finished */ +#define WHD_WLAN_NONRESIDENT WHD_RESULT_CREATE(2042) /**< access to nonresident overlay */ +#define WHD_WLAN_DISABLED WHD_RESULT_CREATE(2043) /**< Disabled in this build */ +#define WHD_WLAN_NOFUNCTION WHD_RESULT_CREATE(2044) /**< Function pointer not provided */ +#define WHD_WLAN_INVALID WHD_RESULT_CREATE(2045) /**< Not valid */ +#define WHD_WLAN_NOBAND WHD_RESULT_CREATE(2046) /**< No Band */ /** * type definition for whd_buffer_t @@ -931,16 +1025,17 @@ typedef whd_buffer_t whd_buffer_queue_ptr_t; /** * Structure for storing AP information */ -typedef struct whd_ap_info { - whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ - whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ - int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ - uint32_t max_data_rate; /**< Maximum data rate in kilobits/s */ - whd_bss_type_t bss_type; /**< Network type */ - whd_security_t security; /**< Security type */ - uint8_t channel; /**< Radio channel that the AP beacon was received on */ - whd_802_11_band_t band; /**< Radio band */ - struct whd_ap_info *next; /**< Pointer to the next scan result */ +typedef struct whd_ap_info +{ + whd_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ + whd_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ + int16_t signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ + uint32_t max_data_rate; /**< Maximum data rate in kilobits/s */ + whd_bss_type_t bss_type; /**< Network type */ + whd_security_t security; /**< Security type */ + uint8_t channel; /**< Radio channel that the AP beacon was received on */ + whd_802_11_band_t band; /**< Radio band */ + struct whd_ap_info *next; /**< Pointer to the next scan result */ } whd_ap_info_t; /** @@ -948,108 +1043,293 @@ typedef struct whd_ap_info { */ typedef struct { - uint32_t count; /**< Number of MAC addresses in the list */ - whd_mac_t mac_list[1]; /**< Variable length array of MAC addresses */ + uint32_t count; /**< Number of MAC addresses in the list */ + whd_mac_t mac_list[1]; /**< Variable length array of MAC addresses */ } whd_maclist_t; #pragma pack() +/** + * Structure describing a list of PMKID + */ +typedef struct _pmkid +{ + whd_mac_t BSSID; + uint8_t PMKID[PMKID_LEN]; +} pmkid_t; + +typedef struct _pmkid_list +{ + uint32_t npmkid; + pmkid_t pmkid[1]; +} pmkid_list_t; + +/** + * Structure used by both dongle and host + * dongle asks host to start auth(SAE), host updates auth status to dongle. + */ +typedef struct whd_auth_req_status +{ + uint16_t flags; + whd_mac_t peer_mac; /* peer mac address */ + uint32_t ssid_len; + uint8_t ssid[SSID_NAME_SIZE]; + uint8_t pmkid[PMKID_LEN]; +} whd_auth_req_status_t; + /** * Time value in milliseconds */ -typedef time_t whd_time_t; +typedef cy_time_t whd_time_t; /** * Structure for storing a WEP key */ typedef struct { - uint8_t index; /**< WEP key index [0/1/2/3] */ - uint8_t length; /**< WEP key length. Either 5 bytes (40-bits) or 13-bytes (104-bits) */ - uint8_t data[32]; /**< WEP key as values NOT characters */ + uint8_t index; /**< WEP key index [0/1/2/3] */ + uint8_t length; /**< WEP key length. Either 5 bytes (40-bits) or 13-bytes (104-bits) */ + uint8_t data[32]; /**< WEP key as values NOT characters */ } whd_wep_key_t; +/** + * Structure for management frame(auth) params + */ +typedef struct whd_auth_params +{ + uint32_t version; + uint32_t dwell_time; + uint16_t len; /* Len includes Len(MAC Headers) + Len(Contents) */ + uint16_t fc; + uint16_t channel; + whd_mac_t da; + whd_mac_t bssid; + uint32_t packetId; + uint8_t data[1]; /* It contains MAC Headers + Contexts*/ +} whd_auth_params_t; + +/** + * Structure for he_omi params + */ +typedef struct +{ + uint8_t rx_nss; + uint8_t chnl_wdth; + uint8_t ul_mu_dis; + uint8_t tx_nsts; + uint8_t er_su_dis; + uint8_t dl_mu_resound; + uint8_t ul_mu_data_dis; + uint8_t reserved; +} whd_he_omi_params_t; + +/** + * Structure for itwt_setup params + */ +typedef struct +{ + uint8_t setup_cmd; + uint8_t trigger; + uint8_t flow_type; /* Un-Announced or Announced */ + uint8_t flow_id; /* 0xFF means any */ + uint8_t wake_duration; /* Minimum TWT wake duration in units of 256 usec */ + uint8_t exponent; /* Used to compute TWT wake interval */ + uint16_t mantissa; /* Used to compute TWT wake interval */ + uint32_t wake_time_h; /* target wake time - BSS TSF (us) */ + uint32_t wake_time_l; +} whd_itwt_setup_params_t; + +/** + * Structure for btwt_join params + */ +typedef struct +{ + uint8_t setup_cmd; + uint8_t trigger; + uint8_t flow_type; /* Un-Announced or Announced */ + uint8_t bid; /* bTWT ID */ + uint8_t wake_duration; /* Minimum TWT wake duration in units of 256 usec */ + uint8_t exponent; /* Used to compute TWT wake interval */ + uint16_t mantissa; /* Used to compute TWT wake interval */ + uint32_t wake_time_h; /* target wake time - BSS TSF (us) */ + uint32_t wake_time_l; +} whd_btwt_join_params_t; + +/** + * Structure for twt_teardown params + */ +typedef struct +{ + uint8_t negotiation_type; + uint8_t flow_id; + uint8_t bcast_twt_id; + uint8_t teardown_all_twt; +} whd_twt_teardown_params_t; + +/** + * Structure for btwt_config params + */ +typedef struct +{ + uint8_t setup_cmd; + uint8_t trigger; + uint8_t flow_type; /* Un-Announced or Announced */ + uint8_t bid; /* bTWT ID */ + uint8_t wake_duration; /* Minimum TWT wake duration in units of 256 usec */ + uint8_t exponent; /* Used to compute TWT wake interval */ + uint16_t mantissa; /* Used to compute TWT wake interval */ +} whd_btwt_config_params_t; + +/** + * Structure for twt_information params + */ +typedef struct +{ + uint8_t flow_id; + uint8_t suspend; /* 1: suspend, 0: resume */ + uint8_t resume_time; /* 0 ~ 4095 seconds */ + uint8_t reserved; +} whd_twt_information_params_t; + +/* MBO attributes as defined in the mbo spec */ +enum { + MBO_ATTR_MBO_AP_CAPABILITY = 1, + MBO_ATTR_NON_PREF_CHAN_REPORT = 2, + MBO_ATTR_CELL_DATA_CAP = 3, + MBO_ATTR_ASSOC_DISALLOWED = 4, + MBO_ATTR_CELL_DATA_CONN_PREF = 5, + MBO_ATTR_TRANS_REASON_CODE = 6, + MBO_ATTR_TRANS_REJ_REASON_CODE = 7, + MBO_ATTR_ASSOC_RETRY_DELAY = 8 +}; + +/** + * Structure for mbo add_chan_pref params + */ +typedef struct +{ + uint8_t opclass; + uint8_t chan; + uint8_t pref; /* 0: non operable band/chan, 1: non preferred band/chan, 255: preferred band/chan */ + uint8_t reason; +} whd_mbo_add_chan_pref_params_t; + +/** + * Structure for mbo del_chan_pref params + */ +typedef struct +{ + uint8_t opclass; + uint8_t chan; +} whd_mbo_del_chan_pref_params_t; + /** * Structure for Out-of-band interrupt config parameters which can be set by application during whd power up */ -typedef struct whd_oob_config { - cyhal_gpio_t host_oob_pin; /**< Host-side GPIO pin selection */ - uint8_t dev_gpio_sel; /**< WiFi device-side GPIO pin selection (must be zero) */ - whd_bool_t is_falling_edge; /**< Interrupt trigger (polarity) */ - uint8_t intr_priority; /**< OOB interrupt priority */ +typedef struct whd_oob_config +{ + cyhal_gpio_t host_oob_pin; /**< Host-side GPIO pin selection */ + cyhal_gpio_drive_mode_t drive_mode; /**< Host-side GPIO pin drive mode */ + whd_bool_t init_drive_state; /**< Host-side GPIO pin initial drive state */ + uint8_t dev_gpio_sel; /**< WiFi device-side GPIO pin selection (must be zero) */ + whd_bool_t is_falling_edge; /**< Interrupt trigger (polarity) */ + uint8_t intr_priority; /**< OOB interrupt priority */ } whd_oob_config_t; /** * Structure for SDIO config parameters which can be set by application during whd power up */ -typedef struct whd_sdio_config { - /* Bus config */ - whd_bool_t sdio_1bit_mode; /**< Default is false, means SDIO operates under 4 bit mode */ - whd_bool_t high_speed_sdio_clock; /**< Default is false, means SDIO operates in normal clock rate */ - whd_oob_config_t oob_config; /**< Out-of-band interrupt configuration (required when bus can sleep) */ +typedef struct whd_sdio_config +{ + /* Bus config */ + whd_bool_t sdio_1bit_mode; /**< Default is false, means SDIO operates under 4 bit mode */ + whd_bool_t high_speed_sdio_clock; /**< Default is false, means SDIO operates in normal clock rate */ + whd_oob_config_t oob_config; /**< Out-of-band interrupt configuration (required when bus can sleep) */ } whd_sdio_config_t; /** * Structure for SPI config parameters which can be set by application during whd power up */ -typedef struct whd_spi_config { - /* Bus config */ - whd_bool_t is_spi_normal_mode; /**< Default is false */ - whd_oob_config_t oob_config; /**< Out-of-band interrupt configuration */ +typedef struct whd_spi_config +{ + /* Bus config */ + whd_bool_t is_spi_normal_mode; /**< Default is false */ + whd_oob_config_t oob_config; /**< Out-of-band interrupt configuration */ } whd_spi_config_t; /** - * Structure for M2M config parameters which can be set by application during whd power up + * Structure for USB config parameters which can be set by application during whd power up */ -typedef struct whd_m2m_config { +typedef struct whd_usb_config { /* Bus config */ - whd_bool_t is_normal_mode; /**< Default is false */ + const char *path; /**< Path to USB device */ +} whd_usb_config_t; + +/** + * Structure for M2M config parameters which can be set by application during whd power up + */ +typedef struct whd_m2m_config +{ + /* Bus config */ + whd_bool_t is_normal_mode; /**< Default is false */ } whd_m2m_config_t; +/** + * Structure for OCI config parameters which can be set by application during whd power up + */ +typedef struct whd_oci_config +{ + /* Bus config */ + whd_bool_t is_normal_mode; /**< Default is false */ +} whd_oci_config_t; /** * Enumeration of applicable packet mask bits for custom Information Elements (IEs) */ -typedef enum { - VENDOR_IE_BEACON = 0x1, /**< Denotes beacon packet */ - VENDOR_IE_PROBE_RESPONSE = 0x2, /**< Denotes probe response packet */ - VENDOR_IE_ASSOC_RESPONSE = 0x4, /**< Denotes association response packet */ - VENDOR_IE_AUTH_RESPONSE = 0x8, /**< Denotes authentication response packet */ - VENDOR_IE_PROBE_REQUEST = 0x10, /**< Denotes probe request packet */ - VENDOR_IE_ASSOC_REQUEST = 0x20, /**< Denotes association request packet */ - VENDOR_IE_CUSTOM = 0x100, /**< Denotes a custom IE(Information Element) identifier */ - VENDOR_IE_UNKNOWN = ~(VENDOR_IE_BEACON | VENDOR_IE_PROBE_RESPONSE | VENDOR_IE_ASSOC_RESPONSE | - VENDOR_IE_AUTH_RESPONSE | VENDOR_IE_PROBE_REQUEST | VENDOR_IE_ASSOC_REQUEST | - VENDOR_IE_CUSTOM) +typedef enum +{ + VENDOR_IE_BEACON = 0x1, /**< Denotes beacon packet */ + VENDOR_IE_PROBE_RESPONSE = 0x2, /**< Denotes probe response packet */ + VENDOR_IE_ASSOC_RESPONSE = 0x4, /**< Denotes association response packet */ + VENDOR_IE_AUTH_RESPONSE = 0x8, /**< Denotes authentication response packet */ + VENDOR_IE_PROBE_REQUEST = 0x10, /**< Denotes probe request packet */ + VENDOR_IE_ASSOC_REQUEST = 0x20, /**< Denotes association request packet */ + VENDOR_IE_CUSTOM = 0x100, /**< Denotes a custom IE(Information Element) identifier */ + VENDOR_IE_UNKNOWN = ~(VENDOR_IE_BEACON | VENDOR_IE_PROBE_RESPONSE | VENDOR_IE_ASSOC_RESPONSE | \ + VENDOR_IE_AUTH_RESPONSE | VENDOR_IE_PROBE_REQUEST | VENDOR_IE_ASSOC_REQUEST | \ + VENDOR_IE_CUSTOM) } whd_ie_packet_flag_t; /** * Structure for LE Scan parameters */ -typedef struct whd_btc_lescan_params { - uint16_t priority; /**< LE scan priority */ - uint16_t duty_cycle; /**< LE scan duty cycle */ - uint16_t max_win; /**< LE Max Scan window */ - uint16_t int_grant; /**< LE Small Interval Grant */ - uint16_t scan_int; /**< LE scan interval */ - uint16_t scan_win; /**< LE scan Window */ +typedef struct whd_btc_lescan_params +{ + uint16_t priority; /**< LE scan priority */ + uint16_t duty_cycle; /**< LE scan duty cycle */ + uint16_t max_win; /**< LE Max Scan window */ + uint16_t int_grant; /**< LE Small Interval Grant */ + uint16_t scan_int; /**< LE scan interval */ + uint16_t scan_win; /**< LE scan Window */ } whd_btc_lescan_params_t; /** * Structure for coex config parameters which can be set by application */ -typedef struct whd_coex_config { - whd_btc_lescan_params_t le_scan_params; /**< LE Scan Parameters */ +typedef struct whd_coex_config +{ + whd_btc_lescan_params_t le_scan_params; /**< LE Scan Parameters */ } whd_coex_config_t; -#define PORT_FILTER_LEN 26 /**< Port filter len */ -#define PACKET_FILTER_LIST_BUFFER_MAX_LEN 1000 /**< Packet filter buffer max len */ +#define PORT_FILTER_LEN 26 /**< Port filter len */ +#define PACKET_FILTER_LIST_BUFFER_MAX_LEN 1000 /**< Packet filter buffer max len */ /** * Enumeration of packet filter rules */ -typedef enum { - WHD_PACKET_FILTER_RULE_POSITIVE_MATCHING = 0, /**< Specifies that a filter should match a given pattern */ - WHD_PACKET_FILTER_RULE_NEGATIVE_MATCHING = 1 /**< Specifies that a filter should NOT match a given pattern */ +typedef enum +{ + WHD_PACKET_FILTER_RULE_POSITIVE_MATCHING = 0, /**< Specifies that a filter should match a given pattern */ + WHD_PACKET_FILTER_RULE_NEGATIVE_MATCHING = 1 /**< Specifies that a filter should NOT match a given pattern */ } whd_packet_filter_rule_t; /** @@ -1057,18 +1337,122 @@ typedef enum { */ typedef struct { - uint32_t id; /**< Unique identifier for a packet filter item */ - whd_packet_filter_rule_t rule; /**< Filter matches are either POSITIVE or NEGATIVE matching */ - uint16_t offset; /**< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ - uint16_t mask_size; /**< Size of the mask in bytes */ - uint8_t *mask; /**< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ - uint8_t *pattern; /**< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ - whd_bool_t enabled_status; /**< When returned from wwd_wifi_get_packet_filters, indicates if the filter is enabled */ + uint32_t id; /**< Unique identifier for a packet filter item */ + whd_packet_filter_rule_t rule; /**< Filter matches are either POSITIVE or NEGATIVE matching */ + uint16_t offset; /**< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ + uint16_t mask_size; /**< Size of the mask in bytes */ + uint8_t *mask; /**< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ + uint8_t *pattern; /**< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ + whd_bool_t enabled_status; /**< When returned from wwd_wifi_get_packet_filters, indicates if the filter is enabled */ } whd_packet_filter_t; -#define TKO_DATA_OFFSET offsetof(wl_tko_t, data) /**< TKO data offset */ +typedef struct whd_keep_alive +{ + uint32_t period_msec; + uint16_t len_bytes; + uint8_t *data; +} whd_keep_alive_t; + +#define TLS_MAX_KEY_LENGTH 48 +#define TLS_MAX_MAC_KEY_LENGTH 32 +#define TLS_MAX_IV_LENGTH 32 +#define TLS_MAX_SEQUENCE_LENGTH 8 +#define TLS_MAX_PAYLOAD_LEN 1024 + +/* Secured WOWL packet was encrypted, need decrypted before check filter match */ +typedef enum wl_wowl_tls_mode{ + TLS_MODE_SSWOWL, + TLS_MODE_MIWOWL +} wl_wowl_tls_mode_t; + +/* add supported cipher suite according rfc5246#appendix-A.5 */ +typedef enum { + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F, + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 +} Cipher_Suite_e; + +typedef enum { + CONTENTTYPE_CHANGE_CIPHER_SPEC = 20, + CONTENTTYPE_ALERT, + CONTENTTYPE_HANDSHAKE, + CONTENTTYPE_APPLICATION_DATA +} ContentType_e; + +typedef enum { + COMPRESSIONMETHOD_NULL = 0 +} CompressionMethod_e; + +typedef enum { + BULKCIPHERALGORITHM_NULL, + BULKCIPHERALGORITHM_RC4, + BULKCIPHERALGORITHM_3DES, + BULKCIPHERALGORITHM_AES +} BulkCipherAlgorithm_e; + +typedef enum { + CIPHERTYPE_STREAM = 1, + CIPHERTYPE_BLOCK, + CIPHERTYPE_AEAD +} CipherType_e; + +typedef enum { + MACALGORITHM_NULL, + MACALGORITHM_HMAC_MD5, + MACALGORITHM_HMAC_SHA1, + MACALGORITHM_HMAC_SHA256, + MACALGORITHM_HMAC_SHA384, + MACALGORITHM_HMAC_SHA512 +} MACAlgorithm_e; + +typedef struct { + uint8_t major; + uint8_t minor; + uint8_t padding[2]; +} ProtocolVersion; + +#define ETHER_ADDR_LEN 6 +#define IPV4_ADDR_LEN 4 + +struct tls_param_info{ + ProtocolVersion version; + uint32_t compression_algorithm; + uint32_t cipher_algorithm; + uint32_t cipher_type; + uint32_t mac_algorithm; + uint32_t keepalive_interval; /* keepalive interval, in seconds */ + uint8_t read_master_key[TLS_MAX_KEY_LENGTH]; + uint32_t read_master_key_len; + uint8_t read_iv[TLS_MAX_IV_LENGTH]; + uint32_t read_iv_len; + uint8_t read_mac_key[TLS_MAX_MAC_KEY_LENGTH]; + uint32_t read_mac_key_len; + uint8_t read_sequence[TLS_MAX_SEQUENCE_LENGTH]; + uint32_t read_sequence_len; + uint8_t write_master_key[TLS_MAX_KEY_LENGTH]; + uint32_t write_master_key_len; + uint8_t write_iv[TLS_MAX_IV_LENGTH]; + uint32_t write_iv_len; + uint8_t write_mac_key[TLS_MAX_MAC_KEY_LENGTH]; + uint32_t write_mac_key_len; + uint8_t write_sequence[TLS_MAX_SEQUENCE_LENGTH]; + uint32_t write_sequence_len; + uint32_t tcp_ack_num; + uint32_t tcp_seq_num; + uint8_t local_ip[IPV4_ADDR_LEN]; + uint8_t remote_ip[IPV4_ADDR_LEN]; + uint16_t local_port; + uint16_t remote_port; + uint8_t local_mac_addr[ETHER_ADDR_LEN]; + uint8_t remote_mac_addr[ETHER_ADDR_LEN]; + uint32_t app_syncid; + uint8_t payload[TLS_MAX_PAYLOAD_LEN]; + uint16_t payload_len; + bool encrypt_then_mac; +}; + +#define TKO_DATA_OFFSET offsetof(wl_tko_t, data) /**< TKO data offset */ #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* ifndef INCLUDED_WHD_TYPES_H_ */ diff --git a/wi-fi/whd/whd_types_int.h b/wi-fi/whd/whd_types_int.h index b2541a0d..bef6dc5a 100644 --- a/wi-fi/whd/whd_types_int.h +++ b/wi-fi/whd/whd_types_int.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,8 +27,12 @@ #include #include +#include "whd_types.h" +#include "whd.h" + #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /****************************************************** @@ -37,163 +41,143 @@ extern "C" { /** * The size of an Ethernet header */ -#define WHD_ETHERNET_SIZE (14) +#define WHD_ETHERNET_SIZE (14) /** * Ethernet Ethertypes */ -#define WHD_ETHERTYPE_IPv4 0x0800 -#define WHD_ETHERTYPE_IPv6 0x86DD -#define WHD_ETHERTYPE_ARP 0x0806 -#define WHD_ETHERTYPE_RARP 0x8035 -#define WHD_ETHERTYPE_EAPOL 0x888E -#define WHD_ETHERTYPE_DOT1AS 0x88F7 -#define WHD_ETHERTYPE_8021Q 0x8100 +#define WHD_ETHERTYPE_IPv4 0x0800 +#define WHD_ETHERTYPE_IPv6 0x86DD +#define WHD_ETHERTYPE_ARP 0x0806 +#define WHD_ETHERTYPE_RARP 0x8035 +#define WHD_ETHERTYPE_EAPOL 0x888E +#define WHD_ETHERTYPE_DOT1AS 0x88F7 +#define WHD_ETHERTYPE_8021Q 0x8100 /* bss_info_cap_t flags */ -#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ -#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ -#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info received on channel (vs offchannel) */ -#define WL_BSS_FLAGS_HS20 0x08 /* hotspot 2.0 capable */ -#define WL_BSS_FLAGS_RSSI_INVALID 0x10 /* BSS contains invalid RSSI */ -#define WL_BSS_FLAGS_RSSI_INACCURATE 0x20 /* BSS contains inaccurate RSSI */ -#define WL_BSS_FLAGS_SNR_INVALID 0x40 /* BSS contains invalid SNR */ -#define WL_BSS_FLAGS_NF_INVALID 0x80 /* BSS contains invalid noise floor */ - -#define HT_CAPABILITIES_IE_LENGTH (26) -#define DOT11_OUI_LEN (3) /** Length in bytes of 802.11 OUI*/ - -#define WHD_ETHER_ADDR_STR_LEN (18) -#define WHD_ETHER_ADDR_LEN (6) - -#define CHECK_IOCTL_BUFFER(buff) \ - if (buff == \ - NULL) { \ - WPRINT_WHD_ERROR(("Buffer alloc failed in function %s at line %d \n", \ - __func__, __LINE__)); \ - return WHD_BUFFER_ALLOC_FAIL; \ - } -#define CHECK_PACKET_NULL(buff, err) \ - if (buff == \ - NULL) { \ - WPRINT_WHD_ERROR(("No register function pointer in %s at line %d \n", \ - __func__, __LINE__)); \ - return err; \ - } -#define CHECK_PACKET_WITH_NULL_RETURN(buff) \ - if (buff == \ - NULL) { \ - WPRINT_WHD_ERROR(( \ - "No register function pointer in %s at line %d \n", \ - __func__, __LINE__)); \ - return; \ - } - -#define CHECK_RETURN(expr) \ - { \ - whd_result_t check_res = (expr); \ - if (check_res != WHD_SUCCESS) { \ - WPRINT_WHD_ERROR(("Function %s failed at line %d checkres = %u \n", \ - __func__, __LINE__, \ - (unsigned int)check_res)); \ - return check_res; \ - } \ - } - -#define CHECK_RETURN_UNSUPPORTED_OK(expr) \ - { \ - whd_result_t check_res = (expr); \ - if (check_res != WHD_SUCCESS) { \ - return check_res; \ - } \ - } -#define CHECK_RETURN_UNSUPPORTED_CONTINUE(expr) \ - { \ - whd_result_t check_res = (expr); \ - if (check_res != WHD_SUCCESS && check_res != WHD_WLAN_UNSUPPORTED) { \ - return check_res; \ - } \ - } -#define RETURN_WITH_ASSERT(expr) \ - { \ - whd_result_t check_res = (expr); \ - whd_assert("Command failed\n", check_res == WHD_SUCCESS); \ - return check_res; \ - } - -#define CHECK_RETURN_IGNORE(expr) \ - { \ - whd_result_t check_res = (expr); \ - if (check_res != WHD_SUCCESS) { \ - } \ - } - -#define CHECK_IFP_NULL(ifp) \ - if (ifp == \ - NULL) { \ - WPRINT_WHD_ERROR(( \ - "Interface is not up/NULL and failed in function %s at line %d \n", \ - __func__, __LINE__)); \ - return WHD_UNKNOWN_INTERFACE; \ - } - -#define CHECK_DRIVER_NULL(driver) \ - if (driver == \ - NULL) { \ - WPRINT_WHD_ERROR(( \ - "WHD driver is not up/NULL and failed in function %s at line %d \n", \ - __func__, __LINE__)); \ - return WHD_DOES_NOT_EXIST; \ - } - -#define MIN_OF(x, y) ((x) < (y) ? (x) : (y)) -#define MAX_OF(x, y) ((x) > (y) ? (x) : (y)) +#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ +#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ +#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info received on channel (vs offchannel) */ +#define WL_BSS_FLAGS_HS20 0x08 /* hotspot 2.0 capable */ +#define WL_BSS_FLAGS_RSSI_INVALID 0x10 /* BSS contains invalid RSSI */ +#define WL_BSS_FLAGS_RSSI_INACCURATE 0x20 /* BSS contains inaccurate RSSI */ +#define WL_BSS_FLAGS_SNR_INVALID 0x40 /* BSS contains invalid SNR */ +#define WL_BSS_FLAGS_NF_INVALID 0x80 /* BSS contains invalid noise floor */ + +#define HT_CAPABILITIES_IE_LENGTH (26) +#define DOT11_OUI_LEN (3)/** Length in bytes of 802.11 OUI*/ +#define DOT11_MGMT_HDR_LEN (24) /* dot11 management header len */ + +#define WHD_ETHER_ADDR_STR_LEN (18) +#define WHD_ETHER_ADDR_LEN (6) + +#define CHECK_IOCTL_BUFFER(buff) if (buff == \ + NULL){ WPRINT_WHD_ERROR( ("Buffer alloc failed in function %s at line %d \n", \ + __func__, __LINE__) ); \ + return WHD_BUFFER_ALLOC_FAIL; } +#define CHECK_PACKET_NULL(buff, err) if (buff == \ + NULL){ WPRINT_WHD_ERROR( ("No register function pointer in %s at line %d \n", \ + __func__, __LINE__) ); \ + return err;} +#define CHECK_PACKET_WITH_NULL_RETURN(buff) if (buff == \ + NULL){ WPRINT_WHD_ERROR( ( \ + "No register function pointer in %s at line %d \n", \ + __func__, __LINE__) ); \ + return;} + +#define CHECK_RETURN(expr) { \ + whd_result_t check_res = (expr); \ + if (check_res != WHD_SUCCESS) \ + { \ + WPRINT_WHD_ERROR( ("Function %s failed at line %d checkres = %u \n", \ + __func__, __LINE__, \ + (unsigned int)check_res) ); \ + return check_res; \ + } \ +} + +#define CHECK_RETURN_UNSUPPORTED_OK(expr) { whd_result_t check_res = (expr); \ + if (check_res != WHD_SUCCESS) \ + { \ + return check_res; \ + } \ +} +#define CHECK_RETURN_UNSUPPORTED_CONTINUE(expr) { whd_result_t check_res = (expr); \ + if (check_res != WHD_SUCCESS && check_res != WHD_WLAN_UNSUPPORTED) \ + { \ + return check_res; \ + } \ +} +#define RETURN_WITH_ASSERT(expr) { whd_result_t check_res = (expr); \ + whd_assert("Command failed\n", check_res == WHD_SUCCESS); \ + return check_res; } + +#define CHECK_RETURN_IGNORE(expr) { whd_result_t check_res = (expr); \ + if (check_res != WHD_SUCCESS) \ + { \ + } \ +} + +#define CHECK_IFP_NULL(ifp) if (ifp == \ + NULL){ WPRINT_WHD_ERROR( ( \ + "Interface is not up/NULL and failed in function %s at line %d \n", \ + __func__, __LINE__) ); \ + return WHD_UNKNOWN_INTERFACE; } + +#define CHECK_DRIVER_NULL(driver) if (driver == \ + NULL){ WPRINT_WHD_ERROR( ( \ + "WHD driver is not up/NULL and failed in function %s at line %d \n", \ + __func__, __LINE__) ); \ + return WHD_DOES_NOT_EXIST; } + +#define MIN_OF(x, y) ( (x) < (y) ? (x) : (y) ) +#define MAX_OF(x, y) ( (x) > (y) ? (x) : (y) ) #ifndef ROUND_UP -#define ROUND_UP(x, y) ((x) % (y) ? (x) + (y) - ((x) % (y)) : (x)) +#define ROUND_UP(x, y) ( (x) % (y) ? (x) + (y) - ( (x) % (y) ) : (x) ) #endif #ifndef DIV_ROUND_UP -#define DIV_ROUND_UP(m, n) (((m) + (n)-1) / (n)) +#define DIV_ROUND_UP(m, n) ( ( (m) + (n) - 1 ) / (n) ) #endif -#define WHD_WRITE_16(pointer, value) (*((uint16_t *)pointer) = value) -#define WHD_WRITE_32(pointer, value) (*((uint32_t *)pointer) = value) -#define WHD_READ_16(pointer) *((uint16_t *)pointer) -#define WHD_READ_32(pointer) *((uint32_t *)pointer) +#define WHD_WRITE_16(pointer, value) (*( (uint16_t *)pointer ) = value) +#define WHD_WRITE_32(pointer, value) (*( (uint32_t *)pointer ) = value) +#define WHD_READ_16(pointer) *( (uint16_t *)pointer ) +#define WHD_READ_32(pointer) *( (uint32_t *)pointer ) /** * Macro for checking for NULL MAC addresses */ -#define NULL_MAC(a) (((((unsigned char *)a)[0]) == 0) && \ - ((((unsigned char *)a)[1]) == 0) && \ - ((((unsigned char *)a)[2]) == 0) && \ - ((((unsigned char *)a)[3]) == 0) && \ - ((((unsigned char *)a)[4]) == 0) && \ - ((((unsigned char *)a)[5]) == 0)) +#define NULL_MAC(a) ( ( ( ( (unsigned char *)a )[0] ) == 0 ) && \ + ( ( ( (unsigned char *)a )[1] ) == 0 ) && \ + ( ( ( (unsigned char *)a )[2] ) == 0 ) && \ + ( ( ( (unsigned char *)a )[3] ) == 0 ) && \ + ( ( ( (unsigned char *)a )[4] ) == 0 ) && \ + ( ( ( (unsigned char *)a )[5] ) == 0 ) ) /** * Macro for checking for Broadcast address */ -#define BROADCAST_ID(a) (((((unsigned char *)a)[0]) == 255) && \ - ((((unsigned char *)a)[1]) == 255) && \ - ((((unsigned char *)a)[2]) == 255) && \ - ((((unsigned char *)a)[3]) == 255) && \ - ((((unsigned char *)a)[4]) == 255) && \ - ((((unsigned char *)a)[5]) == 255)) +#define BROADCAST_ID(a) ( ( ( ( (unsigned char *)a )[0] ) == 255 ) && \ + ( ( ( (unsigned char *)a )[1] ) == 255 ) && \ + ( ( ( (unsigned char *)a )[2] ) == 255 ) && \ + ( ( ( (unsigned char *)a )[3] ) == 255 ) && \ + ( ( ( (unsigned char *)a )[4] ) == 255 ) && \ + ( ( ( (unsigned char *)a )[5] ) == 255 ) ) /* Suppress unused variable warning occurring due to an assert which is disabled in release mode */ -#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ((void)(x)) +#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ( (void)(x) ) /* Suppress unused parameter warning */ -#define UNUSED_PARAMETER(x) ((void)(x)) +#define UNUSED_PARAMETER(x) ( (void)(x) ) /* Suppress unused variable warning */ -#define UNUSED_VARIABLE(x) ((void)(x)) +#define UNUSED_VARIABLE(x) ( (void)(x) ) -#if defined(__IAR_SYSTEMS_ICC__) +#if defined (__IAR_SYSTEMS_ICC__) #define DISABLE_COMPILER_WARNING(x) _Pragma(#x) -#define ENABLE_COMPILER_WARNING(x) _Pragma(#x) +#define ENABLE_COMPILER_WARNING(x) _Pragma(#x) #else #define DISABLE_COMPILER_WARNING(x) #define ENABLE_COMPILER_WARNING(x) @@ -211,150 +195,185 @@ extern "C" { * Structures and Enumerations ******************************************************/ #pragma pack(1) + +#ifndef PROTO_MSGBUF +typedef struct +{ + whd_buffer_queue_ptr_t queue_next; + char bus_header[MAX_BUS_HEADER_SIZE]; +} whd_buffer_header_t; +#else typedef struct { - whd_buffer_queue_ptr_t queue_next; - char bus_header[MAX_BUS_HEADER_SIZE]; + whd_buffer_queue_ptr_t queue_next; + char pad[2]; } whd_buffer_header_t; +#endif /* PROTO_MSGBUF */ + #pragma pack() /* 802.11 Information Element Identification Numbers (as per section 8.4.2.1 of 802.11-2012) */ -typedef enum { - DOT11_IE_ID_SSID = 0, - DOT11_IE_ID_SUPPORTED_RATES = 1, - DOT11_IE_ID_FH_PARAMETER_SET = 2, - DOT11_IE_ID_DSSS_PARAMETER_SET = 3, - DOT11_IE_ID_CF_PARAMETER_SET = 4, - DOT11_IE_ID_TIM = 5, - DOT11_IE_ID_IBSS_PARAMETER_SET = 6, - DOT11_IE_ID_COUNTRY = 7, - DOT11_IE_ID_HOPPING_PATTERN_PARAMETERS = 8, - DOT11_IE_ID_HOPPING_PATTERN_TABLE = 9, - DOT11_IE_ID_REQUEST = 10, - DOT11_IE_ID_BSS_LOAD = 11, - DOT11_IE_ID_EDCA_PARAMETER_SET = 12, - DOT11_IE_ID_TSPEC = 13, - DOT11_IE_ID_TCLAS = 14, - DOT11_IE_ID_SCHEDULE = 15, - DOT11_IE_ID_CHALLENGE_TEXT = 16, - /* 17-31 Reserved */ - DOT11_IE_ID_POWER_CONSTRAINT = 32, - DOT11_IE_ID_POWER_CAPABILITY = 33, - DOT11_IE_ID_TPC_REQUEST = 34, - DOT11_IE_ID_TPC_REPORT = 35, - DOT11_IE_ID_SUPPORTED_CHANNELS = 36, - DOT11_IE_ID_CHANNEL_SWITCH_ANNOUNCEMENT = 37, - DOT11_IE_ID_MEASUREMENT_REQUEST = 38, - DOT11_IE_ID_MEASUREMENT_REPORT = 39, - DOT11_IE_ID_QUIET = 40, - DOT11_IE_ID_IBSS_DFS = 41, - DOT11_IE_ID_ERP = 42, - DOT11_IE_ID_TS_DELAY = 43, - DOT11_IE_ID_TCLAS_PROCESSING = 44, - DOT11_IE_ID_HT_CAPABILITIES = 45, - DOT11_IE_ID_QOS_CAPABILITY = 46, - /* 47 Reserved */ - DOT11_IE_ID_RSN = 48, - /* 49 Reserved */ - DOT11_IE_ID_EXTENDED_SUPPORTED_RATES = 50, - DOT11_IE_ID_AP_CHANNEL_REPORT = 51, - DOT11_IE_ID_NEIGHBOR_REPORT = 52, - DOT11_IE_ID_RCPI = 53, - DOT11_IE_ID_MOBILITY_DOMAIN = 54, - DOT11_IE_ID_FAST_BSS_TRANSITION = 55, - DOT11_IE_ID_TIMEOUT_INTERVAL = 56, - DOT11_IE_ID_RIC_DATA = 57, - DOT11_IE_ID_DSE_REGISTERED_LOCATION = 58, - DOT11_IE_ID_SUPPORTED_OPERATING_CLASSES = 59, - DOT11_IE_ID_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT = 60, - DOT11_IE_ID_HT_OPERATION = 61, - DOT11_IE_ID_SECONDARY_CHANNEL_OFFSET = 62, - DOT11_IE_ID_BSS_AVERAGE_ACCESS_DELAY = 63, - DOT11_IE_ID_ANTENNA = 64, - DOT11_IE_ID_RSNI = 65, - DOT11_IE_ID_MEASUREMENT_PILOT_TRANSMISSION = 66, - DOT11_IE_ID_BSS_AVAILABLE_ADMISSION_CAPACITY = 67, - DOT11_IE_ID_BSS_AC_ACCESS_DELAY = 68, - DOT11_IE_ID_TIME_ADVERTISEMENT = 69, - DOT11_IE_ID_RM_ENABLED_CAPABILITIES = 70, - DOT11_IE_ID_MULTIPLE_BSSID = 71, - DOT11_IE_ID_20_40_BSS_COEXISTENCE = 72, - DOT11_IE_ID_20_40_BSS_INTOLERANT_CHANNEL_REPORT = 73, - DOT11_IE_ID_OVERLAPPING_BSS_SCAN_PARAMETERS = 74, - DOT11_IE_ID_RIC_DESCRIPTOR = 75, - DOT11_IE_ID_MANAGEMENT_MIC = 76, - DOT11_IE_ID_EVENT_REQUEST = 78, - DOT11_IE_ID_EVENT_REPORT = 79, - DOT11_IE_ID_DIAGNOSTIC_REQUEST = 80, - DOT11_IE_ID_DIAGNOSTIC_REPORT = 81, - DOT11_IE_ID_LOCATION_PARAMETERS = 82, - DOT11_IE_ID_NONTRANSMITTED_BSSID_CAPABILITY = 83, - DOT11_IE_ID_SSID_LIST = 84, - DOT11_IE_ID_MULTIPLE_BSSID_INDEX = 85, - DOT11_IE_ID_FMS_DESCRIPTOR = 86, - DOT11_IE_ID_FMS_REQUEST = 87, - DOT11_IE_ID_FMS_RESPONSE = 88, - DOT11_IE_ID_QOS_TRAFFIC_CAPABILITY = 89, - DOT11_IE_ID_BSS_MAX_IDLE_PERIOD = 90, - DOT11_IE_ID_TFS_REQUEST = 91, - DOT11_IE_ID_TFS_RESPONSE = 92, - DOT11_IE_ID_WNM_SLEEP_MODE = 93, - DOT11_IE_ID_TIM_BROADCAST_REQUEST = 94, - DOT11_IE_ID_TIM_BROADCAST_RESPONSE = 95, - DOT11_IE_ID_COLLOCATED_INTERFERENCE_REPORT = 96, - DOT11_IE_ID_CHANNEL_USAGE = 97, - DOT11_IE_ID_TIME_ZONE = 98, - DOT11_IE_ID_DMS_REQUEST = 99, - DOT11_IE_ID_DMS_RESPONSE = 100, - DOT11_IE_ID_LINK_IDENTIFIER = 101, - DOT11_IE_ID_WAKEUP_SCHEDULE = 102, - /* 103 Reserved */ - DOT11_IE_ID_CHANNEL_SWITCH_TIMING = 104, - DOT11_IE_ID_PTI_CONTROL = 105, - DOT11_IE_ID_TPU_BUFFER_STATUS = 106, - DOT11_IE_ID_INTERWORKING = 107, - DOT11_IE_ID_ADVERTISMENT_PROTOCOL = 108, - DOT11_IE_ID_EXPEDITED_BANDWIDTH_REQUEST = 109, - DOT11_IE_ID_QOS_MAP_SET = 110, - DOT11_IE_ID_ROAMING_CONSORTIUM = 111, - DOT11_IE_ID_EMERGENCY_ALERT_IDENTIFIER = 112, - DOT11_IE_ID_MESH_CONFIGURATION = 113, - DOT11_IE_ID_MESH_ID = 114, - DOT11_IE_ID_MESH_LINK_METRIC_REPORT = 115, - DOT11_IE_ID_CONGESTION_NOTIFICATION = 116, - DOT11_IE_ID_MESH_PEERING_MANAGEMENT = 117, - DOT11_IE_ID_MESH_CHANNEL_SWITCH_PARAMETERS = 118, - DOT11_IE_ID_MESH_AWAKE_WINDOW = 119, - DOT11_IE_ID_BEACON_TIMING = 120, - DOT11_IE_ID_MCCAOP_SETUP_REQUEST = 121, - DOT11_IE_ID_MCCAOP_SETUP_REPLY = 122, - DOT11_IE_ID_MCCAOP_ADVERTISMENT = 123, - DOT11_IE_ID_MCCAOP_TEARDOWN = 124, - DOT11_IE_ID_GANN = 125, - DOT11_IE_ID_RANN = 126, - DOT11_IE_ID_EXTENDED_CAPABILITIES = 127, - /* 128-129 Reserved */ - DOT11_IE_ID_PREQ = 130, - DOT11_IE_ID_PREP = 131, - DOT11_IE_ID_PERR = 132, - /* 133-136 Reserved */ - DOT11_IE_ID_PXU = 137, - DOT11_IE_ID_PXUC = 138, - DOT11_IE_ID_AUTHENTICATED_MESH_PEERING_EXCHANGE = 139, - DOT11_IE_ID_MIC = 140, - DOT11_IE_ID_DESTINATION_URI = 141, - DOT11_IE_ID_U_APSD_COEXISTENCE = 142, - /* 143-173 Reserved */ - DOT11_IE_ID_MCCAOP_ADVERTISMENT_OVERVIEW = 174, - /* 175-220 Reserved */ - DOT11_IE_ID_VENDOR_SPECIFIC = 221, - /* 222-255 Reserved */ +typedef enum +{ + DOT11_IE_ID_SSID = 0, + DOT11_IE_ID_SUPPORTED_RATES = 1, + DOT11_IE_ID_FH_PARAMETER_SET = 2, + DOT11_IE_ID_DSSS_PARAMETER_SET = 3, + DOT11_IE_ID_CF_PARAMETER_SET = 4, + DOT11_IE_ID_TIM = 5, + DOT11_IE_ID_IBSS_PARAMETER_SET = 6, + DOT11_IE_ID_COUNTRY = 7, + DOT11_IE_ID_HOPPING_PATTERN_PARAMETERS = 8, + DOT11_IE_ID_HOPPING_PATTERN_TABLE = 9, + DOT11_IE_ID_REQUEST = 10, + DOT11_IE_ID_BSS_LOAD = 11, + DOT11_IE_ID_EDCA_PARAMETER_SET = 12, + DOT11_IE_ID_TSPEC = 13, + DOT11_IE_ID_TCLAS = 14, + DOT11_IE_ID_SCHEDULE = 15, + DOT11_IE_ID_CHALLENGE_TEXT = 16, + /* 17-31 Reserved */ + DOT11_IE_ID_POWER_CONSTRAINT = 32, + DOT11_IE_ID_POWER_CAPABILITY = 33, + DOT11_IE_ID_TPC_REQUEST = 34, + DOT11_IE_ID_TPC_REPORT = 35, + DOT11_IE_ID_SUPPORTED_CHANNELS = 36, + DOT11_IE_ID_CHANNEL_SWITCH_ANNOUNCEMENT = 37, + DOT11_IE_ID_MEASUREMENT_REQUEST = 38, + DOT11_IE_ID_MEASUREMENT_REPORT = 39, + DOT11_IE_ID_QUIET = 40, + DOT11_IE_ID_IBSS_DFS = 41, + DOT11_IE_ID_ERP = 42, + DOT11_IE_ID_TS_DELAY = 43, + DOT11_IE_ID_TCLAS_PROCESSING = 44, + DOT11_IE_ID_HT_CAPABILITIES = 45, + DOT11_IE_ID_QOS_CAPABILITY = 46, + /* 47 Reserved */ + DOT11_IE_ID_RSN = 48, + /* 49 Reserved */ + DOT11_IE_ID_EXTENDED_SUPPORTED_RATES = 50, + DOT11_IE_ID_AP_CHANNEL_REPORT = 51, + DOT11_IE_ID_NEIGHBOR_REPORT = 52, + DOT11_IE_ID_RCPI = 53, + DOT11_IE_ID_MOBILITY_DOMAIN = 54, + DOT11_IE_ID_FAST_BSS_TRANSITION = 55, + DOT11_IE_ID_TIMEOUT_INTERVAL = 56, + DOT11_IE_ID_RIC_DATA = 57, + DOT11_IE_ID_DSE_REGISTERED_LOCATION = 58, + DOT11_IE_ID_SUPPORTED_OPERATING_CLASSES = 59, + DOT11_IE_ID_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT = 60, + DOT11_IE_ID_HT_OPERATION = 61, + DOT11_IE_ID_SECONDARY_CHANNEL_OFFSET = 62, + DOT11_IE_ID_BSS_AVERAGE_ACCESS_DELAY = 63, + DOT11_IE_ID_ANTENNA = 64, + DOT11_IE_ID_RSNI = 65, + DOT11_IE_ID_MEASUREMENT_PILOT_TRANSMISSION = 66, + DOT11_IE_ID_BSS_AVAILABLE_ADMISSION_CAPACITY = 67, + DOT11_IE_ID_BSS_AC_ACCESS_DELAY = 68, + DOT11_IE_ID_TIME_ADVERTISEMENT = 69, + DOT11_IE_ID_RM_ENABLED_CAPABILITIES = 70, + DOT11_IE_ID_MULTIPLE_BSSID = 71, + DOT11_IE_ID_20_40_BSS_COEXISTENCE = 72, + DOT11_IE_ID_20_40_BSS_INTOLERANT_CHANNEL_REPORT = 73, + DOT11_IE_ID_OVERLAPPING_BSS_SCAN_PARAMETERS = 74, + DOT11_IE_ID_RIC_DESCRIPTOR = 75, + DOT11_IE_ID_MANAGEMENT_MIC = 76, + DOT11_IE_ID_EVENT_REQUEST = 78, + DOT11_IE_ID_EVENT_REPORT = 79, + DOT11_IE_ID_DIAGNOSTIC_REQUEST = 80, + DOT11_IE_ID_DIAGNOSTIC_REPORT = 81, + DOT11_IE_ID_LOCATION_PARAMETERS = 82, + DOT11_IE_ID_NONTRANSMITTED_BSSID_CAPABILITY = 83, + DOT11_IE_ID_SSID_LIST = 84, + DOT11_IE_ID_MULTIPLE_BSSID_INDEX = 85, + DOT11_IE_ID_FMS_DESCRIPTOR = 86, + DOT11_IE_ID_FMS_REQUEST = 87, + DOT11_IE_ID_FMS_RESPONSE = 88, + DOT11_IE_ID_QOS_TRAFFIC_CAPABILITY = 89, + DOT11_IE_ID_BSS_MAX_IDLE_PERIOD = 90, + DOT11_IE_ID_TFS_REQUEST = 91, + DOT11_IE_ID_TFS_RESPONSE = 92, + DOT11_IE_ID_WNM_SLEEP_MODE = 93, + DOT11_IE_ID_TIM_BROADCAST_REQUEST = 94, + DOT11_IE_ID_TIM_BROADCAST_RESPONSE = 95, + DOT11_IE_ID_COLLOCATED_INTERFERENCE_REPORT = 96, + DOT11_IE_ID_CHANNEL_USAGE = 97, + DOT11_IE_ID_TIME_ZONE = 98, + DOT11_IE_ID_DMS_REQUEST = 99, + DOT11_IE_ID_DMS_RESPONSE = 100, + DOT11_IE_ID_LINK_IDENTIFIER = 101, + DOT11_IE_ID_WAKEUP_SCHEDULE = 102, + /* 103 Reserved */ + DOT11_IE_ID_CHANNEL_SWITCH_TIMING = 104, + DOT11_IE_ID_PTI_CONTROL = 105, + DOT11_IE_ID_TPU_BUFFER_STATUS = 106, + DOT11_IE_ID_INTERWORKING = 107, + DOT11_IE_ID_ADVERTISMENT_PROTOCOL = 108, + DOT11_IE_ID_EXPEDITED_BANDWIDTH_REQUEST = 109, + DOT11_IE_ID_QOS_MAP_SET = 110, + DOT11_IE_ID_ROAMING_CONSORTIUM = 111, + DOT11_IE_ID_EMERGENCY_ALERT_IDENTIFIER = 112, + DOT11_IE_ID_MESH_CONFIGURATION = 113, + DOT11_IE_ID_MESH_ID = 114, + DOT11_IE_ID_MESH_LINK_METRIC_REPORT = 115, + DOT11_IE_ID_CONGESTION_NOTIFICATION = 116, + DOT11_IE_ID_MESH_PEERING_MANAGEMENT = 117, + DOT11_IE_ID_MESH_CHANNEL_SWITCH_PARAMETERS = 118, + DOT11_IE_ID_MESH_AWAKE_WINDOW = 119, + DOT11_IE_ID_BEACON_TIMING = 120, + DOT11_IE_ID_MCCAOP_SETUP_REQUEST = 121, + DOT11_IE_ID_MCCAOP_SETUP_REPLY = 122, + DOT11_IE_ID_MCCAOP_ADVERTISMENT = 123, + DOT11_IE_ID_MCCAOP_TEARDOWN = 124, + DOT11_IE_ID_GANN = 125, + DOT11_IE_ID_RANN = 126, + DOT11_IE_ID_EXTENDED_CAPABILITIES = 127, + /* 128-129 Reserved */ + DOT11_IE_ID_PREQ = 130, + DOT11_IE_ID_PREP = 131, + DOT11_IE_ID_PERR = 132, + /* 133-136 Reserved */ + DOT11_IE_ID_PXU = 137, + DOT11_IE_ID_PXUC = 138, + DOT11_IE_ID_AUTHENTICATED_MESH_PEERING_EXCHANGE = 139, + DOT11_IE_ID_MIC = 140, + DOT11_IE_ID_DESTINATION_URI = 141, + DOT11_IE_ID_U_APSD_COEXISTENCE = 142, + /* 143-173 Reserved */ + DOT11_IE_ID_MCCAOP_ADVERTISMENT_OVERVIEW = 174, + /* 175-220 Reserved */ + DOT11_IE_ID_VENDOR_SPECIFIC = 221, + /* 222-223 Reserved */ + DOT11_IE_ID_RSNX = 244, + /* 225-255 Reserved */ } dot11_ie_id_t; -uint32_t whd_wifi_get_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t *value); -uint32_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, - const uint16_t *lengths, const uint8_t num_buffers); -uint32_t whd_wifi_set_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t value); +/* 802.11 Status Code */ +typedef enum +{ + DOT11_SC_SUCCESS = 0, + DOT11_SC_FAILURE = 1, + DOT11_SC_TDLS_WAKEUP_SCH_ALT = 2, + DOT11_SC_TDLS_WAKEUP_SCH_REJ = 3, + /* 4 Reserved */ + DOT11_SC_TDLS_SEC_DISABLED = 5, + DOT11_SC_LIFETIME_REJ = 6, + DOT11_SC_NOT_SAME_BSS = 7, + /* 8-9 Reserved */ + DOT11_SC_CAP_MISMATCH = 10, + DOT11_SC_REASSOC_FAIL = 11, + DOT11_SC_ASSOC_FAIL = 12, + DOT11_SC_AUTH_MISMATCH = 13, + DOT11_SC_AUTH_SEQ = 14, + DOT11_SC_AUTH_CHALLENGE_FAIL = 15, + DOT11_SC_AUTH_TIMEOUT = 16, + /* 17-255 Reserved */ +} dot11_sc_t; + +whd_result_t whd_wifi_get_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t *value); +whd_result_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, + const uint16_t *lengths, const uint8_t num_buffers); +whd_result_t whd_wifi_set_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t value); /** Sends an IOVAR command * @@ -363,7 +382,7 @@ uint32_t whd_wifi_set_iovar_value(whd_interface_t ifp, const char *iovar, uint32 * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_iovar_void(whd_interface_t ifp, const char *iovar); +extern whd_result_t whd_wifi_set_iovar_void(whd_interface_t ifp, const char *iovar); /** Sends an IOVAR command * @@ -374,7 +393,7 @@ extern uint32_t whd_wifi_set_iovar_void(whd_interface_t ifp, const char *iovar); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *buffer, uint16_t buffer_length); +extern whd_result_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *buffer, uint16_t buffer_length); /** Sends an IOVAR command * @@ -386,8 +405,8 @@ extern uint32_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, - const uint16_t *in_buffer_lengths, const uint8_t num_buffers); +extern whd_result_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, + const uint16_t *in_buffer_lengths, const uint8_t num_buffers); /** Sends an IOVAR command * @@ -398,8 +417,8 @@ extern uint32_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iova * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar_name, uint8_t *out_buffer, - uint16_t out_length); +extern whd_result_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar_name, uint8_t *out_buffer, + uint16_t out_length); /** Sends an IOVAR command * @@ -410,7 +429,7 @@ extern uint32_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *buffer, uint16_t buffer_length); +extern whd_result_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *buffer, uint16_t buffer_length); /** Sends an IOVAR command * @@ -422,12 +441,12 @@ extern uint32_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, - const uint16_t *in_buffer_lengths, const uint8_t num_buffers); +extern whd_result_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, + const uint16_t *in_buffer_lengths, const uint8_t num_buffers); -extern uint32_t whd_wifi_set_mac_address(whd_interface_t ifp, whd_mac_t mac); +extern whd_result_t whd_wifi_set_mac_address(whd_interface_t ifp, whd_mac_t mac); #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* ifndef INCLUDED_WHD_TYPES_INT_H_ */ diff --git a/wi-fi/whd/whd_utils.c b/wi-fi/whd/whd_utils.c index cf8d8fa9..50b1b671 100644 --- a/wi-fi/whd/whd_utils.c +++ b/wi-fi/whd/whd_utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ * * Utilities to help do specialized (not general purpose) WHD specific things */ +#include #include "whd_debug.h" #include "whd_utils.h" #include "whd_chip_constants.h" @@ -27,14 +28,55 @@ #include "whd_int.h" #include "whd_wlioctl.h" -#define UNSIGNED_CHAR_TO_CHAR(uch) ((uch)&0x7f) +#define UNSIGNED_CHAR_TO_CHAR(uch) ( (uch)& 0x7f ) -#define RSPEC_KBPS_MASK (0x7f) -#define RSPEC_500KBPS(rate) ((rate)&RSPEC_KBPS_MASK) -#define RSPEC_TO_KBPS(rate) (RSPEC_500KBPS((rate)) * (unsigned int)500) +#define RSPEC_KBPS_MASK (0x7f) +#define RSPEC_500KBPS(rate) ( (rate)& RSPEC_KBPS_MASK ) +#define RSPEC_TO_KBPS(rate) (RSPEC_500KBPS( (rate) ) * (unsigned int)500) -#define OTP_WORD_SIZE 16 /* Word size in bits */ -#define WPA_OUI_TYPE1 "\x00\x50\xF2\x01" /** WPA OUI */ +#define OTP_WORD_SIZE 16 /* Word size in bits */ +#define WPA_OUI_TYPE1 "\x00\x50\xF2\x01" /** WPA OUI */ + +#ifdef PROTO_MSGBUF +typedef struct dma_pool +{ + int offset; + int poolsize; + uint8_t big_buffer[0]; +}dma_pool; + +dma_pool *pool_mem; + +uint32_t whd_dmapool_init(uint32_t memory_size) +{ + WPRINT_WHD_DEBUG(("WHD allocating %lu bytes for DMA pool\n", memory_size)); + pool_mem = (dma_pool*)whd_hw_allocatePermanentApi(memory_size); + + if (pool_mem == NULL) + return -1; + + pool_mem->offset = 0; + pool_mem->poolsize = memory_size - (sizeof(dma_pool)); + + if (!whd_hw_openDeviceAccessApi(WHD_HW_DEVICE_WLAN, pool_mem->big_buffer, pool_mem->poolsize, 0 )) + return -1; + + return 0; +} + +void* whd_dmapool_alloc( int size) +{ + uint8_t* allocbuf; + + if ((pool_mem->offset + size) >= pool_mem->poolsize) + return NULL; + + allocbuf = pool_mem->big_buffer + pool_mem->offset; + pool_mem->offset += size; + + return allocbuf; +} +#endif /****************************************************** * Static Variables @@ -43,767 +85,794 @@ whd_tlv8_data_t *whd_tlv_find_tlv8(const uint8_t *message, uint32_t message_leng whd_tlv8_data_t *whd_tlv_find_tlv8(const uint8_t *message, uint32_t message_length, uint8_t type) { - while (message_length != 0) { - uint8_t current_tlv_type = message[0]; - uint16_t current_tlv_length = (uint16_t)(message[1] + 2); - - /* Check if we've overrun the buffer */ - if (current_tlv_length > message_length) { - return NULL; - } - - /* Check if we've found the type we are looking for */ - if (current_tlv_type == type) { - return (whd_tlv8_data_t *)message; - } - - /* Skip current TLV */ - message += current_tlv_length; - message_length -= current_tlv_length; - } - return 0; + while (message_length != 0) + { + uint8_t current_tlv_type = message[0]; + uint16_t current_tlv_length = (uint16_t)(message[1] + 2); + + /* Check if we've overrun the buffer */ + if (current_tlv_length > message_length) + { + return NULL; + } + + /* Check if we've found the type we are looking for */ + if (current_tlv_type == type) + { + return (whd_tlv8_data_t *)message; + } + + /* Skip current TLV */ + message += current_tlv_length; + message_length -= current_tlv_length; + } + return 0; } whd_tlv8_header_t *whd_parse_tlvs(const whd_tlv8_header_t *tlv_buf, uint32_t buflen, - dot11_ie_id_t key) + dot11_ie_id_t key) { - return (whd_tlv8_header_t *)whd_tlv_find_tlv8((const uint8_t *)tlv_buf, buflen, key); + return (whd_tlv8_header_t *)whd_tlv_find_tlv8( (const uint8_t *)tlv_buf, buflen, key ); } whd_bool_t whd_is_wpa_ie(vendor_specific_ie_header_t *wpaie, whd_tlv8_header_t **tlvs, uint32_t *tlvs_len) { - whd_tlv8_header_t *prev_tlvs = *tlvs; - whd_tlv8_header_t *new_tlvs = *tlvs; - vendor_specific_ie_header_t *ie = wpaie; - - /* If the contents match the WPA_OUI and type=1 */ - if ((ie->tlv_header.length >= (uint8_t)VENDOR_SPECIFIC_IE_MINIMUM_LENGTH) && - (memcmp(ie->oui, WPA_OUI_TYPE1, sizeof(ie->oui)) == 0)) { - /* Found the WPA IE */ - return WHD_TRUE; - } - - /* calculate the next ie address */ - new_tlvs = (whd_tlv8_header_t *)(((uint8_t *)ie) + ie->tlv_header.length + sizeof(whd_tlv8_header_t)); - - /* check the rest of length of buffer */ - if (*tlvs_len < (uint32_t)(((uint8_t *)new_tlvs) - ((uint8_t *)prev_tlvs))) { - /* set rest of length to zero to avoid buffer overflow */ - *tlvs_len = 0; - } - else { - /* point to the next ie */ - *tlvs = new_tlvs; - - /* tlvs now points to the beginning of next IE pointer, and *ie points to one or more TLV further + whd_tlv8_header_t *prev_tlvs = *tlvs; + whd_tlv8_header_t *new_tlvs = *tlvs; + vendor_specific_ie_header_t *ie = wpaie; + + /* If the contents match the WPA_OUI and type=1 */ + if ( (ie->tlv_header.length >= (uint8_t)VENDOR_SPECIFIC_IE_MINIMUM_LENGTH) && + (memcmp(ie->oui, WPA_OUI_TYPE1, sizeof(ie->oui) ) == 0) ) + { + /* Found the WPA IE */ + return WHD_TRUE; + } + + /* calculate the next ie address */ + new_tlvs = (whd_tlv8_header_t *)( ( (uint8_t *)ie ) + ie->tlv_header.length + sizeof(whd_tlv8_header_t) ); + + /* check the rest of length of buffer */ + if (*tlvs_len < (uint32_t)( ( (uint8_t *)new_tlvs ) - ( (uint8_t *)prev_tlvs ) ) ) + { + /* set rest of length to zero to avoid buffer overflow */ + *tlvs_len = 0; + } + else + { + /* point to the next ie */ + *tlvs = new_tlvs; + + /* tlvs now points to the beginning of next IE pointer, and *ie points to one or more TLV further * down from the *prev_tlvs. So the tlvs_len need to be adjusted by prev_tlvs instead of *ie */ - *tlvs_len -= (uint32_t)(((uint8_t *)*tlvs) - ((uint8_t *)prev_tlvs)); - } + *tlvs_len -= (uint32_t)( ( (uint8_t *)*tlvs ) - ( (uint8_t *)prev_tlvs ) ); + } - return WHD_FALSE; + return WHD_FALSE; } whd_tlv8_header_t *whd_parse_dot11_tlvs(const whd_tlv8_header_t *tlv_buf, uint32_t buflen, dot11_ie_id_t key) { - return (whd_tlv8_header_t *)whd_tlv_find_tlv8((const uint8_t *)tlv_buf, buflen, key); + return (whd_tlv8_header_t *)whd_tlv_find_tlv8( (const uint8_t *)tlv_buf, buflen, key ); } #ifdef WPRINT_ENABLE_WHD_DEBUG char *whd_ssid_to_string(uint8_t *value, uint8_t length, char *ssid_buf, uint8_t ssid_buf_len) { - memset(ssid_buf, 0, ssid_buf_len); + memset(ssid_buf, 0, ssid_buf_len); - if (ssid_buf_len > 0) { - memcpy(ssid_buf, value, ssid_buf_len < length ? ssid_buf_len : length); - } + if (ssid_buf_len > 0) + { + memcpy(ssid_buf, value, ssid_buf_len < length ? ssid_buf_len : length); + } - return ssid_buf; + return ssid_buf; } /* When adding new events, update this switch statement to print correct string */ -#define CASE_RETURN_STRING(value) \ - case value: \ - return #value; +#define CASE_RETURN_STRING(value) case value: \ + return # value; -#define CASE_RETURN(value) \ - case value: \ - break; +#define CASE_RETURN(value) case value: \ + break; const char *whd_event_to_string(whd_event_num_t value) { - switch (value) { - CASE_RETURN_STRING(WLC_E_ULP) - CASE_RETURN(WLC_E_BT_WIFI_HANDOVER_REQ) - CASE_RETURN(WLC_E_SPW_TXINHIBIT) - CASE_RETURN(WLC_E_FBT_AUTH_REQ_IND) - CASE_RETURN(WLC_E_RSSI_LQM) - CASE_RETURN(WLC_E_PFN_GSCAN_FULL_RESULT) - CASE_RETURN(WLC_E_PFN_SWC) - CASE_RETURN(WLC_E_AUTHORIZED) - CASE_RETURN(WLC_E_PROBREQ_MSG_RX) - CASE_RETURN(WLC_E_RMC_EVENT) - CASE_RETURN(WLC_E_DPSTA_INTF_IND) - CASE_RETURN_STRING(WLC_E_NONE) - CASE_RETURN_STRING(WLC_E_SET_SSID) - CASE_RETURN(WLC_E_PFN_BEST_BATCHING) - CASE_RETURN(WLC_E_JOIN) - CASE_RETURN(WLC_E_START) - CASE_RETURN_STRING(WLC_E_AUTH) - CASE_RETURN(WLC_E_AUTH_IND) - CASE_RETURN(WLC_E_DEAUTH) - CASE_RETURN_STRING(WLC_E_DEAUTH_IND) - CASE_RETURN(WLC_E_ASSOC) - CASE_RETURN(WLC_E_ASSOC_IND) - CASE_RETURN(WLC_E_REASSOC) - CASE_RETURN(WLC_E_REASSOC_IND) - CASE_RETURN(WLC_E_DISASSOC) - CASE_RETURN_STRING(WLC_E_DISASSOC_IND) - CASE_RETURN(WLC_E_ROAM) - CASE_RETURN(WLC_E_ROAM_PREP) - CASE_RETURN(WLC_E_ROAM_START) - CASE_RETURN(WLC_E_QUIET_START) - CASE_RETURN(WLC_E_QUIET_END) - CASE_RETURN(WLC_E_BEACON_RX) - CASE_RETURN_STRING(WLC_E_LINK) - CASE_RETURN_STRING(WLC_E_RRM) - CASE_RETURN(WLC_E_MIC_ERROR) - CASE_RETURN(WLC_E_NDIS_LINK) - CASE_RETURN(WLC_E_TXFAIL) - CASE_RETURN(WLC_E_PMKID_CACHE) - CASE_RETURN(WLC_E_RETROGRADE_TSF) - CASE_RETURN(WLC_E_PRUNE) - CASE_RETURN(WLC_E_AUTOAUTH) - CASE_RETURN(WLC_E_EAPOL_MSG) - CASE_RETURN(WLC_E_SCAN_COMPLETE) - CASE_RETURN(WLC_E_ADDTS_IND) - CASE_RETURN(WLC_E_DELTS_IND) - CASE_RETURN(WLC_E_BCNSENT_IND) - CASE_RETURN(WLC_E_BCNRX_MSG) - CASE_RETURN(WLC_E_BCNLOST_MSG) - CASE_RETURN_STRING(WLC_E_PFN_NET_FOUND) - CASE_RETURN(WLC_E_PFN_NET_LOST) - CASE_RETURN(WLC_E_RESET_COMPLETE) - CASE_RETURN(WLC_E_JOIN_START) - CASE_RETURN(WLC_E_ASSOC_START) - CASE_RETURN(WLC_E_IBSS_ASSOC) - CASE_RETURN(WLC_E_RADIO) - CASE_RETURN(WLC_E_PSM_WATCHDOG) - CASE_RETURN(WLC_E_CCX_ASSOC_START) - CASE_RETURN(WLC_E_CCX_ASSOC_ABORT) - CASE_RETURN(WLC_E_PROBREQ_MSG) - CASE_RETURN(WLC_E_SCAN_CONFIRM_IND) - CASE_RETURN_STRING(WLC_E_PSK_SUP) - CASE_RETURN(WLC_E_COUNTRY_CODE_CHANGED) - CASE_RETURN(WLC_E_EXCEEDED_MEDIUM_TIME) - CASE_RETURN(WLC_E_ICV_ERROR) - CASE_RETURN(WLC_E_UNICAST_DECODE_ERROR) - CASE_RETURN(WLC_E_MULTICAST_DECODE_ERROR) - CASE_RETURN(WLC_E_TRACE) - CASE_RETURN(WLC_E_BTA_HCI_EVENT) - CASE_RETURN(WLC_E_IF) - CASE_RETURN(WLC_E_P2P_DISC_LISTEN_COMPLETE) - CASE_RETURN(WLC_E_RSSI) - CASE_RETURN_STRING(WLC_E_PFN_SCAN_COMPLETE) - CASE_RETURN(WLC_E_EXTLOG_MSG) - CASE_RETURN(WLC_E_ACTION_FRAME) - CASE_RETURN(WLC_E_ACTION_FRAME_COMPLETE) - CASE_RETURN(WLC_E_PRE_ASSOC_IND) - CASE_RETURN(WLC_E_PRE_REASSOC_IND) - CASE_RETURN(WLC_E_CHANNEL_ADOPTED) - CASE_RETURN(WLC_E_AP_STARTED) - CASE_RETURN(WLC_E_DFS_AP_STOP) - CASE_RETURN(WLC_E_DFS_AP_RESUME) - CASE_RETURN(WLC_E_WAI_STA_EVENT) - CASE_RETURN(WLC_E_WAI_MSG) - CASE_RETURN_STRING(WLC_E_ESCAN_RESULT) - CASE_RETURN(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE) - CASE_RETURN(WLC_E_PROBRESP_MSG) - CASE_RETURN(WLC_E_P2P_PROBREQ_MSG) - CASE_RETURN(WLC_E_DCS_REQUEST) - CASE_RETURN(WLC_E_FIFO_CREDIT_MAP) - CASE_RETURN(WLC_E_ACTION_FRAME_RX) - CASE_RETURN(WLC_E_WAKE_EVENT) - CASE_RETURN(WLC_E_RM_COMPLETE) - CASE_RETURN(WLC_E_HTSFSYNC) - CASE_RETURN(WLC_E_OVERLAY_REQ) - CASE_RETURN_STRING(WLC_E_CSA_COMPLETE_IND) - CASE_RETURN(WLC_E_EXCESS_PM_WAKE_EVENT) - CASE_RETURN(WLC_E_PFN_SCAN_NONE) - CASE_RETURN(WLC_E_PFN_SCAN_ALLGONE) - CASE_RETURN(WLC_E_GTK_PLUMBED) - CASE_RETURN(WLC_E_ASSOC_IND_NDIS) - CASE_RETURN(WLC_E_REASSOC_IND_NDIS) - CASE_RETURN(WLC_E_ASSOC_REQ_IE) - CASE_RETURN(WLC_E_ASSOC_RESP_IE) - CASE_RETURN(WLC_E_ASSOC_RECREATED) - CASE_RETURN(WLC_E_ACTION_FRAME_RX_NDIS) - CASE_RETURN(WLC_E_AUTH_REQ) - CASE_RETURN(WLC_E_TDLS_PEER_EVENT) - CASE_RETURN(WLC_E_SPEEDY_RECREATE_FAIL) - CASE_RETURN(WLC_E_NATIVE) - CASE_RETURN(WLC_E_PKTDELAY_IND) - CASE_RETURN(WLC_E_AWDL_AW) - CASE_RETURN(WLC_E_AWDL_ROLE) - CASE_RETURN(WLC_E_AWDL_EVENT) - CASE_RETURN(WLC_E_NIC_AF_TXS) - CASE_RETURN(WLC_E_NAN) - CASE_RETURN(WLC_E_BEACON_FRAME_RX) - CASE_RETURN(WLC_E_SERVICE_FOUND) - CASE_RETURN(WLC_E_GAS_FRAGMENT_RX) - CASE_RETURN(WLC_E_GAS_COMPLETE) - CASE_RETURN(WLC_E_P2PO_ADD_DEVICE) - CASE_RETURN(WLC_E_P2PO_DEL_DEVICE) - CASE_RETURN(WLC_E_WNM_STA_SLEEP) - CASE_RETURN(WLC_E_TXFAIL_THRESH) - CASE_RETURN(WLC_E_PROXD) - CASE_RETURN(WLC_E_IBSS_COALESCE) - CASE_RETURN(WLC_E_AWDL_RX_PRB_RESP) - CASE_RETURN(WLC_E_AWDL_RX_ACT_FRAME) - CASE_RETURN(WLC_E_AWDL_WOWL_NULLPKT) - CASE_RETURN(WLC_E_AWDL_PHYCAL_STATUS) - CASE_RETURN(WLC_E_AWDL_OOB_AF_STATUS) - CASE_RETURN(WLC_E_AWDL_SCAN_STATUS) - CASE_RETURN(WLC_E_AWDL_AW_START) - CASE_RETURN(WLC_E_AWDL_AW_END) - CASE_RETURN(WLC_E_AWDL_AW_EXT) - CASE_RETURN(WLC_E_AWDL_PEER_CACHE_CONTROL) - CASE_RETURN(WLC_E_CSA_START_IND) - CASE_RETURN(WLC_E_CSA_DONE_IND) - CASE_RETURN(WLC_E_CSA_FAILURE_IND) - CASE_RETURN(WLC_E_CCA_CHAN_QUAL) - CASE_RETURN(WLC_E_BSSID) - CASE_RETURN(WLC_E_TX_STAT_ERROR) - CASE_RETURN(WLC_E_BCMC_CREDIT_SUPPORT) - CASE_RETURN(WLC_E_PSTA_PRIMARY_INTF_IND) - case WLC_E_LAST: - default: - return "Unknown"; - - break; - } - - return "Unknown"; + switch (value) + { + CASE_RETURN_STRING(WLC_E_ULP) + CASE_RETURN(WLC_E_BT_WIFI_HANDOVER_REQ) + CASE_RETURN(WLC_E_SPW_TXINHIBIT) + CASE_RETURN(WLC_E_FBT_AUTH_REQ_IND) + CASE_RETURN(WLC_E_RSSI_LQM) + CASE_RETURN(WLC_E_PFN_GSCAN_FULL_RESULT) + CASE_RETURN(WLC_E_PFN_SWC) + CASE_RETURN(WLC_E_AUTHORIZED) + CASE_RETURN(WLC_E_PROBREQ_MSG_RX) + CASE_RETURN(WLC_E_RMC_EVENT) + CASE_RETURN(WLC_E_DPSTA_INTF_IND) + CASE_RETURN_STRING(WLC_E_NONE) + CASE_RETURN_STRING(WLC_E_SET_SSID) + CASE_RETURN(WLC_E_PFN_BEST_BATCHING) + CASE_RETURN(WLC_E_JOIN) + CASE_RETURN(WLC_E_START) + CASE_RETURN_STRING(WLC_E_AUTH) + CASE_RETURN(WLC_E_AUTH_IND) + CASE_RETURN(WLC_E_DEAUTH) + CASE_RETURN_STRING(WLC_E_DEAUTH_IND) + CASE_RETURN(WLC_E_ASSOC) + CASE_RETURN(WLC_E_ASSOC_IND) + CASE_RETURN(WLC_E_REASSOC) + CASE_RETURN(WLC_E_REASSOC_IND) + CASE_RETURN(WLC_E_DISASSOC) + CASE_RETURN_STRING(WLC_E_DISASSOC_IND) + CASE_RETURN(WLC_E_ROAM) + CASE_RETURN(WLC_E_ROAM_PREP) + CASE_RETURN(WLC_E_ROAM_START) + CASE_RETURN(WLC_E_QUIET_START) + CASE_RETURN(WLC_E_QUIET_END) + CASE_RETURN(WLC_E_BEACON_RX) + CASE_RETURN_STRING(WLC_E_LINK) + CASE_RETURN_STRING(WLC_E_RRM) + CASE_RETURN(WLC_E_MIC_ERROR) + CASE_RETURN(WLC_E_NDIS_LINK) + CASE_RETURN(WLC_E_TXFAIL) + CASE_RETURN(WLC_E_PMKID_CACHE) + CASE_RETURN(WLC_E_RETROGRADE_TSF) + CASE_RETURN(WLC_E_PRUNE) + CASE_RETURN(WLC_E_AUTOAUTH) + CASE_RETURN(WLC_E_EAPOL_MSG) + CASE_RETURN(WLC_E_SCAN_COMPLETE) + CASE_RETURN(WLC_E_ADDTS_IND) + CASE_RETURN(WLC_E_DELTS_IND) + CASE_RETURN(WLC_E_BCNSENT_IND) + CASE_RETURN(WLC_E_BCNRX_MSG) + CASE_RETURN(WLC_E_BCNLOST_MSG) + CASE_RETURN_STRING(WLC_E_PFN_NET_FOUND) + CASE_RETURN(WLC_E_PFN_NET_LOST) + CASE_RETURN(WLC_E_RESET_COMPLETE) + CASE_RETURN(WLC_E_JOIN_START) + CASE_RETURN(WLC_E_ASSOC_START) + CASE_RETURN(WLC_E_IBSS_ASSOC) + CASE_RETURN(WLC_E_RADIO) + CASE_RETURN(WLC_E_PSM_WATCHDOG) + CASE_RETURN(WLC_E_CCX_ASSOC_START) + CASE_RETURN(WLC_E_CCX_ASSOC_ABORT) + CASE_RETURN(WLC_E_PROBREQ_MSG) + CASE_RETURN(WLC_E_SCAN_CONFIRM_IND) + CASE_RETURN_STRING(WLC_E_PSK_SUP) + CASE_RETURN(WLC_E_COUNTRY_CODE_CHANGED) + CASE_RETURN(WLC_E_EXCEEDED_MEDIUM_TIME) + CASE_RETURN(WLC_E_ICV_ERROR) + CASE_RETURN(WLC_E_UNICAST_DECODE_ERROR) + CASE_RETURN(WLC_E_MULTICAST_DECODE_ERROR) + CASE_RETURN(WLC_E_TRACE) + CASE_RETURN(WLC_E_BTA_HCI_EVENT) + CASE_RETURN(WLC_E_IF) + CASE_RETURN(WLC_E_P2P_DISC_LISTEN_COMPLETE) + CASE_RETURN(WLC_E_RSSI) + CASE_RETURN_STRING(WLC_E_PFN_SCAN_COMPLETE) + CASE_RETURN(WLC_E_EXTLOG_MSG) + CASE_RETURN(WLC_E_ACTION_FRAME) + CASE_RETURN(WLC_E_ACTION_FRAME_COMPLETE) + CASE_RETURN(WLC_E_PRE_ASSOC_IND) + CASE_RETURN(WLC_E_PRE_REASSOC_IND) + CASE_RETURN(WLC_E_CHANNEL_ADOPTED) + CASE_RETURN(WLC_E_AP_STARTED) + CASE_RETURN(WLC_E_DFS_AP_STOP) + CASE_RETURN(WLC_E_DFS_AP_RESUME) + CASE_RETURN(WLC_E_WAI_STA_EVENT) + CASE_RETURN(WLC_E_WAI_MSG) + CASE_RETURN_STRING(WLC_E_ESCAN_RESULT) + CASE_RETURN(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE) + CASE_RETURN(WLC_E_PROBRESP_MSG) + CASE_RETURN(WLC_E_P2P_PROBREQ_MSG) + CASE_RETURN(WLC_E_DCS_REQUEST) + CASE_RETURN(WLC_E_FIFO_CREDIT_MAP) + CASE_RETURN(WLC_E_ACTION_FRAME_RX) + CASE_RETURN(WLC_E_WAKE_EVENT) + CASE_RETURN(WLC_E_RM_COMPLETE) + CASE_RETURN(WLC_E_HTSFSYNC) + CASE_RETURN(WLC_E_OVERLAY_REQ) + CASE_RETURN_STRING(WLC_E_CSA_COMPLETE_IND) + CASE_RETURN(WLC_E_EXCESS_PM_WAKE_EVENT) + CASE_RETURN(WLC_E_PFN_SCAN_NONE) + CASE_RETURN(WLC_E_PFN_SCAN_ALLGONE) + CASE_RETURN(WLC_E_GTK_PLUMBED) + CASE_RETURN(WLC_E_ASSOC_IND_NDIS) + CASE_RETURN(WLC_E_REASSOC_IND_NDIS) + CASE_RETURN(WLC_E_ASSOC_REQ_IE) + CASE_RETURN(WLC_E_ASSOC_RESP_IE) + CASE_RETURN(WLC_E_ASSOC_RECREATED) + CASE_RETURN(WLC_E_ACTION_FRAME_RX_NDIS) + CASE_RETURN(WLC_E_AUTH_REQ) + CASE_RETURN(WLC_E_TDLS_PEER_EVENT) + CASE_RETURN(WLC_E_SPEEDY_RECREATE_FAIL) + CASE_RETURN(WLC_E_NATIVE) + CASE_RETURN(WLC_E_PKTDELAY_IND) + CASE_RETURN(WLC_E_AWDL_AW) + CASE_RETURN(WLC_E_AWDL_ROLE) + CASE_RETURN(WLC_E_AWDL_EVENT) + CASE_RETURN(WLC_E_NIC_AF_TXS) + CASE_RETURN(WLC_E_NAN) + CASE_RETURN(WLC_E_BEACON_FRAME_RX) + CASE_RETURN(WLC_E_SERVICE_FOUND) + CASE_RETURN(WLC_E_GAS_FRAGMENT_RX) + CASE_RETURN(WLC_E_GAS_COMPLETE) + CASE_RETURN(WLC_E_P2PO_ADD_DEVICE) + CASE_RETURN(WLC_E_P2PO_DEL_DEVICE) + CASE_RETURN(WLC_E_WNM_STA_SLEEP) + CASE_RETURN(WLC_E_TXFAIL_THRESH) + CASE_RETURN(WLC_E_PROXD) + CASE_RETURN(WLC_E_IBSS_COALESCE) + CASE_RETURN(WLC_E_AWDL_RX_PRB_RESP) + CASE_RETURN(WLC_E_AWDL_RX_ACT_FRAME) + CASE_RETURN(WLC_E_AWDL_WOWL_NULLPKT) + CASE_RETURN(WLC_E_AWDL_PHYCAL_STATUS) + CASE_RETURN(WLC_E_AWDL_OOB_AF_STATUS) + CASE_RETURN(WLC_E_AWDL_SCAN_STATUS) + CASE_RETURN(WLC_E_AWDL_AW_START) + CASE_RETURN(WLC_E_AWDL_AW_END) + CASE_RETURN(WLC_E_AWDL_AW_EXT) + CASE_RETURN(WLC_E_AWDL_PEER_CACHE_CONTROL) + CASE_RETURN(WLC_E_CSA_START_IND) + CASE_RETURN(WLC_E_CSA_DONE_IND) + CASE_RETURN(WLC_E_CSA_FAILURE_IND) + CASE_RETURN(WLC_E_CCA_CHAN_QUAL) + CASE_RETURN(WLC_E_BSSID) + CASE_RETURN(WLC_E_TX_STAT_ERROR) + CASE_RETURN(WLC_E_BCMC_CREDIT_SUPPORT) + CASE_RETURN(WLC_E_PSTA_PRIMARY_INTF_IND) + case WLC_E_LAST: + default: + return "Unknown"; + + break; + } + + return "Unknown"; } const char *whd_status_to_string(whd_event_status_t status) { - switch (status) { - CASE_RETURN_STRING(WLC_E_STATUS_SUCCESS) - CASE_RETURN_STRING(WLC_E_STATUS_FAIL) - CASE_RETURN_STRING(WLC_E_STATUS_TIMEOUT) - CASE_RETURN_STRING(WLC_E_STATUS_NO_NETWORKS) - CASE_RETURN_STRING(WLC_E_STATUS_ABORT) - CASE_RETURN_STRING(WLC_E_STATUS_NO_ACK) - CASE_RETURN_STRING(WLC_E_STATUS_UNSOLICITED) - CASE_RETURN_STRING(WLC_E_STATUS_ATTEMPT) - CASE_RETURN_STRING(WLC_E_STATUS_PARTIAL) - CASE_RETURN_STRING(WLC_E_STATUS_NEWSCAN) - CASE_RETURN_STRING(WLC_E_STATUS_NEWASSOC) - CASE_RETURN_STRING(WLC_E_STATUS_11HQUIET) - CASE_RETURN_STRING(WLC_E_STATUS_SUPPRESS) - CASE_RETURN_STRING(WLC_E_STATUS_NOCHANS) - CASE_RETURN_STRING(WLC_E_STATUS_CCXFASTRM) - CASE_RETURN_STRING(WLC_E_STATUS_CS_ABORT) - CASE_RETURN_STRING(WLC_SUP_DISCONNECTED) - CASE_RETURN_STRING(WLC_SUP_CONNECTING) - CASE_RETURN_STRING(WLC_SUP_IDREQUIRED) - CASE_RETURN_STRING(WLC_SUP_AUTHENTICATING) - CASE_RETURN_STRING(WLC_SUP_AUTHENTICATED) - CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE) - CASE_RETURN_STRING(WLC_SUP_KEYED) - CASE_RETURN_STRING(WLC_SUP_TIMEOUT) - CASE_RETURN_STRING(WLC_SUP_LAST_BASIC_STATE) - CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_M4) - CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_WAIT_G1) - CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_G2) - CASE_RETURN_STRING(WLC_DOT11_SC_SUCCESS) - CASE_RETURN_STRING(WLC_DOT11_SC_FAILURE) - CASE_RETURN_STRING(WLC_DOT11_SC_CAP_MISMATCH) - CASE_RETURN_STRING(WLC_DOT11_SC_REASSOC_FAIL) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_FAIL) - CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_MISMATCH) - CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_SEQ) - CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_CHALLENGE_FAIL) - CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_TIMEOUT) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BUSY_FAIL) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_RATE_MISMATCH) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORT_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_PBCC_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_POWER_CAP) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED) - CASE_RETURN_STRING(WLC_DOT11_SC_DECLINED) - CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_PARAMS) - CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_AKMP) - CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_MDID) - CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_FTIE) - case WLC_E_STATUS_FORCE_32_BIT: - default: - break; - } - return "Unknown"; + switch (status) + { + CASE_RETURN_STRING(WLC_E_STATUS_SUCCESS) + CASE_RETURN_STRING(WLC_E_STATUS_FAIL) + CASE_RETURN_STRING(WLC_E_STATUS_TIMEOUT) + CASE_RETURN_STRING(WLC_E_STATUS_NO_NETWORKS) + CASE_RETURN_STRING(WLC_E_STATUS_ABORT) + CASE_RETURN_STRING(WLC_E_STATUS_NO_ACK) + CASE_RETURN_STRING(WLC_E_STATUS_UNSOLICITED) + CASE_RETURN_STRING(WLC_E_STATUS_ATTEMPT) + CASE_RETURN_STRING(WLC_E_STATUS_PARTIAL) + CASE_RETURN_STRING(WLC_E_STATUS_NEWSCAN) + CASE_RETURN_STRING(WLC_E_STATUS_NEWASSOC) + CASE_RETURN_STRING(WLC_E_STATUS_11HQUIET) + CASE_RETURN_STRING(WLC_E_STATUS_SUPPRESS) + CASE_RETURN_STRING(WLC_E_STATUS_NOCHANS) + CASE_RETURN_STRING(WLC_E_STATUS_CCXFASTRM) + CASE_RETURN_STRING(WLC_E_STATUS_CS_ABORT) + CASE_RETURN_STRING(WLC_SUP_DISCONNECTED) + CASE_RETURN_STRING(WLC_SUP_CONNECTING) + CASE_RETURN_STRING(WLC_SUP_IDREQUIRED) + CASE_RETURN_STRING(WLC_SUP_AUTHENTICATING) + CASE_RETURN_STRING(WLC_SUP_AUTHENTICATED) + CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE) + CASE_RETURN_STRING(WLC_SUP_KEYED) + CASE_RETURN_STRING(WLC_SUP_TIMEOUT) + CASE_RETURN_STRING(WLC_SUP_LAST_BASIC_STATE) + CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_M4) + CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_WAIT_G1) + CASE_RETURN_STRING(WLC_SUP_KEYXCHANGE_PREP_G2) + CASE_RETURN_STRING(WLC_DOT11_SC_SUCCESS) + CASE_RETURN_STRING(WLC_DOT11_SC_FAILURE) + CASE_RETURN_STRING(WLC_DOT11_SC_CAP_MISMATCH) + CASE_RETURN_STRING(WLC_DOT11_SC_REASSOC_FAIL) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_FAIL) + CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_MISMATCH) + CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_SEQ) + CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_CHALLENGE_FAIL) + CASE_RETURN_STRING(WLC_DOT11_SC_AUTH_TIMEOUT) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BUSY_FAIL) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_RATE_MISMATCH) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORT_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_PBCC_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_POWER_CAP) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED) + CASE_RETURN_STRING(WLC_DOT11_SC_DECLINED) + CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_PARAMS) + CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_AKMP) + CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_MDID) + CASE_RETURN_STRING(WLC_DOT11_SC_INVALID_FTIE) + case WLC_E_STATUS_FORCE_32_BIT: + default: + break; + } + return "Unknown"; } const char *whd_reason_to_string(whd_event_reason_t reason) { - switch (reason) { - CASE_RETURN_STRING(WLC_E_REASON_INITIAL_ASSOC) - CASE_RETURN_STRING(WLC_E_REASON_LOW_RSSI) - CASE_RETURN_STRING(WLC_E_REASON_DEAUTH) - CASE_RETURN_STRING(WLC_E_REASON_DISASSOC) - CASE_RETURN_STRING(WLC_E_REASON_BCNS_LOST) - CASE_RETURN_STRING(WLC_E_REASON_FAST_ROAM_FAILED) - CASE_RETURN_STRING(WLC_E_REASON_DIRECTED_ROAM) - CASE_RETURN_STRING(WLC_E_REASON_TSPEC_REJECTED) - CASE_RETURN_STRING(WLC_E_REASON_BETTER_AP) - CASE_RETURN_STRING(WLC_E_PRUNE_ENCR_MISMATCH) - CASE_RETURN_STRING(WLC_E_PRUNE_BCAST_BSSID) - CASE_RETURN_STRING(WLC_E_PRUNE_MAC_DENY) - CASE_RETURN_STRING(WLC_E_PRUNE_MAC_NA) - CASE_RETURN_STRING(WLC_E_PRUNE_REG_PASSV) - CASE_RETURN_STRING(WLC_E_PRUNE_SPCT_MGMT) - CASE_RETURN_STRING(WLC_E_PRUNE_RADAR) - CASE_RETURN_STRING(WLC_E_RSN_MISMATCH) - CASE_RETURN_STRING(WLC_E_PRUNE_NO_COMMON_RATES) - CASE_RETURN_STRING(WLC_E_PRUNE_BASIC_RATES) - CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_PREVAP) - CASE_RETURN_STRING(WLC_E_PRUNE_CIPHER_NA) - CASE_RETURN_STRING(WLC_E_PRUNE_KNOWN_STA) - CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_DROAM) - CASE_RETURN_STRING(WLC_E_PRUNE_WDS_PEER) - CASE_RETURN_STRING(WLC_E_PRUNE_QBSS_LOAD) - CASE_RETURN_STRING(WLC_E_PRUNE_HOME_AP) - CASE_RETURN_STRING(WLC_E_PRUNE_AP_BLOCKED) - CASE_RETURN_STRING(WLC_E_PRUNE_NO_DIAG_SUPPORT) - CASE_RETURN_STRING(WLC_E_SUP_OTHER) - CASE_RETURN_STRING(WLC_E_SUP_DECRYPT_KEY_DATA) - CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP128) - CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP40) - CASE_RETURN_STRING(WLC_E_SUP_UNSUP_KEY_LEN) - CASE_RETURN_STRING(WLC_E_SUP_PW_KEY_CIPHER) - CASE_RETURN_STRING(WLC_E_SUP_MSG3_TOO_MANY_IE) - CASE_RETURN_STRING(WLC_E_SUP_MSG3_IE_MISMATCH) - CASE_RETURN_STRING(WLC_E_SUP_NO_INSTALL_FLAG) - CASE_RETURN_STRING(WLC_E_SUP_MSG3_NO_GTK) - CASE_RETURN_STRING(WLC_E_SUP_GRP_KEY_CIPHER) - CASE_RETURN_STRING(WLC_E_SUP_GRP_MSG1_NO_GTK) - CASE_RETURN_STRING(WLC_E_SUP_GTK_DECRYPT_FAIL) - CASE_RETURN_STRING(WLC_E_SUP_SEND_FAIL) - CASE_RETURN_STRING(WLC_E_SUP_DEAUTH) - CASE_RETURN_STRING(WLC_E_SUP_WPA_PSK_TMO) - CASE_RETURN_STRING(DOT11_RC_RESERVED) - CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED) - CASE_RETURN_STRING(DOT11_RC_AUTH_INVAL) - CASE_RETURN_STRING(DOT11_RC_DEAUTH_LEAVING) - CASE_RETURN_STRING(DOT11_RC_INACTIVITY) - CASE_RETURN_STRING(DOT11_RC_BUSY) - CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_2) - CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_3) - CASE_RETURN_STRING(DOT11_RC_DISASSOC_LEAVING) - CASE_RETURN_STRING(DOT11_RC_NOT_AUTH) - CASE_RETURN_STRING(DOT11_RC_BAD_PC) - CASE_RETURN_STRING(DOT11_RC_BAD_CHANNELS) - CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED_QOS) - CASE_RETURN_STRING(DOT11_RC_INSUFFCIENT_BW) - CASE_RETURN_STRING(DOT11_RC_EXCESSIVE_FRAMES) - CASE_RETURN_STRING(DOT11_RC_TX_OUTSIDE_TXOP) - CASE_RETURN_STRING(DOT11_RC_LEAVING_QBSS) - CASE_RETURN_STRING(DOT11_RC_BAD_MECHANISM) - CASE_RETURN_STRING(DOT11_RC_SETUP_NEEDED) - CASE_RETURN_STRING(DOT11_RC_TIMEOUT) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_STATUS_CHG) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_MERGE) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_STOP) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_P2P) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_P2P) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_MESH) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_IBSS) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_RANGING) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_POST_DISC) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IF_ADD) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_PEER_ADD) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IND) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_CONF) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_SDF_RX) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_END) - CASE_RETURN_STRING(WLC_E_NAN_EVENT_BCN_RX) - case DOT11_RC_MAX: - case WLC_E_REASON_FORCE_32_BIT: - default: - break; - } - - return "Unknown"; + switch (reason) + { + CASE_RETURN_STRING(WLC_E_REASON_INITIAL_ASSOC) + CASE_RETURN_STRING(WLC_E_REASON_LOW_RSSI) + CASE_RETURN_STRING(WLC_E_REASON_DEAUTH) + CASE_RETURN_STRING(WLC_E_REASON_DISASSOC) + CASE_RETURN_STRING(WLC_E_REASON_BCNS_LOST) + CASE_RETURN_STRING(WLC_E_REASON_FAST_ROAM_FAILED) + CASE_RETURN_STRING(WLC_E_REASON_DIRECTED_ROAM) + CASE_RETURN_STRING(WLC_E_REASON_TSPEC_REJECTED) + CASE_RETURN_STRING(WLC_E_REASON_BETTER_AP) + CASE_RETURN_STRING(WLC_E_PRUNE_ENCR_MISMATCH) + CASE_RETURN_STRING(WLC_E_PRUNE_BCAST_BSSID) + CASE_RETURN_STRING(WLC_E_PRUNE_MAC_DENY) + CASE_RETURN_STRING(WLC_E_PRUNE_MAC_NA) + CASE_RETURN_STRING(WLC_E_PRUNE_REG_PASSV) + CASE_RETURN_STRING(WLC_E_PRUNE_SPCT_MGMT) + CASE_RETURN_STRING(WLC_E_PRUNE_RADAR) + CASE_RETURN_STRING(WLC_E_RSN_MISMATCH) + CASE_RETURN_STRING(WLC_E_PRUNE_NO_COMMON_RATES) + CASE_RETURN_STRING(WLC_E_PRUNE_BASIC_RATES) + CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_PREVAP) + CASE_RETURN_STRING(WLC_E_PRUNE_CIPHER_NA) + CASE_RETURN_STRING(WLC_E_PRUNE_KNOWN_STA) + CASE_RETURN_STRING(WLC_E_PRUNE_CCXFAST_DROAM) + CASE_RETURN_STRING(WLC_E_PRUNE_WDS_PEER) + CASE_RETURN_STRING(WLC_E_PRUNE_QBSS_LOAD) + CASE_RETURN_STRING(WLC_E_PRUNE_HOME_AP) + CASE_RETURN_STRING(WLC_E_PRUNE_AP_BLOCKED) + CASE_RETURN_STRING(WLC_E_PRUNE_NO_DIAG_SUPPORT) + CASE_RETURN_STRING(WLC_E_SUP_OTHER) + CASE_RETURN_STRING(WLC_E_SUP_DECRYPT_KEY_DATA) + CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP128) + CASE_RETURN_STRING(WLC_E_SUP_BAD_UCAST_WEP40) + CASE_RETURN_STRING(WLC_E_SUP_UNSUP_KEY_LEN) + CASE_RETURN_STRING(WLC_E_SUP_PW_KEY_CIPHER) + CASE_RETURN_STRING(WLC_E_SUP_MSG3_TOO_MANY_IE) + CASE_RETURN_STRING(WLC_E_SUP_MSG3_IE_MISMATCH) + CASE_RETURN_STRING(WLC_E_SUP_NO_INSTALL_FLAG) + CASE_RETURN_STRING(WLC_E_SUP_MSG3_NO_GTK) + CASE_RETURN_STRING(WLC_E_SUP_GRP_KEY_CIPHER) + CASE_RETURN_STRING(WLC_E_SUP_GRP_MSG1_NO_GTK) + CASE_RETURN_STRING(WLC_E_SUP_GTK_DECRYPT_FAIL) + CASE_RETURN_STRING(WLC_E_SUP_SEND_FAIL) + CASE_RETURN_STRING(WLC_E_SUP_DEAUTH) + CASE_RETURN_STRING(WLC_E_SUP_WPA_PSK_TMO) + CASE_RETURN_STRING(DOT11_RC_RESERVED) + CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED) + CASE_RETURN_STRING(DOT11_RC_AUTH_INVAL) + CASE_RETURN_STRING(DOT11_RC_DEAUTH_LEAVING) + CASE_RETURN_STRING(DOT11_RC_INACTIVITY) + CASE_RETURN_STRING(DOT11_RC_BUSY) + CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_2) + CASE_RETURN_STRING(DOT11_RC_INVAL_CLASS_3) + CASE_RETURN_STRING(DOT11_RC_DISASSOC_LEAVING) + CASE_RETURN_STRING(DOT11_RC_NOT_AUTH) + CASE_RETURN_STRING(DOT11_RC_BAD_PC) + CASE_RETURN_STRING(DOT11_RC_BAD_CHANNELS) + CASE_RETURN_STRING(DOT11_RC_UNSPECIFIED_QOS) + CASE_RETURN_STRING(DOT11_RC_INSUFFCIENT_BW) + CASE_RETURN_STRING(DOT11_RC_EXCESSIVE_FRAMES) + CASE_RETURN_STRING(DOT11_RC_TX_OUTSIDE_TXOP) + CASE_RETURN_STRING(DOT11_RC_LEAVING_QBSS) + CASE_RETURN_STRING(DOT11_RC_BAD_MECHANISM) + CASE_RETURN_STRING(DOT11_RC_SETUP_NEEDED) + CASE_RETURN_STRING(DOT11_RC_TIMEOUT) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_STATUS_CHG) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_MERGE) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_STOP) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_P2P) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_P2P) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_MESH) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_IBSS) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_WINDOW_BEGIN_RANGING) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_POST_DISC) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IF_ADD) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_PEER_ADD) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_IND) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_CONF) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_SDF_RX) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_DATA_END) + CASE_RETURN_STRING(WLC_E_NAN_EVENT_BCN_RX) + case DOT11_RC_MAX: + case WLC_E_REASON_FORCE_32_BIT: + default: + break; + } + + return "Unknown"; } char *whd_ether_ntoa(const uint8_t *ea, char *buf, uint8_t buf_len) { - const char hex[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' - }; - char *output = buf; - const uint8_t *octet = ea; - - if (buf_len < WHD_ETHER_ADDR_STR_LEN) { - if (buf_len > 0) { - /* buffer too short */ - buf[0] = '\0'; - } - return buf; - } - - for (; octet != &ea[WHD_ETHER_ADDR_LEN]; octet++) { - *output++ = hex[(*octet >> 4) & 0xf]; - *output++ = hex[*octet & 0xf]; - *output++ = ':'; - } - - *(output - 1) = '\0'; - - return buf; + const char hex[] = + { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + char *output = buf; + const uint8_t *octet = ea; + + if (buf_len < WHD_ETHER_ADDR_STR_LEN) + { + if (buf_len > 0) + { + /* buffer too short */ + buf[0] = '\0'; + } + return buf; + } + + for (; octet != &ea[WHD_ETHER_ADDR_LEN]; octet++) + { + *output++ = hex[(*octet >> 4) & 0xf]; + *output++ = hex[*octet & 0xf]; + *output++ = ':'; + } + + *(output - 1) = '\0'; + + return buf; } const char *whd_ioctl_to_string(uint32_t ioctl) { - switch (ioctl) { - CASE_RETURN_STRING(WLC_GET_MAGIC) - CASE_RETURN_STRING(WLC_GET_VERSION) - CASE_RETURN_STRING(WLC_UP) - CASE_RETURN_STRING(WLC_DOWN) - CASE_RETURN_STRING(WLC_GET_LOOP) - CASE_RETURN_STRING(WLC_SET_LOOP) - CASE_RETURN_STRING(WLC_DUMP) - CASE_RETURN_STRING(WLC_GET_MSGLEVEL) - CASE_RETURN_STRING(WLC_SET_MSGLEVEL) - CASE_RETURN_STRING(WLC_GET_PROMISC) - CASE_RETURN_STRING(WLC_SET_PROMISC) - CASE_RETURN_STRING(WLC_GET_RATE) - CASE_RETURN_STRING(WLC_GET_INSTANCE) - CASE_RETURN_STRING(WLC_GET_INFRA) - CASE_RETURN_STRING(WLC_SET_INFRA) - CASE_RETURN_STRING(WLC_GET_AUTH) - CASE_RETURN_STRING(WLC_SET_AUTH) - CASE_RETURN_STRING(WLC_GET_BSSID) - CASE_RETURN_STRING(WLC_SET_BSSID) - CASE_RETURN_STRING(WLC_GET_SSID) - CASE_RETURN_STRING(WLC_SET_SSID) - CASE_RETURN_STRING(WLC_RESTART) - CASE_RETURN_STRING(WLC_GET_CHANNEL) - CASE_RETURN_STRING(WLC_SET_CHANNEL) - CASE_RETURN_STRING(WLC_GET_SRL) - CASE_RETURN_STRING(WLC_SET_SRL) - CASE_RETURN_STRING(WLC_GET_LRL) - CASE_RETURN_STRING(WLC_SET_LRL) - CASE_RETURN_STRING(WLC_GET_PLCPHDR) - CASE_RETURN_STRING(WLC_SET_PLCPHDR) - CASE_RETURN_STRING(WLC_GET_RADIO) - CASE_RETURN_STRING(WLC_SET_RADIO) - CASE_RETURN_STRING(WLC_GET_PHYTYPE) - CASE_RETURN_STRING(WLC_DUMP_RATE) - CASE_RETURN_STRING(WLC_SET_RATE_PARAMS) - CASE_RETURN_STRING(WLC_GET_KEY) - CASE_RETURN_STRING(WLC_SET_KEY) - CASE_RETURN_STRING(WLC_GET_REGULATORY) - CASE_RETURN_STRING(WLC_SET_REGULATORY) - CASE_RETURN_STRING(WLC_GET_PASSIVE_SCAN) - CASE_RETURN_STRING(WLC_SET_PASSIVE_SCAN) - CASE_RETURN_STRING(WLC_SCAN) - CASE_RETURN_STRING(WLC_SCAN_RESULTS) - CASE_RETURN_STRING(WLC_DISASSOC) - CASE_RETURN_STRING(WLC_REASSOC) - CASE_RETURN_STRING(WLC_GET_ROAM_TRIGGER) - CASE_RETURN_STRING(WLC_SET_ROAM_TRIGGER) - CASE_RETURN_STRING(WLC_GET_ROAM_DELTA) - CASE_RETURN_STRING(WLC_SET_ROAM_DELTA) - CASE_RETURN_STRING(WLC_GET_ROAM_SCAN_PERIOD) - CASE_RETURN_STRING(WLC_SET_ROAM_SCAN_PERIOD) - CASE_RETURN_STRING(WLC_EVM) - CASE_RETURN_STRING(WLC_GET_TXANT) - CASE_RETURN_STRING(WLC_SET_TXANT) - CASE_RETURN_STRING(WLC_GET_ANTDIV) - CASE_RETURN_STRING(WLC_SET_ANTDIV) - CASE_RETURN_STRING(WLC_GET_CLOSED) - CASE_RETURN_STRING(WLC_SET_CLOSED) - CASE_RETURN_STRING(WLC_GET_MACLIST) - CASE_RETURN_STRING(WLC_SET_MACLIST) - CASE_RETURN_STRING(WLC_GET_RATESET) - CASE_RETURN_STRING(WLC_SET_RATESET) - CASE_RETURN_STRING(WLC_LONGTRAIN) - CASE_RETURN_STRING(WLC_GET_BCNPRD) - CASE_RETURN_STRING(WLC_SET_BCNPRD) - CASE_RETURN_STRING(WLC_GET_DTIMPRD) - CASE_RETURN_STRING(WLC_SET_DTIMPRD) - CASE_RETURN_STRING(WLC_GET_SROM) - CASE_RETURN_STRING(WLC_SET_SROM) - CASE_RETURN_STRING(WLC_GET_WEP_RESTRICT) - CASE_RETURN_STRING(WLC_SET_WEP_RESTRICT) - CASE_RETURN_STRING(WLC_GET_COUNTRY) - CASE_RETURN_STRING(WLC_SET_COUNTRY) - CASE_RETURN_STRING(WLC_GET_PM) - CASE_RETURN_STRING(WLC_SET_PM) - CASE_RETURN_STRING(WLC_GET_WAKE) - CASE_RETURN_STRING(WLC_SET_WAKE) - CASE_RETURN_STRING(WLC_GET_FORCELINK) - CASE_RETURN_STRING(WLC_SET_FORCELINK) - CASE_RETURN_STRING(WLC_FREQ_ACCURACY) - CASE_RETURN_STRING(WLC_CARRIER_SUPPRESS) - CASE_RETURN_STRING(WLC_GET_PHYREG) - CASE_RETURN_STRING(WLC_SET_PHYREG) - CASE_RETURN_STRING(WLC_GET_RADIOREG) - CASE_RETURN_STRING(WLC_SET_RADIOREG) - CASE_RETURN_STRING(WLC_GET_REVINFO) - CASE_RETURN_STRING(WLC_GET_UCANTDIV) - CASE_RETURN_STRING(WLC_SET_UCANTDIV) - CASE_RETURN_STRING(WLC_R_REG) - CASE_RETURN_STRING(WLC_W_REG) - CASE_RETURN_STRING(WLC_GET_MACMODE) - CASE_RETURN_STRING(WLC_SET_MACMODE) - CASE_RETURN_STRING(WLC_GET_MONITOR) - CASE_RETURN_STRING(WLC_SET_MONITOR) - CASE_RETURN_STRING(WLC_GET_GMODE) - CASE_RETURN_STRING(WLC_SET_GMODE) - CASE_RETURN_STRING(WLC_GET_LEGACY_ERP) - CASE_RETURN_STRING(WLC_SET_LEGACY_ERP) - CASE_RETURN_STRING(WLC_GET_RX_ANT) - CASE_RETURN_STRING(WLC_GET_CURR_RATESET) - CASE_RETURN_STRING(WLC_GET_SCANSUPPRESS) - CASE_RETURN_STRING(WLC_SET_SCANSUPPRESS) - CASE_RETURN_STRING(WLC_GET_AP) - CASE_RETURN_STRING(WLC_SET_AP) - CASE_RETURN_STRING(WLC_GET_EAP_RESTRICT) - CASE_RETURN_STRING(WLC_SET_EAP_RESTRICT) - CASE_RETURN_STRING(WLC_SCB_AUTHORIZE) - CASE_RETURN_STRING(WLC_SCB_DEAUTHORIZE) - CASE_RETURN_STRING(WLC_GET_WDSLIST) - CASE_RETURN_STRING(WLC_SET_WDSLIST) - CASE_RETURN_STRING(WLC_GET_ATIM) - CASE_RETURN_STRING(WLC_SET_ATIM) - CASE_RETURN_STRING(WLC_GET_RSSI) - CASE_RETURN_STRING(WLC_GET_PHYANTDIV) - CASE_RETURN_STRING(WLC_SET_PHYANTDIV) - CASE_RETURN_STRING(WLC_AP_RX_ONLY) - CASE_RETURN_STRING(WLC_GET_TX_PATH_PWR) - CASE_RETURN_STRING(WLC_SET_TX_PATH_PWR) - CASE_RETURN_STRING(WLC_GET_WSEC) - CASE_RETURN_STRING(WLC_SET_WSEC) - CASE_RETURN_STRING(WLC_GET_PHY_NOISE) - CASE_RETURN_STRING(WLC_GET_BSS_INFO) - CASE_RETURN_STRING(WLC_GET_PKTCNTS) - CASE_RETURN_STRING(WLC_GET_LAZYWDS) - CASE_RETURN_STRING(WLC_SET_LAZYWDS) - CASE_RETURN_STRING(WLC_GET_BANDLIST) - CASE_RETURN_STRING(WLC_GET_BAND) - CASE_RETURN_STRING(WLC_SET_BAND) - CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE) - CASE_RETURN_STRING(WLC_GET_SHORTSLOT) - CASE_RETURN_STRING(WLC_GET_SHORTSLOT_OVERRIDE) - CASE_RETURN_STRING(WLC_SET_SHORTSLOT_OVERRIDE) - CASE_RETURN_STRING(WLC_GET_SHORTSLOT_RESTRICT) - CASE_RETURN_STRING(WLC_SET_SHORTSLOT_RESTRICT) - CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION) - CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION_OVERRIDE) - CASE_RETURN_STRING(WLC_SET_GMODE_PROTECTION_OVERRIDE) - CASE_RETURN_STRING(WLC_UPGRADE) - CASE_RETURN_STRING(WLC_GET_IGNORE_BCNS) - CASE_RETURN_STRING(WLC_SET_IGNORE_BCNS) - CASE_RETURN_STRING(WLC_GET_SCB_TIMEOUT) - CASE_RETURN_STRING(WLC_SET_SCB_TIMEOUT) - CASE_RETURN_STRING(WLC_GET_ASSOCLIST) - CASE_RETURN_STRING(WLC_GET_CLK) - CASE_RETURN_STRING(WLC_SET_CLK) - CASE_RETURN_STRING(WLC_GET_UP) - CASE_RETURN_STRING(WLC_OUT) - CASE_RETURN_STRING(WLC_GET_WPA_AUTH) - CASE_RETURN_STRING(WLC_SET_WPA_AUTH) - CASE_RETURN_STRING(WLC_GET_UCFLAGS) - CASE_RETURN_STRING(WLC_SET_UCFLAGS) - CASE_RETURN_STRING(WLC_GET_PWRIDX) - CASE_RETURN_STRING(WLC_SET_PWRIDX) - CASE_RETURN_STRING(WLC_GET_TSSI) - CASE_RETURN_STRING(WLC_GET_SUP_RATESET_OVERRIDE) - CASE_RETURN_STRING(WLC_SET_SUP_RATESET_OVERRIDE) - CASE_RETURN_STRING(WLC_GET_PROTECTION_CONTROL) - CASE_RETURN_STRING(WLC_SET_PROTECTION_CONTROL) - CASE_RETURN_STRING(WLC_GET_PHYLIST) - CASE_RETURN_STRING(WLC_ENCRYPT_STRENGTH) - CASE_RETURN_STRING(WLC_DECRYPT_STATUS) - CASE_RETURN_STRING(WLC_GET_KEY_SEQ) - CASE_RETURN_STRING(WLC_GET_SCAN_CHANNEL_TIME) - CASE_RETURN_STRING(WLC_SET_SCAN_CHANNEL_TIME) - CASE_RETURN_STRING(WLC_GET_SCAN_UNASSOC_TIME) - CASE_RETURN_STRING(WLC_SET_SCAN_UNASSOC_TIME) - CASE_RETURN_STRING(WLC_GET_SCAN_HOME_TIME) - CASE_RETURN_STRING(WLC_SET_SCAN_HOME_TIME) - CASE_RETURN_STRING(WLC_GET_SCAN_NPROBES) - CASE_RETURN_STRING(WLC_SET_SCAN_NPROBES) - CASE_RETURN_STRING(WLC_GET_PRB_RESP_TIMEOUT) - CASE_RETURN_STRING(WLC_SET_PRB_RESP_TIMEOUT) - CASE_RETURN_STRING(WLC_GET_ATTEN) - CASE_RETURN_STRING(WLC_SET_ATTEN) - CASE_RETURN_STRING(WLC_GET_SHMEM) - CASE_RETURN_STRING(WLC_SET_SHMEM) - CASE_RETURN_STRING(WLC_SET_WSEC_TEST) - CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE_FOR_REASON) - CASE_RETURN_STRING(WLC_TKIP_COUNTERMEASURES) - CASE_RETURN_STRING(WLC_GET_PIOMODE) - CASE_RETURN_STRING(WLC_SET_PIOMODE) - CASE_RETURN_STRING(WLC_SET_ASSOC_PREFER) - CASE_RETURN_STRING(WLC_GET_ASSOC_PREFER) - CASE_RETURN_STRING(WLC_SET_ROAM_PREFER) - CASE_RETURN_STRING(WLC_GET_ROAM_PREFER) - CASE_RETURN_STRING(WLC_SET_LED) - CASE_RETURN_STRING(WLC_GET_LED) - CASE_RETURN_STRING(WLC_GET_INTERFERENCE_MODE) - CASE_RETURN_STRING(WLC_SET_INTERFERENCE_MODE) - CASE_RETURN_STRING(WLC_GET_CHANNEL_QA) - CASE_RETURN_STRING(WLC_START_CHANNEL_QA) - CASE_RETURN_STRING(WLC_GET_CHANNEL_SEL) - CASE_RETURN_STRING(WLC_START_CHANNEL_SEL) - CASE_RETURN_STRING(WLC_GET_VALID_CHANNELS) - CASE_RETURN_STRING(WLC_GET_FAKEFRAG) - CASE_RETURN_STRING(WLC_SET_FAKEFRAG) - CASE_RETURN_STRING(WLC_GET_PWROUT_PERCENTAGE) - CASE_RETURN_STRING(WLC_SET_PWROUT_PERCENTAGE) - CASE_RETURN_STRING(WLC_SET_BAD_FRAME_PREEMPT) - CASE_RETURN_STRING(WLC_GET_BAD_FRAME_PREEMPT) - CASE_RETURN_STRING(WLC_SET_LEAP_LIST) - CASE_RETURN_STRING(WLC_GET_LEAP_LIST) - CASE_RETURN_STRING(WLC_GET_CWMIN) - CASE_RETURN_STRING(WLC_SET_CWMIN) - CASE_RETURN_STRING(WLC_GET_CWMAX) - CASE_RETURN_STRING(WLC_SET_CWMAX) - CASE_RETURN_STRING(WLC_GET_WET) - CASE_RETURN_STRING(WLC_SET_WET) - CASE_RETURN_STRING(WLC_GET_KEY_PRIMARY) - CASE_RETURN_STRING(WLC_SET_KEY_PRIMARY) - CASE_RETURN_STRING(WLC_GET_ACI_ARGS) - CASE_RETURN_STRING(WLC_SET_ACI_ARGS) - CASE_RETURN_STRING(WLC_UNSET_CALLBACK) - CASE_RETURN_STRING(WLC_SET_CALLBACK) - CASE_RETURN_STRING(WLC_GET_RADAR) - CASE_RETURN_STRING(WLC_SET_RADAR) - CASE_RETURN_STRING(WLC_SET_SPECT_MANAGMENT) - CASE_RETURN_STRING(WLC_GET_SPECT_MANAGMENT) - CASE_RETURN_STRING(WLC_WDS_GET_REMOTE_HWADDR) - CASE_RETURN_STRING(WLC_WDS_GET_WPA_SUP) - CASE_RETURN_STRING(WLC_SET_CS_SCAN_TIMER) - CASE_RETURN_STRING(WLC_GET_CS_SCAN_TIMER) - CASE_RETURN_STRING(WLC_MEASURE_REQUEST) - CASE_RETURN_STRING(WLC_INIT) - CASE_RETURN_STRING(WLC_SEND_QUIET) - CASE_RETURN_STRING(WLC_KEEPALIVE) - CASE_RETURN_STRING(WLC_SEND_PWR_CONSTRAINT) - CASE_RETURN_STRING(WLC_UPGRADE_STATUS) - CASE_RETURN_STRING(WLC_GET_SCAN_PASSIVE_TIME) - CASE_RETURN_STRING(WLC_SET_SCAN_PASSIVE_TIME) - CASE_RETURN_STRING(WLC_LEGACY_LINK_BEHAVIOR) - CASE_RETURN_STRING(WLC_GET_CHANNELS_IN_COUNTRY) - CASE_RETURN_STRING(WLC_GET_COUNTRY_LIST) - CASE_RETURN_STRING(WLC_GET_VAR) - CASE_RETURN_STRING(WLC_SET_VAR) - CASE_RETURN_STRING(WLC_NVRAM_GET) - CASE_RETURN_STRING(WLC_NVRAM_SET) - CASE_RETURN_STRING(WLC_NVRAM_DUMP) - CASE_RETURN_STRING(WLC_REBOOT) - CASE_RETURN_STRING(WLC_SET_WSEC_PMK) - CASE_RETURN_STRING(WLC_GET_AUTH_MODE) - CASE_RETURN_STRING(WLC_SET_AUTH_MODE) - CASE_RETURN_STRING(WLC_GET_WAKEENTRY) - CASE_RETURN_STRING(WLC_SET_WAKEENTRY) - CASE_RETURN_STRING(WLC_NDCONFIG_ITEM) - CASE_RETURN_STRING(WLC_NVOTPW) - CASE_RETURN_STRING(WLC_OTPW) - CASE_RETURN_STRING(WLC_IOV_BLOCK_GET) - CASE_RETURN_STRING(WLC_IOV_MODULES_GET) - CASE_RETURN_STRING(WLC_SOFT_RESET) - CASE_RETURN_STRING(WLC_GET_ALLOW_MODE) - CASE_RETURN_STRING(WLC_SET_ALLOW_MODE) - CASE_RETURN_STRING(WLC_GET_DESIRED_BSSID) - CASE_RETURN_STRING(WLC_SET_DESIRED_BSSID) - CASE_RETURN_STRING(WLC_DISASSOC_MYAP) - CASE_RETURN_STRING(WLC_GET_NBANDS) - CASE_RETURN_STRING(WLC_GET_BANDSTATES) - CASE_RETURN_STRING(WLC_GET_WLC_BSS_INFO) - CASE_RETURN_STRING(WLC_GET_ASSOC_INFO) - CASE_RETURN_STRING(WLC_GET_OID_PHY) - CASE_RETURN_STRING(WLC_SET_OID_PHY) - CASE_RETURN_STRING(WLC_SET_ASSOC_TIME) - CASE_RETURN_STRING(WLC_GET_DESIRED_SSID) - CASE_RETURN_STRING(WLC_GET_CHANSPEC) - CASE_RETURN_STRING(WLC_GET_ASSOC_STATE) - CASE_RETURN_STRING(WLC_SET_PHY_STATE) - CASE_RETURN_STRING(WLC_GET_SCAN_PENDING) - CASE_RETURN_STRING(WLC_GET_SCANREQ_PENDING) - CASE_RETURN_STRING(WLC_GET_PREV_ROAM_REASON) - CASE_RETURN_STRING(WLC_SET_PREV_ROAM_REASON) - CASE_RETURN_STRING(WLC_GET_BANDSTATES_PI) - CASE_RETURN_STRING(WLC_GET_PHY_STATE) - CASE_RETURN_STRING(WLC_GET_BSS_WPA_RSN) - CASE_RETURN_STRING(WLC_GET_BSS_WPA2_RSN) - CASE_RETURN_STRING(WLC_GET_BSS_BCN_TS) - CASE_RETURN_STRING(WLC_GET_INT_DISASSOC) - CASE_RETURN_STRING(WLC_SET_NUM_PEERS) - CASE_RETURN_STRING(WLC_GET_NUM_BSS) - CASE_RETURN_STRING(WLC_GET_WSEC_PMK) - CASE_RETURN_STRING(WLC_GET_RANDOM_BYTES) - CASE_RETURN_STRING(WLC_LAST) - default: - return "Unknown Command"; - } + switch (ioctl) + { + CASE_RETURN_STRING(WLC_GET_MAGIC) + CASE_RETURN_STRING(WLC_GET_VERSION) + CASE_RETURN_STRING(WLC_UP) + CASE_RETURN_STRING(WLC_DOWN) + CASE_RETURN_STRING(WLC_GET_LOOP) + CASE_RETURN_STRING(WLC_SET_LOOP) + CASE_RETURN_STRING(WLC_DUMP) + CASE_RETURN_STRING(WLC_GET_MSGLEVEL) + CASE_RETURN_STRING(WLC_SET_MSGLEVEL) + CASE_RETURN_STRING(WLC_GET_PROMISC) + CASE_RETURN_STRING(WLC_SET_PROMISC) + CASE_RETURN_STRING(WLC_GET_RATE) + CASE_RETURN_STRING(WLC_GET_INSTANCE) + CASE_RETURN_STRING(WLC_GET_INFRA) + CASE_RETURN_STRING(WLC_SET_INFRA) + CASE_RETURN_STRING(WLC_GET_AUTH) + CASE_RETURN_STRING(WLC_SET_AUTH) + CASE_RETURN_STRING(WLC_GET_BSSID) + CASE_RETURN_STRING(WLC_SET_BSSID) + CASE_RETURN_STRING(WLC_GET_SSID) + CASE_RETURN_STRING(WLC_SET_SSID) + CASE_RETURN_STRING(WLC_RESTART) + CASE_RETURN_STRING(WLC_GET_CHANNEL) + CASE_RETURN_STRING(WLC_SET_CHANNEL) + CASE_RETURN_STRING(WLC_GET_SRL) + CASE_RETURN_STRING(WLC_SET_SRL) + CASE_RETURN_STRING(WLC_GET_LRL) + CASE_RETURN_STRING(WLC_SET_LRL) + CASE_RETURN_STRING(WLC_GET_PLCPHDR) + CASE_RETURN_STRING(WLC_SET_PLCPHDR) + CASE_RETURN_STRING(WLC_GET_RADIO) + CASE_RETURN_STRING(WLC_SET_RADIO) + CASE_RETURN_STRING(WLC_GET_PHYTYPE) + CASE_RETURN_STRING(WLC_DUMP_RATE) + CASE_RETURN_STRING(WLC_SET_RATE_PARAMS) + CASE_RETURN_STRING(WLC_GET_KEY) + CASE_RETURN_STRING(WLC_SET_KEY) + CASE_RETURN_STRING(WLC_GET_REGULATORY) + CASE_RETURN_STRING(WLC_SET_REGULATORY) + CASE_RETURN_STRING(WLC_GET_PASSIVE_SCAN) + CASE_RETURN_STRING(WLC_SET_PASSIVE_SCAN) + CASE_RETURN_STRING(WLC_SCAN) + CASE_RETURN_STRING(WLC_SCAN_RESULTS) + CASE_RETURN_STRING(WLC_DISASSOC) + CASE_RETURN_STRING(WLC_REASSOC) + CASE_RETURN_STRING(WLC_GET_ROAM_TRIGGER) + CASE_RETURN_STRING(WLC_SET_ROAM_TRIGGER) + CASE_RETURN_STRING(WLC_GET_ROAM_DELTA) + CASE_RETURN_STRING(WLC_SET_ROAM_DELTA) + CASE_RETURN_STRING(WLC_GET_ROAM_SCAN_PERIOD) + CASE_RETURN_STRING(WLC_SET_ROAM_SCAN_PERIOD) + CASE_RETURN_STRING(WLC_EVM) + CASE_RETURN_STRING(WLC_GET_TXANT) + CASE_RETURN_STRING(WLC_SET_TXANT) + CASE_RETURN_STRING(WLC_GET_ANTDIV) + CASE_RETURN_STRING(WLC_SET_ANTDIV) + CASE_RETURN_STRING(WLC_GET_CLOSED) + CASE_RETURN_STRING(WLC_SET_CLOSED) + CASE_RETURN_STRING(WLC_GET_MACLIST) + CASE_RETURN_STRING(WLC_SET_MACLIST) + CASE_RETURN_STRING(WLC_GET_RATESET) + CASE_RETURN_STRING(WLC_SET_RATESET) + CASE_RETURN_STRING(WLC_LONGTRAIN) + CASE_RETURN_STRING(WLC_GET_BCNPRD) + CASE_RETURN_STRING(WLC_SET_BCNPRD) + CASE_RETURN_STRING(WLC_GET_DTIMPRD) + CASE_RETURN_STRING(WLC_SET_DTIMPRD) + CASE_RETURN_STRING(WLC_GET_SROM) + CASE_RETURN_STRING(WLC_SET_SROM) + CASE_RETURN_STRING(WLC_GET_WEP_RESTRICT) + CASE_RETURN_STRING(WLC_SET_WEP_RESTRICT) + CASE_RETURN_STRING(WLC_GET_COUNTRY) + CASE_RETURN_STRING(WLC_SET_COUNTRY) + CASE_RETURN_STRING(WLC_GET_PM) + CASE_RETURN_STRING(WLC_SET_PM) + CASE_RETURN_STRING(WLC_GET_WAKE) + CASE_RETURN_STRING(WLC_SET_WAKE) + CASE_RETURN_STRING(WLC_GET_FORCELINK) + CASE_RETURN_STRING(WLC_SET_FORCELINK) + CASE_RETURN_STRING(WLC_FREQ_ACCURACY) + CASE_RETURN_STRING(WLC_CARRIER_SUPPRESS) + CASE_RETURN_STRING(WLC_GET_PHYREG) + CASE_RETURN_STRING(WLC_SET_PHYREG) + CASE_RETURN_STRING(WLC_GET_RADIOREG) + CASE_RETURN_STRING(WLC_SET_RADIOREG) + CASE_RETURN_STRING(WLC_GET_REVINFO) + CASE_RETURN_STRING(WLC_GET_UCANTDIV) + CASE_RETURN_STRING(WLC_SET_UCANTDIV) + CASE_RETURN_STRING(WLC_R_REG) + CASE_RETURN_STRING(WLC_W_REG) + CASE_RETURN_STRING(WLC_GET_MACMODE) + CASE_RETURN_STRING(WLC_SET_MACMODE) + CASE_RETURN_STRING(WLC_GET_MONITOR) + CASE_RETURN_STRING(WLC_SET_MONITOR) + CASE_RETURN_STRING(WLC_GET_GMODE) + CASE_RETURN_STRING(WLC_SET_GMODE) + CASE_RETURN_STRING(WLC_GET_LEGACY_ERP) + CASE_RETURN_STRING(WLC_SET_LEGACY_ERP) + CASE_RETURN_STRING(WLC_GET_RX_ANT) + CASE_RETURN_STRING(WLC_GET_CURR_RATESET) + CASE_RETURN_STRING(WLC_GET_SCANSUPPRESS) + CASE_RETURN_STRING(WLC_SET_SCANSUPPRESS) + CASE_RETURN_STRING(WLC_GET_AP) + CASE_RETURN_STRING(WLC_SET_AP) + CASE_RETURN_STRING(WLC_GET_EAP_RESTRICT) + CASE_RETURN_STRING(WLC_SET_EAP_RESTRICT) + CASE_RETURN_STRING(WLC_SCB_AUTHORIZE) + CASE_RETURN_STRING(WLC_SCB_DEAUTHORIZE) + CASE_RETURN_STRING(WLC_GET_WDSLIST) + CASE_RETURN_STRING(WLC_SET_WDSLIST) + CASE_RETURN_STRING(WLC_GET_ATIM) + CASE_RETURN_STRING(WLC_SET_ATIM) + CASE_RETURN_STRING(WLC_GET_RSSI) + CASE_RETURN_STRING(WLC_GET_PHYANTDIV) + CASE_RETURN_STRING(WLC_SET_PHYANTDIV) + CASE_RETURN_STRING(WLC_AP_RX_ONLY) + CASE_RETURN_STRING(WLC_GET_TX_PATH_PWR) + CASE_RETURN_STRING(WLC_SET_TX_PATH_PWR) + CASE_RETURN_STRING(WLC_GET_WSEC) + CASE_RETURN_STRING(WLC_SET_WSEC) + CASE_RETURN_STRING(WLC_GET_PHY_NOISE) + CASE_RETURN_STRING(WLC_GET_BSS_INFO) + CASE_RETURN_STRING(WLC_GET_PKTCNTS) + CASE_RETURN_STRING(WLC_GET_LAZYWDS) + CASE_RETURN_STRING(WLC_SET_LAZYWDS) + CASE_RETURN_STRING(WLC_GET_BANDLIST) + CASE_RETURN_STRING(WLC_GET_BAND) + CASE_RETURN_STRING(WLC_SET_BAND) + CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE) + CASE_RETURN_STRING(WLC_GET_SHORTSLOT) + CASE_RETURN_STRING(WLC_GET_SHORTSLOT_OVERRIDE) + CASE_RETURN_STRING(WLC_SET_SHORTSLOT_OVERRIDE) + CASE_RETURN_STRING(WLC_GET_SHORTSLOT_RESTRICT) + CASE_RETURN_STRING(WLC_SET_SHORTSLOT_RESTRICT) + CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION) + CASE_RETURN_STRING(WLC_GET_GMODE_PROTECTION_OVERRIDE) + CASE_RETURN_STRING(WLC_SET_GMODE_PROTECTION_OVERRIDE) + CASE_RETURN_STRING(WLC_UPGRADE) + CASE_RETURN_STRING(WLC_GET_IGNORE_BCNS) + CASE_RETURN_STRING(WLC_SET_IGNORE_BCNS) + CASE_RETURN_STRING(WLC_GET_SCB_TIMEOUT) + CASE_RETURN_STRING(WLC_SET_SCB_TIMEOUT) + CASE_RETURN_STRING(WLC_GET_ASSOCLIST) + CASE_RETURN_STRING(WLC_GET_CLK) + CASE_RETURN_STRING(WLC_SET_CLK) + CASE_RETURN_STRING(WLC_GET_UP) + CASE_RETURN_STRING(WLC_OUT) + CASE_RETURN_STRING(WLC_GET_WPA_AUTH) + CASE_RETURN_STRING(WLC_SET_WPA_AUTH) + CASE_RETURN_STRING(WLC_GET_UCFLAGS) + CASE_RETURN_STRING(WLC_SET_UCFLAGS) + CASE_RETURN_STRING(WLC_GET_PWRIDX) + CASE_RETURN_STRING(WLC_SET_PWRIDX) + CASE_RETURN_STRING(WLC_GET_TSSI) + CASE_RETURN_STRING(WLC_GET_SUP_RATESET_OVERRIDE) + CASE_RETURN_STRING(WLC_SET_SUP_RATESET_OVERRIDE) + CASE_RETURN_STRING(WLC_GET_PROTECTION_CONTROL) + CASE_RETURN_STRING(WLC_SET_PROTECTION_CONTROL) + CASE_RETURN_STRING(WLC_GET_PHYLIST) + CASE_RETURN_STRING(WLC_ENCRYPT_STRENGTH) + CASE_RETURN_STRING(WLC_DECRYPT_STATUS) + CASE_RETURN_STRING(WLC_GET_KEY_SEQ) + CASE_RETURN_STRING(WLC_GET_SCAN_CHANNEL_TIME) + CASE_RETURN_STRING(WLC_SET_SCAN_CHANNEL_TIME) + CASE_RETURN_STRING(WLC_GET_SCAN_UNASSOC_TIME) + CASE_RETURN_STRING(WLC_SET_SCAN_UNASSOC_TIME) + CASE_RETURN_STRING(WLC_GET_SCAN_HOME_TIME) + CASE_RETURN_STRING(WLC_SET_SCAN_HOME_TIME) + CASE_RETURN_STRING(WLC_GET_SCAN_NPROBES) + CASE_RETURN_STRING(WLC_SET_SCAN_NPROBES) + CASE_RETURN_STRING(WLC_GET_PRB_RESP_TIMEOUT) + CASE_RETURN_STRING(WLC_SET_PRB_RESP_TIMEOUT) + CASE_RETURN_STRING(WLC_GET_ATTEN) + CASE_RETURN_STRING(WLC_SET_ATTEN) + CASE_RETURN_STRING(WLC_GET_SHMEM) + CASE_RETURN_STRING(WLC_SET_SHMEM) + CASE_RETURN_STRING(WLC_SET_WSEC_TEST) + CASE_RETURN_STRING(WLC_SCB_DEAUTHENTICATE_FOR_REASON) + CASE_RETURN_STRING(WLC_TKIP_COUNTERMEASURES) + CASE_RETURN_STRING(WLC_GET_PIOMODE) + CASE_RETURN_STRING(WLC_SET_PIOMODE) + CASE_RETURN_STRING(WLC_SET_ASSOC_PREFER) + CASE_RETURN_STRING(WLC_GET_ASSOC_PREFER) + CASE_RETURN_STRING(WLC_SET_ROAM_PREFER) + CASE_RETURN_STRING(WLC_GET_ROAM_PREFER) + CASE_RETURN_STRING(WLC_SET_LED) + CASE_RETURN_STRING(WLC_GET_LED) + CASE_RETURN_STRING(WLC_GET_INTERFERENCE_MODE) + CASE_RETURN_STRING(WLC_SET_INTERFERENCE_MODE) + CASE_RETURN_STRING(WLC_GET_CHANNEL_QA) + CASE_RETURN_STRING(WLC_START_CHANNEL_QA) + CASE_RETURN_STRING(WLC_GET_CHANNEL_SEL) + CASE_RETURN_STRING(WLC_START_CHANNEL_SEL) + CASE_RETURN_STRING(WLC_GET_VALID_CHANNELS) + CASE_RETURN_STRING(WLC_GET_FAKEFRAG) + CASE_RETURN_STRING(WLC_SET_FAKEFRAG) + CASE_RETURN_STRING(WLC_GET_PWROUT_PERCENTAGE) + CASE_RETURN_STRING(WLC_SET_PWROUT_PERCENTAGE) + CASE_RETURN_STRING(WLC_SET_BAD_FRAME_PREEMPT) + CASE_RETURN_STRING(WLC_GET_BAD_FRAME_PREEMPT) + CASE_RETURN_STRING(WLC_SET_LEAP_LIST) + CASE_RETURN_STRING(WLC_GET_LEAP_LIST) + CASE_RETURN_STRING(WLC_GET_CWMIN) + CASE_RETURN_STRING(WLC_SET_CWMIN) + CASE_RETURN_STRING(WLC_GET_CWMAX) + CASE_RETURN_STRING(WLC_SET_CWMAX) + CASE_RETURN_STRING(WLC_GET_WET) + CASE_RETURN_STRING(WLC_SET_WET) + CASE_RETURN_STRING(WLC_GET_KEY_PRIMARY) + CASE_RETURN_STRING(WLC_SET_KEY_PRIMARY) + CASE_RETURN_STRING(WLC_GET_ACI_ARGS) + CASE_RETURN_STRING(WLC_SET_ACI_ARGS) + CASE_RETURN_STRING(WLC_UNSET_CALLBACK) + CASE_RETURN_STRING(WLC_SET_CALLBACK) + CASE_RETURN_STRING(WLC_GET_RADAR) + CASE_RETURN_STRING(WLC_SET_RADAR) + CASE_RETURN_STRING(WLC_SET_SPECT_MANAGMENT) + CASE_RETURN_STRING(WLC_GET_SPECT_MANAGMENT) + CASE_RETURN_STRING(WLC_WDS_GET_REMOTE_HWADDR) + CASE_RETURN_STRING(WLC_WDS_GET_WPA_SUP) + CASE_RETURN_STRING(WLC_SET_CS_SCAN_TIMER) + CASE_RETURN_STRING(WLC_GET_CS_SCAN_TIMER) + CASE_RETURN_STRING(WLC_MEASURE_REQUEST) + CASE_RETURN_STRING(WLC_INIT) + CASE_RETURN_STRING(WLC_SEND_QUIET) + CASE_RETURN_STRING(WLC_KEEPALIVE) + CASE_RETURN_STRING(WLC_SEND_PWR_CONSTRAINT) + CASE_RETURN_STRING(WLC_UPGRADE_STATUS) + CASE_RETURN_STRING(WLC_GET_SCAN_PASSIVE_TIME) + CASE_RETURN_STRING(WLC_SET_SCAN_PASSIVE_TIME) + CASE_RETURN_STRING(WLC_LEGACY_LINK_BEHAVIOR) + CASE_RETURN_STRING(WLC_GET_CHANNELS_IN_COUNTRY) + CASE_RETURN_STRING(WLC_GET_COUNTRY_LIST) + CASE_RETURN_STRING(WLC_GET_VAR) + CASE_RETURN_STRING(WLC_SET_VAR) + CASE_RETURN_STRING(WLC_NVRAM_GET) + CASE_RETURN_STRING(WLC_NVRAM_SET) + CASE_RETURN_STRING(WLC_NVRAM_DUMP) + CASE_RETURN_STRING(WLC_REBOOT) + CASE_RETURN_STRING(WLC_SET_WSEC_PMK) + CASE_RETURN_STRING(WLC_GET_AUTH_MODE) + CASE_RETURN_STRING(WLC_SET_AUTH_MODE) + CASE_RETURN_STRING(WLC_GET_WAKEENTRY) + CASE_RETURN_STRING(WLC_SET_WAKEENTRY) + CASE_RETURN_STRING(WLC_NDCONFIG_ITEM) + CASE_RETURN_STRING(WLC_NVOTPW) + CASE_RETURN_STRING(WLC_OTPW) + CASE_RETURN_STRING(WLC_IOV_BLOCK_GET) + CASE_RETURN_STRING(WLC_IOV_MODULES_GET) + CASE_RETURN_STRING(WLC_SOFT_RESET) + CASE_RETURN_STRING(WLC_GET_ALLOW_MODE) + CASE_RETURN_STRING(WLC_SET_ALLOW_MODE) + CASE_RETURN_STRING(WLC_GET_DESIRED_BSSID) + CASE_RETURN_STRING(WLC_SET_DESIRED_BSSID) + CASE_RETURN_STRING(WLC_DISASSOC_MYAP) + CASE_RETURN_STRING(WLC_GET_NBANDS) + CASE_RETURN_STRING(WLC_GET_BANDSTATES) + CASE_RETURN_STRING(WLC_GET_WLC_BSS_INFO) + CASE_RETURN_STRING(WLC_GET_ASSOC_INFO) + CASE_RETURN_STRING(WLC_GET_OID_PHY) + CASE_RETURN_STRING(WLC_SET_OID_PHY) + CASE_RETURN_STRING(WLC_SET_ASSOC_TIME) + CASE_RETURN_STRING(WLC_GET_DESIRED_SSID) + CASE_RETURN_STRING(WLC_GET_CHANSPEC) + CASE_RETURN_STRING(WLC_GET_ASSOC_STATE) + CASE_RETURN_STRING(WLC_SET_PHY_STATE) + CASE_RETURN_STRING(WLC_GET_SCAN_PENDING) + CASE_RETURN_STRING(WLC_GET_SCANREQ_PENDING) + CASE_RETURN_STRING(WLC_GET_PREV_ROAM_REASON) + CASE_RETURN_STRING(WLC_SET_PREV_ROAM_REASON) + CASE_RETURN_STRING(WLC_GET_BANDSTATES_PI) + CASE_RETURN_STRING(WLC_GET_PHY_STATE) + CASE_RETURN_STRING(WLC_GET_BSS_WPA_RSN) + CASE_RETURN_STRING(WLC_GET_BSS_WPA2_RSN) + CASE_RETURN_STRING(WLC_GET_BSS_BCN_TS) + CASE_RETURN_STRING(WLC_GET_INT_DISASSOC) + CASE_RETURN_STRING(WLC_SET_NUM_PEERS) + CASE_RETURN_STRING(WLC_GET_NUM_BSS) + CASE_RETURN_STRING(WLC_GET_WSEC_PMK) + CASE_RETURN_STRING(WLC_GET_RANDOM_BYTES) + CASE_RETURN_STRING(WLC_LAST) + default: + return "Unknown Command"; + } } #endif /* WPRINT_ENABLE_WHD_DEBUG */ void whd_convert_security_type_to_string(whd_security_t security, char *out_str, uint16_t out_str_len) { - if (security == WHD_SECURITY_OPEN) { - strncat(out_str, " Open", out_str_len); - } - if (security & WEP_ENABLED) { - strncat(out_str, " WEP", out_str_len); - } - if (security & WPA3_SECURITY) { - strncat(out_str, " WPA3", out_str_len); - } - if (security & WPA2_SECURITY) { - strncat(out_str, " WPA2", out_str_len); - } - if (security & WPA_SECURITY) { - strncat(out_str, " WPA", out_str_len); - } - if (security & AES_ENABLED) { - strncat(out_str, " AES", out_str_len); - } - if (security & TKIP_ENABLED) { - strncat(out_str, " TKIP", out_str_len); - } - if (security & SHARED_ENABLED) { - strncat(out_str, " SHARED", out_str_len); - } - if (security & ENTERPRISE_ENABLED) { - strncat(out_str, " Enterprise", out_str_len); - } - if (security & WPS_ENABLED) { - strncat(out_str, " WPS", out_str_len); - } - if (security & FBT_ENABLED) { - strncat(out_str, " FBT", out_str_len); - } - if (security & IBSS_ENABLED) { - strncat(out_str, " IBSS", out_str_len); - } - if (security == WHD_SECURITY_UNKNOWN) { - strncat(out_str, " Unknown", out_str_len); - } - if (!(security & ENTERPRISE_ENABLED) && (security != WHD_SECURITY_OPEN) && - (security != WHD_SECURITY_UNKNOWN)) { - strncat(out_str, " PSK", out_str_len); - } + if (security == WHD_SECURITY_OPEN) + { + strncat(out_str, " Open", out_str_len); + } + if (security & WEP_ENABLED) + { + strncat(out_str, " WEP", out_str_len); + } + if (security & WPA3_SECURITY) + { + strncat(out_str, " WPA3", out_str_len); + } + if (security & WPA2_SECURITY) + { + strncat(out_str, " WPA2", out_str_len); + } + if (security & WPA_SECURITY) + { + strncat(out_str, " WPA", out_str_len); + } + if (security & AES_ENABLED) + { + strncat(out_str, " AES", out_str_len); + } + if (security & TKIP_ENABLED) + { + strncat(out_str, " TKIP", out_str_len); + } + if (security & SHARED_ENABLED) + { + strncat(out_str, " SHARED", out_str_len); + } + if (security & ENTERPRISE_ENABLED) + { + strncat(out_str, " Enterprise", out_str_len); + } + if (security & WPS_ENABLED) + { + strncat(out_str, " WPS", out_str_len); + } + if (security & FBT_ENABLED) + { + strncat(out_str, " FBT", out_str_len); + } + if (security & IBSS_ENABLED) + { + strncat(out_str, " IBSS", out_str_len); + } + if (security == WHD_SECURITY_UNKNOWN) + { + strncat(out_str, " Unknown", out_str_len); + } + if (!(security & ENTERPRISE_ENABLED) && (security != WHD_SECURITY_OPEN) && + (security != WHD_SECURITY_UNKNOWN) ) + { + strncat(out_str, " PSK", out_str_len); + } } /*! @@ -816,88 +885,89 @@ void whd_convert_security_type_to_string(whd_security_t security, char *out_str, void whd_print_scan_result(whd_scan_result_t *record) { - const char *str = NULL; - char sec_type_string[40] = { 0 }; - - switch (record->bss_type) { - case WHD_BSS_TYPE_ADHOC: - str = "Adhoc"; - break; - - case WHD_BSS_TYPE_INFRASTRUCTURE: - str = "Infra"; - break; - - case WHD_BSS_TYPE_ANY: - str = "Any"; - break; - - case WHD_BSS_TYPE_MESH: - case WHD_BSS_TYPE_UNKNOWN: - str = "Unknown"; - break; - - default: - str = "?"; - break; - } + const char *str = NULL; + char sec_type_string[40] = { 0 }; + + switch (record->bss_type) + { + case WHD_BSS_TYPE_ADHOC: + str = "Adhoc"; + break; + + case WHD_BSS_TYPE_INFRASTRUCTURE: + str = "Infra"; + break; + + case WHD_BSS_TYPE_ANY: + str = "Any"; + break; + + case WHD_BSS_TYPE_MESH: + case WHD_BSS_TYPE_UNKNOWN: + str = "Unknown"; + break; + + default: + str = "?"; + break; + } UNUSED_PARAMETER(str); - WPRINT_MACRO(("%5s ", str)); - WPRINT_MACRO(("%02X:%02X:%02X:%02X:%02X:%02X ", record->BSSID.octet[0], record->BSSID.octet[1], - record->BSSID.octet[2], record->BSSID.octet[3], record->BSSID.octet[4], - record->BSSID.octet[5])); + WPRINT_INFO(("%5s ", str)); + WPRINT_INFO(("%02X:%02X:%02X:%02X:%02X:%02X ", record->BSSID.octet[0], record->BSSID.octet[1], + record->BSSID.octet[2], record->BSSID.octet[3], record->BSSID.octet[4], + record->BSSID.octet[5])); if (record->flags & WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL) { - WPRINT_MACRO(("OFF ")); + WPRINT_INFO(("OFF ")); } else { - WPRINT_MACRO(("%d ", record->signal_strength)); + WPRINT_INFO(("%d ", record->signal_strength)); } if (record->max_data_rate < 100000) { - WPRINT_MACRO((" %.1f ", (double)(record->max_data_rate / 1000.0))); + WPRINT_INFO((" %.1f ", (double)(record->max_data_rate / 1000.0))); } else { - WPRINT_MACRO(("%.1f ", (double)(record->max_data_rate / 1000.0))); + WPRINT_INFO(("%.1f ", (double)(record->max_data_rate / 1000.0))); } - WPRINT_MACRO((" %3d ", record->channel)); + WPRINT_INFO((" %3d ", record->channel)); - whd_convert_security_type_to_string(record->security, sec_type_string, (sizeof(sec_type_string) - 1)); + whd_convert_security_type_to_string(record->security, sec_type_string, (sizeof(sec_type_string) - 1) ); - WPRINT_MACRO(("%-20s ", sec_type_string)); - WPRINT_MACRO((" %-32s ", record->SSID.value)); + WPRINT_INFO(("%-20s ", sec_type_string)); + WPRINT_INFO((" %-32s ", record->SSID.value)); if (record->ccode[0] != '\0') { - WPRINT_MACRO(("%c%c ", record->ccode[0], record->ccode[1])); + WPRINT_INFO(("%c%c ", record->ccode[0], record->ccode[1])); } else { - WPRINT_MACRO((" ")); + WPRINT_INFO((" ")); } if (record->flags & WHD_SCAN_RESULT_FLAG_BEACON) { - WPRINT_MACRO((" %-15s", " BEACON")); + WPRINT_INFO((" %-15s", " BEACON")); } else { - WPRINT_MACRO((" %-15s", " PROBE ")); + WPRINT_INFO((" %-15s", " PROBE ")); } - WPRINT_MACRO(("\n")); + WPRINT_INFO(("\n")); } void whd_hexdump(uint8_t *data, uint32_t data_len) { - uint32_t i; - uint8_t buff[17] = { 0 }; + uint32_t i; + uint8_t buff[17] = {0}; UNUSED_PARAMETER(buff); for (i = 0; i < data_len; i++) { if ((i % 16) == 0) { if (i != 0) { - WPRINT_MACRO((" %s\n", buff)); + fprintf(stderr, " %s\n", buff); } - WPRINT_MACRO(("%04" PRIx32 " ", i)); + fprintf(stderr, "%04" PRIx32 " ", i); } - WPRINT_MACRO((" %02x", data[i])); + fprintf(stderr, " %02x", data[i]); if ((data[i] < 0x20) || (data[i] > 0x7e)) { buff[i % 16] = '.'; @@ -908,10 +978,10 @@ void whd_hexdump(uint8_t *data, uint32_t data_len) buff[(i % 16) + 1] = '\0'; } while ((i % 16) != 0) { - WPRINT_MACRO((" ")); + fprintf(stderr, " "); i++; } - WPRINT_MACRO((" %s\n", buff)); + fprintf(stderr, " %s\n", buff); } void whd_ioctl_info_to_string(uint32_t cmd, char *ioctl_str, uint16_t ioctl_str_len) @@ -972,133 +1042,174 @@ void whd_ioctl_info_to_string(uint32_t cmd, char *ioctl_str, uint16_t ioctl_str_ void whd_event_info_to_string(uint32_t cmd, uint16_t flag, uint32_t reason, char *ioctl_str, uint16_t ioctl_str_len) { - if (cmd == 0) { - strncpy(ioctl_str, "WLC_E_SET_SSID", ioctl_str_len); - } - else if (cmd == 3) { - strncpy(ioctl_str, "WLC_E_AUTH ", ioctl_str_len); - } - else if (cmd == 16) { - strncpy(ioctl_str, "WLC_E_LINK ", ioctl_str_len); - } - else if (cmd == 46) { - strncpy(ioctl_str, "WLC_E_PSK_SUP ", ioctl_str_len); - } - else if (cmd == 54) { - strncpy(ioctl_str, "WLC_E_IF ", ioctl_str_len); - } - else if (cmd == 69) { - strncpy(ioctl_str, "WLC_E_ESCAN_RESULT", ioctl_str_len); - } - - if (flag == 0) { - strncat(ioctl_str, " WLC_E_STATUS_SUCCESS", ioctl_str_len); - } - if (flag == 8) { - strncat(ioctl_str, " WLC_E_STATUS_PARTIAL", ioctl_str_len); - } - else if (flag == 262) { - strncat(ioctl_str, " WLC_SUP_KEYED ", ioctl_str_len); - } - - if (reason == 0) { - strncat(ioctl_str, " WLC_E_REASON_INITIAL_ASSOC", ioctl_str_len); - } - else if (reason == 512) { - strncat(ioctl_str, " WLC_E_SUP_OTHER", ioctl_str_len); - } - ioctl_str[ioctl_str_len] = '\0'; + if (cmd == 0) + { + strncpy(ioctl_str, "WLC_E_SET_SSID", ioctl_str_len); + } + else if (cmd == 3) + { + strncpy(ioctl_str, "WLC_E_AUTH ", ioctl_str_len); + } + else if (cmd == 16) + { + strncpy(ioctl_str, "WLC_E_LINK ", ioctl_str_len); + } + else if (cmd == 46) + { + strncpy(ioctl_str, "WLC_E_PSK_SUP ", ioctl_str_len); + } + else if (cmd == 54) + { + strncpy(ioctl_str, "WLC_E_IF ", ioctl_str_len); + } + else if (cmd == 69) + { + strncpy(ioctl_str, "WLC_E_ESCAN_RESULT", ioctl_str_len); + } + + if (flag == 0) + { + strncat(ioctl_str, " WLC_E_STATUS_SUCCESS", ioctl_str_len); + } + if (flag == 8) + { + strncat(ioctl_str, " WLC_E_STATUS_PARTIAL", ioctl_str_len); + } + else if (flag == 262) + { + strncat(ioctl_str, " WLC_SUP_KEYED ", ioctl_str_len); + } + + if (reason == 0) + { + strncat(ioctl_str, " WLC_E_REASON_INITIAL_ASSOC", ioctl_str_len); + } + else if (reason == 512) + { + strncat(ioctl_str, " WLC_E_SUP_OTHER", ioctl_str_len); + } + ioctl_str[ioctl_str_len] = '\0'; } bool whd_str_to_ip(const char *ip4addr, size_t len, void *dest) { - uint8_t *addr = dest; - - if (len > 16) // Too long, not possible - { - return false; - } - - uint8_t stringLength = 0, byteCount = 0; - - //Iterate over each component of the IP. The exit condition is in the middle of the loop - while (true) { - - //No valid character (IPv4 addresses don't have implicit 0, that is x.y..z being read as x.y.0.z) - if ((stringLength == len) || (ip4addr[stringLength] < '0') || (ip4addr[stringLength] > '9')) { - return false; - } - - //For each component, we convert it to the raw value - uint16_t byte = 0; - while (stringLength < len && ip4addr[stringLength] >= '0' && ip4addr[stringLength] <= '9') { - byte *= 10; - byte += ip4addr[stringLength++] - '0'; - - //We go over the maximum value for an IPv4 component - if (byte > 0xff) { - return false; - } - } - - //Append the component - addr[byteCount++] = (uint8_t)byte; - - //If we're at the end, we leave the loop. It's the only way to reach the `true` output - if (byteCount == 4) { - break; - } - - //If the next character is invalid, we return false - if ((stringLength == len) || (ip4addr[stringLength++] != '.')) { - return false; - } - } - - return stringLength == len || ip4addr[stringLength] == '\0'; + uint8_t *addr = dest; + + if (len > 16) // Too long, not possible + { + return false; + } + + uint8_t stringLength = 0, byteCount = 0; + + //Iterate over each component of the IP. The exit condition is in the middle of the loop + while (true) + { + + //No valid character (IPv4 addresses don't have implicit 0, that is x.y..z being read as x.y.0.z) + if ( (stringLength == len) || (ip4addr[stringLength] < '0') || (ip4addr[stringLength] > '9') ) + { + return false; + } + + //For each component, we convert it to the raw value + uint16_t byte = 0; + while (stringLength < len && ip4addr[stringLength] >= '0' && ip4addr[stringLength] <= '9') + { + byte *= 10; + byte += ip4addr[stringLength++] - '0'; + + //We go over the maximum value for an IPv4 component + if (byte > 0xff) + { + return false; + } + } + + //Append the component + addr[byteCount++] = (uint8_t)byte; + + //If we're at the end, we leave the loop. It's the only way to reach the `true` output + if (byteCount == 4) + { + break; + } + + //If the next character is invalid, we return false + if ( (stringLength == len) || (ip4addr[stringLength++] != '.') ) + { + return false; + } + } + + return stringLength == len || ip4addr[stringLength] == '\0'; } static void whd_ipv4_itoa(char *string, uint8_t byte) { - char *baseString = string; - - //Write the digits to the buffer from the least significant to the most - // This is the incorrect order but we will swap later - do { - *string++ = '0' + byte % 10; - byte /= 10; - } while (byte); - - //We put the final \0, then go back one step on the last digit for the swap - *string-- = '\0'; - - //We now swap the digits - while (baseString < string) { - uint8_t tmp = *string; - *string-- = *baseString; - *baseString++ = tmp; - } + char *baseString = string; + + //Write the digits to the buffer from the least significant to the most + // This is the incorrect order but we will swap later + do + { + *string++ = '0' + byte % 10; + byte /= 10; + } while (byte); + + //We put the final \0, then go back one step on the last digit for the swap + *string-- = '\0'; + + //We now swap the digits + while (baseString < string) + { + uint8_t tmp = *string; + *string-- = *baseString; + *baseString++ = tmp; + } } uint8_t whd_ip4_to_string(const void *ip4addr, char *p) { - uint8_t outputPos = 0; - const uint8_t *byteArray = ip4addr; + uint8_t outputPos = 0; + const uint8_t *byteArray = ip4addr; + + for (uint8_t component = 0; component < 4; ++component) + { + //Convert the byte to string + whd_ipv4_itoa(&p[outputPos], byteArray[component]); + + //Move outputPos to the end of the string + while (p[outputPos] != '\0') + { + outputPos += 1; + } + + //Append a dot if this is not the last digit + if (component < 3) + { + p[outputPos++] = '.'; + } + } + // Return length of generated string, excluding the terminating null character + return outputPos; +} - for (uint8_t component = 0; component < 4; ++component) { - //Convert the byte to string - whd_ipv4_itoa(&p[outputPos], byteArray[component]); +#ifndef WHD_USE_CUSTOM_MALLOC_IMPL - //Move outputPos to the end of the string - while (p[outputPos] != '\0') { - outputPos += 1; - } +inline void *whd_mem_malloc (size_t size) +{ + return malloc(size); +} - //Append a dot if this is not the last digit - if (component < 3) { - p[outputPos++] = '.'; - } - } - // Return length of generated string, excluding the terminating null character - return outputPos; +inline void *whd_mem_calloc(size_t nitems, size_t size) +{ + return calloc(nitems, size); +} + +inline void whd_mem_free(void *ptr) +{ + free(ptr); } + +#endif /* ifndef WHD_USE_CUSTOM_MALLOC_IMPL */ diff --git a/wi-fi/whd/whd_utils.h b/wi-fi/whd/whd_utils.h index 96c09d75..721564b9 100644 --- a/wi-fi/whd/whd_utils.h +++ b/wi-fi/whd/whd_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,10 @@ #include "whd_events_int.h" #include "whd_types_int.h" +#ifdef PROTO_MSGBUF +#include "whd_hw.h" +#endif + #ifndef INCLUDED_WHD_UTILS_H_ #define INCLUDED_WHD_UTILS_H_ @@ -31,6 +35,31 @@ extern "C" { #endif +#define NBBY 8 +#define setbit(a, i) ( ( (uint8_t *)a )[(int)(i) / (int)(NBBY)] |= (uint8_t)(1 << ( (i) % NBBY ) ) ) +#define clrbit(a, i) ( ( (uint8_t *)a )[(int)(i) / (int)(NBBY)] &= (uint8_t) ~(1 << ( (i) % NBBY ) ) ) +#define isset(a, i) ( ( (const uint8_t *)a )[(int)(i) / (int)(NBBY)]& (1 << ( (i) % NBBY ) ) ) +#define isclr(a, i) ( ( ( (const uint8_t *)a )[(int)(i) / (int)(NBBY)]& (1 << ( (i) % NBBY ) ) ) == 0 ) + +#define CEIL(x, y) ( ( (x) + ( (y) - 1 ) ) / (y) ) +#define ROUNDUP(x, y) ( ( ( (x) + ( (y) - 1 ) ) / (y) ) * (y) ) +#define ROUNDDN(p, align) ( (p)& ~( (align) - 1 ) ) + +/** + * Get the offset (in bytes) of a member within a structure + */ +#define OFFSET(type, member) ( (uint32_t)&( (type *)0 )->member ) + +/** + * determine size (number of elements) in an array + */ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]) ) + +#ifdef PROTO_MSGBUF +uint32_t whd_dmapool_init(uint32_t memory_size); +void* whd_dmapool_alloc( int size); +#endif + /** Searches for a specific WiFi Information Element in a byte array * * Traverse a string of 1-byte tag/1-byte length/variable-length value @@ -176,6 +205,56 @@ bool whd_str_to_ip(const char *ip4addr, size_t len, void *dest); */ uint8_t whd_ip4_to_string(const void *ip4addr, char *p); + +/*! + ****************************************************************************** + * The wrapper function for memory allocation. + * It allocates the requested memory and returns a pointer to it. + * In default implementation it uses The C library function malloc(). + * + * Use macro WHD_USE_CUSTOM_MALLOC_IMPL (-D) for custom whd_mem_malloc/ + * whd_mem_calloc/whd_mem_free inplemetation. + * + * @param[in] size : This is the size of the memory block, in bytes. + * + * @return + * This function returns a pointer to the allocated memory, or NULL if the + * request fails. + */ +void *whd_mem_malloc(size_t size); + +/*! + ****************************************************************************** + * The wrapper function for memory allocation. + * It allocates the requested memory and sets allocated memory to zero. + * In default implementation it uses The C library function calloc(). + * + * Use macro WHD_USE_CUSTOM_MALLOC_IMPL (-D) for custom whd_mem_malloc/ + * whd_mem_calloc/whd_mem_free inplemetation. + * + * @param[in] nitems : This is the number of elements to be allocated. + * @param[in] size : This is the size of elements. + * + * @return + * This function returns a pointer to the allocated memory, or NULL if the + * request fails. + */ +void *whd_mem_calloc(size_t nitems, size_t size); + +/*! + ****************************************************************************** + * The wrapper function for free allocated memory. + * In default implementation it uses The C library function free(). + * + * Use macro WHD_USE_CUSTOM_MALLOC_IMPL (-D) for custom whd_mem_malloc/ + * whd_mem_calloc/whd_mem_free inplemetation. + * + * @param[in] ptr : pointer to a memory block previously allocated + * with whd_mem_malloc, whd_mem_calloc + * @return + */ +void whd_mem_free(void *ptr); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wi-fi/whd/whd_version.h b/wi-fi/whd/whd_version.h index be20b198..fe77da6d 100644 --- a/wi-fi/whd/whd_version.h +++ b/wi-fi/whd/whd_version.h @@ -1,3 +1,3 @@ -#define WHD_VERSION "v2.1.0-dirty" -#define WHD_BRANCH "v2.1.0" -#define WHD_DATE "2021-11-08 16:40:27 +0800" +#define WHD_VERSION "3.3.0.24096" +#define WHD_BRANCH "v3.3.0" +#define WHD_DATE "2024-07-05 06:07:25 -0500" diff --git a/wi-fi/whd/whd_wifi.c b/wi-fi/whd/whd_wifi.c index 8692e1b0..8e9793e8 100644 --- a/wi-fi/whd/whd_wifi.c +++ b/wi-fi/whd/whd_wifi.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,11 +27,14 @@ #include "whd_chip_constants.h" #include "whd_debug.h" #include "whd_events_int.h" +#ifndef PROTO_MSGBUF #include "whd_cdc_bdc.h" +#endif /* PROTO_MSGBUF */ #include "whd_thread_internal.h" #include "whd_utils.h" #include "whd_wifi_api.h" #include "whd_wlioctl.h" +#include "whd_proto.h" /****************************************************** * @cond Constants @@ -43,6 +46,7 @@ ******************************************************/ + /****************************************************** * Variables ******************************************************/ @@ -52,54 +56,58 @@ void (*whd_wifi_link_update_callback)(void) = NULL; * Function definitions ******************************************************/ -uint32_t whd_wifi_set_mac_address(whd_interface_t ifp, whd_mac_t mac) +whd_result_t whd_wifi_set_mac_address(whd_interface_t ifp, whd_mac_t mac) { - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver = ifp->whd_driver; + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver = ifp->whd_driver; - /* AP interface needs to come up with MAC different from STA */ + /* AP interface needs to come up with MAC different from STA */ #ifdef APOLLO_AUDIO - /* Work around the issue of asking API to set one address and it sets a different address. + /* Work around the issue of asking API to set one address and it sets a different address. * This will cause any comparison of set and get mac address to fail. TODO: move twiddling this * bit to a higher level. */ - if (0) + if (0) #else - if (ifp->role == WHD_AP_ROLE) + if (ifp->role == WHD_AP_ROLE) #endif - { - whd_mac_t ap_mac_address; + { + whd_mac_t ap_mac_address; - memcpy(&ap_mac_address, &mac, sizeof(whd_mac_t)); - if (ap_mac_address.octet[0] & MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT) { - ap_mac_address.octet[0] &= (uint8_t) ~(MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT); - } - else { - ap_mac_address.octet[0] |= MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT; - } + memcpy(&ap_mac_address, &mac, sizeof(whd_mac_t) ); + if (ap_mac_address.octet[0] & MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT) + { + ap_mac_address.octet[0] &= (uint8_t) ~(MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT); + } + else + { + ap_mac_address.octet[0] |= MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT; + } - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR); - CHECK_IOCTL_BUFFER(data); - memcpy(data, &ap_mac_address, sizeof(whd_mac_t)); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR); + CHECK_IOCTL_BUFFER(data); + memcpy(data, &ap_mac_address, sizeof(whd_mac_t) ); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, NULL) ); - if (memcmp(&mac, &ap_mac_address, sizeof(whd_mac_t)) != 0) { - WPRINT_WHD_INFO((" STA MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n" - " AP MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n", - mac.octet[0], mac.octet[1], mac.octet[2], - mac.octet[3], mac.octet[4], mac.octet[3], - ap_mac_address.octet[0], ap_mac_address.octet[1], ap_mac_address.octet[2], - ap_mac_address.octet[3], ap_mac_address.octet[4], ap_mac_address.octet[3])); - } - } - else { - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR); - CHECK_IOCTL_BUFFER(data); - memcpy(data, &mac, sizeof(whd_mac_t)); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); - } + if (memcmp(&mac, &ap_mac_address, sizeof(whd_mac_t) ) != 0) + { + WPRINT_WHD_INFO( (" STA MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n" + " AP MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n", + mac.octet[0], mac.octet[1], mac.octet[2], + mac.octet[3], mac.octet[4], mac.octet[3], + ap_mac_address.octet[0], ap_mac_address.octet[1], ap_mac_address.octet[2], + ap_mac_address.octet[3], ap_mac_address.octet[4], ap_mac_address.octet[3]) ); + } + } + else + { + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR); + CHECK_IOCTL_BUFFER(data); + memcpy(data, &mac, sizeof(whd_mac_t) ); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, NULL) ); + } - return WHD_SUCCESS; + return WHD_SUCCESS; } diff --git a/wi-fi/whd/whd_wifi_api.c b/wi-fi/whd/whd_wifi_api.c index 757f27a7..4f8eede0 100644 --- a/wi-fi/whd/whd_wifi_api.c +++ b/wi-fi/whd/whd_wifi_api.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,10 +23,11 @@ * */ -#include #include "whd_version.h" #include "whd_chip_constants.h" +#ifndef PROTO_MSGBUF #include "whd_cdc_bdc.h" +#endif /* PROTO_MSGBUF */ #include "whd_thread_internal.h" #include "whd_debug.h" #include "whd_utils.h" @@ -35,56 +36,73 @@ #include "whd_wlioctl.h" #include "whd_types.h" #include "whd_types_int.h" +#include "whd_proto.h" +#ifdef CYCFG_ULP_SUPPORT_ENABLED +#include "cy_wcm.h" +#endif + +#ifdef GCI_SECURE_ACCESS +#include "whd_hw.h" +#endif /****************************************************** * Constants ******************************************************/ -#define WL_CHANSPEC_CHAN_MASK (0x00ff) -#define CHSPEC_CHANNEL(chspec) ((uint8_t)((chspec)&WL_CHANSPEC_CHAN_MASK)) -#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | GET_C_VAR(whd_driver, CHANSPEC_BW_20) | \ - GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) | \ - (((channel) <= CH_MAX_2G_CHANNEL) ? GET_C_VAR(whd_driver, \ - CHANSPEC_BAND_2G) : \ - GET_C_VAR(whd_driver, CHANSPEC_BAND_5G))) - -#define MAX_SUPPORTED_MCAST_ENTRIES (10) -#define WLC_EVENT_MSG_LINK (0x01) - -#define JOIN_ASSOCIATED (uint32_t)(1 << 0) -#define JOIN_AUTHENTICATED (uint32_t)(1 << 1) -#define JOIN_LINK_READY (uint32_t)(1 << 2) -#define JOIN_SECURITY_COMPLETE (uint32_t)(1 << 3) -#define JOIN_SSID_SET (uint32_t)(1 << 4) -#define JOIN_NO_NETWORKS (uint32_t)(1 << 5) -#define JOIN_EAPOL_KEY_M1_TIMEOUT (uint32_t)(1 << 6) -#define JOIN_EAPOL_KEY_M3_TIMEOUT (uint32_t)(1 << 7) -#define JOIN_EAPOL_KEY_G1_TIMEOUT (uint32_t)(1 << 8) -#define JOIN_EAPOL_KEY_FAILURE (uint32_t)(1 << 9) - -#define JOIN_SECURITY_FLAGS_MASK (JOIN_SECURITY_COMPLETE | JOIN_EAPOL_KEY_M1_TIMEOUT | JOIN_EAPOL_KEY_M3_TIMEOUT | \ - JOIN_EAPOL_KEY_G1_TIMEOUT | JOIN_EAPOL_KEY_FAILURE) - -#define DEFAULT_JOIN_ATTEMPT_TIMEOUT (7000) /* Overall join attempt timeout in milliseconds. */ -#define DEFAULT_EAPOL_KEY_PACKET_TIMEOUT (2500) /* Timeout when waiting for EAPOL key packet M1 or M3 in milliseconds.*/ - /* Some APs may be slow to provide M1 and 1000 ms is not long enough for edge of cell. */ +#define MAX_SUPPORTED_MCAST_ENTRIES (10) +#define WLC_EVENT_MSG_LINK (0x01) + +#define JOIN_ASSOCIATED (uint32_t)(1 << 0) +#define JOIN_AUTHENTICATED (uint32_t)(1 << 1) +#define JOIN_LINK_READY (uint32_t)(1 << 2) +#define JOIN_SECURITY_COMPLETE (uint32_t)(1 << 3) +#define JOIN_SSID_SET (uint32_t)(1 << 4) +#define JOIN_NO_NETWORKS (uint32_t)(1 << 5) +#define JOIN_EAPOL_KEY_M1_TIMEOUT (uint32_t)(1 << 6) +#define JOIN_EAPOL_KEY_M3_TIMEOUT (uint32_t)(1 << 7) +#define JOIN_EAPOL_KEY_G1_TIMEOUT (uint32_t)(1 << 8) +#define JOIN_EAPOL_KEY_FAILURE (uint32_t)(1 << 9) + +#define JOIN_SECURITY_FLAGS_MASK (JOIN_SECURITY_COMPLETE | JOIN_EAPOL_KEY_M1_TIMEOUT | JOIN_EAPOL_KEY_M3_TIMEOUT | \ + JOIN_EAPOL_KEY_G1_TIMEOUT | JOIN_EAPOL_KEY_FAILURE) + +#define DEFAULT_JOIN_ATTEMPT_TIMEOUT (9000) /* Overall join attempt timeout in milliseconds.(FW will do "full scan"[~2.8 seconds] + "psk-to-pmk"[2.x seconds] + "join"[5 seconds timer in FW]) */ +#define DEFAULT_EAPOL_KEY_PACKET_TIMEOUT (2500) /* Timeout when waiting for EAPOL key packet M1 or M3 in milliseconds.*/ + /* Some APs may be slow to provide M1 and 1000 ms is not long enough for edge of cell. */ #ifndef DEFAULT_PM2_SLEEP_RET_TIME -#define DEFAULT_PM2_SLEEP_RET_TIME (200) +#define DEFAULT_PM2_SLEEP_RET_TIME (200) +#endif + +#define PM2_SLEEP_RET_TIME_MIN (10) /* Minimum return-to-sleep in milliseconds */ +#define PM2_SLEEP_RET_TIME_MAX (2000) /* Maximum return-to-sleep in milliseconds */ +#define NULL_FRAMES_WITH_PM_SET_LIMIT (100) /* NULL_FRAMES_WITH_PM_SET_LIMIT */ +#define RSPEC_KBPS_MASK (0x7f) +#define RSPEC_500KBPS(rate) ( (rate) & RSPEC_KBPS_MASK ) +#define RSPEC_TO_KBPS(rate) (RSPEC_500KBPS( (rate) ) * (uint32_t)500) +#define UNSIGNED_CHAR_TO_CHAR(uch) ( (uch) & 0x7f ) +#define ETHER_ISMULTI(ea) ( ( (const uint8_t *)(ea) )[0] & 1 ) + +#define KEY_MAX_LEN (64) /* Maximum key length */ +#define KEY_MIN_LEN (8) /* Minimum key length */ +#ifdef CYCFG_ULP_SUPPORT_ENABLED +#define MIN_DUMP_BUF_LEN (2048) +#define MAX_DUMP_BUF_LEN (4096) #endif +#define BT_CTRL_REG_ADDR (0x18000c7c) +#define HOST_CTRL_REG_ADDR (0x18000d6c) +#define BT_BUF_REG_ADDR (0x18000c78) + +/* Default TCP Keepalive parameters. */ +#define TKO_DEFAULT_INTERVAL_SEC (1) +#define TKO_DEFAULT_RETRY_COUNT (3) +#define TKO_DEFAULT_RETRY_INTERVAL_SEC (3) + +/** Buffer length check for ulp statistics + * + * @param buflen buffer length + * + */ +#define CHECK_BUFLEN(buflen,max,min) ((buflen) <= (max) && (buflen) >= (min)) -#define PM2_SLEEP_RET_TIME_MIN (10) /* Minimum return-to-sleep in milliseconds */ -#define PM2_SLEEP_RET_TIME_MAX (2000) /* Maximum return-to-sleep in milliseconds */ -#define NULL_FRAMES_WITH_PM_SET_LIMIT (100) /* NULL_FRAMES_WITH_PM_SET_LIMIT */ -#define RSPEC_KBPS_MASK (0x7f) -#define RSPEC_500KBPS(rate) ((rate)&RSPEC_KBPS_MASK) -#define RSPEC_TO_KBPS(rate) (RSPEC_500KBPS((rate)) * (uint32_t)500) -#define UNSIGNED_CHAR_TO_CHAR(uch) ((uch)&0x7f) -#define ETHER_ISMULTI(ea) (((const uint8_t *)(ea))[0] & 1) - -#define KEY_MAX_LEN (64) /* Maximum key length */ -#define KEY_MIN_LEN (8) /* Minimum key length */ -#define BT_CTRL_REG_ADDR (0x18000c7c) -#define HOST_CTRL_REG_ADDR (0x18000d6c) -#define BT_BUF_REG_ADDR (0x18000c78) /****************************************************** * Local Structures ******************************************************/ @@ -93,22 +111,22 @@ typedef struct { - uint32_t entry_count; - whd_mac_t macs[1]; + uint32_t entry_count; + whd_mac_t macs[1]; } mcast_list_t; typedef struct { - int32_t rssi; - whd_mac_t macs; + int32_t rssi; + whd_mac_t macs; } client_rssi_t; typedef struct { - whd_sync_scan_result_t *aps; - uint32_t count; - uint32_t offset; - cy_semaphore_t scan_semaphore; + whd_sync_scan_result_t *aps; + uint32_t count; + uint32_t offset; + cy_semaphore_t scan_semaphore; } whd_scan_userdata_t; #pragma pack() @@ -118,11 +136,14 @@ typedef struct ******************************************************/ /* LOOK: !!!When adding events below, please modify whd_event_to_string!!! */ -const whd_event_num_t join_events[] = { - WLC_E_SET_SSID, WLC_E_LINK, WLC_E_AUTH, WLC_E_DEAUTH_IND, WLC_E_DISASSOC_IND, WLC_E_PSK_SUP, WLC_E_CSA_COMPLETE_IND, - WLC_E_NONE +const whd_event_num_t join_events[] = +{ + WLC_E_SET_SSID, WLC_E_LINK, WLC_E_AUTH, WLC_E_DEAUTH_IND, WLC_E_DISASSOC_IND, WLC_E_PSK_SUP, WLC_E_CSA_COMPLETE_IND, + WLC_E_NONE }; static const whd_event_num_t scan_events[] = { WLC_E_ESCAN_RESULT, WLC_E_NONE }; +static const whd_event_num_t auth_events[] = +{ WLC_E_EXT_AUTH_REQ, WLC_E_EXT_AUTH_FRAME_RX, WLC_E_NONE }; /* Values are in 100's of Kbit/sec (1 = 100Kbit/s). Arranged as: * [Bit index] @@ -133,41 +154,168 @@ static const whd_event_num_t scan_events[] = { WLC_E_ESCAN_RESULT, WLC_E_NONE }; * [0] = Long GI * [1] = Short GI */ -static const uint16_t mcs_data_rate_lookup_table[32][2][2] = { - [0] = { - { 65, 72 }, - { 135, 150 } }, - [1] = { { 130, 144 }, { 270, 300 } }, - [2] = { { 195, 217 }, { 405, 450 } }, - [3] = { { 260, 289 }, { 540, 600 } }, - [4] = { { 390, 433 }, { 810, 900 } }, - [5] = { { 520, 578 }, { 1080, 1200 } }, - [6] = { { 585, 650 }, { 1215, 1350 } }, - [7] = { { 650, 722 }, { 1350, 1500 } }, - [8] = { { 130, 144 }, { 270, 300 } }, - [9] = { { 260, 289 }, { 540, 600 } }, - [10] = { { 390, 433 }, { 810, 900 } }, - [11] = { { 520, 578 }, { 1080, 1200 } }, - [12] = { { 780, 867 }, { 1620, 1800 } }, - [13] = { { 1040, 1156 }, { 2160, 2400 } }, - [14] = { { 1170, 1300 }, { 2430, 2700 } }, - [15] = { { 1300, 1444 }, { 2700, 3000 } }, - [16] = { { 195, 217 }, { 405, 450 } }, - [17] = { { 390, 433 }, { 810, 900 } }, - [18] = { { 585, 650 }, { 1215, 1350 } }, - [19] = { { 780, 867 }, { 1620, 1800 } }, - [20] = { { 1170, 1300 }, { 2430, 2700 } }, - [21] = { { 1560, 1733 }, { 3240, 3600 } }, - [22] = { { 1755, 1950 }, { 3645, 4050 } }, - [23] = { { 1950, 2167 }, { 4050, 4500 } }, - [24] = { { 260, 288 }, { 540, 600 } }, - [25] = { { 520, 576 }, { 1080, 1200 } }, - [26] = { { 780, 868 }, { 1620, 1800 } }, - [27] = { { 1040, 1156 }, { 2160, 2400 } }, - [28] = { { 1560, 1732 }, { 3240, 3600 } }, - [29] = { { 2080, 2312 }, { 4320, 4800 } }, - [30] = { { 2340, 2600 }, { 4860, 5400 } }, - [31] = { { 2600, 2888 }, { 5400, 6000 } }, +static const uint16_t mcs_data_rate_lookup_table[32][2][2] = +{ + [0] = + { + { 65, 72}, + { 135, 150} + }, + [1] = + { + { 130, 144}, + { 270, 300} + }, + [2] = + { + { 195, 217}, + { 405, 450} + }, + [3] = + { + { 260, 289}, + { 540, 600} + }, + [4] = + { + { 390, 433}, + { 810, 900} + }, + [5] = + { + { 520, 578}, + { 1080, 1200} + }, + [6] = + { + { 585, 650}, + { 1215, 1350} + }, + [7] = + { + { 650, 722}, + { 1350, 1500} + }, + [8] = + { + { 130, 144}, + { 270, 300} + }, + [9] = + { + { 260, 289}, + { 540, 600} + }, + [10] = + { + { 390, 433}, + { 810, 900} + }, + [11] = + { + { 520, 578}, + { 1080, 1200} + }, + [12] = + { + { 780, 867}, + { 1620, 1800} + }, + [13] = + { + { 1040, 1156}, + { 2160, 2400} + }, + [14] = + { + { 1170, 1300}, + { 2430, 2700} + }, + [15] = + { + { 1300, 1444}, + { 2700, 3000} + }, + [16] = + { + { 195, 217}, + { 405, 450} + }, + [17] = + { + { 390, 433}, + { 810, 900} + }, + [18] = + { + { 585, 650}, + { 1215, 1350} + }, + [19] = + { + { 780, 867}, + { 1620, 1800} + }, + [20] = + { + { 1170, 1300}, + { 2430, 2700} + }, + [21] = + { + { 1560, 1733}, + { 3240, 3600} + }, + [22] = + { + { 1755, 1950}, + { 3645, 4050} + }, + [23] = + { + { 1950, 2167}, + { 4050, 4500} + }, + [24] = + { + { 260, 288}, + { 540, 600} + }, + [25] = + { + { 520, 576}, + { 1080, 1200} + }, + [26] = + { + { 780, 868}, + { 1620, 1800} + }, + [27] = + { + { 1040, 1156}, + { 2160, 2400} + }, + [28] = + { + { 1560, 1732}, + { 3240, 3600} + }, + [29] = + { + { 2080, 2312}, + { 4320, 4800} + }, + [30] = + { + { 2340, 2600}, + { 4860, 5400} + }, + [31] = + { + { 2600, 2888}, + { 5400, 6000} + }, }; @@ -175,21 +323,22 @@ static const uint16_t mcs_data_rate_lookup_table[32][2][2] = { * Static Function prototypes ******************************************************/ static void *whd_wifi_join_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, void *handler_user_data); + const uint8_t *event_data, void *handler_user_data); static void *whd_wifi_scan_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, - void *handler_user_data); -static uint32_t whd_wifi_prepare_join(whd_interface_t ifp, - whd_security_t security, - const uint8_t *security_key, - uint8_t key_length, - cy_semaphore_t *semaphore); -static uint32_t whd_wifi_check_join_status(whd_interface_t ifp); -static void whd_wifi_active_join_deinit(whd_interface_t ifp, cy_semaphore_t *stack_semaphore, - whd_result_t result); -static uint32_t whd_wifi_active_join_init(whd_interface_t ifp, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length, - cy_semaphore_t *semaphore); + const uint8_t *event_data, + void *handler_user_data); +static whd_result_t whd_wifi_prepare_join(whd_interface_t ifp, + whd_security_t security, + const uint8_t *security_key, + uint8_t key_length, + cy_semaphore_t *semaphore); +static whd_result_t whd_wifi_check_join_status(whd_interface_t ifp); +static void whd_wifi_active_join_deinit(whd_interface_t ifp, cy_semaphore_t *stack_semaphore, + whd_result_t result); +static whd_result_t whd_wifi_active_join_init(whd_interface_t ifp, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length, + cy_semaphore_t *semaphore); +static whd_result_t whd_tko_autoenab(whd_interface_t ifp, whd_bool_t enable); /** Sets the current EAPOL key timeout for the given interface * @@ -199,373 +348,824 @@ static uint32_t whd_wifi_active_join_init(whd_interface_t ifp, whd_security_t au * @return WHD_SUCCESS : if success * Error code : error code to indicate the type of error */ -static uint32_t whd_wifi_set_supplicant_key_timeout(whd_interface_t ifp, int32_t eapol_key_timeout); +static whd_result_t whd_wifi_set_supplicant_key_timeout(whd_interface_t ifp, int32_t eapol_key_timeout); /****************************************************** * Function definitions ******************************************************/ -uint32_t whd_get_bt_info(whd_driver_t whd_driver, whd_bt_info_t bt_info); +whd_result_t whd_get_bt_info(whd_driver_t whd_driver, whd_bt_info_t bt_info); inline wl_chanspec_t whd_channel_to_wl_band(whd_driver_t whd_driver, uint32_t channel) { - return (((channel) <= CH_MAX_2G_CHANNEL) ? (uint16_t)GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) : - (uint16_t)GET_C_VAR(whd_driver, CHANSPEC_BAND_5G)); + return ( ( (channel) <= CH_MAX_2G_CHANNEL ) ? (uint16_t)GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) : + (uint16_t)GET_C_VAR(whd_driver, CHANSPEC_BAND_5G) ); } -uint32_t whd_wifi_set_up(whd_interface_t ifp) +whd_result_t whd_wifi_set_up(whd_interface_t ifp) { - whd_mac_t mac; - char version[200]; - whd_driver_t whd_driver; + whd_mac_t mac; + char version[200]; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; - if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) { - WPRINT_WHD_INFO(("whd_wifi_set_up: already up.\n")); - return WHD_SUCCESS; - } + whd_driver = ifp->whd_driver; + if (whd_driver->internal_info.whd_wlan_status.state == WLAN_UP) + { + WPRINT_WHD_INFO( ("whd_wifi_set_up: already up.\n") ); + return WHD_SUCCESS; + } - /* Send UP command */ - CHECK_RETURN(whd_wifi_set_ioctl_buffer(ifp, WLC_UP, NULL, 0)); + /* Send UP command */ + CHECK_RETURN(whd_wifi_set_ioctl_buffer(ifp, WLC_UP, NULL, 0) ); if (whd_wifi_get_mac_address(ifp, &mac) == WHD_SUCCESS) { - WPRINT_MACRO(("WLAN MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n", mac.octet[0], mac.octet[1], mac.octet[2], - mac.octet[3], mac.octet[4], mac.octet[5])); + WPRINT_INFO(("WLAN MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n", mac.octet[0], mac.octet[1], mac.octet[2], + mac.octet[3], mac.octet[4], mac.octet[5])); } if (whd_wifi_get_wifi_version(ifp, version, sizeof(version)) == WHD_SUCCESS) { - WPRINT_MACRO(("WLAN Firmware : %s", version)); + WPRINT_INFO(("WLAN Firmware : %s", version)); } /* minimize bootloader usage and start time from UART output */ if (whd_wifi_get_clm_version(ifp, version, sizeof(version)) == WHD_SUCCESS) { - WPRINT_MACRO(("WLAN CLM : %s\n", version)); + WPRINT_INFO(("WLAN CLM : %s\n", version)); } - WPRINT_MACRO(("WHD VERSION : " WHD_VERSION)); - WPRINT_MACRO((" : " WHD_BRANCH)); + WPRINT_INFO(("WHD VERSION : " WHD_VERSION)); + WPRINT_INFO((" : " WHD_BRANCH)); #if defined(__ARMCC_VERSION) - WPRINT_MACRO((" : ARM CLANG %u", __ARMCC_VERSION)); + WPRINT_INFO((" : ARM CLANG %u", __ARMCC_VERSION)); #elif defined(__ICCARM__) - WPRINT_MACRO((" : IAR %u", __VER__)); + WPRINT_INFO((" : IAR %u", __VER__)); #elif defined(__GNUC__) - WPRINT_MACRO((" : GCC %u.%u", __GNUC__, __GNUC_MINOR__)); + WPRINT_INFO((" : GCC %u.%u", __GNUC__, __GNUC_MINOR__)); #else - WPRINT_MACRO((" : UNKNOWN CC")); + WPRINT_INFO((" : UNKNOWN CC")); #endif - WPRINT_MACRO((" : " WHD_DATE "\n")); + WPRINT_INFO((" : " WHD_DATE "\n")); - /* Update wlan status */ - whd_driver->internal_info.whd_wlan_status.state = WLAN_UP; + /* Update wlan status */ + whd_driver->internal_info.whd_wlan_status.state = WLAN_UP; - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_set_down(whd_interface_t ifp) +whd_result_t whd_wifi_set_down(whd_interface_t ifp) { - whd_driver_t whd_driver = ifp->whd_driver; + whd_driver_t whd_driver = ifp->whd_driver; - if (whd_driver->internal_info.whd_wlan_status.state != WLAN_UP) { - WPRINT_WHD_INFO(("whd_wifi_set_down: already down.\n")); - return WHD_INTERFACE_NOT_UP; - } + if (whd_driver->internal_info.whd_wlan_status.state != WLAN_UP) + { + WPRINT_WHD_INFO( ("whd_wifi_set_down: already down.\n") ); + return WHD_INTERFACE_NOT_UP; + } - /* Send DOWN command */ - CHECK_RETURN(whd_wifi_set_ioctl_buffer(ifp, WLC_DOWN, NULL, 0)); + /* Send DOWN command */ + CHECK_RETURN(whd_wifi_set_ioctl_buffer(ifp, WLC_DOWN, NULL, 0) ); - /* Update wlan status */ - whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; + /* Update wlan status */ + whd_driver->internal_info.whd_wlan_status.state = WLAN_DOWN; - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_get_bt_info(whd_driver_t whd_driver, whd_bt_info_t bt_info) +whd_result_t whd_get_bt_info(whd_driver_t whd_driver, whd_bt_info_t bt_info) { - whd_result_t result; - whd_interface_t ifp; - uint32_t addr = 0; + whd_result_t result; + whd_interface_t ifp; + uint32_t addr = 0; + + ifp = whd_get_primary_interface(whd_driver); + + CHECK_IFP_NULL(ifp); + + memset(bt_info, 0, sizeof(struct whd_bt_info) ); + bt_info->bt_ctrl_reg_addr = BT_CTRL_REG_ADDR; + bt_info->host_ctrl_reg_addr = HOST_CTRL_REG_ADDR; + bt_info->bt_buf_reg_addr = BT_BUF_REG_ADDR; + result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_BTADDR, (uint8_t *)&addr, sizeof(uint32_t) ); + if (result == WHD_SUCCESS) + { + bt_info->wlan_buf_addr = addr; + } + return WHD_SUCCESS; +} + +whd_result_t whd_wifi_set_chanspec(whd_interface_t ifp, wl_chanspec_t chanspec) +{ + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Map P2P interface to either STA or AP interface depending if it's running as group owner or client */ + if (ifp->role == WHD_P2P_ROLE) + { + if (whd_driver->internal_info.whd_wifi_p2p_go_is_up == WHD_TRUE) + { + ifp->role = WHD_AP_ROLE; + } + else + { + ifp->role = WHD_STA_ROLE; + } + } + WPRINT_WHD_INFO( ("whd_wifi_set_chanspec: ifp->role(%d) chanspec(0x%x)\n", ifp->role, chanspec) ); + + switch (ifp->role) + { + case WHD_STA_ROLE: + case WHD_AP_ROLE: + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(*data), + IOVAR_STR_CHANSPEC); + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)chanspec ); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + break; + case WHD_P2P_ROLE: + case WHD_INVALID_ROLE: + default: + whd_assert("Bad interface", 0 != 0); + return WHD_UNKNOWN_INTERFACE; + } + return WHD_SUCCESS; +} - ifp = whd_get_primary_interface(whd_driver); +whd_result_t whd_wifi_set_channel(whd_interface_t ifp, uint32_t channel) +{ + whd_buffer_t buffer; + uint32_t *data; + wl_chan_switch_t *chan_switch; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Map P2P interface to either STA or AP interface depending if it's running as group owner or client */ + if (ifp->role == WHD_P2P_ROLE) + { + if (whd_driver->internal_info.whd_wifi_p2p_go_is_up == WHD_TRUE) + { + ifp->role = WHD_AP_ROLE; + } + else + { + ifp->role = WHD_STA_ROLE; + } + } + + switch (ifp->role) + { + case WHD_STA_ROLE: + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(uint32_t) ); + CHECK_IOCTL_BUFFER(data); + *data = htod32(channel); + CHECK_RETURN(whd_proto_get_ioctl(ifp, WLC_SET_CHANNEL, buffer, NULL) ); - CHECK_IFP_NULL(ifp); + break; - memset(bt_info, 0, sizeof(struct whd_bt_info)); - bt_info->bt_ctrl_reg_addr = BT_CTRL_REG_ADDR; - bt_info->host_ctrl_reg_addr = HOST_CTRL_REG_ADDR; - bt_info->bt_buf_reg_addr = BT_BUF_REG_ADDR; - result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_BTADDR, (uint8_t *)&addr, sizeof(uint32_t)); - if (result == WHD_SUCCESS) { - bt_info->wlan_buf_addr = addr; - } - return WHD_SUCCESS; + case WHD_AP_ROLE: + chan_switch = (wl_chan_switch_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_chan_switch_t), + IOVAR_STR_CSA); + CHECK_IOCTL_BUFFER(chan_switch); + chan_switch->chspec = + ( wl_chanspec_t )(GET_C_VAR(whd_driver, + CHANSPEC_BW_20) | GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) | channel); + chan_switch->chspec |= whd_channel_to_wl_band(whd_driver, channel); + chan_switch->chspec = htod16(chan_switch->chspec); + chan_switch->count = 1; + chan_switch->mode = 1; + chan_switch->reg = 0; + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + break; + case WHD_P2P_ROLE: + case WHD_INVALID_ROLE: + default: + whd_assert("Bad interface", 0 != 0); + return WHD_UNKNOWN_INTERFACE; + } + + return WHD_SUCCESS; } -uint32_t whd_wifi_set_channel(whd_interface_t ifp, uint32_t channel) +whd_result_t whd_wifi_get_channel(whd_interface_t ifp, uint32_t *channel) { - whd_buffer_t buffer; - uint32_t *data; - wl_chan_switch_t *chan_switch; - whd_driver_t whd_driver; + whd_buffer_t buffer; + whd_buffer_t response; + channel_info_t *channel_info; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + if (channel == NULL) + return WHD_BADARG; - CHECK_DRIVER_NULL(whd_driver); + whd_driver = ifp->whd_driver; - /* Map P2P interface to either STA or AP interface depending if it's running as group owner or client */ - if (ifp->role == WHD_P2P_ROLE) { - if (whd_driver->internal_info.whd_wifi_p2p_go_is_up == WHD_TRUE) { - ifp->role = WHD_AP_ROLE; - } - else { - ifp->role = WHD_STA_ROLE; - } - } + CHECK_DRIVER_NULL(whd_driver); - switch (ifp->role) { - case WHD_STA_ROLE: - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(uint32_t)); - CHECK_IOCTL_BUFFER(data); - *data = htod32(channel); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_SET_CHANNEL, buffer, NULL)); - break; + CHECK_IOCTL_BUFFER(whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(channel_info_t) ) ); - case WHD_AP_ROLE: - chan_switch = (wl_chan_switch_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_chan_switch_t), - IOVAR_STR_CSA); - CHECK_IOCTL_BUFFER(chan_switch); - chan_switch->chspec = - (wl_chanspec_t)(GET_C_VAR(whd_driver, - CHANSPEC_BW_20) | - GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) | channel); - chan_switch->chspec |= whd_channel_to_wl_band(whd_driver, channel); - chan_switch->chspec = htod16(chan_switch->chspec); - chan_switch->count = 1; - chan_switch->mode = 1; - chan_switch->reg = 0; - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0)); - break; - case WHD_P2P_ROLE: - case WHD_INVALID_ROLE: - default: - whd_assert("Bad interface", 0 != 0); - return WHD_UNKNOWN_INTERFACE; - } + CHECK_RETURN(whd_proto_get_ioctl(ifp, WLC_GET_CHANNEL, buffer, &response) ); - return WHD_SUCCESS; + channel_info = (channel_info_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(channel_info, WHD_NO_REGISTER_FUNCTION_POINTER); + *channel = (uint32_t)channel_info->hw_channel; + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + return WHD_SUCCESS; } -uint32_t whd_wifi_get_channel(whd_interface_t ifp, uint32_t *channel) +whd_result_t whd_wifi_enable_supplicant(whd_interface_t ifp, whd_security_t auth_type) { - whd_buffer_t buffer; - whd_buffer_t response; - channel_info_t *channel_info; - whd_driver_t whd_driver; + whd_buffer_t buffer; + uint32_t *data; + uint32_t bss_index = 0; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - if (channel == NULL) - return WHD_BADARG; + whd_driver = ifp->whd_driver; - whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); - CHECK_DRIVER_NULL(whd_driver); + /* Map the interface to a BSS index */ + bss_index = ifp->bsscfgidx; - CHECK_IOCTL_BUFFER(whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(channel_info_t))); + /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); + CHECK_IOCTL_BUFFER(data); + data[0] = bss_index; + data[1] = (uint32_t)( ( ( (auth_type & WPA_SECURITY) != 0 ) || + ( (auth_type & WPA2_SECURITY) != 0 ) || + (auth_type & WPA3_SECURITY) != 0 ) ? 1 : 0 ); + (void)whd_proto_set_iovar(ifp, buffer, 0); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_CHANNEL, buffer, &response)); + return WHD_SUCCESS; +} - channel_info = (channel_info_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(channel_info, WHD_NO_REGISTER_FUNCTION_POINTER); - *channel = (uint32_t)channel_info->hw_channel; - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - return WHD_SUCCESS; +whd_result_t whd_wifi_set_supplicant_key_timeout(whd_interface_t ifp, int32_t eapol_key_timeout) +{ + whd_buffer_t buffer; + int32_t *data; + uint32_t bss_index = 0; + whd_driver_t whd_driver = (whd_driver_t)ifp->whd_driver; + + /* Map the interface to a BSS index */ + bss_index = ifp->bsscfgidx; + + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA_TMO); + CHECK_IOCTL_BUFFER(data); +#ifndef PROTO_MSGBUF + data[0] = (int32_t)bss_index; + data[1] = eapol_key_timeout; +#else + memcpy(data, &bss_index, sizeof(uint32_t)); + memcpy(data + sizeof(bss_index), &eapol_key_timeout, sizeof(uint32_t) ); +#endif + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + + return WHD_SUCCESS; } -uint32_t whd_wifi_enable_supplicant(whd_interface_t ifp, whd_security_t auth_type) +whd_result_t whd_wifi_set_passphrase(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length) { - whd_buffer_t buffer; - uint32_t *data; - uint32_t bss_index = 0; - whd_driver_t whd_driver; + whd_buffer_t buffer; + whd_driver_t whd_driver; + wsec_pmk_t *psk; - CHECK_IFP_NULL(ifp); + if (!ifp || !security_key || (key_length < KEY_MIN_LEN) || (key_length > KEY_MAX_LEN) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); - CHECK_DRIVER_NULL(whd_driver); + psk = (wsec_pmk_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t) ); + CHECK_IOCTL_BUFFER(psk); - /* Map the interface to a BSS index */ - bss_index = ifp->bsscfgidx; + memset(psk, 0, sizeof(wsec_pmk_t) ); + memcpy(psk->key, security_key, key_length); + psk->key_len = htod16(key_length); + psk->flags = htod16( (uint16_t)WSEC_PASSPHRASE ); - /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); - CHECK_IOCTL_BUFFER(data); - data[0] = bss_index; - data[1] = (uint32_t)((((auth_type & WPA_SECURITY) != 0) || - ((auth_type & WPA2_SECURITY) != 0) || - (auth_type & WPA3_SECURITY) != 0) ? - 1 : - 0); - (void)whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); + /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ + CHECK_RETURN(cy_rtos_delay_milliseconds(1) ); - return WHD_SUCCESS; + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SET_WSEC_PMK, buffer, 0) ); + + return WHD_SUCCESS; } -uint32_t whd_wifi_set_supplicant_key_timeout(whd_interface_t ifp, int32_t eapol_key_timeout) +whd_result_t whd_wifi_sae_password(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length) { - whd_buffer_t buffer; - int32_t *data; - uint32_t bss_index = 0; - whd_driver_t whd_driver = (whd_driver_t)ifp->whd_driver; - - /* Map the interface to a BSS index */ - bss_index = ifp->bsscfgidx; + whd_buffer_t buffer; + whd_driver_t whd_driver; + wsec_sae_password_t *sae_password; + + if (!ifp || !security_key || (key_length == 0) || (key_length > WSEC_MAX_SAE_PASSWORD_LEN) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + sae_password = (wsec_sae_password_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wsec_sae_password_t), + IOVAR_STR_SAE_PASSWORD); + CHECK_IOCTL_BUFFER(sae_password); + memset(sae_password, 0, sizeof(wsec_sae_password_t) ); + memcpy(sae_password->password, security_key, key_length); + sae_password->password_len = htod16(key_length); + /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ + cy_rtos_delay_milliseconds(1); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + + return WHD_SUCCESS; +} - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA_TMO); - CHECK_IOCTL_BUFFER(data); - data[0] = (int32_t)bss_index; - data[1] = eapol_key_timeout; - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0)); +whd_result_t whd_wifi_offload_config(whd_interface_t ifp, uint32_t ol_feat, uint32_t reset) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver; + wl_ol_cfg_v1_t *ol_cfg; + uint32_t ol_feat_skip = ~ol_feat; + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + ol_cfg = (wl_ol_cfg_v1_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wl_ol_cfg_v1_t), + IOVAR_STR_OFFLOAD_CONFIG); + CHECK_IOCTL_BUFFER(ol_cfg); + memset(ol_cfg, 0, sizeof(wl_ol_cfg_v1_t) ); + + ol_cfg->ver = WL_OL_CFG_VER_1; + ol_cfg->len = sizeof(wl_ol_cfg_v1_t); + ol_cfg->id = WL_OL_CFG_ID_PROF; + ol_cfg->offload_skip = ol_feat_skip; + + if (reset) { + ol_cfg->u.ol_profile.reset = WHD_TRUE; + ol_cfg->u.ol_profile.type = -1; + } else { + ol_cfg->u.ol_profile.reset = WHD_FALSE; + ol_cfg->u.ol_profile.type = WL_OL_PROF_TYPE_LOW_PWR; + } + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + +#ifdef CYCFG_ULP_SUPPORT_ENABLED + /* Later this APIs can be moved to other place, if required */ + CHECK_RETURN(whd_configure_tko_offload(ifp, WHD_TRUE)); +#endif - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_set_passphrase(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length) +whd_result_t whd_wifi_offload_ipv4_update(whd_interface_t ifp, uint32_t ol_feat, uint32_t ipv4_addr, whd_bool_t is_add) { whd_buffer_t buffer; whd_driver_t whd_driver; - wsec_pmk_t *psk; - - if (!ifp || !security_key || (key_length < KEY_MIN_LEN) || (key_length > KEY_MAX_LEN)) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } + wl_ol_cfg_v1_t *ol_cfg; + struct ipv4_addr addr; + uint8_t i; + uint8_t j=0; + uint32_t ol_feat_skip = ~ol_feat; whd_driver = ifp->whd_driver; CHECK_DRIVER_NULL(whd_driver); - psk = (wsec_pmk_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t)); - CHECK_IOCTL_BUFFER(psk); + for (i=0; i> j) & 0xff; + j = j+8; + } - memset(psk, 0, sizeof(wsec_pmk_t)); - memcpy(psk->key, security_key, key_length); - psk->key_len = htod16(key_length); - psk->flags = htod16((uint16_t)WSEC_PASSPHRASE); + ol_cfg = (wl_ol_cfg_v1_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wl_ol_cfg_v1_t), + IOVAR_STR_OFFLOAD_CONFIG); + CHECK_IOCTL_BUFFER(ol_cfg); + memset(ol_cfg, 0, sizeof(wl_ol_cfg_v1_t) ); - /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ - CHECK_RETURN(cy_rtos_delay_milliseconds(1)); + ol_cfg->ver = WL_OL_CFG_VER_1; + ol_cfg->len = sizeof(wl_ol_cfg_v1_t); + ol_cfg->id = WL_OL_CFG_ID_INET_V4; + ol_cfg->offload_skip = ol_feat_skip; - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_WSEC_PMK, buffer, 0)); + ol_cfg->u.ol_inet_v4.del = (whd_bool_t) !is_add; + memcpy(&ol_cfg->u.ol_inet_v4.host_ipv4, &addr, sizeof(addr)); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); return WHD_SUCCESS; } -uint32_t whd_wifi_sae_password(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length) +whd_result_t whd_wifi_offload_ipv6_update(whd_interface_t ifp, uint32_t ol_feat, uint32_t *ipv6_addr, uint8_t type, whd_bool_t is_add) { whd_buffer_t buffer; whd_driver_t whd_driver; - wsec_sae_password_t *sae_password; - - if (!ifp || !security_key || (key_length < KEY_MIN_LEN) || (key_length > KEY_MAX_LEN)) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } + wl_ol_cfg_v1_t *ol_cfg; + struct ipv6_addr addr; + uint8_t i, j=0; + uint8_t k=0; + uint32_t ol_feat_skip = ~ol_feat; whd_driver = ifp->whd_driver; CHECK_DRIVER_NULL(whd_driver); - sae_password = (wsec_sae_password_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, - sizeof(wsec_sae_password_t), - IOVAR_STR_SAE_PASSWORD); - CHECK_IOCTL_BUFFER(sae_password); - memset(sae_password, 0, sizeof(wsec_sae_password_t)); - memcpy(sae_password->password, security_key, key_length); - sae_password->password_len = htod16(key_length); - /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ - cy_rtos_delay_milliseconds(1); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0)); + for(i=0; i> k) & 0xff; + k = k+8; + if(k == 32) + { + j++; + k=0; + } + } + + ol_cfg = (wl_ol_cfg_v1_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wl_ol_cfg_v1_t), + IOVAR_STR_OFFLOAD_CONFIG); + CHECK_IOCTL_BUFFER(ol_cfg); + memset(ol_cfg, 0, sizeof(wl_ol_cfg_v1_t) ); + + ol_cfg->ver = WL_OL_CFG_VER_1; + ol_cfg->len = sizeof(wl_ol_cfg_v1_t); + ol_cfg->id = WL_OL_CFG_ID_INET_V6; + ol_cfg->offload_skip = ol_feat_skip; + ol_cfg->u.ol_inet_v6.del = (whd_bool_t) !is_add; + ol_cfg->u.ol_inet_v6.type = type; + memcpy(&ol_cfg->u.ol_inet_v6.host_ipv6, &addr, sizeof(addr)); + + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); return WHD_SUCCESS; } -uint32_t whd_wifi_enable_sup_set_passphrase(whd_interface_t ifp, const uint8_t *security_key_psk, uint8_t psk_length, - whd_security_t auth_type) +whd_result_t whd_wifi_offload_enable(whd_interface_t ifp, uint32_t ol_feat, uint32_t enable) { whd_buffer_t buffer; - uint32_t *data; - uint32_t bss_index = 0; whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); + wl_ol_cfg_v1_t *ol_cfg; + uint32_t ol_feat_skip = ~ol_feat; whd_driver = ifp->whd_driver; - CHECK_DRIVER_NULL(whd_driver); - if ((psk_length > (uint8_t)WSEC_MAX_PSK_LEN) || - (psk_length < (uint8_t)WSEC_MIN_PSK_LEN)) { - return WHD_INVALID_KEY; + ol_cfg = (wl_ol_cfg_v1_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wl_ol_cfg_v1_t), + IOVAR_STR_OFFLOAD_CONFIG); + CHECK_IOCTL_BUFFER(ol_cfg); + memset(ol_cfg, 0, sizeof(wl_ol_cfg_v1_t) ); + + ol_cfg->ver = WL_OL_CFG_VER_1; + ol_cfg->len = sizeof(wl_ol_cfg_v1_t); + ol_cfg->id = WL_OL_CFG_ID_ACTIVATE; + ol_cfg->offload_skip = ol_feat_skip; + + if (enable) { + ol_cfg->u.ol_activate.enable = WHD_TRUE; + } else { + ol_cfg->u.ol_activate.enable = WHD_FALSE; } - /* Map the interface to a BSS index */ - bss_index = ifp->bsscfgidx; + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + return WHD_SUCCESS; +} + +whd_result_t whd_configure_wowl(whd_interface_t ifp, uint32_t set_wowl) +{ + uint32_t get_wowl = 0; - /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); - CHECK_IOCTL_BUFFER(data); - data[0] = bss_index; - data[1] = (uint32_t)((((auth_type & WPA_SECURITY) != 0) || - ((auth_type & WPA2_SECURITY) != 0) || - (auth_type & WPA3_SECURITY) != 0) ? - 1 : - 0); - (void)whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); + CHECK_RETURN(whd_wifi_get_iovar_value(ifp, IOVAR_STR_WOWL, &get_wowl)); - CHECK_RETURN(whd_wifi_set_passphrase(ifp, security_key_psk, psk_length)); + set_wowl = ( set_wowl | get_wowl ); - return WHD_SUCCESS; + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_WOWL, set_wowl)); + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_WOWL_OS, set_wowl)); + + return WHD_SUCCESS; } -uint32_t whd_wifi_get_rssi(whd_interface_t ifp, int32_t *rssi) +whd_result_t whd_wifi_keepalive_config(whd_interface_t ifp, whd_keep_alive_t *packet, uint8_t flag ) { - CHECK_IFP_NULL(ifp); + whd_buffer_t buffer = NULL; + whd_driver_t whd_driver; + wl_keep_alive_pkt_t *keepalive_cfg; + uint32_t buffer_length; + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + if (flag == WHD_KEEPALIVE_NULL ) + { + keepalive_cfg = (wl_keep_alive_pkt_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer,sizeof(wl_keep_alive_pkt_t),IOVAR_STR_KEEPALIVE_CONFIG); + + CHECK_IOCTL_BUFFER(keepalive_cfg); + memset(keepalive_cfg, 0, sizeof(wl_keep_alive_pkt_t)); + + keepalive_cfg->period_msec = packet->period_msec; + } + else if (flag == WHD_KEEPALIVE_NAT ) + { + buffer_length =(uint32_t)( (2 * (uint32_t)packet->len_bytes) + WL_KEEP_ALIVE_FIXED_LEN ); + keepalive_cfg = (wl_keep_alive_pkt_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer,(uint16_t)buffer_length,IOVAR_STR_KEEPALIVE_CONFIG); + + CHECK_IOCTL_BUFFER(keepalive_cfg); + keepalive_cfg->period_msec = packet->period_msec; + keepalive_cfg->len_bytes = packet->len_bytes; + memcpy(keepalive_cfg->data,packet->data,packet->len_bytes); + } + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0)); + return WHD_SUCCESS; +} - if (rssi == NULL) - return WHD_BADARG; - if (ifp->role == WHD_STA_ROLE) { - return whd_wifi_get_ioctl_buffer(ifp, WLC_GET_RSSI, (uint8_t *)rssi, sizeof(*rssi)); - } - return WHD_BADARG; +whd_result_t whd_configure_tko_filter(whd_interface_t ifp,whd_tko_auto_filter_t * whd_filter, uint8_t filter_flag) +{ + uint32_t result = 0; + + result = whd_tko_toggle(ifp, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_param returned failure\n")); + } + result = whd_tko_autoenab(ifp, WHD_TRUE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_autoenab returned failure\n")); + } + result = whd_tko_filter(ifp,whd_filter,filter_flag); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_filter returned failure\n")); + } + result = whd_tko_toggle(ifp, WHD_TRUE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_param returned failure\n")); + } + return result; } -uint32_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, const whd_mac_t *client_mac) +whd_result_t whd_configure_tko_offload(whd_interface_t ifp, whd_bool_t enable) { - whd_buffer_t buffer; - whd_buffer_t response; - uint8_t *data = NULL; - client_rssi_t *client_rssi; - whd_driver_t whd_driver = ifp->whd_driver; + uint32_t result = 0; + result = whd_tko_autoenab(ifp, enable); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_autoenab returned failure\n")); + } + result = whd_tko_toggle(ifp, enable); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("Set whd_tko_param returned failure\n")); + } + return result; +} - /* WLAN expects buffer size to be 4-byte aligned */ - client_rssi = - (client_rssi_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, ROUND_UP(sizeof(client_rssi_t), sizeof(uint32_t))); - CHECK_IOCTL_BUFFER(client_rssi); +whd_result_t whd_wifi_enable_sup_set_passphrase(whd_interface_t ifp, const uint8_t *security_key_psk, uint8_t psk_length, + whd_security_t auth_type) +{ + whd_buffer_t buffer; + uint32_t *data; + uint32_t bss_index = 0; + whd_driver_t whd_driver; - memcpy(&client_rssi->macs, client_mac, sizeof(*client_mac)); - client_rssi->rssi = 0; + CHECK_IFP_NULL(ifp); - CHECK_RETURN_UNSUPPORTED_OK(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_RSSI, buffer, &response)); - data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(rssi, data, sizeof(int32_t)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + whd_driver = ifp->whd_driver; - return WHD_SUCCESS; + CHECK_DRIVER_NULL(whd_driver); + + if ( (psk_length > (uint8_t)WSEC_MAX_PSK_LEN) || + (psk_length < (uint8_t)WSEC_MIN_PSK_LEN) ) + { + return WHD_INVALID_KEY; + } + + /* Map the interface to a BSS index */ + bss_index = ifp->bsscfgidx; + + /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); + CHECK_IOCTL_BUFFER(data); + data[0] = bss_index; + data[1] = (uint32_t)( ( ( (auth_type & WPA_SECURITY) != 0 ) || + ( (auth_type & WPA2_SECURITY) != 0 ) || + (auth_type & WPA3_SECURITY) != 0 ) ? 1 : 0 ); + (void)whd_proto_set_iovar(ifp, buffer, 0); + + CHECK_RETURN(whd_wifi_set_passphrase(ifp, security_key_psk, psk_length) ); + + return WHD_SUCCESS; +} + +whd_result_t whd_wifi_set_pmk(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver; + wsec_pmk_t *pmk; + uint32_t i; + + if (!ifp || !security_key || ( (key_length != WSEC_PMK_LEN) && (key_length != WSEC_PMK_WPA3_ENT_192_LEN) ) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d key_length: %u\n", + __func__, __LINE__, key_length) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + pmk = (wsec_pmk_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wsec_pmk_t) ); + CHECK_IOCTL_BUFFER(pmk); + + memset(pmk, 0, sizeof(wsec_pmk_t) ); + + if (key_length == WSEC_PMK_WPA3_ENT_192_LEN) + { + memcpy(pmk->key, security_key, key_length); + pmk->key_len = htod16(key_length); + } + else + { + for (i = 0; i < key_length; i++) + { + snprintf( (char *)&pmk->key[2 * i], 3, "%02x", security_key[i] ); + } + pmk->key_len = htod16(key_length << 1); + pmk->flags = htod16( (uint16_t)WSEC_PASSPHRASE ); + } + + /* Delay required to allow radio firmware to be ready to receive PMK and avoid intermittent failure */ + CHECK_RETURN(cy_rtos_delay_milliseconds(1) ); + + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SET_WSEC_PMK, buffer, 0) ); + + return WHD_SUCCESS; +} + +whd_result_t whd_wifi_set_pmksa(whd_interface_t ifp, const pmkid_t *pmkid) +{ + whd_buffer_t buffer; + whd_buffer_t response; + uint16_t cnt; + pmkid_list_t *orig_pmkid_list; + pmkid_list_t *new_pmkid_list; + whd_driver_t whd_driver; + + if (!ifp || !pmkid) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Get the current pmkid_list list */ + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(uint32_t) + MAXPMKID * + sizeof(pmkid_t), IOVAR_STR_PMKID_INFO) ); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + + /* Verify address is not currently registered */ + orig_pmkid_list = (pmkid_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(orig_pmkid_list, WHD_NO_REGISTER_FUNCTION_POINTER); + orig_pmkid_list->npmkid = dtoh32(orig_pmkid_list->npmkid); + for (cnt = 0; cnt < orig_pmkid_list->npmkid; ++cnt) + { + /* Check if any address matches */ + if (!memcmp(pmkid->BSSID.octet, orig_pmkid_list->pmkid[cnt].BSSID.octet, sizeof(whd_mac_t) ) ) + { + break; + } + } + + if (cnt == MAXPMKID) { + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + WPRINT_WHD_ERROR(("Too manay PMKSA entries cached %" PRIu32 "\n", orig_pmkid_list->npmkid)); + return WHD_WLAN_NORESOURCE; + } + + /* Add Extra Space for New PMKID and write the new multicast list */ + if (cnt == orig_pmkid_list->npmkid) + { + new_pmkid_list = (pmkid_list_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + ( uint16_t )(sizeof(uint32_t) + + (orig_pmkid_list->npmkid + 1) * + sizeof(pmkid_t) ), + IOVAR_STR_PMKID_INFO); + CHECK_IOCTL_BUFFER(new_pmkid_list); + new_pmkid_list->npmkid = orig_pmkid_list->npmkid + 1; + memcpy(new_pmkid_list->pmkid, orig_pmkid_list->pmkid, orig_pmkid_list->npmkid * sizeof(pmkid_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + memcpy(&new_pmkid_list->pmkid[new_pmkid_list->npmkid - 1], pmkid, sizeof(pmkid_t) ); + new_pmkid_list->npmkid = htod32(new_pmkid_list->npmkid); + } + else + /* Replace Old PMKID for New PMKID under same BSSID and write the new multicast list */ + { + new_pmkid_list = (pmkid_list_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + ( uint16_t )(sizeof(uint32_t) + + (orig_pmkid_list->npmkid) * + sizeof(pmkid_t) ), + IOVAR_STR_PMKID_INFO); + CHECK_IOCTL_BUFFER(new_pmkid_list); + new_pmkid_list->npmkid = orig_pmkid_list->npmkid; + memcpy(new_pmkid_list->pmkid, orig_pmkid_list->pmkid, orig_pmkid_list->npmkid * sizeof(pmkid_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + memcpy(&new_pmkid_list->pmkid[cnt], pmkid, sizeof(pmkid_t) ); + new_pmkid_list->npmkid = htod32(new_pmkid_list->npmkid); + } + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} + +whd_result_t whd_wifi_pmkid_clear(whd_interface_t ifp) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver = (whd_driver_t)ifp->whd_driver; + + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, + 0, IOVAR_STR_PMKID_CLEAR) ); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + + return WHD_SUCCESS; +} + +whd_result_t whd_wifi_set_roam_time_threshold(whd_interface_t ifp, uint32_t roam_time_threshold) +{ + if (!ifp || !roam_time_threshold) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_ROAM_TIME_THRESH, roam_time_threshold); +} + +whd_result_t whd_wifi_get_roam_time_threshold(whd_interface_t ifp, uint32_t *roam_time_threshold) +{ + CHECK_IFP_NULL(ifp); + + return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ROAM_TIME_THRESH, roam_time_threshold); +} + +whd_result_t whd_wifi_get_rssi(whd_interface_t ifp, int32_t *rssi) +{ + CHECK_IFP_NULL(ifp); + + if (rssi == NULL) + return WHD_BADARG; + if (ifp->role == WHD_STA_ROLE) + { + return whd_wifi_get_ioctl_buffer(ifp, WLC_GET_RSSI, (uint8_t *)rssi, sizeof(*rssi) ); + } + return WHD_BADARG; +} + +whd_result_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, const whd_mac_t *client_mac) +{ + whd_buffer_t buffer; + whd_buffer_t response; + uint8_t *data = NULL; + client_rssi_t *client_rssi; + whd_driver_t whd_driver = ifp->whd_driver; + + /* WLAN expects buffer size to be 4-byte aligned */ + client_rssi = + (client_rssi_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, ROUND_UP(sizeof(client_rssi_t), + sizeof(uint32_t) ) ); + CHECK_IOCTL_BUFFER(client_rssi); + + memcpy(&client_rssi->macs, client_mac, sizeof(*client_mac) ); + client_rssi->rssi = 0; + + CHECK_RETURN_UNSUPPORTED_OK(whd_proto_get_ioctl(ifp, WLC_GET_RSSI, buffer, &response) ); + data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(rssi, data, sizeof(int32_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; } /** Callback for join events @@ -574,388 +1174,516 @@ uint32_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, const w * Wakes the thread which was doing the join, allowing it to resume. */ static void *whd_wifi_join_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, - void *handler_user_data) + const uint8_t *event_data, + void *handler_user_data) { - cy_semaphore_t *semaphore = (cy_semaphore_t *)handler_user_data; - whd_bool_t join_attempt_complete = WHD_FALSE; - whd_driver_t whd_driver = ifp->whd_driver; - whd_result_t result; - - UNUSED_PARAMETER(event_data); - - if (event_header->bsscfgidx >= WHD_INTERFACE_MAX) { - WPRINT_WHD_DEBUG(("%s: event_header: Bad interface\n", __FUNCTION__)); - return NULL; - } - - switch (event_header->event_type) { - case WLC_E_PSK_SUP: - /* Ignore WLC_E_PSK_SUP event if link is not up */ - if ((whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] & JOIN_LINK_READY) != 0) { - if (event_header->status == WLC_SUP_KEYED) { - /* Successful WPA key exchange */ - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= ~JOIN_SECURITY_FLAGS_MASK; - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_SECURITY_COMPLETE; - } - else { - /* join has completed with an error */ - join_attempt_complete = WHD_TRUE; - if ((event_header->status == WLC_SUP_KEYXCHANGE_WAIT_M1) && - (event_header->reason == WLC_E_SUP_WPA_PSK_TMO)) { - /* A timeout waiting for M1 may occur at the edge of the cell or if the AP is particularly slow. */ - WPRINT_WHD_DEBUG(("Supplicant M1 timeout event\n")); - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_M1_TIMEOUT; - } - else if ((event_header->status == WLC_SUP_KEYXCHANGE_WAIT_M3) && - (event_header->reason == WLC_E_SUP_WPA_PSK_TMO)) { - /* A timeout waiting for M3 is an indicator that the passphrase may be incorrect. */ - WPRINT_WHD_DEBUG(("Supplicant M3 timeout event\n")); - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_M3_TIMEOUT; - } - else if ((event_header->status == WLC_SUP_KEYXCHANGE_WAIT_G1) && - (event_header->reason == WLC_E_SUP_WPA_PSK_TMO)) { - /* A timeout waiting for G1 (group key) may occur at the edge of the cell. */ - WPRINT_WHD_DEBUG(("Supplicant G1 timeout event\n")); - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_G1_TIMEOUT; - } - else { - WPRINT_WHD_DEBUG(("Unsuccessful supplicant event; status=0x%" PRIu32 "\n", - event_header->status)); - /* Unknown failure during EAPOL key handshake */ - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_FAILURE; - } - } - } - break; - - case WLC_E_SET_SSID: - if (event_header->status == WLC_E_STATUS_SUCCESS) { - /* SSID has been successfully set. */ - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_SSID_SET; - } - /* We don't bail out on this event or things like WPS won't work if the AP is rebooting after configuration */ - else if (event_header->status == WLC_E_STATUS_NO_NETWORKS) { - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_NO_NETWORKS; - } - else { - join_attempt_complete = WHD_TRUE; - } - break; - - case WLC_E_LINK: - if ((event_header->flags & WLC_EVENT_MSG_LINK) != 0) { - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_LINK_READY; - } - else { - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= ~JOIN_LINK_READY; - } - break; + cy_semaphore_t *semaphore = (cy_semaphore_t *)handler_user_data; + whd_bool_t join_attempt_complete = WHD_FALSE; + whd_driver_t whd_driver = ifp->whd_driver; + whd_result_t result; + + UNUSED_PARAMETER(event_data); + + if (event_header->bsscfgidx >= WHD_INTERFACE_MAX) + { + WPRINT_WHD_DEBUG( ("%s: event_header: Bad interface\n", __FUNCTION__) ); + return NULL; + } + + switch (event_header->event_type) + { + case WLC_E_PSK_SUP: + /* Ignore WLC_E_PSK_SUP event if link is not up */ + if ( (whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] & JOIN_LINK_READY) != 0 ) + { + if (event_header->status == WLC_SUP_KEYED) + { + /* Successful WPA key exchange */ + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= ~JOIN_SECURITY_FLAGS_MASK; + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_SECURITY_COMPLETE; + } + else + { + /* join has completed with an error */ + join_attempt_complete = WHD_TRUE; + if ( (event_header->status == WLC_SUP_KEYXCHANGE_WAIT_M1) && + (event_header->reason == WLC_E_SUP_WPA_PSK_TMO) ) + { + /* A timeout waiting for M1 may occur at the edge of the cell or if the AP is particularly slow. */ + WPRINT_WHD_DEBUG( ("Supplicant M1 timeout event\n") ); + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_M1_TIMEOUT; + } + else if ( (event_header->status == WLC_SUP_KEYXCHANGE_WAIT_M3) && + (event_header->reason == WLC_E_SUP_WPA_PSK_TMO) ) + { + /* A timeout waiting for M3 is an indicator that the passphrase may be incorrect. */ + WPRINT_WHD_DEBUG( ("Supplicant M3 timeout event\n") ); + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_M3_TIMEOUT; + } + else if ( (event_header->status == WLC_SUP_KEYXCHANGE_WAIT_G1) && + (event_header->reason == WLC_E_SUP_WPA_PSK_TMO) ) + { + /* A timeout waiting for G1 (group key) may occur at the edge of the cell. */ + WPRINT_WHD_DEBUG( ("Supplicant G1 timeout event\n") ); + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_G1_TIMEOUT; + } + else + { + WPRINT_WHD_DEBUG( ("Unsuccessful supplicant event; status=0x%" PRIu32 "\n", + event_header->status) ); + /* Unknown failure during EAPOL key handshake */ + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_EAPOL_KEY_FAILURE; + } + } + } + break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= - ~(JOIN_AUTHENTICATED | JOIN_LINK_READY); - break; + case WLC_E_SET_SSID: + if (event_header->status == WLC_E_STATUS_SUCCESS) + { + /* SSID has been successfully set. */ + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_SSID_SET; + } + /* We don't bail out on this event or things like WPS won't work if the AP is rebooting after configuration */ + else if (event_header->status == WLC_E_STATUS_NO_NETWORKS) + { + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_NO_NETWORKS; + } + else + { + join_attempt_complete = WHD_TRUE; + } + break; - case WLC_E_AUTH: - if (event_header->status == WLC_E_STATUS_SUCCESS) { - whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_AUTHENTICATED; - } - else if (event_header->status == WLC_E_STATUS_UNSOLICITED) { - WPRINT_WHD_DEBUG(("Ignore UNSOLICITED pkt event\n")); - } - else { - /* We cannot authenticate. Perhaps we're blocked or at the edge of a cell. */ - join_attempt_complete = WHD_TRUE; - } - break; + case WLC_E_LINK: + if ( (event_header->flags & WLC_EVENT_MSG_LINK) != 0 ) + { + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_LINK_READY; + } + else + { + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= ~JOIN_LINK_READY; + } + break; - case WLC_E_CSA_COMPLETE_IND: - if (event_header->datalen >= sizeof(wl_chan_switch_t)) { - wl_chan_switch_t *wl_csa = (wl_chan_switch_t *)event_data; - UNUSED_PARAMETER(wl_csa); - WPRINT_WHD_INFO(("CSA event => chan %d\n", (dtoh16(wl_csa->chspec) & 0xff))); - } - break; + case WLC_E_DEAUTH_IND: + case WLC_E_DISASSOC_IND: + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] &= + ~(JOIN_AUTHENTICATED | JOIN_LINK_READY); + break; - /* Note - These are listed to keep gcc pedantic checking happy */ - case WLC_E_RRM: - case WLC_E_NONE: - case WLC_E_ROAM: - case WLC_E_JOIN: - case WLC_E_START: - case WLC_E_AUTH_IND: - case WLC_E_DEAUTH: - case WLC_E_ASSOC: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC: - case WLC_E_REASSOC_IND: - case WLC_E_DISASSOC: - case WLC_E_QUIET_START: - case WLC_E_QUIET_END: - case WLC_E_BEACON_RX: - case WLC_E_MIC_ERROR: - case WLC_E_NDIS_LINK: - case WLC_E_TXFAIL: - case WLC_E_PMKID_CACHE: - case WLC_E_RETROGRADE_TSF: - case WLC_E_PRUNE: - case WLC_E_AUTOAUTH: - case WLC_E_EAPOL_MSG: - case WLC_E_SCAN_COMPLETE: - case WLC_E_ADDTS_IND: - case WLC_E_DELTS_IND: - case WLC_E_BCNSENT_IND: - case WLC_E_BCNRX_MSG: - case WLC_E_BCNLOST_MSG: - case WLC_E_ROAM_PREP: - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - case WLC_E_RESET_COMPLETE: - case WLC_E_JOIN_START: - case WLC_E_ROAM_START: - case WLC_E_ASSOC_START: - case WLC_E_IBSS_ASSOC: - case WLC_E_RADIO: - case WLC_E_PSM_WATCHDOG: - case WLC_E_CCX_ASSOC_START: - case WLC_E_CCX_ASSOC_ABORT: - case WLC_E_PROBREQ_MSG: - case WLC_E_SCAN_CONFIRM_IND: - case WLC_E_COUNTRY_CODE_CHANGED: - case WLC_E_EXCEEDED_MEDIUM_TIME: - case WLC_E_ICV_ERROR: - case WLC_E_UNICAST_DECODE_ERROR: - case WLC_E_MULTICAST_DECODE_ERROR: - case WLC_E_TRACE: - case WLC_E_BTA_HCI_EVENT: - case WLC_E_IF: - case WLC_E_PFN_BEST_BATCHING: - case WLC_E_RSSI: - case WLC_E_EXTLOG_MSG: - case WLC_E_ACTION_FRAME: - case WLC_E_ACTION_FRAME_COMPLETE: - case WLC_E_PRE_ASSOC_IND: - case WLC_E_PRE_REASSOC_IND: - case WLC_E_CHANNEL_ADOPTED: - case WLC_E_AP_STARTED: - case WLC_E_DFS_AP_STOP: - case WLC_E_DFS_AP_RESUME: - case WLC_E_WAI_STA_EVENT: - case WLC_E_WAI_MSG: - case WLC_E_ESCAN_RESULT: - case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE: - case WLC_E_PROBRESP_MSG: - case WLC_E_P2P_PROBREQ_MSG: - case WLC_E_DCS_REQUEST: - case WLC_E_FIFO_CREDIT_MAP: - case WLC_E_ACTION_FRAME_RX: - case WLC_E_WAKE_EVENT: - case WLC_E_RM_COMPLETE: - case WLC_E_HTSFSYNC: - case WLC_E_OVERLAY_REQ: - case WLC_E_EXCESS_PM_WAKE_EVENT: - case WLC_E_PFN_SCAN_NONE: - case WLC_E_PFN_SCAN_ALLGONE: - case WLC_E_GTK_PLUMBED: - case WLC_E_ASSOC_IND_NDIS: - case WLC_E_REASSOC_IND_NDIS: - case WLC_E_ASSOC_REQ_IE: - case WLC_E_ASSOC_RESP_IE: - case WLC_E_ASSOC_RECREATED: - case WLC_E_ACTION_FRAME_RX_NDIS: - case WLC_E_AUTH_REQ: - case WLC_E_TDLS_PEER_EVENT: - case WLC_E_SPEEDY_RECREATE_FAIL: - case WLC_E_NATIVE: - case WLC_E_PKTDELAY_IND: - case WLC_E_AWDL_AW: - case WLC_E_AWDL_ROLE: - case WLC_E_AWDL_EVENT: - case WLC_E_NIC_AF_TXS: - case WLC_E_NAN: - case WLC_E_BEACON_FRAME_RX: - case WLC_E_SERVICE_FOUND: - case WLC_E_GAS_FRAGMENT_RX: - case WLC_E_GAS_COMPLETE: - case WLC_E_P2PO_ADD_DEVICE: - case WLC_E_P2PO_DEL_DEVICE: - case WLC_E_WNM_STA_SLEEP: - case WLC_E_TXFAIL_THRESH: - case WLC_E_PROXD: - case WLC_E_IBSS_COALESCE: - case WLC_E_AWDL_RX_PRB_RESP: - case WLC_E_AWDL_RX_ACT_FRAME: - case WLC_E_AWDL_WOWL_NULLPKT: - case WLC_E_AWDL_PHYCAL_STATUS: - case WLC_E_AWDL_OOB_AF_STATUS: - case WLC_E_AWDL_SCAN_STATUS: - case WLC_E_AWDL_AW_START: - case WLC_E_AWDL_AW_END: - case WLC_E_AWDL_AW_EXT: - case WLC_E_AWDL_PEER_CACHE_CONTROL: - case WLC_E_CSA_START_IND: - case WLC_E_CSA_DONE_IND: - case WLC_E_CSA_FAILURE_IND: - case WLC_E_CCA_CHAN_QUAL: - case WLC_E_BSSID: - case WLC_E_TX_STAT_ERROR: - case WLC_E_BCMC_CREDIT_SUPPORT: - case WLC_E_PSTA_PRIMARY_INTF_IND: - case WLC_E_P2P_DISC_LISTEN_COMPLETE: - case WLC_E_BT_WIFI_HANDOVER_REQ: - case WLC_E_SPW_TXINHIBIT: - case WLC_E_FBT_AUTH_REQ_IND: - case WLC_E_RSSI_LQM: - case WLC_E_PFN_GSCAN_FULL_RESULT: - case WLC_E_PFN_SWC: - case WLC_E_AUTHORIZED: - case WLC_E_PROBREQ_MSG_RX: - case WLC_E_PFN_SCAN_COMPLETE: - case WLC_E_RMC_EVENT: - case WLC_E_DPSTA_INTF_IND: - case WLC_E_ULP: - case WLC_E_LAST: - default: - whd_assert("Received event which was not registered\n", 0 != 0); - break; - } + case WLC_E_AUTH: + if (event_header->status == WLC_E_STATUS_SUCCESS) + { + whd_driver->internal_info.whd_join_status[event_header->bsscfgidx] |= JOIN_AUTHENTICATED; + } + else if (event_header->status == WLC_E_STATUS_UNSOLICITED) + { + WPRINT_WHD_DEBUG( ("Ignore UNSOLICITED pkt event\n") ); + } + else + { + /* We cannot authenticate. Perhaps we're blocked or at the edge of a cell. */ + join_attempt_complete = WHD_TRUE; + } + break; - if (whd_wifi_is_ready_to_transceive(ifp) == WHD_SUCCESS) { - join_attempt_complete = WHD_TRUE; - } + case WLC_E_CSA_COMPLETE_IND: + if (event_header->datalen >= sizeof(wl_chan_switch_t) ) + { + wl_chan_switch_t *wl_csa = (wl_chan_switch_t *)event_data; + UNUSED_PARAMETER(wl_csa); + WPRINT_WHD_INFO( ("CSA event => chan %d\n", (dtoh16(wl_csa->chspec) & 0xff) ) ); + } + break; - if (join_attempt_complete == WHD_TRUE) { - if (semaphore != NULL) { - result = cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, - WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Get semaphore failed in %s at %d \n", __func__, __LINE__)); - } - if (whd_driver->internal_info.active_join_semaphore != NULL) { - whd_assert("Unexpected semaphore\n", whd_driver->internal_info.active_join_semaphore == semaphore); - result = cy_rtos_set_semaphore(whd_driver->internal_info.active_join_semaphore, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Set semaphore failed in %s at %d \n", __func__, __LINE__)); - } - } - result = cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Set semaphore failed in %s at %d \n", __func__, __LINE__)); - } - } - return NULL; - } - else { - return handler_user_data; - } + /* Note - These are listed to keep gcc pedantic checking happy */ + case WLC_E_RRM: + case WLC_E_NONE: + case WLC_E_ROAM: + case WLC_E_JOIN: + case WLC_E_START: + case WLC_E_AUTH_IND: + case WLC_E_DEAUTH: + case WLC_E_ASSOC: + case WLC_E_ASSOC_IND: + case WLC_E_REASSOC: + case WLC_E_REASSOC_IND: + case WLC_E_DISASSOC: + case WLC_E_QUIET_START: + case WLC_E_QUIET_END: + case WLC_E_BEACON_RX: + case WLC_E_MIC_ERROR: + case WLC_E_NDIS_LINK: + case WLC_E_TXFAIL: + case WLC_E_PMKID_CACHE: + case WLC_E_RETROGRADE_TSF: + case WLC_E_PRUNE: + case WLC_E_AUTOAUTH: + case WLC_E_EAPOL_MSG: + case WLC_E_SCAN_COMPLETE: + case WLC_E_ADDTS_IND: + case WLC_E_DELTS_IND: + case WLC_E_BCNSENT_IND: + case WLC_E_BCNRX_MSG: + case WLC_E_BCNLOST_MSG: + case WLC_E_ROAM_PREP: + case WLC_E_PFN_NET_FOUND: + case WLC_E_PFN_NET_LOST: + case WLC_E_RESET_COMPLETE: + case WLC_E_JOIN_START: + case WLC_E_ROAM_START: + case WLC_E_ASSOC_START: + case WLC_E_IBSS_ASSOC: + case WLC_E_RADIO: + case WLC_E_PSM_WATCHDOG: + case WLC_E_CCX_ASSOC_START: + case WLC_E_CCX_ASSOC_ABORT: + case WLC_E_PROBREQ_MSG: + case WLC_E_SCAN_CONFIRM_IND: + case WLC_E_COUNTRY_CODE_CHANGED: + case WLC_E_EXCEEDED_MEDIUM_TIME: + case WLC_E_ICV_ERROR: + case WLC_E_UNICAST_DECODE_ERROR: + case WLC_E_MULTICAST_DECODE_ERROR: + case WLC_E_TRACE: + case WLC_E_BTA_HCI_EVENT: + case WLC_E_IF: + case WLC_E_PFN_BEST_BATCHING: + case WLC_E_RSSI: + case WLC_E_EXTLOG_MSG: + case WLC_E_ACTION_FRAME: + case WLC_E_ACTION_FRAME_COMPLETE: + case WLC_E_PRE_ASSOC_IND: + case WLC_E_PRE_REASSOC_IND: + case WLC_E_CHANNEL_ADOPTED: + case WLC_E_AP_STARTED: + case WLC_E_DFS_AP_STOP: + case WLC_E_DFS_AP_RESUME: + case WLC_E_WAI_STA_EVENT: + case WLC_E_WAI_MSG: + case WLC_E_ESCAN_RESULT: + case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE: + case WLC_E_PROBRESP_MSG: + case WLC_E_P2P_PROBREQ_MSG: + case WLC_E_DCS_REQUEST: + case WLC_E_FIFO_CREDIT_MAP: + case WLC_E_ACTION_FRAME_RX: + case WLC_E_WAKE_EVENT: + case WLC_E_RM_COMPLETE: + case WLC_E_HTSFSYNC: + case WLC_E_OVERLAY_REQ: + case WLC_E_EXCESS_PM_WAKE_EVENT: + case WLC_E_PFN_SCAN_NONE: + case WLC_E_PFN_SCAN_ALLGONE: + case WLC_E_GTK_PLUMBED: + case WLC_E_ASSOC_IND_NDIS: + case WLC_E_REASSOC_IND_NDIS: + case WLC_E_ASSOC_REQ_IE: + case WLC_E_ASSOC_RESP_IE: + case WLC_E_ASSOC_RECREATED: + case WLC_E_ACTION_FRAME_RX_NDIS: + case WLC_E_AUTH_REQ: + case WLC_E_TDLS_PEER_EVENT: + case WLC_E_SPEEDY_RECREATE_FAIL: + case WLC_E_NATIVE: + case WLC_E_PKTDELAY_IND: + case WLC_E_AWDL_AW: + case WLC_E_AWDL_ROLE: + case WLC_E_AWDL_EVENT: + case WLC_E_NIC_AF_TXS: + case WLC_E_NAN: + case WLC_E_BEACON_FRAME_RX: + case WLC_E_SERVICE_FOUND: + case WLC_E_GAS_FRAGMENT_RX: + case WLC_E_GAS_COMPLETE: + case WLC_E_P2PO_ADD_DEVICE: + case WLC_E_P2PO_DEL_DEVICE: + case WLC_E_WNM_STA_SLEEP: + case WLC_E_TXFAIL_THRESH: + case WLC_E_PROXD: + case WLC_E_IBSS_COALESCE: + case WLC_E_AWDL_RX_PRB_RESP: + case WLC_E_AWDL_RX_ACT_FRAME: + case WLC_E_AWDL_WOWL_NULLPKT: + case WLC_E_AWDL_PHYCAL_STATUS: + case WLC_E_AWDL_OOB_AF_STATUS: + case WLC_E_AWDL_SCAN_STATUS: + case WLC_E_AWDL_AW_START: + case WLC_E_AWDL_AW_END: + case WLC_E_AWDL_AW_EXT: + case WLC_E_AWDL_PEER_CACHE_CONTROL: + case WLC_E_CSA_START_IND: + case WLC_E_CSA_DONE_IND: + case WLC_E_CSA_FAILURE_IND: + case WLC_E_CCA_CHAN_QUAL: + case WLC_E_BSSID: + case WLC_E_TX_STAT_ERROR: + case WLC_E_BCMC_CREDIT_SUPPORT: + case WLC_E_PSTA_PRIMARY_INTF_IND: + case WLC_E_P2P_DISC_LISTEN_COMPLETE: + case WLC_E_BT_WIFI_HANDOVER_REQ: + case WLC_E_SPW_TXINHIBIT: + case WLC_E_FBT_AUTH_REQ_IND: + case WLC_E_RSSI_LQM: + case WLC_E_PFN_GSCAN_FULL_RESULT: + case WLC_E_PFN_SWC: + case WLC_E_AUTHORIZED: + case WLC_E_PROBREQ_MSG_RX: + case WLC_E_PFN_SCAN_COMPLETE: + case WLC_E_RMC_EVENT: + case WLC_E_DPSTA_INTF_IND: + case WLC_E_ULP: + case WLC_E_LAST: + default: + whd_assert("Received event which was not registered\n", 0 != 0); + break; + } + + if (whd_wifi_is_ready_to_transceive(ifp) == WHD_SUCCESS) + { + join_attempt_complete = WHD_TRUE; + } + + if (join_attempt_complete == WHD_TRUE) + { + if (semaphore != NULL) + { + result = cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, + WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Get semaphore failed in %s at %d \n", __func__, __LINE__) ); + } + if (whd_driver->internal_info.active_join_semaphore != NULL) + { + whd_assert("Unexpected semaphore\n", whd_driver->internal_info.active_join_semaphore == semaphore); + result = cy_rtos_set_semaphore(whd_driver->internal_info.active_join_semaphore, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Set semaphore failed in %s at %d \n", __func__, __LINE__) ); + } + } + result = cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Set semaphore failed in %s at %d \n", __func__, __LINE__) ); + } + } + return NULL; + } + else + { + return handler_user_data; + } } /* Do any needed preparation prior to launching a join */ -static uint32_t whd_wifi_active_join_init(whd_interface_t ifp, whd_security_t auth_type, const uint8_t *security_key, - uint8_t key_length, cy_semaphore_t *semaphore) +static whd_result_t whd_wifi_active_join_init(whd_interface_t ifp, whd_security_t auth_type, const uint8_t *security_key, + uint8_t key_length, cy_semaphore_t *semaphore) { - whd_driver_t whd_driver = ifp->whd_driver; - - if (whd_driver->internal_info.active_join_mutex_initted == WHD_FALSE) { - CHECK_RETURN(cy_rtos_init_semaphore(&whd_driver->internal_info.active_join_mutex, 1, 0)); - whd_driver->internal_info.active_join_mutex_initted = WHD_TRUE; - CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE)); - } - - CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, - WHD_FALSE)); - whd_driver->internal_info.active_join_semaphore = semaphore; - CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE)); + whd_driver_t whd_driver = ifp->whd_driver; + + if (whd_driver->internal_info.active_join_mutex_initted == WHD_FALSE) + { + CHECK_RETURN(cy_rtos_init_semaphore(&whd_driver->internal_info.active_join_mutex, 1, 0) ); + whd_driver->internal_info.active_join_mutex_initted = WHD_TRUE; + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE) ); + } + + CHECK_RETURN(cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, + WHD_FALSE) ); + whd_driver->internal_info.active_join_semaphore = semaphore; + CHECK_RETURN(cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE) ); + + CHECK_RETURN(whd_wifi_prepare_join(ifp, auth_type, security_key, key_length, semaphore) ); + return WHD_SUCCESS; +} - CHECK_RETURN(whd_wifi_prepare_join(ifp, auth_type, security_key, key_length, semaphore)); - return WHD_SUCCESS; +whd_result_t whd_set_wsec_info_algos(whd_interface_t ifp, uint32_t algos, uint32_t mask) +{ + whd_driver_t whd_driver; + wl_wsec_info_t *wsec_info; + whd_xtlv_t *wsec_info_tlv; + uint16_t tlv_data_len; + uint8_t tlv_data[8]; + uint32_t param_len; + uint8_t *buf; + whd_buffer_t buffer; + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + tlv_data_len = sizeof(tlv_data); + param_len = offsetof(wl_wsec_info_t, tlvs) + + offsetof(wl_wsec_info_tlv_t, data) + tlv_data_len; + + buf = whd_proto_get_iovar_buffer(whd_driver, &buffer, param_len, IOVAR_STR_WSEC_INFO); + CHECK_IOCTL_BUFFER(buf); + + wsec_info = (wl_wsec_info_t *)buf; + wsec_info->version = WL_WSEC_INFO_VERSION; + wsec_info_tlv = (whd_xtlv_t *)(buf + offsetof(struct wl_wsec_info, tlvs)); + + wsec_info->num_tlvs++; + memcpy(tlv_data, &algos, sizeof(algos)); + memcpy(tlv_data + sizeof(algos), &mask, sizeof(mask)); + + wsec_info_tlv->id = htod16(WL_WSEC_INFO_BSS_ALGOS); + wsec_info_tlv->len = htod16(tlv_data_len); + memcpy(wsec_info_tlv->data, tlv_data, tlv_data_len); + + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + return WHD_SUCCESS; } -static uint32_t whd_wifi_prepare_join(whd_interface_t ifp, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length, - cy_semaphore_t *semaphore) +static whd_result_t whd_wifi_prepare_join(whd_interface_t ifp, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length, + cy_semaphore_t *semaphore) { - whd_buffer_t buffer; - uint32_t auth_mfp = WL_MFP_NONE; - whd_result_t retval = WHD_SUCCESS; - whd_result_t check_result = WHD_SUCCESS; - uint32_t *data; - uint32_t *wpa_auth; - uint32_t bss_index = 0; - uint32_t auth; - whd_driver_t whd_driver = ifp->whd_driver; - uint16_t event_entry = 0xFF; - - (void)bss_index; - if ((auth_type == WHD_SECURITY_WPA2_FBT_ENT) || (auth_type == WHD_SECURITY_IBSS_OPEN) || - (auth_type == WHD_SECURITY_WPA2_FBT_PSK)) { - return WHD_UNKNOWN_SECURITY_TYPE; - } - else if ((auth_type & WEP_ENABLED) != 0) { - return WHD_WEP_NOT_ALLOWED; - } - if ((((key_length > (uint8_t)WSEC_MAX_PSK_LEN) || (key_length < (uint8_t)WSEC_MIN_PSK_LEN)) && - ((auth_type == WHD_SECURITY_WPA_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA_AES_PSK) || - (auth_type == WHD_SECURITY_WPA2_AES_PSK) || (auth_type == WHD_SECURITY_WPA2_TKIP_PSK) || - (auth_type == WHD_SECURITY_WPA2_MIXED_PSK))) || - ((key_length > (uint8_t)WSEC_MAX_SAE_PASSWORD_LEN) && - ((auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK)))) { - return WHD_INVALID_KEY; + whd_buffer_t buffer; + uint32_t auth_mfp = WL_MFP_NONE; + whd_result_t retval = WHD_SUCCESS; + whd_result_t check_result = WHD_SUCCESS; + uint32_t *data; + uint32_t *wpa_auth; + uint32_t bss_index = 0; + uint32_t auth; + whd_driver_t whd_driver = ifp->whd_driver; + uint16_t event_entry = 0xFF; + (void)bss_index; + uint16_t chip_id = whd_chip_get_chip_id(whd_driver); + uint32_t algos = 0, mask = 0; + + if ( chip_id == 43022 ) + { + if ( (auth_type == WHD_SECURITY_WPA_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA_AES_PSK) || + (auth_type == WHD_SECURITY_WPA_MIXED_PSK) || (auth_type == WHD_SECURITY_WPA2_TKIP_PSK) || + (auth_type == WHD_SECURITY_WPA_TKIP_ENT) || (auth_type == WHD_SECURITY_WPA_AES_ENT) || + (auth_type == WHD_SECURITY_WPA_MIXED_ENT) || (auth_type == WHD_SECURITY_WPA2_TKIP_ENT) ) + { + WPRINT_WHD_ERROR( ("WPA and TKIP are not supported, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_UNSUPPORTED; + } + } + if ( (auth_type == WHD_SECURITY_WPA2_FBT_ENT) || (auth_type == WHD_SECURITY_IBSS_OPEN) || + (auth_type == WHD_SECURITY_WPA2_FBT_PSK) ) + { + return WHD_UNKNOWN_SECURITY_TYPE; + } + else if ( (auth_type & WEP_ENABLED) != 0 ) + { + return WHD_WEP_NOT_ALLOWED; + } + if ( ( ( (key_length > (uint8_t)WSEC_MAX_PSK_LEN) || (key_length < (uint8_t)WSEC_MIN_PSK_LEN) ) && + ( (auth_type == WHD_SECURITY_WPA_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA_AES_PSK) || + (auth_type == WHD_SECURITY_WPA2_AES_PSK) || (auth_type == WHD_SECURITY_WPA2_AES_PSK_SHA256) || + (auth_type == WHD_SECURITY_WPA2_TKIP_PSK) || (auth_type == WHD_SECURITY_WPA2_MIXED_PSK) ) ) || + ( (key_length > (uint8_t)WSEC_MAX_SAE_PASSWORD_LEN) && + ( (auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) ) ) ) + { + return WHD_INVALID_KEY; + } + + (void)auth_type, (void)security_key, (void)key_length, (void)semaphore; + + /* Clear the current join status */ + whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] = 0; + + /* Get MFP iovar is not necessary for open security */ + if (auth_type != WHD_SECURITY_OPEN) + { + /* Setting wsec will overwrite mfp setting in older branches, store value before setting wsec */ + CHECK_RETURN(whd_wifi_get_iovar_value(ifp, IOVAR_STR_MFP, &auth_mfp) ); + } + + /* Set Wireless Security Type */ + CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_WSEC, (uint32_t)(auth_type & 0xFF) ) ); + + if (whd_driver->chip_info.fwcap_flags & (1 << WHD_FWCAP_GCMP)) { + if (auth_type == WHD_SECURITY_WPA3_ENT || auth_type == WHD_SECURITY_WPA3_192BIT_ENT) { + algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); + mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + WPRINT_WHD_DEBUG(("set_wsec_info algos (0x%" PRIx32 ") mask (0x%" PRIx32 ")\n", algos, mask)); + CHECK_RETURN(whd_set_wsec_info_algos(ifp, algos, mask)); + } + else if (auth_type == WHD_SECURITY_WPA3_ENT_AES_CCMP) { + algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM); + mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256); + WPRINT_WHD_DEBUG(("set_wsec_info algos (0x%" PRIx32 ") mask (0x%" PRIx32 ")\n", algos, mask)); + CHECK_RETURN(whd_set_wsec_info_algos(ifp, algos, mask)); + } } - (void)auth_type, (void)security_key, (void)key_length, (void)semaphore; - - /* Clear the current join status */ - whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] = 0; - - /* Setting wsec will overwrite mfp setting in older branches, store value before setting wsec */ - CHECK_RETURN(whd_wifi_get_iovar_value(ifp, IOVAR_STR_MFP, &auth_mfp)); - - /* Set Wireless Security Type */ - CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_WSEC, (uint32_t)(auth_type & 0xFF))); - - /* Map the interface to a BSS index */ - bss_index = ifp->bsscfgidx; - - /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); - CHECK_IOCTL_BUFFER(data); - data[0] = htod32(bss_index); - data[1] = - htod32((uint32_t)((((auth_type & WPA_SECURITY) != 0) || ((auth_type & WPA2_SECURITY) != 0) || - (auth_type & WPA3_SECURITY) != 0) ? - 1 : - 0)); - (void)whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - - /* Set the EAPOL version to whatever the AP is using (-1) */ - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA2_EAPVER); - CHECK_IOCTL_BUFFER(data); - data[0] = htod32(bss_index); - data[1] = htod32((uint32_t)-1); - (void)whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - - /* Send WPA Key */ - switch (auth_type) { - case WHD_SECURITY_OPEN: - case WHD_SECURITY_WPS_SECURE: - break; - - case WHD_SECURITY_WPA_TKIP_PSK: - case WHD_SECURITY_WPA_AES_PSK: - case WHD_SECURITY_WPA_MIXED_PSK: - case WHD_SECURITY_WPA2_AES_PSK: - case WHD_SECURITY_WPA2_TKIP_PSK: - case WHD_SECURITY_WPA2_MIXED_PSK: - case WHD_SECURITY_WPA2_WPA_AES_PSK: - case WHD_SECURITY_WPA2_WPA_MIXED_PSK: - /* Set the EAPOL key packet timeout value, otherwise unsuccessful supplicant events aren't reported. If the IOVAR is unsupported then continue. */ - CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, - DEFAULT_EAPOL_KEY_PACKET_TIMEOUT)); - CHECK_RETURN(whd_wifi_set_passphrase(ifp, security_key, key_length)); - break; + /* Enable Roaming in FW by default */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ROAM_OFF, 0) ); + + /* Map the interface to a BSS index */ + bss_index = ifp->bsscfgidx; + + /* Set necessary cfg param for GTKOE to work on 43022 */ + if(whd_driver->chip_info.chip_id == 43022) + { + /* Set the wpa auth */ + data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WPA_AUTH); + CHECK_IOCTL_BUFFER(data); + + data[0] = (int32_t)bss_index; + data[1] = ((auth_type == WHD_SECURITY_WPA_TKIP_PSK) ? + (WPA_AUTH_PSK) : (WPA2_AUTH_PSK) ); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + + /* Set the wsec */ + data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_WSEC); + CHECK_IOCTL_BUFFER(data); + + data[0] = (int32_t)bss_index; + data[1] = (auth_type & 0xFF); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); + + /* Set wowl bit for broadcast key rotation */ + CHECK_RETURN(whd_configure_wowl(ifp, WL_WOWL_KEYROT)); + } + + /* Set supplicant variable - mfg app doesn't support these iovars, so don't care if return fails */ + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); + CHECK_IOCTL_BUFFER(data); + data[0] = htod32(bss_index); + data[1] = + htod32( ( uint32_t )( ( ( (auth_type & WPA_SECURITY) != 0 ) || ( (auth_type & WPA2_SECURITY) != 0 ) || + (auth_type & WPA3_SECURITY) != 0 ) ? 1 : 0 ) ); + (void)whd_proto_set_iovar(ifp, buffer, 0); + + /* Set the EAPOL version to whatever the AP is using (-1) */ + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA2_EAPVER); + CHECK_IOCTL_BUFFER(data); + data[0] = htod32(bss_index); + data[1] = htod32( ( uint32_t )-1 ); + (void)whd_proto_set_iovar(ifp, buffer, 0); + + /* Send WPA Key */ + switch (auth_type) + { + case WHD_SECURITY_OPEN: + case WHD_SECURITY_WPS_SECURE: + case WHD_SECURITY_WPA3_OWE: + break; + + case WHD_SECURITY_WPA_TKIP_PSK: + case WHD_SECURITY_WPA_AES_PSK: + case WHD_SECURITY_WPA_MIXED_PSK: + case WHD_SECURITY_WPA2_AES_PSK: + case WHD_SECURITY_WPA2_AES_PSK_SHA256: + case WHD_SECURITY_WPA2_TKIP_PSK: + case WHD_SECURITY_WPA2_MIXED_PSK: + case WHD_SECURITY_WPA2_WPA_AES_PSK: + case WHD_SECURITY_WPA2_WPA_MIXED_PSK: + /* Set the EAPOL key packet timeout value, otherwise unsuccessful supplicant events aren't reported. If the IOVAR is unsupported then continue. */ + CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, + DEFAULT_EAPOL_KEY_PACKET_TIMEOUT) ); + CHECK_RETURN(whd_wifi_set_passphrase(ifp, security_key, key_length) ); + break; case WHD_SECURITY_WPA3_SAE: case WHD_SECURITY_WPA3_WPA2_PSK: @@ -964,138 +1692,186 @@ static uint32_t whd_wifi_prepare_join(whd_interface_t ifp, whd_security_t auth_t } /* Set the EAPOL key packet timeout value, otherwise unsuccessful supplicant events aren't reported. If the IOVAR is unsupported then continue. */ CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, - DEFAULT_EAPOL_KEY_PACKET_TIMEOUT)); - CHECK_RETURN(whd_wifi_sae_password(ifp, security_key, key_length)); + DEFAULT_EAPOL_KEY_PACKET_TIMEOUT)); + if (whd_driver->chip_info.fwcap_flags & (1 << WHD_FWCAP_SAE)) { + CHECK_RETURN(whd_wifi_sae_password(ifp, security_key, key_length)); + } + else { + /* Disable Roaming in FW, because our wpa3_external_supplicant's limitation. + If FW report WLC_E_EXT_AUTH_REQ during roaming, Host already called whd_wifi_stop_external_auth_request. */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ROAM_OFF, 1)); + } break; - case WHD_SECURITY_WPA_TKIP_ENT: - case WHD_SECURITY_WPA_AES_ENT: - case WHD_SECURITY_WPA_MIXED_ENT: - case WHD_SECURITY_WPA2_TKIP_ENT: - case WHD_SECURITY_WPA2_AES_ENT: - case WHD_SECURITY_WPA2_MIXED_ENT: - /* Disable eapol timer by setting to value 0 */ - CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, 0)); - break; + case WHD_SECURITY_WPA_TKIP_ENT: + case WHD_SECURITY_WPA_AES_ENT: + case WHD_SECURITY_WPA_MIXED_ENT: + case WHD_SECURITY_WPA2_TKIP_ENT: + case WHD_SECURITY_WPA2_AES_ENT: + case WHD_SECURITY_WPA2_MIXED_ENT: + case WHD_SECURITY_WPA3_ENT: + case WHD_SECURITY_WPA3_ENT_AES_CCMP: + case WHD_SECURITY_WPA3_192BIT_ENT: + /* Disable eapol timer by setting to value 0 */ + CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, 0) ); + break; #if 0 case WHD_SECURITY_WPA2_FBT_ENT: /* Disable eapol timer by setting to value 0 */ CHECK_RETURN_UNSUPPORTED_CONTINUE(whd_wifi_set_supplicant_key_timeout(ifp, 0) ); break; #endif - case WHD_SECURITY_FORCE_32_BIT: - case WHD_SECURITY_UNKNOWN: - default: - whd_assert("whd_wifi_prepare_join: Unsupported security type\n", 0 != 0); - break; - } - /* Set infrastructure mode */ - CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_INFRA, ((auth_type & IBSS_ENABLED) == 0) ? 1 : 0)); - - if ((auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK)) { - auth = WL_AUTH_SAE; - } - else { - auth = WL_AUTH_OPEN_SYSTEM; - } - CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_AUTH, auth)); - - /* From PMF cert test plan, + case WHD_SECURITY_FORCE_32_BIT: + case WHD_SECURITY_UNKNOWN: + default: + whd_assert("whd_wifi_prepare_join: Unsupported security type\n", 0 != 0); + break; + } + /* Set infrastructure mode */ + CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_INFRA, ( (auth_type & IBSS_ENABLED) == 0 ) ? 1 : 0) ); + + if ( (auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) ) + { + auth = WL_AUTH_SAE; + } + else + { + auth = WL_AUTH_OPEN_SYSTEM; + } + CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_AUTH, auth) ); + + /* From PMF cert test plan, * 2.2 Out of Box Requirements * When WPA2 security is enabled on the DUT, then by defaults the DUT shall: * Enable Robust Management Frame Protection Capable (MFPC) functionality */ - if ((auth_type == WHD_SECURITY_WPA3_SAE) || (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) || - (auth_type & WPA2_SECURITY)) { - auth_mfp = WL_MFP_CAPABLE; - } - - check_result = whd_wifi_set_iovar_value(ifp, IOVAR_STR_MFP, auth_mfp); - if (check_result != WHD_SUCCESS) { - WPRINT_WHD_DEBUG(("Older chipsets might not support MFP..Ignore result\n")); - } - - /* Set WPA authentication mode */ - wpa_auth = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER(wpa_auth); - - switch (auth_type) { + if (auth_type == WHD_SECURITY_WPA3_SAE || auth_type == WHD_SECURITY_WPA3_ENT || auth_type == WHD_SECURITY_WPA3_192BIT_ENT + || auth_type == WHD_SECURITY_WPA3_ENT_AES_CCMP || auth_type == WHD_SECURITY_WPA3_OWE) + { + auth_mfp = WL_MFP_REQUIRED; + } + else if ( (auth_type == WHD_SECURITY_WPA3_WPA2_PSK) || (auth_type & WPA2_SECURITY) ) + { + auth_mfp = WL_MFP_CAPABLE; + } + + check_result = whd_wifi_set_iovar_value(ifp, IOVAR_STR_MFP, auth_mfp); + if (check_result != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("Older chipsets might not support MFP..Ignore result\n") ); + } + + if (auth_type == WHD_SECURITY_WPA3_ENT || auth_type == WHD_SECURITY_WPA3_192BIT_ENT) + { + char *bip_suite = "\x00\x0F\xAC\x0C"; /* Setting Group Management Cipher Suite - GMAC-256 for WPA3 ENT */ + CHECK_RETURN(whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_BIP, bip_suite, 4)); + } + else if (auth_type == WHD_SECURITY_WPA3_ENT_AES_CCMP) + { + char *bip_suite = "\x00\x0F\xAC\x06"; /* Setting Group Management Cipher Suite - BIP-128 for WPA3 ENT */ + CHECK_RETURN(whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_BIP, bip_suite, 4)); + } + + /* Set WPA authentication mode */ + wpa_auth = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + CHECK_IOCTL_BUFFER(wpa_auth); + + switch (auth_type) + { #if 0 case WHD_SECURITY_IBSS_OPEN: /* IBSS does not get authenticated onto an AP */ whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] |= JOIN_AUTHENTICATED; #endif - /* intentional fall-thru */ - /* Disables Eclipse static analysis warning */ - /* no break */ - /* Fall-Through */ - case WHD_SECURITY_OPEN: - case WHD_SECURITY_WPS_SECURE: - *wpa_auth = WPA_AUTH_DISABLED; - /* Open Networks do not have to complete security */ - whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] |= JOIN_SECURITY_COMPLETE; - break; + /* intentional fall-thru */ + /* Disables Eclipse static analysis warning */ + /* no break */ + /* Fall-Through */ + case WHD_SECURITY_OPEN: + case WHD_SECURITY_WPS_SECURE: + *wpa_auth = WPA_AUTH_DISABLED; + /* Open Networks do not have to complete security */ + whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] |= JOIN_SECURITY_COMPLETE; + break; - case WHD_SECURITY_WPA_TKIP_PSK: - case WHD_SECURITY_WPA_AES_PSK: - case WHD_SECURITY_WPA_MIXED_PSK: - *wpa_auth = (uint32_t)WPA_AUTH_PSK; - break; + case WHD_SECURITY_WPA_TKIP_PSK: + case WHD_SECURITY_WPA_AES_PSK: + case WHD_SECURITY_WPA_MIXED_PSK: + *wpa_auth = (uint32_t)WPA_AUTH_PSK; + break; - case WHD_SECURITY_WPA2_AES_PSK: - case WHD_SECURITY_WPA2_TKIP_PSK: - case WHD_SECURITY_WPA2_MIXED_PSK: - case WHD_SECURITY_WPA2_WPA_AES_PSK: - case WHD_SECURITY_WPA2_WPA_MIXED_PSK: - *wpa_auth = (uint32_t)WPA2_AUTH_PSK; - break; + case WHD_SECURITY_WPA2_AES_PSK: + case WHD_SECURITY_WPA2_TKIP_PSK: + case WHD_SECURITY_WPA2_MIXED_PSK: + case WHD_SECURITY_WPA2_WPA_AES_PSK: + case WHD_SECURITY_WPA2_WPA_MIXED_PSK: + *wpa_auth = (uint32_t)WPA2_AUTH_PSK; + break; + case WHD_SECURITY_WPA2_AES_PSK_SHA256: + *wpa_auth = (uint32_t)WPA2_AUTH_PSK_SHA256; + break; - case WHD_SECURITY_WPA3_SAE: - case WHD_SECURITY_WPA3_WPA2_PSK: - *wpa_auth = (uint32_t)WPA3_AUTH_SAE_PSK; - break; + case WHD_SECURITY_WPA3_SAE: + case WHD_SECURITY_WPA3_WPA2_PSK: + *wpa_auth = (uint32_t)WPA3_AUTH_SAE_PSK; + break; - case WHD_SECURITY_WPA_TKIP_ENT: - case WHD_SECURITY_WPA_AES_ENT: - case WHD_SECURITY_WPA_MIXED_ENT: - *wpa_auth = (uint32_t)WPA_AUTH_UNSPECIFIED; - break; + case WHD_SECURITY_WPA_TKIP_ENT: + case WHD_SECURITY_WPA_AES_ENT: + case WHD_SECURITY_WPA_MIXED_ENT: + *wpa_auth = (uint32_t)WPA_AUTH_UNSPECIFIED; + break; - case WHD_SECURITY_WPA2_TKIP_ENT: - case WHD_SECURITY_WPA2_AES_ENT: - case WHD_SECURITY_WPA2_MIXED_ENT: - *wpa_auth = (uint32_t)WPA2_AUTH_UNSPECIFIED; - break; + case WHD_SECURITY_WPA2_TKIP_ENT: + case WHD_SECURITY_WPA2_AES_ENT: + case WHD_SECURITY_WPA2_MIXED_ENT: + *wpa_auth = (uint32_t)WPA2_AUTH_UNSPECIFIED; + break; + case WHD_SECURITY_WPA3_ENT_AES_CCMP: + *wpa_auth = (uint32_t)WPA2_AUTH_1X_SHA256; + break; + case WHD_SECURITY_WPA3_ENT: + *wpa_auth = (uint32_t)WPA3_AUTH_1X_SHA256; + break; + case WHD_SECURITY_WPA3_192BIT_ENT: + *wpa_auth = (uint32_t)WPA3_AUTH_1X_SUITE_B_SHA384; + break; #if 0 case WHD_SECURITY_WPA2_FBT_ENT: *wpa_auth = ( uint32_t )(WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT); break; #endif - case WHD_SECURITY_UNKNOWN: - case WHD_SECURITY_FORCE_32_BIT: - default: - WPRINT_WHD_DEBUG(("Unsupported Security type\n")); - *wpa_auth = WPA_AUTH_DISABLED; - break; - } - *wpa_auth = htod32(*wpa_auth); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_WPA_AUTH, buffer, 0)); - - if (ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) { - whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY]); - ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - } - - CHECK_RETURN(whd_management_set_event_handler(ifp, join_events, whd_wifi_join_events_handler, (void *)semaphore, - &event_entry)); - if (event_entry >= WHD_EVENT_ENTRY_MAX) { - WPRINT_WHD_ERROR(("Join events registration failed in function %s and line %d", __func__, __LINE__)); - return WHD_UNFINISHED; - } - ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = event_entry; - whd_assert("Set join Event handler failed\n", retval == WHD_SUCCESS); + case WHD_SECURITY_WPA3_OWE: + *wpa_auth = (uint32_t)WPA3_AUTH_OWE; + break; - return WHD_SUCCESS; + case WHD_SECURITY_UNKNOWN: + case WHD_SECURITY_FORCE_32_BIT: + default: + WPRINT_WHD_DEBUG( ("Unsupported Security type\n") ); + *wpa_auth = WPA_AUTH_DISABLED; + break; + } + *wpa_auth = htod32(*wpa_auth); + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SET_WPA_AUTH, buffer, 0) ); + + if (ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) + { + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY]); + ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + + CHECK_RETURN(whd_management_set_event_handler(ifp, join_events, whd_wifi_join_events_handler, (void *)semaphore, + &event_entry) ); + if (event_entry >= WHD_EVENT_ENTRY_MAX) + { + WPRINT_WHD_ERROR( ("Join events registration failed in function %s and line %d", __func__, __LINE__) ); + return WHD_UNFINISHED; + } + ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = event_entry; + whd_assert("Set join Event handler failed\n", retval == WHD_SUCCESS); + + return WHD_SUCCESS; } /* do any needed tear down after join @@ -1104,353 +1880,399 @@ static uint32_t whd_wifi_prepare_join(whd_interface_t ifp, whd_security_t auth_t */ static void whd_wifi_active_join_deinit(whd_interface_t ifp, cy_semaphore_t *stack_semaphore, whd_result_t result) { - whd_driver_t whd_driver = ifp->whd_driver; - whd_result_t val; - /* deinit join specific variables, with protection from mutex */ + whd_driver_t whd_driver = ifp->whd_driver; + whd_result_t val; + /* deinit join specific variables, with protection from mutex */ - val = cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - if (val != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Get semaphore failed in %s at %d \n", __func__, __LINE__)); + val = cy_rtos_get_semaphore(&whd_driver->internal_info.active_join_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + if (val != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Get semaphore failed in %s at %d \n", __func__, __LINE__) ); - whd_driver->internal_info.active_join_semaphore = NULL; + whd_driver->internal_info.active_join_semaphore = NULL; - cy_rtos_deinit_semaphore(stack_semaphore); + cy_rtos_deinit_semaphore(stack_semaphore); - if (WHD_SUCCESS != result) { - WPRINT_WHD_INFO(("Failed join (err %" PRIu32 ")\n", result)); - ifp->role = WHD_INVALID_ROLE; - } + if (WHD_SUCCESS != result) + { + WPRINT_WHD_INFO( ("Failed join (err %" PRIu32 ")\n", result) ); + ifp->role = WHD_INVALID_ROLE; + } - val = cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE); - if (val != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Get semaphore failed in %s at %d \n", __func__, __LINE__)); + val = cy_rtos_set_semaphore(&whd_driver->internal_info.active_join_mutex, WHD_FALSE); + if (val != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Get semaphore failed in %s at %d \n", __func__, __LINE__) ); - /* we forced the chip to be up during join, now let it sleep */ - WHD_WLAN_LET_SLEEP(whd_driver); + /* we forced the chip to be up during join, now let it sleep */ + WHD_WLAN_LET_SLEEP(whd_driver); } static uint32_t whd_wifi_join_wait_for_complete(whd_interface_t ifp, cy_semaphore_t *semaphore) { whd_result_t result; - whd_time_t start_time; - whd_time_t current_time; + cy_time_t start_time; + cy_time_t current_time; whd_bool_t done = WHD_FALSE; - cy_rtos_get_time(&start_time); + cy_rtos_get_time(&start_time); - while (!done) { - result = cy_rtos_get_semaphore(semaphore, DEFAULT_JOIN_ATTEMPT_TIMEOUT / 10, WHD_FALSE); - whd_assert("Get semaphore failed", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT)); - REFERENCE_DEBUG_ONLY_VARIABLE(result); + while (!done) + { + result = cy_rtos_get_semaphore(semaphore, DEFAULT_JOIN_ATTEMPT_TIMEOUT / 10, WHD_FALSE); + whd_assert("Get semaphore failed", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT) ); + REFERENCE_DEBUG_ONLY_VARIABLE(result); - result = whd_wifi_is_ready_to_transceive(ifp); - if (result == WHD_SUCCESS) { - break; - } + result = whd_wifi_is_ready_to_transceive(ifp); + if (result == WHD_SUCCESS) + { + break; + } - cy_rtos_get_time(¤t_time); - done = (whd_bool_t)((current_time - start_time) >= DEFAULT_JOIN_ATTEMPT_TIMEOUT); - } + cy_rtos_get_time(¤t_time); + done = (whd_bool_t)( (current_time - start_time) >= DEFAULT_JOIN_ATTEMPT_TIMEOUT ); + } - if (result != WHD_SUCCESS) { - CHECK_RETURN(whd_wifi_leave(ifp)); - WPRINT_WHD_INFO(("%s: not ready to transceive (err %" PRIu32 "); left network\n", __func__, result)); - } + if (result != WHD_SUCCESS) + { + CHECK_RETURN(whd_wifi_leave(ifp) ); + WPRINT_WHD_INFO( ("%s: not ready to transceive (err %" PRIu32 "); left network\n", __func__, result) ); + } - return result; + return result; } -static uint32_t whd_wifi_check_join_status(whd_interface_t ifp) +static whd_result_t whd_wifi_check_join_status(whd_interface_t ifp) { - whd_driver_t whd_driver = ifp->whd_driver; - - if ((uint32_t)ifp->bsscfgidx >= WHD_INTERFACE_MAX) { - WPRINT_WHD_ERROR(("%s: Bad interface %d\n", __FUNCTION__, ifp->bsscfgidx)); - return WHD_INVALID_JOIN_STATUS; - } - switch (whd_driver->internal_info.whd_join_status[ifp->bsscfgidx]) { - case JOIN_NO_NETWORKS: - return WHD_NETWORK_NOT_FOUND; - - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_M1_TIMEOUT: - return WHD_EAPOL_KEY_PACKET_M1_TIMEOUT; - - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_M3_TIMEOUT: - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_M3_TIMEOUT: - return WHD_EAPOL_KEY_PACKET_M3_TIMEOUT; + whd_driver_t whd_driver = ifp->whd_driver; + + if ( (uint32_t)ifp->bsscfgidx >= WHD_INTERFACE_MAX ) + { + WPRINT_WHD_ERROR( ("%s: Bad interface %d\n", __FUNCTION__, ifp->bsscfgidx) ); + return WHD_INVALID_JOIN_STATUS; + } + switch (whd_driver->internal_info.whd_join_status[ifp->bsscfgidx]) + { + case JOIN_NO_NETWORKS: + return WHD_NETWORK_NOT_FOUND; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_M1_TIMEOUT: + return WHD_EAPOL_KEY_PACKET_M1_TIMEOUT; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_M3_TIMEOUT: + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_M3_TIMEOUT: + return WHD_EAPOL_KEY_PACKET_M3_TIMEOUT; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_G1_TIMEOUT: + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_G1_TIMEOUT: + return WHD_EAPOL_KEY_PACKET_G1_TIMEOUT; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_FAILURE: + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_FAILURE: + return WHD_EAPOL_KEY_FAILURE; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_SECURITY_COMPLETE: + return WHD_SUCCESS; + + case 0: + case JOIN_SECURITY_COMPLETE: /* For open/WEP */ + return WHD_NOT_AUTHENTICATED; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SECURITY_COMPLETE: + return WHD_JOIN_IN_PROGRESS; + + case JOIN_AUTHENTICATED | JOIN_LINK_READY: + case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET: + return WHD_NOT_KEYED; + + default: + return WHD_INVALID_JOIN_STATUS; + } +} - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_G1_TIMEOUT: - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_G1_TIMEOUT: - return WHD_EAPOL_KEY_PACKET_G1_TIMEOUT; +whd_result_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_result_t *ap, const uint8_t *security_key, + uint8_t key_length) +{ + whd_buffer_t buffer; + cy_semaphore_t join_semaphore; + whd_result_t result; + wl_extjoin_params_t *ext_join_params; + wl_join_params_t *join_params; + whd_security_t security = ap->security; + whd_driver_t whd_driver; + wl_chanspec_t chanspec = 0; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Keep WLAN awake while joining */ + WHD_WLAN_KEEP_AWAKE(whd_driver); + ifp->role = WHD_STA_ROLE; + + if (ap->bss_type == WHD_BSS_TYPE_MESH) + { + return WHD_UNSUPPORTED; + } + + if (ap->bss_type == WHD_BSS_TYPE_ADHOC) + { + security |= IBSS_ENABLED; + } + + if (ap->channel == 0) + { + WPRINT_WHD_INFO( ("FW will do assoc-scan full channels\n") ); + } + else if (ap->band == WHD_802_11_BAND_2_4GHZ) + { + chanspec = (wl_chanspec_t)(ap->channel | GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) | + GET_C_VAR(whd_driver, + CHANSPEC_BW_20) | GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) ); + } + else if (ap->band == WHD_802_11_BAND_5GHZ) + { + chanspec = (wl_chanspec_t)(ap->channel | GET_C_VAR(whd_driver, CHANSPEC_BAND_5G) | + GET_C_VAR(whd_driver, + CHANSPEC_BW_20) | GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) ); + } + else if (ap->band == WHD_802_11_BAND_6GHZ) + { + chanspec = (wl_chanspec_t)(ap->channel | GET_C_VAR(whd_driver, CHANSPEC_BAND_6G) | + GET_C_VAR(whd_driver, + CHANSPEC_BW_20) | GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE) ); + } + else + { + WPRINT_WHD_ERROR( ("AP Band is not allowed/valid\n") ); + return WHD_BADARG; + } + + if (NULL_MAC(ap->BSSID.octet) ) + { + WPRINT_WHD_ERROR( ("NULL address is not allowed/valid\n") ); + return WHD_BADARG; + } + + if (BROADCAST_ID(ap->BSSID.octet) ) + { + WPRINT_WHD_ERROR( ("Broadcast address is not allowed/valid in join with specific BSSID of AP\n") ); + return WHD_BADARG; + } + + if ( (ap->SSID.length == 0) || (ap->SSID.length > (size_t)SSID_NAME_SIZE) ) + { + WPRINT_WHD_ERROR( ("%s: failure: SSID length error\n", __func__) ); + return WHD_WLAN_BADSSIDLEN; + } + + CHECK_RETURN(cy_rtos_init_semaphore(&join_semaphore, 1, 0) ); + result = whd_wifi_active_join_init(ifp, security, security_key, key_length, &join_semaphore); + + if (result == WHD_SUCCESS) + { + if (ap->bss_type == WHD_BSS_TYPE_ADHOC) + { + CHECK_RETURN(whd_wifi_set_chanspec(ifp, chanspec) ); + } + + /* Join network */ + ext_join_params = + (wl_extjoin_params_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_extjoin_params_t), "join"); + CHECK_IOCTL_BUFFER(ext_join_params); + memset(ext_join_params, 0, sizeof(wl_extjoin_params_t) ); + + ext_join_params->ssid.SSID_len = ap->SSID.length; + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(ext_join_params->ssid.SSID, ap->SSID.value, ext_join_params->ssid.SSID_len); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(&ext_join_params->assoc_params.bssid, &ap->BSSID, sizeof(whd_mac_t) ); + ext_join_params->scan_params.scan_type = 0; + ext_join_params->scan_params.active_time = -1; + ext_join_params->scan_params.home_time = -1; + ext_join_params->scan_params.nprobes = -1; + ext_join_params->scan_params.passive_time = -1; + ext_join_params->assoc_params.bssid_cnt = 0; + if (ap->channel) + { + ext_join_params->assoc_params.chanspec_num = (uint32_t)1; + ext_join_params->assoc_params.chanspec_list[0] = htod16(chanspec); + } + result = whd_proto_set_iovar(ifp, buffer, 0); + + WPRINT_WHD_INFO( ("%s: set_ssid result (err %" PRIu32 "); left network\n", __func__, result) ); + + /* Some firmware, e.g. for 4390, does not support the join IOVAR, so use the older IOCTL call instead */ + if (result == WHD_WLAN_UNSUPPORTED) + { + join_params = + (wl_join_params_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wl_join_params_t) ); + CHECK_IOCTL_BUFFER(join_params); + memset(join_params, 0, sizeof(wl_join_params_t) ); + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(&join_params->ssid, &ext_join_params->ssid, sizeof(wlc_ssid_t) ); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + memcpy(&join_params->params.bssid, &ap->BSSID, sizeof(whd_mac_t) ); + join_params->params.bssid_cnt = 0; + if (ap->channel) + { + join_params->params.chanspec_num = (uint32_t)1; + join_params->params.chanspec_list[0] = htod16(chanspec); + } + result = whd_proto_set_ioctl(ifp, WLC_SET_SSID, buffer, 0); + } + + if (result == WHD_SUCCESS) + { + + uint16_t chip_id = whd_chip_get_chip_id(whd_driver); + + CHECK_RETURN(whd_wifi_join_wait_for_complete(ifp, &join_semaphore) ); + + if ( (chip_id == 0x4373) || (chip_id == 55560) ) + { + /* For 11 AC MAX throughput set the frame burst and MPDU per AMPDU */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_MPDU_PER_AMPDU, 16) ); + } + + } + else + { + WPRINT_WHD_INFO( ("%s:3 not ready to transceive (err %" PRIu32 "); left network\n", __func__, result) ); + } + } + else + { + WPRINT_WHD_INFO( ("%s: active join init failed: (%" PRIu32 ")\n", __FUNCTION__, result) ); + } + /* clean up from the join attempt */ + whd_wifi_active_join_deinit(ifp, &join_semaphore, result); + + CHECK_RETURN(result); + + return WHD_SUCCESS; +} - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_EAPOL_KEY_FAILURE: - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_EAPOL_KEY_FAILURE: - return WHD_EAPOL_KEY_FAILURE; +whd_result_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length) +{ + cy_semaphore_t join_sema; + whd_result_t result; + whd_buffer_t buffer; + wlc_ssid_t *ssid_params; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if (ssid == NULL) + { + WPRINT_WHD_ERROR( ("%s: failure: ssid is null\n", __func__) ); + return WHD_BADARG; + } + + if ( (ssid->length == 0) || (ssid->length > (size_t)SSID_NAME_SIZE) ) + { + WPRINT_WHD_ERROR( ("%s: failure: SSID length error\n", __func__) ); + return WHD_WLAN_BADSSIDLEN; + } + + /* Keep WLAN awake while joining */ + WHD_WLAN_KEEP_AWAKE(whd_driver); + ifp->role = WHD_STA_ROLE; + + CHECK_RETURN(cy_rtos_init_semaphore(&join_sema, 1, 0) ); + result = whd_wifi_active_join_init(ifp, auth_type, security_key, key_length, &join_sema); + + if (result == WHD_SUCCESS) + { + /* Join network */ + ssid_params = (struct wlc_ssid *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(wlc_ssid_t) ); + CHECK_IOCTL_BUFFER(ssid_params); + memset(ssid_params, 0, sizeof(wlc_ssid_t) ); + ssid_params->SSID_len = htod32(ssid->length); + memcpy(ssid_params->SSID, ssid->value, ssid_params->SSID_len); + result = whd_proto_set_ioctl(ifp, WLC_SET_SSID, buffer, 0); + + if (result == WHD_SUCCESS) + { + CHECK_RETURN(whd_wifi_join_wait_for_complete(ifp, &join_sema) ); + } + } + + /* clean up from the join attempt */ + whd_wifi_active_join_deinit(ifp, &join_sema, result); + + return result; +} - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET | JOIN_SECURITY_COMPLETE: - return WHD_SUCCESS; - - case 0: - case JOIN_SECURITY_COMPLETE: /* For open/WEP */ - return WHD_NOT_AUTHENTICATED; - - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SECURITY_COMPLETE: - return WHD_JOIN_IN_PROGRESS; - - case JOIN_AUTHENTICATED | JOIN_LINK_READY: - case JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_SSID_SET: - return WHD_NOT_KEYED; - - default: - return WHD_INVALID_JOIN_STATUS; - } -} - -uint32_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_result_t *ap, const uint8_t *security_key, - uint8_t key_length) -{ - whd_buffer_t buffer; - cy_semaphore_t join_semaphore; - whd_result_t result; - wl_extjoin_params_t *ext_join_params; - wl_join_params_t *join_params; - whd_security_t security = ap->security; - uint16_t wl_band_for_channel = 0; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - /* Keep WLAN awake while joining */ - WHD_WLAN_KEEP_AWAKE(whd_driver); - ifp->role = WHD_STA_ROLE; - - if (ap->bss_type == WHD_BSS_TYPE_MESH) { - return WHD_UNSUPPORTED; - } - - if (ap->bss_type == WHD_BSS_TYPE_ADHOC) { - security |= IBSS_ENABLED; - } - - if (NULL_MAC(ap->BSSID.octet)) { - WPRINT_WHD_ERROR(("NULL address is not allowed/valid\n")); - return WHD_BADARG; - } - - if (BROADCAST_ID(ap->BSSID.octet)) { - WPRINT_WHD_ERROR(("Broadcast address is not allowed/valid in join with specific BSSID of AP\n")); - return WHD_BADARG; - } - - if ((ap->SSID.length == 0) || (ap->SSID.length > (size_t)SSID_NAME_SIZE)) { - WPRINT_WHD_ERROR(("%s: failure: SSID length error\n", __func__)); - return WHD_WLAN_BADSSIDLEN; - } - - CHECK_RETURN(cy_rtos_init_semaphore(&join_semaphore, 1, 0)); - result = whd_wifi_active_join_init(ifp, security, security_key, key_length, &join_semaphore); - - if (result == WHD_SUCCESS) { - /* Check if soft AP is running, if so, move its current channel to the the destination AP */ - if ((ifp->role == WHD_AP_ROLE) && (whd_wifi_is_ready_to_transceive(ifp) == WHD_SUCCESS)) { - uint32_t current_softap_channel = 0; - CHECK_RETURN(whd_wifi_get_channel(ifp, ¤t_softap_channel)); - if (current_softap_channel != ap->channel) { - CHECK_RETURN(whd_wifi_set_channel(ifp, ap->channel)); - WPRINT_WHD_DEBUG(("WARN: moving soft-AP channel from %" PRIu32 " to %d due to STA join\n", - current_softap_channel, ap->channel)); - cy_rtos_delay_milliseconds(100); - } - } - - else { - if (ap->bss_type == WHD_BSS_TYPE_ADHOC) { - CHECK_RETURN(whd_wifi_set_channel(ifp, ap->channel)); - } - } - - /* Join network */ - ext_join_params = - (wl_extjoin_params_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_extjoin_params_t), "join"); - CHECK_IOCTL_BUFFER(ext_join_params); - memset(ext_join_params, 0, sizeof(wl_extjoin_params_t)); - - ext_join_params->ssid.SSID_len = ap->SSID.length; - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(ext_join_params->ssid.SSID, ap->SSID.value, ext_join_params->ssid.SSID_len); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(&ext_join_params->assoc_params.bssid, &ap->BSSID, sizeof(whd_mac_t)); - ext_join_params->scan_params.scan_type = 0; - ext_join_params->scan_params.active_time = -1; - ext_join_params->scan_params.home_time = -1; - ext_join_params->scan_params.nprobes = -1; - ext_join_params->scan_params.passive_time = -1; - ext_join_params->assoc_params.bssid_cnt = 0; - if (ap->channel) { - ext_join_params->assoc_params.chanspec_num = (uint32_t)1; - ext_join_params->assoc_params.chanspec_list[0] = - (wl_chanspec_t)htod16((ap->channel | - GET_C_VAR(whd_driver, CHANSPEC_BW_20) | GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE))); - - /* set band properly */ - wl_band_for_channel = whd_channel_to_wl_band(whd_driver, ap->channel); - - ext_join_params->assoc_params.chanspec_list[0] |= wl_band_for_channel; - } - result = whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0); - - WPRINT_WHD_INFO(("%s: set_ssid result (err %" PRIu32 "); left network\n", __func__, result)); - - /* Some firmware, e.g. for 4390, does not support the join IOVAR, so use the older IOCTL call instead */ - if (result == WHD_WLAN_UNSUPPORTED) { - join_params = - (wl_join_params_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(wl_join_params_t)); - CHECK_IOCTL_BUFFER(join_params); - memset(join_params, 0, sizeof(wl_join_params_t)); - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(&join_params->ssid, &ext_join_params->ssid, sizeof(wlc_ssid_t)); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - memcpy(&join_params->params.bssid, &ap->BSSID, sizeof(whd_mac_t)); - join_params->params.bssid_cnt = 0; - if (ap->channel) { - join_params->params.chanspec_num = (uint32_t)1; - join_params->params.chanspec_list[0] = - (wl_chanspec_t)htod16((ap->channel | - GET_C_VAR(whd_driver, - CHANSPEC_BW_20) | - GET_C_VAR(whd_driver, CHANSPEC_CTL_SB_NONE))); - - /* set band properly */ - join_params->params.chanspec_list[0] |= wl_band_for_channel; - } - result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_SSID, buffer, 0); - } - - if (result == WHD_SUCCESS) { - - uint16_t chip_id = whd_chip_get_chip_id(whd_driver); - - CHECK_RETURN(whd_wifi_join_wait_for_complete(ifp, &join_semaphore)); - - if (chip_id == 0x4373) { - /* For 11 AC MAX throughput set the frame burst and MPDU per AMPDU */ - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_MPDU_PER_AMPDU, 16)); - } - } - else { - WPRINT_WHD_INFO(("%s:3 not ready to transceive (err %" PRIu32 "); left network\n", __func__, result)); - } - } - else { - WPRINT_WHD_INFO(("%s: active join init failed: (%" PRIu32 ")\n", __FUNCTION__, result)); - } - /* clean up from the join attempt */ - whd_wifi_active_join_deinit(ifp, &join_semaphore, result); - - CHECK_RETURN(result); - - return WHD_SUCCESS; -} - -uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length) -{ - cy_semaphore_t join_sema; - whd_result_t result; - whd_buffer_t buffer; - wlc_ssid_t *ssid_params; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - if (ssid == NULL) { - WPRINT_WHD_ERROR(("%s: failure: ssid is null\n", __func__)); - return WHD_BADARG; - } - - if ((ssid->length == 0) || (ssid->length > (size_t)SSID_NAME_SIZE)) { - WPRINT_WHD_ERROR(("%s: failure: SSID length error\n", __func__)); - return WHD_WLAN_BADSSIDLEN; - } - - /* Keep WLAN awake while joining */ - WHD_WLAN_KEEP_AWAKE(whd_driver); - ifp->role = WHD_STA_ROLE; - - CHECK_RETURN(cy_rtos_init_semaphore(&join_sema, 1, 0)); - result = whd_wifi_active_join_init(ifp, auth_type, security_key, key_length, &join_sema); - - if (result == WHD_SUCCESS) { - /* Join network */ - ssid_params = (struct wlc_ssid *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(wlc_ssid_t)); - CHECK_IOCTL_BUFFER(ssid_params); - memset(ssid_params, 0, sizeof(wlc_ssid_t)); - ssid_params->SSID_len = htod32(ssid->length); - memcpy(ssid_params->SSID, ssid->value, ssid_params->SSID_len); - result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_SSID, buffer, 0); - - if (result == WHD_SUCCESS) { - CHECK_RETURN(whd_wifi_join_wait_for_complete(ifp, &join_sema)); - } - } - - /* clean up from the join attempt */ - whd_wifi_active_join_deinit(ifp, &join_sema, result); - - return result; -} - -uint32_t whd_wifi_leave(whd_interface_t ifp) -{ - whd_result_t result = WHD_SUCCESS; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - /* If interface is greater than max return error */ - if (ifp->bsscfgidx >= WHD_INTERFACE_MAX) { - WPRINT_WHD_ERROR(("%s: Bad interface 2\n", __FUNCTION__)); - return WHD_BADARG; - } - if (ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) { - CHECK_RETURN(whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY])); - ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - } - - /* Disassociate from AP */ - result = whd_wifi_set_ioctl_buffer(ifp, WLC_DISASSOC, NULL, 0); - - if (result != WHD_SUCCESS) { - WPRINT_WHD_DEBUG(("whd_sdpcm_send_ioctl(WLC_DISASSOC) failed:%" PRIu32 "\r\n", result)); - } - - whd_driver->internal_info.whd_join_status[ifp->bsscfgidx] = 0; - ifp->role = WHD_INVALID_ROLE; - - if (whd_driver->internal_info.active_join_mutex_initted == WHD_TRUE) { - cy_rtos_deinit_semaphore(&whd_driver->internal_info.active_join_mutex); - whd_driver->internal_info.active_join_mutex_initted = WHD_FALSE; - } - if (whd_driver->internal_info.active_join_semaphore) { - cy_rtos_deinit_semaphore(whd_driver->internal_info.active_join_semaphore); - whd_driver->internal_info.active_join_semaphore = NULL; - } - - - return WHD_SUCCESS; -} +whd_result_t whd_wifi_leave(whd_interface_t ifp) +{ + whd_result_t result = WHD_SUCCESS; + whd_driver_t whd_driver; + uint32_t bss_index = 0; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Map the interface to a BSS index */ + bss_index = ifp->bsscfgidx; + + /* If interface is greater than max return error */ + if (bss_index >= WHD_INTERFACE_MAX) + { + WPRINT_WHD_ERROR( ("%s: Bad interface 2\n", __FUNCTION__) ); + return WHD_BADARG; + } + if (ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) + { + CHECK_RETURN(whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY]) ); + ifp->event_reg_list[WHD_JOIN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + + /* Disassociate from AP */ + result = whd_wifi_set_ioctl_buffer(ifp, WLC_DISASSOC, NULL, 0); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_DEBUG( ("send_ioctl(WLC_DISASSOC) failed:%" PRIu32 "\r\n", result) ); + } + + if((whd_driver->chip_info.chip_id == 43022) || (whd_driver->chip_info.chip_id == 43907) || (whd_driver->chip_info.chip_id == 43909) || (whd_driver->chip_info.chip_id == 43012)) + { + whd_buffer_t buffer = NULL; + uint32_t *data = NULL; + /* De-initialize the supplicant, as sup init happens on every join */ + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)8, "bsscfg:" IOVAR_STR_SUP_WPA); + CHECK_IOCTL_BUFFER(data); + data[0] = htod32(bss_index); + data[1] = htod32(0); + (void)whd_proto_set_iovar(ifp, buffer, 0); + } + + whd_driver->internal_info.whd_join_status[bss_index] = 0; + ifp->role = WHD_INVALID_ROLE; + + if (whd_driver->internal_info.active_join_mutex_initted == WHD_TRUE) + { + cy_rtos_deinit_semaphore(&whd_driver->internal_info.active_join_mutex); + whd_driver->internal_info.active_join_mutex_initted = WHD_FALSE; + } + if (whd_driver->internal_info.active_join_semaphore) + { + cy_rtos_deinit_semaphore(whd_driver->internal_info.active_join_semaphore); + whd_driver->internal_info.active_join_semaphore = NULL; + } + + + return WHD_SUCCESS; +} /** Handles scan result events * @@ -1465,1541 +2287,2242 @@ uint32_t whd_wifi_leave(whd_interface_t ifp) * */ static void *whd_wifi_scan_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, - const uint8_t *event_data, - void *handler_user_data) -{ - whd_scan_result_t *record; - wl_escan_result_t *eresult; - wl_bss_info_t *bss_info; - uint16_t chanspec; - uint32_t version; - whd_tlv8_header_t *cp; - uint32_t len; - uint16_t ie_offset; - uint32_t bss_info_length; - country_info_ie_fixed_portion_t *country_info_ie; - rsn_ie_fixed_portion_t *rsnie; - wpa_ie_fixed_portion_t *wpaie = NULL; - uint8_t rate_num; - ht_capabilities_ie_t *ht_capabilities_ie = NULL; - uint32_t count_tmp = 0; - uint16_t temp16; - uint16_t bss_count; - whd_driver_t whd_driver = ifp->whd_driver; - - if (whd_driver->internal_info.scan_result_callback == NULL) { - return handler_user_data; - } - - if (event_header->status == WLC_E_STATUS_SUCCESS) { - whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_COMPLETED_SUCCESSFULLY); - whd_driver->internal_info.scan_result_callback = NULL; - whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); - ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - return handler_user_data; - } - if ((event_header->status == WLC_E_STATUS_NEWSCAN) || (event_header->status == WLC_E_STATUS_NEWASSOC) || - (event_header->status == WLC_E_STATUS_ABORT)) { - whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_ABORTED); - whd_driver->internal_info.scan_result_callback = NULL; - whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); - ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - return handler_user_data; - } - - if (event_header->status != WLC_E_STATUS_PARTIAL) { - return handler_user_data; - } - - eresult = (wl_escan_result_t *)event_data; - bss_info = &eresult->bss_info[0]; - bss_count = dtoh16(eresult->bss_count); + const uint8_t *event_data, + void *handler_user_data) - version = dtoh32(WHD_READ_32(&bss_info->version)); - whd_minor_assert("wl_bss_info_t has wrong version", version == WL_BSS_INFO_VERSION); - - /* PNO bss info doesn't contain the correct bss info version */ - if (version != WL_BSS_INFO_VERSION) { - whd_minor_assert("Invalid bss_info version returned by firmware\n", version != WL_BSS_INFO_VERSION); - - return handler_user_data; - } - - whd_minor_assert("More than one result returned by firmware", bss_count == 1); - if (bss_count != 1) { - return handler_user_data; - } - - /* +{ + whd_scan_result_t *record; + wl_escan_result_t *eresult; + wl_bss_info_t *bss_info; + uint16_t chanspec; + uint32_t version; + whd_tlv8_header_t *cp; + uint32_t len; + uint16_t ie_offset; + uint32_t bss_info_length; + country_info_ie_fixed_portion_t *country_info_ie; + rsn_ie_fixed_portion_t *rsnie; + wpa_ie_fixed_portion_t *wpaie = NULL; + rsnx_ie_t *rsnxie = NULL; + uint8_t rate_num; + ht_capabilities_ie_t *ht_capabilities_ie = NULL; + uint32_t count_tmp = 0; + uint16_t temp16; + uint16_t bss_count; + whd_driver_t whd_driver = ifp->whd_driver; + + if (whd_driver->internal_info.scan_result_callback == NULL) + { + return handler_user_data; + } + + if (event_header->status == WLC_E_STATUS_SUCCESS) + { + whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_COMPLETED_SUCCESSFULLY); + whd_driver->internal_info.scan_result_callback = NULL; + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); + ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + return handler_user_data; + } + if ( (event_header->status == WLC_E_STATUS_NEWSCAN) || (event_header->status == WLC_E_STATUS_NEWASSOC) || + (event_header->status == WLC_E_STATUS_ABORT) ) + { + whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_ABORTED); + whd_driver->internal_info.scan_result_callback = NULL; + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); + ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + return handler_user_data; + } + + if (event_header->status != WLC_E_STATUS_PARTIAL) + { + return handler_user_data; + } + + eresult = (wl_escan_result_t *)event_data; + bss_info = &eresult->bss_info[0]; + bss_count = dtoh16(eresult->bss_count); + + version = dtoh32(WHD_READ_32(&bss_info->version) ); + whd_minor_assert("wl_bss_info_t has wrong version", version == WL_BSS_INFO_VERSION); + + /* PNO bss info doesn't contain the correct bss info version */ + if (version != WL_BSS_INFO_VERSION) + { + whd_minor_assert("Invalid bss_info version returned by firmware\n", version != WL_BSS_INFO_VERSION); + + return handler_user_data; + } + + whd_minor_assert("More than one result returned by firmware", bss_count == 1); + if (bss_count != 1) + { + return handler_user_data; + } + + /* * check the SSID length and bssinfo ie offset for buffer overflow */ - bss_info->ie_offset = dtoh16(bss_info->ie_offset); - bss_info->ie_length = dtoh32(bss_info->ie_length); - if ((bss_info->SSID_len > sizeof(bss_info->SSID)) || (bss_info->ie_offset < sizeof(wl_bss_info_t)) || - (bss_info->ie_offset > (sizeof(wl_bss_info_t) + bss_info->ie_length))) { - WPRINT_WHD_ERROR(("Invalid bss length check %s: SSID_len:%d,ie_len:%" PRIu32 ",ie_off:%d\n", __FUNCTION__, - bss_info->SSID_len, bss_info->ie_length, bss_info->ie_offset)); - whd_minor_assert(" bss length check failed\n", bss_info->SSID_len != sizeof(bss_info->SSID)); - return handler_user_data; - } - - /* Safe to access *whd_scan_result_ptr, as whd_scan_result_ptr == NULL case is handled above */ - record = (whd_scan_result_t *)(whd_driver->internal_info.whd_scan_result_ptr); - - /* Clear the last scan result data */ - memset(record, 0, sizeof(whd_scan_result_t)); - - /* + bss_info->ie_offset = dtoh16(bss_info->ie_offset); + bss_info->ie_length = dtoh32(bss_info->ie_length); + if ( (bss_info->SSID_len > sizeof(bss_info->SSID) ) || (bss_info->ie_offset < sizeof(wl_bss_info_t) ) || + (bss_info->ie_offset > (sizeof(wl_bss_info_t) + bss_info->ie_length) ) ) + { + WPRINT_WHD_ERROR( ("Invalid bss length check %s: SSID_len:%d,ie_len:%" PRIu32 ",ie_off:%d\n", __FUNCTION__, + bss_info->SSID_len, bss_info->ie_length, bss_info->ie_offset) ); + whd_minor_assert(" bss length check failed\n", bss_info->SSID_len != sizeof(bss_info->SSID) ); + return handler_user_data; + } + + /* Safe to access *whd_scan_result_ptr, as whd_scan_result_ptr == NULL case is handled above */ + record = (whd_scan_result_t *)(whd_driver->internal_info.whd_scan_result_ptr); + + /* Clear the last scan result data */ + memset(record, 0, sizeof(whd_scan_result_t) ); + + /* * Totally ignore off channel results. This can only happen with DSSS (1 and 2 Mb). It is better to * totally ignore it when it happens. It is hard to argue it is "significant" given that it can't * happen in 5G with OFDM (or other 2G modulations). This is left here so that it could be * passed as a scan result for debugging only. */ - if (!(bss_info->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL)) { - record->flags |= WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL; - /* Comment out this return statement to pass along an off channel result for debugging */ - return handler_user_data; - } - - /* Copy the SSID into the output record structure */ - record->SSID.length = (uint8_t)MIN_OF(sizeof(record->SSID.value), bss_info->SSID_len); - memset(record->SSID.value, 0, sizeof(record->SSID.value)); - memcpy(record->SSID.value, bss_info->SSID, record->SSID.length); - - /* Copy the BSSID into the output record structure */ - memcpy((void *)record->BSSID.octet, (const void *)bss_info->BSSID.octet, sizeof(bss_info->BSSID.octet)); - - /* Copy the RSSI into the output record structure */ - record->signal_strength = (int16_t)dtoh16((WHD_READ_16(&bss_info->RSSI))); - - /* Find maximum data rate and put it in the output record structure */ - record->max_data_rate = 0; - count_tmp = WHD_READ_32(&bss_info->rateset.count); - if (count_tmp > 16) { - count_tmp = 16; - } + if (!(bss_info->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) ) + { + record->flags |= WHD_SCAN_RESULT_FLAG_RSSI_OFF_CHANNEL; + /* Comment out this return statement to pass along an off channel result for debugging */ + return handler_user_data; + } + + /* Copy the SSID into the output record structure */ + record->SSID.length = (uint8_t)MIN_OF(sizeof(record->SSID.value), bss_info->SSID_len); + memset(record->SSID.value, 0, sizeof(record->SSID.value) ); + memcpy(record->SSID.value, bss_info->SSID, record->SSID.length); + + /* Copy the BSSID into the output record structure */ + memcpy( (void *)record->BSSID.octet, (const void *)bss_info->BSSID.octet, sizeof(bss_info->BSSID.octet) ); + + /* Copy the RSSI into the output record structure */ + record->signal_strength = ( int16_t )dtoh16( (WHD_READ_16(&bss_info->RSSI) ) ); + + /* Find maximum data rate and put it in the output record structure */ + record->max_data_rate = 0; + count_tmp = WHD_READ_32(&bss_info->rateset.count); + if (count_tmp > 16) + { + count_tmp = 16; + } #ifdef WPRINT_ENABLE_WHD_DEBUG - /* print out scan results info */ - { - char ea_buf[WHD_ETHER_ADDR_STR_LEN]; - char ssid_buf[SSID_NAME_SIZE + 1]; - - WPRINT_WHD_DEBUG(("Scan result: channel=%d signal=%d ssid=%s bssid=%s\n", record->channel, - record->signal_strength, - whd_ssid_to_string(record->SSID.value, record->SSID.length, ssid_buf, - (uint8_t)sizeof(ssid_buf)), - whd_ether_ntoa((const uint8_t *)bss_info->BSSID.octet, ea_buf, sizeof(ea_buf)))); - } + /* print out scan results info */ + { + char ea_buf[WHD_ETHER_ADDR_STR_LEN]; + char ssid_buf[SSID_NAME_SIZE + 1]; + + WPRINT_WHD_DEBUG( ("Scan result: channel=%d signal=%d ssid=%s bssid=%s\n", record->channel, + record->signal_strength, + whd_ssid_to_string(record->SSID.value, record->SSID.length, ssid_buf, + (uint8_t)sizeof(ssid_buf) ), + whd_ether_ntoa( (const uint8_t *)bss_info->BSSID.octet, ea_buf, sizeof(ea_buf) ) ) ); + } #endif /* WPRINT_ENABLE_WHD_DEBUG */ - for (rate_num = 0; rate_num < count_tmp; rate_num++) { - uint32_t rate = RSPEC_TO_KBPS(bss_info->rateset.rates[rate_num]); - if (record->max_data_rate < rate) { - record->max_data_rate = rate; - } - } - - bss_info->capability = dtoh16(bss_info->capability); - - /* Write the BSS type into the output record structure */ - record->bss_type = - ((bss_info->capability & DOT11_CAP_ESS) != - 0) ? - WHD_BSS_TYPE_INFRASTRUCTURE : - ((bss_info->capability & DOT11_CAP_IBSS) != - 0) ? - WHD_BSS_TYPE_ADHOC : - WHD_BSS_TYPE_UNKNOWN; - - /* Determine the network security. - * Some of this section has been copied from the standard broadcom host driver file wl/exe/wlu.c function wl_dump_wpa_rsn_ies - */ - - ie_offset = WHD_READ_16(&bss_info->ie_offset); - cp = (whd_tlv8_header_t *)(((uint8_t *)bss_info) + ie_offset); - len = WHD_READ_32(&bss_info->ie_length); - bss_info_length = WHD_READ_32(&bss_info->length); - - record->ie_ptr = (uint8_t *)cp; - record->ie_len = len; - - /* Validate the length of the IE section */ - if ((ie_offset > bss_info_length) || (len > bss_info_length - ie_offset)) { - whd_minor_assert("Invalid ie length", 1 == 0); - return handler_user_data; - } - - /* Find an RSN IE (Robust-Security-Network Information-Element) */ - rsnie = (rsn_ie_fixed_portion_t *)whd_parse_dot11_tlvs(cp, len, DOT11_IE_ID_RSN); - - /* Find a WPA IE */ - if (rsnie == NULL) { - whd_tlv8_header_t *parse = cp; - uint32_t parse_len = len; - while ((wpaie = - (wpa_ie_fixed_portion_t *)whd_parse_tlvs(parse, parse_len, DOT11_IE_ID_VENDOR_SPECIFIC)) != 0) { - if (whd_is_wpa_ie((vendor_specific_ie_header_t *)wpaie, &parse, &parse_len) != WHD_FALSE) { - break; - } - } - } - - temp16 = WHD_READ_16(&bss_info->capability); - - /* Check if AP is configured for RSN */ - if ((rsnie != NULL) && - (rsnie->tlv_header.length >= RSN_IE_MINIMUM_LENGTH + rsnie->pairwise_suite_count * sizeof(uint32_t))) { - uint16_t a; - uint32_t group_key_suite; - akm_suite_portion_t *akm_suites; - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - akm_suites = (akm_suite_portion_t *)&(rsnie->pairwise_suite_list[rsnie->pairwise_suite_count]); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - for (a = 0; a < akm_suites->akm_suite_count; ++a) { - uint32_t akm_suite_list_item = ntoh32(akm_suites->akm_suite_list[a]) & 0xFF; - if (akm_suite_list_item == (uint32_t)WHD_AKM_PSK) { - record->security |= WPA2_SECURITY; - } - if (akm_suite_list_item == (uint32_t)WHD_AKM_SAE_SHA256) { - record->security |= WPA3_SECURITY; - } - if (akm_suite_list_item == (uint32_t)WHD_AKM_8021X) { - record->security |= WPA2_SECURITY; - record->security |= ENTERPRISE_ENABLED; - } - if (akm_suite_list_item == (uint32_t)WHD_AKM_FT_8021X) { - record->security |= WPA2_SECURITY; - record->security |= FBT_ENABLED; - record->security |= ENTERPRISE_ENABLED; - } - if (akm_suite_list_item == (uint32_t)WHD_AKM_FT_PSK) { - record->security |= WPA2_SECURITY; - record->security |= FBT_ENABLED; - } - } - - group_key_suite = ntoh32(rsnie->group_key_suite) & 0xFF; - /* Check the RSN contents to see if there are any references to TKIP cipher (2) in the group key or pairwise keys, */ - /* If so it must be mixed mode. */ - if (group_key_suite == (uint32_t)WHD_CIPHER_TKIP) { - record->security |= TKIP_ENABLED; - } - if (group_key_suite == (uint32_t)WHD_CIPHER_CCMP_128) { - record->security |= AES_ENABLED; - } - - for (a = 0; a < rsnie->pairwise_suite_count; ++a) { - uint32_t pairwise_suite_list_item = ntoh32(rsnie->pairwise_suite_list[a]) & 0xFF; - if (pairwise_suite_list_item == (uint32_t)WHD_CIPHER_TKIP) { - record->security |= TKIP_ENABLED; - } - - if (pairwise_suite_list_item == (uint32_t)WHD_CIPHER_CCMP_128) { - record->security |= AES_ENABLED; - } - } - } - /* Check if AP is configured for WPA */ - else if ((wpaie != NULL) && - (wpaie->vendor_specific_header.tlv_header.length >= - WPA_IE_MINIMUM_LENGTH + wpaie->unicast_suite_count * sizeof(uint32_t))) { - uint16_t a; - uint32_t group_key_suite; - akm_suite_portion_t *akm_suites; - - record->security = (whd_security_t)WPA_SECURITY; - group_key_suite = ntoh32(wpaie->multicast_suite) & 0xFF; - if (group_key_suite == (uint32_t)WHD_CIPHER_TKIP) { - record->security |= TKIP_ENABLED; - } - if (group_key_suite == (uint32_t)WHD_CIPHER_CCMP_128) { - record->security |= AES_ENABLED; - } - - akm_suites = (akm_suite_portion_t *)&(wpaie->unicast_suite_list[wpaie->unicast_suite_count]); - for (a = 0; a < akm_suites->akm_suite_count; ++a) { - uint32_t akm_suite_list_item = ntoh32(akm_suites->akm_suite_list[a]) & 0xFF; - if (akm_suite_list_item == (uint32_t)WHD_AKM_8021X) { - record->security |= ENTERPRISE_ENABLED; - } - } - - for (a = 0; a < wpaie->unicast_suite_count; ++a) { - if (wpaie->unicast_suite_list[a][3] == (uint32_t)WHD_CIPHER_CCMP_128) { - record->security |= AES_ENABLED; - } - } - } - /* Check if AP is configured for WEP, that is, if the capabilities field indicates privacy, then security supports WEP */ - else if ((temp16 & DOT11_CAP_PRIVACY) != 0) { - record->security = WHD_SECURITY_WEP_PSK; - } - else { - /* Otherwise no security */ - record->security = WHD_SECURITY_OPEN; - } - - /* Update the maximum data rate with 11n rates from the HT Capabilities IE */ - ht_capabilities_ie = (ht_capabilities_ie_t *)whd_parse_tlvs(cp, len, DOT11_IE_ID_HT_CAPABILITIES); - if ((ht_capabilities_ie != NULL) && (ht_capabilities_ie->tlv_header.length == HT_CAPABILITIES_IE_LENGTH)) { - uint8_t a; - uint8_t supports_40mhz = - (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SUPPORTED_CHANNEL_WIDTH_SET) != 0 ? 1 : 0; - uint8_t short_gi[2] = { (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SHORT_GI_FOR_20MHZ) != 0 ? 1 : 0, - (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SHORT_GI_FOR_40MHZ) != 0 ? 1 : 0 }; - - /* Find highest bit from MCS info */ - for (a = 31; a != 0xFF; --a) { - if ((ht_capabilities_ie->rx_mcs[a / 8] & (1 << (a % 8))) != 0) { - break; - } - } - if (a != 0xFF) { - record->max_data_rate = - (uint32_t)(100UL * mcs_data_rate_lookup_table[a][supports_40mhz][short_gi[supports_40mhz]]); - } - } - - if (bss_info->flags & WL_BSS_FLAGS_FROM_BEACON) { - record->flags |= WHD_SCAN_RESULT_FLAG_BEACON; - } - - /* Get the channel for pre-N and control channel for n/HT or later */ - chanspec = dtoh16(WHD_READ_16(&bss_info->chanspec)); - if (bss_info->n_cap) { - /* Check control channel first.The channel that chanspec reports is the center frequency which might not be the same as - * the 20 MHz channel that the beacons is on (primary or control channel) if it's an 802.11n/AC 40MHz or wider channel. - */ - record->channel = bss_info->ctl_ch; - } - else { - /* 11 a/b/g and 20MHz bandwidth only */ - record->channel = ((uint8_t)(chanspec & WL_CHANSPEC_CHAN_MASK)); - } - - /* Find country info IE (Country-Information Information-Element) */ - country_info_ie = (country_info_ie_fixed_portion_t *)whd_parse_dot11_tlvs(cp, len, DOT11_IE_ID_COUNTRY); - if ((country_info_ie != NULL) && (country_info_ie->tlv_header.length >= COUNTRY_INFO_IE_MINIMUM_LENGTH)) { - record->ccode[0] = UNSIGNED_CHAR_TO_CHAR(country_info_ie->ccode[0]); - record->ccode[1] = UNSIGNED_CHAR_TO_CHAR(country_info_ie->ccode[1]); - } - record->band = - ((chanspec & - GET_C_VAR(whd_driver, - CHANSPEC_BAND_MASK)) == - GET_C_VAR(whd_driver, CHANSPEC_BAND_2G) ? - WHD_802_11_BAND_2_4GHZ : - WHD_802_11_BAND_5GHZ); - - whd_driver->internal_info.scan_result_callback(&whd_driver->internal_info.whd_scan_result_ptr, handler_user_data, - WHD_SCAN_INCOMPLETE); - - /* whd_driver->internal_info.scan_result_callback() can make whd_scan_result_ptr to NULL */ - if (whd_driver->internal_info.whd_scan_result_ptr == NULL) { - whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_ABORTED); - whd_driver->internal_info.scan_result_callback = NULL; - whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); - ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - } - - return handler_user_data; -} - -static void whd_scan_count_handler(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) -{ - uint32_t result; - whd_scan_userdata_t *scan_userdata = (whd_scan_userdata_t *)user_data; - - /* finished scan, either successfully or through an abort */ - if (status != WHD_SCAN_INCOMPLETE) { - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - result = cy_rtos_set_semaphore(&scan_userdata->scan_semaphore, WHD_FALSE); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Set semaphore failed in %s at %d \n", __func__, __LINE__)); - return; - } - - /* just count the available networks */ - scan_userdata->offset += 1; - - memset(*result_ptr, 0, sizeof(whd_scan_result_t)); - return; -} - -static void whd_scan_result_handler(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) -{ - uint32_t result; - whd_sync_scan_result_t *record; - whd_scan_userdata_t *scan_userdata = (whd_scan_userdata_t *)user_data; - whd_scan_result_t *current_result; - - /* Safe to access *scan_userdata. This static function registered only from whd_wifi_scan_synch and - * not exposed for general use. The user_data is valid when passed in from whd_wifi_scan_synch. - */ - - /* finished scan, either successfully or through an abort */ - if (status != WHD_SCAN_INCOMPLETE) { - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - result = cy_rtos_set_semaphore(&scan_userdata->scan_semaphore, WHD_FALSE); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - if (result != WHD_SUCCESS) - WPRINT_WHD_ERROR(("Set semaphore failed in %s at %d \n", __func__, __LINE__)); - return; - } - - /* can't really keep anymore scan results */ - if (scan_userdata->offset == scan_userdata->count) { - /*Offset and the count requested is reached. return with out saving the record details */ - memset(*result_ptr, 0, sizeof(whd_scan_result_t)); - return; - } - - /* Safe to access *result_ptr as result_ptr should only be NULL if the scan has completed or - * been aborted, which is handled above - */ - current_result = (whd_scan_result_t *)(*result_ptr); - - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - /* Safe to access *scan_userdata, as noted above */ - record = (whd_sync_scan_result_t *)(&scan_userdata->aps[scan_userdata->offset]); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - - /* Copy the SSID into the output record structure */ - record->SSID.length = current_result->SSID.length; - memset(record->SSID.value, 0, sizeof(record->SSID.value)); - memcpy(record->SSID.value, current_result->SSID.value, record->SSID.length); - - /* Copy the BSSID into the output record structure */ - memcpy((void *)record->BSSID.octet, (const void *)current_result->BSSID.octet, - sizeof(current_result->BSSID.octet)); - - record->security = current_result->security; - record->signal_strength = current_result->signal_strength; - record->channel = current_result->channel; - - scan_userdata->offset += 1; - memset(*result_ptr, 0, sizeof(whd_scan_result_t)); - return; -} - -uint32_t whd_wifi_scan_synch(whd_interface_t ifp, - whd_sync_scan_result_t *scan_result, - uint32_t *count) -{ - uint32_t result; - whd_scan_result_t *scan_result_ptr; - whd_scan_userdata_t scan_userdata; - scan_userdata.count = *count; - scan_userdata.aps = scan_result; - scan_userdata.offset = 0; - - if (!ifp || !scan_result) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - CHECK_RETURN(cy_rtos_init_semaphore(&scan_userdata.scan_semaphore, 1, 0)); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - - whd_scan_result_callback_t handler = (*count == 0) ? whd_scan_count_handler : whd_scan_result_handler; - - scan_result_ptr = (whd_scan_result_t *)malloc(sizeof(whd_scan_result_t)); - if (scan_result_ptr == NULL) { - goto error; - } - memset(scan_result_ptr, 0, sizeof(whd_scan_result_t)); - - if (whd_wifi_scan(ifp, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY, NULL, NULL, NULL, NULL, - handler, (whd_scan_result_t *)scan_result_ptr, &scan_userdata) != WHD_SUCCESS) { - WPRINT_WHD_INFO(("Failed scan \n")); - goto error; - } - - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - result = cy_rtos_get_semaphore(&scan_userdata.scan_semaphore, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - whd_assert("Get semaphore failed", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT)); - - DISABLE_COMPILER_WARNING(diag_suppress = Pa039) - result = cy_rtos_deinit_semaphore(&scan_userdata.scan_semaphore); - ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - if (WHD_SUCCESS != result) { - WPRINT_WHD_INFO(("Failed join (err %" PRIu32 ")\n", result)); - } - if (scan_result_ptr != NULL) { - free(scan_result_ptr); - scan_result_ptr = NULL; - } - *count = scan_userdata.offset; - - return WHD_SUCCESS; - -error: - if (scan_result_ptr != NULL) { - free(scan_result_ptr); - scan_result_ptr = NULL; - } - - return WHD_MALLOC_FAILURE; -} - -/* - * NOTE: search references of function wlu_get in wl/exe/wlu.c to find what format the returned IOCTL data is. - */ -uint32_t whd_wifi_scan(whd_interface_t ifp, - whd_scan_type_t scan_type, - whd_bss_type_t bss_type, - const whd_ssid_t *optional_ssid, - const whd_mac_t *optional_mac, - const uint16_t *optional_channel_list, - const whd_scan_extended_params_t *optional_extended_params, - whd_scan_result_callback_t callback, - whd_scan_result_t *result_ptr, - void *user_data) -{ - whd_buffer_t buffer; - wl_escan_params_t *scan_params; - uint16_t param_size = offsetof(wl_escan_params_t, params) + WL_SCAN_PARAMS_FIXED_SIZE; - uint16_t channel_list_size = 0; - whd_driver_t whd_driver = ifp->whd_driver; - uint16_t event_entry = 0xFF; - - whd_assert("Bad args", callback != NULL); - - if ((result_ptr == NULL) || (callback == NULL)) { - return WHD_BADARG; - } - - if (!((scan_type == WHD_SCAN_TYPE_ACTIVE) || (scan_type == WHD_SCAN_TYPE_PASSIVE) || - (scan_type == WHD_SCAN_TYPE_PROHIBITED_CHANNELS) || (scan_type == WHD_SCAN_TYPE_NO_BSSID_FILTER))) - return WHD_BADARG; - - if (!((bss_type == WHD_BSS_TYPE_INFRASTRUCTURE) || (bss_type == WHD_BSS_TYPE_ADHOC) || - (bss_type == WHD_BSS_TYPE_ANY))) - return WHD_BADARG; - - /* Determine size of channel_list, and add it to the parameter size so correct sized buffer can be allocated */ - if (optional_channel_list != NULL) { - /* Look for entry with channel number 0, which suggests the end of channel_list */ - for (channel_list_size = 0; optional_channel_list[channel_list_size] != 0; channel_list_size++) { - } - param_size = (uint16_t)(param_size + channel_list_size * sizeof(uint16_t)); - } - - if (ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) { - whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); - ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; - } - CHECK_RETURN(whd_management_set_event_handler(ifp, scan_events, whd_wifi_scan_events_handler, user_data, - &event_entry)); - if (event_entry >= WHD_MAX_EVENT_SUBSCRIPTION) { - WPRINT_WHD_ERROR(("scan_events registration failed in function %s and line %d", __func__, __LINE__)); - return WHD_UNFINISHED; - } - ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = event_entry; - /* Allocate a buffer for the IOCTL message */ - scan_params = (wl_escan_params_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, param_size, IOVAR_STR_ESCAN); - CHECK_IOCTL_BUFFER(scan_params); - - /* Clear the scan parameters structure */ - memset(scan_params, 0, param_size); - - /* Fill in the appropriate details of the scan parameters structure */ - scan_params->version = htod32(ESCAN_REQ_VERSION); - scan_params->action = htod16(WL_SCAN_ACTION_START); - scan_params->params.scan_type = (int8_t)scan_type; - scan_params->params.bss_type = (int8_t)bss_type; - - /* Fill out the SSID parameter if provided */ - if (optional_ssid != NULL) { - scan_params->params.ssid.SSID_len = htod32(optional_ssid->length); - memcpy(scan_params->params.ssid.SSID, optional_ssid->value, scan_params->params.ssid.SSID_len); - } - - /* Fill out the BSSID parameter if provided */ - if (optional_mac != NULL) { - memcpy(scan_params->params.bssid.octet, optional_mac, sizeof(whd_mac_t)); - } - else { - memset(scan_params->params.bssid.octet, 0xff, sizeof(whd_mac_t)); - } - - /* Fill out the extended parameters if provided */ - if (optional_extended_params != NULL) { - scan_params->params.nprobes = (int32_t)htod32(optional_extended_params->number_of_probes_per_channel); - scan_params->params.active_time = - (int32_t)htod32(optional_extended_params->scan_active_dwell_time_per_channel_ms); - scan_params->params.passive_time = (int32_t)htod32( - optional_extended_params->scan_passive_dwell_time_per_channel_ms); - scan_params->params.home_time = (int32_t)htod32( - optional_extended_params->scan_home_channel_dwell_time_between_channels_ms); - } - else { - scan_params->params.nprobes = (int32_t)htod32(-1); - scan_params->params.active_time = (int32_t)htod32(-1); - scan_params->params.passive_time = (int32_t)htod32(-1); - scan_params->params.home_time = (int32_t)htod32(-1); - } - - /* Copy the channel list parameter if provided */ - if ((channel_list_size > 0) && (optional_channel_list != NULL)) { - int i; - - for (i = 0; i < channel_list_size; i++) { - scan_params->params.channel_list[i] = htod16(CH20MHZ_CHSPEC(optional_channel_list[i])); - } - scan_params->params.channel_num = (int32_t)htod32(channel_list_size); - } - - whd_driver->internal_info.scan_result_callback = callback; - whd_driver->internal_info.whd_scan_result_ptr = result_ptr; - - /* Send the Incremental Scan IOVAR message - blocks until the response is received */ - - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0)); - - return WHD_SUCCESS; -} - -uint32_t whd_wifi_stop_scan(whd_interface_t ifp) -{ - whd_buffer_t buffer; - wl_escan_params_t *scan_params; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; - CHECK_DRIVER_NULL(whd_driver) - - /* Allocate a buffer for the IOCTL message */ - scan_params = (wl_escan_params_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_escan_params_t), - IOVAR_STR_ESCAN); - CHECK_IOCTL_BUFFER(scan_params); - /* Clear the scan parameters structure */ - memset(scan_params, 0, sizeof(wl_escan_params_t)); - - /* Fill in the appropriate details of the scan parameters structure */ - scan_params->version = htod32(ESCAN_REQ_VERSION); - scan_params->action = htod16(WL_SCAN_ACTION_ABORT); - - /* Send the Scan IOVAR message to abort scan*/ - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, 0)); - - return WHD_SUCCESS; -} - -uint32_t whd_wifi_deauth_sta(whd_interface_t ifp, whd_mac_t *mac, whd_dot11_reason_code_t reason) -{ - whd_result_t result; - scb_val_t *scb_val; - whd_buffer_t buffer1; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - if (mac == NULL) { - uint8_t *buffer = NULL; - whd_maclist_t *clients = NULL; - const whd_mac_t *current; - wl_bss_info_t ap_info; - whd_security_t sec; - uint32_t max_clients = 0; - size_t size = 0; - - result = whd_wifi_ap_get_max_assoc(ifp, &max_clients); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to get max number of associated clients\n")); - max_clients = 5; - } - - size = (sizeof(uint32_t) + (max_clients * sizeof(whd_mac_t))); - buffer = calloc(1, size); - - if (buffer == NULL) { - WPRINT_WHD_ERROR(("Unable to allocate memory for associated clients list, %s failed at line %d \n", - __func__, __LINE__)); - return WHD_MALLOC_FAILURE; - } - - clients = (whd_maclist_t *)buffer; - clients->count = max_clients; - memset(&ap_info, 0, sizeof(wl_bss_info_t)); - - result = whd_wifi_get_associated_client_list(ifp, clients, (uint16_t)size); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to get client list, %s failed at line %d \n", __func__, __LINE__)); - free(buffer); - return result; - } - - current = &clients->mac_list[0]; - result = whd_wifi_get_ap_info(ifp, &ap_info, &sec); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Function %s failed at line %d \n", __func__, __LINE__)); - free(buffer); - return result; - } - - - while ((clients->count > 0) && (!(NULL_MAC(current->octet)))) { - if (memcmp(current->octet, &(ap_info.BSSID), sizeof(whd_mac_t)) != 0) { - WPRINT_WHD_INFO(("Deauthenticating STA MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", current->octet[0], - current->octet[1], current->octet[2], current->octet[3], current->octet[4], - current->octet[5])); - - scb_val = (scb_val_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer1, sizeof(scb_val_t)); - if (scb_val == NULL) { - WPRINT_WHD_ERROR(("Buffer alloc failed in function %s at line %d \n", __func__, __LINE__)); - free(buffer); - return WHD_BUFFER_ALLOC_FAIL; - } - memset((char *)scb_val, 0, sizeof(scb_val_t)); - memcpy((char *)&scb_val->ea, (char *)current, sizeof(whd_mac_t)); - scb_val->val = (uint32_t)reason; - result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SCB_DEAUTHENTICATE_FOR_REASON, buffer1, 0); - - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to deauth client\n")); - } - } - - --clients->count; - ++current; - } - - free(buffer); - - return WHD_SUCCESS; - } - - scb_val = (scb_val_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer1, sizeof(scb_val_t)); - CHECK_IOCTL_BUFFER(scb_val); - memset((char *)scb_val, 0, sizeof(scb_val_t)); - memcpy((char *)&scb_val->ea, (char *)mac, sizeof(whd_mac_t)); - scb_val->val = (uint32_t)reason; - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SCB_DEAUTHENTICATE_FOR_REASON, buffer1, 0)); - - return WHD_SUCCESS; -} - -uint32_t whd_wifi_get_mac_address(whd_interface_t ifp, whd_mac_t *mac) -{ - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - if (mac == NULL) - return WHD_BADARG; - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - CHECK_IOCTL_BUFFER(whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR)); - - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - - memcpy(mac, whd_buffer_get_current_piece_data_pointer(whd_driver, response), sizeof(whd_mac_t)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - - return WHD_SUCCESS; -} - -uint32_t whd_wifi_get_bssid(whd_interface_t ifp, whd_mac_t *bssid) -{ - whd_buffer_t buffer; - whd_buffer_t response; - whd_result_t result; - whd_driver_t whd_driver; - uint8_t *data = NULL; - CHECK_IFP_NULL(ifp); + for (rate_num = 0; rate_num < count_tmp; rate_num++) + { + uint32_t rate = RSPEC_TO_KBPS(bss_info->rateset.rates[rate_num]); + if (record->max_data_rate < rate) + { + record->max_data_rate = rate; + } + } - if (bssid == NULL) - return WHD_BADARG; + bss_info->capability = dtoh16(bss_info->capability); - whd_driver = ifp->whd_driver; + /* Write the BSS type into the output record structure */ + record->bss_type = + ( (bss_info->capability & DOT11_CAP_ESS) != + 0 ) ? WHD_BSS_TYPE_INFRASTRUCTURE : ( (bss_info->capability & DOT11_CAP_IBSS) != + 0 ) ? WHD_BSS_TYPE_ADHOC : WHD_BSS_TYPE_UNKNOWN; - CHECK_DRIVER_NULL(whd_driver); + /* Determine the network security. + * Some of this section has been copied from the standard broadcom host driver file wl/exe/wlu.c function wl_dump_wpa_rsn_ies + */ - if ((ifp->role == WHD_STA_ROLE) || (ifp->role == WHD_AP_ROLE)) { - memset(bssid, 0, sizeof(whd_mac_t)); - CHECK_IOCTL_BUFFER(whd_cdc_get_ioctl_buffer(whd_driver, &buffer, sizeof(whd_mac_t))); - if ((result = - whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_BSSID, buffer, &response)) == WHD_SUCCESS) { - data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(bssid->octet, data, sizeof(whd_mac_t)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } - return result; - } - else if (ifp->role == WHD_INVALID_ROLE) { - WPRINT_WHD_ERROR(("STA not associated with AP\n")); - return WHD_WLAN_NOTASSOCIATED; - } - else { - return WHD_UNSUPPORTED; - } + ie_offset = WHD_READ_16(&bss_info->ie_offset); + cp = (whd_tlv8_header_t *)( ( (uint8_t *)bss_info ) + ie_offset ); + len = WHD_READ_32(&bss_info->ie_length); + bss_info_length = WHD_READ_32(&bss_info->length); + + record->ie_ptr = (uint8_t *)cp; + record->ie_len = len; + + /* Validate the length of the IE section */ + if ( (ie_offset > bss_info_length) || (len > bss_info_length - ie_offset) ) + { + whd_minor_assert("Invalid ie length", 1 == 0); + return handler_user_data; + } + + /* Find an RSN IE (Robust-Security-Network Information-Element) */ + rsnie = (rsn_ie_fixed_portion_t *)whd_parse_dot11_tlvs(cp, len, DOT11_IE_ID_RSN); + + /* Find a WPA IE */ + if (rsnie == NULL) + { + whd_tlv8_header_t *parse = cp; + uint32_t parse_len = len; + while ( (wpaie = + (wpa_ie_fixed_portion_t *)whd_parse_tlvs(parse, parse_len, DOT11_IE_ID_VENDOR_SPECIFIC) ) != 0 ) + { + if (whd_is_wpa_ie( (vendor_specific_ie_header_t *)wpaie, &parse, &parse_len ) != WHD_FALSE) + { + break; + } + } + } + + temp16 = WHD_READ_16(&bss_info->capability); + + /* Check if AP is configured for RSN */ + if ( (rsnie != NULL) && + (rsnie->tlv_header.length >= RSN_IE_MINIMUM_LENGTH + rsnie->pairwise_suite_count * sizeof(uint32_t) ) ) + { + uint16_t a; + uint32_t group_key_suite; + akm_suite_portion_t *akm_suites; + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + akm_suites = (akm_suite_portion_t *)&(rsnie->pairwise_suite_list[rsnie->pairwise_suite_count]); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + for (a = 0; a < akm_suites->akm_suite_count; ++a) + { + uint32_t akm_suite_list_item = ntoh32(akm_suites->akm_suite_list[a]) & 0xFF; + if (akm_suite_list_item == (uint32_t)WHD_AKM_PSK) + { + record->security |= WPA2_SECURITY; + } + if (akm_suite_list_item == (uint32_t)WHD_AKM_PSK_SHA256) + { + record->security |= WPA2_SECURITY; + record->security |= SHA256_1X; + } + if (akm_suite_list_item == (uint32_t)WHD_AKM_SAE_SHA256) + { + record->security |= WPA3_SECURITY; + } + if (akm_suite_list_item == (uint32_t)WHD_AKM_8021X) + { + record->security |= WPA2_SECURITY; + record->security |= ENTERPRISE_ENABLED; + } + if (akm_suite_list_item == (uint32_t)WHD_AKM_FT_8021X) + { + record->security |= WPA2_SECURITY; + record->security |= FBT_ENABLED; + record->security |= ENTERPRISE_ENABLED; + } + if (akm_suite_list_item == (uint32_t)WHD_AKM_FT_PSK) + { + record->security |= WPA2_SECURITY; + record->security |= FBT_ENABLED; + } + } + + group_key_suite = ntoh32(rsnie->group_key_suite) & 0xFF; + /* Check the RSN contents to see if there are any references to TKIP cipher (2) in the group key or pairwise keys, */ + /* If so it must be mixed mode. */ + if (group_key_suite == (uint32_t)WHD_CIPHER_TKIP) + { + record->security |= TKIP_ENABLED; + } + if (group_key_suite == (uint32_t)WHD_CIPHER_CCMP_128) + { + record->security |= AES_ENABLED; + } + + for (a = 0; a < rsnie->pairwise_suite_count; ++a) + { + uint32_t pairwise_suite_list_item = ntoh32(rsnie->pairwise_suite_list[a]) & 0xFF; + if (pairwise_suite_list_item == (uint32_t)WHD_CIPHER_TKIP) + { + record->security |= TKIP_ENABLED; + } + + if (pairwise_suite_list_item == (uint32_t)WHD_CIPHER_CCMP_128) + { + record->security |= AES_ENABLED; + } + } + } + /* Check if AP is configured for WPA */ + else if ( (wpaie != NULL) && + (wpaie->vendor_specific_header.tlv_header.length >= + WPA_IE_MINIMUM_LENGTH + wpaie->unicast_suite_count * sizeof(uint32_t) ) ) + { + uint16_t a; + uint32_t group_key_suite; + akm_suite_portion_t *akm_suites; + + record->security = (whd_security_t)WPA_SECURITY; + group_key_suite = ntoh32(wpaie->multicast_suite) & 0xFF; + if (group_key_suite == (uint32_t)WHD_CIPHER_TKIP) + { + record->security |= TKIP_ENABLED; + } + if (group_key_suite == (uint32_t)WHD_CIPHER_CCMP_128) + { + record->security |= AES_ENABLED; + } + + akm_suites = (akm_suite_portion_t *)&(wpaie->unicast_suite_list[wpaie->unicast_suite_count]); + for (a = 0; a < akm_suites->akm_suite_count; ++a) + { + uint32_t akm_suite_list_item = ntoh32(akm_suites->akm_suite_list[a]) & 0xFF; + if (akm_suite_list_item == (uint32_t)WHD_AKM_8021X) + { + record->security |= ENTERPRISE_ENABLED; + } + } + + for (a = 0; a < wpaie->unicast_suite_count; ++a) + { + if (wpaie->unicast_suite_list[a][3] == (uint32_t)WHD_CIPHER_CCMP_128) + { + record->security |= AES_ENABLED; + } + } + } + /* Check if AP is configured for WEP, that is, if the capabilities field indicates privacy, then security supports WEP */ + else if ( (temp16 & DOT11_CAP_PRIVACY) != 0 ) + { + record->security = WHD_SECURITY_WEP_PSK; + } + else + { + /* Otherwise no security */ + record->security = WHD_SECURITY_OPEN; + } + + /* Find a RSNX IE */ + rsnxie = (rsnx_ie_t *)whd_parse_tlvs(cp, len, DOT11_IE_ID_RSNX); + if ( (rsnxie != NULL) && (rsnxie->tlv_header.length == DOT11_RSNX_CAP_LEN) && + (rsnxie->data[0] & (1 << DOT11_RSNX_SAE_H2E) ) ) + { + record->flags |= WHD_SCAN_RESULT_FLAG_SAE_H2E; + } + + /* Update the maximum data rate with 11n rates from the HT Capabilities IE */ + ht_capabilities_ie = (ht_capabilities_ie_t *)whd_parse_tlvs(cp, len, DOT11_IE_ID_HT_CAPABILITIES); + if ( (ht_capabilities_ie != NULL) && (ht_capabilities_ie->tlv_header.length == HT_CAPABILITIES_IE_LENGTH) ) + { + uint8_t a; + uint8_t supports_40mhz = + (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SUPPORTED_CHANNEL_WIDTH_SET) != 0 ? 1 : 0; + uint8_t short_gi[2] = + { (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SHORT_GI_FOR_20MHZ) != 0 ? 1 : 0, + (ht_capabilities_ie->ht_capabilities_info & HT_CAPABILITIES_INFO_SHORT_GI_FOR_40MHZ) != 0 ? 1 : 0 }; + + /* Find highest bit from MCS info */ + for (a = 31; a != 0xFF; --a) + { + if ( (ht_capabilities_ie->rx_mcs[a / 8] & (1 << (a % 8) ) ) != 0 ) + { + break; + } + } + if (a != 0xFF) + { + record->max_data_rate = + ( uint32_t )(100UL * mcs_data_rate_lookup_table[a][supports_40mhz][short_gi[supports_40mhz]]); + } + } + + if (bss_info->flags & WL_BSS_FLAGS_FROM_BEACON) + { + record->flags |= WHD_SCAN_RESULT_FLAG_BEACON; + } + + /* Get the channel for pre-N and control channel for n/HT or later */ + chanspec = dtoh16(WHD_READ_16(&bss_info->chanspec) ); + if (CHSPEC_IS6G(chanspec) ) + { + uint16_t ctrl_ch_num; + + whd_chip_get_chanspec_ctl_channel_num(whd_driver, chanspec, &ctrl_ch_num); + record->channel = ctrl_ch_num; + } + else if (bss_info->n_cap) + { + /* Check control channel first.The channel that chanspec reports is the center frequency which might not be the same as + * the 20 MHz channel that the beacons is on (primary or control channel) if it's an 802.11n/AC 40MHz or wider channel. + */ + record->channel = bss_info->ctl_ch; + } + else + { + /* 11 a/b/g and 20MHz bandwidth only */ + record->channel = ( ( uint8_t )(chanspec & WL_CHANSPEC_CHAN_MASK) ); + } + + /* Find country info IE (Country-Information Information-Element) */ + country_info_ie = (country_info_ie_fixed_portion_t *)whd_parse_dot11_tlvs(cp, len, DOT11_IE_ID_COUNTRY); + if ( (country_info_ie != NULL) && (country_info_ie->tlv_header.length >= COUNTRY_INFO_IE_MINIMUM_LENGTH) ) + { + record->ccode[0] = UNSIGNED_CHAR_TO_CHAR(country_info_ie->ccode[0]); + record->ccode[1] = UNSIGNED_CHAR_TO_CHAR(country_info_ie->ccode[1]); + } + record->band = (CHSPEC_IS2G(chanspec) ? WHD_802_11_BAND_2_4GHZ : + (CHSPEC_IS5G(chanspec) ? WHD_802_11_BAND_5GHZ : WHD_802_11_BAND_6GHZ) ); + + whd_driver->internal_info.scan_result_callback(&whd_driver->internal_info.whd_scan_result_ptr, handler_user_data, + WHD_SCAN_INCOMPLETE); + + /* whd_driver->internal_info.scan_result_callback() can make whd_scan_result_ptr to NULL */ + if (whd_driver->internal_info.whd_scan_result_ptr == NULL) + { + whd_driver->internal_info.scan_result_callback(NULL, handler_user_data, WHD_SCAN_ABORTED); + whd_driver->internal_info.scan_result_callback = NULL; + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); + ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + + return handler_user_data; } -uint32_t whd_wifi_ap_get_max_assoc(whd_interface_t ifp, uint32_t *max_assoc) +/** Handles auth result events + * + * This function receives scan record events, and parses them into a better format, then passes the results + * to the user application. + * + * @param event_header : The event details + * @param event_data : The data for the event which contains the auth result structure + * @param handler_user_data: data which will be passed to user application + * + * @returns : handler_user_data parameter + * + */ +static void *whd_wifi_auth_events_handler(whd_interface_t ifp, const whd_event_header_t *event_header, + const uint8_t *event_data, + void *handler_user_data) { - if (!ifp || !max_assoc) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - - return whd_wifi_get_iovar_value(ifp, IOVAR_STR_MAX_ASSOC, max_assoc); + whd_driver_t whd_driver = ifp->whd_driver; + whd_scan_result_t *record; + + if (whd_driver->internal_info.auth_result_callback == NULL) + { + WPRINT_WHD_ERROR( ("No set callback function in %s at %d \n", __func__, __LINE__) ); + return handler_user_data; + } + if (event_header->event_type == WLC_E_EXT_AUTH_REQ) + { + uint8_t flag = 0; + if (whd_driver->internal_info.whd_scan_result_ptr) + { + record = (whd_scan_result_t *)(whd_driver->internal_info.whd_scan_result_ptr); + if (record->flags & WHD_SCAN_RESULT_FLAG_SAE_H2E) + flag = 1; + else + flag = 0; + + } + whd_driver->internal_info.auth_result_callback( (void *)event_data, sizeof(whd_auth_req_status_t), + WHD_AUTH_EXT_REQ, &flag, handler_user_data ); + return handler_user_data; + } + else if (event_header->event_type == WLC_E_EXT_AUTH_FRAME_RX) + { + uint32_t mgmt_frame_len; + wl_rx_mgmt_data_t *rxframe; + uint8_t *frame; + + mgmt_frame_len = event_header->datalen - sizeof(wl_rx_mgmt_data_t); + rxframe = (wl_rx_mgmt_data_t *)event_data; + frame = (uint8_t *)(rxframe + 1); + whd_driver->internal_info.auth_result_callback( (void *)frame, mgmt_frame_len, WHD_AUTH_EXT_FRAME_RX, NULL, + handler_user_data ); + return handler_user_data; + + } + + return handler_user_data; } -uint32_t whd_wifi_get_associated_client_list(whd_interface_t ifp, void *client_list_buffer, uint16_t buffer_length) +static void whd_scan_count_handler(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_result_t result; - whd_maclist_t *data = NULL; - uint8_t *pdata = NULL; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - /* Check if soft AP interface is up, if not, return a count of 0 as a result */ - result = whd_wifi_is_ready_to_transceive(ifp); - if ((result == WHD_SUCCESS) && (ifp->role == WHD_AP_ROLE)) { - data = (whd_maclist_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, buffer_length); - CHECK_IOCTL_BUFFER(data); - memset(data, 0, buffer_length); - data->count = htod32(((whd_maclist_t *)client_list_buffer)->count); - - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_ASSOCLIST, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(client_list_buffer, (void *)pdata, - (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), buffer_length)); - - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } - else if (result == WHD_INTERFACE_NOT_UP) { - /* not up, so can't have associated clients */ - ((whd_maclist_t *)client_list_buffer)->count = 0; - } - else { - WPRINT_WHD_ERROR(("Invalid Interface\n")); - return WHD_INVALID_INTERFACE; - } - return result; + uint32_t result; + whd_scan_userdata_t *scan_userdata = (whd_scan_userdata_t *)user_data; + + /* finished scan, either successfully or through an abort */ + if (status != WHD_SCAN_INCOMPLETE) + { + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + result = cy_rtos_set_semaphore(&scan_userdata->scan_semaphore, WHD_FALSE); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Set semaphore failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* just count the available networks */ + scan_userdata->offset += 1; + + memset(*result_ptr, 0, sizeof(whd_scan_result_t) ); + return; } -uint32_t whd_wifi_get_ap_info(whd_interface_t ifp, wl_bss_info_t *ap_info, whd_security_t *security) +static void whd_scan_result_handler(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status) { - whd_buffer_t buffer; - whd_buffer_t response; - uint32_t *data; - uint8_t *pdata = NULL; - uint32_t security_value; /* hold misc security values */ - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + uint32_t result; + whd_sync_scan_result_t *record; + whd_scan_userdata_t *scan_userdata = (whd_scan_userdata_t *)user_data; + whd_scan_result_t *current_result; - if ((ap_info == NULL) || (security == NULL)) - return WHD_BADARG; - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - /* Read the BSS info */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, WLC_IOCTL_SMLEN); - CHECK_IOCTL_BUFFER(data); - *data = WLC_IOCTL_SMLEN; - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_BSS_INFO, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(ap_info, (void *)(pdata + 4), sizeof(wl_bss_info_t)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - - /* Read the WSEC setting */ - CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_WSEC, &security_value)); - security_value = security_value & SECURITY_MASK; - *security = (whd_security_t)(security_value); - - if (*security == WHD_SECURITY_WEP_PSK) { - /* Read the WEP auth setting */ - CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_AUTH, &security_value)); - - if (security_value == SHARED_AUTH) { - *security |= SHARED_ENABLED; - } - } - else if ((*security & (TKIP_ENABLED | AES_ENABLED)) != 0) { - /* Read the WPA auth setting */ - CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_WPA_AUTH, &security_value)); - - if (security_value == WPA2_AUTH_PSK) { - *security |= WPA2_SECURITY; - } - else if (security_value == WPA_AUTH_PSK) { - *security |= WPA_SECURITY; - } - } - else if (*security != WHD_SECURITY_OPEN) { - *security = WHD_SECURITY_UNKNOWN; - WPRINT_WHD_ERROR(("Unknown security type, %s failed at line %d \n", __func__, __LINE__)); - return WHD_UNKNOWN_SECURITY_TYPE; - } + /* Safe to access *scan_userdata. This static function registered only from whd_wifi_scan_synch and + * not exposed for general use. The user_data is valid when passed in from whd_wifi_scan_synch. + */ - return WHD_SUCCESS; -} + /* finished scan, either successfully or through an abort */ + if (status != WHD_SCAN_INCOMPLETE) + { + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + result = cy_rtos_set_semaphore(&scan_userdata->scan_semaphore, WHD_FALSE); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + if (result != WHD_SUCCESS) + WPRINT_WHD_ERROR( ("Set semaphore failed in %s at %d \n", __func__, __LINE__) ); + return; + } + + /* can't really keep anymore scan results */ + if (scan_userdata->offset == scan_userdata->count) + { + /*Offset and the count requested is reached. return with out saving the record details */ + memset(*result_ptr, 0, sizeof(whd_scan_result_t) ); + return; + } + + /* Safe to access *result_ptr as result_ptr should only be NULL if the scan has completed or + * been aborted, which is handled above + */ + current_result = (whd_scan_result_t *)(*result_ptr); -uint32_t whd_wifi_enable_powersave(whd_interface_t ifp) -{ - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + /* Safe to access *scan_userdata, as noted above */ + record = (whd_sync_scan_result_t *)(&scan_userdata->aps[scan_userdata->offset]); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) - whd_driver = ifp->whd_driver; + /* Copy the SSID into the output record structure */ + record->SSID.length = current_result->SSID.length; + memset(record->SSID.value, 0, sizeof(record->SSID.value) ); + memcpy(record->SSID.value, current_result->SSID.value, record->SSID.length); - CHECK_DRIVER_NULL(whd_driver); + /* Copy the BSSID into the output record structure */ + memcpy( (void *)record->BSSID.octet, (const void *)current_result->BSSID.octet, + sizeof(current_result->BSSID.octet) ); - /* Set legacy powersave mode - PM1 */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER(data); - *data = htod32((uint32_t)PM1_POWERSAVE_MODE); + record->security = current_result->security; + record->signal_strength = current_result->signal_strength; + record->channel = current_result->channel; - RETURN_WITH_ASSERT(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_PM, buffer, NULL)); + scan_userdata->offset += 1; + memset(*result_ptr, 0, sizeof(whd_scan_result_t) ); + return; } -uint32_t whd_wifi_get_powersave_mode(whd_interface_t ifp, uint32_t *value) +whd_result_t whd_wifi_scan_synch(whd_interface_t ifp, + whd_sync_scan_result_t *scan_result, + uint32_t *count + ) { - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); + uint32_t result; + whd_scan_result_t *scan_result_ptr; + whd_scan_userdata_t scan_userdata; + scan_userdata.count = *count; + scan_userdata.aps = scan_result; + scan_userdata.offset = 0; + + if (!ifp || !scan_result) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + CHECK_RETURN(cy_rtos_init_semaphore(&scan_userdata.scan_semaphore, 1, 0) ); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + + whd_scan_result_callback_t handler = (*count == 0) + ? whd_scan_count_handler : whd_scan_result_handler; + + scan_result_ptr = (whd_scan_result_t *)whd_mem_malloc(sizeof(whd_scan_result_t) ); + if (scan_result_ptr == NULL) + { + goto error; + } + memset(scan_result_ptr, 0, sizeof(whd_scan_result_t) ); + + if (whd_wifi_scan(ifp, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY, NULL, NULL, NULL, NULL, + handler, (whd_scan_result_t *)scan_result_ptr, &scan_userdata) != WHD_SUCCESS) + { + WPRINT_WHD_INFO( ("Failed scan \n") ); + goto error; + } + + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + result = cy_rtos_get_semaphore(&scan_userdata.scan_semaphore, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + whd_assert("Get semaphore failed", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT) ); + + DISABLE_COMPILER_WARNING(diag_suppress = Pa039) + result = cy_rtos_deinit_semaphore(&scan_userdata.scan_semaphore); + ENABLE_COMPILER_WARNING(diag_suppress = Pa039) + if (WHD_SUCCESS != result) + { + WPRINT_WHD_INFO( ("Failed join (err %" PRIu32 ")\n", result) ); + } + if (scan_result_ptr != NULL) + { + whd_mem_free(scan_result_ptr); + scan_result_ptr = NULL; + } + *count = scan_userdata.offset; + + return WHD_SUCCESS; - if (value == NULL) - return WHD_BADARG; - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); +error: + if (scan_result_ptr != NULL) + { + whd_mem_free(scan_result_ptr); + scan_result_ptr = NULL; + } - return whd_wifi_get_ioctl_value(ifp, WLC_GET_PM, value); + return WHD_MALLOC_FAILURE; } -uint32_t whd_wifi_enable_powersave_with_throughput(whd_interface_t ifp, uint16_t return_to_sleep_delay_ms) +/* + * NOTE: search references of function wlu_get in wl/exe/wlu.c to find what format the returned IOCTL data is. + */ +whd_result_t whd_wifi_scan(whd_interface_t ifp, + whd_scan_type_t scan_type, + whd_bss_type_t bss_type, + const whd_ssid_t *optional_ssid, + const whd_mac_t *optional_mac, + const uint16_t *optional_channel_list, + const whd_scan_extended_params_t *optional_extended_params, + whd_scan_result_callback_t callback, + whd_scan_result_t *result_ptr, + void *user_data + ) { - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver; - uint16_t chip_id; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; + whd_buffer_t buffer; + wl_escan_params_t *scan_params; + uint16_t param_size = offsetof(wl_escan_params_t, params) + WL_SCAN_PARAMS_FIXED_SIZE; + uint16_t channel_list_size = 0; + whd_driver_t whd_driver = ifp->whd_driver; + uint16_t event_entry = 0xFF; + + whd_assert("Bad args", callback != NULL); + + if ( (result_ptr == NULL) || (callback == NULL) ) + { + return WHD_BADARG; + } + + if (!( (scan_type == WHD_SCAN_TYPE_ACTIVE) || (scan_type == WHD_SCAN_TYPE_PASSIVE) || + (scan_type == WHD_SCAN_TYPE_PROHIBITED_CHANNELS) || (scan_type == WHD_SCAN_TYPE_NO_BSSID_FILTER) ) ) + return WHD_BADARG; + + if (!( (bss_type == WHD_BSS_TYPE_INFRASTRUCTURE) || (bss_type == WHD_BSS_TYPE_ADHOC) || + (bss_type == WHD_BSS_TYPE_ANY) ) ) + return WHD_BADARG; + + /* Determine size of channel_list, and add it to the parameter size so correct sized buffer can be allocated */ + if (optional_channel_list != NULL) + { + /* Look for entry with channel number 0, which suggests the end of channel_list */ + for (channel_list_size = 0; optional_channel_list[channel_list_size] != 0; channel_list_size++) + { + } + param_size = ( uint16_t )(param_size + channel_list_size * sizeof(uint16_t) ); + } + + if (ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) + { + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY]); + ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + CHECK_RETURN(whd_management_set_event_handler(ifp, scan_events, whd_wifi_scan_events_handler, user_data, + &event_entry) ); + if (event_entry >= WHD_MAX_EVENT_SUBSCRIPTION) + { + WPRINT_WHD_ERROR( ("scan_events registration failed in function %s and line %d", __func__, __LINE__) ); + return WHD_UNFINISHED; + } + ifp->event_reg_list[WHD_SCAN_EVENT_ENTRY] = event_entry; + /* Allocate a buffer for the IOCTL message */ + scan_params = (wl_escan_params_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, param_size, IOVAR_STR_ESCAN); + CHECK_IOCTL_BUFFER(scan_params); + + /* Clear the scan parameters structure */ + memset(scan_params, 0, param_size); + + /* Fill in the appropriate details of the scan parameters structure */ + scan_params->version = htod32(ESCAN_REQ_VERSION); + scan_params->action = htod16(WL_SCAN_ACTION_START); + scan_params->params.scan_type = (int8_t)scan_type; + scan_params->params.bss_type = (int8_t)bss_type; + + /* Fill out the SSID parameter if provided */ + if (optional_ssid != NULL) + { + scan_params->params.ssid.SSID_len = htod32(optional_ssid->length); + memcpy(scan_params->params.ssid.SSID, optional_ssid->value, scan_params->params.ssid.SSID_len); + } + + /* Fill out the BSSID parameter if provided */ + if (optional_mac != NULL) + { + memcpy(scan_params->params.bssid.octet, optional_mac, sizeof(whd_mac_t) ); + } + else + { + memset(scan_params->params.bssid.octet, 0xff, sizeof(whd_mac_t) ); + } + + /* Fill out the extended parameters if provided */ + if (optional_extended_params != NULL) + { + scan_params->params.nprobes = (int32_t)htod32(optional_extended_params->number_of_probes_per_channel); + scan_params->params.active_time = + (int32_t)htod32(optional_extended_params->scan_active_dwell_time_per_channel_ms); + scan_params->params.passive_time = (int32_t)htod32( + optional_extended_params->scan_passive_dwell_time_per_channel_ms); + scan_params->params.home_time = (int32_t)htod32( + optional_extended_params->scan_home_channel_dwell_time_between_channels_ms); + } + else + { +#ifndef PROTO_MSGBUF + scan_params->params.nprobes = (int32_t)htod32(-1); + scan_params->params.active_time = (int32_t)htod32(-1); + scan_params->params.passive_time = (int32_t)htod32(-1); + scan_params->params.home_time = (int32_t)htod32(-1); +#else + memset(&(scan_params->params.nprobes), -1, 16); +#endif + } - CHECK_DRIVER_NULL(whd_driver); + /* Copy the channel list parameter if provided */ + if ( (channel_list_size > 0) && (optional_channel_list != NULL) ) + { + int i; - if (return_to_sleep_delay_ms < PM2_SLEEP_RET_TIME_MIN) { - WPRINT_WHD_ERROR(("Delay too short, %s failed at line %d \n", __func__, __LINE__)); - return WHD_DELAY_TOO_SHORT; - } - else if (return_to_sleep_delay_ms > PM2_SLEEP_RET_TIME_MAX) { - WPRINT_WHD_ERROR(("Delay too long, %s failed at line %d \n", __func__, __LINE__)); - return WHD_DELAY_TOO_LONG; - } + for (i = 0; i < channel_list_size; i++) + { + scan_params->params.channel_list[i] = htod16(CH20MHZ_CHSPEC(optional_channel_list[i]) ); + } + scan_params->params.channel_num = (int32_t)htod32(channel_list_size); + } - /* Set the maximum time to wait before going back to sleep */ - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PM2_SLEEP_RET, - (uint32_t)(return_to_sleep_delay_ms / 10) * 10)); - chip_id = whd_chip_get_chip_id(whd_driver); + whd_driver->internal_info.scan_result_callback = callback; + whd_driver->internal_info.whd_scan_result_ptr = result_ptr; - if (chip_id == 43362) { - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PM_LIMIT, NULL_FRAMES_WITH_PM_SET_LIMIT)); - } + /* Send the Incremental Scan IOVAR message - blocks until the response is received */ - /* set PM2 fast return to sleep powersave mode */ - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - CHECK_IOCTL_BUFFER(data); - *data = htod32((uint32_t)PM2_POWERSAVE_MODE); + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); - RETURN_WITH_ASSERT(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_PM, buffer, NULL)); + return WHD_SUCCESS; } -uint32_t whd_wifi_disable_powersave(whd_interface_t ifp) +whd_result_t whd_wifi_stop_scan(whd_interface_t ifp) { - whd_buffer_t buffer; - whd_driver_t whd_driver; + whd_buffer_t buffer; + wl_escan_params_t *scan_params; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver) - whd_driver = ifp->whd_driver; + /* Allocate a buffer for the IOCTL message */ + scan_params = (wl_escan_params_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_escan_params_t), + IOVAR_STR_ESCAN); + CHECK_IOCTL_BUFFER(scan_params); + /* Clear the scan parameters structure */ + memset(scan_params, 0, sizeof(wl_escan_params_t) ); - CHECK_DRIVER_NULL(whd_driver); + /* Fill in the appropriate details of the scan parameters structure */ + scan_params->version = htod32(ESCAN_REQ_VERSION); + scan_params->action = htod16(WL_SCAN_ACTION_ABORT); - uint32_t *data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + /* Send the Scan IOVAR message to abort scan*/ + CHECK_RETURN(whd_proto_set_iovar(ifp, buffer, 0) ); - CHECK_IOCTL_BUFFER(data); - *data = htod32((uint32_t)NO_POWERSAVE_MODE); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_PM, buffer, NULL)); - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_register_multicast_address(whd_interface_t ifp, const whd_mac_t *mac) +whd_result_t whd_wifi_external_auth_request(whd_interface_t ifp, + whd_auth_result_callback_t callback, + void *result_ptr, + void *user_data + ) { - whd_buffer_t buffer; - whd_buffer_t response; - uint16_t a; - mcast_list_t *orig_mcast_list; - mcast_list_t *new_mcast_list; - whd_driver_t whd_driver; - - if (!ifp || !mac || !ETHER_ISMULTI(mac)) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); - - /* Get the current multicast list */ - CHECK_IOCTL_BUFFER(whd_cdc_get_iovar_buffer(whd_driver, &buffer, - sizeof(uint32_t) + MAX_SUPPORTED_MCAST_ENTRIES * sizeof(whd_mac_t), IOVAR_STR_MCAST_LIST)); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - - /* Verify address is not currently registered */ - orig_mcast_list = (mcast_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(orig_mcast_list, WHD_NO_REGISTER_FUNCTION_POINTER); - orig_mcast_list->entry_count = dtoh32(orig_mcast_list->entry_count); - for (a = 0; a < orig_mcast_list->entry_count; ++a) { - /* Check if any address matches */ - if (0 == memcmp(mac, &orig_mcast_list->macs[a], sizeof(whd_mac_t))) { - /* A matching address has been found so we can stop now. */ - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - return WHD_SUCCESS; - } - } + CHECK_IFP_NULL(ifp); + whd_driver_t whd_driver = ifp->whd_driver; + uint16_t event_entry = 0xFF; + + whd_assert("Bad args", callback != NULL); + + if (ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) + { + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY]); + ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + CHECK_RETURN(whd_management_set_event_handler(ifp, auth_events, whd_wifi_auth_events_handler, user_data, + &event_entry) ); + if (event_entry >= WHD_MAX_EVENT_SUBSCRIPTION) + { + WPRINT_WHD_ERROR( ("auth_events registration failed in function %s and line %d", __func__, __LINE__) ); + return WHD_UNFINISHED; + } + ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY] = event_entry; + + + whd_driver->internal_info.auth_result_callback = callback; + + return WHD_SUCCESS; +} - /* Add the provided address to the list and write the new multicast list */ - new_mcast_list = (mcast_list_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, - (uint16_t)(sizeof(uint32_t) + - (orig_mcast_list->entry_count + 1) * - sizeof(whd_mac_t)), - IOVAR_STR_MCAST_LIST); - CHECK_IOCTL_BUFFER(new_mcast_list); - new_mcast_list->entry_count = orig_mcast_list->entry_count; - memcpy(new_mcast_list->macs, orig_mcast_list->macs, orig_mcast_list->entry_count * sizeof(whd_mac_t)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - memcpy(&new_mcast_list->macs[new_mcast_list->entry_count], mac, sizeof(whd_mac_t)); - ++new_mcast_list->entry_count; - new_mcast_list->entry_count = htod32(new_mcast_list->entry_count); - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); +whd_result_t whd_wifi_stop_external_auth_request(whd_interface_t ifp) +{ + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver) + + if (ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY] != WHD_EVENT_NOT_REGISTERED) + { + whd_wifi_deregister_event_handler(ifp, ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY]); + ifp->event_reg_list[WHD_AUTH_EVENT_ENTRY] = WHD_EVENT_NOT_REGISTERED; + } + whd_driver->internal_info.auth_result_callback = NULL; + return WHD_SUCCESS; } -uint32_t whd_wifi_unregister_multicast_address(whd_interface_t ifp, const whd_mac_t *mac) +whd_result_t whd_wifi_deauth_sta(whd_interface_t ifp, whd_mac_t *mac, whd_dot11_reason_code_t reason) { - whd_buffer_t buffer; - whd_buffer_t response; - uint16_t a; - mcast_list_t *orig_mcast_list; - whd_driver_t whd_driver; + whd_result_t result; + scb_val_t *scb_val; + whd_buffer_t buffer1; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + if (mac == NULL) + { + uint8_t *buffer = NULL; + whd_maclist_t *clients = NULL; + const whd_mac_t *current; + wl_bss_info_t ap_info; + whd_security_t sec; + uint32_t max_clients = 0; + size_t size = 0; + + result = whd_wifi_ap_get_max_assoc(ifp, &max_clients); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to get max number of associated clients\n") ); + max_clients = 5; + } + + size = (sizeof(uint32_t) + (max_clients * sizeof(whd_mac_t) ) ); + buffer = whd_mem_calloc(1, size); + + if (buffer == NULL) + { + WPRINT_WHD_ERROR( ("Unable to allocate memory for associated clients list, %s failed at line %d \n", + __func__, __LINE__) ); + return WHD_MALLOC_FAILURE; + } + + clients = (whd_maclist_t *)buffer; + clients->count = max_clients; + memset(&ap_info, 0, sizeof(wl_bss_info_t) ); + + result = whd_wifi_get_associated_client_list(ifp, clients, (uint16_t)size); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to get client list, %s failed at line %d \n", __func__, __LINE__) ); + whd_mem_free(buffer); + return result; + } + + current = &clients->mac_list[0]; + result = whd_wifi_get_ap_info(ifp, &ap_info, &sec); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Function %s failed at line %d \n", __func__, __LINE__) ); + whd_mem_free(buffer); + return result; + } + + + while ( (clients->count > 0) && (!(NULL_MAC(current->octet) ) ) ) + { + if (memcmp(current->octet, &(ap_info.BSSID), sizeof(whd_mac_t) ) != 0) + { + WPRINT_WHD_INFO( ("Deauthenticating STA MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", current->octet[0], + current->octet[1], current->octet[2], current->octet[3], current->octet[4], + current->octet[5]) ); + + scb_val = (scb_val_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer1, sizeof(scb_val_t) ); + if (scb_val == NULL) + { + WPRINT_WHD_ERROR( ("Buffer alloc failed in function %s at line %d \n", __func__, __LINE__) ); + whd_mem_free(buffer); + return WHD_BUFFER_ALLOC_FAIL; + } + memset( (char *)scb_val, 0, sizeof(scb_val_t) ); + memcpy( (char *)&scb_val->ea, (char *)current, sizeof(whd_mac_t) ); + scb_val->val = (uint32_t)reason; + result = whd_proto_set_ioctl(ifp, WLC_SCB_DEAUTHENTICATE_FOR_REASON, buffer1, 0); + + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to deauth client\n") ); + } + } + + --clients->count; + ++current; + } + + whd_mem_free(buffer); + + return WHD_SUCCESS; + } + + scb_val = (scb_val_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer1, sizeof(scb_val_t) ); + CHECK_IOCTL_BUFFER(scb_val); + memset( (char *)scb_val, 0, sizeof(scb_val_t) ); + memcpy( (char *)&scb_val->ea, (char *)mac, sizeof(whd_mac_t) ); + scb_val->val = (uint32_t)reason; + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SCB_DEAUTHENTICATE_FOR_REASON, buffer1, 0) ); + + return WHD_SUCCESS; +} - if (!ifp || !mac || !ETHER_ISMULTI(mac)) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } +whd_result_t whd_wifi_get_mac_address(whd_interface_t ifp, whd_mac_t *mac) +{ + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver; - whd_driver = ifp->whd_driver; + CHECK_IFP_NULL(ifp); - CHECK_DRIVER_NULL(whd_driver); + if (mac == NULL) + return WHD_BADARG; - /* Get the current multicast list */ - CHECK_IOCTL_BUFFER(whd_cdc_get_iovar_buffer(whd_driver, &buffer, - sizeof(uint32_t) + MAX_SUPPORTED_MCAST_ENTRIES * sizeof(whd_mac_t), IOVAR_STR_MCAST_LIST)); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - - /* Find the address, assuming it is part of the list */ - orig_mcast_list = (mcast_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - orig_mcast_list->entry_count = dtoh32(orig_mcast_list->entry_count); - if (orig_mcast_list->entry_count != 0) { - mcast_list_t *new_mcast_list = (mcast_list_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, - (uint16_t)(sizeof(uint32_t) + - (orig_mcast_list->entry_count - 1) * - sizeof(whd_mac_t)), - IOVAR_STR_MCAST_LIST); - CHECK_IOCTL_BUFFER(new_mcast_list); - - for (a = 0; a < orig_mcast_list->entry_count; ++a) { - WPRINT_WHD_INFO(("MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", orig_mcast_list->macs[a].octet[0], - orig_mcast_list->macs[a].octet[1], orig_mcast_list->macs[a].octet[2], - orig_mcast_list->macs[a].octet[3], orig_mcast_list->macs[a].octet[4], - orig_mcast_list->macs[a].octet[5])); - if (0 == memcmp(mac, &orig_mcast_list->macs[a], sizeof(whd_mac_t))) { - /* Copy the existing list up to the matching address */ - memcpy(new_mcast_list->macs, orig_mcast_list->macs, a * sizeof(whd_mac_t)); - - /* Skip the current address and copy the remaining entries */ - memcpy(&new_mcast_list->macs[a], &orig_mcast_list->macs[a + 1], - (size_t)(orig_mcast_list->entry_count - a - 1) * sizeof(whd_mac_t)); - - new_mcast_list->entry_count = orig_mcast_list->entry_count - 1; - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - new_mcast_list->entry_count = htod32(new_mcast_list->entry_count); - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); - } - } - /* There was something in the list, but the request MAC wasn't there */ - CHECK_RETURN(whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX)); - } - /* If we get here than the address wasn't in the list or the list was empty */ - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - WPRINT_WHD_ERROR(("whd_wifi_unregister_multicast_address address not registered yet \n")); - return WHD_DOES_NOT_EXIST; -} + whd_driver = ifp->whd_driver; -uint32_t whd_wifi_set_listen_interval(whd_interface_t ifp, uint8_t listen_interval, - whd_listen_interval_time_unit_t time_unit) -{ - uint8_t listen_interval_dtim; + CHECK_DRIVER_NULL(whd_driver); - CHECK_IFP_NULL(ifp); + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR) ); - switch (time_unit) { - case WHD_LISTEN_INTERVAL_TIME_UNIT_DTIM: { - listen_interval_dtim = listen_interval; - break; - } - case WHD_LISTEN_INTERVAL_TIME_UNIT_BEACON: { - /* If the wake interval measured in DTIMs is set to 0, the wake interval is measured in beacon periods */ - listen_interval_dtim = 0; + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); - /* The wake period is measured in beacon periods, set the value as required */ - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_BEACON, listen_interval)); - break; - } - default: - WPRINT_WHD_ERROR(("whd_wifi_set_listen_interval: Invalid Time unit specified \n")); - return WHD_BADARG; - } + memcpy(mac, whd_buffer_get_current_piece_data_pointer(whd_driver, response), sizeof(whd_mac_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_DTIM, listen_interval_dtim)); + return WHD_SUCCESS; +} - CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_ASSOC, listen_interval)); +whd_result_t whd_wifi_get_bssid(whd_interface_t ifp, whd_mac_t *bssid) +{ + whd_buffer_t buffer; + whd_buffer_t response; + whd_result_t result; + whd_driver_t whd_driver; + uint8_t *data = NULL; + CHECK_IFP_NULL(ifp); + + if (bssid == NULL) + return WHD_BADARG; + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if ( (ifp->role == WHD_STA_ROLE) || (ifp->role == WHD_AP_ROLE) ) + { + memset(bssid, 0, sizeof(whd_mac_t) ); + CHECK_IOCTL_BUFFER(whd_proto_get_ioctl_buffer(whd_driver, &buffer, sizeof(whd_mac_t) ) ); + if ( (result = + whd_proto_get_ioctl(ifp, WLC_GET_BSSID, buffer, &response) ) == WHD_SUCCESS ) + { + data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(bssid->octet, data, sizeof(whd_mac_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + return result; + } + else if (ifp->role == WHD_INVALID_ROLE) + { + WPRINT_WHD_ERROR( ("STA not associated with AP\n") ); + return WHD_WLAN_NOTASSOCIATED; + } + else + { + return WHD_UNSUPPORTED; + } +} - return WHD_SUCCESS; +whd_result_t whd_wifi_ap_get_max_assoc(whd_interface_t ifp, uint32_t *max_assoc) +{ + if (!ifp || !max_assoc) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + return whd_wifi_get_iovar_value(ifp, IOVAR_STR_MAX_ASSOC, max_assoc); } -uint32_t whd_wifi_get_listen_interval(whd_interface_t ifp, whd_listen_interval_t *li) +whd_result_t whd_wifi_get_associated_client_list(whd_interface_t ifp, void *client_list_buffer, uint16_t buffer_length) { - whd_buffer_t buffer; - whd_buffer_t response; - int *data; - uint8_t *pdata = NULL; - whd_driver_t whd_driver; + whd_buffer_t buffer; + whd_buffer_t response; + whd_result_t result; + whd_maclist_t *data = NULL; + uint8_t *pdata = NULL; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Check if soft AP interface is up, if not, return a count of 0 as a result */ + result = whd_wifi_is_ready_to_transceive(ifp); + if ( (result == WHD_SUCCESS) && (ifp->role == WHD_AP_ROLE) ) + { + data = (whd_maclist_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, buffer_length); + CHECK_IOCTL_BUFFER(data); + memset(data, 0, buffer_length); + data->count = htod32( ( (whd_maclist_t *)client_list_buffer )->count ); + + CHECK_RETURN(whd_proto_get_ioctl(ifp, WLC_GET_ASSOCLIST, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(client_list_buffer, (void *)pdata, + (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), buffer_length) ); + + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + else if (result == WHD_INTERFACE_NOT_UP) + { + /* not up, so can't have associated clients */ + ( (whd_maclist_t *)client_list_buffer )->count = 0; + } + else + { + WPRINT_WHD_ERROR( ("Invalid Interface\n") ); + return WHD_INVALID_INTERFACE; + } + return result; +} - CHECK_IFP_NULL(ifp); +whd_result_t whd_wifi_get_ap_info(whd_interface_t ifp, wl_bss_info_t *ap_info, whd_security_t *security) +{ + whd_buffer_t buffer; + whd_buffer_t response; + uint32_t *data; + uint8_t *pdata = NULL; + uint32_t security_value; /* hold misc security values */ + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + if ( (ap_info == NULL) || (security == NULL) ) + return WHD_BADARG; + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + /* Read the BSS info */ + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, WLC_IOCTL_SMLEN); + CHECK_IOCTL_BUFFER(data); + *data = WLC_IOCTL_SMLEN; + CHECK_RETURN(whd_proto_get_ioctl(ifp, WLC_GET_BSS_INFO, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(ap_info, (void *)(pdata + 4), sizeof(wl_bss_info_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + /* Read the WSEC setting */ + CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_WSEC, &security_value) ); + security_value = security_value & SECURITY_MASK; + *security = ( whd_security_t )(security_value); + + if (*security == WHD_SECURITY_WEP_PSK) + { + /* Read the WEP auth setting */ + CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_AUTH, &security_value) ); + + if (security_value == SHARED_AUTH) + { + *security |= SHARED_ENABLED; + } + } + else if ( (*security & (TKIP_ENABLED | AES_ENABLED) ) != 0 ) + { + /* Read the WPA auth setting */ + CHECK_RETURN(whd_wifi_get_ioctl_value(ifp, WLC_GET_WPA_AUTH, &security_value) ); + + if (security_value == WPA2_AUTH_PSK) + { + *security |= WPA2_SECURITY; + } + else if (security_value == WPA_AUTH_PSK) + { + *security |= WPA_SECURITY; + } + } + else if (*security != WHD_SECURITY_OPEN) + { + *security = WHD_SECURITY_UNKNOWN; + WPRINT_WHD_ERROR( ("Unknown security type, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_UNKNOWN_SECURITY_TYPE; + } + + return WHD_SUCCESS; +} - if (li == NULL) - return WHD_BADARG; +whd_result_t whd_wifi_enable_powersave(whd_interface_t ifp) +{ + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; - CHECK_DRIVER_NULL(whd_driver); + CHECK_DRIVER_NULL(whd_driver); - data = (int *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_BEACON); - CHECK_IOCTL_BUFFER(data); - memset(data, 0, 1); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((uint8_t *)&(li->beacon), (char *)pdata, 1); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - - data = (int *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_DTIM); - CHECK_IOCTL_BUFFER(data); - memset(data, 0, 1); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((uint8_t *)&(li->dtim), (char *)pdata, 1); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - - data = (int *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_ASSOC); - CHECK_IOCTL_BUFFER(data); - memset(data, 0, 4); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((uint16_t *)&(li->assoc), (char *)pdata, 2); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + /* Set legacy powersave mode - PM1 */ + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)PM1_POWERSAVE_MODE ); - return WHD_SUCCESS; + RETURN_WITH_ASSERT(whd_proto_set_ioctl(ifp, WLC_SET_PM, buffer, NULL) ); } -uint32_t whd_wifi_is_ready_to_transceive(whd_interface_t ifp) +whd_result_t whd_wifi_get_powersave_mode(whd_interface_t ifp, uint32_t *value) { - whd_driver_t whd_driver; + whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + if (value == NULL) + return WHD_BADARG; - CHECK_DRIVER_NULL(whd_driver); + whd_driver = ifp->whd_driver; - switch (ifp->role) { - case WHD_AP_ROLE: - return (whd_wifi_get_ap_is_up(whd_driver) == WHD_TRUE) ? WHD_SUCCESS : WHD_INTERFACE_NOT_UP; + CHECK_DRIVER_NULL(whd_driver); - case WHD_STA_ROLE: - return whd_wifi_check_join_status(ifp); + return whd_wifi_get_ioctl_value(ifp, WLC_GET_PM, value); +} - /* Disables Eclipse static analysis warning */ - /* No break needed due to returns in all case paths */ - /* no break */ - /* Fall Through */ - case WHD_P2P_ROLE: - case WHD_INVALID_ROLE: +#ifdef CYCFG_ULP_SUPPORT_ENABLED +whd_result_t whd_wifi_config_ulp_mode(whd_interface_t ifp, uint32_t *mode, uint32_t *wait_time) +{ + whd_driver_t whd_driver; + uint32_t get_ulp_mode = 0; + uint16_t wlan_chip_id = 0; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + wlan_chip_id = whd_chip_get_chip_id(ifp->whd_driver); + + if (wlan_chip_id == 43022) + { + WPRINT_WHD_DEBUG(("Connected Chip supports ULP \n")); + + if((*mode == ULP_DS1_SUPPORT) || (*mode == ULP_DS2_SUPPORT)) + { + + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ULP_WAIT, *wait_time)); + + whd_wifi_get_iovar_value(ifp, IOVAR_STR_ULP, &get_ulp_mode); + if(get_ulp_mode == 0) + { + /* Enable wowl magic pattern wake bit */ + CHECK_RETURN(whd_configure_wowl(ifp, ( WL_WOWL_MAGIC | WL_WOWL_ARPOFFLOAD | WL_WOWL_DEAUTH ))); + /* Set ulp mode */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ULP, *mode)); + } + else + { + WPRINT_WHD_DEBUG(("ULP mode already set to %d \n", (int)get_ulp_mode)); + } + } + else if(*mode == ULP_NO_SUPPORT) + { + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_ULP, *mode)); + } + else + { + WPRINT_WHD_ERROR(("Given ULP Configuration mode is not supported\n")); + return WHD_BADARG; + } + } + else + { + WPRINT_WHD_ERROR(("Connected Chip doesn't support ULP \n")); + return WHD_BADARG; + } + + return WHD_SUCCESS; +} +#endif - default: - return WHD_UNKNOWN_INTERFACE; - } +whd_result_t whd_wifi_enable_powersave_with_throughput(whd_interface_t ifp, uint16_t return_to_sleep_delay_ms) +{ + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver; + uint16_t chip_id; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if (return_to_sleep_delay_ms < PM2_SLEEP_RET_TIME_MIN) + { + WPRINT_WHD_ERROR( ("Delay too short, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_DELAY_TOO_SHORT; + } + else if (return_to_sleep_delay_ms > PM2_SLEEP_RET_TIME_MAX) + { + WPRINT_WHD_ERROR( ("Delay too long, %s failed at line %d \n", __func__, __LINE__) ); + return WHD_DELAY_TOO_LONG; + } + + /* Set the maximum time to wait before going back to sleep */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PM2_SLEEP_RET, + (uint32_t)(return_to_sleep_delay_ms / 10) * 10) ); + chip_id = whd_chip_get_chip_id(whd_driver); + + if (chip_id == 43362) + { + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PM_LIMIT, NULL_FRAMES_WITH_PM_SET_LIMIT) ); + } + + /* set PM2 fast return to sleep powersave mode */ + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)PM2_POWERSAVE_MODE ); + + RETURN_WITH_ASSERT(whd_proto_set_ioctl(ifp, WLC_SET_PM, buffer, NULL) ); } -uint32_t whd_wifi_get_acparams(whd_interface_t ifp, edcf_acparam_t *acp) +whd_result_t whd_wifi_disable_powersave(whd_interface_t ifp) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver; - uint8_t *pdata = NULL; + whd_buffer_t buffer; + whd_driver_t whd_driver; - if (!ifp || !acp) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - whd_driver = ifp->whd_driver; + CHECK_IFP_NULL(ifp); - CHECK_DRIVER_NULL(whd_driver); + whd_driver = ifp->whd_driver; - int *data = (int *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, 64, IOVAR_STR_AC_PARAMS_STA); + CHECK_DRIVER_NULL(whd_driver); - CHECK_IOCTL_BUFFER(data); - memset(data, 0, 64); - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((char *)acp, (char *)pdata, (sizeof(edcf_acparam_t) * 4)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + uint32_t *data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)4); - return WHD_SUCCESS; + CHECK_IOCTL_BUFFER(data); + *data = htod32( (uint32_t)NO_POWERSAVE_MODE ); + CHECK_RETURN(whd_proto_set_ioctl(ifp, WLC_SET_PM, buffer, NULL) ); + return WHD_SUCCESS; } -uint32_t whd_wifi_get_channels(whd_interface_t ifp, whd_list_t *channel_list) +whd_result_t whd_wifi_register_multicast_address(whd_interface_t ifp, const whd_mac_t *mac) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_list_t *list; - whd_driver_t whd_driver; - uint16_t buffer_length; + whd_buffer_t buffer; + whd_buffer_t response; + uint16_t a; + mcast_list_t *orig_mcast_list; + mcast_list_t *new_mcast_list; + whd_driver_t whd_driver; + + if (!ifp || !mac || !ETHER_ISMULTI(mac) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Get the current multicast list */ + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(uint32_t) + MAX_SUPPORTED_MCAST_ENTRIES * + sizeof(whd_mac_t), IOVAR_STR_MCAST_LIST) ); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + + /* Verify address is not currently registered */ + orig_mcast_list = (mcast_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(orig_mcast_list, WHD_NO_REGISTER_FUNCTION_POINTER); + orig_mcast_list->entry_count = dtoh32(orig_mcast_list->entry_count); + for (a = 0; a < orig_mcast_list->entry_count; ++a) + { + /* Check if any address matches */ + if (0 == memcmp(mac, &orig_mcast_list->macs[a], sizeof(whd_mac_t) ) ) + { + /* A matching address has been found so we can stop now. */ + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + return WHD_SUCCESS; + } + } + + /* Add the provided address to the list and write the new multicast list */ + new_mcast_list = (mcast_list_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + ( uint16_t )(sizeof(uint32_t) + + (orig_mcast_list->entry_count + 1) * + sizeof(whd_mac_t) ), + IOVAR_STR_MCAST_LIST); + CHECK_IOCTL_BUFFER(new_mcast_list); + new_mcast_list->entry_count = orig_mcast_list->entry_count; + memcpy(new_mcast_list->macs, orig_mcast_list->macs, orig_mcast_list->entry_count * sizeof(whd_mac_t) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + memcpy(&new_mcast_list->macs[new_mcast_list->entry_count], mac, sizeof(whd_mac_t) ); + ++new_mcast_list->entry_count; + new_mcast_list->entry_count = htod32(new_mcast_list->entry_count); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); - if (!ifp || !channel_list) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } - if (!channel_list->count) { - WPRINT_WHD_ERROR(("channel_list->count is zero and max channel is %d in func %s at line %d \n", - WL_NUMCHANNELS, __func__, __LINE__)); - return WHD_WLAN_BADARG; - } +} - whd_driver = ifp->whd_driver; +whd_result_t whd_wifi_unregister_multicast_address(whd_interface_t ifp, const whd_mac_t *mac) +{ + whd_buffer_t buffer; + whd_buffer_t response; + uint16_t a; + mcast_list_t *orig_mcast_list; + whd_driver_t whd_driver; + + if (!ifp || !mac || !ETHER_ISMULTI(mac) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + /* Get the current multicast list */ + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(uint32_t) + MAX_SUPPORTED_MCAST_ENTRIES * + sizeof(whd_mac_t), IOVAR_STR_MCAST_LIST) ); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + + /* Find the address, assuming it is part of the list */ + orig_mcast_list = (mcast_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + orig_mcast_list->entry_count = dtoh32(orig_mcast_list->entry_count); + if (orig_mcast_list->entry_count != 0) + { + mcast_list_t *new_mcast_list = (mcast_list_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + ( uint16_t )(sizeof(uint32_t) + + (orig_mcast_list-> + entry_count - 1) * + sizeof(whd_mac_t) ), + IOVAR_STR_MCAST_LIST); + CHECK_IOCTL_BUFFER(new_mcast_list); + + for (a = 0; a < orig_mcast_list->entry_count; ++a) + { + WPRINT_WHD_INFO( ("MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", orig_mcast_list->macs[a].octet[0], + orig_mcast_list->macs[a].octet[1], orig_mcast_list->macs[a].octet[2], + orig_mcast_list->macs[a].octet[3], orig_mcast_list->macs[a].octet[4], + orig_mcast_list->macs[a].octet[5]) ); + if (0 == memcmp(mac, &orig_mcast_list->macs[a], sizeof(whd_mac_t) ) ) + { + /* Copy the existing list up to the matching address */ + memcpy(new_mcast_list->macs, orig_mcast_list->macs, a * sizeof(whd_mac_t) ); + + /* Skip the current address and copy the remaining entries */ + memcpy(&new_mcast_list->macs[a], &orig_mcast_list->macs[a + 1], + ( size_t )(orig_mcast_list->entry_count - a - 1) * sizeof(whd_mac_t) ); + + new_mcast_list->entry_count = orig_mcast_list->entry_count - 1; + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + new_mcast_list->entry_count = htod32(new_mcast_list->entry_count); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); + } + } + /* There was something in the list, but the request MAC wasn't there */ + CHECK_RETURN(whd_buffer_release(whd_driver, buffer, WHD_NETWORK_TX) ); + } + /* If we get here than the address wasn't in the list or the list was empty */ + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + WPRINT_WHD_ERROR( ("whd_wifi_unregister_multicast_address address not registered yet \n") ); + return WHD_DOES_NOT_EXIST; +} - CHECK_DRIVER_NULL(whd_driver); +whd_result_t whd_wifi_set_listen_interval(whd_interface_t ifp, uint8_t listen_interval, + whd_listen_interval_time_unit_t time_unit) +{ + uint8_t listen_interval_dtim; - buffer_length = sizeof(uint32_t) * (WL_NUMCHANNELS + 1); + CHECK_IFP_NULL(ifp); - list = (whd_list_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, buffer_length); - CHECK_IOCTL_BUFFER(list); + switch (time_unit) + { + case WHD_LISTEN_INTERVAL_TIME_UNIT_DTIM: + { + listen_interval_dtim = listen_interval; + break; + } + case WHD_LISTEN_INTERVAL_TIME_UNIT_BEACON: + { + /* If the wake interval measured in DTIMs is set to 0, the wake interval is measured in beacon periods */ + listen_interval_dtim = 0; + + /* The wake period is measured in beacon periods, set the value as required */ + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_BEACON, listen_interval) ); + break; + } + default: + WPRINT_WHD_ERROR( ("whd_wifi_set_listen_interval: Invalid Time unit specified \n") ); + return WHD_BADARG; + } - memset(list, 0, buffer_length); - list->count = htod32(WL_NUMCHANNELS); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_VALID_CHANNELS, buffer, &response)); + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_DTIM, listen_interval_dtim) ); - list = (whd_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - memcpy(channel_list, list, - (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), - (sizeof(uint32_t) * (channel_list->count + 1)))); + CHECK_RETURN(whd_wifi_set_iovar_value(ifp, IOVAR_STR_LISTEN_INTERVAL_ASSOC, listen_interval) ); - whd_buffer_release(whd_driver, response, WHD_NETWORK_RX); + return WHD_SUCCESS; - return WHD_SUCCESS; } -uint32_t whd_wifi_manage_custom_ie(whd_interface_t ifp, whd_custom_ie_action_t action, const uint8_t *oui, - uint8_t subtype, const void *data, uint16_t length, uint16_t which_packets) +whd_result_t whd_wifi_get_listen_interval(whd_interface_t ifp, whd_listen_interval_t *li) { - whd_buffer_t buffer; - vndr_ie_setbuf_t *ie_setbuf; - uint32_t *iovar_data; - whd_driver_t whd_driver; + whd_buffer_t buffer; + whd_buffer_t response; + int *data; + uint8_t *pdata = NULL; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + if (li == NULL) + return WHD_BADARG; + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + data = (int *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_BEACON); + CHECK_IOCTL_BUFFER(data); + memset(data, 0, 1); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (uint8_t *)&(li->beacon), (char *)pdata, 1 ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + data = (int *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_DTIM); + CHECK_IOCTL_BUFFER(data); + memset(data, 0, 1); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (uint8_t *)&(li->dtim), (char *)pdata, 1 ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + data = (int *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 4, IOVAR_STR_LISTEN_INTERVAL_ASSOC); + CHECK_IOCTL_BUFFER(data); + memset(data, 0, 4); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (uint16_t *)&(li->assoc), (char *)pdata, 2 ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; +} - if (!ifp || !oui || !data) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } +whd_result_t whd_wifi_is_ready_to_transceive(whd_interface_t ifp) +{ + whd_driver_t whd_driver; - /* VNDR_IE = OUI + subtype + data_length */ - if (VNDR_IE_MAX_LEN < WIFI_IE_OUI_LENGTH + 1 + length) { - WPRINT_WHD_ERROR(("Invalid length :%u in func %s\n", length, __func__)); - return WHD_WLAN_BADARG; - } + CHECK_IFP_NULL(ifp); - if (which_packets & VENDOR_IE_UNKNOWN) { - WPRINT_WHD_ERROR(("Unsupported packet ID(%x) in func %s\n", which_packets, __func__)); - return WHD_WLAN_BADARG; - } + whd_driver = ifp->whd_driver; - whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); - CHECK_DRIVER_NULL(whd_driver); + switch (ifp->role) + { + case WHD_AP_ROLE: + return (whd_wifi_get_ap_is_up(whd_driver) == WHD_TRUE) ? WHD_SUCCESS : WHD_INTERFACE_NOT_UP; - whd_assert("Bad Args", oui != NULL); + case WHD_STA_ROLE: + return whd_wifi_check_join_status(ifp); - iovar_data = - (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)(sizeof(vndr_ie_setbuf_t) + length + 4), - "bsscfg:" IOVAR_STR_VENDOR_IE); - CHECK_IOCTL_BUFFER(iovar_data); - *iovar_data = ifp->bsscfgidx; - ie_setbuf = (vndr_ie_setbuf_t *)(iovar_data + 1); + /* Disables Eclipse static analysis warning */ + /* No break needed due to returns in all case paths */ + /* no break */ + /* Fall Through */ + case WHD_P2P_ROLE: + case WHD_INVALID_ROLE: - /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ - if (action == WHD_ADD_CUSTOM_IE) { - memcpy((char *)ie_setbuf->cmd, "add", 3); - } - else { - memcpy((char *)ie_setbuf->cmd, "del", 3); - } - ie_setbuf->cmd[3] = 0; + default: + return WHD_UNKNOWN_INTERFACE; + } +} - /* Set the values */ - ie_setbuf->vndr_ie_buffer.iecount = (int32_t)htod32(1); +whd_result_t whd_wifi_get_acparams(whd_interface_t ifp, edcf_acparam_t *acp) +{ + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver; + uint8_t *pdata = NULL; + + if (!ifp || !acp) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + int *data = (int *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 64, IOVAR_STR_AC_PARAMS_STA); + + CHECK_IOCTL_BUFFER(data); + memset(data, 0, 64); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (char *)acp, (char *)pdata, (sizeof(edcf_acparam_t) * 4) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; +} + +whd_result_t whd_wifi_get_channels(whd_interface_t ifp, whd_list_t *channel_list) +{ + whd_buffer_t buffer; + whd_buffer_t response; + whd_list_t *list; + whd_driver_t whd_driver; + uint16_t buffer_length; + + if (!ifp || !channel_list) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + if (!channel_list->count) + { + WPRINT_WHD_ERROR( ("channel_list->count is zero and max channel is %d in func %s at line %d \n", + MAXCHANNEL, __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + buffer_length = sizeof(uint32_t) * (MAXCHANNEL + 1); + + list = (whd_list_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, buffer_length); + CHECK_IOCTL_BUFFER(list); + + memset(list, 0, buffer_length); + list->count = htod32(MAXCHANNEL); + CHECK_RETURN(whd_proto_get_ioctl(ifp, WLC_GET_VALID_CHANNELS, buffer, &response) ); + + list = (whd_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + memcpy(channel_list, list, + (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), + (sizeof(uint32_t) * (channel_list->count + 1) ) ) ); + + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; +} +whd_result_t whd_wifi_manage_custom_ie(whd_interface_t ifp, whd_custom_ie_action_t action, const uint8_t *oui, + uint8_t subtype, const void *data, uint16_t length, uint16_t which_packets) +{ + whd_buffer_t buffer; + vndr_ie_setbuf_t *ie_setbuf; + uint32_t *iovar_data; + whd_driver_t whd_driver; + + if (!ifp || !oui || !data) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + /* VNDR_IE = OUI + subtype + data_length */ + if (VNDR_IE_MAX_LEN < WIFI_IE_OUI_LENGTH + 1 + length) + { + WPRINT_WHD_ERROR( ("Invalid length :%u in func %s\n", length, __func__) ); + return WHD_WLAN_BADARG; + } + + if (which_packets & VENDOR_IE_UNKNOWN) + { + WPRINT_WHD_ERROR( ("Unsupported packet ID(%x) in func %s\n", which_packets, __func__) ); + return WHD_WLAN_BADARG; + } + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + whd_assert("Bad Args", oui != NULL); + + iovar_data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)(sizeof(vndr_ie_setbuf_t) + length + 4), + "bsscfg:" IOVAR_STR_VENDOR_IE); + CHECK_IOCTL_BUFFER(iovar_data); + *iovar_data = ifp->bsscfgidx; + ie_setbuf = (vndr_ie_setbuf_t *)(iovar_data + 1); + + /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ + if (action == WHD_ADD_CUSTOM_IE) + { + memcpy( (char *)ie_setbuf->cmd, "add", 3 ); + } + else + { + memcpy( (char *)ie_setbuf->cmd, "del", 3 ); + } + ie_setbuf->cmd[3] = 0; + + /* Set the values */ ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag = htod32(which_packets); ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = 0xdd; ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = - (uint8_t)(length + sizeof(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui) + 1); /* +1: one byte for sub type */ + ( uint8_t )(length + sizeof(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui) + 1); /* +1: one byte for sub type */ + ie_setbuf->vndr_ie_buffer.iecount = (int32_t)htod32(1); - /* Stop lint warning about vndr_ie_list array element not yet being defined */ - memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, (size_t)WIFI_IE_OUI_LENGTH); + /* Stop lint warning about vndr_ie_list array element not yet being defined */ + memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, (size_t)WIFI_IE_OUI_LENGTH); - ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] = subtype; + ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] = subtype; - memcpy(&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[1], data, length); + memcpy(&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[1], data, length); - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } -uint32_t whd_wifi_send_action_frame(whd_interface_t ifp, whd_af_params_t *af_params) +whd_result_t whd_wifi_send_action_frame(whd_interface_t ifp, whd_af_params_t *af_params) { - whd_buffer_t buffer; - whd_af_params_t *af_frame; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; + whd_buffer_t buffer; + whd_af_params_t *af_frame; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if ( (af_params == NULL) || (af_params->action_frame.len > ACTION_FRAME_SIZE) ) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + af_frame = (whd_af_params_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, WL_WIFI_AF_PARAMS_SIZE, + IOVAR_STR_ACTION_FRAME); + CHECK_IOCTL_BUFFER (af_frame); + memcpy(af_frame, af_params, WL_WIFI_AF_PARAMS_SIZE); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - CHECK_DRIVER_NULL(whd_driver); +whd_result_t whd_wifi_send_auth_frame(whd_interface_t ifp, whd_auth_params_t *auth_params) +{ + whd_buffer_t buffer; + whd_auth_params_t *auth_frame; + whd_driver_t whd_driver; + uint16_t auth_frame_len; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if (auth_params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + /* FW doesn't need MAC Header Length */ + auth_params->len -= DOT11_MGMT_HDR_LEN; + auth_frame_len = OFFSET(whd_auth_params_t, data) + auth_params->len; + auth_frame = (whd_auth_params_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, auth_frame_len, + IOVAR_STR_MGMT_FRAME); + CHECK_IOCTL_BUFFER (auth_frame); + memcpy(auth_frame, auth_params, OFFSET(whd_auth_params_t, data) ); + memcpy(auth_frame->data, &auth_params->data[DOT11_MGMT_HDR_LEN], auth_params->len); + auth_frame->dwell_time = MGMT_AUTH_FRAME_DWELL_TIME; + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - if ((af_params == NULL) || (af_params->action_frame.len > ACTION_FRAME_SIZE)) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", __func__, __LINE__)); - return WHD_WLAN_BADARG; - } +whd_result_t whd_wifi_he_omi(whd_interface_t ifp, whd_he_omi_params_t *he_omi_params) +{ + whd_buffer_t buffer; + whd_xtlv_t *he_omi_iovar; + whd_driver_t whd_driver; + wl_he_omi_t he_omi; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + he_omi.version = WL_HE_OMI_VER; + he_omi.length = sizeof(wl_he_omi_t) - 2; + he_omi.rx_nss = he_omi_params->rx_nss; + he_omi.chnl_wdth = he_omi_params->chnl_wdth; + he_omi.ul_mu_dis = he_omi_params->ul_mu_dis; + he_omi.tx_nsts = he_omi_params->tx_nsts; + he_omi.er_su_dis = he_omi_params->er_su_dis; + he_omi.dl_mu_resound = he_omi_params->dl_mu_resound; + he_omi.ul_mu_data_dis = he_omi_params->ul_mu_data_dis; + + he_omi_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_he_omi_t) + 4, + IOVAR_STR_HE); + CHECK_IOCTL_BUFFER (he_omi_iovar); + he_omi_iovar->id = WL_HE_CMD_OMI; + he_omi_iovar->len = sizeof(wl_he_omi_t); + memcpy(he_omi_iovar->data, (uint8_t *)&he_omi, sizeof(wl_he_omi_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - af_frame = (whd_af_params_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, WL_WIFI_AF_PARAMS_SIZE, - IOVAR_STR_ACTION_FRAME); - CHECK_IOCTL_BUFFER(af_frame); - memcpy(af_frame, af_params, WL_WIFI_AF_PARAMS_SIZE); - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); +whd_result_t whd_wifi_bss_max_idle(whd_interface_t ifp, uint16_t period) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver; + uint32_t *iovar_data; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + iovar_data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, 8, IOVAR_WNM_MAXIDLE); + CHECK_IOCTL_BUFFER (iovar_data); + /* set bss_max_idle_period */ + iovar_data[0] = period; + /* set bss_idle_opt */ + iovar_data[1] = 1; + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } -uint32_t whd_wifi_set_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t value) +whd_result_t whd_wifi_itwt_setup(whd_interface_t ifp, whd_itwt_setup_params_t *twt_params) { - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver; + whd_buffer_t buffer; + whd_xtlv_t *twt_iovar; + whd_driver_t whd_driver; + wl_twt_setup_t itwt_setup; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + memset( (uint8_t *)&itwt_setup, 0x00, sizeof(itwt_setup) ); + itwt_setup.version = WL_TWT_SETUP_VER; + itwt_setup.length = sizeof(wl_twt_setup_t) - 4; + itwt_setup.desc.negotiation_type = TWT_CTRL_NEGO_TYPE_0; + itwt_setup.desc.flow_flags = WL_TWT_FLOW_FLAG_REQUEST; + if (twt_params == NULL) + { + WPRINT_WHD_INFO( ("Trigger Individual TWT with default value\n") ); + itwt_setup.desc.setup_cmd = TWT_SETUP_CMD_SUGGEST_TWT; + itwt_setup.desc.wake_dur = 255 * 256; + itwt_setup.desc.wake_int = 8192 * (1 << 10); + itwt_setup.desc.flow_id = 0xFF; + itwt_setup.desc.flow_flags |= WL_TWT_FLOW_FLAG_TRIGGER; + itwt_setup.desc.flow_flags |= WL_TWT_FLOW_FLAG_UNANNOUNCED; + } + else + { + itwt_setup.desc.setup_cmd = twt_params->setup_cmd; + itwt_setup.desc.wake_dur = twt_params->wake_duration * 256; + itwt_setup.desc.wake_int = twt_params->mantissa * (1 << twt_params->exponent); + itwt_setup.desc.flow_id = twt_params->flow_id; + itwt_setup.desc.flow_flags |= (twt_params->trigger) ? WL_TWT_FLOW_FLAG_TRIGGER : 0; + itwt_setup.desc.flow_flags |= (twt_params->flow_type) ? WL_TWT_FLOW_FLAG_UNANNOUNCED : 0; + itwt_setup.desc.wake_time_h = twt_params->wake_time_h; + itwt_setup.desc.wake_time_l = twt_params->wake_time_l; + } + twt_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_twt_setup_t) + 4, + IOVAR_STR_TWT); + CHECK_IOCTL_BUFFER (twt_iovar); + twt_iovar->id = WL_TWT_CMD_SETUP; + twt_iovar->len = sizeof(wl_twt_setup_t); + memcpy(twt_iovar->data, (uint8_t *)&itwt_setup, sizeof(wl_twt_setup_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - CHECK_IFP_NULL(ifp); +whd_result_t whd_wifi_btwt_join(whd_interface_t ifp, whd_btwt_join_params_t *twt_params) +{ + whd_buffer_t buffer; + whd_xtlv_t *twt_iovar; + whd_driver_t whd_driver; + wl_twt_setup_t btwt_setup; + + if (twt_params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d\n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + memset( (uint8_t *)&btwt_setup, 0x00, sizeof(btwt_setup) ); + btwt_setup.version = WL_TWT_SETUP_VER; + btwt_setup.length = sizeof(wl_twt_setup_t) - 4; + btwt_setup.desc.flow_flags = WL_TWT_FLOW_FLAG_REQUEST; + btwt_setup.desc.flow_id = 0; /* map to bTWT recommendation subfield */ + btwt_setup.desc.negotiation_type = TWT_CTRL_NEGO_TYPE_3; + btwt_setup.desc.wake_type = WL_TWT_TIME_TYPE_BSS; + btwt_setup.desc.setup_cmd = twt_params->setup_cmd; + btwt_setup.desc.flow_flags |= (twt_params->trigger) ? WL_TWT_FLOW_FLAG_TRIGGER : 0; + btwt_setup.desc.flow_flags |= (twt_params->flow_type) ? WL_TWT_FLOW_FLAG_UNANNOUNCED : 0; + btwt_setup.desc.wake_dur = twt_params->wake_duration * 256; + btwt_setup.desc.wake_int = twt_params->mantissa * (1 << twt_params->exponent); + btwt_setup.desc.bid = twt_params->bid; + + twt_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_twt_setup_t) + 4, + IOVAR_STR_TWT); + CHECK_IOCTL_BUFFER (twt_iovar); + twt_iovar->id = WL_TWT_CMD_SETUP; + twt_iovar->len = sizeof(wl_twt_setup_t); + memcpy(twt_iovar->data, (uint8_t *)&btwt_setup, sizeof(wl_twt_setup_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - whd_driver = ifp->whd_driver; +whd_result_t whd_wifi_twt_teardown(whd_interface_t ifp, whd_twt_teardown_params_t *twt_params) +{ + whd_buffer_t buffer; + whd_xtlv_t *twt_iovar; + whd_driver_t whd_driver; + wl_twt_teardown_t twt_teardown; + + if (twt_params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d\n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + memset( (uint8_t *)&twt_teardown, 0x00, sizeof(twt_teardown) ); + twt_teardown.version = WL_TWT_TEARDOWN_VER; + twt_teardown.length = sizeof(wl_twt_teardown_t) - 4; + twt_teardown.teardesc.negotiation_type = twt_params->negotiation_type; + twt_teardown.teardesc.flow_id = twt_params->flow_id; + twt_teardown.teardesc.bid = twt_params->bcast_twt_id; + twt_teardown.teardesc.alltwt = twt_params->teardown_all_twt; + + twt_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_twt_teardown_t) + 4, + IOVAR_STR_TWT); + CHECK_IOCTL_BUFFER (twt_iovar); + twt_iovar->id = WL_TWT_CMD_TEARDOWN; + twt_iovar->len = sizeof(wl_twt_teardown_t); + memcpy(twt_iovar->data, (uint8_t *)&twt_teardown, sizeof(wl_twt_teardown_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - CHECK_DRIVER_NULL(whd_driver); +whd_result_t whd_wifi_twt_information_frame(whd_interface_t ifp, whd_twt_information_params_t *twt_params) +{ + whd_buffer_t buffer; + whd_xtlv_t *twt_iovar; + whd_driver_t whd_driver; + wl_twt_info_t twt_information; + + if (twt_params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d\n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + memset( (uint8_t *)&twt_information, 0x00, sizeof(twt_information) ); + twt_information.version = WL_TWT_INFO_VER; + twt_information.length = sizeof(wl_twt_info_t) - 4; + twt_information.infodesc.flow_flags |= WL_TWT_INFO_FLAG_ALL_TWT; + twt_information.infodesc.flow_id = twt_params->flow_id; + if (twt_params->suspend == 1) + { + twt_information.infodesc.next_twt_h = 0; + twt_information.infodesc.next_twt_l = 0; + } + else + { + twt_information.infodesc.flow_flags = WL_TWT_INFO_FLAG_RESUME; + twt_information.infodesc.next_twt_h = 0; + twt_information.infodesc.next_twt_l = (twt_params->resume_time << 20) & 0xFFFFFFFF; + } + + twt_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_twt_info_t) + 4, + IOVAR_STR_TWT); + CHECK_IOCTL_BUFFER (twt_iovar); + twt_iovar->id = WL_TWT_CMD_INFO; + twt_iovar->len = sizeof(wl_twt_info_t); + memcpy(twt_iovar->data, (uint8_t *)&twt_information, sizeof(wl_twt_info_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)sizeof(value)); - CHECK_IOCTL_BUFFER(data); - *data = htod32(value); - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, ioctl, buffer, 0)); +whd_result_t whd_wifi_btwt_config(whd_interface_t ifp, whd_btwt_config_params_t *twt_params) +{ + whd_buffer_t buffer; + whd_xtlv_t *twt_iovar; + whd_driver_t whd_driver; + + if (twt_params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d\n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + CHECK_IFP_NULL(ifp); + wl_twt_setup_t config_btwt; + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + memset( (uint8_t *)&config_btwt, 0x00, sizeof(config_btwt) ); + config_btwt.version = WL_TWT_SETUP_VER; + config_btwt.length = sizeof(wl_twt_setup_t) - 4; + config_btwt.desc.negotiation_type = TWT_CTRL_NEGO_TYPE_2; + config_btwt.desc.wake_type = WL_TWT_TIME_TYPE_BSS; + config_btwt.desc.setup_cmd = twt_params->setup_cmd; + config_btwt.desc.wake_dur = twt_params->wake_duration * 256; + config_btwt.desc.wake_int = twt_params->mantissa * (1 << twt_params->exponent); + config_btwt.desc.bid = twt_params->bid; + config_btwt.desc.flow_flags |= (twt_params->trigger) ? WL_TWT_FLOW_FLAG_TRIGGER : 0; + config_btwt.desc.flow_flags |= (twt_params->flow_type) ? WL_TWT_FLOW_FLAG_UNANNOUNCED : 0; + + twt_iovar = (whd_xtlv_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(wl_twt_setup_t) + 4, + IOVAR_STR_TWT); + CHECK_IOCTL_BUFFER (twt_iovar); + twt_iovar->id = WL_TWT_CMD_SETUP; + twt_iovar->len = sizeof(wl_twt_setup_t); + memcpy(twt_iovar->data, (uint8_t *)&config_btwt, sizeof(wl_twt_setup_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - return WHD_SUCCESS; +uint32_t whd_wifi_mbo_add_chan_pref(whd_interface_t ifp, whd_mbo_add_chan_pref_params_t *mbo_params) +{ + whd_buffer_t buffer; + whd_iov_buf_t *mbo_iovar; + whd_driver_t whd_driver; + mbo_add_chan_pref_t ch_pref; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if ((wlan_chip_id != 55500) && (wlan_chip_id != 55900)) + { + WPRINT_WHD_ERROR(("Connected Chip doesn't support MBO \n")); + return WHD_UNSUPPORTED; + } + + memset( (uint8_t *)&ch_pref, 0x00, sizeof(ch_pref) ); + //opclass + ch_pref.opclass.id = WL_MBO_XTLV_OPCLASS; + ch_pref.opclass.len = sizeof(mbo_params->opclass); + memcpy(ch_pref.opclass.data, (uint32_t *)&mbo_params->opclass, sizeof(mbo_params->opclass)); + //channel + ch_pref.chan.id = WL_MBO_XTLV_CHAN; + ch_pref.chan.len = sizeof(mbo_params->chan); + memcpy(ch_pref.chan.data, (uint32_t *)&mbo_params->chan, sizeof(mbo_params->chan)); + //channel preference + ch_pref.pref.id = WL_MBO_XTLV_PREFERENCE; + ch_pref.pref.len = sizeof(mbo_params->pref); + memcpy(ch_pref.pref.data, (uint32_t *)&mbo_params->pref, sizeof(mbo_params->pref)); + //reason + ch_pref.reason.id = WL_MBO_XTLV_REASON_CODE; + ch_pref.reason.len = sizeof(mbo_params->reason); + memcpy(ch_pref.reason.data, (uint32_t *)&mbo_params->reason, sizeof(mbo_params->reason)); + + mbo_iovar = (whd_iov_buf_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_iov_buf_t) + sizeof(ch_pref), + IOVAR_STR_MBO); + CHECK_IOCTL_BUFFER (mbo_iovar); + mbo_iovar->version = WL_MBO_IOV_VERSION; + mbo_iovar->len = sizeof(ch_pref); + mbo_iovar->id = WL_MBO_CMD_ADD_CHAN_PREF; + memcpy(mbo_iovar->data, (uint16_t *)&ch_pref, sizeof(mbo_add_chan_pref_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } -uint32_t whd_wifi_get_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t *value) +uint32_t whd_wifi_mbo_del_chan_pref(whd_interface_t ifp, whd_mbo_del_chan_pref_params_t *mbo_params) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver; - uint8_t *data = NULL; + whd_buffer_t buffer; + whd_iov_buf_t *mbo_iovar; + whd_driver_t whd_driver; + mbo_del_chan_pref_t ch_pref; + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if ((wlan_chip_id != 55500) && (wlan_chip_id != 55900)) + { + WPRINT_WHD_ERROR(("Connected Chip doesn't support MBO \n")); + return WHD_UNSUPPORTED; + } + + memset( (uint8_t *)&ch_pref, 0x00, sizeof(ch_pref) ); + //opclass + ch_pref.opclass.id = WL_MBO_XTLV_OPCLASS; + ch_pref.opclass.len = sizeof(mbo_params->opclass); + memcpy(ch_pref.opclass.data, (uint32_t *)&mbo_params->opclass, sizeof(mbo_params->opclass)); + //channel + ch_pref.chan.id = WL_MBO_XTLV_CHAN; + ch_pref.chan.len = sizeof(mbo_params->chan); + memcpy(ch_pref.chan.data, (uint32_t *)&mbo_params->chan, sizeof(mbo_params->chan)); + + mbo_iovar = (whd_iov_buf_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_iov_buf_t) + sizeof(ch_pref), + IOVAR_STR_MBO); + CHECK_IOCTL_BUFFER (mbo_iovar); + mbo_iovar->version = WL_MBO_IOV_VERSION; + mbo_iovar->len = sizeof(ch_pref); + mbo_iovar->id = WL_MBO_CMD_DEL_CHAN_PREF; + memcpy(mbo_iovar->data, (uint16_t *)&ch_pref, sizeof(mbo_del_chan_pref_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - if (value == NULL) - return WHD_BADARG; +uint32_t whd_wifi_mbo_send_notif(whd_interface_t ifp, uint8_t sub_elem_type) +{ + whd_buffer_t buffer; + whd_iov_buf_t *mbo_iovar; + whd_driver_t whd_driver; + mbo_xtlv_t sub_elem; + + if (sub_elem_type != MBO_ATTR_CELL_DATA_CAP && + sub_elem_type != MBO_ATTR_NON_PREF_CHAN_REPORT) + { + WPRINT_WHD_ERROR( ("Invalid value in func %s at line %d\n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + CHECK_IFP_NULL(ifp); + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + uint16_t wlan_chip_id = whd_chip_get_chip_id(whd_driver); + if ((wlan_chip_id != 55500) && (wlan_chip_id != 55900)) + { + WPRINT_WHD_ERROR(("Connected Chip doesn't support MBO \n")); + return WHD_UNSUPPORTED; + } + + memset( (uint8_t *)&sub_elem, 0x00, sizeof(sub_elem) ); + sub_elem.id = WL_MBO_XTLV_SUB_ELEM_TYPE; + sub_elem.len = sizeof(sub_elem_type); + memcpy(sub_elem.data, (uint32_t *)&sub_elem_type, sizeof(sub_elem_type)); + + mbo_iovar = (whd_iov_buf_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_iov_buf_t) + sizeof(sub_elem), + IOVAR_STR_MBO); + CHECK_IOCTL_BUFFER (mbo_iovar); + mbo_iovar->version = WL_MBO_IOV_VERSION; + mbo_iovar->len = sizeof(sub_elem); + mbo_iovar->id = WL_MBO_CMD_SEND_NOTIF; + memcpy(mbo_iovar->data, (uint16_t *)&sub_elem, sizeof(mbo_xtlv_t) ); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); +} - CHECK_IFP_NULL(ifp); +whd_result_t whd_wifi_set_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t value) +{ + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver; - whd_driver = ifp->whd_driver; + CHECK_IFP_NULL(ifp); - CHECK_DRIVER_NULL(whd_driver); + whd_driver = ifp->whd_driver; - CHECK_IOCTL_BUFFER(whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)sizeof(*value))); - CHECK_RETURN_UNSUPPORTED_OK(whd_cdc_send_ioctl(ifp, CDC_GET, ioctl, buffer, &response)); - data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - *value = dtoh32(*(uint32_t *)data); + CHECK_DRIVER_NULL(whd_driver); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)sizeof(value) ); + CHECK_IOCTL_BUFFER(data); + *data = htod32(value); + CHECK_RETURN(whd_proto_set_ioctl(ifp, ioctl, buffer, 0) ); - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_set_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, void *in_buffer, uint16_t in_buffer_length) +whd_result_t whd_wifi_get_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t *value) { - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver = ifp->whd_driver; - - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, in_buffer_length); - CHECK_IOCTL_BUFFER(data); + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver; + uint8_t *data = NULL; - memcpy(data, in_buffer, in_buffer_length); + if (value == NULL) + return WHD_BADARG; - CHECK_RETURN(whd_cdc_send_ioctl(ifp, CDC_SET, ioctl, buffer, NULL)); - - return WHD_SUCCESS; -} + CHECK_IFP_NULL(ifp); -uint32_t whd_wifi_get_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, uint8_t *out_buffer, uint16_t out_length) -{ - whd_buffer_t buffer; - uint32_t *data; - whd_buffer_t response; - whd_result_t result; - whd_driver_t whd_driver; + whd_driver = ifp->whd_driver; - CHECK_IFP_NULL(ifp); + CHECK_DRIVER_NULL(whd_driver); - whd_driver = ifp->whd_driver; - data = (uint32_t *)whd_cdc_get_ioctl_buffer(whd_driver, &buffer, out_length); - CHECK_IOCTL_BUFFER(data); - memcpy(data, out_buffer, out_length); - - result = whd_cdc_send_ioctl(ifp, CDC_GET, ioctl, buffer, &response); - - /* it worked: copy the result to the output buffer */ - if (WHD_SUCCESS == result) { - data = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - *data = dtoh32(*data); - memcpy(out_buffer, data, out_length); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } + CHECK_IOCTL_BUFFER(whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)sizeof(*value) ) ); + CHECK_RETURN_UNSUPPORTED_OK(whd_proto_get_ioctl(ifp, ioctl, buffer, &response) ); + data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + *value = dtoh32(*(uint32_t *)data); - CHECK_RETURN(result); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_set_iovar_void(whd_interface_t ifp, const char *iovar) +whd_result_t whd_wifi_set_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, void *in_buffer, uint16_t in_buffer_length) { - whd_buffer_t buffer; - whd_driver_t whd_driver = ifp->whd_driver; + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver = ifp->whd_driver; - whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)0, iovar); + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, in_buffer_length); + CHECK_IOCTL_BUFFER(data); - return whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); -} + memcpy(data, in_buffer, in_buffer_length); -uint32_t whd_wifi_set_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t value) -{ - whd_buffer_t buffer; - uint32_t *data; - whd_driver_t whd_driver = ifp->whd_driver; + CHECK_RETURN(whd_proto_set_ioctl(ifp, ioctl, buffer, NULL) ); - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(value), iovar); - CHECK_IOCTL_BUFFER(data); - *data = htod32(value); - return whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); + return WHD_SUCCESS; } -uint32_t whd_wifi_get_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t *value) +whd_result_t whd_wifi_get_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, uint8_t *out_buffer, uint16_t out_length) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver = ifp->whd_driver; - uint8_t *data = NULL; + whd_buffer_t buffer; + uint32_t *data; + whd_buffer_t response; + whd_result_t result; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + data = (uint32_t *)whd_proto_get_ioctl_buffer(whd_driver, &buffer, out_length); + CHECK_IOCTL_BUFFER(data); + memcpy(data, out_buffer, out_length); + + result = whd_proto_get_ioctl(ifp, ioctl, buffer, &response); + + /* it worked: copy the result to the output buffer */ + if (WHD_SUCCESS == result) + { + data = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + *data = dtoh32(*data); + memcpy(out_buffer, data, out_length); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + + CHECK_RETURN(result); + + return WHD_SUCCESS; +} - if (value == NULL) - return WHD_BADARG; +whd_result_t whd_wifi_set_iovar_void(whd_interface_t ifp, const char *iovar) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver = ifp->whd_driver; - CHECK_IOCTL_BUFFER(whd_cdc_get_iovar_buffer(whd_driver, &buffer, 4, iovar)); - CHECK_RETURN_UNSUPPORTED_OK(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - *value = dtoh32(*(uint32_t *)data); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)0, iovar); - return WHD_SUCCESS; + return whd_proto_set_iovar(ifp, buffer, NULL); } -uint32_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *in_buffer, uint16_t in_buffer_length) +whd_result_t whd_wifi_set_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t value) { - return whd_wifi_set_iovar_buffers(ifp, iovar, (const void **)&in_buffer, (const uint16_t *)&in_buffer_length, 1); + whd_buffer_t buffer; + uint32_t *data; + whd_driver_t whd_driver = ifp->whd_driver; + + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)sizeof(value), iovar); + CHECK_IOCTL_BUFFER(data); + *data = htod32(value); + return whd_proto_set_iovar(ifp, buffer, NULL); } -uint32_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar_name, uint8_t *out_buffer, - uint16_t out_length) +whd_result_t whd_wifi_get_iovar_value(whd_interface_t ifp, const char *iovar, uint32_t *value) { - uint32_t *data; - whd_buffer_t buffer; - whd_buffer_t response; - whd_result_t result; - whd_driver_t whd_driver = ifp->whd_driver; - - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)out_length, iovar_name); - CHECK_IOCTL_BUFFER(data); - - result = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver = ifp->whd_driver; + uint8_t *data = NULL; + + if (value == NULL) + return WHD_BADARG; + + CHECK_IOCTL_BUFFER(whd_proto_get_iovar_buffer(whd_driver, &buffer, 4, iovar) ); + CHECK_RETURN_UNSUPPORTED_OK(whd_proto_get_iovar(ifp, buffer, &response) ); + data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + *value = dtoh32(*(uint32_t *)data); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; +} - /* it worked: copy the result to the output buffer */ - if (WHD_SUCCESS == result) { - data = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - *data = dtoh32(*data); - memcpy(out_buffer, data, out_length); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } +whd_result_t whd_wifi_set_iovar_buffer(whd_interface_t ifp, const char *iovar, void *in_buffer, uint16_t in_buffer_length) +{ + return whd_wifi_set_iovar_buffers(ifp, iovar, (const void **)&in_buffer, (const uint16_t *)&in_buffer_length, 1); +} - return result; +whd_result_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar_name, uint8_t *out_buffer, + uint16_t out_length) +{ + uint32_t *data; + whd_buffer_t buffer; + whd_buffer_t response; + whd_result_t result; + whd_driver_t whd_driver = ifp->whd_driver; + + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)out_length, iovar_name); + CHECK_IOCTL_BUFFER(data); + + result = whd_proto_get_iovar(ifp, buffer, &response); + + /* it worked: copy the result to the output buffer */ + if (WHD_SUCCESS == result) + { + data = (uint32_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + *data = dtoh32(*data); + memcpy(out_buffer, data, out_length); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } + + return result; } /* @@ -3008,235 +4531,294 @@ uint32_t whd_wifi_get_iovar_buffer(whd_interface_t ifp, const char *iovar_name, static whd_result_t whd_iovar_mkbuf(const char *name, char *data, uint32_t datalen, char *iovar_buf, uint16_t buflen) { - uint32_t iovar_len; + uint32_t iovar_len; - iovar_len = strlen(name) + 1; + iovar_len = strlen(name) + 1; - /* check for overflow */ - if ((iovar_len + datalen) > buflen) { - return WHD_BADARG; - } + /* check for overflow */ + if ( (iovar_len + datalen) > buflen ) + { + return WHD_BADARG; + } - /* copy data to the buffer past the end of the iovar name string */ - if (datalen > 0) - memmove(&iovar_buf[iovar_len], data, datalen); + /* copy data to the buffer past the end of the iovar name string */ + if (datalen > 0) { + memmove(&iovar_buf[iovar_len], data, datalen); + } - /* copy the name to the beginning of the buffer */ - strncpy(iovar_buf, name, iovar_len); + /* copy the name to the beginning of the buffer */ + strcpy(iovar_buf, name); - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_result_t whd_wifi_get_iovar_buffer_with_param(whd_interface_t ifp, const char *iovar_name, void *param, - uint32_t paramlen, uint8_t *out_buffer, uint32_t out_length) + uint32_t paramlen, uint8_t *out_buffer, uint32_t out_length) { - uint32_t *data; - whd_buffer_t buffer; - whd_buffer_t response; - whd_result_t result; - whd_driver_t whd_driver; + uint32_t *data; + whd_buffer_t buffer; + whd_buffer_t response; + whd_result_t result; + whd_driver_t whd_driver; - if (!ifp || !iovar_name || !param || !out_buffer) { - WPRINT_WHD_ERROR(("Invalid param in func %s at line %d \n", - __func__, __LINE__)); - return WHD_WLAN_BADARG; - } + if (!ifp || !iovar_name || !param || !out_buffer) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", + __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } - whd_driver = (whd_driver_t)ifp->whd_driver; + whd_driver = (whd_driver_t)ifp->whd_driver; - /* Format the input string */ - result = whd_iovar_mkbuf(iovar_name, param, paramlen, (char *)out_buffer, (uint16_t)out_length); - if (result != WHD_SUCCESS) - return result; + /* Format the input string */ + result = whd_iovar_mkbuf(iovar_name, param, paramlen, (char *)out_buffer, (uint16_t)out_length); + if (result != WHD_SUCCESS) + return result; - data = whd_cdc_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)out_length); + data = whd_proto_get_ioctl_buffer(whd_driver, &buffer, (uint16_t)out_length); - if (data == NULL) - return WHD_WLAN_NOMEM; + if (data == NULL) + return WHD_WLAN_NOMEM; - memcpy(data, out_buffer, out_length); + memcpy(data, out_buffer, out_length); - result = (whd_result_t)whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_VAR, buffer, &response); + result = (whd_result_t)whd_proto_get_ioctl(ifp, WLC_GET_VAR, buffer, &response); - if (result == WHD_SUCCESS) { - memcpy(out_buffer, whd_buffer_get_current_piece_data_pointer(whd_driver, response), - (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), out_length)); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - } + if (result == WHD_SUCCESS) + { + memcpy(out_buffer, whd_buffer_get_current_piece_data_pointer(whd_driver, response), + (size_t)MIN_OF(whd_buffer_get_current_piece_size(whd_driver, response), out_length) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + } - return result; + return result; } -uint32_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, - const uint16_t *lengths, const uint8_t num_buffers) +whd_result_t whd_wifi_set_iovar_buffers(whd_interface_t ifp, const char *iovar, const void **in_buffers, + const uint16_t *lengths, const uint8_t num_buffers) { - whd_buffer_t buffer; - uint32_t *data; - int tot_in_buffer_length = 0; - uint8_t buffer_num = 0; - whd_driver_t whd_driver = ifp->whd_driver; - - /* get total length of all buffers: they will be copied into memory one after the other. */ - for (; buffer_num < num_buffers; buffer_num++) { - tot_in_buffer_length += lengths[buffer_num]; - } - - /* get a valid buffer */ - data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)tot_in_buffer_length, iovar); - CHECK_IOCTL_BUFFER(data); - - /* copy all data into buffer */ - for (buffer_num = 0; buffer_num < num_buffers; buffer_num++) { - memcpy(data, in_buffers[buffer_num], lengths[buffer_num]); - data += lengths[buffer_num]; - } - - /* send iovar */ - return whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); + whd_buffer_t buffer; + uint32_t *data; + int tot_in_buffer_length = 0; + uint8_t buffer_num = 0; + whd_driver_t whd_driver = ifp->whd_driver; + + /* get total length of all buffers: they will be copied into memory one after the other. */ + for (; buffer_num < num_buffers; buffer_num++) + { + tot_in_buffer_length += lengths[buffer_num]; + } + + /* get a valid buffer */ + data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)tot_in_buffer_length, iovar); + CHECK_IOCTL_BUFFER(data); + + /* copy all data into buffer */ + for (buffer_num = 0; buffer_num < num_buffers; buffer_num++) + { + memcpy(data, in_buffers[buffer_num], lengths[buffer_num]); + data += lengths[buffer_num]; + } + + /* send iovar */ + return whd_proto_set_iovar(ifp, buffer, NULL); } -uint32_t whd_wifi_get_clm_version(whd_interface_t ifp, char *version, uint8_t length) +whd_result_t whd_wifi_get_clm_version(whd_interface_t ifp, char *version, uint8_t length) { - whd_result_t result; + whd_result_t result; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - if (version == NULL) - return WHD_BADARG; + if (version == NULL) + return WHD_BADARG; - version[0] = '\0'; + version[0] = '\0'; - result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_CLMVER, (uint8_t *)version, length); - if ((result == WHD_SUCCESS) && version[0]) { - uint8_t version_length; - char *p; + result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_CLMVER, (uint8_t *)version, length); + if ( (result == WHD_SUCCESS) && version[0] ) + { + uint8_t version_length; + char *p; - version_length = strlen(version); + version_length = strlen(version); /* -2 because \0 termination needs a char and strlen doesn't include length of \0 */ if (version_length > length - 2) version_length = length - 2; version[version_length + 1] = '\0'; - /* Replace all newline/linefeed characters with space character */ - p = version; - while ((p = strchr(p, '\n')) != NULL) { - *p = ' '; - } - } + /* Replace all newline/linefeed characters with space character */ + p = version; + while ( (p = strchr(p, '\n') ) != NULL ) + { + *p = ' '; + } + } - CHECK_RETURN(result); - return WHD_SUCCESS; + CHECK_RETURN(result); + return WHD_SUCCESS; } -uint32_t whd_wifi_get_wifi_version(whd_interface_t ifp, char *buf, uint8_t length) +whd_result_t whd_wifi_get_wifi_version(whd_interface_t ifp, char *buf, uint8_t length) { - whd_result_t result; - uint8_t ver_len; + whd_result_t result; + uint8_t ver_len; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - if (buf == NULL) - return WHD_BADARG; + if (buf == NULL) + return WHD_BADARG; - result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_VERSION, (uint8_t *)buf, length); + result = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_VERSION, (uint8_t *)buf, length); - ver_len = strlen(buf); + ver_len = strlen(buf); - if (ver_len > length - 2) - ver_len = length - 2; + if (ver_len > length - 2) + ver_len = length - 2; - if ((ver_len > 1) && (buf[ver_len + 1] == '\n')) { - buf[ver_len + 1] = '\0'; - } + if ( (ver_len > 1) && (buf[ver_len + 1] == '\n') ) + { + buf[ver_len + 1] = '\0'; + } - CHECK_RETURN(result); - return WHD_SUCCESS; + CHECK_RETURN(result); + return WHD_SUCCESS; } -uint32_t whd_network_get_ifidx_from_ifp(whd_interface_t ifp, uint8_t *ifidx) +whd_result_t whd_network_get_ifidx_from_ifp(whd_interface_t ifp, uint8_t *ifidx) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - if (!ifidx) - return WHD_BADARG; + if (!ifidx) + return WHD_BADARG; - *ifidx = ifp->ifidx; + *ifidx = ifp->ifidx; - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_network_get_bsscfgidx_from_ifp(whd_interface_t ifp, uint8_t *bsscfgidx) +whd_result_t whd_network_get_bsscfgidx_from_ifp(whd_interface_t ifp, uint8_t *bsscfgidx) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - if (!bsscfgidx) - return WHD_BADARG; + if (!bsscfgidx) + return WHD_BADARG; - *bsscfgidx = ifp->bsscfgidx; + *bsscfgidx = ifp->bsscfgidx; - return WHD_SUCCESS; + return WHD_SUCCESS; } -uint32_t whd_wifi_ap_set_beacon_interval(whd_interface_t ifp, uint16_t interval) +whd_result_t whd_wifi_ap_set_beacon_interval(whd_interface_t ifp, uint16_t interval) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_BCNPRD, interval)); - return WHD_SUCCESS; + CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_BCNPRD, interval) ); + return WHD_SUCCESS; } -uint32_t whd_wifi_ap_set_dtim_interval(whd_interface_t ifp, uint16_t interval) +whd_result_t whd_wifi_ap_set_dtim_interval(whd_interface_t ifp, uint16_t interval) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_DTIMPRD, interval)); - return WHD_SUCCESS; + CHECK_RETURN(whd_wifi_set_ioctl_value(ifp, WLC_SET_DTIMPRD, interval) ); + return WHD_SUCCESS; } -uint32_t whd_wifi_get_bss_info(whd_interface_t ifp, wl_bss_info_t *bi) +whd_result_t whd_wifi_get_bss_info(whd_interface_t ifp, wl_bss_info_t *bi) { - whd_buffer_t buffer, response; - uint32_t result; - uint8_t *data; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - CHECK_DRIVER_NULL(whd_driver); + whd_buffer_t buffer, response; + uint32_t result; + uint8_t *data; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if (bi == NULL) + return WHD_BADARG; + + if (whd_proto_get_ioctl_buffer(whd_driver, &buffer, WLC_IOCTL_SMLEN) == NULL) + { + WPRINT_WHD_INFO( ("%s: Unable to malloc WLC_GET_BSS_INFO buffer\n", __FUNCTION__) ); + return WHD_SUCCESS; + } + result = whd_proto_get_ioctl(ifp, WLC_GET_BSS_INFO, buffer, &response); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_INFO( ("%s: WLC_GET_BSS_INFO Failed\n", __FUNCTION__) ); + return result; + } + data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy(bi, data + 4, sizeof(wl_bss_info_t) ); + + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + + return WHD_SUCCESS; +} - if (bi == NULL) - return WHD_BADARG; +whd_result_t whd_wifi_set_coex_config(whd_interface_t ifp, whd_coex_config_t *coex_config) +{ + CHECK_IFP_NULL(ifp); - if (whd_cdc_get_ioctl_buffer(whd_driver, &buffer, WLC_IOCTL_SMLEN) == NULL) { - WPRINT_WHD_INFO(("%s: Unable to malloc WLC_GET_BSS_INFO buffer\n", __FUNCTION__)); - return WHD_SUCCESS; - } - result = whd_cdc_send_ioctl(ifp, CDC_GET, WLC_GET_BSS_INFO, buffer, &response); - if (result != WHD_SUCCESS) { - WPRINT_WHD_INFO(("%s: WLC_GET_BSS_INFO Failed\n", __FUNCTION__)); - return result; - } - data = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(data, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy(bi, data + 4, sizeof(wl_bss_info_t)); + if (coex_config == NULL) + return WHD_BADARG; - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); + return whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_BTC_LESCAN_PARAMS, &coex_config->le_scan_params, + sizeof(whd_btc_lescan_params_t) ); +} - return WHD_SUCCESS; +whd_result_t whd_wifi_set_auth_status(whd_interface_t ifp, whd_auth_req_status_t *params) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver; + whd_auth_req_status_t *auth_status; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + CHECK_DRIVER_NULL(whd_driver); + + if (params == NULL) + { + WPRINT_WHD_ERROR( ("Invalid param in func %s at line %d \n", __func__, __LINE__) ); + return WHD_WLAN_BADARG; + } + + auth_status = (whd_auth_req_status_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(whd_auth_req_status_t), + IOVAR_STR_AUTH_STATUS); + CHECK_IOCTL_BUFFER (auth_status); + memcpy(auth_status, params, sizeof(whd_auth_req_status_t) ); + if (params->flags == DOT11_SC_SUCCESS) + { + auth_status->flags = WL_EXTAUTH_SUCCESS; + } + else + { + auth_status->flags = WL_EXTAUTH_FAIL; + } + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } -uint32_t whd_wifi_set_coex_config(whd_interface_t ifp, whd_coex_config_t *coex_config) +whd_result_t whd_wifi_get_fwcap(whd_interface_t ifp, uint32_t *value) { - CHECK_IFP_NULL(ifp); + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); - if (coex_config == NULL) - return WHD_BADARG; + whd_driver = ifp->whd_driver; - return whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_BTC_LESCAN_PARAMS, &coex_config->le_scan_params, - sizeof(whd_btc_lescan_params_t)); + CHECK_DRIVER_NULL(whd_driver); + + *value = whd_driver->chip_info.fwcap_flags; + return WHD_SUCCESS; } /* @@ -3250,116 +4832,120 @@ uint32_t whd_wifi_set_coex_config(whd_interface_t ifp, whd_coex_config_t *coex_c */ whd_result_t whd_arp_version(whd_interface_t ifp, uint32_t *value) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_VERSION, value); + return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_VERSION, value); } whd_result_t whd_arp_peerage_get(whd_interface_t ifp, uint32_t *value) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, value); + return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, value); } whd_result_t whd_arp_peerage_set(whd_interface_t ifp, uint32_t value) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_set_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, value); + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, value); } whd_result_t whd_arp_arpoe_get(whd_interface_t ifp, uint32_t *value) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARPOE, value); + return whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARPOE, value); } whd_result_t whd_arp_arpoe_set(whd_interface_t ifp, uint32_t value) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_set_iovar_value(ifp, IOVAR_STR_ARPOE, value); + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_ARPOE, value); } whd_result_t whd_arp_cache_clear(whd_interface_t ifp) { - whd_result_t whd_ret; - CHECK_IFP_NULL(ifp); + whd_result_t whd_ret; + CHECK_IFP_NULL(ifp); - whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_TABLE_CLEAR); - return whd_ret; + whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_TABLE_CLEAR); + return whd_ret; } whd_result_t whd_arp_features_get(whd_interface_t ifp, uint32_t *features) { - if ((ifp == NULL) || (features == NULL)) { - return WHD_BADARG; - } - - if (whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)features, sizeof(uint32_t)) != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_ol for features\n", __func__)); - return WHD_IOCTL_FAIL; - } - - return WHD_SUCCESS; + if ( (ifp == NULL) || (features == NULL) ) + { + return WHD_BADARG; + } + + if (whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)features, sizeof(uint32_t) ) != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_ol for features\n", __func__) ); + return WHD_IOCTL_FAIL; + } + + return WHD_SUCCESS; } whd_result_t whd_arp_features_set(whd_interface_t ifp, uint32_t features) { - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - return whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)&features, sizeof(features)); + return whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)&features, sizeof(features) ); } whd_result_t whd_arp_features_print(uint32_t features, const char *title) { if (title != NULL) { - WPRINT_MACRO(("%s\n", title)); - } - WPRINT_MACRO((" features : 0x%x\n", (int)features)); - WPRINT_MACRO((" agent_enabled: (0x%x) %s\n", (int)(features & ARP_OL_AGENT), - (features & ARP_OL_AGENT) ? "Enabled" : " disabled")); - WPRINT_MACRO((" snoop_enabled: (0x%x) %s\n", (int)(features & ARP_OL_SNOOP), - (features & ARP_OL_SNOOP) ? "Enabled" : " disabled")); - WPRINT_MACRO((" host_auto_reply_enabled: (0x%x) %s\n", (int)(features & ARP_OL_HOST_AUTO_REPLY), - (features & ARP_OL_HOST_AUTO_REPLY) ? "Enabled" : " disabled")); - WPRINT_MACRO((" peer_auto_reply_enabled: (0x%x) %s\n", (int)(features & ARP_OL_PEER_AUTO_REPLY), - (features & ARP_OL_PEER_AUTO_REPLY) ? "Enabled" : " disabled")); - - return WHD_SUCCESS; + WPRINT_INFO(("%s\n", title)); + } + WPRINT_INFO((" features : 0x%x\n", (int)features)); + WPRINT_INFO((" agent_enabled: (0x%x) %s\n", (int)(features & ARP_OL_AGENT), + (features & ARP_OL_AGENT) ? "Enabled" : " disabled")); + WPRINT_INFO((" snoop_enabled: (0x%x) %s\n", (int)(features & ARP_OL_SNOOP), + (features & ARP_OL_SNOOP) ? "Enabled" : " disabled")); + WPRINT_INFO((" host_auto_reply_enabled: (0x%x) %s\n", (int)(features & ARP_OL_HOST_AUTO_REPLY), + (features & ARP_OL_HOST_AUTO_REPLY) ? "Enabled" : " disabled")); + WPRINT_INFO((" peer_auto_reply_enabled: (0x%x) %s\n", (int)(features & ARP_OL_PEER_AUTO_REPLY), + (features & ARP_OL_PEER_AUTO_REPLY) ? "Enabled" : " disabled")); + + return WHD_SUCCESS; } whd_result_t whd_arp_hostip_list_add(whd_interface_t ifp, uint32_t *host_ipv4_list, uint32_t count) { - uint32_t filled = 0; - uint32_t current_ipv4_list[ARP_MULTIHOMING_MAX]; - CHECK_IFP_NULL(ifp); - - whd_result_t whd_ret = WHD_SUCCESS; - if (host_ipv4_list == NULL) { - WPRINT_WHD_ERROR(("%s() BAD ARGS ifp:%p host_ipv4_list:%u count %d\n", __func__, ifp, (int)host_ipv4_list, - (int)count)); - return WHD_BADARG; - } - /* check if unique */ - whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, current_ipv4_list, &filled); - if ((whd_ret == WHD_SUCCESS) && (filled > 0)) { - uint32_t curr_index; - uint32_t new_index; + uint32_t filled = 0; + uint32_t current_ipv4_list[ARP_MULTIHOMING_MAX]; + CHECK_IFP_NULL(ifp); + + whd_result_t whd_ret = WHD_SUCCESS; + if (host_ipv4_list == NULL) + { + WPRINT_WHD_ERROR( ("%s() BAD ARGS ifp:%p host_ipv4_list:%u count %d\n", __func__, ifp, (int)host_ipv4_list, + (int)count) ); + return WHD_BADARG; + } + /* check if unique */ + whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, current_ipv4_list, &filled); + if ( (whd_ret == WHD_SUCCESS) && (filled > 0) ) + { + uint32_t curr_index; + uint32_t new_index; for (curr_index = 0; curr_index < filled; curr_index++) { for (new_index = 0; new_index < count; new_index++) { - WPRINT_WHD_DEBUG(("%s() curr:%u of %u curr:0x%x new:%u of %u:0x%x\n", __func__, curr_index, - filled, current_ipv4_list[curr_index], - new_index, count, host_ipv4_list[new_index])); + WPRINT_WHD_DEBUG(("%s() curr:%" PRIu32 " of %" PRIu32 " curr:0x%" PRIx32 " new:%" PRIu32" of %" PRIu32 ":0x%" PRIx32 "\n", __func__, curr_index, + filled, current_ipv4_list[curr_index], + new_index, count, host_ipv4_list[new_index])); if (current_ipv4_list[curr_index] == host_ipv4_list[new_index]) { /* decrement count */ count--; if (new_index < count) { /* copy next one down */ - WPRINT_WHD_DEBUG(("move %u (+1) of %u\n", new_index, count)); + WPRINT_WHD_DEBUG(("move %" PRIu32 " (+1) of %" PRIu32 " \n", new_index, count)); host_ipv4_list[new_index] = host_ipv4_list[new_index + 1]; } break; @@ -3373,55 +4959,67 @@ whd_result_t whd_arp_hostip_list_add(whd_interface_t ifp, uint32_t *host_ipv4_li if (count > 0) { uint32_t new_index; - WPRINT_WHD_DEBUG(("%s() whd_wifi_set_iovar_buffer( %p, %x)\n", __func__, host_ipv4_list, count)); + WPRINT_WHD_DEBUG(("%s() whd_wifi_set_iovar_buffer( %p, %" PRIx32 ")\n", __func__, host_ipv4_list, count)); for (new_index = 0; new_index < count; new_index++) { - WPRINT_WHD_DEBUG((" 0x%x\n", host_ipv4_list[new_index])); + WPRINT_WHD_DEBUG((" 0x%" PRIx32 "\n", host_ipv4_list[new_index])); } - whd_ret = whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_ARP_HOSTIP, host_ipv4_list, (count * sizeof(uint32_t))); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("Failed to set arp_hostip 0x%x error:%d\n", (int)host_ipv4_list[0], (int)whd_ret)); - } - } - return whd_ret; +#ifdef CYCFG_ULP_SUPPORT_ENABLED + CHECK_RETURN(whd_configure_wowl(ifp, WL_WOWL_ARPOFFLOAD)); + whd_ret = whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_WOWL_ARP_HOST_IP, host_ipv4_list, (count * sizeof(uint32_t) ) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to set arp_hostip 0x%x error:%d\n", (int)host_ipv4_list[0], (int)whd_ret) ); + } +#endif + whd_ret = whd_wifi_set_iovar_buffer(ifp, IOVAR_STR_ARP_HOSTIP, host_ipv4_list, (count * sizeof(uint32_t) ) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("Failed to set arp_hostip 0x%x error:%d\n", (int)host_ipv4_list[0], (int)whd_ret) ); + } + } + return whd_ret; } whd_result_t whd_arp_hostip_list_add_string(whd_interface_t ifp, const char *ip_addr) { - /* convert string to uint32_t */ - uint32_t addr; - CHECK_IFP_NULL(ifp); + /* convert string to uint32_t */ + uint32_t addr; + CHECK_IFP_NULL(ifp); - whd_str_to_ip(ip_addr, strlen(ip_addr), &addr); + whd_str_to_ip(ip_addr, strlen(ip_addr), &addr); - return whd_arp_hostip_list_add(ifp, &addr, 1); + return whd_arp_hostip_list_add(ifp, &addr, 1); } whd_result_t whd_arp_hostip_list_clear_id(whd_interface_t ifp, uint32_t ipv4_addr) { - whd_result_t whd_ret; - uint32_t filled; - uint32_t host_ipv4_list[ARP_MULTIHOMING_MAX]; - CHECK_IFP_NULL(ifp); - - if (ipv4_addr == 0x00l) { - return WHD_BADARG; - } - memset(host_ipv4_list, 0x00, sizeof(host_ipv4_list)); - whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, host_ipv4_list, &filled); - if ((whd_ret == WHD_SUCCESS) && (filled > 0)) { - uint32_t index; - - /* clear the list in the WLAN processor */ - whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_HOSTIP_CLEAR); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%d %s() whd_wifi_set_iovar_void() failed:%d\n", __LINE__, __func__, (int)whd_ret)); - return whd_ret; - } + whd_result_t whd_ret; + uint32_t filled; + uint32_t host_ipv4_list[ARP_MULTIHOMING_MAX]; + CHECK_IFP_NULL(ifp); + + if (ipv4_addr == 0x00l) + { + return WHD_BADARG; + } + memset(host_ipv4_list, 0x00, sizeof(host_ipv4_list) ); + whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, host_ipv4_list, &filled); + if ( (whd_ret == WHD_SUCCESS) && (filled > 0) ) + { + uint32_t index; + + /* clear the list in the WLAN processor */ + whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_HOSTIP_CLEAR); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%d %s() whd_wifi_set_iovar_void() failed:%d\n", __LINE__, __func__, (int)whd_ret) ); + return whd_ret; + } /* remove the one address from the list and re-write arp_hostip list */ for (index = 0; index < filled; index++) { - WPRINT_WHD_DEBUG(("%d %s() drop() 0x%x == 0x%x ? %s\n", __LINE__, __func__, host_ipv4_list[index], - ipv4_addr, (host_ipv4_list[index] == ipv4_addr) ? "DROP" : "")); + WPRINT_WHD_DEBUG(("%d %s() drop() 0x%" PRIx32 " == 0x%" PRIx32 " ? %s\n", __LINE__, __func__, host_ipv4_list[index], + ipv4_addr, (host_ipv4_list[index] == ipv4_addr) ? "DROP" : "")); if (host_ipv4_list[index] == ipv4_addr) { uint32_t drop; /* drop this one, move rest up */ @@ -3445,182 +5043,197 @@ whd_result_t whd_arp_hostip_list_clear_id(whd_interface_t ifp, uint32_t ipv4_add whd_result_t whd_arp_hostip_list_clear_id_string(whd_interface_t ifp, const char *ip_addr) { - /* convert string to uint32_t */ - uint32_t addr; - CHECK_IFP_NULL(ifp); + /* convert string to uint32_t */ + uint32_t addr; + CHECK_IFP_NULL(ifp); - whd_str_to_ip(ip_addr, strlen(ip_addr), &addr); + whd_str_to_ip(ip_addr, strlen(ip_addr), &addr); - return whd_arp_hostip_list_clear_id(ifp, addr); + return whd_arp_hostip_list_clear_id(ifp, addr); } whd_result_t whd_arp_hostip_list_clear(whd_interface_t ifp) { - CHECK_IFP_NULL(ifp); - return whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_HOSTIP_CLEAR); + CHECK_IFP_NULL(ifp); + return whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_HOSTIP_CLEAR); } whd_result_t whd_arp_hostip_list_get(whd_interface_t ifp, uint32_t count, uint32_t *host_ipv4_list, uint32_t *filled) { - whd_result_t whd_ret = WHD_SUCCESS; - uint32_t temp[ARP_MULTIHOMING_MAX]; - arp_ol_stats_t arp_stats; /* WL struct, not ours! */ - CHECK_IFP_NULL(ifp); - - if ((host_ipv4_list == NULL) || (filled == NULL)) { - return WHD_BADARG; - } - - /* set up the buffer to retrieve the stats data */ - memset(&arp_stats, 0x00, sizeof(arp_ol_stats_t)); - whd_ret = whd_wifi_get_iovar_buffer(ifp, "arp_stats", (uint8_t *)&arp_stats, sizeof(arp_ol_stats_t)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_stats\n", __func__)); - return WHD_IOCTL_FAIL; - } - - *filled = 0; - whd_ret = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_HOSTIP, (uint8_t *)&temp, sizeof(temp)); - /* transfer the info */ - if (whd_ret == WHD_SUCCESS) { - uint32_t index; - for (index = 0; (index < count) && (index < arp_stats.host_ip_entries); index++) { - /* only IPv4 !!! */ - if (htod32(temp[index]) != 0L) { - host_ipv4_list[*filled] = temp[index]; - *filled = *filled + 1; - } - } - } - return whd_ret; + whd_result_t whd_ret = WHD_SUCCESS; + uint32_t temp[ARP_MULTIHOMING_MAX]; + arp_ol_stats_t arp_stats; /* WL struct, not ours! */ + CHECK_IFP_NULL(ifp); + + if ( (host_ipv4_list == NULL) || (filled == NULL) ) + { + return WHD_BADARG; + } + + /* set up the buffer to retrieve the stats data */ + memset(&arp_stats, 0x00, sizeof(arp_ol_stats_t) ); + whd_ret = whd_wifi_get_iovar_buffer(ifp, "arp_stats", (uint8_t *)&arp_stats, sizeof(arp_ol_stats_t) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_stats\n", __func__) ); + return WHD_IOCTL_FAIL; + } + + *filled = 0; + whd_ret = whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_HOSTIP, (uint8_t *)&temp, sizeof(temp) ); + /* transfer the info */ + if (whd_ret == WHD_SUCCESS) + { + uint32_t index; + for (index = 0; (index < count) && (index < arp_stats.host_ip_entries); index++) + { + /* only IPv4 !!! */ + if (htod32(temp[index]) != 0L) + { + host_ipv4_list[*filled] = temp[index]; + *filled = *filled + 1; + } + } + } + return whd_ret; } whd_result_t whd_arp_stats_clear(whd_interface_t ifp) { - whd_result_t whd_ret; - CHECK_IFP_NULL(ifp); - whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_STATS_CLEAR); - return whd_ret; + whd_result_t whd_ret; + CHECK_IFP_NULL(ifp); + whd_ret = whd_wifi_set_iovar_void(ifp, IOVAR_STR_ARP_STATS_CLEAR); + return whd_ret; } whd_result_t whd_arp_stats_get(whd_interface_t ifp, whd_arp_stats_t *arp_stats) { - whd_result_t whd_ret; - uint32_t filled; - static whd_arp_stats_t arp_stats_test; /* read twice to make sure we match */ - CHECK_IFP_NULL(ifp); + whd_result_t whd_ret; + uint32_t filled; + static whd_arp_stats_t arp_stats_test; /* read twice to make sure we match */ + CHECK_IFP_NULL(ifp); - if (arp_stats == NULL) { - return WHD_BADARG; - } + if (arp_stats == NULL) + { + return WHD_BADARG; + } /* set up the buffer to retrieve the data */ memcpy(&arp_stats_test, arp_stats, sizeof(whd_arp_stats_t)); memset(arp_stats, 0xFF, sizeof(whd_arp_stats_t)); - /* read multiple times to make sure we got valid data */ - do { - /* get them until they match */ - whd_ret = - whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_STATS, (uint8_t *)&arp_stats->stats, - sizeof(arp_ol_stats_t)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_stats\n", __func__)); - return WHD_IOCTL_FAIL; - } - /* get all feature info in one call */ - whd_ret = - whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)&arp_stats->features_enabled, - sizeof(arp_stats->features_enabled)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_ol\n", __func__)); - return WHD_IOCTL_FAIL; - } - whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_VERSION, &(arp_stats->version)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_version\n", __func__)); - return WHD_IOCTL_FAIL; - } - whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, &(arp_stats->peerage)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get arp_peerage\n", __func__)); - return WHD_IOCTL_FAIL; - } - whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARPOE, &(arp_stats->arpoe)); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get some settings\n", __func__)); - return WHD_IOCTL_FAIL; - } - - /* set endian correctly */ - arp_stats->stats.host_ip_entries = dtoh32(arp_stats->stats.host_ip_entries); - arp_stats->stats.host_ip_overflow = dtoh32(arp_stats->stats.host_ip_overflow); - arp_stats->stats.arp_table_entries = dtoh32(arp_stats->stats.arp_table_entries); - arp_stats->stats.arp_table_overflow = dtoh32(arp_stats->stats.arp_table_overflow); - arp_stats->stats.host_request = dtoh32(arp_stats->stats.host_request); - arp_stats->stats.host_reply = dtoh32(arp_stats->stats.host_reply); - arp_stats->stats.host_service = dtoh32(arp_stats->stats.host_service); - arp_stats->stats.peer_request = dtoh32(arp_stats->stats.peer_request); - arp_stats->stats.peer_request_drop = dtoh32(arp_stats->stats.peer_request_drop); - arp_stats->stats.peer_reply = dtoh32(arp_stats->stats.peer_reply); - arp_stats->stats.peer_reply_drop = dtoh32(arp_stats->stats.peer_reply_drop); - arp_stats->stats.peer_service = dtoh32(arp_stats->stats.peer_service); - - whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, arp_stats->host_ip_list, &filled); - if (whd_ret != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s() failed to get host_ip_list\n", __func__)); - return WHD_IOCTL_FAIL; - } - - if (memcmp(&arp_stats_test, arp_stats, sizeof(whd_arp_stats_t)) == 0) { - break; - } + /* read multiple times to make sure we got valid data */ + do + { + /* get them until they match */ + whd_ret = + whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_STATS, (uint8_t *)&arp_stats->stats, + sizeof(arp_ol_stats_t) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_stats\n", __func__) ); + return WHD_IOCTL_FAIL; + } + /* get all feature info in one call */ + whd_ret = + whd_wifi_get_iovar_buffer(ifp, IOVAR_STR_ARP_OL, (uint8_t *)&arp_stats->features_enabled, + sizeof(arp_stats->features_enabled) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_ol\n", __func__) ); + return WHD_IOCTL_FAIL; + } + whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_VERSION, &(arp_stats->version) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_version\n", __func__) ); + return WHD_IOCTL_FAIL; + } + whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARP_PEERAGE, &(arp_stats->peerage) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get arp_peerage\n", __func__) ); + return WHD_IOCTL_FAIL; + } + whd_ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_ARPOE, &(arp_stats->arpoe) ); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get some settings\n", __func__) ); + return WHD_IOCTL_FAIL; + } + + /* set endian correctly */ + arp_stats->stats.host_ip_entries = dtoh32(arp_stats->stats.host_ip_entries); + arp_stats->stats.host_ip_overflow = dtoh32(arp_stats->stats.host_ip_overflow); + arp_stats->stats.arp_table_entries = dtoh32(arp_stats->stats.arp_table_entries); + arp_stats->stats.arp_table_overflow = dtoh32(arp_stats->stats.arp_table_overflow); + arp_stats->stats.host_request = dtoh32(arp_stats->stats.host_request); + arp_stats->stats.host_reply = dtoh32(arp_stats->stats.host_reply); + arp_stats->stats.host_service = dtoh32(arp_stats->stats.host_service); + arp_stats->stats.peer_request = dtoh32(arp_stats->stats.peer_request); + arp_stats->stats.peer_request_drop = dtoh32(arp_stats->stats.peer_request_drop); + arp_stats->stats.peer_reply = dtoh32(arp_stats->stats.peer_reply); + arp_stats->stats.peer_reply_drop = dtoh32(arp_stats->stats.peer_reply_drop); + arp_stats->stats.peer_service = dtoh32(arp_stats->stats.peer_service); + + whd_ret = whd_arp_hostip_list_get(ifp, ARP_MULTIHOMING_MAX, arp_stats->host_ip_list, &filled); + if (whd_ret != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s() failed to get host_ip_list\n", __func__) ); + return WHD_IOCTL_FAIL; + } + + if (memcmp(&arp_stats_test, arp_stats, sizeof(whd_arp_stats_t) ) == 0) + { + break; + } - memcpy(&arp_stats_test, arp_stats, sizeof(whd_arp_stats_t)); - } while (1); + memcpy(&arp_stats_test, arp_stats, sizeof(whd_arp_stats_t) ); + } while (1); - return whd_ret; + return whd_ret; } whd_result_t whd_arp_stats_print(whd_arp_stats_t *arp_stats, const char *title) { - uint32_t index; + uint32_t index; - if (arp_stats == NULL) { - return WHD_BADARG; - } + if (arp_stats == NULL) + { + return WHD_BADARG; + } if (title != NULL) { - WPRINT_MACRO(("%s\n", title)); - } - WPRINT_MACRO((" version: 0x%lx\n", (unsigned long int)arp_stats->version)); - WPRINT_MACRO((" host_ip_entries: %d\n", (int)arp_stats->stats.host_ip_entries)); - WPRINT_MACRO((" host_ip_overflow: %d\n", (int)arp_stats->stats.host_ip_overflow)); - WPRINT_MACRO((" arp_table_entries: %d\n", (int)arp_stats->stats.arp_table_entries)); - WPRINT_MACRO((" arp_table_overflow: %d\n", (int)arp_stats->stats.arp_table_overflow)); - WPRINT_MACRO((" host_request: %d\n", (int)arp_stats->stats.host_request)); - WPRINT_MACRO((" host_reply: %d\n", (int)arp_stats->stats.host_reply)); - WPRINT_MACRO((" host_service: %d\n", (int)arp_stats->stats.host_service)); - WPRINT_MACRO((" peer_request: %d\n", (int)arp_stats->stats.peer_request)); - WPRINT_MACRO((" peer_request_drop: %d\n", (int)arp_stats->stats.peer_request_drop)); - WPRINT_MACRO((" peer_reply: %d\n", (int)arp_stats->stats.peer_reply)); - WPRINT_MACRO((" peer_reply_drop: %d\n", (int)arp_stats->stats.peer_reply_drop)); - WPRINT_MACRO((" peer_service: %d\n", (int)arp_stats->stats.peer_service)); - WPRINT_MACRO((" peerage: %d\n", (int)arp_stats->peerage)); - WPRINT_MACRO((" arpoe: %d %s\n", (int)arp_stats->arpoe, - (arp_stats->arpoe != 0) ? "Enabled" : " disabled")); - - whd_arp_features_print(arp_stats->features_enabled, NULL); + WPRINT_INFO(("%s\n", title)); + } + WPRINT_INFO((" version: 0x%" PRIx32 "\n", arp_stats->version)); + WPRINT_INFO((" host_ip_entries: %d\n", (int)arp_stats->stats.host_ip_entries)); + WPRINT_INFO((" host_ip_overflow: %d\n", (int)arp_stats->stats.host_ip_overflow)); + WPRINT_INFO((" arp_table_entries: %d\n", (int)arp_stats->stats.arp_table_entries)); + WPRINT_INFO((" arp_table_overflow: %d\n", (int)arp_stats->stats.arp_table_overflow)); + WPRINT_INFO((" host_request: %d\n", (int)arp_stats->stats.host_request)); + WPRINT_INFO((" host_reply: %d\n", (int)arp_stats->stats.host_reply)); + WPRINT_INFO((" host_service: %d\n", (int)arp_stats->stats.host_service)); + WPRINT_INFO((" peer_request: %d\n", (int)arp_stats->stats.peer_request)); + WPRINT_INFO((" peer_request_drop: %d\n", (int)arp_stats->stats.peer_request_drop)); + WPRINT_INFO((" peer_reply: %d\n", (int)arp_stats->stats.peer_reply)); + WPRINT_INFO((" peer_reply_drop: %d\n", (int)arp_stats->stats.peer_reply_drop)); + WPRINT_INFO((" peer_service: %d\n", (int)arp_stats->stats.peer_service)); + WPRINT_INFO((" peerage: %d\n", (int)arp_stats->peerage)); + WPRINT_INFO((" arpoe: %d %s\n", (int)arp_stats->arpoe, + (arp_stats->arpoe != 0) ? "Enabled" : " disabled")); + + whd_arp_features_print(arp_stats->features_enabled, NULL); if (arp_stats->stats.host_ip_entries > 0) { - WPRINT_MACRO(("WLAN Device Host IP entries\n")); + WPRINT_INFO(("WLAN Device Host IP entries\n")); for (index = 0; index < arp_stats->stats.host_ip_entries; index++) { uint32_t ipv4_addr = arp_stats->host_ip_list[index]; char ipv4_string[32]; memset(ipv4_string, 0x00, sizeof(ipv4_string)); whd_ip4_to_string(&ipv4_addr, ipv4_string); - WPRINT_MACRO((" %d of %d IPV4: 0x%x %s\n", (int)index, (int)arp_stats->stats.host_ip_entries, - (int)arp_stats->host_ip_list[index], ipv4_string)); + WPRINT_INFO((" %d of %d IPV4: 0x%x %s\n", (int)index, (int)arp_stats->stats.host_ip_entries, + (int)arp_stats->host_ip_list[index], ipv4_string)); } } return WHD_SUCCESS; @@ -3629,222 +5242,223 @@ whd_result_t whd_arp_stats_print(whd_arp_stats_t *arp_stats, const char *title) whd_result_t whd_wifi_toggle_packet_filter(whd_interface_t ifp, uint8_t filter_id, whd_bool_t enable) { - whd_buffer_t buffer; - whd_driver_t whd_driver; - - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - wl_pkt_filter_enable_t *data = (wl_pkt_filter_enable_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, - sizeof(wl_pkt_filter_enable_t), - IOVAR_STR_PKT_FILTER_ENABLE); - CHECK_IOCTL_BUFFER(data); - data->id = (uint32_t)filter_id; - data->enable = (uint32_t)enable; - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); + whd_buffer_t buffer; + whd_driver_t whd_driver; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + wl_pkt_filter_enable_t *data = (wl_pkt_filter_enable_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(wl_pkt_filter_enable_t), + IOVAR_STR_PKT_FILTER_ENABLE); + CHECK_IOCTL_BUFFER(data); + data->id = (uint32_t)filter_id; + data->enable = (uint32_t)enable; + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } whd_result_t whd_pf_enable_packet_filter(whd_interface_t ifp, uint8_t filter_id) { - return whd_wifi_toggle_packet_filter(ifp, filter_id, WHD_TRUE); + return whd_wifi_toggle_packet_filter(ifp, filter_id, WHD_TRUE); } whd_result_t whd_pf_disable_packet_filter(whd_interface_t ifp, uint8_t filter_id) { - return whd_wifi_toggle_packet_filter(ifp, filter_id, WHD_FALSE); + return whd_wifi_toggle_packet_filter(ifp, filter_id, WHD_FALSE); } whd_result_t whd_pf_add_packet_filter(whd_interface_t ifp, const whd_packet_filter_t *settings) { - wl_pkt_filter_t *packet_filter; - whd_driver_t whd_driver; - whd_buffer_t buffer; - uint32_t buffer_length = - (uint32_t)((2 * (uint32_t)settings->mask_size) + WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); + wl_pkt_filter_t *packet_filter; + whd_driver_t whd_driver; + whd_buffer_t buffer; + uint32_t buffer_length = + (uint32_t)( (2 * (uint32_t)settings->mask_size) + WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN ); - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; - packet_filter = (wl_pkt_filter_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)buffer_length, - IOVAR_STR_PKT_FILTER_ADD); - CHECK_IOCTL_BUFFER(packet_filter); + packet_filter = (wl_pkt_filter_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)buffer_length, + IOVAR_STR_PKT_FILTER_ADD); + CHECK_IOCTL_BUFFER(packet_filter); - /* Copy filter entries */ - packet_filter->id = settings->id; - packet_filter->type = 0; - packet_filter->negate_match = settings->rule; - packet_filter->u.pattern.offset = (uint32_t)settings->offset; - packet_filter->u.pattern.size_bytes = settings->mask_size; + /* Copy filter entries */ + packet_filter->id = settings->id; + packet_filter->type = 0; + packet_filter->negate_match = settings->rule; + packet_filter->u.pattern.offset = (uint32_t)settings->offset; + packet_filter->u.pattern.size_bytes = settings->mask_size; - /* Copy mask */ - memcpy(packet_filter->u.pattern.mask_and_pattern, settings->mask, settings->mask_size); + /* Copy mask */ + memcpy(packet_filter->u.pattern.mask_and_pattern, settings->mask, settings->mask_size); - /* Copy filter pattern */ - memcpy(packet_filter->u.pattern.mask_and_pattern + settings->mask_size, settings->pattern, settings->mask_size); + /* Copy filter pattern */ + memcpy(packet_filter->u.pattern.mask_and_pattern + settings->mask_size, settings->pattern, settings->mask_size); - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } whd_result_t whd_pf_remove_packet_filter(whd_interface_t ifp, uint8_t filter_id) { - whd_buffer_t buffer; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + whd_buffer_t buffer; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; - uint32_t *data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(uint32_t), - IOVAR_STR_PKT_FILTER_DELETE); - CHECK_IOCTL_BUFFER(data); - *data = (uint32_t)filter_id; - RETURN_WITH_ASSERT(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL)); + uint32_t *data = (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(uint32_t), + IOVAR_STR_PKT_FILTER_DELETE); + CHECK_IOCTL_BUFFER(data); + *data = (uint32_t)filter_id; + RETURN_WITH_ASSERT(whd_proto_set_iovar(ifp, buffer, NULL) ); } whd_result_t whd_pf_get_packet_filter_stats(whd_interface_t ifp, uint8_t filter_id, whd_pkt_filter_stats_t *stats) { - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver; - uint8_t *pdata; + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver; + uint8_t *pdata; - CHECK_IFP_NULL(ifp); + CHECK_IFP_NULL(ifp); - whd_driver = ifp->whd_driver; + whd_driver = ifp->whd_driver; - uint32_t *data = - (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(uint32_t) + sizeof(wl_pkt_filter_stats_t), - IOVAR_STR_PKT_FILTER_STATS); - CHECK_IOCTL_BUFFER(data); + uint32_t *data = + (uint32_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(uint32_t) + sizeof(wl_pkt_filter_stats_t), + IOVAR_STR_PKT_FILTER_STATS); + CHECK_IOCTL_BUFFER(data); - memset(data, 0, sizeof(uint32_t) + sizeof(wl_pkt_filter_stats_t)); - *data = (uint32_t)filter_id; + memset(data, 0, sizeof(uint32_t) + sizeof(wl_pkt_filter_stats_t) ); + *data = (uint32_t)filter_id; - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((char *)stats, (char *)pdata, (sizeof(wl_pkt_filter_stats_t))); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX)); + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (char *)stats, (char *)pdata, (sizeof(wl_pkt_filter_stats_t) ) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX) ); - return WHD_SUCCESS; + return WHD_SUCCESS; } whd_result_t whd_wifi_clear_packet_filter_stats(whd_interface_t ifp, uint32_t filter_id) { - RETURN_WITH_ASSERT(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PKT_FILTER_CLEAR_STATS, (uint32_t)filter_id)); + RETURN_WITH_ASSERT(whd_wifi_set_iovar_value(ifp, IOVAR_STR_PKT_FILTER_CLEAR_STATS, (uint32_t)filter_id) ); } whd_result_t whd_pf_get_packet_filter_mask_and_pattern(whd_interface_t ifp, uint8_t filter_id, uint32_t max_size, uint8_t *mask, - uint8_t *pattern, uint32_t *size_out) + uint8_t *pattern, uint32_t *size_out) { - whd_bool_t enabled_list; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - for (enabled_list = WHD_FALSE; enabled_list <= WHD_TRUE; enabled_list++) { - - whd_buffer_t buffer; - whd_buffer_t response; - uint32_t *data; - wl_pkt_filter_list_t *filter_list; - wl_pkt_filter_t *filter_ptr; - uint32_t i; - wl_pkt_filter_t *in_filter; - - data = whd_cdc_get_iovar_buffer(whd_driver, &buffer, PACKET_FILTER_LIST_BUFFER_MAX_LEN, - IOVAR_STR_PKT_FILTER_LIST); - CHECK_IOCTL_BUFFER(data); - *data = (uint32_t)enabled_list; - - CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response)); - - filter_list = (wl_pkt_filter_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - filter_ptr = filter_list->filter; - for (i = 0; i < filter_list->num; i++) { - in_filter = filter_ptr; - - if (in_filter->id == filter_id) { - *size_out = MIN_OF(in_filter->u.pattern.size_bytes, max_size); - memcpy(mask, in_filter->u.pattern.mask_and_pattern, *size_out); - memcpy(pattern, in_filter->u.pattern.mask_and_pattern + in_filter->u.pattern.size_bytes, *size_out); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX)); - if (*size_out < in_filter->u.pattern.size_bytes) { - return WHD_PARTIAL_RESULTS; - } - return WHD_SUCCESS; - } - - /* Update WL filter pointer */ - filter_ptr = - (wl_pkt_filter_t *)((char *)filter_ptr + - (WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * in_filter->u.pattern.size_bytes)); - - /* WLAN returns word-aligned filter list */ - filter_ptr = (wl_pkt_filter_t *)ROUND_UP((unsigned long)filter_ptr, 4); - } - } - return WHD_FILTER_NOT_FOUND; + whd_bool_t enabled_list; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + for (enabled_list = WHD_FALSE; enabled_list <= WHD_TRUE; enabled_list++) + { + + whd_buffer_t buffer; + whd_buffer_t response; + uint32_t *data; + wl_pkt_filter_list_t *filter_list; + wl_pkt_filter_t *filter_ptr; + uint32_t i; + wl_pkt_filter_t *in_filter; + + data = whd_proto_get_iovar_buffer(whd_driver, &buffer, PACKET_FILTER_LIST_BUFFER_MAX_LEN, + IOVAR_STR_PKT_FILTER_LIST); + CHECK_IOCTL_BUFFER(data); + *data = (uint32_t)enabled_list; + + CHECK_RETURN(whd_proto_get_iovar(ifp, buffer, &response) ); + + filter_list = (wl_pkt_filter_list_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + filter_ptr = filter_list->filter; + for (i = 0; i < filter_list->num; i++) + { + in_filter = filter_ptr; + + if (in_filter->id == filter_id) + { + *size_out = MIN_OF(in_filter->u.pattern.size_bytes, max_size); + memcpy (mask, in_filter->u.pattern.mask_and_pattern, *size_out); + memcpy (pattern, in_filter->u.pattern.mask_and_pattern + in_filter->u.pattern.size_bytes, *size_out); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_RX) ); + if (*size_out < in_filter->u.pattern.size_bytes) + { + return WHD_PARTIAL_RESULTS; + } + return WHD_SUCCESS; + } + + /* Update WL filter pointer */ + filter_ptr = + (wl_pkt_filter_t *)( (char *)filter_ptr + + (WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * + in_filter->u.pattern.size_bytes) ); + + /* WLAN returns word-aligned filter list */ + filter_ptr = (wl_pkt_filter_t *)ROUND_UP( (unsigned long)filter_ptr, 4 ); + } + } + return WHD_FILTER_NOT_FOUND; } /* Set/Get TKO retry & interval parameters */ whd_result_t whd_tko_param(whd_interface_t ifp, whd_tko_retry_t *whd_retry, uint8_t set) { - uint32_t len = 0; - uint8_t *data = NULL; - wl_tko_t *tko = NULL; - whd_buffer_t buffer; - whd_buffer_t response; - wl_tko_param_t *wl_param_p = NULL; - whd_result_t result = WHD_SUCCESS; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); - data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); - if (data == NULL) { - WPRINT_WHD_ERROR(("%s: Failed to get iovar buf\n", __func__)); - return WHD_IOCTL_FAIL; - } - - tko = (wl_tko_t *)data; - tko->subcmd_id = WL_TKO_SUBCMD_PARAM; - tko->len = TKO_DATA_OFFSET; - wl_param_p = (wl_tko_param_t *)tko->data; - tko->len += sizeof(wl_tko_param_t); - - tko->subcmd_id = htod16(tko->subcmd_id); - tko->len = htod16(tko->len); - - if (set) { - /* SET parameters */ - - /* Set defaults if needed */ - wl_param_p->interval = whd_retry->tko_interval == - 0 ? - TCP_KEEPALIVE_OFFLOAD_INTERVAL_SEC : - whd_retry->tko_interval; - wl_param_p->retry_count = whd_retry->tko_retry_count == - 0 ? - TCP_KEEPALIVE_OFFLOAD_RETRY_COUNT : - whd_retry->tko_retry_count; - wl_param_p->retry_interval = whd_retry->tko_retry_interval == - 0 ? - TCP_KEEPALIVE_OFFLOAD_RETRY_INTERVAL_SEC : - whd_retry->tko_retry_interval; - - result = whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + whd_buffer_t response; + wl_tko_param_t *wl_param_p = NULL; + whd_result_t result = WHD_SUCCESS; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + if (data == NULL) + { + WPRINT_WHD_ERROR( ("%s: Failed to get iovar buf\n", __func__) ); + return WHD_IOCTL_FAIL; + } + + tko = (wl_tko_t *)data; + tko->subcmd_id = WL_TKO_SUBCMD_PARAM; + tko->len = TKO_DATA_OFFSET; + wl_param_p = (wl_tko_param_t *)tko->data; + tko->len += sizeof(wl_tko_param_t); + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + if (set) + { + /* SET parameters */ + + /* Set defaults if needed */ + wl_param_p->interval = whd_retry->tko_interval == + 0 ? TCP_KEEPALIVE_OFFLOAD_INTERVAL_SEC : whd_retry->tko_interval; + wl_param_p->retry_count = whd_retry->tko_retry_count == + 0 ? TCP_KEEPALIVE_OFFLOAD_RETRY_COUNT : whd_retry->tko_retry_count; + wl_param_p->retry_interval = whd_retry->tko_retry_interval == + 0 ? TCP_KEEPALIVE_OFFLOAD_RETRY_INTERVAL_SEC : whd_retry->tko_retry_interval; + + result = whd_proto_set_iovar(ifp, buffer, NULL); if (result != WHD_SUCCESS) { WPRINT_WHD_ERROR(("%s: Cannot set params\n", __func__)); } @@ -3853,126 +5467,131 @@ whd_tko_param(whd_interface_t ifp, whd_tko_retry_t *whd_retry, uint8_t set) /* GET parameters */ wl_tko_param_t tko_param_real; - result = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); - if (result == WHD_SUCCESS) { - wl_param_p = &tko_param_real; - memcpy((char *)wl_param_p, - (char *)whd_buffer_get_current_piece_data_pointer(whd_driver, response) + TKO_DATA_OFFSET, - (sizeof(wl_tko_param_t))); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX)); - - /* Copy items from wl level struct to higher level struct */ - whd_retry->tko_interval = wl_param_p->interval; - whd_retry->tko_retry_interval = wl_param_p->retry_interval; - whd_retry->tko_retry_count = wl_param_p->retry_count; - } - else { - WPRINT_WHD_ERROR(("%s: Cannot get params.\n", __func__)); - } - } - - return result; + result = whd_proto_get_iovar(ifp, buffer, &response); + if (result == WHD_SUCCESS) + { + wl_param_p = &tko_param_real; + memcpy( (char *)wl_param_p, + (char *)whd_buffer_get_current_piece_data_pointer(whd_driver, response) + TKO_DATA_OFFSET, + (sizeof(wl_tko_param_t) ) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX) ); + + /* Copy items from wl level struct to higher level struct */ + whd_retry->tko_interval = wl_param_p->interval; + whd_retry->tko_retry_interval = wl_param_p->retry_interval; + whd_retry->tko_retry_count = wl_param_p->retry_count; + } + else + { + WPRINT_WHD_ERROR( ("%s: Cannot get params.\n", __func__) ); + } + } + + return result; } /* Query Status */ whd_result_t whd_tko_get_status(whd_interface_t ifp, whd_tko_status_t *whd_status) { - whd_result_t result = WHD_SUCCESS; - uint32_t len = 0; - uint8_t *data = NULL; - wl_tko_t *tko = NULL; - whd_buffer_t buffer; - whd_buffer_t response; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - /* Get a buffer */ - len = (int)(100 - strlen(IOVAR_STR_TKO) - 1); - data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); - CHECK_IOCTL_BUFFER(data); - - /* Fill buffer with request */ - tko = (wl_tko_t *)data; - tko->subcmd_id = WL_TKO_SUBCMD_STATUS; - tko->len = TKO_DATA_OFFSET; - - tko->len += sizeof(wl_tko_status_t); - - tko->subcmd_id = htod16(tko->subcmd_id); - tko->len = htod16(tko->len); - - /* Make request and get result */ - result = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: send iovar failed\n", __func__)); - return result; - } - - /* Parse result */ - tko = (wl_tko_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - if (tko) { - len = htod16(tko->len); - - if (len >= MAX_TKO_CONN + 1) /* MAX_TKO status's + 1 for the count */ - { - memcpy(whd_status, tko->data, MAX_TKO_CONN + 1); - } - } - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX)); - return result; + whd_result_t result = WHD_SUCCESS; + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + /* Get a buffer */ + len = (int)(100 - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + /* Fill buffer with request */ + tko = (wl_tko_t *)data; + tko->subcmd_id = WL_TKO_SUBCMD_STATUS; + tko->len = TKO_DATA_OFFSET; + + tko->len += sizeof(wl_tko_status_t); + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + /* Make request and get result */ + result = whd_proto_get_iovar(ifp, buffer, &response); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: send iovar failed\n", __func__) ); + return result; + } + + /* Parse result */ + tko = (wl_tko_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + if (tko) + { + len = htod16(tko->len); + + if (len >= MAX_TKO_CONN + 1) /* MAX_TKO status's + 1 for the count */ + { + memcpy(whd_status, tko->data, MAX_TKO_CONN + 1); + } + } + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX) ); + return result; } /* Query FW for number tko max tcp connections */ whd_result_t whd_tko_max_assoc(whd_interface_t ifp, uint8_t *max) { - uint32_t len = 0; - uint8_t *data = NULL; - uint8_t *pdata = NULL; - wl_tko_t *tko = NULL; - whd_buffer_t buffer; - whd_buffer_t response; - wl_tko_max_tcp_t *tko_max_tcp = NULL; - wl_tko_max_tcp_t tcp_result; - whd_driver_t whd_driver; - whd_result_t result = WHD_SUCCESS; - CHECK_IFP_NULL(ifp); - - whd_driver = ifp->whd_driver; - - len = (int)(100 - strlen(IOVAR_STR_TKO) - 1); - data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); - CHECK_IOCTL_BUFFER(data); - - tko = (wl_tko_t *)data; - - tko->subcmd_id = WL_TKO_SUBCMD_MAX_TCP; - tko->len = TKO_DATA_OFFSET; - - tko_max_tcp = (wl_tko_max_tcp_t *)tko->data; - tko->len += sizeof(wl_tko_max_tcp_t); - - tko->subcmd_id = htod16(tko->subcmd_id); - tko->len = htod16(tko->len); - - result = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: send iovar failed\n", __func__)); - return result; - } - tko_max_tcp = &tcp_result; - pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); - CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); - memcpy((char *)tko_max_tcp, - (char *)pdata + TKO_DATA_OFFSET, - (sizeof(wl_tko_max_tcp_t))); - CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX)); - - *max = tko_max_tcp->max; - return WHD_SUCCESS; + uint32_t len = 0; + uint8_t *data = NULL; + uint8_t *pdata = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + whd_buffer_t response; + wl_tko_max_tcp_t *tko_max_tcp = NULL; + wl_tko_max_tcp_t tcp_result; + whd_driver_t whd_driver; + whd_result_t result = WHD_SUCCESS; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + len = (int)(100 - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + tko = (wl_tko_t *)data; + + tko->subcmd_id = WL_TKO_SUBCMD_MAX_TCP; + tko->len = TKO_DATA_OFFSET; + + tko_max_tcp = (wl_tko_max_tcp_t *)tko->data; + tko->len += sizeof(wl_tko_max_tcp_t); + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + result = whd_proto_get_iovar(ifp, buffer, &response); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: send iovar failed\n", __func__) ); + return result; + } + tko_max_tcp = &tcp_result; + pdata = whd_buffer_get_current_piece_data_pointer(whd_driver, response); + CHECK_PACKET_NULL(pdata, WHD_NO_REGISTER_FUNCTION_POINTER); + memcpy( (char *)tko_max_tcp, + (char *)pdata + TKO_DATA_OFFSET, + (sizeof(wl_tko_max_tcp_t) ) ); + CHECK_RETURN(whd_buffer_release(whd_driver, response, WHD_NETWORK_TX) ); + + *max = tko_max_tcp->max; + return WHD_SUCCESS; } /* Exercise GET of wl_tko_connect_t IOVAR */ @@ -3980,137 +5599,488 @@ whd_tko_max_assoc(whd_interface_t ifp, uint8_t *max) whd_result_t whd_tko_get_FW_connect(whd_interface_t ifp, uint8_t index, whd_tko_connect_t *whd_connect, uint16_t buflen) { - uint32_t len = 0; - uint8_t *data = NULL; - wl_tko_t *tko = NULL; - wl_tko_connect_t *connect = NULL; - whd_result_t result = WHD_SUCCESS; - whd_buffer_t response; - whd_buffer_t buffer; - whd_driver_t whd_driver; - CHECK_IFP_NULL(ifp); + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + wl_tko_connect_t *connect = NULL; + whd_result_t result = WHD_SUCCESS; + whd_buffer_t response; + whd_buffer_t buffer; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + tko = (wl_tko_t *)data; + + tko->subcmd_id = WL_TKO_SUBCMD_CONNECT; + tko->len = offsetof(wl_tko_t, data); + connect = (wl_tko_connect_t *)tko->data; + connect->index = index; + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + result = whd_proto_get_iovar(ifp, buffer, &response); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: send iovar failed\n", __func__) ); + return result; + } + tko = (wl_tko_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); + tko->subcmd_id = dtoh16(tko->subcmd_id); + tko->len = dtoh16(tko->len); + + if (tko->subcmd_id != WL_TKO_SUBCMD_CONNECT) + { + WPRINT_WHD_ERROR( ("%s: IOVAR returned garbage!\n", __func__) ); + return WHD_BADARG; + } + connect = (wl_tko_connect_t *)tko->data; + if (tko->len >= sizeof(*connect) ) + { + connect->local_port = dtoh16(connect->local_port); + connect->remote_port = dtoh16(connect->remote_port); + connect->local_seq = dtoh32(connect->local_seq); + connect->remote_seq = dtoh32(connect->remote_seq); + if (connect->ip_addr_type != 0) + { + WPRINT_WHD_ERROR( ("%s: Address type not IPV4\n", __func__) ); + return WHD_BADARG; + } + if (connect->ip_addr_type == 0) + { + /* IPv4 */ + uint16_t mylen; + mylen = sizeof(wl_tko_connect_t) + (2 * IPV4_ADDR_LEN) + connect->request_len + connect->response_len; + if (buflen < mylen) + { + WPRINT_WHD_ERROR( ("%s: Buf len (%d) too small , need %d\n", __func__, buflen, mylen) ); + return WHD_BADARG; + } + + /* + * Assumes whd_tko_connect_t and wl_tko_connect_t are the same. + * If/when they become different (due to different FW versions, etc) than + * this may have to be copied field by field instead. + */ + memcpy(whd_connect, connect, MIN_OF(mylen, buflen) ); + } + } + return WHD_SUCCESS; +} - whd_driver = ifp->whd_driver; - CHECK_DRIVER_NULL(whd_driver); +whd_result_t +whd_tko_toggle(whd_interface_t ifp, whd_bool_t enable) +{ + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + wl_tko_enable_t *tko_enable = NULL; + whd_driver_t whd_driver; + whd_result_t result; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + tko = (wl_tko_t *)data; + + tko->subcmd_id = WL_TKO_SUBCMD_ENABLE; + tko->len = TKO_DATA_OFFSET; + + tko_enable = (wl_tko_enable_t *)tko->data; + tko_enable->enable = enable; + + tko->len += sizeof(wl_tko_enable_t); + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + /* invoke SET iovar */ + result = whd_proto_set_iovar(ifp, buffer, NULL); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: tko %s FAILED\n", __func__, (enable == WHD_TRUE ? "enable" : "disable") ) ); + return result; + } + else + { + WPRINT_WHD_ERROR( ("%s: Successfully %s\n", __func__, (enable == WHD_TRUE ? "enabled" : "disabled") ) ); + } + return result; +} - len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); - data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); - CHECK_IOCTL_BUFFER(data); +static whd_result_t +whd_tko_autoenab(whd_interface_t ifp, whd_bool_t enable) +{ + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + wl_tko_autoenab_t *tko_autoenab = NULL; + whd_driver_t whd_driver; + whd_result_t result; + + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + + len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + tko = (wl_tko_t *)data; + + tko->subcmd_id = WL_TKO_SUBCMD_AUTOENAB; + tko->len = TKO_DATA_OFFSET; + + tko_autoenab = (wl_tko_autoenab_t *)tko->data; + tko_autoenab->enable = enable; + tko_autoenab->version = WL_TKO_AUTO_VER; + tko_autoenab->length = REMAINING_LEN(tko_autoenab, wl_tko_autoenab_t, length); + tko->len += sizeof(wl_tko_autoenab_t); + + tko->subcmd_id = htod16(tko->subcmd_id); + tko->len = htod16(tko->len); + + /* invoke SET iovar */ + result = whd_proto_set_iovar(ifp, buffer, NULL); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR(("%s: tko autoenab %s FAILED\n", __func__, (enable == WHD_TRUE ? "enable" : "disable"))); + } + else + { + WPRINT_WHD_INFO(("%s: Successfully %s tko autoenab\n", __func__, (enable == WHD_TRUE ? "enabled" : "disabled"))); + } + + return result; +} - tko = (wl_tko_t *)data; +whd_result_t +whd_tko_filter(whd_interface_t ifp, whd_tko_auto_filter_t * whd_filter, uint8_t filter_flag) +{ + uint32_t len = 0; + uint8_t *data = NULL; + wl_tko_t *tko = NULL; + whd_buffer_t buffer; + wl_tko_filter_t *wl_filter = NULL; + whd_result_t result = WHD_SUCCESS; + whd_driver_t whd_driver; + CHECK_IFP_NULL(ifp); + + whd_driver = ifp->whd_driver; + CHECK_DRIVER_NULL(whd_driver); + + len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); + data = (uint8_t * )whd_proto_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); + CHECK_IOCTL_BUFFER(data); + + if (data == NULL) + { + WPRINT_WHD_ERROR( ("%s: Failed to get iovar buf\n", __func__) ); + return WHD_IOCTL_FAIL; + } - tko->subcmd_id = WL_TKO_SUBCMD_CONNECT; - tko->len = offsetof(wl_tko_t, data); - connect = (wl_tko_connect_t *)tko->data; - connect->index = index; + tko = (wl_tko_t *)data; + tko->subcmd_id = WL_TKO_SUBCMD_FILTER; + tko->len = TKO_DATA_OFFSET; + wl_filter=(wl_tko_filter_t*)tko->data; + tko->len += sizeof(wl_tko_filter_t); tko->subcmd_id = htod16(tko->subcmd_id); tko->len = htod16(tko->len); - result = whd_cdc_send_iovar(ifp, CDC_GET, buffer, &response); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: send iovar failed\n", __func__)); - return result; - } - tko = (wl_tko_t *)whd_buffer_get_current_piece_data_pointer(whd_driver, response); - tko->subcmd_id = dtoh16(tko->subcmd_id); - tko->len = dtoh16(tko->len); + /* SET parameters */ + wl_filter->version = WL_TKO_AUTO_VER; + wl_filter->length = REMAINING_LEN(wl_filter, wl_tko_autoenab_t, length); + if(filter_flag & TKO_FILTER_SRC_PORT) + wl_filter->sport = whd_filter->sport; - if (tko->subcmd_id != WL_TKO_SUBCMD_CONNECT) { - WPRINT_WHD_ERROR(("%s: IOVAR returned garbage!\n", __func__)); - return WHD_BADARG; - } - connect = (wl_tko_connect_t *)tko->data; - if (tko->len >= sizeof(*connect)) { - connect->local_port = dtoh16(connect->local_port); - connect->remote_port = dtoh16(connect->remote_port); - connect->local_seq = dtoh32(connect->local_seq); - connect->remote_seq = dtoh32(connect->remote_seq); - if (connect->ip_addr_type != 0) { - WPRINT_WHD_ERROR(("%s: Address type not IPV4\n", __func__)); - return WHD_BADARG; - } - if (connect->ip_addr_type == 0) { - /* IPv4 */ - uint16_t mylen; - mylen = sizeof(wl_tko_connect_t) + (2 * IPV4_ADDR_LEN) + connect->request_len + connect->response_len; - if (buflen < mylen) { - WPRINT_WHD_ERROR(("%s: Buf len (%d) too small , need %d\n", __func__, buflen, mylen)); - return WHD_BADARG; - } + if(filter_flag & TKO_FILTER_DST_PORT) + wl_filter->dport =whd_filter->dport; - /* - * Assumes whd_tko_connect_t and wl_tko_connect_t are the same. - * If/when they become different (due to different FW versions, etc) than - * this may have to be copied field by field instead. - */ - memcpy(whd_connect, connect, MIN_OF(mylen, buflen)); - } - } - return WHD_SUCCESS; -} + if(filter_flag & TKO_FILTER_SRC_IP) + memcpy(wl_filter->ip_src,whd_filter->ip_src,IPV6_ADDR_LEN); -whd_result_t -whd_tko_toggle(whd_interface_t ifp, whd_bool_t enable) -{ - uint32_t len = 0; - uint8_t *data = NULL; - wl_tko_t *tko = NULL; - whd_buffer_t buffer; - wl_tko_enable_t *tko_enable = NULL; - whd_driver_t whd_driver; - whd_result_t result; - CHECK_IFP_NULL(ifp); + if(filter_flag & TKO_FILTER_DST_IP) + memcpy(wl_filter->ip_dst,whd_filter->ip_dst,IPV6_ADDR_LEN); - whd_driver = ifp->whd_driver; + result=whd_proto_set_iovar(ifp,buffer,NULL); + if (result != WHD_SUCCESS) + { + WPRINT_WHD_ERROR( ("%s: Cannot set filter\n", __func__) ); + } + return result; +} - len = (int)(WHD_PAYLOAD_MTU - strlen(IOVAR_STR_TKO) - 1); - data = (uint8_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, (uint16_t)len, IOVAR_STR_TKO); - CHECK_IOCTL_BUFFER(data); +whd_result_t +whd_get_wowl_cap(whd_interface_t ifp, uint32_t *value) +{ + whd_result_t ret; + ret = whd_wifi_get_iovar_value(ifp, IOVAR_STR_WOWL, value); + WPRINT_WHD_DEBUG(("%s : wowl %" PRIx32 "\n", __func__, *value)); + return ret; +} - tko = (wl_tko_t *)data; +whd_result_t +whd_set_wowl_cap(whd_interface_t ifp, uint32_t value) +{ + WPRINT_WHD_DEBUG(("%s : wowl %" PRIx32 "\n", __func__, value)); + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_WOWL, value); +} - tko->subcmd_id = WL_TKO_SUBCMD_ENABLE; - tko->len = TKO_DATA_OFFSET; +whd_result_t +whd_wowl_clear(whd_interface_t ifp) +{ + uint32_t value = 0; + WPRINT_WHD_ERROR(("%s : %" PRIx32 "\n", __func__, value)); + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_WOWL_CLEAR, value); +} - tko_enable = (wl_tko_enable_t *)tko->data; - tko_enable->enable = enable; +whd_result_t +whd_wowl_activate(whd_interface_t ifp, uint32_t value) +{ + WPRINT_WHD_ERROR(("%s : %" PRIx32 "\n", __func__, value)); + return whd_wifi_set_iovar_value(ifp, IOVAR_STR_WOWL_ACTIVATE, value); +} - tko->len += sizeof(wl_tko_enable_t); +whd_result_t +whd_set_wowl_pattern(whd_interface_t ifp, char* opt, uint32_t offset, uint8_t mask_size, + uint8_t * mask, uint8_t pattern_size, uint8_t * pattern, uint8_t type) +{ + whd_buffer_t buffer; + whd_driver_t whd_driver = ifp->whd_driver; + char* data; + wl_wowl_pattern_t *wl_pattern; + + if (strcmp(opt, "add") != 0 && + strcmp(opt, "del") != 0 && + strcmp(opt, "clr") != 0) { + WPRINT_WHD_ERROR( ("%s : operation not add, del, cl \n",__func__ )); + return WHD_BADARG; + } + WPRINT_WHD_DEBUG(("%s : %s, offset %lu, pattern %s len %d %d\n",__func__ , opt, (unsigned long)offset, + pattern, mask_size, pattern_size)); + data = (char*)whd_proto_get_iovar_buffer(whd_driver, &buffer, + strlen(opt) + 1 + sizeof(wl_wowl_pattern_t) + mask_size + pattern_size , IOVAR_STR_WOWL_PATTERN); + + if(data == NULL) + { + WPRINT_WHD_ERROR( ("%s : %d \n",__FUNCTION__ , __LINE__)); + return WHD_BUFFER_ALLOC_FAIL; + } + + strcpy(data, opt); + data += strlen(opt) + 1; + + wl_pattern = (wl_wowl_pattern_t *)data; + + if (strcmp(opt, "clr") != 0) + { + wl_pattern->offset = offset; + wl_pattern->masksize = mask_size; + wl_pattern->patternsize = pattern_size; + wl_pattern->patternoffset = sizeof(wl_wowl_pattern_t) + mask_size; + wl_pattern->id = 0; + wl_pattern->reasonsize = 0x00; + wl_pattern->type = type; + + data = (char*)(data + sizeof(wl_wowl_pattern_t)); + memcpy(data, (const char *)mask, mask_size); + + data = (char*)(data + mask_size); + memcpy(data, (const char *)pattern, pattern_size); + } + + return whd_proto_set_iovar(ifp, buffer, NULL); +} - tko->subcmd_id = htod16(tko->subcmd_id); - tko->len = htod16(tko->len); +whd_result_t +whd_get_wowl_pattern(whd_interface_t ifp,uint32_t pattern_num, wl_wowl_pattern_t * pattern) +{ + whd_result_t ret; + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver = ifp->whd_driver; + uint32_t i, cnt = 0; + wl_wowl_pattern_list_t* list; + wl_wowl_pattern_t *wl_pattern; + uint8_t *ptr; + uint32_t tot; + + whd_proto_get_iovar_buffer(whd_driver, &buffer, WHD_PAYLOAD_MTU, IOVAR_STR_WOWL_PATTERN); + ret = whd_proto_get_iovar(ifp, buffer, &response); + if (ret != WHD_SUCCESS) + { + whd_buffer_release(whd_driver, response, WHD_NETWORK_RX); + return WHD_WLAN_ERROR; + } + + list = (wl_wowl_pattern_list_t*) whd_buffer_get_current_piece_data_pointer(whd_driver, response); + ptr = (uint8_t *)list->pattern; + cnt = (pattern_num < list->count ? pattern_num : list->count); + tot = 0; + for (i = 0; i < cnt; i++) { + wl_pattern = (wl_wowl_pattern_t *)ptr + tot; + tot += (wl_pattern->masksize + wl_pattern->patternsize + sizeof(wl_wowl_pattern_t)); + } + memcpy(pattern, list->pattern, tot); + ret = whd_buffer_release(whd_driver, response, WHD_NETWORK_RX); + return ret; +} - /* invoke SET iovar */ - result = whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL); - if (result != WHD_SUCCESS) { - WPRINT_WHD_ERROR(("%s: tko %s FAILED\n", __func__, (enable == WHD_TRUE ? "enable" : "disable"))); - return result; - } - else { - WPRINT_WHD_ERROR(("%s: Successfully %s\n", __func__, (enable == WHD_TRUE ? "enabled" : "disabled"))); - } - return result; +whd_result_t +whd_wowl_activate_secure(whd_interface_t ifp, tls_param_info_t *tlsparam) +{ + whd_result_t ret; + whd_buffer_t buffer; + whd_driver_t whd_driver = ifp->whd_driver; + uint8_t *data; + data = (uint8_t *)whd_proto_get_iovar_buffer(whd_driver, &buffer, + sizeof(tls_param_info_t), IOVAR_STR_WOWL_ACTIVATE_SECURE); + memcpy(data, tlsparam, sizeof(tls_param_info_t)); + ret = whd_proto_set_iovar(ifp, buffer, NULL); + if (ret == WHD_SUCCESS) + { + CHECK_RETURN(whd_wowl_activate(ifp, 1)); + } + else + { + WPRINT_WHD_ERROR( ("whd_wowl_activate_secure failed and error - %ld\n", (unsigned long)ret)); + } + return ret; } whd_result_t -whd_print_wlan_log(whd_driver_t whd_drv) +whd_wowl_get_secure_session_status(whd_interface_t ifp, secure_sess_info_t *tls_sess_info) +{ + whd_result_t ret; + whd_buffer_t buffer; + whd_buffer_t response; + whd_driver_t whd_driver = ifp->whd_driver; + struct secure_sess_info *sess_info; + ret = (whd_result_t)whd_proto_get_iovar_buffer(whd_driver, &buffer, sizeof(struct secure_sess_info), + IOVAR_STR_WOWL_SEC_SESS_INFO); + + ret = whd_proto_get_iovar(ifp, buffer, &response); + if (ret != WHD_SUCCESS) + { + whd_buffer_release(whd_driver, response, WHD_NETWORK_RX); + return WHD_WLAN_ERROR; + } + sess_info = (secure_sess_info_t*) whd_buffer_get_current_piece_data_pointer(whd_driver, response); + memcpy(tls_sess_info, sess_info, sizeof(struct secure_sess_info)); + ret = whd_buffer_release(whd_driver, response, WHD_NETWORK_RX); + return ret; +} + +whd_result_t whd_print_wlan_log(whd_driver_t whd_drv) { char *buf; whd_result_t result; - buf = malloc(WLAN_LOG_BUF_LEN); - if (buf == NULL) + buf = whd_mem_malloc(WLAN_LOG_BUF_LEN); + if (buf == NULL) { return WHD_MALLOC_FAILURE; + } result = whd_wifi_read_wlan_log(whd_drv, buf, WLAN_LOG_BUF_LEN); - free(buf); + whd_mem_free(buf); return result; } -whd_result_t -whd_wifi_print_wlan_log(whd_interface_t ifp) +whd_result_t whd_wifi_print_wlan_log(whd_interface_t ifp) { return whd_print_wlan_log(ifp->whd_driver); } + +#ifdef CYCFG_ULP_SUPPORT_ENABLED +whd_result_t +whd_wifi_get_deepsleep_stats(whd_driver_t whd_driver, char *buf, uint32_t buflen) +{ + whd_result_t ret; + whd_interface_t ifp; + char *param = "ulpstats"; + char *trunc = NULL; + + if(!CHECK_BUFLEN(buflen, MAX_DUMP_BUF_LEN, MIN_DUMP_BUF_LEN)) + { + WPRINT_WHD_ERROR( ("Invalid buffer length for ulp statistics") ); + return WHD_BADARG; + } + + memset(buf, 0, buflen); + + /* Getting ulpstats is supported only in Station mode, default interface mode is STA(0) */ + ifp = whd_driver->iflist[CY_WCM_INTERFACE_TYPE_STA]; + + ret = whd_wifi_get_iovar_buffer_with_param(ifp, IOVAR_STR_DUMP, param, (uint32_t)strlen(param), (uint8_t*)buf, buflen); + + if(ret == WHD_SUCCESS) + { + trunc = strstr(buf, "DS2 Counters"); + if (trunc != NULL) + { + memset(trunc, '\0', strlen(trunc) + 1); + buflen = (uint32_t)strlen(buf); + } + WPRINT_WHD_INFO( ("ULP statistics: \n%s\n", buf)); + whd_driver->ds_cb_info.callback(whd_driver->ds_cb_info.ctx, buf, buflen); + } + else + { + WPRINT_WHD_ERROR( ("Failed to get ULP statistics, error code: %lu", (unsigned long)ret) ); + } + + return ret; +} + +whd_result_t +whd_wifi_register_ds_callback(whd_interface_t ifp, whd_ds_callback_t callback, void *ctx, char *buf, uint32_t buflen) +{ + whd_driver_t whd_driver; + + if(ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + whd_driver = ifp->whd_driver; + + whd_driver->ds_cb_info.callback = callback; + whd_driver->ds_cb_info.ctx = ctx; + whd_driver->ds_cb_info.buf = buf; + whd_driver->ds_cb_info.buflen = buflen; + + return WHD_SUCCESS; +} + +whd_result_t +whd_wifi_deregister_ds_callback(whd_interface_t ifp, whd_ds_callback_t callback) +{ + whd_driver_t whd_driver; + + if(ifp == NULL) + { + return WHD_UNKNOWN_INTERFACE; + } + + whd_driver = ifp->whd_driver; + + memset(&whd_driver->ds_cb_info, 0, sizeof(whd_driver->ds_cb_info)); + + return WHD_SUCCESS; +} +#endif diff --git a/wi-fi/whd/whd_wifi_api.h b/wi-fi/whd/whd_wifi_api.h index c0fe5a4a..2c817476 100644 --- a/wi-fi/whd/whd_wifi_api.h +++ b/wi-fi/whd/whd_wifi_api.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,9 +32,13 @@ #define INCLUDED_WHD_WIFI_API_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif +#define REMAINING_LEN(ptr, type, member) \ + (sizeof(*(ptr)) - offsetof(type, member) - sizeof((ptr)->member)) + /****************************************************** * Function declarations ******************************************************/ @@ -60,9 +64,9 @@ extern "C" { * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_init_config, - whd_resource_source_t *resource_ops, whd_buffer_funcs_t *buffer_ops, - whd_netif_funcs_t *network_ops); +extern whd_result_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_init_config, + whd_resource_source_t *resource_ops, whd_buffer_funcs_t *buffer_ops, + whd_netif_funcs_t *network_ops); /* @} */ /* @} */ @@ -71,7 +75,7 @@ extern uint32_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_in * @{ */ -#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) +#if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE) && !defined(COMPONENT_WIFI_INTERFACE_OCI) /** Attach the WLAN Device to a specific SDIO bus * * @param whd_driver Pointer to handle instance of the driver @@ -80,7 +84,7 @@ extern uint32_t whd_init(whd_driver_t *whd_driver_ptr, whd_init_config_t *whd_in * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_bus_sdio_attach(whd_driver_t whd_driver, whd_sdio_config_t *whd_config, cyhal_sdio_t *sdio_obj); +extern whd_result_t whd_bus_sdio_attach(whd_driver_t whd_driver, whd_sdio_config_t *whd_config, cyhal_sdio_t *sdio_obj); /** Detach the WLAN Device to a specific SDIO bus * @@ -97,7 +101,7 @@ extern void whd_bus_sdio_detach(whd_driver_t whd_driver); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_bus_spi_attach(whd_driver_t whd_driver, whd_spi_config_t *whd_config, cyhal_spi_t *spi_obj); +extern whd_result_t whd_bus_spi_attach(whd_driver_t whd_driver, whd_spi_config_t *whd_config, cyhal_spi_t *spi_obj); /** Detach the WLAN Device to a specific SPI bus * @@ -105,6 +109,23 @@ extern uint32_t whd_bus_spi_attach(whd_driver_t whd_driver, whd_spi_config_t *wh */ extern void whd_bus_spi_detach(whd_driver_t whd_driver); +#elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_USB_INTERFACE) +/** Attach the WLAN Device to a specific USB bus + * + * @param whd_driver Pointer to handle instance of the driver + * @param config Pointer to USB configuration structure + * @param usb_obj The USB HOST hardware interface + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_bus_usb_attach(whd_driver_t whd_driver, whd_usb_config_t *config, cyhal_usb_t *usb_obj); + +/** Detach the WLAN Device to a specific USB bus + * + * @param whd_driver Pointer to handle instance of the driver + */ +extern void whd_bus_usb_detach(whd_driver_t whd_driver); + #elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE) /** Attach the WLAN Device to M2M bus * @@ -114,7 +135,7 @@ extern void whd_bus_spi_detach(whd_driver_t whd_driver); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_bus_m2m_attach(whd_driver_t whd_driver, whd_m2m_config_t *whd_config, cyhal_m2m_t *m2m_obj); +extern whd_result_t whd_bus_m2m_attach(whd_driver_t whd_driver, whd_m2m_config_t *whd_config, cyhal_m2m_t *m2m_obj); /** Detach the WLAN Device to a specific M2M bus * @@ -122,8 +143,24 @@ extern uint32_t whd_bus_m2m_attach(whd_driver_t whd_driver, whd_m2m_config_t *wh */ extern void whd_bus_m2m_detach(whd_driver_t whd_driver); +#elif defined(COMPONENT_WIFI_INTERFACE_OCI) +/** Attach the WLAN Device to AXI(OCI) bus + * + * @param whd_driver Pointer to handle instance of the driver + * @param whd_config Configuration for OCI(AXI) bus + * @param oci_obj The OCI interface, from the Level 3 CY HW APIs + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_bus_oci_attach(whd_driver_t whd_driver, whd_oci_config_t *whd_config); + +/** Detach the WLAN Device to a specific AXI(OCI) bus + * + * @param whd_driver Pointer to handle instance of the driver + */ +extern void whd_bus_oci_detach(whd_driver_t whd_driver); #else -error "CYBSP_WIFI_INTERFACE_TYPE is not defined" +error "CYBSP_WIFI_INTERFACE_TYPE or COMPONENT_WIFI_INTERFACE_OCI is not defined" #endif /* @} */ @@ -150,7 +187,7 @@ error "CYBSP_WIFI_INTERFACE_TYPE is not defined" * * @return WHD_SUCCESS if initialization is successful, error code otherwise */ -extern uint32_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp); +extern whd_result_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp); /** * Turn off the Wi-Fi device @@ -165,7 +202,7 @@ extern uint32_t whd_wifi_on(whd_driver_t whd_driver, whd_interface_t *ifpp); * * @return WHD_SUCCESS if deinitialization is successful, Error code otherwise */ -extern uint32_t whd_wifi_off(whd_interface_t ifp); +extern whd_result_t whd_wifi_off(whd_interface_t ifp); /** Shutdown this instance of the wifi driver, freeing all used resources * @@ -173,7 +210,7 @@ extern uint32_t whd_wifi_off(whd_interface_t ifp); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_deinit(whd_interface_t ifp); +extern whd_result_t whd_deinit(whd_interface_t ifp); /** Brings up the Wi-Fi core * @@ -181,7 +218,7 @@ extern uint32_t whd_deinit(whd_interface_t ifp); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_up(whd_interface_t ifp); +extern whd_result_t whd_wifi_set_up(whd_interface_t ifp); /** Bring down the Wi-Fi core * @@ -192,7 +229,7 @@ extern uint32_t whd_wifi_set_up(whd_interface_t ifp); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_down(whd_interface_t ifp); +extern whd_result_t whd_wifi_set_down(whd_interface_t ifp); /** Creates a secondary interface * @@ -202,7 +239,7 @@ extern uint32_t whd_wifi_set_down(whd_interface_t ifp); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_add_secondary_interface(whd_driver_t whd_drv, whd_mac_t *mac_addr, whd_interface_t *ifpp); +extern whd_result_t whd_add_secondary_interface(whd_driver_t whd_drv, whd_mac_t *mac_addr, whd_interface_t *ifpp); /* @} */ /** @addtogroup wifijoin WHD Wi-Fi Join, Scan and Halt API @@ -232,9 +269,10 @@ typedef void (*whd_scan_result_callback_t)(whd_scan_result_t **result_ptr, void * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_scan_synch(whd_interface_t ifp, - whd_sync_scan_result_t *scan_result, - uint32_t *count); +extern whd_result_t whd_wifi_scan_synch(whd_interface_t ifp, + whd_sync_scan_result_t *scan_result, + uint32_t *count + ); /** Initiates a scan to search for 802.11 networks. * @@ -266,16 +304,16 @@ extern uint32_t whd_wifi_scan_synch(whd_interface_t ifp, * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_scan(whd_interface_t ifp, - whd_scan_type_t scan_type, - whd_bss_type_t bss_type, - const whd_ssid_t *optional_ssid, - const whd_mac_t *optional_mac, - const uint16_t *optional_channel_list, - const whd_scan_extended_params_t *optional_extended_params, - whd_scan_result_callback_t callback, - whd_scan_result_t *result_ptr, - void *user_data); +extern whd_result_t whd_wifi_scan(whd_interface_t ifp, + whd_scan_type_t scan_type, + whd_bss_type_t bss_type, + const whd_ssid_t *optional_ssid, + const whd_mac_t *optional_mac, + const uint16_t *optional_channel_list, + const whd_scan_extended_params_t *optional_extended_params, + whd_scan_result_callback_t callback, + whd_scan_result_t *result_ptr, + void *user_data); /** Abort a previously issued scan * @@ -283,7 +321,49 @@ extern uint32_t whd_wifi_scan(whd_interface_t ifp, * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_stop_scan(whd_interface_t ifp); +extern whd_result_t whd_wifi_stop_scan(whd_interface_t ifp); + +/** Auth result callback function pointer type + * + * @param result_ptr A pointer to the pointer that indicates where to put the auth result + * @param len the size of result + * @param status Status of auth process + * @param flag flag of h2e will be indicated in auth request event, otherwise is NULL. + * @param user_data user specific data that will be passed directly to the callback function + * + */ +typedef void (*whd_auth_result_callback_t)(void *result_ptr, uint32_t len, whd_auth_status_t status, uint8_t *flag, + void *user_data); + +/** Initiates SAE auth + * + * The results of the auth will be individually provided to the callback function. + * Note: The callback function will be executed in the context of the WHD thread and so must not perform any + * actions that may cause a bus transaction. + * + * @param ifp Pointer to handle instance of whd interface + * @param callback The callback function which will receive and process the result data. + * @param result_ptr Pointer to a pointer to a result storage structure. + * @param user_data user specific data that will be passed directly to the callback function + * + * @note - Callback must not use blocking functions, nor use WHD functions, since it is called from the context of the + * WHD thread. + * - The callback, result_ptr and user_data variables will be referenced after the function returns. + * Those variables must remain valid until the scan is complete. + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_external_auth_request(whd_interface_t ifp, + whd_auth_result_callback_t callback, + void *result_ptr, + void *user_data); +/** Abort authentication request + * + * @param ifp Pointer to handle instance of whd interface + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_stop_external_auth_request(whd_interface_t ifp); /** Joins a Wi-Fi network * @@ -301,8 +381,8 @@ extern uint32_t whd_wifi_stop_scan(whd_interface_t ifp); * @return WHD_SUCCESS when the system is joined and ready to send data packets * Error code if an error occurred */ -extern uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length); +extern whd_result_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length); /** Joins a specific Wi-Fi network * @@ -319,8 +399,21 @@ extern uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_s * @return WHD_SUCCESS when the system is joined and ready to send data packets * Error code if an error occurred */ -extern uint32_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_result_t *ap, const uint8_t *security_key, - uint8_t key_length); +extern whd_result_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_result_t *ap, const uint8_t *security_key, + uint8_t key_length); + +/** Set the current chanspec on the WLAN radio + * + * @note On most WLAN devices this will set the chanspec for both AP *AND* STA + * (since there is only one radio - it cannot be on two chanspec simulaneously) + * + * @param ifp Pointer to handle instance of whd interface + * @param chanspec The desired chanspec + * + * @return WHD_SUCCESS if the chanspec was successfully set + * Error code if the chanspec was not successfully set + */ +extern whd_result_t whd_wifi_set_chanspec(whd_interface_t ifp, wl_chanspec_t chanspec); /* @} */ @@ -341,7 +434,7 @@ extern uint32_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_resul * @return WHD_SUCCESS if the channel was successfully set * Error code if the channel was not successfully set */ -extern uint32_t whd_wifi_set_channel(whd_interface_t ifp, uint32_t channel); +extern whd_result_t whd_wifi_set_channel(whd_interface_t ifp, uint32_t channel); /** Get the current channel on the WLAN radio * @@ -354,18 +447,18 @@ extern uint32_t whd_wifi_set_channel(whd_interface_t ifp, uint32_t channel); * @return WHD_SUCCESS if the channel was successfully retrieved * Error code if the channel was not successfully retrieved */ -extern uint32_t whd_wifi_get_channel(whd_interface_t ifp, uint32_t *channel); +extern whd_result_t whd_wifi_get_channel(whd_interface_t ifp, uint32_t *channel); /** Gets the supported channels * * @param ifp Pointer to handle instance of whd interface * @param channel_list Buffer to store list of the supported channels - * and max channel is WL_NUMCHANNELS + * and max channel is MAXCHANNEL * * @return WHD_SUCCESS if the active connections was successfully read * WHD_ERROR if the active connections was not successfully read */ -extern uint32_t whd_wifi_get_channels(whd_interface_t ifp, whd_list_t *channel_list); +extern whd_result_t whd_wifi_get_channels(whd_interface_t ifp, whd_list_t *channel_list); /** Set the passphrase @@ -377,7 +470,7 @@ extern uint32_t whd_wifi_get_channels(whd_interface_t ifp, whd_list_t *channel_l * @return WHD_SUCCESS when the key is set * Error code if an error occurred */ -extern uint32_t whd_wifi_set_passphrase(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length); +extern whd_result_t whd_wifi_set_passphrase(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length); /** Set the SAE password * @@ -388,7 +481,96 @@ extern uint32_t whd_wifi_set_passphrase(whd_interface_t ifp, const uint8_t *secu * @return WHD_SUCCESS when the key is set * Error code if an error occurred */ -extern uint32_t whd_wifi_sae_password(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length); +extern whd_result_t whd_wifi_sae_password(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length); + +/** Set the offload configuration + * + * @param ifp Pointer to handle instance of whd interface + * @param ol_feat Offload Skip bitmap + * @param reset reset or set configuration + * + * @return WHD_SUCCESS when the offload config is set/reset + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_offload_config(whd_interface_t ifp, uint32_t ol_feat, uint32_t reset); + +/** Update IPV4 address + * + * @param ifp Pointer to handle instance of whd interface + * @param ol_feat Offload Skip bitmap + * @param ipv4_addr set ipv4 address + * @param is_add To add or delete IPV4 address + * + * @return WHD_SUCCESS when the ipv4 address updated or not + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_offload_ipv4_update(whd_interface_t ifp, uint32_t ol_feat, uint32_t ipv4_addr, whd_bool_t is_add); + +/** Update IPV6 address + * + * @param ifp Pointer to handle instance of whd interface + * @param ol_feat Offload Skip bitmap + * @param ipv6_addr set ipv6 address + * @param type set 0:unicast 1:anycast + * @param is_add To add or delete IPV6 address + * + * @return WHD_SUCCESS when the ipv6 address updated or not + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_offload_ipv6_update(whd_interface_t ifp, uint32_t ol_feat, uint32_t *ipv6_addr, uint8_t type, whd_bool_t is_add); + +/** Enable the offload module + * + * @param ifp Pointer to handle instance of whd interface + * @param ol_feat Offload Skip bitmap + * @param enable Enable/Disable offload module + * + * @return WHD_SUCCESS when offload module enabled or not + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_offload_enable(whd_interface_t ifp, uint32_t ol_feat, uint32_t enable); + +/** Configure the offload module + * + * @param ifp Pointer to handle instance of whd interface + * @param set_wowl value indicates, which are all wowl bits to be set + * + * @return WHD_SUCCESS when offload module enabled or not + * Error code if an error occurred + */ +extern whd_result_t whd_configure_wowl(whd_interface_t ifp, uint32_t set_wowl); + +/** Configure the Keep Alive offload module + * + * @param ifp Pointer to handle instance of whd interface + * @param packet whd period,len_bytes & Data parameter structure + * @param flag Flag to set NULL(0)/NAT(1) keepalive + * + * @return WHD_SUCCESS when offload module enabled or not + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_keepalive_config(whd_interface_t ifp, whd_keep_alive_t * packet, uint8_t flag); + +/** Configure the TKO offload module + * + * @param ifp Pointer to handle instance of whd interface + * @param enable Enable/Disable TCP Keepalive offload + * + * @return WHD_SUCCESS when offload module enabled or not + * Error code if an error occurred + */ +extern whd_result_t whd_configure_tko_offload(whd_interface_t ifp, whd_bool_t enable); + +/** Configure the TKO filter module + * + * @param ifp Pointer to handle instance of whd interface + * @param whd_filter wl_filter structure buffer from Firmware + * @param filter_flag To set filter + * + * @return WHD_SUCCESS when offload module enabled or not + * Error code if an error occurred + */ +extern whd_result_t whd_configure_tko_filter(whd_interface_t ifp, whd_tko_auto_filter_t * whd_filter, uint8_t filter_flag); /** Enable WHD internal supplicant and set WPA2 passphrase in case of WPA3/WPA2 transition mode * @@ -400,9 +582,29 @@ extern uint32_t whd_wifi_sae_password(whd_interface_t ifp, const uint8_t *securi * @return WHD_SUCCESS when the supplicant variable and wpa2 passphrase is set * Error code if an error occurred */ -extern uint32_t whd_wifi_enable_sup_set_passphrase(whd_interface_t ifp, const uint8_t *security_key_psk, - uint8_t psk_length, whd_security_t auth_type); +extern whd_result_t whd_wifi_enable_sup_set_passphrase(whd_interface_t ifp, const uint8_t *security_key_psk, + uint8_t psk_length, whd_security_t auth_type); +/** Set the PMK Key + * + * @param ifp Pointer to handle instance of whd interface + * @param security_key The security key (PMK) which is to be set + * @param key_length length of the PMK(It must be 32 bytes) + * + * @return WHD_SUCCESS when the key is set + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_set_pmk(whd_interface_t ifp, const uint8_t *security_key, uint8_t key_length); + +/** Set the Roam time threshold + * + * @param ifp Pointer to handle instance of whd interface + * @param roam_time_threshold The maximum roam time threshold which is to be set + * + * @return WHD_SUCCESS when the roam_time_threshold is set + * Error code if an error occurred + */ +extern whd_result_t whd_wifi_set_roam_time_threshold(whd_interface_t ifp, uint32_t roam_time_threshold); /** Enable WHD internal supplicant * @@ -412,7 +614,24 @@ extern uint32_t whd_wifi_enable_sup_set_passphrase(whd_interface_t ifp, const ui * @return WHD_SUCCESS when the supplicant variable is set * Error code if an error occurred */ -extern uint32_t whd_wifi_enable_supplicant(whd_interface_t ifp, whd_security_t auth_type); +extern whd_result_t whd_wifi_enable_supplicant(whd_interface_t ifp, whd_security_t auth_type); + +/** Set PMKID in Device (WLAN) + * + * @param ifp Pointer to handle instance of whd interface + * @param pmkid Pointer to BSSID and PMKID(16 bytes) + * + * @return whd_result_t + */ +extern whd_result_t whd_wifi_set_pmksa(whd_interface_t ifp, const pmkid_t *pmkid); + +/** Clear all PMKIDs in Device (WLAN), especially the PMKIDs in Supplicant module + * + * @param ifp Pointer to handle instance of whd interface + * + * @return whd_result_t + */ +extern whd_result_t whd_wifi_pmkid_clear(whd_interface_t ifp); /** Retrieve the latest RSSI value * @@ -422,7 +641,17 @@ extern uint32_t whd_wifi_enable_supplicant(whd_interface_t ifp, whd_security_t a * @return WHD_SUCCESS if the RSSI was successfully retrieved * Error code if the RSSI was not retrieved */ -extern uint32_t whd_wifi_get_rssi(whd_interface_t ifp, int32_t *rssi); +extern whd_result_t whd_wifi_get_rssi(whd_interface_t ifp, int32_t *rssi); + +/** Retrieve the latest Roam time threshold value + * + * @param ifp Pointer to handle instance of whd interface + * @param roam_time_threshold The location where the roam time threshold value will be stored + * + * @return WHD_SUCCESS if the roam time threshold was successfully retrieved + * Error code if the roam time threshold was not retrieved + */ +extern whd_result_t whd_wifi_get_roam_time_threshold(whd_interface_t ifp, uint32_t *roam_time_threshold); /** Retrieve the associated STA's RSSI value * @@ -433,7 +662,7 @@ extern uint32_t whd_wifi_get_rssi(whd_interface_t ifp, int32_t *rssi); * @return WHD_SUCCESS : if the RSSI was successfully retrieved * Error code : if the RSSI was not retrieved */ -extern uint32_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, const whd_mac_t *client_mac); +extern whd_result_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, const whd_mac_t *client_mac); /* @} */ @@ -451,7 +680,7 @@ extern uint32_t whd_wifi_get_ap_client_rssi(whd_interface_t ifp, int32_t *rssi, * @return WHD_SUCCESS On successful disassociation from the AP * Error code If an error occurred */ -extern uint32_t whd_wifi_leave(whd_interface_t ifp); +extern whd_result_t whd_wifi_leave(whd_interface_t ifp); /* @} */ /** @addtogroup wifiutilities WHD Wi-Fi Utility API @@ -468,7 +697,7 @@ extern uint32_t whd_wifi_leave(whd_interface_t ifp); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_mac_address(whd_interface_t ifp, whd_mac_t *mac); +extern whd_result_t whd_wifi_get_mac_address(whd_interface_t ifp, whd_mac_t *mac); /** Get the BSSID of the interface * @@ -477,7 +706,7 @@ extern uint32_t whd_wifi_get_mac_address(whd_interface_t ifp, whd_mac_t *mac); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_bssid(whd_interface_t ifp, whd_mac_t *bssid); +extern whd_result_t whd_wifi_get_bssid(whd_interface_t ifp, whd_mac_t *bssid); /* @} */ /** @addtogroup wifisoftap WHD Wi-Fi SoftAP API @@ -493,13 +722,13 @@ extern uint32_t whd_wifi_get_bssid(whd_interface_t ifp, whd_mac_t *bssid); * @param auth_type Authentication type * @param security_key A byte array containing the cleartext security key for the network * @param key_length The length of the security_key in bytes. - * @param channel 802.11 channel number + * @param chanspec The desired chanspec * * @return WHD_SUCCESS if successfully initialises an AP * Error code if an error occurred */ -extern uint32_t whd_wifi_init_ap(whd_interface_t ifp, whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length, uint8_t channel); +extern whd_result_t whd_wifi_init_ap(whd_interface_t ifp, whd_ssid_t *ssid, whd_security_t auth_type, + const uint8_t *security_key, uint8_t key_length, uint16_t chanspec); /** Start the infrastructure WiFi network (SoftAP) * using the parameter set by whd_wifi_init_ap() and optionally by whd_wifi_manage_custom_ie() @@ -507,7 +736,7 @@ extern uint32_t whd_wifi_init_ap(whd_interface_t ifp, whd_ssid_t *ssid, whd_secu * @return WHD_SUCCESS if successfully creates an AP * Error code if an error occurred */ -extern uint32_t whd_wifi_start_ap(whd_interface_t ifp); +extern whd_result_t whd_wifi_start_ap(whd_interface_t ifp); /** Stops an existing infrastructure WiFi network * @@ -516,7 +745,7 @@ extern uint32_t whd_wifi_start_ap(whd_interface_t ifp); * @return WHD_SUCCESS if the AP is successfully stopped or if the AP has not yet been brought up * Error code if an error occurred */ -extern uint32_t whd_wifi_stop_ap(whd_interface_t ifp); +extern whd_result_t whd_wifi_stop_ap(whd_interface_t ifp); /** Get the maximum number of associations supported by AP interfaces @@ -527,7 +756,7 @@ extern uint32_t whd_wifi_stop_ap(whd_interface_t ifp); * @return WHD_SUCCESS if the maximum number of associated clients was successfully read * WHD_ERROR if the maximum number of associated clients was not successfully read */ -extern uint32_t whd_wifi_ap_get_max_assoc(whd_interface_t ifp, uint32_t *max_assoc); +extern whd_result_t whd_wifi_ap_get_max_assoc(whd_interface_t ifp, uint32_t *max_assoc); /** Gets the current number of active connections * @@ -538,8 +767,8 @@ extern uint32_t whd_wifi_ap_get_max_assoc(whd_interface_t ifp, uint32_t *max_ass * @return WHD_SUCCESS if the active connections was successfully read * WHD_ERROR if the active connections was not successfully read */ -extern uint32_t whd_wifi_get_associated_client_list(whd_interface_t ifp, void *client_list_buffer, - uint16_t buffer_length); +extern whd_result_t whd_wifi_get_associated_client_list(whd_interface_t ifp, void *client_list_buffer, + uint16_t buffer_length); /** Deauthenticates a STA which may or may not be associated to SoftAP * @@ -552,7 +781,7 @@ extern uint32_t whd_wifi_get_associated_client_list(whd_interface_t ifp, void *c * @return WHD_SUCCESS On successful deauthentication of the other STA * WHD_ERROR If an error occurred */ -extern uint32_t whd_wifi_deauth_sta(whd_interface_t ifp, whd_mac_t *mac, whd_dot11_reason_code_t reason); +extern whd_result_t whd_wifi_deauth_sta(whd_interface_t ifp, whd_mac_t *mac, whd_dot11_reason_code_t reason); /** Retrieves AP information * @@ -563,7 +792,7 @@ extern uint32_t whd_wifi_deauth_sta(whd_interface_t ifp, whd_mac_t *mac, whd_dot * @return WHD_SUCCESS if the AP info was successfully retrieved * Error code if the AP info was not successfully retrieved */ -extern uint32_t whd_wifi_get_ap_info(whd_interface_t ifp, whd_bss_info_t *ap_info, whd_security_t *security); +extern whd_result_t whd_wifi_get_ap_info(whd_interface_t ifp, whd_bss_info_t *ap_info, whd_security_t *security); /** Set the beacon interval. * @@ -574,7 +803,7 @@ extern uint32_t whd_wifi_get_ap_info(whd_interface_t ifp, whd_bss_info_t *ap_inf * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_ap_set_beacon_interval(whd_interface_t ifp, uint16_t interval); +extern whd_result_t whd_wifi_ap_set_beacon_interval(whd_interface_t ifp, uint16_t interval); /** Set the DTIM interval. * @@ -585,7 +814,7 @@ extern uint32_t whd_wifi_ap_set_beacon_interval(whd_interface_t ifp, uint16_t in * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_ap_set_dtim_interval(whd_interface_t ifp, uint16_t interval); +extern whd_result_t whd_wifi_ap_set_dtim_interval(whd_interface_t ifp, uint16_t interval); /* @} */ @@ -605,7 +834,7 @@ extern uint32_t whd_wifi_ap_set_dtim_interval(whd_interface_t ifp, uint16_t inte * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_enable_powersave(whd_interface_t ifp); +extern whd_result_t whd_wifi_enable_powersave(whd_interface_t ifp); /** Enables powersave mode on specified interface while attempting to maximise throughput * @@ -625,7 +854,7 @@ extern uint32_t whd_wifi_enable_powersave(whd_interface_t ifp); * Error code if power save mode was not successfully enabled * */ -extern uint32_t whd_wifi_enable_powersave_with_throughput(whd_interface_t ifp, uint16_t return_to_sleep_delay); +extern whd_result_t whd_wifi_enable_powersave_with_throughput(whd_interface_t ifp, uint16_t return_to_sleep_delay); /** Get powersave mode on specified interface * @@ -635,7 +864,7 @@ extern uint32_t whd_wifi_enable_powersave_with_throughput(whd_interface_t ifp, u * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_powersave_mode(whd_interface_t ifp, uint32_t *value); +extern whd_result_t whd_wifi_get_powersave_mode(whd_interface_t ifp, uint32_t *value); /** Disables 802.11 power save mode on specified interface * @@ -645,7 +874,22 @@ extern uint32_t whd_wifi_get_powersave_mode(whd_interface_t ifp, uint32_t *value * Error code if power save mode was not successfully disabled * */ -extern uint32_t whd_wifi_disable_powersave(whd_interface_t ifp); +extern whd_result_t whd_wifi_disable_powersave(whd_interface_t ifp); + +/** Configure ULP mode on specified interface + * + * @param ifp Pointer to handle instance of whd interface + * @param mode mode to be set for ULP(DS0/DS1/DS2) + 1 for DS1, 2 for DS2 and 0 indicates to disable(DS0) + * @param wait_time indicates ulp_wait in ms to be set + (if no network activity for this time, device will enter into DS2) + * + * @return WHD_SUCCESS if ulp mode was successfully configured + * Error code if ulp mode was not configured successfully + * + */ +extern whd_result_t whd_wifi_config_ulp_mode(whd_interface_t ifp, uint32_t *mode, uint32_t *wait_time); + /* @} */ /** @addtogroup wifiutilities WHD Wi-Fi Utility API @@ -665,7 +909,7 @@ extern uint32_t whd_wifi_disable_powersave(whd_interface_t ifp); * @return WHD_SUCCESS if the address was registered successfully * Error code if the address was not registered */ -extern uint32_t whd_wifi_register_multicast_address(whd_interface_t ifp, const whd_mac_t *mac); +extern whd_result_t whd_wifi_register_multicast_address(whd_interface_t ifp, const whd_mac_t *mac); /** Unregisters interest in a multicast address * @@ -678,7 +922,7 @@ extern uint32_t whd_wifi_register_multicast_address(whd_interface_t ifp, const w * @return WHD_SUCCESS if the address was unregistered successfully * Error code if the address was not unregistered */ -extern uint32_t whd_wifi_unregister_multicast_address(whd_interface_t ifp, const whd_mac_t *mac); +extern whd_result_t whd_wifi_unregister_multicast_address(whd_interface_t ifp, const whd_mac_t *mac); /** Sets the 802.11 powersave listen interval for a Wi-Fi client, and communicates * the listen interval to the Access Point. The listen interval will be set to @@ -697,8 +941,8 @@ extern uint32_t whd_wifi_unregister_multicast_address(whd_interface_t ifp, const * @return WHD_SUCCESS If the listen interval was successfully set. * Error code If the listen interval was not successfully set. */ -extern uint32_t whd_wifi_set_listen_interval(whd_interface_t ifp, uint8_t listen_interval, - whd_listen_interval_time_unit_t time_unit); +extern whd_result_t whd_wifi_set_listen_interval(whd_interface_t ifp, uint8_t listen_interval, + whd_listen_interval_time_unit_t time_unit); /** Gets the current value of all beacon listen interval variables * @@ -711,7 +955,7 @@ extern uint32_t whd_wifi_set_listen_interval(whd_interface_t ifp, uint8_t listen * @return WHD_SUCCESS If all listen interval values are read successfully * Error code If at least one of the listen interval values are NOT read successfully */ -extern uint32_t whd_wifi_get_listen_interval(whd_interface_t ifp, whd_listen_interval_t *li); +extern whd_result_t whd_wifi_get_listen_interval(whd_interface_t ifp, whd_listen_interval_t *li); /** Determines if a particular interface is ready to transceive ethernet packets * @@ -725,7 +969,7 @@ extern uint32_t whd_wifi_get_listen_interval(whd_interface_t ifp, whd_listen_int * This can occur if the passphrase is incorrect. * Error code if the interface is not ready to transceive ethernet packets */ -extern uint32_t whd_wifi_is_ready_to_transceive(whd_interface_t ifp); +extern whd_result_t whd_wifi_is_ready_to_transceive(whd_interface_t ifp); /* Certification APIs */ @@ -740,7 +984,7 @@ extern uint32_t whd_wifi_is_ready_to_transceive(whd_interface_t ifp); * @return WHD_SUCCESS if the AC Parameters were successfully retrieved * Error code if the AC Parameters were not retrieved */ -extern uint32_t whd_wifi_get_acparams(whd_interface_t ifp, whd_edcf_ac_param_t *acp); +extern whd_result_t whd_wifi_get_acparams(whd_interface_t ifp, whd_edcf_ac_param_t *acp); /* Action Frames */ @@ -757,9 +1001,9 @@ extern uint32_t whd_wifi_get_acparams(whd_interface_t ifp, whd_edcf_ac_param_t * * @return WHD_SUCCESS if the custom IE action was successful * Error code if the custom IE action failed */ -extern uint32_t whd_wifi_manage_custom_ie(whd_interface_t ifp, whd_custom_ie_action_t action, - const uint8_t *oui, uint8_t subtype, const void *data, - uint16_t length, uint16_t which_packets); +extern whd_result_t whd_wifi_manage_custom_ie(whd_interface_t ifp, whd_custom_ie_action_t action, + const uint8_t *oui, uint8_t subtype, const void *data, + uint16_t length, uint16_t which_packets); /** Send a pre-prepared action frame * @@ -768,7 +1012,107 @@ extern uint32_t whd_wifi_manage_custom_ie(whd_interface_t ifp, whd_custom_ie_act * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_send_action_frame(whd_interface_t ifp, whd_af_params_t *af_params); +extern whd_result_t whd_wifi_send_action_frame(whd_interface_t ifp, whd_af_params_t *af_params); + +/** Send a pre-prepared authentication frame + * + * @param ifp Pointer to handle instance of whd interface + * @param auth_params pointer to a pre-prepared authentication frame structure + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_send_auth_frame(whd_interface_t ifp, whd_auth_params_t *auth_params); + +/** Configure HE OM Control + * + * @param ifp Pointer to handle instance of whd interface + * @param he_omi_params pointer to he_omi parameters + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_he_omi(whd_interface_t ifp, whd_he_omi_params_t *he_omi_params); + +/** Configure BSS Max Idle Time + * + * @param ifp Pointer to handle instance of whd interface + * @param period The bss max idle period time unit(seconds) + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_bss_max_idle(whd_interface_t ifp, uint16_t period); + +/** Trigger individual TWT session(used by STA) + * + * @param ifp Pointer to handle instance of whd interface + * @param twt_params pointer to itwt_setup parameters + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_itwt_setup(whd_interface_t ifp, whd_itwt_setup_params_t *twt_params); + +/** Trigger Join broadcast TWT session(used by STA) + * + * @param ifp Pointer to handle instance of whd interface + * @param twt_params pointer to btwt_join parameters + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_btwt_join(whd_interface_t ifp, whd_btwt_join_params_t *twt_params); + +/** Trigger teardown all individual or broadcast TWT sessions + * + * @param ifp Pointer to handle instance of whd interface + * @param twt_params pointer to twt_taerdown parameters + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_twt_teardown(whd_interface_t ifp, whd_twt_teardown_params_t *twt_params); + +/** Trigger TWT information frame(used by STA) + * + * @param ifp Pointer to handle instance of whd interface + * @param twt_params pointer to twt_information parameters + * + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_twt_information_frame(whd_interface_t ifp, whd_twt_information_params_t *twt_params); + +/** Configure TWT IE in beacon(used by AP) + * + * @param ifp Pointer to handle instance of whd interface + * @param twt_params pointer to btwt_config parameters + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_btwt_config(whd_interface_t ifp, whd_btwt_config_params_t *twt_params); + +/** Add MBO preferred/non-preferrd channel attributes + * + * @param ifp Pointer to handle instance of whd interface + * @param mbo_params pointer to whd_mbo_add_chan_pref_params_t structure + * + * @return WHD_SUCCESS or Error code + */ +extern uint32_t whd_wifi_mbo_add_chan_pref(whd_interface_t ifp, whd_mbo_add_chan_pref_params_t *mbo_params); + +/** Delete MBO preferred/non-preferrd channel attributes + * + * @param ifp Pointer to handle instance of whd interface + * @param mbo_params pointer to whd_mbo_del_chan_pref_params_t structure + * + * @return WHD_SUCCESS or Error code + */ +extern uint32_t whd_wifi_mbo_del_chan_pref(whd_interface_t ifp, whd_mbo_del_chan_pref_params_t *mbo_params); + +/** Send WNM Notification request sub-element type + * + * @param ifp Pointer to handle instance of whd interface + * @param sub_elem_type sub-element type <2/3> + * + * @return WHD_SUCCESS or Error code + */ +extern uint32_t whd_wifi_mbo_send_notif(whd_interface_t ifp, uint8_t sub_elem_type); /** Set coex configuration * @@ -777,7 +1121,25 @@ extern uint32_t whd_wifi_send_action_frame(whd_interface_t ifp, whd_af_params_t * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_coex_config(whd_interface_t ifp, whd_coex_config_t *coex_config); +extern whd_result_t whd_wifi_set_coex_config(whd_interface_t ifp, whd_coex_config_t *coex_config); + +/** Set auth status used for External AUTH(SAE) + * + * @param ifp Pointer to handle instance of whd interface + * @param status Pointer to Auth_Status structure + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_set_auth_status(whd_interface_t ifp, whd_auth_req_status_t *status); + +/** Get FW(chip) Capability + * + * @param ifp Pointer to handle instance of whd interface + * @param value Enum value of the current FW capability, ex: sae or sae_ext or ...etc, + * (enum value map to whd_fwcap_id_t) + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_get_fwcap(whd_interface_t ifp, uint32_t *value); /** Get version of Device (WLAN) Firmware * @@ -995,8 +1357,8 @@ whd_result_t whd_wifi_toggle_packet_filter(whd_interface_t ifp, uint8_t filter_i * @return whd_result_t */ whd_result_t whd_pf_get_packet_filter_mask_and_pattern(whd_interface_t ifp, uint8_t filter_id, uint32_t max_size, - uint8_t *mask, - uint8_t *pattern, uint32_t *size_out); + uint8_t *mask, + uint8_t *pattern, uint32_t *size_out); /** Clear the packet filter stats associated with a filter id * @param[in] ifp : pointer to handle instance of whd interface @@ -1043,7 +1405,7 @@ whd_result_t whd_tko_max_assoc(whd_interface_t ifp, uint8_t *max); * @return whd_result_t */ whd_result_t whd_tko_get_FW_connect(whd_interface_t ifp, uint8_t index, whd_tko_connect_t *whd_connect, - uint16_t buflen); + uint16_t buflen); /** Return the stats associated with a filter * @param[in] ifp : Pointer to handle instance of whd interface @@ -1052,6 +1414,13 @@ whd_result_t whd_tko_get_FW_connect(whd_interface_t ifp, uint8_t index, whd_tko_ */ whd_result_t whd_tko_toggle(whd_interface_t ifp, whd_bool_t enable); +/** Return the stats associated with a filter + * @param[in] ifp : Pointer to handle instance of whd interface + * @param[in] whd_filter : wl_filter structure buffer from Firmware + * @param[in] filter_flag: To set filter + * @return whd_result_t + */ +extern whd_result_t whd_tko_filter(whd_interface_t ifp, whd_tko_auto_filter_t * whd_filter, uint8_t filter_flag); /* @} */ @@ -1068,7 +1437,7 @@ whd_result_t whd_tko_toggle(whd_interface_t ifp, whd_bool_t enable); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t value); +extern whd_result_t whd_wifi_set_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t value); /** Sends an IOCTL command - CDC_GET IOCTL value * @@ -1078,7 +1447,7 @@ extern uint32_t whd_wifi_set_ioctl_value(whd_interface_t ifp, uint32_t ioctl, ui * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t *value); +extern whd_result_t whd_wifi_get_ioctl_value(whd_interface_t ifp, uint32_t ioctl, uint32_t *value); /** Sends an IOCTL command - CDC_SET IOCTL buffer * @@ -1089,7 +1458,7 @@ extern uint32_t whd_wifi_get_ioctl_value(whd_interface_t ifp, uint32_t ioctl, ui * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_set_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, void *buffer, uint16_t buffer_length); +extern whd_result_t whd_wifi_set_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, void *buffer, uint16_t buffer_length); /** Sends an IOCTL command - CDC_GET IOCTL buffer * @@ -1100,8 +1469,8 @@ extern uint32_t whd_wifi_set_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, v * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, uint8_t *out_buffer, - uint16_t out_length); +extern whd_result_t whd_wifi_get_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, uint8_t *out_buffer, + uint16_t out_length); /** Sends an IOVAR command * @@ -1114,8 +1483,8 @@ extern uint32_t whd_wifi_get_ioctl_buffer(whd_interface_t ifp, uint32_t ioctl, u * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_iovar_buffer_with_param(whd_interface_t ifp, const char *iovar_name, void *param, - uint32_t paramlen, uint8_t *out_buffer, uint32_t out_length); +extern whd_result_t whd_wifi_get_iovar_buffer_with_param(whd_interface_t ifp, const char *iovar_name, void *param, + uint32_t paramlen, uint8_t *out_buffer, uint32_t out_length); /* @} */ @@ -1132,7 +1501,7 @@ extern uint32_t whd_wifi_get_iovar_buffer_with_param(whd_interface_t ifp, const * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_wifi_version(whd_interface_t ifp, char *version, uint8_t length); +extern whd_result_t whd_wifi_get_wifi_version(whd_interface_t ifp, char *version, uint8_t length); /** Retrieves the WLAN CLM version * @@ -1142,7 +1511,7 @@ extern uint32_t whd_wifi_get_wifi_version(whd_interface_t ifp, char *version, ui * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_clm_version(whd_interface_t ifp, char *version, uint8_t length); +extern whd_result_t whd_wifi_get_clm_version(whd_interface_t ifp, char *version, uint8_t length); /** To print whd log information * @@ -1152,7 +1521,7 @@ extern uint32_t whd_wifi_get_clm_version(whd_interface_t ifp, char *version, uin * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_read_wlan_log(whd_driver_t whd_drv, char *buffer, uint32_t buffer_size); +extern whd_result_t whd_wifi_read_wlan_log(whd_driver_t whd_drv, char *buffer, uint32_t buffer_size); /** To print whd log information * @@ -1160,7 +1529,7 @@ extern uint32_t whd_wifi_read_wlan_log(whd_driver_t whd_drv, char *buffer, uint3 * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_print_whd_log(whd_driver_t whd_drv); +extern whd_result_t whd_wifi_print_whd_log(whd_driver_t whd_drv); /** Retrieves the ifidx from interface pointer. * ifidx is a unique value and be used to identify a instance of tcp/ip stack @@ -1170,7 +1539,7 @@ extern uint32_t whd_wifi_print_whd_log(whd_driver_t whd_drv); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_network_get_ifidx_from_ifp(whd_interface_t ifp, uint8_t *ifidx); +extern whd_result_t whd_network_get_ifidx_from_ifp(whd_interface_t ifp, uint8_t *ifidx); /** Retrieves the bsscfgidx from interface pointer. * @@ -1181,7 +1550,7 @@ extern uint32_t whd_network_get_ifidx_from_ifp(whd_interface_t ifp, uint8_t *ifi * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_network_get_bsscfgidx_from_ifp(whd_interface_t ifp, uint8_t *bsscfgidx); +extern whd_result_t whd_network_get_bsscfgidx_from_ifp(whd_interface_t ifp, uint8_t *bsscfgidx); /** Retrieves the bss info @@ -1191,7 +1560,7 @@ extern uint32_t whd_network_get_bsscfgidx_from_ifp(whd_interface_t ifp, uint8_t * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_wifi_get_bss_info(whd_interface_t ifp, wl_bss_info_t *bi); +extern whd_result_t whd_wifi_get_bss_info(whd_interface_t ifp, wl_bss_info_t *bi); /** Prints WHD stats * @@ -1200,13 +1569,57 @@ extern uint32_t whd_wifi_get_bss_info(whd_interface_t ifp, wl_bss_info_t *bi); * * @return WHD_SUCCESS or Error code */ -extern uint32_t whd_print_stats(whd_driver_t whd_drv, whd_bool_t reset_after_print); +extern whd_result_t whd_print_stats(whd_driver_t whd_drv, whd_bool_t reset_after_print); -extern uint32_t whd_print_wlan_log(whd_driver_t whd_drv); +extern whd_result_t whd_print_wlan_log(whd_driver_t whd_drv); + +extern whd_result_t whd_wifi_print_wlan_log(whd_interface_t ifp); + +/** Fetches ulp statistics and fills the buffer with that data and executes deepsleep + * indication callback if application registers for it + * + * @param whd_driver Instance of whd driver + * @param buf Pointer to buffer to be filled with ulpstats data + * @param buflen Buffer length of the above buffer + * should be between 2048 and 4096 + * + * @return WHD_SUCCESS or Error code + */ +extern whd_result_t whd_wifi_get_deepsleep_stats(whd_driver_t whd_driver, char *buf, uint32_t buflen); + +/* Function pointer to be used callback registration */ +typedef void* (*whd_ds_callback_t)(void*, char*, uint32_t); + +/* Structure to store callback registration and parameters */ +typedef struct deepsleep_cb_info { + whd_ds_callback_t callback; + void* ctx; + char* buf; + uint32_t buflen; +} deepsleep_cb_info_t ; + +/** Function to register callbacks to be executed + * + * @param ifp Pointer to handle instance of whd interface + * @param callback Callback api to be registered + * @param ctx Pointer to context + * @param buf Buffer to be filled with data + * @param buflen Buffer length of the above buffer + * + * @return WHD_SUCCESS or WHD_UNKNOWN_INTERFACE + */ +extern whd_result_t whd_wifi_register_ds_callback(whd_interface_t ifp, whd_ds_callback_t callback, void *ctx, char* buf, uint32_t buflen); + +/** Function to unregister callbacks that are note needed to be executed anymore + * + * @param ifp Pointer to handle instance of whd interface + * @param callback Callback api to be registered + * + * @return WHD_SUCCESS or WHD_UNKNOWN_INTERFACE + */ +extern whd_result_t whd_wifi_deregister_ds_callback(whd_interface_t ifp, whd_ds_callback_t callback); -extern uint32_t whd_wifi_print_wlan_log(whd_interface_t ifp); -/* @} */ /* @} */ #ifdef __cplusplus diff --git a/wi-fi/whd/whd_wifi_p2p.c b/wi-fi/whd/whd_wifi_p2p.c index ddd23c15..677eddd0 100644 --- a/wi-fi/whd/whd_wifi_p2p.c +++ b/wi-fi/whd/whd_wifi_p2p.c @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,9 @@ #include "whd_chip_constants.h" #include "whd_debug.h" #include "whd_events_int.h" +#ifndef PROTO_MSGBUF #include "whd_sdpcm.h" +#endif /* PROTO_MSGBUF */ #include "whd_thread_internal.h" #include "whd_utils.h" #include "whd_wifi_api.h" @@ -32,12 +34,13 @@ whd_bool_t whd_wifi_p2p_is_go_up(whd_driver_t whd_driver) { - return whd_driver->internal_info.whd_wifi_p2p_go_is_up; + return whd_driver->internal_info.whd_wifi_p2p_go_is_up; } void whd_wifi_p2p_set_go_is_up(whd_driver_t whd_driver, whd_bool_t is_up) { - if (whd_driver->internal_info.whd_wifi_p2p_go_is_up != is_up) { - whd_driver->internal_info.whd_wifi_p2p_go_is_up = is_up; - } + if (whd_driver->internal_info.whd_wifi_p2p_go_is_up != is_up) + { + whd_driver->internal_info.whd_wifi_p2p_go_is_up = is_up; + } } diff --git a/wi-fi/whd/whd_wifi_p2p.h b/wi-fi/whd/whd_wifi_p2p.h index 484f17aa..952a7866 100644 --- a/wi-fi/whd/whd_wifi_p2p.h +++ b/wi-fi/whd/whd_wifi_p2p.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,8 @@ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /** @cond !ADDTHIS*/ diff --git a/wi-fi/whd/whd_wlioctl.h b/wi-fi/whd/whd_wlioctl.h index 61b7d0a6..09490986 100644 --- a/wi-fi/whd/whd_wlioctl.h +++ b/wi-fi/whd/whd_wlioctl.h @@ -1,5 +1,5 @@ /* - * Copyright 2021, Cypress Semiconductor Corporation (an Infineon company) + * Copyright 2024, Cypress Semiconductor Corporation (an Infineon company) * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,178 +21,542 @@ #ifndef INCLUDED_WHD_WLIOCTL_H #define INCLUDED_WHD_WLIOCTL_H +#include + +#include "whd_types.h" + #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* These are the flags in the BSS Capability Information field as defined in section 7.3.1.4 of IEEE Std 802.11-2007 */ -#define DOT11_CAP_ESS (0x0001) /** Extended service set capability */ -#define DOT11_CAP_IBSS (0x0002) /** Ad-hoc capability (Independent Basic Service Set) */ -#define DOT11_CAP_PRIVACY (0x0010) /** Privacy subfield - indicates data confidentiality is required for all data frames exchanged */ +#define DOT11_CAP_ESS (0x0001) /** Extended service set capability */ +#define DOT11_CAP_IBSS (0x0002) /** Ad-hoc capability (Independent Basic Service Set) */ +#define DOT11_CAP_PRIVACY (0x0010) /** Privacy subfield - indicates data confidentiality is required for all data frames exchanged */ + +#define CH_MAX_2G_CHANNEL (14) /* Max channel in 2G band */ +#define MAX_WFDS_SVC_NAME_LEN (200) /* maximum service_name length */ -#define CH_MAX_2G_CHANNEL (14) /* Max channel in 2G band */ -#define MAX_WFDS_SVC_NAME_LEN (200) /* maximum service_name length */ +#define MGMT_AUTH_FRAME_DWELL_TIME (100) /* Default Dwell Time(Let FW MSCH have enough left time to piggyback this "mgmt_frame" request within "join" request) */ #define ACTION_FRAME_SIZE 1040 +#define WL_KEEP_ALIVE_FIXED_LEN offsetof(wl_keep_alive_pkt_t, data) typedef uint16_t chanspec_t; -#define ETHER_ADDR_LEN 6 +#define ETHER_ADDR_LEN 6 -typedef struct ether_addr { - uint8_t octet[ETHER_ADDR_LEN]; +typedef struct ether_addr +{ + uint8_t octet[ETHER_ADDR_LEN]; } wl_ether_addr_t; -struct wl_ether_header { - uint8_t ether_dhost[ETHER_ADDR_LEN]; - uint8_t ether_shost[ETHER_ADDR_LEN]; - uint16_t ether_type; +struct wl_ether_header +{ + uint8_t ether_dhost[ETHER_ADDR_LEN]; + uint8_t ether_shost[ETHER_ADDR_LEN]; + uint16_t ether_type; }; -typedef struct wl_action_frame { - wl_ether_addr_t da; - uint16_t len; - uint32_t packetId; - uint8_t data[ACTION_FRAME_SIZE]; +typedef struct wl_action_frame +{ + wl_ether_addr_t da; + uint16_t len; + uint32_t packetId; + uint8_t data[ACTION_FRAME_SIZE]; } wl_action_frame_t; -typedef struct wl_af_params { - uint32_t channel; - int32_t dwell_time; - struct ether_addr BSSID; - wl_action_frame_t action_frame; +typedef struct wl_af_params +{ + uint32_t channel; + int32_t dwell_time; + struct ether_addr BSSID; + wl_action_frame_t action_frame; } wl_af_params_t; +typedef struct wl_rx_mgmt_data +{ + uint16_t version; + uint16_t channel; + int32_t rssi; + uint32_t mactime; + uint32_t rate; +} wl_rx_mgmt_data_t; + +/* tlv used to return wl_wsec_info properties */ +typedef struct wl_wsec_info_tlv { + uint16_t type; + uint16_t len; /* data length */ + uint8_t data[1]; /* data follows */ +}wl_wsec_info_tlv_t; + +/* input/output data type for wsec_info iovar */ +typedef struct wl_wsec_info { + uint8_t version; /* structure version */ + uint8_t pad[2]; + uint8_t num_tlvs; + wl_wsec_info_tlv_t tlvs[1]; /* tlv data follows */ +}wl_wsec_info_t; + +/* algo bit vector */ +#define KEY_ALGO_MASK(_algo) (1 << (_algo)) +/* version of the wl_wsec_info structure */ +#define WL_WSEC_INFO_VERSION 0x01 +#define CRYPTO_ALGO_AES_GCM 14 /* 128 bit GCM */ +#define CRYPTO_ALGO_AES_CCM256 15 /* 256 bit CCM */ +#define CRYPTO_ALGO_AES_GCM256 16 /* 256 bit GCM */ +#define CRYPTO_ALGO_BIP_CMAC256 17 /* 256 bit BIP CMAC */ +#define CRYPTO_ALGO_BIP_GMAC 18 /* 128 bit BIP GMAC */ +#define CRYPTO_ALGO_BIP_GMAC256 19 /* 256 bit BIP GMAC */ + +/* start enum value for BSS properties */ +#define WL_WSEC_INFO_BSS_BASE 0x0100 +#define WL_WSEC_INFO_BSS_ALGOS (WL_WSEC_INFO_BSS_BASE + 6) + #define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params) +/* External Auth Code Type(SAE) */ +#define WL_EXTAUTH_START 1 +#define WL_EXTAUTH_ABORT 2 +#define WL_EXTAUTH_FAIL 3 +#define WL_EXTAUTH_SUCCESS 4 + +/* HE top level command IDs */ +enum +{ + /* 0-12 Reserved */ + WL_HE_CMD_OMI = 13, + /* 14-27 Reserved */ + WL_HE_CMD_MUEDCA_OPT = 28, + WL_HE_CMD_LAST +}; + +#define INVALID_HE_OMI_ARG 255 + +#define WL_HE_OMI_V1 1 +typedef struct wl_he_omi_v1 +{ + uint8_t version; + uint8_t length; + uint8_t rx_nss; + uint8_t chnl_wdth; + uint8_t ul_mu_dis; + uint8_t tx_nsts; + uint8_t er_su_dis; + uint8_t dl_mu_resound; + uint8_t ul_mu_data_dis; +} wl_he_omi_v1_t; + +#define WL_HE_OMI_VER (WL_HE_OMI_V1) +typedef wl_he_omi_v1_t wl_he_omi_t; + +/* TWT top level command IDs */ +enum +{ + WL_TWT_CMD_ENAB = 0, + WL_TWT_CMD_SETUP = 1, + WL_TWT_CMD_TEARDOWN = 2, + WL_TWT_CMD_INFO = 3, + WL_TWT_CMD_AUTOSCHED = 4, + WL_TWT_CMD_STATS = 5, + WL_TWT_CMD_EARLY_TERM_TIME = 6, + WL_TWT_CMD_RESP_CONFIG = 7, + WL_TWT_CMD_SPPS_ENAB = 8, + WL_TWT_CMD_FEATURES = 9, + WL_TWT_CMD_LAST +}; + +/* Setup Command field (Table 9-262k) */ +#define TWT_SETUP_CMD_REQUEST_TWT 0u /* Request TWT */ +#define TWT_SETUP_CMD_SUGGEST_TWT 1u /* Suggest TWT */ +#define TWT_SETUP_CMD_DEMAND_TWT 2u /* Demand TWT */ +#define TWT_SETUP_CMD_GROUPING_TWT 3u /* Grouping TWT */ +#define TWT_SETUP_CMD_ACCEPT_TWT 4u /* Accept TWT */ +#define TWT_SETUP_CMD_ALTERNATE_TWT 5u /* Alternate TWT */ +#define TWT_SETUP_CMD_DICTATE_TWT 6u /* Dictate TWT */ +#define TWT_SETUP_CMD_REJECT_TWT 7u /* Reject TWT */ + +typedef enum keep_alive +{ + WHD_KEEPALIVE_NULL = 0, + WHD_KEEPALIVE_NAT = 1, +}keepaliveType_t; + +typedef enum twt_ctrl_nego_type +{ + TWT_CTRL_NEGO_TYPE_0 = 0, /* Individual TWT Setup */ + TWT_CTRL_NEGO_TYPE_1 = 1, /* Wake TBTT Negotiation */ + TWT_CTRL_NEGO_TYPE_2 = 2, /* Broadcast TWT IE in Beacon */ + TWT_CTRL_NEGO_TYPE_3 = 3, /* Broadcast TWT memberships */ +} twt_ctrl_nego_type_t; + +/* TWT Setup descriptor */ +typedef struct wl_twt_sdesc +{ + /* Setup Command. */ + uint8_t setup_cmd; /* See TWT_SETUP_CMD_XXXX in 802.11ah.h */ + uint8_t flow_flags; /* Flow attributes. See WL_TWT_FLOW_FLAG_XXXX below */ + uint8_t flow_id; /* must be between 0 and 7. Set 0xFF for auto assignment */ + uint8_t wake_type; /* See WL_TWT_TIME_TYPE_XXXX below */ + uint32_t wake_time_h; /* target wake time - BSS TSF (us) */ + uint32_t wake_time_l; + uint32_t wake_dur; /* target wake duration in unit of microseconds */ + uint32_t wake_int; /* target wake interval */ + uint32_t btwt_persistence; /* Broadcast TWT Persistence */ + uint32_t wake_int_max; /* max wake interval(uS) for TWT */ + uint8_t duty_cycle_min; /* min duty cycle for TWT(Percentage) */ + uint8_t pad; + uint8_t bid; /* must be between 0 and 31. Set 0xFF for auto assignment */ + uint8_t channel; /* Twt channel - Not used for now */ + uint8_t negotiation_type; /* Negotiation Type: See macros TWT_NEGO_TYPE_X */ + uint8_t frame_recomm; /* frame recommendation for broadcast TWTs - Not used for now */ + /* deprecated - to be removed */ + uint16_t li; +} wl_twt_sdesc_t; + +#define WL_TWT_FLOW_FLAG_BROADCAST (1 << 0) +#define WL_TWT_FLOW_FLAG_IMPLICIT (1 << 1) +#define WL_TWT_FLOW_FLAG_UNANNOUNCED (1 << 2) +#define WL_TWT_FLOW_FLAG_TRIGGER (1 << 3) +#define WL_TWT_FLOW_FLAG_WAKE_TBTT_NEGO (1 << 4) +#define WL_TWT_FLOW_FLAG_REQUEST (1 << 5) + +#define WL_TWT_FLOW_FLAG_PROTECT (1u << 0u) +#define WL_TWT_FLOW_FLAG_RESPONDER_PM (1u << 6u) +#define WL_TWT_FLOW_FLAG_UNSOLICITED (1u << 7u) + +/* Flow id */ +#define WL_TWT_FLOW_ID_FID 0x07u /* flow id */ +#define WL_TWT_FLOW_ID_GID_MASK 0x70u /* group id - broadcast TWT only */ +#define WL_TWT_FLOW_ID_GID_SHIFT 4u + +#define WL_TWT_INV_BCAST_ID 0xFFu +#define WL_TWT_INV_FLOW_ID 0xFFu + +/* auto flow_id */ +#define WL_TWT_SETUP_FLOW_ID_AUTO 0xFFu +/* auto broadcast ID */ +#define WL_TWT_SETUP_BCAST_ID_AUTO 0xFFu +/* Infinite persistence for broadcast schedule */ +#define WL_TWT_INFINITE_BTWT_PERSIST 0xFFFFFFFFu + +/* Wake type */ +#define WL_TWT_TIME_TYPE_BSS 0u +#define WL_TWT_TIME_TYPE_OFFSET 1u +#define WL_TWT_TIME_TYPE_AUTO 2u + +#define WL_TWT_SETUP_VER 0u + +/* HE TWT Setup command */ +typedef struct wl_twt_setup +{ + /* structure control */ + uint16_t version; /* structure version */ + uint16_t length; /* data length (starting after this field) */ + /* peer address */ + wl_ether_addr_t peer; /* leave it all 0s' for AP */ + uint8_t pad[2]; + /* setup descriptor */ + wl_twt_sdesc_t desc; + /* deprecated - to be removed */ + uint16_t dialog; + uint8_t pad1[2]; +} wl_twt_setup_t; + +/* deprecated -to be removed */ +#define WL_TWT_DIALOG_TOKEN_AUTO 0xFFFF + +#define WL_TWT_TEARDOWN_VER 0u + +/* twt teardown descriptor */ +typedef struct wl_twt_teardesc +{ + uint8_t negotiation_type; + uint8_t flow_id; /* must be between 0 and 7 */ + uint8_t bid; /* must be between 0 and 31 */ + uint8_t alltwt; /* all twt teardown - 0 or 1 */ +} wl_twt_teardesc_t; + +/* HE TWT Teardown command */ +typedef struct wl_twt_teardown +{ + /* structure control */ + uint16_t version; /* structure version */ + uint16_t length; /* data length (starting after this field) */ + /* peer address */ + wl_ether_addr_t peer; /* leave it all 0s' for AP */ + wl_twt_teardesc_t teardesc; /* Teardown descriptor */ + + /* deprecated - to be removed */ + uint8_t flow_flags; + uint8_t flow_id; + uint8_t bid; + uint8_t pad; +} wl_twt_teardown_t; + +/* twt information descriptor */ +typedef struct wl_twt_infodesc +{ + uint8_t flow_flags; /* See WL_TWT_INFO_FLAG_XXX below */ + uint8_t flow_id; + uint8_t pad[2]; + uint32_t next_twt_h; + uint32_t next_twt_l; + /* deprecated - to be removed */ + uint8_t wake_type; + uint8_t pad1[3]; +} wl_twt_infodesc_t; + +/* Flow flags */ +#define WL_TWT_INFO_FLAG_ALL_TWT (1u << 0u) /* All TWT */ +#define WL_TWT_INFO_FLAG_RESUME (1u << 1u) /* 1 is TWT Resume, 0 is TWT Suspend */ + +/* deprecated - to be removed */ +#define WL_TWT_INFO_FLAG_RESP_REQ (1 << 0) /* Response Requested */ +#define WL_TWT_INFO_FLAG_NEXT_TWT_REQ (1 << 1) /* Next TWT Request */ +#define WL_TWT_INFO_FLAG_BTWT_RESCHED (1 << 2) /* Broadcast Reschedule */ +typedef wl_twt_infodesc_t wl_twt_idesc_t; + +#define WL_TWT_INFO_VER 0u + +/* HE TWT Information command */ +typedef struct wl_twt_info +{ + /* structure control */ + uint16_t version; /* structure version */ + uint16_t length; /* data length (starting after this field) */ + /* peer address */ + wl_ether_addr_t peer; /* leave it all 0s' for AP */ + uint8_t pad[2]; + wl_twt_infodesc_t infodesc; /* information descriptor */ + /* deprecated - to be removed */ + wl_twt_idesc_t desc; +} wl_twt_info_t; + +#define WL_MBO_IOV_MAJOR_VER 1 +#define WL_MBO_IOV_MINOR_VER 1 +#define WL_MBO_IOV_MAJOR_VER_SHIFT 8 +#define WL_MBO_IOV_VERSION \ + ((WL_MBO_IOV_MAJOR_VER << WL_MBO_IOV_MAJOR_VER_SHIFT)| WL_MBO_IOV_MINOR_VER) + +enum wl_mbo_cmd_ids { + WL_MBO_CMD_ADD_CHAN_PREF = 1, + WL_MBO_CMD_DEL_CHAN_PREF = 2, + WL_MBO_CMD_LIST_CHAN_PREF = 3, + WL_MBO_CMD_CELLULAR_DATA_CAP = 4, + WL_MBO_CMD_DUMP_COUNTERS = 5, + WL_MBO_CMD_CLEAR_COUNTERS = 6, + WL_MBO_CMD_FORCE_ASSOC = 7, + WL_MBO_CMD_BSSTRANS_REJECT = 8, + WL_MBO_CMD_SEND_NOTIF = 9, + /* Unused command, This enum no can be use + * for next new command + */ + WL_MBO_CMD_CLEAR_CHAN_PREF = 10, + WL_MBO_CMD_NBR_INFO_CACHE = 11, + WL_MBO_CMD_ANQPO_SUPPORT = 12, + WL_MBO_CMD_DBG_EVENT_CHECK = 13, + WL_MBO_CMD_EVENT_MASK = 14, + WL_MBO_CMD_ASSOC_DISALLOWED = 15, + WL_MBO_CMD_CELLULAR_DATA_PREF = 16, + WL_MBO_CMD_ENABLE = 17, + /* Add before this !! */ + WL_MBO_CMD_LAST +}; + +enum wl_mbo_xtlv_id { + WL_MBO_XTLV_OPCLASS = 0x1, + WL_MBO_XTLV_CHAN = 0x2, + WL_MBO_XTLV_PREFERENCE = 0x3, + WL_MBO_XTLV_REASON_CODE = 0x4, + WL_MBO_XTLV_CELL_DATA_CAP = 0x5, + WL_MBO_XTLV_COUNTERS = 0x6, + WL_MBO_XTLV_ENABLE = 0x7, + WL_MBO_XTLV_SUB_ELEM_TYPE = 0x8, + WL_MBO_XTLV_BTQ_TRIG_START_OFFSET = 0x9, + WL_MBO_XTLV_BTQ_TRIG_RSSI_DELTA = 0xa, + WL_MBO_XTLV_ANQP_CELL_SUPP = 0xb, + WL_MBO_XTLV_BIT_MASK = 0xc, + WL_MBO_XTLV_ASSOC_DISALLOWED = 0xd, + WL_MBO_XTLV_CELLULAR_DATA_PREF = 0xe +}; + +typedef struct whd_iov_buf +{ + uint16_t version; + uint16_t len; + uint16_t id; + uint16_t data[1]; +} whd_iov_buf_t; + +typedef struct mbo_xtlv +{ + uint16_t id; + uint16_t len; + uint32_t data[1]; +} mbo_xtlv_t; + +/* MBO add Channel Preference */ +typedef struct mbo_add_chan_pref { + mbo_xtlv_t opclass; + mbo_xtlv_t chan; + mbo_xtlv_t pref; + mbo_xtlv_t reason; +} mbo_add_chan_pref_t; + +/* MBO delete Channel Preference */ +typedef struct mbo_del_chan_pref { + mbo_xtlv_t opclass; + mbo_xtlv_t chan; +} mbo_del_chan_pref_t; + +typedef struct whd_xtlv +{ + uint16_t id; + uint16_t len; + uint8_t data[1]; +} whd_xtlv_t; + /* ether types */ -#define ETHER_TYPE_LEN 2 -#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ -#define ETHER_TYPE_IP 0x0800 /* IP */ -#define ETHER_TYPE_ARP 0x0806 /* ARP */ -#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ -#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ -#define ETHER_TYPE_WAI 0x88b4 /* WAPI WAI */ -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ +#define ETHER_TYPE_LEN 2 +#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */ +#define ETHER_TYPE_IP 0x0800 /* IP */ +#define ETHER_TYPE_ARP 0x0806 /* ARP */ +#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ +#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ +#define ETHER_TYPE_WAI 0x88b4 /* WAPI WAI */ +#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ #define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame) #define BWL_DEFAULT_PACKING -#define RWL_ACTION_WIFI_CATEGORY 127 -#define RWL_WIFI_OUI_BYTE1 0x90 -#define RWL_WIFI_OUI_BYTE2 0x4C -#define RWL_WIFI_OUI_BYTE3 0x0F -#define RWL_WIFI_ACTION_FRAME_SIZE sizeof(struct dot11_action_wifi_vendor_specific) -#define RWL_WIFI_DEFAULT 0x00 -#define RWL_WIFI_FIND_MY_PEER 0x09 +#define RWL_ACTION_WIFI_CATEGORY 127 +#define RWL_WIFI_OUI_BYTE1 0x90 +#define RWL_WIFI_OUI_BYTE2 0x4C +#define RWL_WIFI_OUI_BYTE3 0x0F +#define RWL_WIFI_ACTION_FRAME_SIZE sizeof(struct dot11_action_wifi_vendor_specific) +#define RWL_WIFI_DEFAULT 0x00 +#define RWL_WIFI_FIND_MY_PEER 0x09 #define RWL_WIFI_FOUND_PEER 0x0A -#define RWL_ACTION_WIFI_FRAG_TYPE 0x55 +#define RWL_ACTION_WIFI_FRAG_TYPE 0x55 -typedef struct ssid_info { - uint8_t ssid_len; - uint8_t ssid[32]; +typedef struct ssid_info +{ + uint8_t ssid_len; + uint8_t ssid[32]; } ssid_info_t; -typedef struct cnt_rx { - uint32_t cnt_rxundec; - uint32_t cnt_rxframe; +typedef struct cnt_rx +{ + uint32_t cnt_rxundec; + uint32_t cnt_rxframe; } cnt_rx_t; -#define RWL_REF_MAC_ADDRESS_OFFSET 17 -#define RWL_DUT_MAC_ADDRESS_OFFSET 23 -#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50 -#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51 -#define WL_BSS_INFO_VERSION 109 -#define MCSSET_LEN 16 - -typedef struct wlc_ssid { - uint32_t SSID_len; - uint8_t SSID[32]; +#define RWL_REF_MAC_ADDRESS_OFFSET 17 +#define RWL_DUT_MAC_ADDRESS_OFFSET 23 +#define RWL_WIFI_CLIENT_CHANNEL_OFFSET 50 +#define RWL_WIFI_SERVER_CHANNEL_OFFSET 51 +#define WL_BSS_INFO_VERSION 109 +#define MCSSET_LEN 16 + +typedef struct wlc_ssid +{ + uint32_t SSID_len; + uint8_t SSID[32]; } wlc_ssid_t; -#define WL_BSSTYPE_INFRA 1 -#define WL_BSSTYPE_INDEP 0 -#define WL_BSSTYPE_ANY 2 -#define WL_SCANFLAGS_PASSIVE 0x01 -#define WL_SCANFLAGS_PROHIBITED 0x04 -typedef struct wl_scan_params { - wlc_ssid_t ssid; - wl_ether_addr_t bssid; - int8_t bss_type; - int8_t scan_type; - int32_t nprobes; - int32_t active_time; - int32_t passive_time; - int32_t home_time; - int32_t channel_num; - uint16_t channel_list[1]; +#define WL_BSSTYPE_INFRA 1 +#define WL_BSSTYPE_INDEP 0 +#define WL_BSSTYPE_ANY 2 +#define WL_SCANFLAGS_PASSIVE 0x01 +#define WL_SCANFLAGS_PROHIBITED 0x04 +typedef struct wl_scan_params +{ + wlc_ssid_t ssid; + wl_ether_addr_t bssid; + int8_t bss_type; + int8_t scan_type; + int32_t nprobes; + int32_t active_time; + int32_t passive_time; + int32_t home_time; + int32_t channel_num; + uint16_t channel_list[1]; } wl_scan_params_t; -#define WL_SCAN_PARAMS_FIXED_SIZE (64) +#define WL_SCAN_PARAMS_FIXED_SIZE (64) #define WL_SCAN_PARAMS_COUNT_MASK (0x0000ffff) -#define WL_SCAN_PARAMS_NSSID_SHIFT (16) -#define WL_SCAN_ACTION_START (1) -#define WL_SCAN_ACTION_CONTINUE (2) -#define WL_SCAN_ACTION_ABORT (3) -#define ISCAN_REQ_VERSION (1) -typedef struct wl_iscan_params { - uint32_t version; - uint16_t action; - uint16_t scan_duration; - wl_scan_params_t params; +#define WL_SCAN_PARAMS_NSSID_SHIFT (16) +#define WL_SCAN_ACTION_START (1) +#define WL_SCAN_ACTION_CONTINUE (2) +#define WL_SCAN_ACTION_ABORT (3) +#define ISCAN_REQ_VERSION (1) +typedef struct wl_iscan_params +{ + uint32_t version; + uint16_t action; + uint16_t scan_duration; + wl_scan_params_t params; } wl_iscan_params_t; -#define WL_ISCAN_PARAMS_FIXED_SIZE (offsetof(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) -typedef struct wl_scan_results { - uint32_t buflen; - uint32_t version; - uint32_t count; - wl_bss_info_t bss_info[1]; +#define WL_ISCAN_PARAMS_FIXED_SIZE (offsetof(wl_iscan_params_t, params) + sizeof(wlc_ssid_t) ) +typedef struct wl_scan_results +{ + uint32_t buflen; + uint32_t version; + uint32_t count; + wl_bss_info_t bss_info[1]; } wl_scan_results_t; -#define WL_SCAN_RESULTS_FIXED_SIZE (12) -#define WL_SCAN_RESULTS_SUCCESS (0) -#define WL_SCAN_RESULTS_PARTIAL (1) -#define WL_SCAN_RESULTS_PENDING (2) -#define WL_SCAN_RESULTS_ABORTED (3) -#define WL_SCAN_RESULTS_NO_MEM (4) -#define ESCAN_REQ_VERSION 1 -typedef struct wl_escan_params { - uint32_t version; - uint16_t action; - uint16_t sync_id; - wl_scan_params_t params; +#define WL_SCAN_RESULTS_FIXED_SIZE (12) +#define WL_SCAN_RESULTS_SUCCESS (0) +#define WL_SCAN_RESULTS_PARTIAL (1) +#define WL_SCAN_RESULTS_PENDING (2) +#define WL_SCAN_RESULTS_ABORTED (3) +#define WL_SCAN_RESULTS_NO_MEM (4) +#define ESCAN_REQ_VERSION 1 +typedef struct wl_escan_params +{ + uint32_t version; + uint16_t action; + uint16_t sync_id; + wl_scan_params_t params; } wl_escan_params_t; -#define WL_ESCAN_PARAMS_FIXED_SIZE (offsetof(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) -typedef struct wl_escan_result { - uint32_t buflen; - uint32_t version; - uint16_t sync_id; - uint16_t bss_count; - wl_bss_info_t bss_info[1]; +#define WL_ESCAN_PARAMS_FIXED_SIZE (offsetof(wl_escan_params_t, params) + sizeof(wlc_ssid_t) ) +typedef struct wl_escan_result +{ + uint32_t buflen; + uint32_t version; + uint16_t sync_id; + uint16_t bss_count; + wl_bss_info_t bss_info[1]; } wl_escan_result_t; -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) -typedef struct wl_iscan_results { - uint32_t status; - wl_scan_results_t results; +#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t) ) +typedef struct wl_iscan_results +{ + uint32_t status; + wl_scan_results_t results; } wl_iscan_results_t; #define WL_ISCAN_RESULTS_FIXED_SIZE \ - (WL_SCAN_RESULTS_FIXED_SIZE + offsetof(wl_iscan_results_t, results)) -#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ -typedef struct wl_rateset { - uint32_t count; /* # rates in this set */ - uint8_t rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ + (WL_SCAN_RESULTS_FIXED_SIZE + offsetof(wl_iscan_results_t, results) ) +#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */ +typedef struct wl_rateset +{ + uint32_t count; /* # rates in this set */ + uint8_t rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ } wl_rateset_t; -typedef struct wl_rateset_args { - uint32_t count; /* # rates in this set */ - uint8_t rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ - uint8_t mcs[WL_MAXRATES_IN_SET]; /* supported mcs index bit map */ +typedef struct wl_rateset_args +{ + uint32_t count; /* # rates in this set */ + uint8_t rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */ + uint8_t mcs[WL_MAXRATES_IN_SET]; /* supported mcs index bit map */ } wl_rateset_args_t; -#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ -#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ -#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ -#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ +#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */ +#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */ +#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */ +#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */ #define WL_RSPEC_TXEXP_MASK 0x00000300 #define WL_RSPEC_TXEXP_SHIFT 8 -#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ -#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ -#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ -#define WL_RSPEC_TXBF 0x00200000 /* bit indicates TXBF mode */ -#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ -#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ -#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ -#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ -#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ +#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */ +#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */ +#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */ +#define WL_RSPEC_TXBF 0x00200000 /* bit indicates TXBF mode */ +#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */ +#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */ +#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */ +#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */ +#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */ #define WL_RSPEC_BW_UNSPECIFIED 0 #define WL_RSPEC_BW_20MHZ 0x00010000 #define WL_RSPEC_BW_40MHZ 0x00020000 @@ -201,223 +565,233 @@ typedef struct wl_rateset_args { #define WL_RSPEC_BW_10MHZ 0x00050000 #define WL_RSPEC_BW_5MHZ 0x00060000 #define WL_RSPEC_BW_2P5MHZ 0x00070000 -#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ -#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ -#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */ -typedef struct wl_uint32_list { - uint32_t count; - uint32_t element[1]; +typedef struct wl_uint32_list +{ + uint32_t count; + uint32_t element[1]; } wl_uint32_list_t; -typedef struct wl_join_scan_params { - uint8_t scan_type; /* 0 use default, active or passive scan */ - int32_t nprobes; /* -1 use default, number of probes per channel */ - int32_t active_time; /* -1 use default, dwell time per channel for +typedef struct wl_join_scan_params +{ + uint8_t scan_type; /* 0 use default, active or passive scan */ + int32_t nprobes; /* -1 use default, number of probes per channel */ + int32_t active_time; /* -1 use default, dwell time per channel for * active scanning */ - int32_t passive_time; /* -1 use default, dwell time per channel + int32_t passive_time; /* -1 use default, dwell time per channel * for passive scanning */ - int32_t home_time; /* -1 use default, dwell time for the home channel + int32_t home_time; /* -1 use default, dwell time for the home channel * between channel scans */ } wl_join_scan_params_t; -#define NRATE_MCS_INUSE (0x00000080) +#define NRATE_MCS_INUSE (0x00000080) #define NRATE_RATE_MASK (0x0000007f) -#define NRATE_STF_MASK (0x0000ff00) -#define NRATE_STF_SHIFT (8) -#define NRATE_OVERRIDE (0x80000000) -#define NRATE_OVERRIDE_MCS_ONLY (0x40000000) +#define NRATE_STF_MASK (0x0000ff00) +#define NRATE_STF_SHIFT (8) +#define NRATE_OVERRIDE (0x80000000) +#define NRATE_OVERRIDE_MCS_ONLY (0x40000000) #define NRATE_SGI_MASK (0x00800000) -#define NRATE_SGI_SHIFT (23) +#define NRATE_SGI_SHIFT (23) #define NRATE_LDPC_CODING (0x00400000) -#define NRATE_LDPC_SHIFT (22) +#define NRATE_LDPC_SHIFT (22) #define NRATE_BCMC_OVERRIDE (0x00200000) -#define NRATE_BCMC_SHIFT (21) -#define NRATE_STF_SISO (0) -#define NRATE_STF_CDD (1) -#define NRATE_STF_STBC (2) -#define NRATE_STF_SDM (3) -#define ANTENNA_NUM_1 (1) -#define ANTENNA_NUM_2 (2) -#define ANTENNA_NUM_3 (3) -#define ANTENNA_NUM_4 (4) -#define ANT_SELCFG_AUTO (0x80) -#define ANT_SELCFG_MASK (0x33) -#define ANT_SELCFG_MAX (4) -#define ANT_SELCFG_TX_UNICAST (0) -#define ANT_SELCFG_RX_UNICAST (1) -#define ANT_SELCFG_TX_DEF (2) -#define ANT_SELCFG_RX_DEF (3) +#define NRATE_BCMC_SHIFT (21) +#define NRATE_STF_SISO (0) +#define NRATE_STF_CDD (1) +#define NRATE_STF_STBC (2) +#define NRATE_STF_SDM (3) +#define ANTENNA_NUM_1 (1) +#define ANTENNA_NUM_2 (2) +#define ANTENNA_NUM_3 (3) +#define ANTENNA_NUM_4 (4) +#define ANT_SELCFG_AUTO (0x80) +#define ANT_SELCFG_MASK (0x33) +#define ANT_SELCFG_MAX (4) +#define ANT_SELCFG_TX_UNICAST (0) +#define ANT_SELCFG_RX_UNICAST (1) +#define ANT_SELCFG_TX_DEF (2) +#define ANT_SELCFG_RX_DEF (3) typedef struct { - uint8_t ant_config[ANT_SELCFG_MAX]; - uint8_t num_antcfg; + uint8_t ant_config[ANT_SELCFG_MAX]; + uint8_t num_antcfg; } wlc_antselcfg_t; -#define HIGHEST_SINGLE_STREAM_MCS (7) -#define WLC_CNTRY_BUF_SZ (4) -typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - int32_t rev; - char ccode[WLC_CNTRY_BUF_SZ]; +#define HIGHEST_SINGLE_STREAM_MCS (7) +#define WLC_CNTRY_BUF_SZ (4) +typedef struct wl_country +{ + char country_abbrev[WLC_CNTRY_BUF_SZ]; + int32_t rev; + char ccode[WLC_CNTRY_BUF_SZ]; } wl_country_t; -typedef struct wl_channels_in_country { - uint32_t buflen; - uint32_t band; - int8_t country_abbrev[WLC_CNTRY_BUF_SZ]; - uint32_t count; - uint32_t channel[1]; +typedef struct wl_channels_in_country +{ + uint32_t buflen; + uint32_t band; + int8_t country_abbrev[WLC_CNTRY_BUF_SZ]; + uint32_t count; + uint32_t channel[1]; } wl_channels_in_country_t; -typedef struct wl_country_list { - uint32_t buflen; - uint32_t band_set; - uint32_t band; - uint32_t count; - int8_t country_abbrev[1]; +typedef struct wl_country_list +{ + uint32_t buflen; + uint32_t band_set; + uint32_t band; + uint32_t count; + int8_t country_abbrev[1]; } wl_country_list_t; -#define WL_NUM_RPI_BINS 8 -#define WL_RM_TYPE_BASIC 1 -#define WL_RM_TYPE_CCA 2 -#define WL_RM_TYPE_RPI 3 -#define WL_RM_FLAG_PARALLEL (1 << 0) -#define WL_RM_FLAG_LATE (1 << 1) -#define WL_RM_FLAG_INCAPABLE (1 << 2) -#define WL_RM_FLAG_REFUSED (1 << 3) -typedef struct wl_rm_req_elt { - int8_t type; - int8_t flags; - wl_chanspec_t chanspec; - uint32_t token; - uint32_t tsf_h; - uint32_t tsf_l; - uint32_t dur; +#define WL_NUM_RPI_BINS 8 +#define WL_RM_TYPE_BASIC 1 +#define WL_RM_TYPE_CCA 2 +#define WL_RM_TYPE_RPI 3 +#define WL_RM_FLAG_PARALLEL (1 << 0) +#define WL_RM_FLAG_LATE (1 << 1) +#define WL_RM_FLAG_INCAPABLE (1 << 2) +#define WL_RM_FLAG_REFUSED (1 << 3) +typedef struct wl_rm_req_elt +{ + int8_t type; + int8_t flags; + wl_chanspec_t chanspec; + uint32_t token; + uint32_t tsf_h; + uint32_t tsf_l; + uint32_t dur; } wl_rm_req_elt_t; -typedef struct wl_rm_req { - uint32_t token; - uint32_t count; - void *cb; - void *cb_arg; - wl_rm_req_elt_t req[1]; +typedef struct wl_rm_req +{ + uint32_t token; + uint32_t count; + void *cb; + void *cb_arg; + wl_rm_req_elt_t req[1]; } wl_rm_req_t; -#define WL_RM_REQ_FIXED_LEN offsetof(wl_rm_req_t, req) -typedef struct wl_rm_rep_elt { - int8_t type; - int8_t flags; - wl_chanspec_t chanspec; - uint32_t token; - uint32_t tsf_h; - uint32_t tsf_l; - uint32_t dur; - uint32_t len; - uint8_t data[1]; +#define WL_RM_REQ_FIXED_LEN offsetof(wl_rm_req_t, req) +typedef struct wl_rm_rep_elt +{ + int8_t type; + int8_t flags; + wl_chanspec_t chanspec; + uint32_t token; + uint32_t tsf_h; + uint32_t tsf_l; + uint32_t dur; + uint32_t len; + uint8_t data[1]; } wl_rm_rep_elt_t; -#define WL_RM_REP_ELT_FIXED_LEN 24 -#define WL_RPI_REP_BIN_NUM 8 -typedef struct wl_rm_rpi_rep { - uint8_t rpi[WL_RPI_REP_BIN_NUM]; - int8_t rpi_max[WL_RPI_REP_BIN_NUM]; +#define WL_RM_REP_ELT_FIXED_LEN 24 +#define WL_RPI_REP_BIN_NUM 8 +typedef struct wl_rm_rpi_rep +{ + uint8_t rpi[WL_RPI_REP_BIN_NUM]; + int8_t rpi_max[WL_RPI_REP_BIN_NUM]; } wl_rm_rpi_rep_t; -typedef struct wl_rm_rep { - uint32_t token; - uint32_t len; - wl_rm_rep_elt_t rep[1]; +typedef struct wl_rm_rep +{ + uint32_t token; + uint32_t len; + wl_rm_rep_elt_t rep[1]; } wl_rm_rep_t; -#define WL_RM_REP_FIXED_LEN 8 -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 -#define WL_SOFT_KEY (1 << 0) -#define WL_PRIMARY_KEY (1 << 1) -#define WL_KF_RES_4 (1 << 4) -#define WL_KF_RES_5 (1 << 5) -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) -#define DOT11_MAX_KEY_SIZE 32 -typedef struct wl_wsec_key { - uint32_t index; - uint32_t len; - uint8_t data[DOT11_MAX_KEY_SIZE]; - uint32_t pad_1[18]; - uint32_t algo; - uint32_t flags; - uint32_t pad_2[2]; - int32_t pad_3; - int32_t iv_initialized; - int32_t pad_4; - struct - { - uint32_t hi; - uint16_t lo; - } rxiv; - uint32_t pad_5[2]; - wl_ether_addr_t ea; +#define WL_RM_REP_FIXED_LEN 8 +#define CRYPTO_ALGO_OFF 0 +#define CRYPTO_ALGO_WEP1 1 +#define CRYPTO_ALGO_TKIP 2 +#define CRYPTO_ALGO_WEP128 3 +#define CRYPTO_ALGO_AES_CCM 4 +#define CRYPTO_ALGO_AES_OCB_MSDU 5 +#define CRYPTO_ALGO_AES_OCB_MPDU 6 +#define CRYPTO_ALGO_NALG 7 +#define WSEC_GEN_MIC_ERROR 0x0001 +#define WSEC_GEN_REPLAY 0x0002 +#define WSEC_GEN_ICV_ERROR 0x0004 +#define WL_SOFT_KEY (1 << 0) +#define WL_PRIMARY_KEY (1 << 1) +#define WL_KF_RES_4 (1 << 4) +#define WL_KF_RES_5 (1 << 5) +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) +#define DOT11_MAX_KEY_SIZE 32 +typedef struct wl_wsec_key +{ + uint32_t index; + uint32_t len; + uint8_t data[DOT11_MAX_KEY_SIZE]; + uint32_t pad_1[18]; + uint32_t algo; + uint32_t flags; + uint32_t pad_2[2]; + int32_t pad_3; + int32_t iv_initialized; + int32_t pad_4; + struct + { + uint32_t hi; + uint16_t lo; + } rxiv; + uint32_t pad_5[2]; + wl_ether_addr_t ea; } wl_wsec_key_t; -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 -#define WSEC_PASSPHRASE (1 << 0) +#define WSEC_MIN_PSK_LEN 8 +#define WSEC_MAX_PSK_LEN 64 +#define WSEC_PMK_LEN 32 +#define WSEC_PMK_WPA3_ENT_192_LEN 48 +#define WSEC_PMK_MAX_LEN 64 +#define WSEC_PASSPHRASE (1 << 0) typedef struct { - uint16_t key_len; - uint16_t flags; - uint8_t key[WSEC_MAX_PSK_LEN]; + uint16_t key_len; + uint16_t flags; + uint8_t key[WSEC_MAX_PSK_LEN + 1]; } wsec_pmk_t; -#define WSEC_MAX_SAE_PASSWORD_LEN 128 +#define WSEC_MAX_SAE_PASSWORD_LEN 128 typedef struct { - uint16_t password_len; /* octets in key materials */ - uint8_t password[WSEC_MAX_SAE_PASSWORD_LEN]; /* maximum key len for SAE passphrase */ + uint16_t password_len; /* octets in key materials */ + uint8_t password[WSEC_MAX_SAE_PASSWORD_LEN]; /* maximum key len for SAE passphrase */ } wsec_sae_password_t; -#define OPEN_AUTH 0x0000 -#define SHARED_AUTH 0x0001 +#define OPEN_AUTH 0x0000 +#define SHARED_AUTH 0x0001 //#define WEP_ENABLED 0x0001 // moved to whd_types.h //#define TKIP_ENABLED 0x0002 //#define AES_ENABLED 0x0004 -typedef enum { - AUTH_ALGO_80211_OPEN = 1, - AUTH_ALGO_80211_SHARED_KEY = 2, - AUTH_ALGO_WPA = 3, - AUTH_ALGO_WPA_PSK = 4, - AUTH_ALGO_WPA_NONE = 5, - AUTH_ALGO_RSNA = 6, - AUTH_ALGO_RSNA_PSK = 7, +typedef enum +{ + AUTH_ALGO_80211_OPEN = 1, AUTH_ALGO_80211_SHARED_KEY = 2, AUTH_ALGO_WPA = 3, AUTH_ALGO_WPA_PSK = 4, + AUTH_ALGO_WPA_NONE = 5, AUTH_ALGO_RSNA = 6, AUTH_ALGO_RSNA_PSK = 7, } AUTH_ALGORITHM; -#define WSEC_SWFLAG 0x0008 -#define CKIP_KP_ENABLED 0x0010 -#define CKIP_MIC_ENABLED 0x0020 -#define SES_OW_ENABLED 0x0040 -#define FIPS_ENABLED 0x0080 -#define SMS4_ENABLED 0x0100 - -#define MFP_NONE 0x0000 -#define MFP_CAPABLE 0x0200 -#define MFP_REQUIRED 0x0400 -#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ - -#define WPA_AUTH_DISABLED 0x0000 -#define WPA_AUTH_NONE 0x0001 -#define WPA_AUTH_UNSPECIFIED 0x0002 -#define WPA_AUTH_PSK 0x0004 -#define WPA_AUTH_CCKM 0x0008 -#define WPA2_AUTH_CCKM 0x0010 -#define WPA2_AUTH_UNSPECIFIED 0x0040 -#define WPA2_AUTH_PSK 0x0080 -#define BRCM_AUTH_PSK 0x0100 -#define BRCM_AUTH_DPT 0x0200 -#define WPA_AUTH_WAPI 0x0400 -#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ +#define WSEC_SWFLAG 0x0008 +#define CKIP_KP_ENABLED 0x0010 +#define CKIP_MIC_ENABLED 0x0020 +#define SES_OW_ENABLED 0x0040 +#define FIPS_ENABLED 0x0080 +#define SMS4_ENABLED 0x0100 + +#define MFP_NONE 0x0000 +#define MFP_CAPABLE 0x0200 +#define MFP_REQUIRED 0x0400 +#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */ + +#define WPA_AUTH_DISABLED 0x0000 +#define WPA_AUTH_NONE 0x0001 +#define WPA_AUTH_UNSPECIFIED 0x0002 +#define WPA_AUTH_PSK 0x0004 +#define WPA_AUTH_CCKM 0x0008 +#define WPA2_AUTH_CCKM 0x0010 +#define WPA2_AUTH_UNSPECIFIED 0x0040 +#define WPA2_AUTH_PSK 0x0080 +#define BRCM_AUTH_PSK 0x0100 +#define BRCM_AUTH_DPT 0x0200 +#define WPA_AUTH_WAPI 0x0400 +#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */ #define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */ #define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */ @@ -425,204 +799,211 @@ typedef enum { #define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */ #define WPA2_AUTH_FILS_SHA256 0x10000 /* FILS with SHA256 key derivation */ #define WPA2_AUTH_FILS_SHA384 0x20000 /* FILS with SHA384 key derivation */ -#define WPA2_AUTH_IS_FILS(auth) ((auth) & (WPA2_AUTH_FILS_SHA256 | WPA2_AUTH_FILS_SHA384)) -#define WPA3_AUTH_SAE_PSK 0x40000 /* SAE authentication with SHA-256 */ -#define WPA3_AUTH_SAE_FBT 0x80000 /* FT authentication over SAE */ -#define WPA3_AUTH_OWE 0x100000 /* OWE */ -#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ - -#define MAXPMKID 16 -#define WPA2_PMKID_LEN 16 -typedef struct _pmkid { - wl_ether_addr_t BSSID; - uint8_t PMKID[WPA2_PMKID_LEN]; -} pmkid_t; -typedef struct _pmkid_list { - uint32_t npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; -typedef struct _pmkid_cand { - wl_ether_addr_t BSSID; - uint8_t preauth; +#define WPA2_AUTH_IS_FILS(auth) ( (auth) & (WPA2_AUTH_FILS_SHA256 | WPA2_AUTH_FILS_SHA384) ) +#define WPA3_AUTH_SAE_PSK 0x40000 /* SAE authentication with SHA-256 */ +#define WPA3_AUTH_SAE_FBT 0x80000 /* FT authentication over SAE */ +#define WPA3_AUTH_1X_SUITE_B_SHA384 0x400000 /* Suite B-192 SHA384 */ +#define WPA3_AUTH_OWE 0x100000 /* OWE */ +#define WPA3_AUTH_1X_SHA256 0x1000000 /* WPA3 1x with SHA256 key derivation */ +#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */ + +#define MAXPMKID 16 + +typedef struct _pmkid_cand +{ + wl_ether_addr_t BSSID; + uint8_t preauth; } pmkid_cand_t; -typedef struct _pmkid_cand_list { - uint32_t npmkid_cand; - pmkid_cand_t pmkid_cand[1]; +typedef struct _pmkid_cand_list +{ + uint32_t npmkid_cand; + pmkid_cand_t pmkid_cand[1]; } pmkid_cand_list_t; -typedef struct wl_led_info { - uint32_t index; - uint32_t behavior; - uint8_t activehi; +typedef struct wl_led_info +{ + uint32_t index; + uint32_t behavior; + uint8_t activehi; } wl_led_info_t; -struct wl_dot11_assoc_req { - uint16_t capability; - uint16_t listen; +struct wl_dot11_assoc_req +{ + uint16_t capability; + uint16_t listen; }; -struct wl_dot11_assoc_resp { - uint16_t capability; - uint16_t status; - uint16_t aid; +struct wl_dot11_assoc_resp +{ + uint16_t capability; + uint16_t status; + uint16_t aid; }; -typedef struct wl_assoc_info { - uint32_t req_len; - uint32_t resp_len; - uint32_t flags; - struct wl_dot11_assoc_req req; - wl_ether_addr_t reassoc_bssid; - struct wl_dot11_assoc_resp resp; +typedef struct wl_assoc_info +{ + uint32_t req_len; + uint32_t resp_len; + uint32_t flags; + struct wl_dot11_assoc_req req; + wl_ether_addr_t reassoc_bssid; + struct wl_dot11_assoc_resp resp; } wl_assoc_info_t; #define WLC_ASSOC_REQ_IS_REASSOC 0x01 typedef struct { - uint32_t byteoff; - uint32_t nbytes; - uint16_t buf[1]; + uint32_t byteoff; + uint32_t nbytes; + uint16_t buf[1]; } srom_rw_t; typedef struct { - uint32_t source; - uint32_t byteoff; - uint32_t nbytes; + uint32_t source; + uint32_t byteoff; + uint32_t nbytes; } cis_rw_t; -#define WLC_CIS_DEFAULT 0 +#define WLC_CIS_DEFAULT 0 #define WLC_CIS_SROM 1 -#define WLC_CIS_OTP 2 +#define WLC_CIS_OTP 2 typedef struct { - uint32_t byteoff; - uint32_t val; - uint32_t size; - uint32_t band; + uint32_t byteoff; + uint32_t val; + uint32_t size; + uint32_t band; } rw_reg_t; -#define WL_ATTEN_APP_INPUT_PCL_OFF 0 +#define WL_ATTEN_APP_INPUT_PCL_OFF 0 #define WL_ATTEN_PCL_ON 1 -#define WL_ATTEN_PCL_OFF 2 +#define WL_ATTEN_PCL_OFF 2 typedef struct { - uint16_t auto_ctrl; - uint16_t bb; - uint16_t radio; - uint16_t txctl1; + uint16_t auto_ctrl; + uint16_t bb; + uint16_t radio; + uint16_t txctl1; } atten_t; -struct wme_tx_params_s { - uint8_t short_retry; - uint8_t short_fallback; - uint8_t long_retry; - uint8_t long_fallback; - uint16_t max_rate; +struct wme_tx_params_s +{ + uint8_t short_retry; + uint8_t short_fallback; + uint8_t long_retry; + uint8_t long_fallback; + uint16_t max_rate; }; typedef struct wme_tx_params_s wme_tx_params_t; #define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) -#define WL_PWRIDX_PCL_OFF -2 -#define WL_PWRIDX_PCL_ON -1 -#define WL_PWRIDX_LOWER_LIMIT -2 -#define WL_PWRIDX_UPPER_LIMIT 63 +#define WL_PWRIDX_PCL_OFF -2 +#define WL_PWRIDX_PCL_ON -1 +#define WL_PWRIDX_LOWER_LIMIT -2 +#define WL_PWRIDX_UPPER_LIMIT 63 typedef struct { - uint32_t val; - wl_ether_addr_t ea; + uint32_t val; + wl_ether_addr_t ea; } scb_val_t; -#define BCM_MAC_STATUS_INDICATION (0x40010200L) +#define BCM_MAC_STATUS_INDICATION (0x40010200L) typedef struct { - uint16_t ver; - uint16_t len; - uint16_t cap; - uint32_t flags; - uint32_t idle; - wl_ether_addr_t ea; - wl_rateset_t rateset; - uint32_t in; - uint32_t listen_interval_inms; - uint32_t tx_pkts; - uint32_t tx_failures; - uint32_t rx_ucast_pkts; - uint32_t rx_mcast_pkts; - uint32_t tx_rate; - uint32_t rx_rate; + uint16_t ver; + uint16_t len; + uint16_t cap; + uint32_t flags; + uint32_t idle; + wl_ether_addr_t ea; + wl_rateset_t rateset; + uint32_t in; + uint32_t listen_interval_inms; + uint32_t tx_pkts; + uint32_t tx_failures; + uint32_t rx_ucast_pkts; + uint32_t rx_mcast_pkts; + uint32_t tx_rate; + uint32_t rx_rate; } sta_info_t; -#define WL_OLD_STAINFO_SIZE offsetof(sta_info_t, tx_pkts) -#define WL_STA_VER 2 -#define WL_STA_BRCM 0x1 -#define WL_STA_WME 0x2 +#define WL_OLD_STAINFO_SIZE offsetof(sta_info_t, tx_pkts) +#define WL_STA_VER 2 +#define WL_STA_BRCM 0x1 +#define WL_STA_WME 0x2 #define WL_STA_ABCAP 0x4 #define WL_STA_AUTHE 0x8 #define WL_STA_ASSOC 0x10 #define WL_STA_AUTHO 0x20 -#define WL_STA_WDS 0x40 -#define WL_STA_WDS_LINKUP 0x80 -#define WL_STA_PS 0x100 -#define WL_STA_APSD_BE 0x200 -#define WL_STA_APSD_BK 0x400 -#define WL_STA_APSD_VI 0x800 -#define WL_STA_APSD_VO 0x1000 +#define WL_STA_WDS 0x40 +#define WL_STA_WDS_LINKUP 0x80 +#define WL_STA_PS 0x100 +#define WL_STA_APSD_BE 0x200 +#define WL_STA_APSD_BK 0x400 +#define WL_STA_APSD_VI 0x800 +#define WL_STA_APSD_VO 0x1000 #define WL_STA_N_CAP 0x2000 -#define WL_STA_SCBSTATS 0x4000 -#define WL_WDS_LINKUP WL_STA_WDS_LINKUP -typedef struct channel_info { - int32_t hw_channel; - int32_t target_channel; - int32_t scan_channel; +#define WL_STA_SCBSTATS 0x4000 +#define WL_WDS_LINKUP WL_STA_WDS_LINKUP +typedef struct channel_info +{ + int32_t hw_channel; + int32_t target_channel; + int32_t scan_channel; } channel_info_t; -struct mac_list { - uint32_t count; - wl_ether_addr_t ea[1]; +struct mac_list +{ + uint32_t count; + wl_ether_addr_t ea[1]; }; -typedef struct get_pktcnt { - uint32_t rx_good_pkt; - uint32_t rx_bad_pkt; - uint32_t tx_good_pkt; - uint32_t tx_bad_pkt; - uint32_t rx_ocast_good_pkt; +typedef struct get_pktcnt +{ + uint32_t rx_good_pkt; + uint32_t rx_bad_pkt; + uint32_t tx_good_pkt; + uint32_t tx_bad_pkt; + uint32_t rx_ocast_good_pkt; } get_pktcnt_t; -typedef struct wl_ioctl { - uint32_t cmd; - void *buf; - uint32_t len; - uint8_t set; - uint32_t used; - uint32_t needed; +typedef struct wl_ioctl +{ + uint32_t cmd; + void *buf; + uint32_t len; + uint8_t set; + uint32_t used; + uint32_t needed; } wl_ioctl_t; -typedef struct wlc_rev_info { - uint32_t vendorid; - uint32_t deviceid; - uint32_t radiorev; - uint32_t chiprev; - uint32_t corerev; - uint32_t boardid; - uint32_t boardvendor; - uint32_t boardrev; - uint32_t driverrev; - uint32_t ucoderev; - uint32_t bus; - uint32_t chipnum; - uint32_t phytype; - uint32_t phyrev; - uint32_t anarev; +typedef struct wlc_rev_info +{ + uint32_t vendorid; + uint32_t deviceid; + uint32_t radiorev; + uint32_t chiprev; + uint32_t corerev; + uint32_t boardid; + uint32_t boardvendor; + uint32_t boardrev; + uint32_t driverrev; + uint32_t ucoderev; + uint32_t bus; + uint32_t chipnum; + uint32_t phytype; + uint32_t phyrev; + uint32_t anarev; } wlc_rev_info_t; -#define WL_REV_INFO_LEGACY_LENGTH 48 -#define WL_BRAND_MAX 10 -typedef struct wl_instance_info { - uint32_t instance; - int8_t brand[WL_BRAND_MAX]; +#define WL_REV_INFO_LEGACY_LENGTH 48 +#define WL_BRAND_MAX 10 +typedef struct wl_instance_info +{ + uint32_t instance; + int8_t brand[WL_BRAND_MAX]; } wl_instance_info_t; -typedef struct wl_txfifo_sz { - uint8_t fifo; - uint8_t size; +typedef struct wl_txfifo_sz +{ + uint8_t fifo; + uint8_t size; } wl_txfifo_sz_t; #define WLC_IOV_NAME_LEN 30 -typedef struct wlc_iov_trx_s { - uint8_t module; - uint8_t type; - int8_t name[WLC_IOV_NAME_LEN]; +typedef struct wlc_iov_trx_s +{ + uint8_t module; + uint8_t type; + int8_t name[WLC_IOV_NAME_LEN]; } wlc_iov_trx_t; /* Event mask ext support */ -typedef enum event_msgs_ext_command { - EVENTMSGS_NONE = 0, - EVENTMSGS_SET_BIT = 1, - EVENTMSGS_RESET_BIT = 2, - EVENTMSGS_SET_MASK = 3 +typedef enum event_msgs_ext_command +{ + EVENTMSGS_NONE = 0, EVENTMSGS_SET_BIT = 1, EVENTMSGS_RESET_BIT = 2, EVENTMSGS_SET_MASK = 3 } event_msgs_ext_command_t; #define EVENTMSGS_VER 1 @@ -631,12 +1012,13 @@ typedef enum event_msgs_ext_command { /* for GET it would be actual firmware mask size */ /* maxgetsize - is only used for GET. indicate max mask size that the */ /* application can read from the firmware */ -typedef struct eventmsgs_ext { - uint8_t ver; - uint8_t command; - uint8_t len; - uint8_t maxgetsize; - uint8_t mask[1]; +typedef struct eventmsgs_ext +{ + uint8_t ver; + uint8_t command; + uint8_t len; + uint8_t maxgetsize; + uint8_t mask[1]; } eventmsgs_ext_t; #define IOVAR_STR_BTADDR "bus:btsdiobufaddr" @@ -740,23 +1122,32 @@ typedef struct eventmsgs_ext { #define IOVAR_STR_MPDU_PER_AMPDU "ampdu_mpdu" #define IOVAR_STR_VHT_FEATURES "vht_features" #define IOVAR_STR_CHANSPEC "chanspec" - -#define IOVAR_STR_WOWL "wowl" -#define IOVAR_STR_WOWL_OS "wowl_os" -#define IOVAR_STR_WOWL_KEEP_ALIVE "wowl_keepalive" -#define IOVAR_STR_WOWL_PATTERN "wowl_pattern" -#define IOVAR_STR_WOWL_PATTERN_CLR "clr" -#define IOVAR_STR_WOWL_PATTERN_ADD "add" -#define IOVAR_STR_WOWL_ARP_HOST_IP "wowl_arp_hostip" -#define IOVAR_STR_ULP_WAIT "ulp_wait" -#define IOVAR_STR_ULP "ulp" - -#define IOVAR_STR_PNO_ON "pfn" -#define IOVAR_STR_PNO_ADD "pfn_add" -#define IOVAR_STR_PNO_SET "pfn_set" -#define IOVAR_STR_PNO_CLEAR "pfnclear" -#define IOVAR_STR_SCAN_CACHE_CLEAR "scancache_clear" -#define MCS_SETLEN 16 +#define IOVAR_STR_MGMT_FRAME "mgmt_frame" + +#define IOVAR_STR_WOWL "wowl" +#define IOVAR_STR_WOWL_OS "wowl_os" +#define IOVAR_STR_WOWL_ACTIVATE "wowl_activate" + +#define IOVAR_STR_WOWL_CLEAR "wowl_clear" +#define IOVAR_STR_WOWL_ACTIVATE_SECURE "wowl_activate_secure" +#define IOVAR_STR_WOWL_SEC_SESS_INFO "wowl_secure_sess_info" + +#define IOVAR_STR_WOWL_KEEP_ALIVE "wowl_keepalive" +#define IOVAR_STR_WOWL_PATTERN "wowl_pattern" +#define IOVAR_STR_WOWL_PATTERN_CLR "clr" +#define IOVAR_STR_WOWL_PATTERN_ADD "add" +#define IOVAR_STR_WOWL_ARP_HOST_IP "wowl_arp_hostip" +#define IOVAR_STR_ULP_WAIT "ulp_wait" +#define IOVAR_STR_ULP "ulp" +#define IOVAR_STR_ULP_HOST_INTR_MODE "ulp_host_intr_mode" +#define IOVAR_STR_DUMP "dump" + +#define IOVAR_STR_PNO_ON "pfn" +#define IOVAR_STR_PNO_ADD "pfn_add" +#define IOVAR_STR_PNO_SET "pfn_set" +#define IOVAR_STR_PNO_CLEAR "pfnclear" +#define IOVAR_STR_SCAN_CACHE_CLEAR "scancache_clear" +#define MCS_SETLEN 16 #define IOVAR_STR_RRM "rrm" #define IOVAR_STR_RRM_NOISE_REQ "rrm_noise_req" @@ -773,431 +1164,447 @@ typedef struct eventmsgs_ext { #define IOVAR_STR_RRM_BCNREQ_MAXOFF_TIME "rrm_bcn_req_max_off_chan_time" #define IOVAR_STR_RRM_BCNREQ_TRFMS_PRD "rrm_bcn_req_traff_meas_per" -#define IOVAR_STR_WNM "wnm" -#define IOVAR_STR_BSSTRANS_QUERY "wnm_bsstrans_query" -#define IOVAR_STR_BSSTRANS_RESP "wnm_bsstrans_resp" - -#define IOVAR_STR_MESH_ADD_ROUTE "mesh_add_route" -#define IOVAR_STR_MESH_DEL_ROUTE "mesh_del_route" -#define IOVAR_STR_MESH_FIND "mesh_find" -#define IOVAR_STR_MESH_FILTER "mesh_filter" -#define IOVAR_STR_MESH_PEER "mesh_peer" -#define IOVAR_STR_MESH_PEER_STATUS "mesh_peer_status" -#define IOVAR_STR_MESH_DELFILTER "mesh_delfilter" -#define IOVAR_STR_MESH_MAX_PEERS "mesh_max_peers" - -#define IOVAR_STR_FBT_OVER_DS "fbtoverds" -#define IOVAR_STR_FBT_CAPABILITIES "fbt_cap" - -#define IOVAR_STR_MFP "mfp" - -#define IOVAR_STR_OTPRAW "otpraw" -#define IOVAR_NAN "nan" -#define IOVAR_STR_CLMLOAD "clmload" -#define IOVAR_STR_CLMLOAD_STATUS "clmload_status" -#define IOVAR_STR_CLMVER "clmver" -#define IOVAR_STR_MEMUSE "memuse" - -#define IOVAR_STR_LDPC_CAP "ldpc_cap" -#define IOVAR_STR_LDPC_TX "ldpc_tx" -#define IOVAR_STR_SGI_RX "sgi_rx" -#define IOVAR_STR_SGI_TX "sgi_tx" - -#define IOVAR_STR_APIVTW_OVERRIDE "brcmapivtwo" - -#define IOVAR_STR_BWTE_BWTE_GCI_MASK "bwte_gci_mask" -#define IOVAR_STR_BWTE_GCI_SENDMSG "bwte_gci_sendm" -#define IOVAR_STR_WD_DISABLE "wd_disable" -#define IOVAR_STR_DLTRO "dltro" -#define IOVAR_STR_SAE_PASSWORD "sae_password" - -#define IOVAR_STR_BTC_LESCAN_PARAMS "btc_lescan_params" - -#define IOVAR_STR_ARP_VERSION "arp_version" -#define IOVAR_STR_ARP_PEERAGE "arp_peerage" -#define IOVAR_STR_ARPOE "arpoe" -#define IOVAR_STR_ARP_OL "arp_ol" -#define IOVAR_STR_ARP_TABLE_CLEAR "arp_table_clear" -#define IOVAR_STR_ARP_HOSTIP "arp_hostip" -#define IOVAR_STR_ARP_HOSTIP_CLEAR "arp_hostip_clear" -#define IOVAR_STR_ARP_STATS "arp_stats" -#define IOVAR_STR_ARP_STATS_CLEAR "arp_stats_clear" -#define IOVAR_STR_TKO "tko" +#define IOVAR_STR_WNM "wnm" +#define IOVAR_STR_BSSTRANS_QUERY "wnm_bsstrans_query" +#define IOVAR_STR_BSSTRANS_RESP "wnm_bsstrans_resp" + +#define IOVAR_STR_MESH_ADD_ROUTE "mesh_add_route" +#define IOVAR_STR_MESH_DEL_ROUTE "mesh_del_route" +#define IOVAR_STR_MESH_FIND "mesh_find" +#define IOVAR_STR_MESH_FILTER "mesh_filter" +#define IOVAR_STR_MESH_PEER "mesh_peer" +#define IOVAR_STR_MESH_PEER_STATUS "mesh_peer_status" +#define IOVAR_STR_MESH_DELFILTER "mesh_delfilter" +#define IOVAR_STR_MESH_MAX_PEERS "mesh_max_peers" + +#define IOVAR_STR_FBT_OVER_DS "fbtoverds" +#define IOVAR_STR_FBT_CAPABILITIES "fbt_cap" + +#define IOVAR_STR_MFP "mfp" +#define IOVAR_STR_BIP "bip" + +#define IOVAR_STR_OTPRAW "otpraw" +#define IOVAR_NAN "nan" +#define IOVAR_STR_CLMLOAD "clmload" +#define IOVAR_STR_CLMLOAD_STATUS "clmload_status" +#define IOVAR_STR_CLMVER "clmver" +#define IOVAR_STR_MEMUSE "memuse" + +#define IOVAR_STR_LDPC_CAP "ldpc_cap" +#define IOVAR_STR_LDPC_TX "ldpc_tx" +#define IOVAR_STR_SGI_RX "sgi_rx" +#define IOVAR_STR_SGI_TX "sgi_tx" + +#define IOVAR_STR_APIVTW_OVERRIDE "brcmapivtwo" + +#define IOVAR_STR_BWTE_BWTE_GCI_MASK "bwte_gci_mask" +#define IOVAR_STR_BWTE_GCI_SENDMSG "bwte_gci_sendm" +#define IOVAR_STR_WD_DISABLE "wd_disable" +#define IOVAR_STR_DLTRO "dltro" +#define IOVAR_STR_SAE_PASSWORD "sae_password" +#define IOVAR_STR_SAE_PWE_LOOP "sae_max_pwe_loop" +#define IOVAR_STR_PMKID_INFO "pmkid_info" +#define IOVAR_STR_PMKID_CLEAR "pmkid_clear" +#define IOVAR_STR_AUTH_STATUS "auth_status" + +#define IOVAR_STR_BTC_LESCAN_PARAMS "btc_lescan_params" + +#define IOVAR_STR_ARP_VERSION "arp_version" +#define IOVAR_STR_ARP_PEERAGE "arp_peerage" +#define IOVAR_STR_ARPOE "arpoe" +#define IOVAR_STR_ARP_OL "arp_ol" +#define IOVAR_STR_ARP_TABLE_CLEAR "arp_table_clear" +#define IOVAR_STR_ARP_HOSTIP "arp_hostip" +#define IOVAR_STR_ARP_HOSTIP_CLEAR "arp_hostip_clear" +#define IOVAR_STR_ARP_STATS "arp_stats" +#define IOVAR_STR_ARP_STATS_CLEAR "arp_stats_clear" +#define IOVAR_STR_TKO "tko" +#define IOVAR_STR_ROAM_TIME_THRESH "roam_time_thresh" + +#define IOVAR_WNM_MAXIDLE "wnm_maxidle" +#define IOVAR_STR_HE "he" +#define IOVAR_STR_TWT "twt" +#define IOVAR_STR_OFFLOAD_CONFIG "offload_config" +#define IOVAR_STR_WSEC_INFO "wsec_info" +#define IOVAR_STR_KEEPALIVE_CONFIG "keep_alive" +#define IOVAR_STR_MBO "mbo" /* This value derived from the above strings, which appear maxed out in the 20s */ -#define IOVAR_NAME_STR_MAX_SIZE 32 - -#define WLC_IOCTL_MAGIC (0x14e46c77) -#define WLC_IOCTL_VERSION (1) -#define WLC_IOCTL_SMLEN (256) -#define WLC_IOCTL_MEDLEN (1536) -#define WLC_IOCTL_MAXLEN (8192) - -#define WLC_GET_MAGIC ((uint32_t)0) -#define WLC_GET_VERSION ((uint32_t)1) -#define WLC_UP ((uint32_t)2) -#define WLC_DOWN ((uint32_t)3) -#define WLC_GET_LOOP ((uint32_t)4) -#define WLC_SET_LOOP ((uint32_t)5) -#define WLC_DUMP ((uint32_t)6) -#define WLC_GET_MSGLEVEL ((uint32_t)7) -#define WLC_SET_MSGLEVEL ((uint32_t)8) -#define WLC_GET_PROMISC ((uint32_t)9) -#define WLC_SET_PROMISC ((uint32_t)10) -#define WLC_GET_RATE ((uint32_t)12) -#define WLC_GET_INSTANCE ((uint32_t)14) -#define WLC_GET_INFRA ((uint32_t)19) -#define WLC_SET_INFRA ((uint32_t)20) -#define WLC_GET_AUTH ((uint32_t)21) -#define WLC_SET_AUTH ((uint32_t)22) -#define WLC_GET_BSSID ((uint32_t)23) -#define WLC_SET_BSSID ((uint32_t)24) -#define WLC_GET_SSID ((uint32_t)25) -#define WLC_SET_SSID ((uint32_t)26) -#define WLC_RESTART ((uint32_t)27) -#define WLC_GET_CHANNEL ((uint32_t)29) -#define WLC_SET_CHANNEL ((uint32_t)30) -#define WLC_GET_SRL ((uint32_t)31) -#define WLC_SET_SRL ((uint32_t)32) -#define WLC_GET_LRL ((uint32_t)33) -#define WLC_SET_LRL ((uint32_t)34) -#define WLC_GET_PLCPHDR ((uint32_t)35) -#define WLC_SET_PLCPHDR ((uint32_t)36) -#define WLC_GET_RADIO ((uint32_t)37) -#define WLC_SET_RADIO ((uint32_t)38) -#define WLC_GET_PHYTYPE ((uint32_t)39) -#define WLC_DUMP_RATE ((uint32_t)40) -#define WLC_SET_RATE_PARAMS ((uint32_t)41) -#define WLC_GET_KEY ((uint32_t)44) -#define WLC_SET_KEY ((uint32_t)45) -#define WLC_GET_REGULATORY ((uint32_t)46) -#define WLC_SET_REGULATORY ((uint32_t)47) -#define WLC_GET_PASSIVE_SCAN ((uint32_t)48) -#define WLC_SET_PASSIVE_SCAN ((uint32_t)49) -#define WLC_SCAN ((uint32_t)50) -#define WLC_SCAN_RESULTS ((uint32_t)51) -#define WLC_DISASSOC ((uint32_t)52) -#define WLC_REASSOC ((uint32_t)53) -#define WLC_GET_ROAM_TRIGGER ((uint32_t)54) -#define WLC_SET_ROAM_TRIGGER ((uint32_t)55) -#define WLC_GET_ROAM_DELTA ((uint32_t)56) -#define WLC_SET_ROAM_DELTA ((uint32_t)57) -#define WLC_GET_ROAM_SCAN_PERIOD ((uint32_t)58) -#define WLC_SET_ROAM_SCAN_PERIOD ((uint32_t)59) -#define WLC_EVM ((uint32_t)60) -#define WLC_GET_TXANT ((uint32_t)61) -#define WLC_SET_TXANT ((uint32_t)62) -#define WLC_GET_ANTDIV ((uint32_t)63) -#define WLC_SET_ANTDIV ((uint32_t)64) -#define WLC_GET_CLOSED ((uint32_t)67) -#define WLC_SET_CLOSED ((uint32_t)68) -#define WLC_GET_MACLIST ((uint32_t)69) -#define WLC_SET_MACLIST ((uint32_t)70) -#define WLC_GET_RATESET ((uint32_t)71) -#define WLC_SET_RATESET ((uint32_t)72) -#define WLC_LONGTRAIN ((uint32_t)74) -#define WLC_GET_BCNPRD ((uint32_t)75) -#define WLC_SET_BCNPRD ((uint32_t)76) -#define WLC_GET_DTIMPRD ((uint32_t)77) -#define WLC_SET_DTIMPRD ((uint32_t)78) -#define WLC_GET_SROM ((uint32_t)79) -#define WLC_SET_SROM ((uint32_t)80) -#define WLC_GET_WEP_RESTRICT ((uint32_t)81) -#define WLC_SET_WEP_RESTRICT ((uint32_t)82) -#define WLC_GET_COUNTRY ((uint32_t)83) -#define WLC_SET_COUNTRY ((uint32_t)84) -#define WLC_GET_PM ((uint32_t)85) -#define WLC_SET_PM ((uint32_t)86) -#define WLC_GET_WAKE ((uint32_t)87) -#define WLC_SET_WAKE ((uint32_t)88) -#define WLC_GET_FORCELINK ((uint32_t)90) -#define WLC_SET_FORCELINK ((uint32_t)91) -#define WLC_FREQ_ACCURACY ((uint32_t)92) -#define WLC_CARRIER_SUPPRESS ((uint32_t)93) -#define WLC_GET_PHYREG ((uint32_t)94) -#define WLC_SET_PHYREG ((uint32_t)95) -#define WLC_GET_RADIOREG ((uint32_t)96) -#define WLC_SET_RADIOREG ((uint32_t)97) -#define WLC_GET_REVINFO ((uint32_t)98) -#define WLC_GET_UCANTDIV ((uint32_t)99) -#define WLC_SET_UCANTDIV ((uint32_t)100) -#define WLC_R_REG ((uint32_t)101) -#define WLC_W_REG ((uint32_t)102) -#define WLC_GET_MACMODE ((uint32_t)105) -#define WLC_SET_MACMODE ((uint32_t)106) -#define WLC_GET_MONITOR ((uint32_t)107) -#define WLC_SET_MONITOR ((uint32_t)108) -#define WLC_GET_GMODE ((uint32_t)109) -#define WLC_SET_GMODE ((uint32_t)110) -#define WLC_GET_LEGACY_ERP ((uint32_t)111) -#define WLC_SET_LEGACY_ERP ((uint32_t)112) -#define WLC_GET_RX_ANT ((uint32_t)113) -#define WLC_GET_CURR_RATESET ((uint32_t)114) -#define WLC_GET_SCANSUPPRESS ((uint32_t)115) -#define WLC_SET_SCANSUPPRESS ((uint32_t)116) -#define WLC_GET_AP ((uint32_t)117) -#define WLC_SET_AP ((uint32_t)118) -#define WLC_GET_EAP_RESTRICT ((uint32_t)119) -#define WLC_SET_EAP_RESTRICT ((uint32_t)120) -#define WLC_SCB_AUTHORIZE ((uint32_t)121) -#define WLC_SCB_DEAUTHORIZE ((uint32_t)122) -#define WLC_GET_WDSLIST ((uint32_t)123) -#define WLC_SET_WDSLIST ((uint32_t)124) -#define WLC_GET_ATIM ((uint32_t)125) -#define WLC_SET_ATIM ((uint32_t)126) -#define WLC_GET_RSSI ((uint32_t)127) -#define WLC_GET_PHYANTDIV ((uint32_t)128) -#define WLC_SET_PHYANTDIV ((uint32_t)129) -#define WLC_AP_RX_ONLY ((uint32_t)130) -#define WLC_GET_TX_PATH_PWR ((uint32_t)131) -#define WLC_SET_TX_PATH_PWR ((uint32_t)132) -#define WLC_GET_WSEC ((uint32_t)133) -#define WLC_SET_WSEC ((uint32_t)134) -#define WLC_GET_PHY_NOISE ((uint32_t)135) -#define WLC_GET_BSS_INFO ((uint32_t)136) -#define WLC_GET_PKTCNTS ((uint32_t)137) -#define WLC_GET_LAZYWDS ((uint32_t)138) -#define WLC_SET_LAZYWDS ((uint32_t)139) -#define WLC_GET_BANDLIST ((uint32_t)140) -#define WLC_GET_BAND ((uint32_t)141) -#define WLC_SET_BAND ((uint32_t)142) -#define WLC_SCB_DEAUTHENTICATE ((uint32_t)143) -#define WLC_GET_SHORTSLOT ((uint32_t)144) -#define WLC_GET_SHORTSLOT_OVERRIDE ((uint32_t)145) -#define WLC_SET_SHORTSLOT_OVERRIDE ((uint32_t)146) -#define WLC_GET_SHORTSLOT_RESTRICT ((uint32_t)147) -#define WLC_SET_SHORTSLOT_RESTRICT ((uint32_t)148) -#define WLC_GET_GMODE_PROTECTION ((uint32_t)149) -#define WLC_GET_GMODE_PROTECTION_OVERRIDE ((uint32_t)150) -#define WLC_SET_GMODE_PROTECTION_OVERRIDE ((uint32_t)151) -#define WLC_UPGRADE ((uint32_t)152) -#define WLC_GET_IGNORE_BCNS ((uint32_t)155) -#define WLC_SET_IGNORE_BCNS ((uint32_t)156) -#define WLC_GET_SCB_TIMEOUT ((uint32_t)157) -#define WLC_SET_SCB_TIMEOUT ((uint32_t)158) -#define WLC_GET_ASSOCLIST ((uint32_t)159) -#define WLC_GET_CLK ((uint32_t)160) -#define WLC_SET_CLK ((uint32_t)161) -#define WLC_GET_UP ((uint32_t)162) -#define WLC_OUT ((uint32_t)163) -#define WLC_GET_WPA_AUTH ((uint32_t)164) -#define WLC_SET_WPA_AUTH ((uint32_t)165) -#define WLC_GET_UCFLAGS ((uint32_t)166) -#define WLC_SET_UCFLAGS ((uint32_t)167) -#define WLC_GET_PWRIDX ((uint32_t)168) -#define WLC_SET_PWRIDX ((uint32_t)169) -#define WLC_GET_TSSI ((uint32_t)170) -#define WLC_GET_SUP_RATESET_OVERRIDE ((uint32_t)171) -#define WLC_SET_SUP_RATESET_OVERRIDE ((uint32_t)172) -#define WLC_GET_PROTECTION_CONTROL ((uint32_t)178) -#define WLC_SET_PROTECTION_CONTROL ((uint32_t)179) -#define WLC_GET_PHYLIST ((uint32_t)180) -#define WLC_ENCRYPT_STRENGTH ((uint32_t)181) -#define WLC_DECRYPT_STATUS ((uint32_t)182) -#define WLC_GET_KEY_SEQ ((uint32_t)183) -#define WLC_GET_SCAN_CHANNEL_TIME ((uint32_t)184) -#define WLC_SET_SCAN_CHANNEL_TIME ((uint32_t)185) -#define WLC_GET_SCAN_UNASSOC_TIME ((uint32_t)186) -#define WLC_SET_SCAN_UNASSOC_TIME ((uint32_t)187) -#define WLC_GET_SCAN_HOME_TIME ((uint32_t)188) -#define WLC_SET_SCAN_HOME_TIME ((uint32_t)189) -#define WLC_GET_SCAN_NPROBES ((uint32_t)190) -#define WLC_SET_SCAN_NPROBES ((uint32_t)191) -#define WLC_GET_PRB_RESP_TIMEOUT ((uint32_t)192) -#define WLC_SET_PRB_RESP_TIMEOUT ((uint32_t)193) -#define WLC_GET_ATTEN ((uint32_t)194) -#define WLC_SET_ATTEN ((uint32_t)195) -#define WLC_GET_SHMEM ((uint32_t)196) -#define WLC_SET_SHMEM ((uint32_t)197) -#define WLC_SET_WSEC_TEST ((uint32_t)200) -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON ((uint32_t)201) -#define WLC_TKIP_COUNTERMEASURES ((uint32_t)202) -#define WLC_GET_PIOMODE ((uint32_t)203) -#define WLC_SET_PIOMODE ((uint32_t)204) -#define WLC_SET_ASSOC_PREFER ((uint32_t)205) -#define WLC_GET_ASSOC_PREFER ((uint32_t)206) -#define WLC_SET_ROAM_PREFER ((uint32_t)207) -#define WLC_GET_ROAM_PREFER ((uint32_t)208) -#define WLC_SET_LED ((uint32_t)209) -#define WLC_GET_LED ((uint32_t)210) -#define WLC_GET_INTERFERENCE_MODE ((uint32_t)211) -#define WLC_SET_INTERFERENCE_MODE ((uint32_t)212) -#define WLC_GET_CHANNEL_QA ((uint32_t)213) -#define WLC_START_CHANNEL_QA ((uint32_t)214) -#define WLC_GET_CHANNEL_SEL ((uint32_t)215) -#define WLC_START_CHANNEL_SEL ((uint32_t)216) -#define WLC_GET_VALID_CHANNELS ((uint32_t)217) -#define WLC_GET_FAKEFRAG ((uint32_t)218) -#define WLC_SET_FAKEFRAG ((uint32_t)219) -#define WLC_GET_PWROUT_PERCENTAGE ((uint32_t)220) -#define WLC_SET_PWROUT_PERCENTAGE ((uint32_t)221) -#define WLC_SET_BAD_FRAME_PREEMPT ((uint32_t)222) -#define WLC_GET_BAD_FRAME_PREEMPT ((uint32_t)223) -#define WLC_SET_LEAP_LIST ((uint32_t)224) -#define WLC_GET_LEAP_LIST ((uint32_t)225) -#define WLC_GET_CWMIN ((uint32_t)226) -#define WLC_SET_CWMIN ((uint32_t)227) -#define WLC_GET_CWMAX ((uint32_t)228) -#define WLC_SET_CWMAX ((uint32_t)229) -#define WLC_GET_WET ((uint32_t)230) -#define WLC_SET_WET ((uint32_t)231) -#define WLC_GET_PUB ((uint32_t)232) -#define WLC_GET_KEY_PRIMARY ((uint32_t)235) -#define WLC_SET_KEY_PRIMARY ((uint32_t)236) -#define WLC_GET_ACI_ARGS ((uint32_t)238) -#define WLC_SET_ACI_ARGS ((uint32_t)239) -#define WLC_UNSET_CALLBACK ((uint32_t)240) -#define WLC_SET_CALLBACK ((uint32_t)241) -#define WLC_GET_RADAR ((uint32_t)242) -#define WLC_SET_RADAR ((uint32_t)243) -#define WLC_SET_SPECT_MANAGMENT ((uint32_t)244) -#define WLC_GET_SPECT_MANAGMENT ((uint32_t)245) -#define WLC_WDS_GET_REMOTE_HWADDR ((uint32_t)246) -#define WLC_WDS_GET_WPA_SUP ((uint32_t)247) -#define WLC_SET_CS_SCAN_TIMER ((uint32_t)248) -#define WLC_GET_CS_SCAN_TIMER ((uint32_t)249) -#define WLC_MEASURE_REQUEST ((uint32_t)250) -#define WLC_INIT ((uint32_t)251) -#define WLC_SEND_QUIET ((uint32_t)252) -#define WLC_KEEPALIVE ((uint32_t)253) -#define WLC_SEND_PWR_CONSTRAINT ((uint32_t)254) -#define WLC_UPGRADE_STATUS ((uint32_t)255) -#define WLC_CURRENT_PWR ((uint32_t)256) -#define WLC_GET_SCAN_PASSIVE_TIME ((uint32_t)257) -#define WLC_SET_SCAN_PASSIVE_TIME ((uint32_t)258) -#define WLC_LEGACY_LINK_BEHAVIOR ((uint32_t)259) -#define WLC_GET_CHANNELS_IN_COUNTRY ((uint32_t)260) -#define WLC_GET_COUNTRY_LIST ((uint32_t)261) -#define WLC_GET_VAR ((uint32_t)262) -#define WLC_SET_VAR ((uint32_t)263) -#define WLC_NVRAM_GET ((uint32_t)264) -#define WLC_NVRAM_SET ((uint32_t)265) -#define WLC_NVRAM_DUMP ((uint32_t)266) -#define WLC_REBOOT ((uint32_t)267) -#define WLC_SET_WSEC_PMK ((uint32_t)268) -#define WLC_GET_AUTH_MODE ((uint32_t)269) -#define WLC_SET_AUTH_MODE ((uint32_t)270) -#define WLC_GET_WAKEENTRY ((uint32_t)271) -#define WLC_SET_WAKEENTRY ((uint32_t)272) -#define WLC_NDCONFIG_ITEM ((uint32_t)273) -#define WLC_NVOTPW ((uint32_t)274) -#define WLC_OTPW ((uint32_t)275) -#define WLC_IOV_BLOCK_GET ((uint32_t)276) -#define WLC_IOV_MODULES_GET ((uint32_t)277) -#define WLC_SOFT_RESET ((uint32_t)278) -#define WLC_GET_ALLOW_MODE ((uint32_t)279) -#define WLC_SET_ALLOW_MODE ((uint32_t)280) -#define WLC_GET_DESIRED_BSSID ((uint32_t)281) -#define WLC_SET_DESIRED_BSSID ((uint32_t)282) -#define WLC_DISASSOC_MYAP ((uint32_t)283) -#define WLC_GET_NBANDS ((uint32_t)284) -#define WLC_GET_BANDSTATES ((uint32_t)285) -#define WLC_GET_WLC_BSS_INFO ((uint32_t)286) -#define WLC_GET_ASSOC_INFO ((uint32_t)287) -#define WLC_GET_OID_PHY ((uint32_t)288) -#define WLC_SET_OID_PHY ((uint32_t)289) -#define WLC_SET_ASSOC_TIME ((uint32_t)290) -#define WLC_GET_DESIRED_SSID ((uint32_t)291) -#define WLC_GET_CHANSPEC ((uint32_t)292) -#define WLC_GET_ASSOC_STATE ((uint32_t)293) -#define WLC_SET_PHY_STATE ((uint32_t)294) -#define WLC_GET_SCAN_PENDING ((uint32_t)295) -#define WLC_GET_SCANREQ_PENDING ((uint32_t)296) -#define WLC_GET_PREV_ROAM_REASON ((uint32_t)297) -#define WLC_SET_PREV_ROAM_REASON ((uint32_t)298) -#define WLC_GET_BANDSTATES_PI ((uint32_t)299) -#define WLC_GET_PHY_STATE ((uint32_t)300) -#define WLC_GET_BSS_WPA_RSN ((uint32_t)301) -#define WLC_GET_BSS_WPA2_RSN ((uint32_t)302) -#define WLC_GET_BSS_BCN_TS ((uint32_t)303) -#define WLC_GET_INT_DISASSOC ((uint32_t)304) -#define WLC_SET_NUM_PEERS ((uint32_t)305) -#define WLC_GET_NUM_BSS ((uint32_t)306) -#define WLC_GET_WSEC_PMK ((uint32_t)318) -#define WLC_GET_RANDOM_BYTES ((uint32_t)319) -#define WLC_LAST ((uint32_t)320) - -#define EPICTRL_COOKIE 0xABADCEDE -#define CMN_IOCTL_OFF 0x180 -#define WL_OID_BASE 0xFFE41420 -#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) -#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) -#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) -#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) -#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) -#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) -#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) -#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) -#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) -#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) -#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) -#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) -#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) -#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) -#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) -#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) -#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) -#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) -#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) -#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) -#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) -#define WL_DECRYPT_STATUS_SUCCESS 1 -#define WL_DECRYPT_STATUS_FAILURE 2 -#define WL_DECRYPT_STATUS_UNKNOWN 3 -#define WLC_UPGRADE_SUCCESS 0 -#define WLC_UPGRADE_PENDING 1 +#define IOVAR_NAME_STR_MAX_SIZE 32 + +#define WLC_IOCTL_MAGIC (0x14e46c77) +#define WLC_IOCTL_VERSION (1) +#define WLC_IOCTL_SMLEN (256) +#define WLC_IOCTL_MEDLEN (1536) +#define WLC_IOCTL_MAXLEN (8192) + +#define WLC_GET_MAGIC ( (uint32_t)0 ) +#define WLC_GET_VERSION ( (uint32_t)1 ) +#define WLC_UP ( (uint32_t)2 ) +#define WLC_DOWN ( (uint32_t)3 ) +#define WLC_GET_LOOP ( (uint32_t)4 ) +#define WLC_SET_LOOP ( (uint32_t)5 ) +#define WLC_DUMP ( (uint32_t)6 ) +#define WLC_GET_MSGLEVEL ( (uint32_t)7 ) +#define WLC_SET_MSGLEVEL ( (uint32_t)8 ) +#define WLC_GET_PROMISC ( (uint32_t)9 ) +#define WLC_SET_PROMISC ( (uint32_t)10 ) +#define WLC_GET_RATE ( (uint32_t)12 ) +#define WLC_GET_INSTANCE ( (uint32_t)14 ) +#define WLC_GET_INFRA ( (uint32_t)19 ) +#define WLC_SET_INFRA ( (uint32_t)20 ) +#define WLC_GET_AUTH ( (uint32_t)21 ) +#define WLC_SET_AUTH ( (uint32_t)22 ) +#define WLC_GET_BSSID ( (uint32_t)23 ) +#define WLC_SET_BSSID ( (uint32_t)24 ) +#define WLC_GET_SSID ( (uint32_t)25 ) +#define WLC_SET_SSID ( (uint32_t)26 ) +#define WLC_RESTART ( (uint32_t)27 ) +#define WLC_GET_CHANNEL ( (uint32_t)29 ) +#define WLC_SET_CHANNEL ( (uint32_t)30 ) +#define WLC_GET_SRL ( (uint32_t)31 ) +#define WLC_SET_SRL ( (uint32_t)32 ) +#define WLC_GET_LRL ( (uint32_t)33 ) +#define WLC_SET_LRL ( (uint32_t)34 ) +#define WLC_GET_PLCPHDR ( (uint32_t)35 ) +#define WLC_SET_PLCPHDR ( (uint32_t)36 ) +#define WLC_GET_RADIO ( (uint32_t)37 ) +#define WLC_SET_RADIO ( (uint32_t)38 ) +#define WLC_GET_PHYTYPE ( (uint32_t)39 ) +#define WLC_DUMP_RATE ( (uint32_t)40 ) +#define WLC_SET_RATE_PARAMS ( (uint32_t)41 ) +#define WLC_GET_KEY ( (uint32_t)44 ) +#define WLC_SET_KEY ( (uint32_t)45 ) +#define WLC_GET_REGULATORY ( (uint32_t)46 ) +#define WLC_SET_REGULATORY ( (uint32_t)47 ) +#define WLC_GET_PASSIVE_SCAN ( (uint32_t)48 ) +#define WLC_SET_PASSIVE_SCAN ( (uint32_t)49 ) +#define WLC_SCAN ( (uint32_t)50 ) +#define WLC_SCAN_RESULTS ( (uint32_t)51 ) +#define WLC_DISASSOC ( (uint32_t)52 ) +#define WLC_REASSOC ( (uint32_t)53 ) +#define WLC_GET_ROAM_TRIGGER ( (uint32_t)54 ) +#define WLC_SET_ROAM_TRIGGER ( (uint32_t)55 ) +#define WLC_GET_ROAM_DELTA ( (uint32_t)56 ) +#define WLC_SET_ROAM_DELTA ( (uint32_t)57 ) +#define WLC_GET_ROAM_SCAN_PERIOD ( (uint32_t)58 ) +#define WLC_SET_ROAM_SCAN_PERIOD ( (uint32_t)59 ) +#define WLC_EVM ( (uint32_t)60 ) +#define WLC_GET_TXANT ( (uint32_t)61 ) +#define WLC_SET_TXANT ( (uint32_t)62 ) +#define WLC_GET_ANTDIV ( (uint32_t)63 ) +#define WLC_SET_ANTDIV ( (uint32_t)64 ) +#define WLC_GET_CLOSED ( (uint32_t)67 ) +#define WLC_SET_CLOSED ( (uint32_t)68 ) +#define WLC_GET_MACLIST ( (uint32_t)69 ) +#define WLC_SET_MACLIST ( (uint32_t)70 ) +#define WLC_GET_RATESET ( (uint32_t)71 ) +#define WLC_SET_RATESET ( (uint32_t)72 ) +#define WLC_LONGTRAIN ( (uint32_t)74 ) +#define WLC_GET_BCNPRD ( (uint32_t)75 ) +#define WLC_SET_BCNPRD ( (uint32_t)76 ) +#define WLC_GET_DTIMPRD ( (uint32_t)77 ) +#define WLC_SET_DTIMPRD ( (uint32_t)78 ) +#define WLC_GET_SROM ( (uint32_t)79 ) +#define WLC_SET_SROM ( (uint32_t)80 ) +#define WLC_GET_WEP_RESTRICT ( (uint32_t)81 ) +#define WLC_SET_WEP_RESTRICT ( (uint32_t)82 ) +#define WLC_GET_COUNTRY ( (uint32_t)83 ) +#define WLC_SET_COUNTRY ( (uint32_t)84 ) +#define WLC_GET_PM ( (uint32_t)85 ) +#define WLC_SET_PM ( (uint32_t)86 ) +#define WLC_GET_WAKE ( (uint32_t)87 ) +#define WLC_SET_WAKE ( (uint32_t)88 ) +#define WLC_GET_FORCELINK ( (uint32_t)90 ) +#define WLC_SET_FORCELINK ( (uint32_t)91 ) +#define WLC_FREQ_ACCURACY ( (uint32_t)92 ) +#define WLC_CARRIER_SUPPRESS ( (uint32_t)93 ) +#define WLC_GET_PHYREG ( (uint32_t)94 ) +#define WLC_SET_PHYREG ( (uint32_t)95 ) +#define WLC_GET_RADIOREG ( (uint32_t)96 ) +#define WLC_SET_RADIOREG ( (uint32_t)97 ) +#define WLC_GET_REVINFO ( (uint32_t)98 ) +#define WLC_GET_UCANTDIV ( (uint32_t)99 ) +#define WLC_SET_UCANTDIV ( (uint32_t)100 ) +#define WLC_R_REG ( (uint32_t)101 ) +#define WLC_W_REG ( (uint32_t)102 ) +#define WLC_GET_MACMODE ( (uint32_t)105 ) +#define WLC_SET_MACMODE ( (uint32_t)106 ) +#define WLC_GET_MONITOR ( (uint32_t)107 ) +#define WLC_SET_MONITOR ( (uint32_t)108 ) +#define WLC_GET_GMODE ( (uint32_t)109 ) +#define WLC_SET_GMODE ( (uint32_t)110 ) +#define WLC_GET_LEGACY_ERP ( (uint32_t)111 ) +#define WLC_SET_LEGACY_ERP ( (uint32_t)112 ) +#define WLC_GET_RX_ANT ( (uint32_t)113 ) +#define WLC_GET_CURR_RATESET ( (uint32_t)114 ) +#define WLC_GET_SCANSUPPRESS ( (uint32_t)115 ) +#define WLC_SET_SCANSUPPRESS ( (uint32_t)116 ) +#define WLC_GET_AP ( (uint32_t)117 ) +#define WLC_SET_AP ( (uint32_t)118 ) +#define WLC_GET_EAP_RESTRICT ( (uint32_t)119 ) +#define WLC_SET_EAP_RESTRICT ( (uint32_t)120 ) +#define WLC_SCB_AUTHORIZE ( (uint32_t)121 ) +#define WLC_SCB_DEAUTHORIZE ( (uint32_t)122 ) +#define WLC_GET_WDSLIST ( (uint32_t)123 ) +#define WLC_SET_WDSLIST ( (uint32_t)124 ) +#define WLC_GET_ATIM ( (uint32_t)125 ) +#define WLC_SET_ATIM ( (uint32_t)126 ) +#define WLC_GET_RSSI ( (uint32_t)127 ) +#define WLC_GET_PHYANTDIV ( (uint32_t)128 ) +#define WLC_SET_PHYANTDIV ( (uint32_t)129 ) +#define WLC_AP_RX_ONLY ( (uint32_t)130 ) +#define WLC_GET_TX_PATH_PWR ( (uint32_t)131 ) +#define WLC_SET_TX_PATH_PWR ( (uint32_t)132 ) +#define WLC_GET_WSEC ( (uint32_t)133 ) +#define WLC_SET_WSEC ( (uint32_t)134 ) +#define WLC_GET_PHY_NOISE ( (uint32_t)135 ) +#define WLC_GET_BSS_INFO ( (uint32_t)136 ) +#define WLC_GET_PKTCNTS ( (uint32_t)137 ) +#define WLC_GET_LAZYWDS ( (uint32_t)138 ) +#define WLC_SET_LAZYWDS ( (uint32_t)139 ) +#define WLC_GET_BANDLIST ( (uint32_t)140 ) +#define WLC_GET_BAND ( (uint32_t)141 ) +#define WLC_SET_BAND ( (uint32_t)142 ) +#define WLC_SCB_DEAUTHENTICATE ( (uint32_t)143 ) +#define WLC_GET_SHORTSLOT ( (uint32_t)144 ) +#define WLC_GET_SHORTSLOT_OVERRIDE ( (uint32_t)145 ) +#define WLC_SET_SHORTSLOT_OVERRIDE ( (uint32_t)146 ) +#define WLC_GET_SHORTSLOT_RESTRICT ( (uint32_t)147 ) +#define WLC_SET_SHORTSLOT_RESTRICT ( (uint32_t)148 ) +#define WLC_GET_GMODE_PROTECTION ( (uint32_t)149 ) +#define WLC_GET_GMODE_PROTECTION_OVERRIDE ( (uint32_t)150 ) +#define WLC_SET_GMODE_PROTECTION_OVERRIDE ( (uint32_t)151 ) +#define WLC_UPGRADE ( (uint32_t)152 ) +#define WLC_GET_IGNORE_BCNS ( (uint32_t)155 ) +#define WLC_SET_IGNORE_BCNS ( (uint32_t)156 ) +#define WLC_GET_SCB_TIMEOUT ( (uint32_t)157 ) +#define WLC_SET_SCB_TIMEOUT ( (uint32_t)158 ) +#define WLC_GET_ASSOCLIST ( (uint32_t)159 ) +#define WLC_GET_CLK ( (uint32_t)160 ) +#define WLC_SET_CLK ( (uint32_t)161 ) +#define WLC_GET_UP ( (uint32_t)162 ) +#define WLC_OUT ( (uint32_t)163 ) +#define WLC_GET_WPA_AUTH ( (uint32_t)164 ) +#define WLC_SET_WPA_AUTH ( (uint32_t)165 ) +#define WLC_GET_UCFLAGS ( (uint32_t)166 ) +#define WLC_SET_UCFLAGS ( (uint32_t)167 ) +#define WLC_GET_PWRIDX ( (uint32_t)168 ) +#define WLC_SET_PWRIDX ( (uint32_t)169 ) +#define WLC_GET_TSSI ( (uint32_t)170 ) +#define WLC_GET_SUP_RATESET_OVERRIDE ( (uint32_t)171 ) +#define WLC_SET_SUP_RATESET_OVERRIDE ( (uint32_t)172 ) +#define WLC_GET_PROTECTION_CONTROL ( (uint32_t)178 ) +#define WLC_SET_PROTECTION_CONTROL ( (uint32_t)179 ) +#define WLC_GET_PHYLIST ( (uint32_t)180 ) +#define WLC_ENCRYPT_STRENGTH ( (uint32_t)181 ) +#define WLC_DECRYPT_STATUS ( (uint32_t)182 ) +#define WLC_GET_KEY_SEQ ( (uint32_t)183 ) +#define WLC_GET_SCAN_CHANNEL_TIME ( (uint32_t)184 ) +#define WLC_SET_SCAN_CHANNEL_TIME ( (uint32_t)185 ) +#define WLC_GET_SCAN_UNASSOC_TIME ( (uint32_t)186 ) +#define WLC_SET_SCAN_UNASSOC_TIME ( (uint32_t)187 ) +#define WLC_GET_SCAN_HOME_TIME ( (uint32_t)188 ) +#define WLC_SET_SCAN_HOME_TIME ( (uint32_t)189 ) +#define WLC_GET_SCAN_NPROBES ( (uint32_t)190 ) +#define WLC_SET_SCAN_NPROBES ( (uint32_t)191 ) +#define WLC_GET_PRB_RESP_TIMEOUT ( (uint32_t)192 ) +#define WLC_SET_PRB_RESP_TIMEOUT ( (uint32_t)193 ) +#define WLC_GET_ATTEN ( (uint32_t)194 ) +#define WLC_SET_ATTEN ( (uint32_t)195 ) +#define WLC_GET_SHMEM ( (uint32_t)196 ) +#define WLC_SET_SHMEM ( (uint32_t)197 ) +#define WLC_SET_WSEC_TEST ( (uint32_t)200 ) +#define WLC_SCB_DEAUTHENTICATE_FOR_REASON ( (uint32_t)201 ) +#define WLC_TKIP_COUNTERMEASURES ( (uint32_t)202 ) +#define WLC_GET_PIOMODE ( (uint32_t)203 ) +#define WLC_SET_PIOMODE ( (uint32_t)204 ) +#define WLC_SET_ASSOC_PREFER ( (uint32_t)205 ) +#define WLC_GET_ASSOC_PREFER ( (uint32_t)206 ) +#define WLC_SET_ROAM_PREFER ( (uint32_t)207 ) +#define WLC_GET_ROAM_PREFER ( (uint32_t)208 ) +#define WLC_SET_LED ( (uint32_t)209 ) +#define WLC_GET_LED ( (uint32_t)210 ) +#define WLC_GET_INTERFERENCE_MODE ( (uint32_t)211 ) +#define WLC_SET_INTERFERENCE_MODE ( (uint32_t)212 ) +#define WLC_GET_CHANNEL_QA ( (uint32_t)213 ) +#define WLC_START_CHANNEL_QA ( (uint32_t)214 ) +#define WLC_GET_CHANNEL_SEL ( (uint32_t)215 ) +#define WLC_START_CHANNEL_SEL ( (uint32_t)216 ) +#define WLC_GET_VALID_CHANNELS ( (uint32_t)217 ) +#define WLC_GET_FAKEFRAG ( (uint32_t)218 ) +#define WLC_SET_FAKEFRAG ( (uint32_t)219 ) +#define WLC_GET_PWROUT_PERCENTAGE ( (uint32_t)220 ) +#define WLC_SET_PWROUT_PERCENTAGE ( (uint32_t)221 ) +#define WLC_SET_BAD_FRAME_PREEMPT ( (uint32_t)222 ) +#define WLC_GET_BAD_FRAME_PREEMPT ( (uint32_t)223 ) +#define WLC_SET_LEAP_LIST ( (uint32_t)224 ) +#define WLC_GET_LEAP_LIST ( (uint32_t)225 ) +#define WLC_GET_CWMIN ( (uint32_t)226 ) +#define WLC_SET_CWMIN ( (uint32_t)227 ) +#define WLC_GET_CWMAX ( (uint32_t)228 ) +#define WLC_SET_CWMAX ( (uint32_t)229 ) +#define WLC_GET_WET ( (uint32_t)230 ) +#define WLC_SET_WET ( (uint32_t)231 ) +#define WLC_GET_PUB ( (uint32_t)232 ) +#define WLC_GET_KEY_PRIMARY ( (uint32_t)235 ) +#define WLC_SET_KEY_PRIMARY ( (uint32_t)236 ) +#define WLC_GET_ACI_ARGS ( (uint32_t)238 ) +#define WLC_SET_ACI_ARGS ( (uint32_t)239 ) +#define WLC_UNSET_CALLBACK ( (uint32_t)240 ) +#define WLC_SET_CALLBACK ( (uint32_t)241 ) +#define WLC_GET_RADAR ( (uint32_t)242 ) +#define WLC_SET_RADAR ( (uint32_t)243 ) +#define WLC_SET_SPECT_MANAGMENT ( (uint32_t)244 ) +#define WLC_GET_SPECT_MANAGMENT ( (uint32_t)245 ) +#define WLC_WDS_GET_REMOTE_HWADDR ( (uint32_t)246 ) +#define WLC_WDS_GET_WPA_SUP ( (uint32_t)247 ) +#define WLC_SET_CS_SCAN_TIMER ( (uint32_t)248 ) +#define WLC_GET_CS_SCAN_TIMER ( (uint32_t)249 ) +#define WLC_MEASURE_REQUEST ( (uint32_t)250 ) +#define WLC_INIT ( (uint32_t)251 ) +#define WLC_SEND_QUIET ( (uint32_t)252 ) +#define WLC_KEEPALIVE ( (uint32_t)253 ) +#define WLC_SEND_PWR_CONSTRAINT ( (uint32_t)254 ) +#define WLC_UPGRADE_STATUS ( (uint32_t)255 ) +#define WLC_CURRENT_PWR ( (uint32_t)256 ) +#define WLC_GET_SCAN_PASSIVE_TIME ( (uint32_t)257 ) +#define WLC_SET_SCAN_PASSIVE_TIME ( (uint32_t)258 ) +#define WLC_LEGACY_LINK_BEHAVIOR ( (uint32_t)259 ) +#define WLC_GET_CHANNELS_IN_COUNTRY ( (uint32_t)260 ) +#define WLC_GET_COUNTRY_LIST ( (uint32_t)261 ) +#define WLC_GET_VAR ( (uint32_t)262 ) +#define WLC_SET_VAR ( (uint32_t)263 ) +#define WLC_NVRAM_GET ( (uint32_t)264 ) +#define WLC_NVRAM_SET ( (uint32_t)265 ) +#define WLC_NVRAM_DUMP ( (uint32_t)266 ) +#define WLC_REBOOT ( (uint32_t)267 ) +#define WLC_SET_WSEC_PMK ( (uint32_t)268 ) +#define WLC_GET_AUTH_MODE ( (uint32_t)269 ) +#define WLC_SET_AUTH_MODE ( (uint32_t)270 ) +#define WLC_GET_WAKEENTRY ( (uint32_t)271 ) +#define WLC_SET_WAKEENTRY ( (uint32_t)272 ) +#define WLC_NDCONFIG_ITEM ( (uint32_t)273 ) +#define WLC_NVOTPW ( (uint32_t)274 ) +#define WLC_OTPW ( (uint32_t)275 ) +#define WLC_IOV_BLOCK_GET ( (uint32_t)276 ) +#define WLC_IOV_MODULES_GET ( (uint32_t)277 ) +#define WLC_SOFT_RESET ( (uint32_t)278 ) +#define WLC_GET_ALLOW_MODE ( (uint32_t)279 ) +#define WLC_SET_ALLOW_MODE ( (uint32_t)280 ) +#define WLC_GET_DESIRED_BSSID ( (uint32_t)281 ) +#define WLC_SET_DESIRED_BSSID ( (uint32_t)282 ) +#define WLC_DISASSOC_MYAP ( (uint32_t)283 ) +#define WLC_GET_NBANDS ( (uint32_t)284 ) +#define WLC_GET_BANDSTATES ( (uint32_t)285 ) +#define WLC_GET_WLC_BSS_INFO ( (uint32_t)286 ) +#define WLC_GET_ASSOC_INFO ( (uint32_t)287 ) +#define WLC_GET_OID_PHY ( (uint32_t)288 ) +#define WLC_SET_OID_PHY ( (uint32_t)289 ) +#define WLC_SET_ASSOC_TIME ( (uint32_t)290 ) +#define WLC_GET_DESIRED_SSID ( (uint32_t)291 ) +#define WLC_GET_CHANSPEC ( (uint32_t)292 ) +#define WLC_GET_ASSOC_STATE ( (uint32_t)293 ) +#define WLC_SET_PHY_STATE ( (uint32_t)294 ) +#define WLC_GET_SCAN_PENDING ( (uint32_t)295 ) +#define WLC_GET_SCANREQ_PENDING ( (uint32_t)296 ) +#define WLC_GET_PREV_ROAM_REASON ( (uint32_t)297 ) +#define WLC_SET_PREV_ROAM_REASON ( (uint32_t)298 ) +#define WLC_GET_BANDSTATES_PI ( (uint32_t)299 ) +#define WLC_GET_PHY_STATE ( (uint32_t)300 ) +#define WLC_GET_BSS_WPA_RSN ( (uint32_t)301 ) +#define WLC_GET_BSS_WPA2_RSN ( (uint32_t)302 ) +#define WLC_GET_BSS_BCN_TS ( (uint32_t)303 ) +#define WLC_GET_INT_DISASSOC ( (uint32_t)304 ) +#define WLC_SET_NUM_PEERS ( (uint32_t)305 ) +#define WLC_GET_NUM_BSS ( (uint32_t)306 ) +#define WLC_GET_WSEC_PMK ( (uint32_t)318 ) +#define WLC_GET_RANDOM_BYTES ( (uint32_t)319 ) +#define WLC_LAST ( (uint32_t)320 ) + +#define EPICTRL_COOKIE 0xABADCEDE +#define CMN_IOCTL_OFF 0x180 +#define WL_OID_BASE 0xFFE41420 +#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) +#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK) +#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK) +#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH) +#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS) +#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR) +#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) +#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC) +#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS) +#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY) +#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY) +#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME) +#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID) +#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE) +#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING) +#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING) +#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON) +#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON) +#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE) +#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC) +#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS) +#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS) +#define WL_DECRYPT_STATUS_SUCCESS 1 +#define WL_DECRYPT_STATUS_FAILURE 2 +#define WL_DECRYPT_STATUS_UNKNOWN 3 +#define WLC_UPGRADE_SUCCESS 0 +#define WLC_UPGRADE_PENDING 1 typedef struct { - int8_t *name; - void *param; + int8_t *name; + void *param; } ndconfig_item_t; -typedef struct _wl_assoc_result { - unsigned long associated; - unsigned long NDIS_auth; - unsigned long NDIS_infra; +typedef struct _wl_assoc_result +{ + unsigned long associated; + unsigned long NDIS_auth; + unsigned long NDIS_infra; } wl_assoc_result_t; -#define WL_RADIO_SW_DISABLE (1 << 0) -#define WL_RADIO_HW_DISABLE (1 << 1) -#define WL_RADIO_MPC_DISABLE (1 << 2) -#define WL_RADIO_COUNTRY_DISABLE (1 << 3) -#define WL_TXPWR_OVERRIDE (1U << 31) -#define WL_PHY_PAVARS_LEN (6) -#define WL_DIAG_INTERRUPT (1) -#define WL_DIAG_LOOPBACK (2) -#define WL_DIAG_MEMORY (3) -#define WL_DIAG_LED (4) -#define WL_DIAG_REG (5) -#define WL_DIAG_SROM (6) -#define WL_DIAG_DMA (7) -#define WL_DIAGERR_SUCCESS (0) -#define WL_DIAGERR_FAIL_TO_RUN (1) -#define WL_DIAGERR_NOT_SUPPORTED (2) -#define WL_DIAGERR_INTERRUPT_FAIL (3) -#define WL_DIAGERR_LOOPBACK_FAIL (4) -#define WL_DIAGERR_SROM_FAIL (5) -#define WL_DIAGERR_SROM_BADCRC (6) -#define WL_DIAGERR_REG_FAIL (7) -#define WL_DIAGERR_MEMORY_FAIL (8) -#define WL_DIAGERR_NOMEM (9) -#define WL_DIAGERR_DMA_FAIL (10) -#define WL_DIAGERR_MEMORY_TIMEOUT (11) -#define WL_DIAGERR_MEMORY_BADPATTERN (12) -#define WLC_BAND_AUTO (0) -#define WLC_BAND_5G (1) -#define WLC_BAND_2G (2) -#define WLC_BAND_ALL (3) -#define WL_CHAN_FREQ_RANGE_2G (0) -#define WL_CHAN_FREQ_RANGE_5GL (1) -#define WL_CHAN_FREQ_RANGE_5GM (2) -#define WL_CHAN_FREQ_RANGE_5GH (3) +#define WL_RADIO_SW_DISABLE (1 << 0) +#define WL_RADIO_HW_DISABLE (1 << 1) +#define WL_RADIO_MPC_DISABLE (1 << 2) +#define WL_RADIO_COUNTRY_DISABLE (1 << 3) +#define WL_TXPWR_OVERRIDE (1U << 31) +#define WL_PHY_PAVARS_LEN (6) +#define WL_DIAG_INTERRUPT (1) +#define WL_DIAG_LOOPBACK (2) +#define WL_DIAG_MEMORY (3) +#define WL_DIAG_LED (4) +#define WL_DIAG_REG (5) +#define WL_DIAG_SROM (6) +#define WL_DIAG_DMA (7) +#define WL_DIAGERR_SUCCESS (0) +#define WL_DIAGERR_FAIL_TO_RUN (1) +#define WL_DIAGERR_NOT_SUPPORTED (2) +#define WL_DIAGERR_INTERRUPT_FAIL (3) +#define WL_DIAGERR_LOOPBACK_FAIL (4) +#define WL_DIAGERR_SROM_FAIL (5) +#define WL_DIAGERR_SROM_BADCRC (6) +#define WL_DIAGERR_REG_FAIL (7) +#define WL_DIAGERR_MEMORY_FAIL (8) +#define WL_DIAGERR_NOMEM (9) +#define WL_DIAGERR_DMA_FAIL (10) +#define WL_DIAGERR_MEMORY_TIMEOUT (11) +#define WL_DIAGERR_MEMORY_BADPATTERN (12) +#define WLC_BAND_AUTO (0) +#define WLC_BAND_5G (1) +#define WLC_BAND_2G (2) +#define WLC_BAND_6G (3) +#define WLC_BAND_ALL (4) +#define WL_CHAN_FREQ_RANGE_2G (0) +#define WL_CHAN_FREQ_RANGE_5GL (1) +#define WL_CHAN_FREQ_RANGE_5GM (2) +#define WL_CHAN_FREQ_RANGE_5GH (3) #define WLC_PHY_TYPE_A (0) #define WLC_PHY_TYPE_B (1) #define WLC_PHY_TYPE_G (2) #define WLC_PHY_TYPE_N (4) #define WLC_PHY_TYPE_LP (5) #define WLC_PHY_TYPE_SSN (6) -#define WLC_PHY_TYPE_NULL (0xf) +#define WLC_PHY_TYPE_NULL (0xf) #define WLC_MACMODE_DISABLED (0) #define WLC_MACMODE_DENY (1) #define WLC_MACMODE_ALLOW (2) @@ -1208,10 +1615,10 @@ typedef struct _wl_assoc_result { #define GMODE_PERFORMANCE (4) #define GMODE_LRS (5) #define GMODE_MAX (6) -#define WLC_PLCP_AUTO (-1) +#define WLC_PLCP_AUTO (-1) #define WLC_PLCP_SHORT (0) #define WLC_PLCP_LONG (1) -#define WLC_PROTECTION_AUTO (-1) +#define WLC_PROTECTION_AUTO (-1) #define WLC_PROTECTION_OFF (0) #define WLC_PROTECTION_ON (1) #define WLC_PROTECTION_MMHDR_ONLY (2) @@ -1230,8 +1637,8 @@ typedef struct _wl_assoc_result { #define WLC_N_BW_20IN2G_40IN5G (2) #define WLC_N_TXRX_CHAIN0 (0) #define WLC_N_TXRX_CHAIN1 (1) -#define WLC_N_SGI_20 (0x01) -#define WLC_N_SGI_40 (0x02) +#define WLC_N_SGI_20 (0x01) +#define WLC_N_SGI_40 (0x02) #define PM_OFF (0) #define PM_MAX (1) #define PM_FAST (2) @@ -1240,280 +1647,286 @@ typedef struct _wl_assoc_result { #define NON_WLAN (1) #define WLAN_MANUAL (2) #define WLAN_AUTO (3) -#define AUTO_ACTIVE (1 << 7) -typedef struct wl_aci_args { - int32_t enter_aci_thresh; - int32_t exit_aci_thresh; - int32_t usec_spin; - int32_t glitch_delay; - uint16_t nphy_adcpwr_enter_thresh; - uint16_t nphy_adcpwr_exit_thresh; - uint16_t nphy_repeat_ctr; - uint16_t nphy_num_samples; - uint16_t nphy_undetect_window_sz; - uint16_t nphy_b_energy_lo_aci; - uint16_t nphy_b_energy_md_aci; - uint16_t nphy_b_energy_hi_aci; +#define AUTO_ACTIVE (1 << 7) +typedef struct wl_aci_args +{ + int32_t enter_aci_thresh; + int32_t exit_aci_thresh; + int32_t usec_spin; + int32_t glitch_delay; + uint16_t nphy_adcpwr_enter_thresh; + uint16_t nphy_adcpwr_exit_thresh; + uint16_t nphy_repeat_ctr; + uint16_t nphy_num_samples; + uint16_t nphy_undetect_window_sz; + uint16_t nphy_b_energy_lo_aci; + uint16_t nphy_b_energy_md_aci; + uint16_t nphy_b_energy_hi_aci; } wl_aci_args_t; -#define WL_ACI_ARGS_LEGACY_LENGTH 16 +#define WL_ACI_ARGS_LEGACY_LENGTH 16 typedef struct { - int32_t npulses; - int32_t ncontig; - int32_t min_pw; - int32_t max_pw; - uint16_t thresh0; - uint16_t thresh1; - uint16_t blank; - uint16_t fmdemodcfg; - int32_t npulses_lp; - int32_t min_pw_lp; - int32_t max_pw_lp; - int32_t min_fm_lp; - int32_t max_deltat_lp; - int32_t min_deltat; - int32_t max_deltat; - uint16_t autocorr; - uint16_t st_level_time; - uint16_t t2_min; - uint32_t version; + int32_t npulses; + int32_t ncontig; + int32_t min_pw; + int32_t max_pw; + uint16_t thresh0; + uint16_t thresh1; + uint16_t blank; + uint16_t fmdemodcfg; + int32_t npulses_lp; + int32_t min_pw_lp; + int32_t max_pw_lp; + int32_t min_fm_lp; + int32_t max_deltat_lp; + int32_t min_deltat; + int32_t max_deltat; + uint16_t autocorr; + uint16_t st_level_time; + uint16_t t2_min; + uint32_t version; } wl_radar_args_t; #define WL_RADAR_ARGS_VERSION 1 -#define WL_RADAR_DETECTOR_OFF 0 -#define WL_RADAR_DETECTOR_ON 1 -#define WL_RADAR_SIMULATED 2 -#define WL_RSSI_ANT_VERSION 1 -#define WL_RSSI_ANT_MAX 4 +#define WL_RADAR_DETECTOR_OFF 0 +#define WL_RADAR_DETECTOR_ON 1 +#define WL_RADAR_SIMULATED 2 +#define WL_RSSI_ANT_VERSION 1 +#define WL_RSSI_ANT_MAX 4 typedef struct { - uint32_t version; - uint32_t count; - int8_t rssi_ant[WL_RSSI_ANT_MAX]; + uint32_t version; + uint32_t count; + int8_t rssi_ant[WL_RSSI_ANT_MAX]; } wl_rssi_ant_t; #define WL_DFS_CACSTATE_IDLE 0 -#define WL_DFS_CACSTATE_PREISM_CAC 1 -#define WL_DFS_CACSTATE_ISM 2 -#define WL_DFS_CACSTATE_CSA 3 -#define WL_DFS_CACSTATE_POSTISM_CAC 4 -#define WL_DFS_CACSTATE_PREISM_OOC 5 -#define WL_DFS_CACSTATE_POSTISM_OOC 6 -#define WL_DFS_CACSTATES 7 +#define WL_DFS_CACSTATE_PREISM_CAC 1 +#define WL_DFS_CACSTATE_ISM 2 +#define WL_DFS_CACSTATE_CSA 3 +#define WL_DFS_CACSTATE_POSTISM_CAC 4 +#define WL_DFS_CACSTATE_PREISM_OOC 5 +#define WL_DFS_CACSTATE_POSTISM_OOC 6 +#define WL_DFS_CACSTATES 7 typedef struct { - uint32_t state; - uint32_t duration; - wl_chanspec_t chanspec_cleared; - uint16_t pad; + uint32_t state; + uint32_t duration; + wl_chanspec_t chanspec_cleared; + uint16_t pad; } wl_dfs_status_t; #define NUM_PWRCTRL_RATES 12 typedef struct { - uint8_t txpwr_band_max[NUM_PWRCTRL_RATES]; - uint8_t txpwr_limit[NUM_PWRCTRL_RATES]; - uint8_t txpwr_local_max; - uint8_t txpwr_local_constraint; - uint8_t txpwr_chan_reg_max; - uint8_t txpwr_target[2][NUM_PWRCTRL_RATES]; - uint8_t txpwr_est_Pout[2]; - uint8_t txpwr_opo[NUM_PWRCTRL_RATES]; - uint8_t txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; - uint8_t txpwr_bphy_ofdm_max; - uint8_t txpwr_aphy_max[NUM_PWRCTRL_RATES]; - int8_t txpwr_antgain[2]; - uint8_t txpwr_est_Pout_gofdm; + uint8_t txpwr_band_max[NUM_PWRCTRL_RATES]; + uint8_t txpwr_limit[NUM_PWRCTRL_RATES]; + uint8_t txpwr_local_max; + uint8_t txpwr_local_constraint; + uint8_t txpwr_chan_reg_max; + uint8_t txpwr_target[2][NUM_PWRCTRL_RATES]; + uint8_t txpwr_est_Pout[2]; + uint8_t txpwr_opo[NUM_PWRCTRL_RATES]; + uint8_t txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; + uint8_t txpwr_bphy_ofdm_max; + uint8_t txpwr_aphy_max[NUM_PWRCTRL_RATES]; + int8_t txpwr_antgain[2]; + uint8_t txpwr_est_Pout_gofdm; } tx_power_legacy_t; -#define WL_TX_POWER_RATES 45 -#define WL_TX_POWER_CCK_FIRST 0 -#define WL_TX_POWER_CCK_NUM 4 +#define WL_TX_POWER_RATES 45 +#define WL_TX_POWER_CCK_FIRST 0 +#define WL_TX_POWER_CCK_NUM 4 #define WL_TX_POWER_OFDM_FIRST 4 -#define WL_TX_POWER_OFDM_NUM 8 -#define WL_TX_POWER_MCS_SISO_NUM 8 -#define WL_TX_POWER_MCS20_FIRST 12 -#define WL_TX_POWER_MCS20_NUM 16 -#define WL_TX_POWER_MCS40_FIRST 28 -#define WL_TX_POWER_MCS40_NUM 17 -#define WL_TX_POWER_MCS20SISO_NUM 8 +#define WL_TX_POWER_OFDM_NUM 8 +#define WL_TX_POWER_MCS_SISO_NUM 8 +#define WL_TX_POWER_MCS20_FIRST 12 +#define WL_TX_POWER_MCS20_NUM 16 +#define WL_TX_POWER_MCS40_FIRST 28 +#define WL_TX_POWER_MCS40_NUM 17 +#define WL_TX_POWER_MCS20SISO_NUM 8 #define WL_TX_POWER_MCS40_LAST 44 -#define WL_TX_POWER_F_ENABLED 1 -#define WL_TX_POWER_F_HW 2 -#define WL_TX_POWER_F_MIMO 4 -#define WL_TX_POWER_F_SISO 8 -#define WL_TX_POWER_F_40M_CAP 16 +#define WL_TX_POWER_F_ENABLED 1 +#define WL_TX_POWER_F_HW 2 +#define WL_TX_POWER_F_MIMO 4 +#define WL_TX_POWER_F_SISO 8 +#define WL_TX_POWER_F_40M_CAP 16 #define MAX_QTX_POWER 32 typedef struct { - uint32_t flags; - wl_chanspec_t chanspec; - wl_chanspec_t local_chanspec; - uint8_t local_max; - uint8_t local_constraint; - int8_t antgain[2]; - uint8_t rf_cores; - uint8_t est_Pout[4]; - uint8_t est_Pout_cck; - uint8_t user_limit[WL_TX_POWER_RATES]; - uint8_t reg_limit[WL_TX_POWER_RATES]; - uint8_t board_limit[WL_TX_POWER_RATES]; - uint8_t target[WL_TX_POWER_RATES]; + uint32_t flags; + wl_chanspec_t chanspec; + wl_chanspec_t local_chanspec; + uint8_t local_max; + uint8_t local_constraint; + int8_t antgain[2]; + uint8_t rf_cores; + uint8_t est_Pout[4]; + uint8_t est_Pout_cck; + uint8_t user_limit[WL_TX_POWER_RATES]; + uint8_t reg_limit[WL_TX_POWER_RATES]; + uint8_t board_limit[WL_TX_POWER_RATES]; + uint8_t target[WL_TX_POWER_RATES]; } tx_power_t; -typedef struct tx_inst_power { - uint8_t txpwr_est_Pout[2]; - uint8_t txpwr_est_Pout_gofdm; +typedef struct tx_inst_power +{ + uint8_t txpwr_est_Pout[2]; + uint8_t txpwr_est_Pout_gofdm; } tx_inst_power_t; -#define WLC_MEASURE_TPC 1 -#define WLC_MEASURE_CHANNEL_BASIC 2 -#define WLC_MEASURE_CHANNEL_CCA 3 -#define WLC_MEASURE_CHANNEL_RPI 4 -#define SPECT_MNGMT_OFF 0 -#define SPECT_MNGMT_LOOSE_11H 1 -#define SPECT_MNGMT_STRICT_11H 2 -#define SPECT_MNGMT_STRICT_11D 3 -#define SPECT_MNGMT_LOOSE_11H_D 4 -#define WL_CHAN_VALID_HW (1 << 0) -#define WL_CHAN_VALID_SW (1 << 1) -#define WL_CHAN_BAND_5G (1 << 2) -#define WL_CHAN_RADAR (1 << 3) -#define WL_CHAN_INACTIVE (1 << 4) -#define WL_CHAN_PASSIVE (1 << 5) -#define WL_CHAN_RESTRICTED (1 << 6) -#define WL_BTC_DISABLE 0 -#define WL_BTC_ENABLE (1 << 0) -#define WL_BTC_PREMPT (1 << 1) -#define WL_BTC_PARTIAL (1 << 2) -#define WL_BTC_DEFAULT (1 << 3) -#define WL_BTC_HYBRID (WL_BTC_ENABLE | WL_BTC_PARTIAL) -#define WL_INF_BTC_DISABLE 0 -#define WL_INF_BTC_ENABLE 1 -#define WL_INF_BTC_AUTO 3 -#define WL_BTC_DEFWIRE 0 -#define WL_BTC_2WIRE 2 -#define WL_BTC_3WIRE 3 -#define WL_BTC_4WIRE 4 -#define WL_BTC_FLAG_PREMPT (1 << 0) -#define WL_BTC_FLAG_BT_DEF (1 << 1) -#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) -#define WL_BTC_FLAG_SIM_RSP (1 << 3) -#define WL_BTC_FLAG_PS_PROTECT (1 << 4) -#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) -#define WL_BTC_FLAG_ECI (1 << 6) -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 -#define WL_PRHDRS_VAL 0x00000004 -#define WL_PRPKT_VAL 0x00000008 -#define WL_INFORM_VAL 0x00000010 -#define WL_TMP_VAL 0x00000020 -#define WL_OID_VAL 0x00000040 -#define WL_RATE_VAL 0x00000080 -#define WL_ASSOC_VAL 0x00000100 -#define WL_PRUSR_VAL 0x00000200 -#define WL_PS_VAL 0x00000400 -#define WL_TXPWR_VAL 0x00000800 -#define WL_PORT_VAL 0x00001000 -#define WL_DUAL_VAL 0x00002000 -#define WL_WSEC_VAL 0x00004000 -#define WL_WSEC_DUMP_VAL 0x00008000 -#define WL_LOG_VAL 0x00010000 -#define WL_NRSSI_VAL 0x00020000 -#define WL_LOFT_VAL 0x00040000 -#define WL_REGULATORY_VAL 0x00080000 -#define WL_PHYCAL_VAL 0x00100000 -#define WL_RADAR_VAL 0x00200000 -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_NITRO_VAL 0x04000000 -#define WL_MBSS_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 -#define WL_FFPLD_VAL 0x40000000 -#define WL_NIN_VAL 0x80000000 -#define WL_DPT_VAL 0x00000001 -#define WL_SCAN_VAL 0x00000002 -#define WL_WOWL_VAL 0x00000004 -#define WL_COEX_VAL 0x00000008 -#define WL_RTDC_VAL 0x00000010 -#define WL_BTA_VAL 0x00000040 -#define WL_LED_NUMGPIO 16 -#define WL_LED_OFF 0 -#define WL_LED_ON 1 -#define WL_LED_ACTIVITY 2 -#define WL_LED_RADIO 3 -#define WL_LED_ARADIO 4 -#define WL_LED_BRADIO 5 -#define WL_LED_BGMODE 6 -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 -#define WL_LED_INACTIVE 11 -#define WL_LED_ASSOCACT 12 -#define WL_LED_NUMBEHAVIOR 13 -#define WL_LED_BEH_MASK 0x7f -#define WL_LED_AL_MASK 0x80 -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 -#define WL_WDS_WPA_ROLE_AUTH 0 -#define WL_WDS_WPA_ROLE_SUP 1 -#define WL_WDS_WPA_ROLE_AUTO 255 -#define WL_EVENTING_MASK_LEN ((WLC_E_LAST + 7) / 8) - -#define VNDR_IE_CMD_LEN 4 -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 -#define VNDR_IE_PRBREQ_FLAG 0x10 -#define VNDR_IE_ASSOCREQ_FLAG 0x20 -#define VNDR_IE_CUSTOM_FLAG 0x100 -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32_t)) -struct wl_vndr_ie { - uint8_t id; - uint8_t len; - uint8_t oui[3]; - uint8_t data[1]; +#define WLC_MEASURE_TPC 1 +#define WLC_MEASURE_CHANNEL_BASIC 2 +#define WLC_MEASURE_CHANNEL_CCA 3 +#define WLC_MEASURE_CHANNEL_RPI 4 +#define SPECT_MNGMT_OFF 0 +#define SPECT_MNGMT_LOOSE_11H 1 +#define SPECT_MNGMT_STRICT_11H 2 +#define SPECT_MNGMT_STRICT_11D 3 +#define SPECT_MNGMT_LOOSE_11H_D 4 +#define WL_CHAN_VALID_HW (1 << 0) +#define WL_CHAN_VALID_SW (1 << 1) +#define WL_CHAN_BAND_5G (1 << 2) +#define WL_CHAN_RADAR (1 << 3) +#define WL_CHAN_INACTIVE (1 << 4) +#define WL_CHAN_PASSIVE (1 << 5) +#define WL_CHAN_RESTRICTED (1 << 6) +#define WL_BTC_DISABLE 0 +#define WL_BTC_ENABLE (1 << 0) +#define WL_BTC_PREMPT (1 << 1) +#define WL_BTC_PARTIAL (1 << 2) +#define WL_BTC_DEFAULT (1 << 3) +#define WL_BTC_HYBRID (WL_BTC_ENABLE | WL_BTC_PARTIAL) +#define WL_INF_BTC_DISABLE 0 +#define WL_INF_BTC_ENABLE 1 +#define WL_INF_BTC_AUTO 3 +#define WL_BTC_DEFWIRE 0 +#define WL_BTC_2WIRE 2 +#define WL_BTC_3WIRE 3 +#define WL_BTC_4WIRE 4 +#define WL_BTC_FLAG_PREMPT (1 << 0) +#define WL_BTC_FLAG_BT_DEF (1 << 1) +#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2) +#define WL_BTC_FLAG_SIM_RSP (1 << 3) +#define WL_BTC_FLAG_PS_PROTECT (1 << 4) +#define WL_BTC_FLAG_SIM_TX_LP (1 << 5) +#define WL_BTC_FLAG_ECI (1 << 6) +#define WL_ERROR_VAL 0x00000001 +#define WL_TRACE_VAL 0x00000002 +#define WL_PRHDRS_VAL 0x00000004 +#define WL_PRPKT_VAL 0x00000008 +#define WL_INFORM_VAL 0x00000010 +#define WL_TMP_VAL 0x00000020 +#define WL_OID_VAL 0x00000040 +#define WL_RATE_VAL 0x00000080 +#define WL_ASSOC_VAL 0x00000100 +#define WL_PRUSR_VAL 0x00000200 +#define WL_PS_VAL 0x00000400 +#define WL_TXPWR_VAL 0x00000800 +#define WL_PORT_VAL 0x00001000 +#define WL_DUAL_VAL 0x00002000 +#define WL_WSEC_VAL 0x00004000 +#define WL_WSEC_DUMP_VAL 0x00008000 +#define WL_LOG_VAL 0x00010000 +#define WL_NRSSI_VAL 0x00020000 +#define WL_LOFT_VAL 0x00040000 +#define WL_REGULATORY_VAL 0x00080000 +#define WL_PHYCAL_VAL 0x00100000 +#define WL_RADAR_VAL 0x00200000 +#define WL_MPC_VAL 0x00400000 +#define WL_APSTA_VAL 0x00800000 +#define WL_DFS_VAL 0x01000000 +#define WL_BA_VAL 0x02000000 +#define WL_NITRO_VAL 0x04000000 +#define WL_MBSS_VAL 0x04000000 +#define WL_CAC_VAL 0x08000000 +#define WL_AMSDU_VAL 0x10000000 +#define WL_AMPDU_VAL 0x20000000 +#define WL_FFPLD_VAL 0x40000000 +#define WL_NIN_VAL 0x80000000 +#define WL_DPT_VAL 0x00000001 +#define WL_SCAN_VAL 0x00000002 +#define WL_WOWL_VAL 0x00000004 +#define WL_COEX_VAL 0x00000008 +#define WL_RTDC_VAL 0x00000010 +#define WL_BTA_VAL 0x00000040 +#define WL_LED_NUMGPIO 16 +#define WL_LED_OFF 0 +#define WL_LED_ON 1 +#define WL_LED_ACTIVITY 2 +#define WL_LED_RADIO 3 +#define WL_LED_ARADIO 4 +#define WL_LED_BRADIO 5 +#define WL_LED_BGMODE 6 +#define WL_LED_WI1 7 +#define WL_LED_WI2 8 +#define WL_LED_WI3 9 +#define WL_LED_ASSOC 10 +#define WL_LED_INACTIVE 11 +#define WL_LED_ASSOCACT 12 +#define WL_LED_NUMBEHAVIOR 13 +#define WL_LED_BEH_MASK 0x7f +#define WL_LED_AL_MASK 0x80 +#define WL_NUMCHANNELS 64 +#define WL_NUMCHANSPECS 100 +#define WL_WDS_WPA_ROLE_AUTH 0 +#define WL_WDS_WPA_ROLE_SUP 1 +#define WL_WDS_WPA_ROLE_AUTO 255 +#define WL_EVENTING_MASK_LEN 16 + +#define MAXCHANNEL 236 + +#define VNDR_IE_CMD_LEN 4 +#define VNDR_IE_BEACON_FLAG 0x1 +#define VNDR_IE_PRBRSP_FLAG 0x2 +#define VNDR_IE_ASSOCRSP_FLAG 0x4 +#define VNDR_IE_AUTHRSP_FLAG 0x8 +#define VNDR_IE_PRBREQ_FLAG 0x10 +#define VNDR_IE_ASSOCREQ_FLAG 0x20 +#define VNDR_IE_CUSTOM_FLAG 0x100 +#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32_t) ) +struct wl_vndr_ie +{ + uint8_t id; + uint8_t len; + uint8_t oui[3]; + uint8_t data[1]; }; typedef struct wl_vndr_ie wl_vndr_ie_t; typedef struct { - uint32_t pktflag; - wl_vndr_ie_t vndr_ie_data; + uint32_t pktflag; + wl_vndr_ie_t vndr_ie_data; } vndr_ie_info_t; typedef struct { - int32_t iecount; - vndr_ie_info_t vndr_ie_list[1]; + int32_t iecount; + vndr_ie_info_t vndr_ie_list[1]; } vndr_ie_buf_t; typedef struct { - int8_t cmd[VNDR_IE_CMD_LEN]; - vndr_ie_buf_t vndr_ie_buffer; + int8_t cmd[VNDR_IE_CMD_LEN]; + vndr_ie_buf_t vndr_ie_buffer; } vndr_ie_setbuf_t; #define WL_JOIN_PREF_RSSI 1 -#define WL_JOIN_PREF_WPA 2 +#define WL_JOIN_PREF_WPA 2 #define WL_JOIN_PREF_BAND 3 -#define WLJP_BAND_ASSOC_PREF 255 -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" -struct tsinfo_arg { - uint8_t octets[3]; +#define WLJP_BAND_ASSOC_PREF 255 +#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" +struct tsinfo_arg +{ + uint8_t octets[3]; }; -#define NREINITREASONCOUNT 8 +#define NREINITREASONCOUNT 8 /* XXX NREINITREASONCOUNT is 8 in other branches. * Any change to this will break wl tool compatibility with other branches * #define NREINITREASONCOUNT WL_REINIT_RC_LAST */ -#define NFIFO 6 -#define WL_CNT_T_VERSION 6 -#define WL_CNT_EXT_T_VERSION 1 -#define WL_PHYRATE_LOG_SIZE 1200 +#define NFIFO 6 +#define WL_CNT_T_VERSION 6 +#define WL_CNT_EXT_T_VERSION 1 +#define WL_PHYRATE_LOG_SIZE 1200 typedef struct { - uint16_t version; /**< see definition of WL_CNT_T_VERSION */ - uint16_t datalen; /**< length of data including all paddings. */ - uint8_t data[1]; /**< variable length payload: + uint16_t version; /**< see definition of WL_CNT_T_VERSION */ + uint16_t datalen; /**< length of data including all paddings. */ + uint8_t data[1]; /**< variable length payload: * 1 or more bcm_xtlv_t type of tuples. * each tuple is padded to multiple of 4 bytes. * 'datalen' field of this structure includes all paddings. @@ -1522,172 +1935,172 @@ typedef struct /** wlc layer counters */ typedef struct { - /* transmit stat counters */ - uint32_t txframe; /**< tx data frames */ - uint32_t txbyte; /**< tx data bytes */ - uint32_t txretrans; /**< tx mac retransmits */ - uint32_t txerror; /**< tx data errors (derived: sum of others) */ - uint32_t txctl; /**< tx management frames */ - uint32_t txprshort; /**< tx short preamble frames */ - uint32_t txserr; /**< tx status errors */ - uint32_t txnobuf; /**< tx out of buffers errors */ - uint32_t txnoassoc; /**< tx discard because we're not associated */ - uint32_t txrunt; /**< tx runt frames */ - uint32_t txchit; /**< tx header cache hit (fastpath) */ - uint32_t txcmiss; /**< tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32_t txuflo; /**< tx fifo underflows */ - uint32_t txphyerr; /**< tx phy errors (indicated in tx status) */ - uint32_t txphycrs; /**< PR8861/8963 counter */ - - /* receive stat counters */ - uint32_t rxframe; /**< rx data frames */ - uint32_t rxbyte; /**< rx data bytes */ - uint32_t rxerror; /**< rx data errors (derived: sum of others) */ - uint32_t rxctl; /**< rx management frames */ - uint32_t rxnobuf; /**< rx out of buffers errors */ - uint32_t rxnondata; /**< rx non data frames in the data channel errors */ - uint32_t rxbadds; /**< rx bad DS errors */ - uint32_t rxbadcm; /**< rx bad control or management frames */ - uint32_t rxfragerr; /**< rx fragmentation errors */ - uint32_t rxrunt; /**< rx runt frames */ - uint32_t rxgiant; /**< rx giant frames */ - uint32_t rxnoscb; /**< rx no scb error */ - uint32_t rxbadproto; /**< rx invalid frames */ - uint32_t rxbadsrcmac; /**< rx frames with Invalid Src Mac */ - uint32_t rxbadda; /**< rx frames tossed for invalid da */ - uint32_t rxfilter; /**< rx frames filtered out */ - - /* receive chip error counters */ - uint32_t rxoflo; /**< rx fifo overflow errors */ - uint32_t rxuflo[NFIFO]; /**< rx dma descriptor underflow errors */ - - uint32_t d11cnt_txrts_off; /**< d11cnt txrts value when reset d11cnt */ - uint32_t d11cnt_rxcrc_off; /**< d11cnt rxcrc value when reset d11cnt */ - uint32_t d11cnt_txnocts_off; /**< d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32_t dmade; /**< tx/rx dma descriptor errors */ - uint32_t dmada; /**< tx/rx dma data errors */ - uint32_t dmape; /**< tx/rx dma descriptor protocol errors */ - uint32_t reset; /**< reset count */ - uint32_t tbtt; /**< cnts the TBTT int's */ - uint32_t txdmawar; /**< # occurrences of PR15420 workaround */ - uint32_t pkt_callback_reg_fail; /**< callbacks register failure */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32_t txfrag; /**< dot11TransmittedFragmentCount */ - uint32_t txmulti; /**< dot11MulticastTransmittedFrameCount */ - uint32_t txfail; /**< dot11FailedCount */ - uint32_t txretry; /**< dot11RetryCount */ - uint32_t txretrie; /**< dot11MultipleRetryCount */ - uint32_t rxdup; /**< dot11FrameduplicateCount */ - uint32_t txrts; /**< dot11RTSSuccessCount */ - uint32_t txnocts; /**< dot11RTSFailureCount */ - uint32_t txnoack; /**< dot11ACKFailureCount */ - uint32_t rxfrag; /**< dot11ReceivedFragmentCount */ - uint32_t rxmulti; /**< dot11MulticastReceivedFrameCount */ - uint32_t rxcrc; /**< dot11FCSErrorCount */ - uint32_t txfrmsnt; /**< dot11TransmittedFrameCount (bogus MIB?) */ - uint32_t rxundec; /**< dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill; /**< TKIPLocalMICFailures */ - uint32_t tkipcntrmsr; /**< TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay; /**< TKIPReplays */ - uint32_t ccmpfmterr; /**< CCMPFormatErrors */ - uint32_t ccmpreplay; /**< CCMPReplays */ - uint32_t ccmpundec; /**< CCMPDecryptErrors */ - uint32_t fourwayfail; /**< FourWayHandshakeFailures */ - uint32_t wepundec; /**< dot11WEPUndecryptableCount */ - uint32_t wepicverr; /**< dot11WEPICVErrorCount */ - uint32_t decsuccess; /**< DecryptSuccessCount */ - uint32_t tkipicverr; /**< TKIPICVErrorCount */ - uint32_t wepexcluded; /**< dot11WEPExcludedCount */ - - uint32_t txchanrej; /**< Tx frames suppressed due to channel rejection */ - uint32_t psmwds; /**< Count PSM watchdogs */ - uint32_t phywatchdog; /**< Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - uint32_t prq_entries_handled; /**< PRQ entries read in */ - uint32_t prq_undirected_entries; /**< which were bcast bss & ssid */ - uint32_t prq_bad_entries; /**< which could not be translated to info */ - uint32_t atim_suppress_count; /**< TX suppressions on ATIM fifo */ - uint32_t bcn_template_not_ready; /**< Template marked in use on send bcn ... */ - uint32_t bcn_template_not_ready_done; /**< ...but "DMA done" interrupt rcvd */ - uint32_t late_tbtt_dpc; /**< TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - uint32_t rx1mbps; /**< packets rx at 1Mbps */ - uint32_t rx2mbps; /**< packets rx at 2Mbps */ - uint32_t rx5mbps5; /**< packets rx at 5.5Mbps */ - uint32_t rx6mbps; /**< packets rx at 6Mbps */ - uint32_t rx9mbps; /**< packets rx at 9Mbps */ - uint32_t rx11mbps; /**< packets rx at 11Mbps */ - uint32_t rx12mbps; /**< packets rx at 12Mbps */ - uint32_t rx18mbps; /**< packets rx at 18Mbps */ - uint32_t rx24mbps; /**< packets rx at 24Mbps */ - uint32_t rx36mbps; /**< packets rx at 36Mbps */ - uint32_t rx48mbps; /**< packets rx at 48Mbps */ - uint32_t rx54mbps; /**< packets rx at 54Mbps */ - uint32_t rx108mbps; /**< packets rx at 108mbps */ - uint32_t rx162mbps; /**< packets rx at 162mbps */ - uint32_t rx216mbps; /**< packets rx at 216 mbps */ - uint32_t rx270mbps; /**< packets rx at 270 mbps */ - uint32_t rx324mbps; /**< packets rx at 324 mbps */ - uint32_t rx378mbps; /**< packets rx at 378 mbps */ - uint32_t rx432mbps; /**< packets rx at 432 mbps */ - uint32_t rx486mbps; /**< packets rx at 486 mbps */ - uint32_t rx540mbps; /**< packets rx at 540 mbps */ - - uint32_t rfdisable; /**< count of radio disables */ - - uint32_t txexptime; /**< Tx frames suppressed due to timer expiration */ - - uint32_t txmpdu_sgi; /**< count for sgi transmit */ - uint32_t rxmpdu_sgi; /**< count for sgi received */ - uint32_t txmpdu_stbc; /**< count for stbc transmit */ - uint32_t rxmpdu_stbc; /**< count for stbc received */ - - uint32_t rxundec_mcst; /**< dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill_mcst; /**< TKIPLocalMICFailures */ - uint32_t tkipcntrmsr_mcst; /**< TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay_mcst; /**< TKIPReplays */ - uint32_t ccmpfmterr_mcst; /**< CCMPFormatErrors */ - uint32_t ccmpreplay_mcst; /**< CCMPReplays */ - uint32_t ccmpundec_mcst; /**< CCMPDecryptErrors */ - uint32_t fourwayfail_mcst; /**< FourWayHandshakeFailures */ - uint32_t wepundec_mcst; /**< dot11WEPUndecryptableCount */ - uint32_t wepicverr_mcst; /**< dot11WEPICVErrorCount */ - uint32_t decsuccess_mcst; /**< DecryptSuccessCount */ - uint32_t tkipicverr_mcst; /**< TKIPICVErrorCount */ - uint32_t wepexcluded_mcst; /**< dot11WEPExcludedCount */ - - uint32_t dma_hang; /**< count for dma hang */ - uint32_t reinit; /**< count for reinit */ - - uint32_t pstatxucast; /**< count of ucast frames xmitted on all psta assoc */ - uint32_t pstatxnoassoc; /**< count of txnoassoc frames xmitted on all psta assoc */ - uint32_t pstarxucast; /**< count of ucast frames received on all psta assoc */ - uint32_t pstarxbcmc; /**< count of bcmc frames received on all psta */ - uint32_t pstatxbcmc; /**< count of bcmc frames transmitted on all psta */ - - uint32_t cso_passthrough; /**< hw cso required but passthrough */ - uint32_t cso_normal; /**< hw cso hdr for normal process */ - uint32_t chained; /**< number of frames chained */ - uint32_t chainedsz1; /**< number of chain size 1 frames */ - uint32_t unchained; /**< number of frames not chained */ - uint32_t maxchainsz; /**< max chain size so far */ - uint32_t currchainsz; /**< current chain size */ - uint32_t pciereset; /**< Secondary Bus Reset issued by driver */ - uint32_t cfgrestore; /**< configspace restore by driver */ - uint32_t reinitreason[NREINITREASONCOUNT]; /**< reinitreason counters; 0: Unknown reason */ - uint32_t rxrtry; - uint32_t rxmpdu_mu; /**< Number of MU MPDUs received */ + /* transmit stat counters */ + uint32_t txframe; /**< tx data frames */ + uint32_t txbyte; /**< tx data bytes */ + uint32_t txretrans; /**< tx mac retransmits */ + uint32_t txerror; /**< tx data errors (derived: sum of others) */ + uint32_t txctl; /**< tx management frames */ + uint32_t txprshort; /**< tx short preamble frames */ + uint32_t txserr; /**< tx status errors */ + uint32_t txnobuf; /**< tx out of buffers errors */ + uint32_t txnoassoc; /**< tx discard because we're not associated */ + uint32_t txrunt; /**< tx runt frames */ + uint32_t txchit; /**< tx header cache hit (fastpath) */ + uint32_t txcmiss; /**< tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32_t txuflo; /**< tx fifo underflows */ + uint32_t txphyerr; /**< tx phy errors (indicated in tx status) */ + uint32_t txphycrs; /**< PR8861/8963 counter */ + + /* receive stat counters */ + uint32_t rxframe; /**< rx data frames */ + uint32_t rxbyte; /**< rx data bytes */ + uint32_t rxerror; /**< rx data errors (derived: sum of others) */ + uint32_t rxctl; /**< rx management frames */ + uint32_t rxnobuf; /**< rx out of buffers errors */ + uint32_t rxnondata; /**< rx non data frames in the data channel errors */ + uint32_t rxbadds; /**< rx bad DS errors */ + uint32_t rxbadcm; /**< rx bad control or management frames */ + uint32_t rxfragerr; /**< rx fragmentation errors */ + uint32_t rxrunt; /**< rx runt frames */ + uint32_t rxgiant; /**< rx giant frames */ + uint32_t rxnoscb; /**< rx no scb error */ + uint32_t rxbadproto; /**< rx invalid frames */ + uint32_t rxbadsrcmac; /**< rx frames with Invalid Src Mac */ + uint32_t rxbadda; /**< rx frames tossed for invalid da */ + uint32_t rxfilter; /**< rx frames filtered out */ + + /* receive chip error counters */ + uint32_t rxoflo; /**< rx fifo overflow errors */ + uint32_t rxuflo[NFIFO]; /**< rx dma descriptor underflow errors */ + + uint32_t d11cnt_txrts_off; /**< d11cnt txrts value when reset d11cnt */ + uint32_t d11cnt_rxcrc_off; /**< d11cnt rxcrc value when reset d11cnt */ + uint32_t d11cnt_txnocts_off; /**< d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32_t dmade; /**< tx/rx dma descriptor errors */ + uint32_t dmada; /**< tx/rx dma data errors */ + uint32_t dmape; /**< tx/rx dma descriptor protocol errors */ + uint32_t reset; /**< reset count */ + uint32_t tbtt; /**< cnts the TBTT int's */ + uint32_t txdmawar; /**< # occurrences of PR15420 workaround */ + uint32_t pkt_callback_reg_fail; /**< callbacks register failure */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32_t txfrag; /**< dot11TransmittedFragmentCount */ + uint32_t txmulti; /**< dot11MulticastTransmittedFrameCount */ + uint32_t txfail; /**< dot11FailedCount */ + uint32_t txretry; /**< dot11RetryCount */ + uint32_t txretrie; /**< dot11MultipleRetryCount */ + uint32_t rxdup; /**< dot11FrameduplicateCount */ + uint32_t txrts; /**< dot11RTSSuccessCount */ + uint32_t txnocts; /**< dot11RTSFailureCount */ + uint32_t txnoack; /**< dot11ACKFailureCount */ + uint32_t rxfrag; /**< dot11ReceivedFragmentCount */ + uint32_t rxmulti; /**< dot11MulticastReceivedFrameCount */ + uint32_t rxcrc; /**< dot11FCSErrorCount */ + uint32_t txfrmsnt; /**< dot11TransmittedFrameCount (bogus MIB?) */ + uint32_t rxundec; /**< dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill; /**< TKIPLocalMICFailures */ + uint32_t tkipcntrmsr; /**< TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay; /**< TKIPReplays */ + uint32_t ccmpfmterr; /**< CCMPFormatErrors */ + uint32_t ccmpreplay; /**< CCMPReplays */ + uint32_t ccmpundec; /**< CCMPDecryptErrors */ + uint32_t fourwayfail; /**< FourWayHandshakeFailures */ + uint32_t wepundec; /**< dot11WEPUndecryptableCount */ + uint32_t wepicverr; /**< dot11WEPICVErrorCount */ + uint32_t decsuccess; /**< DecryptSuccessCount */ + uint32_t tkipicverr; /**< TKIPICVErrorCount */ + uint32_t wepexcluded; /**< dot11WEPExcludedCount */ + + uint32_t txchanrej; /**< Tx frames suppressed due to channel rejection */ + uint32_t psmwds; /**< Count PSM watchdogs */ + uint32_t phywatchdog; /**< Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32_t prq_entries_handled; /**< PRQ entries read in */ + uint32_t prq_undirected_entries; /**< which were bcast bss & ssid */ + uint32_t prq_bad_entries; /**< which could not be translated to info */ + uint32_t atim_suppress_count; /**< TX suppressions on ATIM fifo */ + uint32_t bcn_template_not_ready; /**< Template marked in use on send bcn ... */ + uint32_t bcn_template_not_ready_done; /**< ...but "DMA done" interrupt rcvd */ + uint32_t late_tbtt_dpc; /**< TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32_t rx1mbps; /**< packets rx at 1Mbps */ + uint32_t rx2mbps; /**< packets rx at 2Mbps */ + uint32_t rx5mbps5; /**< packets rx at 5.5Mbps */ + uint32_t rx6mbps; /**< packets rx at 6Mbps */ + uint32_t rx9mbps; /**< packets rx at 9Mbps */ + uint32_t rx11mbps; /**< packets rx at 11Mbps */ + uint32_t rx12mbps; /**< packets rx at 12Mbps */ + uint32_t rx18mbps; /**< packets rx at 18Mbps */ + uint32_t rx24mbps; /**< packets rx at 24Mbps */ + uint32_t rx36mbps; /**< packets rx at 36Mbps */ + uint32_t rx48mbps; /**< packets rx at 48Mbps */ + uint32_t rx54mbps; /**< packets rx at 54Mbps */ + uint32_t rx108mbps; /**< packets rx at 108mbps */ + uint32_t rx162mbps; /**< packets rx at 162mbps */ + uint32_t rx216mbps; /**< packets rx at 216 mbps */ + uint32_t rx270mbps; /**< packets rx at 270 mbps */ + uint32_t rx324mbps; /**< packets rx at 324 mbps */ + uint32_t rx378mbps; /**< packets rx at 378 mbps */ + uint32_t rx432mbps; /**< packets rx at 432 mbps */ + uint32_t rx486mbps; /**< packets rx at 486 mbps */ + uint32_t rx540mbps; /**< packets rx at 540 mbps */ + + uint32_t rfdisable; /**< count of radio disables */ + + uint32_t txexptime; /**< Tx frames suppressed due to timer expiration */ + + uint32_t txmpdu_sgi; /**< count for sgi transmit */ + uint32_t rxmpdu_sgi; /**< count for sgi received */ + uint32_t txmpdu_stbc; /**< count for stbc transmit */ + uint32_t rxmpdu_stbc; /**< count for stbc received */ + + uint32_t rxundec_mcst; /**< dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill_mcst; /**< TKIPLocalMICFailures */ + uint32_t tkipcntrmsr_mcst; /**< TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay_mcst; /**< TKIPReplays */ + uint32_t ccmpfmterr_mcst; /**< CCMPFormatErrors */ + uint32_t ccmpreplay_mcst; /**< CCMPReplays */ + uint32_t ccmpundec_mcst; /**< CCMPDecryptErrors */ + uint32_t fourwayfail_mcst; /**< FourWayHandshakeFailures */ + uint32_t wepundec_mcst; /**< dot11WEPUndecryptableCount */ + uint32_t wepicverr_mcst; /**< dot11WEPICVErrorCount */ + uint32_t decsuccess_mcst; /**< DecryptSuccessCount */ + uint32_t tkipicverr_mcst; /**< TKIPICVErrorCount */ + uint32_t wepexcluded_mcst; /**< dot11WEPExcludedCount */ + + uint32_t dma_hang; /**< count for dma hang */ + uint32_t reinit; /**< count for reinit */ + + uint32_t pstatxucast; /**< count of ucast frames xmitted on all psta assoc */ + uint32_t pstatxnoassoc; /**< count of txnoassoc frames xmitted on all psta assoc */ + uint32_t pstarxucast; /**< count of ucast frames received on all psta assoc */ + uint32_t pstarxbcmc; /**< count of bcmc frames received on all psta */ + uint32_t pstatxbcmc; /**< count of bcmc frames transmitted on all psta */ + + uint32_t cso_passthrough; /**< hw cso required but passthrough */ + uint32_t cso_normal; /**< hw cso hdr for normal process */ + uint32_t chained; /**< number of frames chained */ + uint32_t chainedsz1; /**< number of chain size 1 frames */ + uint32_t unchained; /**< number of frames not chained */ + uint32_t maxchainsz; /**< max chain size so far */ + uint32_t currchainsz; /**< current chain size */ + uint32_t pciereset; /**< Secondary Bus Reset issued by driver */ + uint32_t cfgrestore; /**< configspace restore by driver */ + uint32_t reinitreason[NREINITREASONCOUNT]; /**< reinitreason counters; 0: Unknown reason */ + uint32_t rxrtry; + uint32_t rxmpdu_mu; /**< Number of MU MPDUs received */ /* detailed control/management frames */ uint32_t txbar; /**< Number of TX BAR */ @@ -1734,1642 +2147,1710 @@ typedef struct uint32_t rxbcast; /* BroadcastReceivedFrameCount */ uint32_t rxdropped; /* rx dropped pkts (derived: sum of others) */ /* XXX: Do not remove or rename in the middle of this struct. - * All counter variables have to be of uint32_t. - * Please follow the instruction in - * http://hwnbu-twiki.sj.broadcom.com/bin/view/Mwgroup/WlCounters#Counter_Edition - */ + * All counter variables have to be of uint32_t. + * Please follow the instruction in + * http://hwnbu-twiki.sj.broadcom.com/bin/view/Mwgroup/WlCounters#Counter_Edition + */ } wl_cnt_ver_30_t; typedef struct { - uint16_t version; /* see definition of WL_CNT_T_VERSION */ - uint16_t length; /* length of entire structure */ - - /* transmit stat counters */ - uint32_t txframe; /* tx data frames */ - uint32_t txbyte; /* tx data bytes */ - uint32_t txretrans; /* tx mac retransmits */ - uint32_t txerror; /* tx data errors (derived: sum of others) */ - uint32_t txctl; /* tx management frames */ - uint32_t txprshort; /* tx short preamble frames */ - uint32_t txserr; /* tx status errors */ - uint32_t txnobuf; /* tx out of buffers errors */ - uint32_t txnoassoc; /* tx discard because we're not associated */ - uint32_t txrunt; /* tx runt frames */ - uint32_t txchit; /* tx header cache hit (fastpath) */ - uint32_t txcmiss; /* tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32_t txuflo; /* tx fifo underflows */ - uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ - uint32_t txphycrs; /* PR8861/8963 counter */ - - /* receive stat counters */ - uint32_t rxframe; /* rx data frames */ - uint32_t rxbyte; /* rx data bytes */ - uint32_t rxerror; /* rx data errors (derived: sum of others) */ - uint32_t rxctl; /* rx management frames */ - uint32_t rxnobuf; /* rx out of buffers errors */ - uint32_t rxnondata; /* rx non data frames in the data channel errors */ - uint32_t rxbadds; /* rx bad DS errors */ - uint32_t rxbadcm; /* rx bad control or management frames */ - uint32_t rxfragerr; /* rx fragmentation errors */ - uint32_t rxrunt; /* rx runt frames */ - uint32_t rxgiant; /* rx giant frames */ - uint32_t rxnoscb; /* rx no scb error */ - uint32_t rxbadproto; /* rx invalid frames */ - uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ - uint32_t rxbadda; /* rx frames tossed for invalid da */ - uint32_t rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - uint32_t rxoflo; /* rx fifo overflow errors */ - uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32_t dmade; /* tx/rx dma descriptor errors */ - uint32_t dmada; /* tx/rx dma data errors */ - uint32_t dmape; /* tx/rx dma descriptor protocol errors */ - uint32_t reset; /* reset count */ - uint32_t tbtt; /* cnts the TBTT int's */ - uint32_t txdmawar; /* # occurrences of PR15420 workaround */ - uint32_t pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + uint16_t version; /* see definition of WL_CNT_T_VERSION */ + uint16_t length; /* length of entire structure */ + + /* transmit stat counters */ + uint32_t txframe; /* tx data frames */ + uint32_t txbyte; /* tx data bytes */ + uint32_t txretrans; /* tx mac retransmits */ + uint32_t txerror; /* tx data errors (derived: sum of others) */ + uint32_t txctl; /* tx management frames */ + uint32_t txprshort; /* tx short preamble frames */ + uint32_t txserr; /* tx status errors */ + uint32_t txnobuf; /* tx out of buffers errors */ + uint32_t txnoassoc; /* tx discard because we're not associated */ + uint32_t txrunt; /* tx runt frames */ + uint32_t txchit; /* tx header cache hit (fastpath) */ + uint32_t txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32_t txuflo; /* tx fifo underflows */ + uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ + uint32_t txphycrs; /* PR8861/8963 counter */ + + /* receive stat counters */ + uint32_t rxframe; /* rx data frames */ + uint32_t rxbyte; /* rx data bytes */ + uint32_t rxerror; /* rx data errors (derived: sum of others) */ + uint32_t rxctl; /* rx management frames */ + uint32_t rxnobuf; /* rx out of buffers errors */ + uint32_t rxnondata; /* rx non data frames in the data channel errors */ + uint32_t rxbadds; /* rx bad DS errors */ + uint32_t rxbadcm; /* rx bad control or management frames */ + uint32_t rxfragerr; /* rx fragmentation errors */ + uint32_t rxrunt; /* rx runt frames */ + uint32_t rxgiant; /* rx giant frames */ + uint32_t rxnoscb; /* rx no scb error */ + uint32_t rxbadproto; /* rx invalid frames */ + uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32_t rxbadda; /* rx frames tossed for invalid da */ + uint32_t rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32_t rxoflo; /* rx fifo overflow errors */ + uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32_t dmade; /* tx/rx dma descriptor errors */ + uint32_t dmada; /* tx/rx dma data errors */ + uint32_t dmape; /* tx/rx dma descriptor protocol errors */ + uint32_t reset; /* reset count */ + uint32_t tbtt; /* cnts the TBTT int's */ + uint32_t txdmawar; /* # occurrences of PR15420 workaround */ + uint32_t pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, * Control Management (includes retransmissions) */ - uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ - uint32_t txctsfrm; /* number of CTS sent out by the MAC */ - uint32_t txackfrm; /* number of ACK frames sent out */ - uint32_t txdnlfrm; /* Not used */ - uint32_t txbcnfrm; /* beacons transmitted */ - uint32_t txfunfl[8]; /* per-fifo tx underflows */ - uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ + uint32_t txctsfrm; /* number of CTS sent out by the MAC */ + uint32_t txackfrm; /* number of ACK frames sent out */ + uint32_t txdnlfrm; /* Not used */ + uint32_t txbcnfrm; /* beacons transmitted */ + uint32_t txfunfl[8]; /* per-fifo tx underflows */ + uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS * or BCN) */ - uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for + uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for * driver enqueued frames */ - uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not + uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not * data/control/management */ - uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - uint32_t rxbadplcp; /* parity check of the PLCP header failed */ - uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - uint32_t rxstrt; /* Number of received frames with a good PLCP + uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32_t rxbadplcp; /* parity check of the PLCP header failed */ + uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32_t rxstrt; /* Number of received frames with a good PLCP * (i.e. passing parity check) */ - uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ - uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ - uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ - uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC * (unlikely to see these) */ - uint32_t rxbeaconmbss; /* beacons received from member of BSS */ - uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + uint32_t rxbeaconmbss; /* beacons received from member of BSS */ + uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from * other BSS (WDS FRAME) */ - uint32_t rxbeaconobss; /* beacons received from other BSS */ - uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames + uint32_t rxbeaconobss; /* beacons received from other BSS */ + uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames * expecting a response */ - uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ - uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - uint32_t pmqovfl; /* Number of PMQ overflows */ - uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into + uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32_t pmqovfl; /* Number of PMQ overflows */ + uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into * the PRQ fifo */ - uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did * not get ACK */ - uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ + uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ * fifo because a probe response could not be sent out within * the time limit defined in M_PRS_MAXTIME */ - uint32_t rxnack; /* XXX Number of NACKS received (Afterburner) */ - uint32_t frmscons; /* XXX Number of frames completed without transmission because of an + uint32_t rxnack; /* XXX Number of NACKS received (Afterburner) */ + uint32_t frmscons; /* XXX Number of frames completed without transmission because of an * Afterburner re-queue */ - uint32_t txnack; /* XXX Number of NACKs transmitted (Afterburner) */ - uint32_t txglitch_nack; /* obsolete */ - uint32_t txburst; /* obsolete */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32_t txfrag; /* dot11TransmittedFragmentCount */ - uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32_t txfail; /* dot11FailedCount */ - uint32_t txretry; /* dot11RetryCount */ - uint32_t txretrie; /* dot11MultipleRetryCount */ - uint32_t rxdup; /* dot11FrameduplicateCount */ - uint32_t txrts; /* dot11RTSSuccessCount */ - uint32_t txnocts; /* dot11RTSFailureCount */ - uint32_t txnoack; /* dot11ACKFailureCount */ - uint32_t rxfrag; /* dot11ReceivedFragmentCount */ - uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32_t rxcrc; /* dot11FCSErrorCount */ - uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - uint32_t rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay; /* TKIPReplays */ - uint32_t ccmpfmterr; /* CCMPFormatErrors */ - uint32_t ccmpreplay; /* CCMPReplays */ - uint32_t ccmpundec; /* CCMPDecryptErrors */ - uint32_t fourwayfail; /* FourWayHandshakeFailures */ - uint32_t wepundec; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr; /* dot11WEPICVErrorCount */ - uint32_t decsuccess; /* DecryptSuccessCount */ - uint32_t tkipicverr; /* TKIPICVErrorCount */ - uint32_t wepexcluded; /* dot11WEPExcludedCount */ - - uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay_mcst; /* TKIPReplays */ - uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ - uint32_t ccmpreplay_mcst; /* CCMPReplays */ - uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ - uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ - uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ - uint32_t decsuccess_mcst; /* DecryptSuccessCount */ - uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ - uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ - - uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ - uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ - uint32_t psmwds; /* Count PSM watchdogs */ - uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - uint32_t prq_entries_handled; /* PRQ entries read in */ - uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ - uint32_t prq_bad_entries; /* which could not be translated to info */ - uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ - uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ - uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ - uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - uint32_t rx1mbps; /* packets rx at 1Mbps */ - uint32_t rx2mbps; /* packets rx at 2Mbps */ - uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ - uint32_t rx6mbps; /* packets rx at 6Mbps */ - uint32_t rx9mbps; /* packets rx at 9Mbps */ - uint32_t rx11mbps; /* packets rx at 11Mbps */ - uint32_t rx12mbps; /* packets rx at 12Mbps */ - uint32_t rx18mbps; /* packets rx at 18Mbps */ - uint32_t rx24mbps; /* packets rx at 24Mbps */ - uint32_t rx36mbps; /* packets rx at 36Mbps */ - uint32_t rx48mbps; /* packets rx at 48Mbps */ - uint32_t rx54mbps; /* packets rx at 54Mbps */ - uint32_t rx108mbps; /* packets rx at 108mbps */ - uint32_t rx162mbps; /* packets rx at 162mbps */ - uint32_t rx216mbps; /* packets rx at 216 mbps */ - uint32_t rx270mbps; /* packets rx at 270 mbps */ - uint32_t rx324mbps; /* packets rx at 324 mbps */ - uint32_t rx378mbps; /* packets rx at 378 mbps */ - uint32_t rx432mbps; /* packets rx at 432 mbps */ - uint32_t rx486mbps; /* packets rx at 486 mbps */ - uint32_t rx540mbps; /* packets rx at 540 mbps */ - - /* pkteng rx frame stats */ - uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ - uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ - - uint32_t rfdisable; /* count of radio disables */ - uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ - - uint32_t txmpdu_sgi; /* count for sgi transmit */ - uint32_t rxmpdu_sgi; /* count for sgi received */ - uint32_t txmpdu_stbc; /* count for stbc transmit */ - uint32_t rxmpdu_stbc; /* count for stbc received */ + uint32_t txnack; /* XXX Number of NACKs transmitted (Afterburner) */ + uint32_t txglitch_nack; /* obsolete */ + uint32_t txburst; /* obsolete */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32_t txfrag; /* dot11TransmittedFragmentCount */ + uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32_t txfail; /* dot11FailedCount */ + uint32_t txretry; /* dot11RetryCount */ + uint32_t txretrie; /* dot11MultipleRetryCount */ + uint32_t rxdup; /* dot11FrameduplicateCount */ + uint32_t txrts; /* dot11RTSSuccessCount */ + uint32_t txnocts; /* dot11RTSFailureCount */ + uint32_t txnoack; /* dot11ACKFailureCount */ + uint32_t rxfrag; /* dot11ReceivedFragmentCount */ + uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32_t rxcrc; /* dot11FCSErrorCount */ + uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32_t rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay; /* TKIPReplays */ + uint32_t ccmpfmterr; /* CCMPFormatErrors */ + uint32_t ccmpreplay; /* CCMPReplays */ + uint32_t ccmpundec; /* CCMPDecryptErrors */ + uint32_t fourwayfail; /* FourWayHandshakeFailures */ + uint32_t wepundec; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr; /* dot11WEPICVErrorCount */ + uint32_t decsuccess; /* DecryptSuccessCount */ + uint32_t tkipicverr; /* TKIPICVErrorCount */ + uint32_t wepexcluded; /* dot11WEPExcludedCount */ + + uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay_mcst; /* TKIPReplays */ + uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32_t ccmpreplay_mcst; /* CCMPReplays */ + uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32_t decsuccess_mcst; /* DecryptSuccessCount */ + uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ + uint32_t psmwds; /* Count PSM watchdogs */ + uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32_t prq_entries_handled; /* PRQ entries read in */ + uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ + uint32_t prq_bad_entries; /* which could not be translated to info */ + uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32_t rx1mbps; /* packets rx at 1Mbps */ + uint32_t rx2mbps; /* packets rx at 2Mbps */ + uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ + uint32_t rx6mbps; /* packets rx at 6Mbps */ + uint32_t rx9mbps; /* packets rx at 9Mbps */ + uint32_t rx11mbps; /* packets rx at 11Mbps */ + uint32_t rx12mbps; /* packets rx at 12Mbps */ + uint32_t rx18mbps; /* packets rx at 18Mbps */ + uint32_t rx24mbps; /* packets rx at 24Mbps */ + uint32_t rx36mbps; /* packets rx at 36Mbps */ + uint32_t rx48mbps; /* packets rx at 48Mbps */ + uint32_t rx54mbps; /* packets rx at 54Mbps */ + uint32_t rx108mbps; /* packets rx at 108mbps */ + uint32_t rx162mbps; /* packets rx at 162mbps */ + uint32_t rx216mbps; /* packets rx at 216 mbps */ + uint32_t rx270mbps; /* packets rx at 270 mbps */ + uint32_t rx324mbps; /* packets rx at 324 mbps */ + uint32_t rx378mbps; /* packets rx at 378 mbps */ + uint32_t rx432mbps; /* packets rx at 432 mbps */ + uint32_t rx486mbps; /* packets rx at 486 mbps */ + uint32_t rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32_t rfdisable; /* count of radio disables */ + uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ + + uint32_t txmpdu_sgi; /* count for sgi transmit */ + uint32_t rxmpdu_sgi; /* count for sgi received */ + uint32_t txmpdu_stbc; /* count for stbc transmit */ + uint32_t rxmpdu_stbc; /* count for stbc received */ } wl_cnt_ver_six_t; typedef struct { - uint16_t version; /* see definition of WL_CNT_T_VERSION */ - uint16_t length; /* length of entire structure */ - - /* transmit stat counters */ - uint32_t txframe; /* tx data frames */ - uint32_t txbyte; /* tx data bytes */ - uint32_t txretrans; /* tx mac retransmits */ - uint32_t txerror; /* tx data errors (derived: sum of others) */ - uint32_t txctl; /* tx management frames */ - uint32_t txprshort; /* tx short preamble frames */ - uint32_t txserr; /* tx status errors */ - uint32_t txnobuf; /* tx out of buffers errors */ - uint32_t txnoassoc; /* tx discard because we're not associated */ - uint32_t txrunt; /* tx runt frames */ - uint32_t txchit; /* tx header cache hit (fastpath) */ - uint32_t txcmiss; /* tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32_t txuflo; /* tx fifo underflows */ - uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ - uint32_t txphycrs; /* PR8861/8963 counter */ - - /* receive stat counters */ - uint32_t rxframe; /* rx data frames */ - uint32_t rxbyte; /* rx data bytes */ - uint32_t rxerror; /* rx data errors (derived: sum of others) */ - uint32_t rxctl; /* rx management frames */ - uint32_t rxnobuf; /* rx out of buffers errors */ - uint32_t rxnondata; /* rx non data frames in the data channel errors */ - uint32_t rxbadds; /* rx bad DS errors */ - uint32_t rxbadcm; /* rx bad control or management frames */ - uint32_t rxfragerr; /* rx fragmentation errors */ - uint32_t rxrunt; /* rx runt frames */ - uint32_t rxgiant; /* rx giant frames */ - uint32_t rxnoscb; /* rx no scb error */ - uint32_t rxbadproto; /* rx invalid frames */ - uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ - uint32_t rxbadda; /* rx frames tossed for invalid da */ - uint32_t rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - uint32_t rxoflo; /* rx fifo overflow errors */ - uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32_t dmade; /* tx/rx dma descriptor errors */ - uint32_t dmada; /* tx/rx dma data errors */ - uint32_t dmape; /* tx/rx dma descriptor protocol errors */ - uint32_t reset; /* reset count */ - uint32_t tbtt; /* cnts the TBTT int's */ - uint32_t txdmawar; /* # occurrences of PR15420 workaround */ - uint32_t pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + uint16_t version; /* see definition of WL_CNT_T_VERSION */ + uint16_t length; /* length of entire structure */ + + /* transmit stat counters */ + uint32_t txframe; /* tx data frames */ + uint32_t txbyte; /* tx data bytes */ + uint32_t txretrans; /* tx mac retransmits */ + uint32_t txerror; /* tx data errors (derived: sum of others) */ + uint32_t txctl; /* tx management frames */ + uint32_t txprshort; /* tx short preamble frames */ + uint32_t txserr; /* tx status errors */ + uint32_t txnobuf; /* tx out of buffers errors */ + uint32_t txnoassoc; /* tx discard because we're not associated */ + uint32_t txrunt; /* tx runt frames */ + uint32_t txchit; /* tx header cache hit (fastpath) */ + uint32_t txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32_t txuflo; /* tx fifo underflows */ + uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ + uint32_t txphycrs; /* PR8861/8963 counter */ + + /* receive stat counters */ + uint32_t rxframe; /* rx data frames */ + uint32_t rxbyte; /* rx data bytes */ + uint32_t rxerror; /* rx data errors (derived: sum of others) */ + uint32_t rxctl; /* rx management frames */ + uint32_t rxnobuf; /* rx out of buffers errors */ + uint32_t rxnondata; /* rx non data frames in the data channel errors */ + uint32_t rxbadds; /* rx bad DS errors */ + uint32_t rxbadcm; /* rx bad control or management frames */ + uint32_t rxfragerr; /* rx fragmentation errors */ + uint32_t rxrunt; /* rx runt frames */ + uint32_t rxgiant; /* rx giant frames */ + uint32_t rxnoscb; /* rx no scb error */ + uint32_t rxbadproto; /* rx invalid frames */ + uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32_t rxbadda; /* rx frames tossed for invalid da */ + uint32_t rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32_t rxoflo; /* rx fifo overflow errors */ + uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32_t dmade; /* tx/rx dma descriptor errors */ + uint32_t dmada; /* tx/rx dma data errors */ + uint32_t dmape; /* tx/rx dma descriptor protocol errors */ + uint32_t reset; /* reset count */ + uint32_t tbtt; /* cnts the TBTT int's */ + uint32_t txdmawar; /* # occurrences of PR15420 workaround */ + uint32_t pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, * Control Management (includes retransmissions) */ - uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ - uint32_t txctsfrm; /* number of CTS sent out by the MAC */ - uint32_t txackfrm; /* number of ACK frames sent out */ - uint32_t txdnlfrm; /* Not used */ - uint32_t txbcnfrm; /* beacons transmitted */ - uint32_t txfunfl[8]; /* per-fifo tx underflows */ - uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ + uint32_t txctsfrm; /* number of CTS sent out by the MAC */ + uint32_t txackfrm; /* number of ACK frames sent out */ + uint32_t txdnlfrm; /* Not used */ + uint32_t txbcnfrm; /* beacons transmitted */ + uint32_t txfunfl[8]; /* per-fifo tx underflows */ + uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS * or BCN) */ - uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for + uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for * driver enqueued frames */ - uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not + uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not * data/control/management */ - uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - uint32_t rxbadplcp; /* parity check of the PLCP header failed */ - uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - uint32_t rxstrt; /* Number of received frames with a good PLCP + uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32_t rxbadplcp; /* parity check of the PLCP header failed */ + uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32_t rxstrt; /* Number of received frames with a good PLCP * (i.e. passing parity check) */ - uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ - uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ - uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ - uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC * (unlikely to see these) */ - uint32_t rxbeaconmbss; /* beacons received from member of BSS */ - uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + uint32_t rxbeaconmbss; /* beacons received from member of BSS */ + uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from * other BSS (WDS FRAME) */ - uint32_t rxbeaconobss; /* beacons received from other BSS */ - uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames + uint32_t rxbeaconobss; /* beacons received from other BSS */ + uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames * expecting a response */ - uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ - uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - uint32_t pmqovfl; /* Number of PMQ overflows */ - uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into + uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32_t pmqovfl; /* Number of PMQ overflows */ + uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into * the PRQ fifo */ - uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did * not get ACK */ - uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ + uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ * fifo because a probe response could not be sent out within * the time limit defined in M_PRS_MAXTIME */ - uint32_t rxnack; /* obsolete */ - uint32_t frmscons; /* obsolete */ - uint32_t txnack; /* obsolete */ - uint32_t txglitch_nack; /* obsolete */ - uint32_t txburst; /* obsolete */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32_t txfrag; /* dot11TransmittedFragmentCount */ - uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32_t txfail; /* dot11FailedCount */ - uint32_t txretry; /* dot11RetryCount */ - uint32_t txretrie; /* dot11MultipleRetryCount */ - uint32_t rxdup; /* dot11FrameduplicateCount */ - uint32_t txrts; /* dot11RTSSuccessCount */ - uint32_t txnocts; /* dot11RTSFailureCount */ - uint32_t txnoack; /* dot11ACKFailureCount */ - uint32_t rxfrag; /* dot11ReceivedFragmentCount */ - uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32_t rxcrc; /* dot11FCSErrorCount */ - uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - uint32_t rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay; /* TKIPReplays */ - uint32_t ccmpfmterr; /* CCMPFormatErrors */ - uint32_t ccmpreplay; /* CCMPReplays */ - uint32_t ccmpundec; /* CCMPDecryptErrors */ - uint32_t fourwayfail; /* FourWayHandshakeFailures */ - uint32_t wepundec; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr; /* dot11WEPICVErrorCount */ - uint32_t decsuccess; /* DecryptSuccessCount */ - uint32_t tkipicverr; /* TKIPICVErrorCount */ - uint32_t wepexcluded; /* dot11WEPExcludedCount */ - - uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ - uint32_t psmwds; /* Count PSM watchdogs */ - uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - uint32_t prq_entries_handled; /* PRQ entries read in */ - uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ - uint32_t prq_bad_entries; /* which could not be translated to info */ - uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ - uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ - uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ - uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - uint32_t rx1mbps; /* packets rx at 1Mbps */ - uint32_t rx2mbps; /* packets rx at 2Mbps */ - uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ - uint32_t rx6mbps; /* packets rx at 6Mbps */ - uint32_t rx9mbps; /* packets rx at 9Mbps */ - uint32_t rx11mbps; /* packets rx at 11Mbps */ - uint32_t rx12mbps; /* packets rx at 12Mbps */ - uint32_t rx18mbps; /* packets rx at 18Mbps */ - uint32_t rx24mbps; /* packets rx at 24Mbps */ - uint32_t rx36mbps; /* packets rx at 36Mbps */ - uint32_t rx48mbps; /* packets rx at 48Mbps */ - uint32_t rx54mbps; /* packets rx at 54Mbps */ - uint32_t rx108mbps; /* packets rx at 108mbps */ - uint32_t rx162mbps; /* packets rx at 162mbps */ - uint32_t rx216mbps; /* packets rx at 216 mbps */ - uint32_t rx270mbps; /* packets rx at 270 mbps */ - uint32_t rx324mbps; /* packets rx at 324 mbps */ - uint32_t rx378mbps; /* packets rx at 378 mbps */ - uint32_t rx432mbps; /* packets rx at 432 mbps */ - uint32_t rx486mbps; /* packets rx at 486 mbps */ - uint32_t rx540mbps; /* packets rx at 540 mbps */ - - /* pkteng rx frame stats */ - uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ - uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ - - uint32_t rfdisable; /* count of radio disables */ - uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ - - uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ - - uint32_t txmpdu_sgi; /* count for sgi transmit */ - uint32_t rxmpdu_sgi; /* count for sgi received */ - uint32_t txmpdu_stbc; /* count for stbc transmit */ - uint32_t rxmpdu_stbc; /* count for stbc received */ - - uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay_mcst; /* TKIPReplays */ - uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ - uint32_t ccmpreplay_mcst; /* CCMPReplays */ - uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ - uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ - uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ - uint32_t decsuccess_mcst; /* DecryptSuccessCount */ - uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ - uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ - - uint32_t dma_hang; /* count for stbc received */ + uint32_t rxnack; /* obsolete */ + uint32_t frmscons; /* obsolete */ + uint32_t txnack; /* obsolete */ + uint32_t txglitch_nack; /* obsolete */ + uint32_t txburst; /* obsolete */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32_t txfrag; /* dot11TransmittedFragmentCount */ + uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32_t txfail; /* dot11FailedCount */ + uint32_t txretry; /* dot11RetryCount */ + uint32_t txretrie; /* dot11MultipleRetryCount */ + uint32_t rxdup; /* dot11FrameduplicateCount */ + uint32_t txrts; /* dot11RTSSuccessCount */ + uint32_t txnocts; /* dot11RTSFailureCount */ + uint32_t txnoack; /* dot11ACKFailureCount */ + uint32_t rxfrag; /* dot11ReceivedFragmentCount */ + uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32_t rxcrc; /* dot11FCSErrorCount */ + uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32_t rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay; /* TKIPReplays */ + uint32_t ccmpfmterr; /* CCMPFormatErrors */ + uint32_t ccmpreplay; /* CCMPReplays */ + uint32_t ccmpundec; /* CCMPDecryptErrors */ + uint32_t fourwayfail; /* FourWayHandshakeFailures */ + uint32_t wepundec; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr; /* dot11WEPICVErrorCount */ + uint32_t decsuccess; /* DecryptSuccessCount */ + uint32_t tkipicverr; /* TKIPICVErrorCount */ + uint32_t wepexcluded; /* dot11WEPExcludedCount */ + + uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32_t psmwds; /* Count PSM watchdogs */ + uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32_t prq_entries_handled; /* PRQ entries read in */ + uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ + uint32_t prq_bad_entries; /* which could not be translated to info */ + uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32_t rx1mbps; /* packets rx at 1Mbps */ + uint32_t rx2mbps; /* packets rx at 2Mbps */ + uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ + uint32_t rx6mbps; /* packets rx at 6Mbps */ + uint32_t rx9mbps; /* packets rx at 9Mbps */ + uint32_t rx11mbps; /* packets rx at 11Mbps */ + uint32_t rx12mbps; /* packets rx at 12Mbps */ + uint32_t rx18mbps; /* packets rx at 18Mbps */ + uint32_t rx24mbps; /* packets rx at 24Mbps */ + uint32_t rx36mbps; /* packets rx at 36Mbps */ + uint32_t rx48mbps; /* packets rx at 48Mbps */ + uint32_t rx54mbps; /* packets rx at 54Mbps */ + uint32_t rx108mbps; /* packets rx at 108mbps */ + uint32_t rx162mbps; /* packets rx at 162mbps */ + uint32_t rx216mbps; /* packets rx at 216 mbps */ + uint32_t rx270mbps; /* packets rx at 270 mbps */ + uint32_t rx324mbps; /* packets rx at 324 mbps */ + uint32_t rx378mbps; /* packets rx at 378 mbps */ + uint32_t rx432mbps; /* packets rx at 432 mbps */ + uint32_t rx486mbps; /* packets rx at 486 mbps */ + uint32_t rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32_t rfdisable; /* count of radio disables */ + uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ + + uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ + + uint32_t txmpdu_sgi; /* count for sgi transmit */ + uint32_t rxmpdu_sgi; /* count for sgi received */ + uint32_t txmpdu_stbc; /* count for stbc transmit */ + uint32_t rxmpdu_stbc; /* count for stbc received */ + + uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay_mcst; /* TKIPReplays */ + uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32_t ccmpreplay_mcst; /* CCMPReplays */ + uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32_t decsuccess_mcst; /* DecryptSuccessCount */ + uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32_t dma_hang; /* count for stbc received */ } wl_cnt_ver_seven_t; typedef struct { - uint16_t version; /* see definition of WL_CNT_T_VERSION */ - uint16_t length; /* length of entire structure */ - - /* transmit stat counters */ - uint32_t txframe; /* tx data frames */ - uint32_t txbyte; /* tx data bytes */ - uint32_t txretrans; /* tx mac retransmits */ - uint32_t txerror; /* tx data errors (derived: sum of others) */ - uint32_t txctl; /* tx management frames */ - uint32_t txprshort; /* tx short preamble frames */ - uint32_t txserr; /* tx status errors */ - uint32_t txnobuf; /* tx out of buffers errors */ - uint32_t txnoassoc; /* tx discard because we're not associated */ - uint32_t txrunt; /* tx runt frames */ - uint32_t txchit; /* tx header cache hit (fastpath) */ - uint32_t txcmiss; /* tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32_t txuflo; /* tx fifo underflows */ - uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ - uint32_t txphycrs; /* PR8861/8963 counter */ - - /* receive stat counters */ - uint32_t rxframe; /* rx data frames */ - uint32_t rxbyte; /* rx data bytes */ - uint32_t rxerror; /* rx data errors (derived: sum of others) */ - uint32_t rxctl; /* rx management frames */ - uint32_t rxnobuf; /* rx out of buffers errors */ - uint32_t rxnondata; /* rx non data frames in the data channel errors */ - uint32_t rxbadds; /* rx bad DS errors */ - uint32_t rxbadcm; /* rx bad control or management frames */ - uint32_t rxfragerr; /* rx fragmentation errors */ - uint32_t rxrunt; /* rx runt frames */ - uint32_t rxgiant; /* rx giant frames */ - uint32_t rxnoscb; /* rx no scb error */ - uint32_t rxbadproto; /* rx invalid frames */ - uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ - uint32_t rxbadda; /* rx frames tossed for invalid da */ - uint32_t rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - uint32_t rxoflo; /* rx fifo overflow errors */ - uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32_t dmade; /* tx/rx dma descriptor errors */ - uint32_t dmada; /* tx/rx dma data errors */ - uint32_t dmape; /* tx/rx dma descriptor protocol errors */ - uint32_t reset; /* reset count */ - uint32_t tbtt; /* cnts the TBTT int's */ - uint32_t txdmawar; /* # occurrences of PR15420 workaround */ - uint32_t pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + uint16_t version; /* see definition of WL_CNT_T_VERSION */ + uint16_t length; /* length of entire structure */ + + /* transmit stat counters */ + uint32_t txframe; /* tx data frames */ + uint32_t txbyte; /* tx data bytes */ + uint32_t txretrans; /* tx mac retransmits */ + uint32_t txerror; /* tx data errors (derived: sum of others) */ + uint32_t txctl; /* tx management frames */ + uint32_t txprshort; /* tx short preamble frames */ + uint32_t txserr; /* tx status errors */ + uint32_t txnobuf; /* tx out of buffers errors */ + uint32_t txnoassoc; /* tx discard because we're not associated */ + uint32_t txrunt; /* tx runt frames */ + uint32_t txchit; /* tx header cache hit (fastpath) */ + uint32_t txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32_t txuflo; /* tx fifo underflows */ + uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ + uint32_t txphycrs; /* PR8861/8963 counter */ + + /* receive stat counters */ + uint32_t rxframe; /* rx data frames */ + uint32_t rxbyte; /* rx data bytes */ + uint32_t rxerror; /* rx data errors (derived: sum of others) */ + uint32_t rxctl; /* rx management frames */ + uint32_t rxnobuf; /* rx out of buffers errors */ + uint32_t rxnondata; /* rx non data frames in the data channel errors */ + uint32_t rxbadds; /* rx bad DS errors */ + uint32_t rxbadcm; /* rx bad control or management frames */ + uint32_t rxfragerr; /* rx fragmentation errors */ + uint32_t rxrunt; /* rx runt frames */ + uint32_t rxgiant; /* rx giant frames */ + uint32_t rxnoscb; /* rx no scb error */ + uint32_t rxbadproto; /* rx invalid frames */ + uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32_t rxbadda; /* rx frames tossed for invalid da */ + uint32_t rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32_t rxoflo; /* rx fifo overflow errors */ + uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32_t dmade; /* tx/rx dma descriptor errors */ + uint32_t dmada; /* tx/rx dma data errors */ + uint32_t dmape; /* tx/rx dma descriptor protocol errors */ + uint32_t reset; /* reset count */ + uint32_t tbtt; /* cnts the TBTT int's */ + uint32_t txdmawar; /* # occurrences of PR15420 workaround */ + uint32_t pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, * Control Management (includes retransmissions) */ - uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ - uint32_t txctsfrm; /* number of CTS sent out by the MAC */ - uint32_t txackfrm; /* number of ACK frames sent out */ - uint32_t txdnlfrm; /* Not used */ - uint32_t txbcnfrm; /* beacons transmitted */ - uint32_t txfunfl[6]; /* per-fifo tx underflows */ - uint32_t rxtoolate; /* receive too late */ - uint32_t txfbw; /* transmit at fallback bw (dynamic bw) */ - uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ + uint32_t txctsfrm; /* number of CTS sent out by the MAC */ + uint32_t txackfrm; /* number of ACK frames sent out */ + uint32_t txdnlfrm; /* Not used */ + uint32_t txbcnfrm; /* beacons transmitted */ + uint32_t txfunfl[6]; /* per-fifo tx underflows */ + uint32_t rxtoolate; /* receive too late */ + uint32_t txfbw; /* transmit at fallback bw (dynamic bw) */ + uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS * or BCN) */ - uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for + uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for * driver enqueued frames */ - uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not + uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not * data/control/management */ - uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - uint32_t rxbadplcp; /* parity check of the PLCP header failed */ - uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - uint32_t rxstrt; /* Number of received frames with a good PLCP + uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32_t rxbadplcp; /* parity check of the PLCP header failed */ + uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32_t rxstrt; /* Number of received frames with a good PLCP * (i.e. passing parity check) */ - uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ - uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ - uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ - uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC * (unlikely to see these) */ - uint32_t rxbeaconmbss; /* beacons received from member of BSS */ - uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + uint32_t rxbeaconmbss; /* beacons received from member of BSS */ + uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from * other BSS (WDS FRAME) */ - uint32_t rxbeaconobss; /* beacons received from other BSS */ - uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames + uint32_t rxbeaconobss; /* beacons received from other BSS */ + uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames * expecting a response */ - uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ - uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - uint32_t pmqovfl; /* Number of PMQ overflows */ - uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into + uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32_t pmqovfl; /* Number of PMQ overflows */ + uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into * the PRQ fifo */ - uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did * not get ACK */ - uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ + uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ * fifo because a probe response could not be sent out within * the time limit defined in M_PRS_MAXTIME */ - uint32_t rxnack; /* obsolete */ - uint32_t frmscons; /* obsolete */ - uint32_t txnack; /* obsolete */ - uint32_t rxback; /* blockack rxcnt */ - uint32_t txback; /* blockack txcnt */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32_t txfrag; /* dot11TransmittedFragmentCount */ - uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32_t txfail; /* dot11FailedCount */ - uint32_t txretry; /* dot11RetryCount */ - uint32_t txretrie; /* dot11MultipleRetryCount */ - uint32_t rxdup; /* dot11FrameduplicateCount */ - uint32_t txrts; /* dot11RTSSuccessCount */ - uint32_t txnocts; /* dot11RTSFailureCount */ - uint32_t txnoack; /* dot11ACKFailureCount */ - uint32_t rxfrag; /* dot11ReceivedFragmentCount */ - uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32_t rxcrc; /* dot11FCSErrorCount */ - uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - uint32_t rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay; /* TKIPReplays */ - uint32_t ccmpfmterr; /* CCMPFormatErrors */ - uint32_t ccmpreplay; /* CCMPReplays */ - uint32_t ccmpundec; /* CCMPDecryptErrors */ - uint32_t fourwayfail; /* FourWayHandshakeFailures */ - uint32_t wepundec; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr; /* dot11WEPICVErrorCount */ - uint32_t decsuccess; /* DecryptSuccessCount */ - uint32_t tkipicverr; /* TKIPICVErrorCount */ - uint32_t wepexcluded; /* dot11WEPExcludedCount */ - - uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ - uint32_t psmwds; /* Count PSM watchdogs */ - uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - uint32_t prq_entries_handled; /* PRQ entries read in */ - uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ - uint32_t prq_bad_entries; /* which could not be translated to info */ - uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ - uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ - uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ - uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - uint32_t rx1mbps; /* packets rx at 1Mbps */ - uint32_t rx2mbps; /* packets rx at 2Mbps */ - uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ - uint32_t rx6mbps; /* packets rx at 6Mbps */ - uint32_t rx9mbps; /* packets rx at 9Mbps */ - uint32_t rx11mbps; /* packets rx at 11Mbps */ - uint32_t rx12mbps; /* packets rx at 12Mbps */ - uint32_t rx18mbps; /* packets rx at 18Mbps */ - uint32_t rx24mbps; /* packets rx at 24Mbps */ - uint32_t rx36mbps; /* packets rx at 36Mbps */ - uint32_t rx48mbps; /* packets rx at 48Mbps */ - uint32_t rx54mbps; /* packets rx at 54Mbps */ - uint32_t rx108mbps; /* packets rx at 108mbps */ - uint32_t rx162mbps; /* packets rx at 162mbps */ - uint32_t rx216mbps; /* packets rx at 216 mbps */ - uint32_t rx270mbps; /* packets rx at 270 mbps */ - uint32_t rx324mbps; /* packets rx at 324 mbps */ - uint32_t rx378mbps; /* packets rx at 378 mbps */ - uint32_t rx432mbps; /* packets rx at 432 mbps */ - uint32_t rx486mbps; /* packets rx at 486 mbps */ - uint32_t rx540mbps; /* packets rx at 540 mbps */ - - /* pkteng rx frame stats */ - uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ - uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ - - uint32_t rfdisable; /* count of radio disables */ - uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ - uint32_t bphy_badplcp; - - uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ - - uint32_t txmpdu_sgi; /* count for sgi transmit */ - uint32_t rxmpdu_sgi; /* count for sgi received */ - uint32_t txmpdu_stbc; /* count for stbc transmit */ - uint32_t rxmpdu_stbc; /* count for stbc received */ - - uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay_mcst; /* TKIPReplays */ - uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ - uint32_t ccmpreplay_mcst; /* CCMPReplays */ - uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ - uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ - uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ - uint32_t decsuccess_mcst; /* DecryptSuccessCount */ - uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ - uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ - - uint32_t dma_hang; /* count for dma hang */ - uint32_t reinit; /* count for reinit */ - - uint32_t pstatxucast; /* count of ucast frames xmitted on all psta assoc */ - uint32_t pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ - uint32_t pstarxucast; /* count of ucast frames received on all psta assoc */ - uint32_t pstarxbcmc; /* count of bcmc frames received on all psta */ - uint32_t pstatxbcmc; /* count of bcmc frames transmitted on all psta */ - - uint32_t cso_passthrough; /* hw cso required but passthrough */ - uint32_t cso_normal; /* hw cso hdr for normal process */ - uint32_t chained; /* number of frames chained */ - uint32_t chainedsz1; /* number of chain size 1 frames */ - uint32_t unchained; /* number of frames not chained */ - uint32_t maxchainsz; /* max chain size so far */ - uint32_t currchainsz; /* current chain size */ - - uint32_t rxdrop20s; /* drop secondary cnt */ + uint32_t rxnack; /* obsolete */ + uint32_t frmscons; /* obsolete */ + uint32_t txnack; /* obsolete */ + uint32_t rxback; /* blockack rxcnt */ + uint32_t txback; /* blockack txcnt */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32_t txfrag; /* dot11TransmittedFragmentCount */ + uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32_t txfail; /* dot11FailedCount */ + uint32_t txretry; /* dot11RetryCount */ + uint32_t txretrie; /* dot11MultipleRetryCount */ + uint32_t rxdup; /* dot11FrameduplicateCount */ + uint32_t txrts; /* dot11RTSSuccessCount */ + uint32_t txnocts; /* dot11RTSFailureCount */ + uint32_t txnoack; /* dot11ACKFailureCount */ + uint32_t rxfrag; /* dot11ReceivedFragmentCount */ + uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32_t rxcrc; /* dot11FCSErrorCount */ + uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32_t rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay; /* TKIPReplays */ + uint32_t ccmpfmterr; /* CCMPFormatErrors */ + uint32_t ccmpreplay; /* CCMPReplays */ + uint32_t ccmpundec; /* CCMPDecryptErrors */ + uint32_t fourwayfail; /* FourWayHandshakeFailures */ + uint32_t wepundec; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr; /* dot11WEPICVErrorCount */ + uint32_t decsuccess; /* DecryptSuccessCount */ + uint32_t tkipicverr; /* TKIPICVErrorCount */ + uint32_t wepexcluded; /* dot11WEPExcludedCount */ + + uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32_t psmwds; /* Count PSM watchdogs */ + uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32_t prq_entries_handled; /* PRQ entries read in */ + uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ + uint32_t prq_bad_entries; /* which could not be translated to info */ + uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32_t rx1mbps; /* packets rx at 1Mbps */ + uint32_t rx2mbps; /* packets rx at 2Mbps */ + uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ + uint32_t rx6mbps; /* packets rx at 6Mbps */ + uint32_t rx9mbps; /* packets rx at 9Mbps */ + uint32_t rx11mbps; /* packets rx at 11Mbps */ + uint32_t rx12mbps; /* packets rx at 12Mbps */ + uint32_t rx18mbps; /* packets rx at 18Mbps */ + uint32_t rx24mbps; /* packets rx at 24Mbps */ + uint32_t rx36mbps; /* packets rx at 36Mbps */ + uint32_t rx48mbps; /* packets rx at 48Mbps */ + uint32_t rx54mbps; /* packets rx at 54Mbps */ + uint32_t rx108mbps; /* packets rx at 108mbps */ + uint32_t rx162mbps; /* packets rx at 162mbps */ + uint32_t rx216mbps; /* packets rx at 216 mbps */ + uint32_t rx270mbps; /* packets rx at 270 mbps */ + uint32_t rx324mbps; /* packets rx at 324 mbps */ + uint32_t rx378mbps; /* packets rx at 378 mbps */ + uint32_t rx432mbps; /* packets rx at 432 mbps */ + uint32_t rx486mbps; /* packets rx at 486 mbps */ + uint32_t rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32_t rfdisable; /* count of radio disables */ + uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ + uint32_t bphy_badplcp; + + uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ + + uint32_t txmpdu_sgi; /* count for sgi transmit */ + uint32_t rxmpdu_sgi; /* count for sgi received */ + uint32_t txmpdu_stbc; /* count for stbc transmit */ + uint32_t rxmpdu_stbc; /* count for stbc received */ + + uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay_mcst; /* TKIPReplays */ + uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32_t ccmpreplay_mcst; /* CCMPReplays */ + uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32_t decsuccess_mcst; /* DecryptSuccessCount */ + uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32_t dma_hang; /* count for dma hang */ + uint32_t reinit; /* count for reinit */ + + uint32_t pstatxucast; /* count of ucast frames xmitted on all psta assoc */ + uint32_t pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ + uint32_t pstarxucast; /* count of ucast frames received on all psta assoc */ + uint32_t pstarxbcmc; /* count of bcmc frames received on all psta */ + uint32_t pstatxbcmc; /* count of bcmc frames transmitted on all psta */ + + uint32_t cso_passthrough; /* hw cso required but passthrough */ + uint32_t cso_normal; /* hw cso hdr for normal process */ + uint32_t chained; /* number of frames chained */ + uint32_t chainedsz1; /* number of chain size 1 frames */ + uint32_t unchained; /* number of frames not chained */ + uint32_t maxchainsz; /* max chain size so far */ + uint32_t currchainsz; /* current chain size */ + + uint32_t rxdrop20s; /* drop secondary cnt */ } wl_cnt_ver_eight_t; /* per-rate receive stat counters subset of full counters */ typedef struct { - uint32_t rx1mbps; /* packets rx at 1Mbps */ - uint32_t rx2mbps; /* packets rx at 2Mbps */ - uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ - uint32_t rx6mbps; /* packets rx at 6Mbps */ - uint32_t rx9mbps; /* packets rx at 9Mbps */ - uint32_t rx11mbps; /* packets rx at 11Mbps */ - uint32_t rx12mbps; /* packets rx at 12Mbps */ - uint32_t rx18mbps; /* packets rx at 18Mbps */ - uint32_t rx24mbps; /* packets rx at 24Mbps */ - uint32_t rx36mbps; /* packets rx at 36Mbps */ - uint32_t rx48mbps; /* packets rx at 48Mbps */ - uint32_t rx54mbps; /* packets rx at 54Mbps */ - uint32_t rx108mbps; /* packets rx at 108mbps */ - uint32_t rx162mbps; /* packets rx at 162mbps */ - uint32_t rx216mbps; /* packets rx at 216 mbps */ - uint32_t rx270mbps; /* packets rx at 270 mbps */ + uint32_t rx1mbps; /* packets rx at 1Mbps */ + uint32_t rx2mbps; /* packets rx at 2Mbps */ + uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ + uint32_t rx6mbps; /* packets rx at 6Mbps */ + uint32_t rx9mbps; /* packets rx at 9Mbps */ + uint32_t rx11mbps; /* packets rx at 11Mbps */ + uint32_t rx12mbps; /* packets rx at 12Mbps */ + uint32_t rx18mbps; /* packets rx at 18Mbps */ + uint32_t rx24mbps; /* packets rx at 24Mbps */ + uint32_t rx36mbps; /* packets rx at 36Mbps */ + uint32_t rx48mbps; /* packets rx at 48Mbps */ + uint32_t rx54mbps; /* packets rx at 54Mbps */ + uint32_t rx108mbps; /* packets rx at 108mbps */ + uint32_t rx162mbps; /* packets rx at 162mbps */ + uint32_t rx216mbps; /* packets rx at 216 mbps */ + uint32_t rx270mbps; /* packets rx at 270 mbps */ } whd_phyrate_counters_t; typedef struct { - uint32_t count; - uint8_t log[WL_PHYRATE_LOG_SIZE]; + uint32_t count; + uint8_t log[WL_PHYRATE_LOG_SIZE]; } whd_phyrate_log_t; typedef struct { - uint16_t version; /* see definition of WL_CNT_T_VERSION */ - uint16_t length; /* length of entire structure */ - - /* transmit stat counters */ - uint32_t txframe; /* tx data frames */ - uint32_t txbyte; /* tx data bytes */ - uint32_t txretrans; /* tx mac retransmits */ - uint32_t txerror; /* tx data errors (derived: sum of others) */ - uint32_t txctl; /* tx management frames */ - uint32_t txprshort; /* tx short preamble frames */ - uint32_t txserr; /* tx status errors */ - uint32_t txnobuf; /* tx out of buffers errors */ - uint32_t txnoassoc; /* tx discard because we're not associated */ - uint32_t txrunt; /* tx runt frames */ - uint32_t txchit; /* tx header cache hit (fastpath) */ - uint32_t txcmiss; /* tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32_t txuflo; /* tx fifo underflows */ - uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ - uint32_t txphycrs; /* PR8861/8963 counter */ - - /* receive stat counters */ - uint32_t rxframe; /* rx data frames */ - uint32_t rxbyte; /* rx data bytes */ - uint32_t rxerror; /* rx data errors (derived: sum of others) */ - uint32_t rxctl; /* rx management frames */ - uint32_t rxnobuf; /* rx out of buffers errors */ - uint32_t rxnondata; /* rx non data frames in the data channel errors */ - uint32_t rxbadds; /* rx bad DS errors */ - uint32_t rxbadcm; /* rx bad control or management frames */ - uint32_t rxfragerr; /* rx fragmentation errors */ - uint32_t rxrunt; /* rx runt frames */ - uint32_t rxgiant; /* rx giant frames */ - uint32_t rxnoscb; /* rx no scb error */ - uint32_t rxbadproto; /* rx invalid frames */ - uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ - uint32_t rxbadda; /* rx frames tossed for invalid da */ - uint32_t rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - uint32_t rxoflo; /* rx fifo overflow errors */ - uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32_t dmade; /* tx/rx dma descriptor errors */ - uint32_t dmada; /* tx/rx dma data errors */ - uint32_t dmape; /* tx/rx dma descriptor protocol errors */ - uint32_t reset; /* reset count */ - uint32_t tbtt; /* cnts the TBTT int's */ - uint32_t txdmawar; /* # occurrences of PR15420 workaround */ - uint32_t pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + uint16_t version; /* see definition of WL_CNT_T_VERSION */ + uint16_t length; /* length of entire structure */ + + /* transmit stat counters */ + uint32_t txframe; /* tx data frames */ + uint32_t txbyte; /* tx data bytes */ + uint32_t txretrans; /* tx mac retransmits */ + uint32_t txerror; /* tx data errors (derived: sum of others) */ + uint32_t txctl; /* tx management frames */ + uint32_t txprshort; /* tx short preamble frames */ + uint32_t txserr; /* tx status errors */ + uint32_t txnobuf; /* tx out of buffers errors */ + uint32_t txnoassoc; /* tx discard because we're not associated */ + uint32_t txrunt; /* tx runt frames */ + uint32_t txchit; /* tx header cache hit (fastpath) */ + uint32_t txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32_t txuflo; /* tx fifo underflows */ + uint32_t txphyerr; /* tx phy errors (indicated in tx status) */ + uint32_t txphycrs; /* PR8861/8963 counter */ + + /* receive stat counters */ + uint32_t rxframe; /* rx data frames */ + uint32_t rxbyte; /* rx data bytes */ + uint32_t rxerror; /* rx data errors (derived: sum of others) */ + uint32_t rxctl; /* rx management frames */ + uint32_t rxnobuf; /* rx out of buffers errors */ + uint32_t rxnondata; /* rx non data frames in the data channel errors */ + uint32_t rxbadds; /* rx bad DS errors */ + uint32_t rxbadcm; /* rx bad control or management frames */ + uint32_t rxfragerr; /* rx fragmentation errors */ + uint32_t rxrunt; /* rx runt frames */ + uint32_t rxgiant; /* rx giant frames */ + uint32_t rxnoscb; /* rx no scb error */ + uint32_t rxbadproto; /* rx invalid frames */ + uint32_t rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32_t rxbadda; /* rx frames tossed for invalid da */ + uint32_t rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32_t rxoflo; /* rx fifo overflow errors */ + uint32_t rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32_t d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32_t d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32_t d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32_t dmade; /* tx/rx dma descriptor errors */ + uint32_t dmada; /* tx/rx dma data errors */ + uint32_t dmape; /* tx/rx dma descriptor protocol errors */ + uint32_t reset; /* reset count */ + uint32_t tbtt; /* cnts the TBTT int's */ + uint32_t txdmawar; /* # occurrences of PR15420 workaround */ + uint32_t pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32_t txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, * Control Management (includes retransmissions) */ - uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ - uint32_t txctsfrm; /* number of CTS sent out by the MAC */ - uint32_t txackfrm; /* number of ACK frames sent out */ - uint32_t txdnlfrm; /* Not used */ - uint32_t txbcnfrm; /* beacons transmitted */ - uint32_t txfunfl[6]; /* per-fifo tx underflows */ - uint32_t rxtoolate; /* receive too late */ - uint32_t txfbw; /* transmit at fallback bw (dynamic bw) */ - uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + uint32_t txrtsfrm; /* number of RTS sent out by the MAC */ + uint32_t txctsfrm; /* number of CTS sent out by the MAC */ + uint32_t txackfrm; /* number of ACK frames sent out */ + uint32_t txdnlfrm; /* Not used */ + uint32_t txbcnfrm; /* beacons transmitted */ + uint32_t txfunfl[6]; /* per-fifo tx underflows */ + uint32_t rxtoolate; /* receive too late */ + uint32_t txfbw; /* transmit at fallback bw (dynamic bw) */ + uint32_t txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS * or BCN) */ - uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for + uint32_t txphyerror; /* Transmit phy error, type of error is reported in tx-status for * driver enqueued frames */ - uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not + uint32_t rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32_t rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32_t rxinvmachdr; /* Either the protocol version != 0 or frame type not * data/control/management */ - uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - uint32_t rxbadplcp; /* parity check of the PLCP header failed */ - uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - uint32_t rxstrt; /* Number of received frames with a good PLCP + uint32_t rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32_t rxbadplcp; /* parity check of the PLCP header failed */ + uint32_t rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32_t rxstrt; /* Number of received frames with a good PLCP * (i.e. passing parity check) */ - uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ - uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ - uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ - uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + uint32_t rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32_t rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32_t rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32_t rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32_t rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32_t rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32_t rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32_t rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32_t rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32_t rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32_t rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32_t rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32_t rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32_t rxcfrmmcast; /* number of RX Control multicast frames received by the MAC * (unlikely to see these) */ - uint32_t rxbeaconmbss; /* beacons received from member of BSS */ - uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + uint32_t rxbeaconmbss; /* beacons received from member of BSS */ + uint32_t rxdfrmucastobss; /* number of unicast frames addressed to the MAC from * other BSS (WDS FRAME) */ - uint32_t rxbeaconobss; /* beacons received from other BSS */ - uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames + uint32_t rxbeaconobss; /* beacons received from other BSS */ + uint32_t rxrsptmout; /* Number of response timeouts for transmitted frames * expecting a response */ - uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ - uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - uint32_t pmqovfl; /* Number of PMQ overflows */ - uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into + uint32_t bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32_t rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32_t rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32_t rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32_t txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32_t pmqovfl; /* Number of PMQ overflows */ + uint32_t rxcgprqfrm; /* Number of received Probe requests that made it into * the PRQ fifo */ - uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + uint32_t rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32_t txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did * not get ACK */ - uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ + uint32_t txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32_t prs_timeout; /* Number of probe requests that were dropped from the PRQ * fifo because a probe response could not be sent out within * the time limit defined in M_PRS_MAXTIME */ - uint32_t rxnack; /* obsolete */ - uint32_t frmscons; /* obsolete */ - uint32_t txnack; /* obsolete */ - uint32_t rxback; /* blockack rxcnt */ - uint32_t txback; /* blockack txcnt */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32_t txfrag; /* dot11TransmittedFragmentCount */ - uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32_t txfail; /* dot11FailedCount */ - uint32_t txretry; /* dot11RetryCount */ - uint32_t txretrie; /* dot11MultipleRetryCount */ - uint32_t rxdup; /* dot11FrameduplicateCount */ - uint32_t txrts; /* dot11RTSSuccessCount */ - uint32_t txnocts; /* dot11RTSFailureCount */ - uint32_t txnoack; /* dot11ACKFailureCount */ - uint32_t rxfrag; /* dot11ReceivedFragmentCount */ - uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32_t rxcrc; /* dot11FCSErrorCount */ - uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - uint32_t rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay; /* TKIPReplays */ - uint32_t ccmpfmterr; /* CCMPFormatErrors */ - uint32_t ccmpreplay; /* CCMPReplays */ - uint32_t ccmpundec; /* CCMPDecryptErrors */ - uint32_t fourwayfail; /* FourWayHandshakeFailures */ - uint32_t wepundec; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr; /* dot11WEPICVErrorCount */ - uint32_t decsuccess; /* DecryptSuccessCount */ - uint32_t tkipicverr; /* TKIPICVErrorCount */ - uint32_t wepexcluded; /* dot11WEPExcludedCount */ - - uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ - uint32_t psmwds; /* Count PSM watchdogs */ - uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ - - /* MBSS counters, AP only */ - uint32_t prq_entries_handled; /* PRQ entries read in */ - uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ - uint32_t prq_bad_entries; /* which could not be translated to info */ - uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ - uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ - uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ - uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ - - /* per-rate receive stat counters */ - uint32_t rx1mbps; /* packets rx at 1Mbps */ - uint32_t rx2mbps; /* packets rx at 2Mbps */ - uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ - uint32_t rx6mbps; /* packets rx at 6Mbps */ - uint32_t rx9mbps; /* packets rx at 9Mbps */ - uint32_t rx11mbps; /* packets rx at 11Mbps */ - uint32_t rx12mbps; /* packets rx at 12Mbps */ - uint32_t rx18mbps; /* packets rx at 18Mbps */ - uint32_t rx24mbps; /* packets rx at 24Mbps */ - uint32_t rx36mbps; /* packets rx at 36Mbps */ - uint32_t rx48mbps; /* packets rx at 48Mbps */ - uint32_t rx54mbps; /* packets rx at 54Mbps */ - uint32_t rx108mbps; /* packets rx at 108mbps */ - uint32_t rx162mbps; /* packets rx at 162mbps */ - uint32_t rx216mbps; /* packets rx at 216 mbps */ - uint32_t rx270mbps; /* packets rx at 270 mbps */ - uint32_t rx324mbps; /* packets rx at 324 mbps */ - uint32_t rx378mbps; /* packets rx at 378 mbps */ - uint32_t rx432mbps; /* packets rx at 432 mbps */ - uint32_t rx486mbps; /* packets rx at 486 mbps */ - uint32_t rx540mbps; /* packets rx at 540 mbps */ - - /* pkteng rx frame stats */ - uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ - uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ - - uint32_t rfdisable; /* count of radio disables */ - uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ - uint32_t bphy_badplcp; - - uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ - - uint32_t txmpdu_sgi; /* count for sgi transmit */ - uint32_t rxmpdu_sgi; /* count for sgi received */ - uint32_t txmpdu_stbc; /* count for stbc transmit */ - uint32_t rxmpdu_stbc; /* count for stbc received */ - - uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ - uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ - uint32_t tkipreplay_mcst; /* TKIPReplays */ - uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ - uint32_t ccmpreplay_mcst; /* CCMPReplays */ - uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ - uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ - uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ - uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ - uint32_t decsuccess_mcst; /* DecryptSuccessCount */ - uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ - uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ - - uint32_t dma_hang; /* count for dma hang */ - uint32_t reinit; /* count for reinit */ - - uint32_t pstatxucast; /* count of ucast frames xmitted on all psta assoc */ - uint32_t pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ - uint32_t pstarxucast; /* count of ucast frames received on all psta assoc */ - uint32_t pstarxbcmc; /* count of bcmc frames received on all psta */ - uint32_t pstatxbcmc; /* count of bcmc frames transmitted on all psta */ - - uint32_t cso_passthrough; /* hw cso required but passthrough */ - uint32_t cso_normal; /* hw cso hdr for normal process */ - uint32_t chained; /* number of frames chained */ - uint32_t chainedsz1; /* number of chain size 1 frames */ - uint32_t unchained; /* number of frames not chained */ - uint32_t maxchainsz; /* max chain size so far */ - uint32_t currchainsz; /* current chain size */ - uint32_t rxdrop20s; /* drop secondary cnt */ - uint32_t pciereset; /* Secondary Bus Reset issued by driver */ - uint32_t cfgrestore; /* configspace restore by driver */ - uint32_t reinitreason[8]; /* reinitreason counters; 0: Unknown reason */ - uint32_t rxrtry; /* num of received packets with retry bit on */ + uint32_t rxnack; /* obsolete */ + uint32_t frmscons; /* obsolete */ + uint32_t txnack; /* obsolete */ + uint32_t rxback; /* blockack rxcnt */ + uint32_t txback; /* blockack txcnt */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32_t txfrag; /* dot11TransmittedFragmentCount */ + uint32_t txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32_t txfail; /* dot11FailedCount */ + uint32_t txretry; /* dot11RetryCount */ + uint32_t txretrie; /* dot11MultipleRetryCount */ + uint32_t rxdup; /* dot11FrameduplicateCount */ + uint32_t txrts; /* dot11RTSSuccessCount */ + uint32_t txnocts; /* dot11RTSFailureCount */ + uint32_t txnoack; /* dot11ACKFailureCount */ + uint32_t rxfrag; /* dot11ReceivedFragmentCount */ + uint32_t rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32_t rxcrc; /* dot11FCSErrorCount */ + uint32_t txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32_t rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay; /* TKIPReplays */ + uint32_t ccmpfmterr; /* CCMPFormatErrors */ + uint32_t ccmpreplay; /* CCMPReplays */ + uint32_t ccmpundec; /* CCMPDecryptErrors */ + uint32_t fourwayfail; /* FourWayHandshakeFailures */ + uint32_t wepundec; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr; /* dot11WEPICVErrorCount */ + uint32_t decsuccess; /* DecryptSuccessCount */ + uint32_t tkipicverr; /* TKIPICVErrorCount */ + uint32_t wepexcluded; /* dot11WEPExcludedCount */ + + uint32_t txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32_t psmwds; /* Count PSM watchdogs */ + uint32_t phywatchdog; /* Count Phy watchdogs (triggered by ucode) */ + + /* MBSS counters, AP only */ + uint32_t prq_entries_handled; /* PRQ entries read in */ + uint32_t prq_undirected_entries; /* which were bcast bss & ssid */ + uint32_t prq_bad_entries; /* which could not be translated to info */ + uint32_t atim_suppress_count; /* TX suppressions on ATIM fifo */ + uint32_t bcn_template_not_ready; /* Template marked in use on send bcn ... */ + uint32_t bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */ + uint32_t late_tbtt_dpc; /* TBTT DPC did not happen in time */ + + /* per-rate receive stat counters */ + uint32_t rx1mbps; /* packets rx at 1Mbps */ + uint32_t rx2mbps; /* packets rx at 2Mbps */ + uint32_t rx5mbps5; /* packets rx at 5.5Mbps */ + uint32_t rx6mbps; /* packets rx at 6Mbps */ + uint32_t rx9mbps; /* packets rx at 9Mbps */ + uint32_t rx11mbps; /* packets rx at 11Mbps */ + uint32_t rx12mbps; /* packets rx at 12Mbps */ + uint32_t rx18mbps; /* packets rx at 18Mbps */ + uint32_t rx24mbps; /* packets rx at 24Mbps */ + uint32_t rx36mbps; /* packets rx at 36Mbps */ + uint32_t rx48mbps; /* packets rx at 48Mbps */ + uint32_t rx54mbps; /* packets rx at 54Mbps */ + uint32_t rx108mbps; /* packets rx at 108mbps */ + uint32_t rx162mbps; /* packets rx at 162mbps */ + uint32_t rx216mbps; /* packets rx at 216 mbps */ + uint32_t rx270mbps; /* packets rx at 270 mbps */ + uint32_t rx324mbps; /* packets rx at 324 mbps */ + uint32_t rx378mbps; /* packets rx at 378 mbps */ + uint32_t rx432mbps; /* packets rx at 432 mbps */ + uint32_t rx486mbps; /* packets rx at 486 mbps */ + uint32_t rx540mbps; /* packets rx at 540 mbps */ + + /* pkteng rx frame stats */ + uint32_t pktengrxducast; /* unicast frames rxed by the pkteng code */ + uint32_t pktengrxdmcast; /* multicast frames rxed by the pkteng code */ + + uint32_t rfdisable; /* count of radio disables */ + uint32_t bphy_rxcrsglitch; /* PHY count of bphy glitches */ + uint32_t bphy_badplcp; + + uint32_t txexptime; /* Tx frames suppressed due to timer expiration */ + + uint32_t txmpdu_sgi; /* count for sgi transmit */ + uint32_t rxmpdu_sgi; /* count for sgi received */ + uint32_t txmpdu_stbc; /* count for stbc transmit */ + uint32_t rxmpdu_stbc; /* count for stbc received */ + + uint32_t rxundec_mcst; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32_t tkipmicfaill_mcst; /* TKIPLocalMICFailures */ + uint32_t tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */ + uint32_t tkipreplay_mcst; /* TKIPReplays */ + uint32_t ccmpfmterr_mcst; /* CCMPFormatErrors */ + uint32_t ccmpreplay_mcst; /* CCMPReplays */ + uint32_t ccmpundec_mcst; /* CCMPDecryptErrors */ + uint32_t fourwayfail_mcst; /* FourWayHandshakeFailures */ + uint32_t wepundec_mcst; /* dot11WEPUndecryptableCount */ + uint32_t wepicverr_mcst; /* dot11WEPICVErrorCount */ + uint32_t decsuccess_mcst; /* DecryptSuccessCount */ + uint32_t tkipicverr_mcst; /* TKIPICVErrorCount */ + uint32_t wepexcluded_mcst; /* dot11WEPExcludedCount */ + + uint32_t dma_hang; /* count for dma hang */ + uint32_t reinit; /* count for reinit */ + + uint32_t pstatxucast; /* count of ucast frames xmitted on all psta assoc */ + uint32_t pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */ + uint32_t pstarxucast; /* count of ucast frames received on all psta assoc */ + uint32_t pstarxbcmc; /* count of bcmc frames received on all psta */ + uint32_t pstatxbcmc; /* count of bcmc frames transmitted on all psta */ + + uint32_t cso_passthrough; /* hw cso required but passthrough */ + uint32_t cso_normal; /* hw cso hdr for normal process */ + uint32_t chained; /* number of frames chained */ + uint32_t chainedsz1; /* number of chain size 1 frames */ + uint32_t unchained; /* number of frames not chained */ + uint32_t maxchainsz; /* max chain size so far */ + uint32_t currchainsz; /* current chain size */ + uint32_t rxdrop20s; /* drop secondary cnt */ + uint32_t pciereset; /* Secondary Bus Reset issued by driver */ + uint32_t cfgrestore; /* configspace restore by driver */ + uint32_t reinitreason[8]; /* reinitreason counters; 0: Unknown reason */ + uint32_t rxrtry; /* num of received packets with retry bit on */ } wl_cnt_ver_ten_t; typedef struct { - uint16_t version; - uint16_t length; - uint32_t rxampdu_sgi; - uint32_t rxampdu_stbc; - uint32_t rxmpdu_sgi; - uint32_t rxmpdu_stbc; - uint32_t rxmcs0_40M; - uint32_t rxmcs1_40M; - uint32_t rxmcs2_40M; - uint32_t rxmcs3_40M; - uint32_t rxmcs4_40M; - uint32_t rxmcs5_40M; - uint32_t rxmcs6_40M; - uint32_t rxmcs7_40M; - uint32_t rxmcs32_40M; - uint32_t txfrmsnt_20Mlo; - uint32_t txfrmsnt_20Mup; - uint32_t txfrmsnt_40M; - uint32_t rx_20ul; + uint16_t version; + uint16_t length; + uint32_t rxampdu_sgi; + uint32_t rxampdu_stbc; + uint32_t rxmpdu_sgi; + uint32_t rxmpdu_stbc; + uint32_t rxmcs0_40M; + uint32_t rxmcs1_40M; + uint32_t rxmcs2_40M; + uint32_t rxmcs3_40M; + uint32_t rxmcs4_40M; + uint32_t rxmcs5_40M; + uint32_t rxmcs6_40M; + uint32_t rxmcs7_40M; + uint32_t rxmcs32_40M; + uint32_t txfrmsnt_20Mlo; + uint32_t txfrmsnt_20Mup; + uint32_t txfrmsnt_40M; + uint32_t rx_20ul; } wl_cnt_ext_t; -#define WL_RXDIV_STATS_T_VERSION 1 +#define WL_RXDIV_STATS_T_VERSION 1 typedef struct { - uint16_t version; - uint16_t length; - uint32_t rxant[4]; + uint16_t version; + uint16_t length; + uint32_t rxant[4]; } wl_rxdiv_stats_t; -#define WL_DELTA_STATS_T_VERSION 1 +#define WL_DELTA_STATS_T_VERSION 1 typedef struct { - uint16_t version; - uint16_t length; - uint32_t txframe; - uint32_t txbyte; - uint32_t txretrans; - uint32_t txfail; - uint32_t rxframe; - uint32_t rxbyte; - uint32_t rx1mbps; - uint32_t rx2mbps; - uint32_t rx5mbps5; - uint32_t rx6mbps; - uint32_t rx9mbps; - uint32_t rx11mbps; - uint32_t rx12mbps; - uint32_t rx18mbps; - uint32_t rx24mbps; - uint32_t rx36mbps; - uint32_t rx48mbps; - uint32_t rx54mbps; - uint32_t rx108mbps; - uint32_t rx162mbps; - uint32_t rx216mbps; - uint32_t rx270mbps; - uint32_t rx324mbps; - uint32_t rx378mbps; - uint32_t rx432mbps; - uint32_t rx486mbps; - uint32_t rx540mbps; + uint16_t version; + uint16_t length; + uint32_t txframe; + uint32_t txbyte; + uint32_t txretrans; + uint32_t txfail; + uint32_t rxframe; + uint32_t rxbyte; + uint32_t rx1mbps; + uint32_t rx2mbps; + uint32_t rx5mbps5; + uint32_t rx6mbps; + uint32_t rx9mbps; + uint32_t rx11mbps; + uint32_t rx12mbps; + uint32_t rx18mbps; + uint32_t rx24mbps; + uint32_t rx36mbps; + uint32_t rx48mbps; + uint32_t rx54mbps; + uint32_t rx108mbps; + uint32_t rx162mbps; + uint32_t rx216mbps; + uint32_t rx270mbps; + uint32_t rx324mbps; + uint32_t rx378mbps; + uint32_t rx432mbps; + uint32_t rx486mbps; + uint32_t rx540mbps; } wl_delta_stats_t; -#define WL_WME_CNT_VERSION 1 +#define WL_WME_CNT_VERSION 1 typedef struct { - uint32_t packets; - uint32_t bytes; + uint32_t packets; + uint32_t bytes; } wl_traffic_stats_t; -#define AC_COUNT 4 +#define AC_COUNT 4 typedef struct { - uint16_t version; - uint16_t length; - wl_traffic_stats_t tx[AC_COUNT]; - wl_traffic_stats_t tx_failed[AC_COUNT]; - wl_traffic_stats_t rx[AC_COUNT]; - wl_traffic_stats_t rx_failed[AC_COUNT]; - wl_traffic_stats_t forward[AC_COUNT]; - wl_traffic_stats_t tx_expired[AC_COUNT]; + uint16_t version; + uint16_t length; + wl_traffic_stats_t tx[AC_COUNT]; + wl_traffic_stats_t tx_failed[AC_COUNT]; + wl_traffic_stats_t rx[AC_COUNT]; + wl_traffic_stats_t rx_failed[AC_COUNT]; + wl_traffic_stats_t forward[AC_COUNT]; + wl_traffic_stats_t tx_expired[AC_COUNT]; } wl_wme_cnt_t; -#define WL_MKEEP_ALIVE_VERSION 1 -#define WL_MKEEP_ALIVE_FIXED_LEN offsetof(wl_mkeep_alive_pkt_t, data) -#define WL_MKEEP_ALIVE_PRECISION 500 - -#define WLC_BA_CNT_VERSION 1 -typedef struct wlc_ba_cnt { - uint16_t version; - uint16_t length; - uint32_t txpdu; - uint32_t txsdu; - uint32_t txfc; - uint32_t txfci; - uint32_t txretrans; - uint32_t txbatimer; - uint32_t txdrop; - uint32_t txaddbareq; - uint32_t txaddbaresp; - uint32_t txdelba; - uint32_t txba; - uint32_t txbar; - uint32_t txpad[4]; - uint32_t rxpdu; - uint32_t rxqed; - uint32_t rxdup; - uint32_t rxnobuf; - uint32_t rxaddbareq; - uint32_t rxaddbaresp; - uint32_t rxdelba; - uint32_t rxba; - uint32_t rxbar; - uint32_t rxinvba; - uint32_t rxbaholes; - uint32_t rxunexp; - uint32_t rxpad[4]; +#define WL_MKEEP_ALIVE_VERSION 1 +#define WL_MKEEP_ALIVE_FIXED_LEN offsetof(wl_mkeep_alive_pkt_t, data) +#define WL_MKEEP_ALIVE_PRECISION 500 + +#define WLC_BA_CNT_VERSION 1 +typedef struct wlc_ba_cnt +{ + uint16_t version; + uint16_t length; + uint32_t txpdu; + uint32_t txsdu; + uint32_t txfc; + uint32_t txfci; + uint32_t txretrans; + uint32_t txbatimer; + uint32_t txdrop; + uint32_t txaddbareq; + uint32_t txaddbaresp; + uint32_t txdelba; + uint32_t txba; + uint32_t txbar; + uint32_t txpad[4]; + uint32_t rxpdu; + uint32_t rxqed; + uint32_t rxdup; + uint32_t rxnobuf; + uint32_t rxaddbareq; + uint32_t rxaddbaresp; + uint32_t rxdelba; + uint32_t rxba; + uint32_t rxbar; + uint32_t rxinvba; + uint32_t rxbaholes; + uint32_t rxunexp; + uint32_t rxpad[4]; } wlc_ba_cnt_t; -struct ampdu_tid_control { - uint8_t tid; - uint8_t enable; +struct ampdu_tid_control +{ + uint8_t tid; + uint8_t enable; }; -struct wl_msglevel2 { - uint32_t low; - uint32_t high; +struct wl_msglevel2 +{ + uint32_t low; + uint32_t high; }; -struct ampdu_ea_tid { - wl_ether_addr_t ea; - uint8_t tid; +struct ampdu_ea_tid +{ + wl_ether_addr_t ea; + uint8_t tid; }; -struct ampdu_retry_tid { - uint8_t tid; - uint8_t retry; +struct ampdu_retry_tid +{ + uint8_t tid; + uint8_t retry; }; -struct ampdu_ba_sizes { - uint8_t ba_tx_wsize; - uint8_t ba_rx_wsize; +struct ampdu_ba_sizes +{ + uint8_t ba_tx_wsize; + uint8_t ba_rx_wsize; }; -#define DPT_DISCOVERY_MANUAL 0x01 -#define DPT_DISCOVERY_AUTO 0x02 -#define DPT_DISCOVERY_SCAN 0x04 -#define DPT_PATHSEL_AUTO 0 -#define DPT_PATHSEL_DIRECT 1 -#define DPT_PATHSEL_APPATH 2 -#define DPT_DENY_LIST_ADD 1 -#define DPT_DENY_LIST_REMOVE 2 -#define DPT_MANUAL_EP_CREATE 1 -#define DPT_MANUAL_EP_MODIFY 2 -#define DPT_MANUAL_EP_DELETE 3 -typedef struct dpt_iovar { - wl_ether_addr_t ea; - uint8_t mode; - uint32_t pad; +#define DPT_DISCOVERY_MANUAL 0x01 +#define DPT_DISCOVERY_AUTO 0x02 +#define DPT_DISCOVERY_SCAN 0x04 +#define DPT_PATHSEL_AUTO 0 +#define DPT_PATHSEL_DIRECT 1 +#define DPT_PATHSEL_APPATH 2 +#define DPT_DENY_LIST_ADD 1 +#define DPT_DENY_LIST_REMOVE 2 +#define DPT_MANUAL_EP_CREATE 1 +#define DPT_MANUAL_EP_MODIFY 2 +#define DPT_MANUAL_EP_DELETE 3 +typedef struct dpt_iovar +{ + wl_ether_addr_t ea; + uint8_t mode; + uint32_t pad; } dpt_iovar_t; -#define DPT_STATUS_ACTIVE 0x01 -#define DPT_STATUS_AES 0x02 -#define DPT_STATUS_FAILED 0x04 -#define DPT_FNAME_LEN 48 -typedef struct dpt_status { - uint8_t status; - uint8_t fnlen; - uint8_t name[DPT_FNAME_LEN]; - uint32_t rssi; - sta_info_t sta; +#define DPT_STATUS_ACTIVE 0x01 +#define DPT_STATUS_AES 0x02 +#define DPT_STATUS_FAILED 0x04 +#define DPT_FNAME_LEN 48 +typedef struct dpt_status +{ + uint8_t status; + uint8_t fnlen; + uint8_t name[DPT_FNAME_LEN]; + uint32_t rssi; + sta_info_t sta; } dpt_status_t; -typedef struct dpt_list { - uint32_t num; - dpt_status_t status[1]; +typedef struct dpt_list +{ + uint32_t num; + dpt_status_t status[1]; } dpt_list_t; -typedef struct dpt_fname { - uint8_t len; - uint8_t name[DPT_FNAME_LEN]; +typedef struct dpt_fname +{ + uint8_t len; + uint8_t name[DPT_FNAME_LEN]; } dpt_fname_t; -#define BDD_FNAME_LEN 32 -typedef struct bdd_fname { - uint8_t len; - uint8_t name[BDD_FNAME_LEN]; +#define BDD_FNAME_LEN 32 +typedef struct bdd_fname +{ + uint8_t len; + uint8_t name[BDD_FNAME_LEN]; } bdd_fname_t; -struct ts_list { - int32_t count; - struct tsinfo_arg tsinfo[1]; +struct ts_list +{ + int32_t count; + struct tsinfo_arg tsinfo[1]; }; -typedef struct tspec_arg { - uint16_t version; - uint16_t length; - uint32_t flag; - struct tsinfo_arg tsinfo; - uint16_t nom_msdu_size; - uint16_t max_msdu_size; - uint32_t min_srv_interval; - uint32_t max_srv_interval; - uint32_t inactivity_interval; - uint32_t suspension_interval; - uint32_t srv_start_time; - uint32_t min_data_rate; - uint32_t mean_data_rate; - uint32_t peak_data_rate; - uint32_t max_burst_size; - uint32_t delay_bound; - uint32_t min_phy_rate; - uint16_t surplus_bw; - uint16_t medium_time; - uint8_t dialog_token; +typedef struct tspec_arg +{ + uint16_t version; + uint16_t length; + uint32_t flag; + struct tsinfo_arg tsinfo; + uint16_t nom_msdu_size; + uint16_t max_msdu_size; + uint32_t min_srv_interval; + uint32_t max_srv_interval; + uint32_t inactivity_interval; + uint32_t suspension_interval; + uint32_t srv_start_time; + uint32_t min_data_rate; + uint32_t mean_data_rate; + uint32_t peak_data_rate; + uint32_t max_burst_size; + uint32_t delay_bound; + uint32_t min_phy_rate; + uint16_t surplus_bw; + uint16_t medium_time; + uint8_t dialog_token; } tspec_arg_t; -typedef struct tspec_per_sta_arg { - wl_ether_addr_t ea; - struct tspec_arg ts; +typedef struct tspec_per_sta_arg +{ + wl_ether_addr_t ea; + struct tspec_arg ts; } tspec_per_sta_arg_t; -typedef struct wme_max_bandwidth { - uint32_t ac[AC_COUNT]; +typedef struct wme_max_bandwidth +{ + uint32_t ac[AC_COUNT]; } wme_max_bandwidth_t; -#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) -#define TSPEC_ARG_VERSION 2 -#define TSPEC_ARG_LENGTH 55 -#define TSPEC_DEFAULT_DIALOG_TOKEN 42 -#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 -#define TSPEC_PENDING 0 -#define TSPEC_ACCEPTED 1 -#define TSPEC_REJECTED 2 -#define TSPEC_UNKNOWN 3 -#define TSPEC_STATUS_MASK 7 -#define WL_WLAN_ASSOC_REASON_NORMAL_NETWORK 0 -#define WL_WLAN_ASSOC_REASON_ROAM_FROM_CELLULAR_NETWORK 1 -#define WL_WLAN_ASSOC_REASON_ROAM_FROM_LAN 2 -#define WL_WLAN_ASSOC_REASON_MAX 2 -#define WL_SWFL_ABBFL 0x0001 -#define WL_SWFL_ABENCORE 0x0002 -#define WL_SWFL_NOHWRADIO 0x0004 -#define WL_LIFETIME_MAX 0xFFFF -typedef struct wl_lifetime { - uint32_t ac; - uint32_t lifetime; +#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t) ) +#define TSPEC_ARG_VERSION 2 +#define TSPEC_ARG_LENGTH 55 +#define TSPEC_DEFAULT_DIALOG_TOKEN 42 +#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 +#define TSPEC_PENDING 0 +#define TSPEC_ACCEPTED 1 +#define TSPEC_REJECTED 2 +#define TSPEC_UNKNOWN 3 +#define TSPEC_STATUS_MASK 7 +#define WL_WLAN_ASSOC_REASON_NORMAL_NETWORK 0 +#define WL_WLAN_ASSOC_REASON_ROAM_FROM_CELLULAR_NETWORK 1 +#define WL_WLAN_ASSOC_REASON_ROAM_FROM_LAN 2 +#define WL_WLAN_ASSOC_REASON_MAX 2 +#define WL_SWFL_ABBFL 0x0001 +#define WL_SWFL_ABENCORE 0x0002 +#define WL_SWFL_NOHWRADIO 0x0004 +#define WL_LIFETIME_MAX 0xFFFF +typedef struct wl_lifetime +{ + uint32_t ac; + uint32_t lifetime; } wl_lifetime_t; -typedef struct wl_chan_switch { - uint8_t mode; - uint8_t count; - wl_chanspec_t chspec; - uint8_t reg; +typedef struct wl_chan_switch +{ + uint8_t mode; + uint8_t count; + wl_chanspec_t chspec; + uint8_t reg; } wl_chan_switch_t; -#define WLC_ROAM_TRIGGER_DEFAULT 0 -#define WLC_ROAM_TRIGGER_BANDWIDTH 1 -#define WLC_ROAM_TRIGGER_DISTANCE 2 -#define WLC_ROAM_TRIGGER_MAX_VALUE 2 -enum { - PFN_LIST_ORDER, - PFN_RSSI +#define WLC_ROAM_TRIGGER_DEFAULT 0 +#define WLC_ROAM_TRIGGER_BANDWIDTH 1 +#define WLC_ROAM_TRIGGER_DISTANCE 2 +#define WLC_ROAM_TRIGGER_MAX_VALUE 2 +enum +{ + PFN_LIST_ORDER, PFN_RSSI }; -#define SORT_CRITERIA_BIT 0 -#define AUTO_NET_SWITCH_BIT 1 -#define ENABLE_BKGRD_SCAN_BIT 2 -#define IMMEDIATE_SCAN_BIT 3 -#define AUTO_CONNECT_BIT 4 -#define IMMEDIATE_EVENT_BIT 8 -#define SUPPRESS_SSID_BIT 9 -#define ENABLE_NET_OFFLOAD_BIT 10 -#define SORT_CRITERIA_MASK 0x01 -#define AUTO_NET_SWITCH_MASK 0x02 -#define ENABLE_BKGRD_SCAN_MASK 0x04 -#define IMMEDIATE_SCAN_MASK 0x08 -#define AUTO_CONNECT_MASK 0x10 -#define PFN_VERSION 2 +#define SORT_CRITERIA_BIT 0 +#define AUTO_NET_SWITCH_BIT 1 +#define ENABLE_BKGRD_SCAN_BIT 2 +#define IMMEDIATE_SCAN_BIT 3 +#define AUTO_CONNECT_BIT 4 +#define IMMEDIATE_EVENT_BIT 8 +#define SUPPRESS_SSID_BIT 9 +#define ENABLE_NET_OFFLOAD_BIT 10 +#define SORT_CRITERIA_MASK 0x01 +#define AUTO_NET_SWITCH_MASK 0x02 +#define ENABLE_BKGRD_SCAN_MASK 0x04 +#define IMMEDIATE_SCAN_MASK 0x08 +#define AUTO_CONNECT_MASK 0x10 +#define PFN_VERSION 2 /* PFN network info structure */ -typedef struct wl_pfn_subnet_info { - struct ether_addr BSSID; - uint8_t channel; /* channel number only */ - uint8_t SSID_len; - uint8_t SSID[32]; +typedef struct wl_pfn_subnet_info +{ + struct ether_addr BSSID; + uint8_t channel; /* channel number only */ + uint8_t SSID_len; + uint8_t SSID[32]; } wl_pfn_subnet_info_t; -typedef struct wl_pfn_net_info { - wl_pfn_subnet_info_t pfnsubnet; - int16_t RSSI; /* receive signal strength (in dBm) */ - uint16_t timestamp; /* age in seconds */ +typedef struct wl_pfn_net_info +{ + wl_pfn_subnet_info_t pfnsubnet; + int16_t RSSI; /* receive signal strength (in dBm) */ + uint16_t timestamp; /* age in seconds */ } wl_pfn_net_info_t; /* used to report exactly one scan result */ /* plus reports detailed scan info in bss_info */ -typedef struct wl_pfn_scanresult { - uint32_t version; - uint32_t status; - uint32_t count; - wl_pfn_net_info_t netinfo; - wl_bss_info_t bss_info; +typedef struct wl_pfn_scanresult +{ + uint32_t version; + uint32_t status; + uint32_t count; + wl_pfn_net_info_t netinfo; + wl_bss_info_t bss_info; } wl_pfn_scanresult_t; /* PFN data structure */ -typedef struct wl_pfn_param { - int32_t version; /* PNO parameters version */ - int32_t scan_freq; /* Scan frequency */ - int32_t lost_network_timeout; /* Timeout in sec. to declare +typedef struct wl_pfn_param +{ + int32_t version; /* PNO parameters version */ + int32_t scan_freq; /* Scan frequency */ + int32_t lost_network_timeout; /* Timeout in sec. to declare * discovered network as lost */ - int16_t flags; /* Bit field to control features + int16_t flags; /* Bit field to control features * of PFN such as sort criteria auto * enable switch and background scan */ - int16_t rssi_margin; /* Margin to avoid jitter for choosing a + int16_t rssi_margin; /* Margin to avoid jitter for choosing a * PFN based on RSSI sort criteria */ - uint8_t bestn; /* number of best networks in each scan */ - uint8_t mscan; /* number of scans recorded */ - uint8_t repeat; /* Minimum number of scan intervals + uint8_t bestn; /* number of best networks in each scan */ + uint8_t mscan; /* number of scans recorded */ + uint8_t repeat; /* Minimum number of scan intervals * before scan frequency changes in adaptive scan */ - uint8_t exp; /* Exponent of 2 for maximum scan interval */ + uint8_t exp; /* Exponent of 2 for maximum scan interval */ - int32_t slow_freq; /* slow scan period */ + int32_t slow_freq; /* slow scan period */ } wl_pfn_param_t; -typedef struct wl_pfn_bssid { - struct ether_addr macaddr; - /* Bit4: suppress_lost, Bit3: suppress_found */ - uint16_t flags; +typedef struct wl_pfn_bssid +{ + struct ether_addr macaddr; + /* Bit4: suppress_lost, Bit3: suppress_found */ + uint16_t flags; } wl_pfn_bssid_t; -typedef struct wl_pfn_cfg { - uint32_t reporttype; - int32_t channel_num; - uint16_t channel_list[WL_NUMCHANNELS]; - uint32_t flags; +typedef struct wl_pfn_cfg +{ + uint32_t reporttype; + int32_t channel_num; + uint16_t channel_list[WL_NUMCHANNELS]; + uint32_t flags; } wl_pfn_cfg_t; /* for use with wl_pfn.flags */ #define WL_PFN_HIDDEN_MASK 0x4 #define WL_PFN_SUPPRESSLOST_MASK 0x10 -typedef struct wl_pfn { - wlc_ssid_t ssid; /* ssid name and its length */ - int32_t flags; /* bit2: hidden */ - int32_t infra; /* BSS Vs IBSS */ - int32_t auth; /* Open Vs Closed */ - int32_t wpa_auth; /* WPA type */ - int32_t wsec; /* wsec value */ +typedef struct wl_pfn +{ + wlc_ssid_t ssid; /* ssid name and its length */ + int32_t flags; /* bit2: hidden */ + int32_t infra; /* BSS Vs IBSS */ + int32_t auth; /* Open Vs Closed */ + int32_t wpa_auth; /* WPA type */ + int32_t wsec; /* wsec value */ } wl_pfn_t; -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 -#define TOE_ERRTEST_TX_CSUM 0x00000001 -#define TOE_ERRTEST_RX_CSUM 0x00000002 -#define TOE_ERRTEST_RX_CSUM2 0x00000004 -struct toe_ol_stats_t { - uint32_t tx_summed; - uint32_t tx_iph_fill; - uint32_t tx_tcp_fill; - uint32_t tx_udp_fill; - uint32_t tx_icmp_fill; - uint32_t rx_iph_good; - uint32_t rx_iph_bad; - uint32_t rx_tcp_good; - uint32_t rx_tcp_bad; - uint32_t rx_udp_good; - uint32_t rx_udp_bad; - uint32_t rx_icmp_good; - uint32_t rx_icmp_bad; - uint32_t tx_tcp_errinj; - uint32_t tx_udp_errinj; - uint32_t tx_icmp_errinj; - uint32_t rx_tcp_errinj; - uint32_t rx_udp_errinj; - uint32_t rx_icmp_errinj; +#define TOE_TX_CSUM_OL 0x00000001 +#define TOE_RX_CSUM_OL 0x00000002 +#define TOE_ERRTEST_TX_CSUM 0x00000001 +#define TOE_ERRTEST_RX_CSUM 0x00000002 +#define TOE_ERRTEST_RX_CSUM2 0x00000004 +struct toe_ol_stats_t +{ + uint32_t tx_summed; + uint32_t tx_iph_fill; + uint32_t tx_tcp_fill; + uint32_t tx_udp_fill; + uint32_t tx_icmp_fill; + uint32_t rx_iph_good; + uint32_t rx_iph_bad; + uint32_t rx_tcp_good; + uint32_t rx_tcp_bad; + uint32_t rx_udp_good; + uint32_t rx_udp_bad; + uint32_t rx_icmp_good; + uint32_t rx_icmp_bad; + uint32_t tx_tcp_errinj; + uint32_t tx_udp_errinj; + uint32_t tx_icmp_errinj; + uint32_t rx_tcp_errinj; + uint32_t rx_udp_errinj; + uint32_t rx_icmp_errinj; }; -#define ARP_OL_AGENT 0x00000001 -#define ARP_OL_SNOOP 0x00000002 -#define ARP_OL_HOST_AUTO_REPLY 0x00000004 -#define ARP_OL_PEER_AUTO_REPLY 0x00000008 -#define ARP_ERRTEST_REPLY_PEER 0x1 -#define ARP_ERRTEST_REPLY_HOST 0x2 +#define ARP_OL_AGENT 0x00000001 +#define ARP_OL_SNOOP 0x00000002 +#define ARP_OL_HOST_AUTO_REPLY 0x00000004 +#define ARP_OL_PEER_AUTO_REPLY 0x00000008 +#define ARP_ERRTEST_REPLY_PEER 0x1 +#define ARP_ERRTEST_REPLY_HOST 0x2 #define ARP_MULTIHOMING_MAX 8 -typedef struct arp_ol_stats { - uint32_t host_ip_entries; - uint32_t host_ip_overflow; - uint32_t arp_table_entries; - uint32_t arp_table_overflow; - uint32_t host_request; - uint32_t host_reply; - uint32_t host_service; - uint32_t peer_request; - uint32_t peer_request_drop; - uint32_t peer_reply; - uint32_t peer_reply_drop; - uint32_t peer_service; -} arp_ol_stats_t; -typedef struct wl_keep_alive_pkt { - uint32_t period_msec; - uint16_t len_bytes; - uint8_t data[1]; +typedef struct arp_ol_stats +{ + uint32_t host_ip_entries; + uint32_t host_ip_overflow; + uint32_t arp_table_entries; + uint32_t arp_table_overflow; + uint32_t host_request; + uint32_t host_reply; + uint32_t host_service; + uint32_t peer_request; + uint32_t peer_request_drop; + uint32_t peer_reply; + uint32_t peer_reply_drop; + uint32_t peer_service; +}arp_ol_stats_t; + +typedef struct wl_keep_alive_pkt +{ + uint32_t period_msec; + uint16_t len_bytes; + uint8_t data[1]; } wl_keep_alive_pkt_t; -#define WL_KEEP_ALIVE_FIXED_LEN offsetof(wl_keep_alive_pkt_t, data) -typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH + +typedef enum wl_pkt_filter_type +{ + WL_PKT_FILTER_TYPE_PATTERN_MATCH } wl_pkt_filter_type_t; #define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t -typedef struct wl_pkt_filter_pattern { - uint32_t offset; - uint32_t size_bytes; - uint8_t mask_and_pattern[1]; +typedef struct wl_pkt_filter_pattern +{ + uint32_t offset; + uint32_t size_bytes; + uint8_t mask_and_pattern[1]; } wl_pkt_filter_pattern_t; -typedef struct wl_pkt_filter { - uint32_t id; - uint32_t type; - uint32_t negate_match; - union { - wl_pkt_filter_pattern_t pattern; - } u; +typedef struct wl_pkt_filter +{ + uint32_t id; + uint32_t type; + uint32_t negate_match; + union + { + wl_pkt_filter_pattern_t pattern; + } u; } wl_pkt_filter_t; -#define WL_PKT_FILTER_FIXED_LEN offsetof(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN offsetof(wl_pkt_filter_pattern_t, mask_and_pattern) -typedef struct wl_pkt_filter_enable { - uint32_t id; - uint32_t enable; +#define WL_PKT_FILTER_FIXED_LEN offsetof(wl_pkt_filter_t, u) +#define WL_PKT_FILTER_PATTERN_FIXED_LEN offsetof(wl_pkt_filter_pattern_t, mask_and_pattern) +typedef struct wl_pkt_filter_enable +{ + uint32_t id; + uint32_t enable; } wl_pkt_filter_enable_t; -typedef struct wl_pkt_filter_list { - uint32_t num; - wl_pkt_filter_t filter[1]; +typedef struct wl_pkt_filter_list +{ + uint32_t num; + wl_pkt_filter_t filter[1]; } wl_pkt_filter_list_t; -#define WL_PKT_FILTER_LIST_FIXED_LEN offsetof(wl_pkt_filter_list_t, filter) -typedef struct wl_pkt_filter_stats { - uint32_t num_pkts_matched; - uint32_t num_pkts_forwarded; - uint32_t num_pkts_discarded; +#define WL_PKT_FILTER_LIST_FIXED_LEN offsetof(wl_pkt_filter_list_t, filter) +typedef struct wl_pkt_filter_stats +{ + uint32_t num_pkts_matched; + uint32_t num_pkts_forwarded; + uint32_t num_pkts_discarded; } wl_pkt_filter_stats_t; -typedef struct wl_seq_cmd_ioctl { - uint32_t cmd; - uint32_t len; +typedef struct wl_seq_cmd_ioctl +{ + uint32_t cmd; + uint32_t len; } wl_seq_cmd_ioctl_t; -#define WL_SEQ_CMD_ALIGN_BYTES 4 +#define WL_SEQ_CMD_ALIGN_BYTES 4 #define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \ - (((cmd) == WLC_GET_MAGIC) || \ - ((cmd) == WLC_GET_VERSION) || \ - ((cmd) == WLC_GET_AP) || \ - ((cmd) == WLC_GET_INSTANCE)) -#define WL_PKTENG_PER_TX_START 0x01 -#define WL_PKTENG_PER_TX_STOP 0x02 -#define WL_PKTENG_PER_RX_START 0x04 -#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 -#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 -#define WL_PKTENG_PER_RX_STOP 0x08 -#define WL_PKTENG_PER_MASK 0xff -#define WL_PKTENG_SYNCHRONOUS 0x100 -typedef struct wl_pkteng { - uint32_t flags; - uint32_t delay; - uint32_t nframes; - uint32_t length; - uint8_t seqno; - wl_ether_addr_t dest; - wl_ether_addr_t src; + ( ( (cmd) == WLC_GET_MAGIC ) || \ + ( (cmd) == WLC_GET_VERSION ) || \ + ( (cmd) == WLC_GET_AP ) || \ + ( (cmd) == WLC_GET_INSTANCE ) ) +#define WL_PKTENG_PER_TX_START 0x01 +#define WL_PKTENG_PER_TX_STOP 0x02 +#define WL_PKTENG_PER_RX_START 0x04 +#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05 +#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06 +#define WL_PKTENG_PER_RX_STOP 0x08 +#define WL_PKTENG_PER_MASK 0xff +#define WL_PKTENG_SYNCHRONOUS 0x100 +typedef struct wl_pkteng +{ + uint32_t flags; + uint32_t delay; + uint32_t nframes; + uint32_t length; + uint8_t seqno; + wl_ether_addr_t dest; + wl_ether_addr_t src; } wl_pkteng_t; -#define NUM_80211b_RATES 4 -#define NUM_80211ag_RATES 8 -#define NUM_80211n_RATES 32 -#define NUM_80211_RATES (NUM_80211b_RATES + NUM_80211ag_RATES + NUM_80211n_RATES) -typedef struct wl_pkteng_stats { - uint32_t lostfrmcnt; - int32_t rssi; - int32_t snr; - uint16_t rxpktcnt[NUM_80211_RATES + 1]; +#define NUM_80211b_RATES 4 +#define NUM_80211ag_RATES 8 +#define NUM_80211n_RATES 32 +#define NUM_80211_RATES (NUM_80211b_RATES + NUM_80211ag_RATES + NUM_80211n_RATES) +typedef struct wl_pkteng_stats +{ + uint32_t lostfrmcnt; + int32_t rssi; + int32_t snr; + uint16_t rxpktcnt[NUM_80211_RATES + 1]; } wl_pkteng_stats_t; -typedef struct wl_sslpnphy_papd_debug_data { - uint8_t psat_pwr; - uint8_t psat_indx; - uint8_t final_idx; - uint8_t start_idx; - int32_t min_phase; - int32_t voltage; - int8_t temperature; +typedef struct wl_sslpnphy_papd_debug_data +{ + uint8_t psat_pwr; + uint8_t psat_indx; + uint8_t final_idx; + uint8_t start_idx; + int32_t min_phase; + int32_t voltage; + int8_t temperature; } wl_sslpnphy_papd_debug_data_t; -typedef struct wl_sslpnphy_debug_data { - int16_t papdcompRe[64]; - int16_t papdcompIm[64]; +typedef struct wl_sslpnphy_debug_data +{ + int16_t papdcompRe[64]; + int16_t papdcompIm[64]; } wl_sslpnphy_debug_data_t; -typedef struct wl_sslpnphy_spbdump_data { - uint16_t tbl_length; - int16_t spbreal[256]; - int16_t spbimg[256]; +typedef struct wl_sslpnphy_spbdump_data +{ + uint16_t tbl_length; + int16_t spbreal[256]; + int16_t spbimg[256]; } wl_sslpnphy_spbdump_data_t; -typedef struct wl_sslpnphy_percal_debug_data { - uint32_t cur_idx; - uint32_t tx_drift; - uint8_t prev_cal_idx; - uint32_t percal_ctr; - int32_t nxt_cal_idx; - uint32_t force_1idxcal; - uint32_t onedxacl_req; - int32_t last_cal_volt; - int8_t last_cal_temp; - uint32_t vbat_ripple; - uint32_t exit_route; - int32_t volt_winner; +typedef struct wl_sslpnphy_percal_debug_data +{ + uint32_t cur_idx; + uint32_t tx_drift; + uint8_t prev_cal_idx; + uint32_t percal_ctr; + int32_t nxt_cal_idx; + uint32_t force_1idxcal; + uint32_t onedxacl_req; + int32_t last_cal_volt; + int8_t last_cal_temp; + uint32_t vbat_ripple; + uint32_t exit_route; + int32_t volt_winner; } wl_sslpnphy_percal_debug_data_t; -#define WL_WOWL_MAGIC (1 << 0) -#define WL_WOWL_NET (1 << 1) -#define WL_WOWL_DIS (1 << 2) -#define WL_WOWL_RETR (1 << 3) -#define WL_WOWL_BCN (1 << 4) -#define WL_WOWL_TST (1 << 5) -#define WL_WOWL_TRAFFIC (1 << 12) -#define WL_WOWL_BCAST (1 << 15) -#define WL_WOWL_GTK (0x441f) -#define WL_WOWL_DEAUTH (0x1F) -#define WL_WOWL_ALL (0x541E) +#define WL_WOWL_MAGIC (1 << 0) +#define WL_WOWL_NET (1 << 1) +#define WL_WOWL_DIS (1 << 2) +#define WL_WOWL_RETR (1 << 3) +#define WL_WOWL_BCN (1 << 4) +#define WL_WOWL_TST (1 << 5) +#define WL_WOWL_ARPOFFLOAD (1 << 12) +#define WL_WOWL_KEYROT (1 << 14) +#define WL_WOWL_BCAST (1 << 15) +#define WL_WOWL_SECURE (1 << 25) /* Wakeup if received matched secured pattern */ +#define WL_WOWL_GTK (0x441f) +#define WL_WOWL_DEAUTH (0x1F) +#define WL_WOWL_ALL (0x541E) #define MAGIC_PKT_MINLEN 102 -typedef struct -{ - uint32_t masksize; - uint32_t offset; - uint32_t patternoffset; - uint32_t patternsize; + +typedef enum { + WOWL_PATTERN_TYPE_BITMAP = 0, + WOWL_PATTERN_TYPE_ARP, + WOWL_PATTERN_TYPE_NA, + WOWL_PATTERN_TYPE_SECWOWL +} wowl_pattern_type_t; + +typedef struct wl_wowl_pattern { + uint32_t masksize; /**< Size of the mask in #of bytes */ + uint32_t offset; /**< Pattern byte offset in packet */ + uint32_t patternoffset; /**< Offset of start of pattern in the structure */ + uint32_t patternsize; /**< Size of the pattern itself in #of bytes */ + uint32_t id; /**< id */ + uint32_t reasonsize; /**< Size of the wakeup reason code */ + uint32_t type; /**< Type of pattern */ + /* Mask follows the structure above */ + /* Pattern follows the mask is at 'patternoffset' from the start */ } wl_wowl_pattern_t; -typedef struct + +typedef struct wl_wowl_pattern_list { - uint32_t count; - wl_wowl_pattern_t pattern[1]; + uint32_t count; + wl_wowl_pattern_t pattern[1]; } wl_wowl_pattern_list_t; -typedef struct + +typedef struct wl_wowl_wakeind { - uint8_t pci_wakeind; - uint16_t ucode_wakeind; + uint8_t pci_wakeind; /**< Whether PCI PMECSR PMEStatus bit was set */ + uint16_t ucode_wakeind; /**< What wakeup-event indication was set by ucode */ } wl_wowl_wakeind_t; -typedef struct wl_txrate_class { - uint8_t init_rate; - uint8_t min_rate; - uint8_t max_rate; + +typedef struct wl_txrate_class +{ + uint8_t init_rate; + uint8_t min_rate; + uint8_t max_rate; } wl_txrate_class_t; -#define WL_DELAYMODE_DEFER 0 -#define WL_DELAYMODE_FORCE 1 -#define WL_DELAYMODE_AUTO 2 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 100 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 -#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 -#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 -#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 -#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 -#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 -#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 -#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 -typedef struct wl_obss_scan_arg { - int16_t passive_dwell; - int16_t active_dwell; - int16_t bss_widthscan_interval; - int16_t passive_total; - int16_t active_total; - int16_t chanwidth_transition_delay; - int16_t activity_threshold; + +#define WL_DELAYMODE_DEFER 0 +#define WL_DELAYMODE_FORCE 1 +#define WL_DELAYMODE_AUTO 2 +#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 100 +#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 +#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 +#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 20 +#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 +#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 +#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5 +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5 +#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100 +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 +#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 +#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 +#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 +typedef struct wl_obss_scan_arg +{ + int16_t passive_dwell; + int16_t active_dwell; + int16_t bss_widthscan_interval; + int16_t passive_total; + int16_t active_total; + int16_t chanwidth_transition_delay; + int16_t activity_threshold; } wl_obss_scan_arg_t; -#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) +#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t) #define WL_MIN_NUM_OBSS_SCAN_ARG 7 #define WL_COEX_INFO_MASK 0x07 -#define WL_COEX_INFO_REQ 0x01 -#define WL_COEX_40MHZ_INTOLERANT 0x02 -#define WL_COEX_WIDTH20 0x04 -typedef struct wl_action_obss_coex_req { - uint8_t info; - uint8_t num; - uint8_t ch_list[1]; +#define WL_COEX_INFO_REQ 0x01 +#define WL_COEX_40MHZ_INTOLERANT 0x02 +#define WL_COEX_WIDTH20 0x04 +typedef struct wl_action_obss_coex_req +{ + uint8_t info; + uint8_t num; + uint8_t ch_list[1]; } wl_action_obss_coex_req_t; #define MAX_RSSI_LEVELS 8 -typedef struct wl_rssi_event { - uint32_t rate_limit_msec; - uint8_t num_rssi_levels; - int8_t rssi_levels[MAX_RSSI_LEVELS]; +typedef struct wl_rssi_event +{ + uint32_t rate_limit_msec; + uint8_t num_rssi_levels; + int8_t rssi_levels[MAX_RSSI_LEVELS]; } wl_rssi_event_t; -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 +#define WLFEATURE_DISABLE_11N 0x00000001 +#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 +#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 +#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 +#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 +#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 +#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 +#define WLFEATURE_DISABLE_11N_GF 0x00000080 #pragma pack(1) -typedef struct sta_prbreq_wps_ie_hdr { - wl_ether_addr_t staAddr; - uint16_t ieLen; +typedef struct sta_prbreq_wps_ie_hdr +{ + wl_ether_addr_t staAddr; + uint16_t ieLen; } sta_prbreq_wps_ie_hdr_t; -typedef struct sta_prbreq_wps_ie_data { - sta_prbreq_wps_ie_hdr_t hdr; - uint8_t ieData[1]; +typedef struct sta_prbreq_wps_ie_data +{ + sta_prbreq_wps_ie_hdr_t hdr; + uint8_t ieData[1]; } sta_prbreq_wps_ie_data_t; -typedef struct sta_prbreq_wps_ie_list { - uint32_t totLen; - uint8_t ieDataList[1]; +typedef struct sta_prbreq_wps_ie_list +{ + uint32_t totLen; + uint8_t ieDataList[1]; } sta_prbreq_wps_ie_list_t; /* EDCF related items from 802.11.h */ /* ACI from 802.11.h */ -#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ -#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ -#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ -#define EDCF_ACM_MASK 0x10 /* ACM mask */ -#define EDCF_ACI_MASK 0x60 /* ACI mask */ -#define EDCF_ACI_SHIFT 5 /* ACI shift */ -#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ +#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ +#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ +#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ +#define EDCF_ACM_MASK 0x10 /* ACM mask */ +#define EDCF_ACI_MASK 0x60 /* ACI mask */ +#define EDCF_ACI_SHIFT 5 /* ACI shift */ +#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */ /* ECW from 802.11.h */ -#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ -#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ -#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ -#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ +#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ +#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ +#define EDCF_ECW2CW(exp) ( (1 << (exp) ) - 1 ) +#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ +#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ +#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ /* TXOP from 802.11.h */ -#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ -#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ -#define EDCF_TXOP2USEC(txop) ((txop) << 5) +#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ +#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ +#define EDCF_TXOP2USEC(txop) ( (txop) << 5 ) #define EDCF_ACPARAM -struct edcf_acparam { - uint8_t ACI; - uint8_t ECW; - uint16_t TXOP; /* stored in network order (ls octet first) */ +struct edcf_acparam +{ + uint8_t ACI; + uint8_t ECW; + uint16_t TXOP; /* stored in network order (ls octet first) */ }; typedef struct edcf_acparam edcf_acparam_t; @@ -3377,10 +3858,11 @@ typedef struct edcf_acparam edcf_acparam_t; #pragma pack() /* discovery state */ -typedef struct wl_p2p_disc_st { - uint8_t state; /* see p2p_discovery_state_t */ - uint16_t chanspec; /* valid in listen state */ - uint16_t dwell_time_ms; /* valid in listen state, in ms */ +typedef struct wl_p2p_disc_st +{ + uint8_t state; /* see p2p_discovery_state_t */ + uint16_t chanspec; /* valid in listen state */ + uint16_t dwell_time_ms; /* valid in listen state, in ms */ } wl_p2p_disc_st_t; /* scan request */ @@ -3393,81 +3875,87 @@ typedef struct wl_p2p_scan { /* escan request */ typedef struct { - uint8_t type; /* 'S' for WLC_SCAN, 'E' for "escan" */ - uint8_t reserved[3]; + uint8_t type; /* 'S' for WLC_SCAN, 'E' for "escan" */ + uint8_t reserved[3]; - /* escan params */ - wl_escan_params_t escan; + /* escan params */ + wl_escan_params_t escan; } wl_p2p_escan_t; /* i/f request */ -typedef struct wl_p2p_if { - struct ether_addr mac_address; - uint8_t interface_type; - uint16_t chan_spec; +typedef struct wl_p2p_if +{ + struct ether_addr mac_address; + uint8_t interface_type; + uint16_t chan_spec; } wl_p2p_if_t; /* i/f query */ -typedef struct wl_p2p_ifq { - uint32_t bsscfgidx; - char ifname[16]; +typedef struct wl_p2p_ifq +{ + uint32_t bsscfgidx; + char ifname[16]; } wl_p2p_ifq_t; /* OppPS & CTWindow */ -typedef struct wl_p2p_ops { - uint8_t ops; /* 0: disable 1: enable */ - uint8_t ctw; /* >= 10 */ +typedef struct wl_p2p_ops +{ + uint8_t ops; /* 0: disable 1: enable */ + uint8_t ctw; /* >= 10 */ } wl_p2p_ops_t; /* absence and presence request */ -typedef struct wl_p2p_sched_desc { - uint32_t start; - uint32_t interval; - uint32_t duration; - uint32_t count; /* see count */ +typedef struct wl_p2p_sched_desc +{ + uint32_t start; + uint32_t interval; + uint32_t duration; + uint32_t count; /* see count */ } wl_p2p_sched_desc_t; -typedef struct wl_p2p_sched { - uint8_t type; /* see schedule type */ - uint8_t action; /* see schedule action */ - uint8_t option; /* see schedule option */ - wl_p2p_sched_desc_t desc[1]; +typedef struct wl_p2p_sched +{ + uint8_t type; /* see schedule type */ + uint8_t action; /* see schedule action */ + uint8_t option; /* see schedule option */ + wl_p2p_sched_desc_t desc[1]; } wl_p2p_sched_t; /* schedule type */ -#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ -#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ -#define WL_P2P_SCHED_TYPE_REQ_PSC 2 /* Requested Presence */ +#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */ +#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */ +#define WL_P2P_SCHED_TYPE_REQ_PSC 2 /* Requested Presence */ /* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */ -#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ -#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ -#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ +#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */ +#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */ +#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */ /* schedule option - WL_P2P_SCHED_TYPE_ABS */ -#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count in time */ -#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ - -typedef struct wl_p2p_wfds_hash { - uint32_t advt_id; - uint16_t nw_cfg_method; - uint8_t wfds_hash[6]; - uint8_t name_len; - uint8_t service_name[MAX_WFDS_SVC_NAME_LEN]; +#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count in time */ +#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */ + +typedef struct wl_p2p_wfds_hash +{ + uint32_t advt_id; + uint16_t nw_cfg_method; + uint8_t wfds_hash[6]; + uint8_t name_len; + uint8_t service_name[MAX_WFDS_SVC_NAME_LEN]; } wl_p2p_wfds_hash_t; -#define P2P_IP_ALLOC_LEN 12 +#define P2P_IP_ALLOC_LEN 12 /* Definitions for Reliable Multicast */ /* NOTE: RMC structures should not be packed */ -#define WL_RMC_CNT_VERSION (1) -#define WL_RMC_TR_VERSION (1) -#define WL_RMC_MAX_CLIENT (32) -#define WL_RMC_FLAG_INBLACKLIST (1) -#define WL_RMC_FLAG_ACTIVEACKER (2) -#define WL_RMC_FLAG_RELMCAST (4) -#define WL_RMC_FLAG_MASTER_TX (8) -#define WL_RMC_MAX_TABLE_ENTRY (8) +#define WL_RMC_CNT_VERSION (1) +#define WL_RMC_TR_VERSION (1) +#define WL_RMC_MAX_CLIENT (32) +#define WL_RMC_FLAG_INBLACKLIST (1) +#define WL_RMC_FLAG_ACTIVEACKER (2) +#define WL_RMC_FLAG_RELMCAST (4) +#define WL_RMC_FLAG_MASTER_TX (8) +#define WL_RMC_MAX_TABLE_ENTRY (8) #define WL_RMC_VER (1) #define WL_RMC_INDEX_ACK_ALL (255) @@ -3482,188 +3970,204 @@ typedef struct wl_p2p_wfds_hash { #define WL_RMC_ARTMO_MIN (350) /* time in ms */ #define WL_RMC_ARTMO_MAX (40000) /* time in ms */ -enum rmc_opcodes { - RELMCAST_ENTRY_OP_DISABLE = 0, /* Disable multi-cast group */ - RELMCAST_ENTRY_OP_DELETE = 1, /* Delete multi-cast group */ - RELMCAST_ENTRY_OP_ENABLE = 2, /* Enable multi-cast group */ - RELMCAST_ENTRY_OP_ACK_ALL = 3 /* Enable ACK ALL bit in AMT */ +enum rmc_opcodes +{ + RELMCAST_ENTRY_OP_DISABLE = 0, /* Disable multi-cast group */ + RELMCAST_ENTRY_OP_DELETE = 1, /* Delete multi-cast group */ + RELMCAST_ENTRY_OP_ENABLE = 2, /* Enable multi-cast group */ + RELMCAST_ENTRY_OP_ACK_ALL = 3 /* Enable ACK ALL bit in AMT */ }; /* RMC operational modes */ -enum rmc_modes { - WL_RMC_MODE_RECEIVER = 0, /* Receiver mode by default */ - WL_RMC_MODE_TRANSMITTER = 1, /* Transmitter mode using wl ackreq */ - WL_RMC_MODE_INITIATOR = 2 /* Initiator mode using wl ackreq */ +enum rmc_modes +{ + WL_RMC_MODE_RECEIVER = 0, /* Receiver mode by default */ + WL_RMC_MODE_TRANSMITTER = 1, /* Transmitter mode using wl ackreq */ + WL_RMC_MODE_INITIATOR = 2 /* Initiator mode using wl ackreq */ }; /* Each RMC mcast client info */ -typedef struct wl_relmcast_client { - uint8_t flag; /* status of client such as AR, R, or blacklisted */ - int16_t rssi; /* rssi value of RMC client */ - struct ether_addr addr; /* mac address of RMC client */ +typedef struct wl_relmcast_client +{ + uint8_t flag; /* status of client such as AR, R, or blacklisted */ + int16_t rssi; /* rssi value of RMC client */ + struct ether_addr addr; /* mac address of RMC client */ } wl_relmcast_client_t; /* RMC Counters */ -typedef struct wl_rmc_cnts { - uint16_t version; /* see definition of WL_CNT_T_VERSION */ - uint16_t length; /* length of entire structure */ - uint16_t dupcnt; /* counter for duplicate rmc MPDU */ - uint16_t ackreq_err; /* counter for wl ackreq error */ - uint16_t af_tx_err; /* error count for action frame transmit */ - uint16_t null_tx_err; /* error count for rmc null frame transmit */ - uint16_t af_unicast_tx_err; /* error count for rmc unicast frame transmit */ - uint16_t mc_no_amt_slot; /* No mcast AMT entry available */ - /* Unused. Keep for rom compatibility */ - uint16_t mc_no_glb_slot; /* No mcast entry available in global table */ - uint16_t mc_not_mirrored; /* mcast group is not mirrored */ - uint16_t mc_existing_tr; /* mcast group is already taken by transmitter */ - uint16_t mc_exist_in_amt; /* mcast group is already programmed in amt */ - /* Unused. Keep for rom compatibility */ - uint16_t mc_not_exist_in_gbl; /* mcast group is not in global table */ - uint16_t mc_not_exist_in_amt; /* mcast group is not in AMT table */ - uint16_t mc_utilized; /* mcast addressed is already taken */ - uint16_t mc_taken_other_tr; /* multi-cast addressed is already taken */ - uint32_t rmc_rx_frames_mac; /* no of mc frames received from mac */ - uint32_t rmc_tx_frames_mac; /* no of mc frames transmitted to mac */ - uint32_t mc_null_ar_cnt; /* no. of times NULL AR is received */ - uint32_t mc_ar_role_selected; /* no. of times took AR role */ - uint32_t mc_ar_role_deleted; /* no. of times AR role cancelled */ - uint32_t mc_noacktimer_expired; /* no. of times noack timer expired */ - uint16_t mc_no_wl_clk; /* no wl clk detected when trying to access amt */ - uint16_t mc_tr_cnt_exceeded; /* No of transmitters in the network exceeded */ +typedef struct wl_rmc_cnts +{ + uint16_t version; /* see definition of WL_CNT_T_VERSION */ + uint16_t length; /* length of entire structure */ + uint16_t dupcnt; /* counter for duplicate rmc MPDU */ + uint16_t ackreq_err; /* counter for wl ackreq error */ + uint16_t af_tx_err; /* error count for action frame transmit */ + uint16_t null_tx_err; /* error count for rmc null frame transmit */ + uint16_t af_unicast_tx_err; /* error count for rmc unicast frame transmit */ + uint16_t mc_no_amt_slot; /* No mcast AMT entry available */ + /* Unused. Keep for rom compatibility */ + uint16_t mc_no_glb_slot; /* No mcast entry available in global table */ + uint16_t mc_not_mirrored; /* mcast group is not mirrored */ + uint16_t mc_existing_tr; /* mcast group is already taken by transmitter */ + uint16_t mc_exist_in_amt; /* mcast group is already programmed in amt */ + /* Unused. Keep for rom compatibility */ + uint16_t mc_not_exist_in_gbl; /* mcast group is not in global table */ + uint16_t mc_not_exist_in_amt; /* mcast group is not in AMT table */ + uint16_t mc_utilized; /* mcast addressed is already taken */ + uint16_t mc_taken_other_tr; /* multi-cast addressed is already taken */ + uint32_t rmc_rx_frames_mac; /* no of mc frames received from mac */ + uint32_t rmc_tx_frames_mac; /* no of mc frames transmitted to mac */ + uint32_t mc_null_ar_cnt; /* no. of times NULL AR is received */ + uint32_t mc_ar_role_selected; /* no. of times took AR role */ + uint32_t mc_ar_role_deleted; /* no. of times AR role cancelled */ + uint32_t mc_noacktimer_expired; /* no. of times noack timer expired */ + uint16_t mc_no_wl_clk; /* no wl clk detected when trying to access amt */ + uint16_t mc_tr_cnt_exceeded; /* No of transmitters in the network exceeded */ } wl_rmc_cnts_t; /* RMC Status */ -typedef struct wl_relmcast_st { - uint8_t ver; /* version of RMC */ - uint8_t num; /* number of clients detected by transmitter */ - wl_relmcast_client_t clients[WL_RMC_MAX_CLIENT]; - uint16_t err; /* error status (used in infra) */ - uint16_t actf_time; /* action frame time period */ +typedef struct wl_relmcast_st +{ + uint8_t ver; /* version of RMC */ + uint8_t num; /* number of clients detected by transmitter */ + wl_relmcast_client_t clients[WL_RMC_MAX_CLIENT]; + uint16_t err; /* error status (used in infra) */ + uint16_t actf_time; /* action frame time period */ } wl_relmcast_status_t; /* Entry for each STA/node */ -typedef struct wl_rmc_entry { - /* operation on multi-cast entry such add, +typedef struct wl_rmc_entry +{ + /* operation on multi-cast entry such add, * delete, ack-all */ - int8_t flag; - struct ether_addr addr; /* multi-cast group mac address */ + int8_t flag; + struct ether_addr addr; /* multi-cast group mac address */ } wl_rmc_entry_t; /* RMC table */ -typedef struct wl_rmc_entry_table { - uint8_t index; /* index to a particular mac entry in table */ - uint8_t opcode; /* opcodes or operation on entry */ - wl_rmc_entry_t entry[WL_RMC_MAX_TABLE_ENTRY]; +typedef struct wl_rmc_entry_table +{ + uint8_t index; /* index to a particular mac entry in table */ + uint8_t opcode; /* opcodes or operation on entry */ + wl_rmc_entry_t entry[WL_RMC_MAX_TABLE_ENTRY]; } wl_rmc_entry_table_t; -typedef struct wl_rmc_trans_elem { - struct ether_addr tr_mac; /* transmitter mac */ - struct ether_addr ar_mac; /* ar mac */ - uint16_t artmo; /* AR timeout */ - uint8_t amt_idx; /* amt table entry */ - uint16_t flag; /* entry will be acked, not acked, programmed, full etc */ +typedef struct wl_rmc_trans_elem +{ + struct ether_addr tr_mac; /* transmitter mac */ + struct ether_addr ar_mac; /* ar mac */ + uint16_t artmo; /* AR timeout */ + uint8_t amt_idx; /* amt table entry */ + uint16_t flag; /* entry will be acked, not acked, programmed, full etc */ } wl_rmc_trans_elem_t; /* RMC transmitters */ -typedef struct wl_rmc_trans_in_network { - uint8_t ver; /* version of RMC */ - uint8_t num_tr; /* number of transmitters in the network */ - wl_rmc_trans_elem_t trs[WL_RMC_MAX_NUM_TRS]; +typedef struct wl_rmc_trans_in_network +{ + uint8_t ver; /* version of RMC */ + uint8_t num_tr; /* number of transmitters in the network */ + wl_rmc_trans_elem_t trs[WL_RMC_MAX_NUM_TRS]; } wl_rmc_trans_in_network_t; /* To update vendor specific ie for RMC */ -typedef struct wl_rmc_vsie { - uint8_t oui[3]; - uint16_t payload; /* IE Data Payload */ +typedef struct wl_rmc_vsie +{ + uint8_t oui[3]; + uint16_t payload; /* IE Data Payload */ } wl_rmc_vsie_t; /* WLC_E_ULP event data */ -#define WL_ULP_EVENT_VERSION 1 -#define WL_ULP_DISABLE_CONSOLE 1 /* Disable console message on ULP entry */ -#define WL_ULP_UCODE_DOWNLOAD 2 /* Download ULP ucode file */ -#define WL_ULP_ENTRY 3 /* inform ulp entry to Host during warmboot */ - -typedef struct wl_ulp_event { - uint16_t version; - uint16_t ulp_dongle_action; +#define WL_ULP_EVENT_VERSION 1 +#define WL_ULP_DISABLE_CONSOLE 1 /* Disable console message on ULP entry */ +#define WL_ULP_UCODE_DOWNLOAD 2 /* Download ULP ucode file */ +#define WL_ULP_ENTRY 3 /* inform ulp entry to Host during warmboot */ + +typedef struct wl_ulp_event +{ + uint16_t version; + uint16_t ulp_dongle_action; } wl_ulp_event_t; /* clm download */ -#define DLOAD_HANDLER_VER 1 /* Downloader version */ -#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ -#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ +#define DLOAD_HANDLER_VER 1 /* Downloader version */ +#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ +#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ -#define DL_CRC_NOT_INUSE 0x0001 -#define DL_BEGIN 0x0002 -#define DL_END 0x0004 +#define DL_CRC_NOT_INUSE 0x0001 +#define DL_BEGIN 0x0002 +#define DL_END 0x0004 -enum { - DL_TYPE_UCODE = 1, - DL_TYPE_CLM = 2 +enum +{ + DL_TYPE_UCODE = 1, DL_TYPE_CLM = 2 }; -struct wl_dload_data { - uint16_t flag; - uint16_t dload_type; - uint32_t len; - uint32_t crc; - uint8_t data[1]; +struct wl_dload_data +{ + uint16_t flag; + uint16_t dload_type; + uint32_t len; + uint32_t crc; + uint8_t data[1]; }; typedef struct wl_dload_data wl_dload_data_t; -struct wl_clm_dload_info { - uint32_t ds_id; - uint32_t clm_total_len; - uint32_t num_chunks; - uint32_t chunk_len; - uint32_t chunk_offset; - uint8_t data_chunk[1]; +struct wl_clm_dload_info +{ + uint32_t ds_id; + uint32_t clm_total_len; + uint32_t num_chunks; + uint32_t chunk_len; + uint32_t chunk_offset; + uint8_t data_chunk[1]; }; typedef struct wl_clm_dload_info wl_clm_dload_info_t; #pragma pack(1) -typedef struct mesh_peer_info { - uint16_t mesh_peer_prot_id; - uint16_t local_link_id; - uint16_t peer_link_id; - uint16_t peer_aid; - uint8_t state; +typedef struct mesh_peer_info +{ + uint16_t mesh_peer_prot_id; + uint16_t local_link_id; + uint16_t peer_link_id; + uint16_t peer_aid; + uint8_t state; } mesh_peer_info_t; -typedef struct mesh_peer_info_ext { - mesh_peer_info_t peer_info; - uint16_t local_aid; - struct ether_addr ea; - uint32_t entry_state; - int32_t rssi; +typedef struct mesh_peer_info_ext +{ + mesh_peer_info_t peer_info; + uint16_t local_aid; + struct ether_addr ea; + uint32_t entry_state; + int32_t rssi; } mesh_peer_info_ext_t; -typedef struct mesh_peer_info_dump { - uint32_t buflen; - uint32_t version; - uint32_t count; /* number of results */ - mesh_peer_info_ext_t mpi_ext[1]; +typedef struct mesh_peer_info_dump +{ + uint32_t buflen; + uint32_t version; + uint32_t count; /* number of results */ + mesh_peer_info_ext_t mpi_ext[1]; } mesh_peer_info_dump_t; -#define WL_CHANSPEC_CTL_SB_LLL 0x0000 -#define WL_CHANSPEC_CTL_SB_LLU 0x0100 -#define WL_CHANSPEC_CTL_SB_LUL 0x0200 -#define WL_CHANSPEC_CTL_SB_LUU 0x0300 -#define WL_CHANSPEC_CTL_SB_ULL 0x0400 -#define WL_CHANSPEC_CTL_SB_ULU 0x0500 -#define WL_CHANSPEC_CTL_SB_UUL 0x0600 -#define WL_CHANSPEC_CTL_SB_UUU 0x0700 -#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL -#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU -#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL -#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU -#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL -#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU -#define INVCHANSPEC 255 -#define WL_CHANSPEC_CTL_SB_SHIFT 8 -#define WL_CHANSPEC_BW_5 0x0000 +#define WL_CHANSPEC_CTL_SB_LLL 0x0000 +#define WL_CHANSPEC_CTL_SB_LLU 0x0100 +#define WL_CHANSPEC_CTL_SB_LUL 0x0200 +#define WL_CHANSPEC_CTL_SB_LUU 0x0300 +#define WL_CHANSPEC_CTL_SB_ULL 0x0400 +#define WL_CHANSPEC_CTL_SB_ULU 0x0500 +#define WL_CHANSPEC_CTL_SB_UUL 0x0600 +#define WL_CHANSPEC_CTL_SB_UUU 0x0700 +#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL +#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU +#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL +#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU +#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL +#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU +#define INVCHANSPEC 255 +#define WL_CHANSPEC_CTL_SB_SHIFT 8 +#define WL_CHANSPEC_BW_5 0x0000 #define WL_CHANSPEC_BW_80 0x2000 #define WL_CHANSPEC_BW_160 0x2800 #define WL_CHANSPEC_BW_8080 0x3000 @@ -3671,50 +4175,54 @@ typedef struct mesh_peer_info_dump { struct ether_addr; struct wl_join_scan_params; -typedef struct wl_assoc_params { - struct ether_addr bssid; - uint16_t bssid_cnt; - uint32_t chanspec_num; - chanspec_t chanspec_list[1]; +typedef struct wl_assoc_params +{ + struct ether_addr bssid; + uint16_t bssid_cnt; + uint32_t chanspec_num; + chanspec_t chanspec_list[1]; } wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(wl_chanspec_t)) +#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(wl_chanspec_t) ) typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE +#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE typedef wl_assoc_params_t wl_join_assoc_params_t; -#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE -typedef struct wl_join_params { - wlc_ssid_t ssid; - struct wl_assoc_params params; +#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE +typedef struct wl_join_params +{ + wlc_ssid_t ssid; + struct wl_assoc_params params; } wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(wl_chanspec_t)) +#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(wl_chanspec_t) ) /* extended join params */ -typedef struct wl_extjoin_params { - wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ - struct wl_join_scan_params scan_params; - wl_join_assoc_params_t assoc_params; /* optional field, but it must include the fixed portion +typedef struct wl_extjoin_params +{ + wlc_ssid_t ssid; /* {0, ""}: wildcard scan */ + struct wl_join_scan_params scan_params; + wl_join_assoc_params_t assoc_params; /* optional field, but it must include the fixed portion * of the wl_join_assoc_params_t struct when it does * present. */ } wl_extjoin_params_t; -#define WL_EXTJOIN_PARAMS_FIXED_SIZE (sizeof(wl_extjoin_params_t) - sizeof(chanspec_t)) +#define WL_EXTJOIN_PARAMS_FIXED_SIZE (sizeof(wl_extjoin_params_t) - sizeof(chanspec_t) ) -#define WLC_SET_CUSTOM_COUNTRY ((uint32_t)320) +#define WLC_SET_CUSTOM_COUNTRY ( (uint32_t)320 ) /* WLC_GET_AUTH, WLC_SET_AUTH values */ -#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ -#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ -#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ -#define WL_AUTH_SAE 3 /* Simultaneous Authentication of Equals (SAE) */ +#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ +#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ +#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ +#define WL_AUTH_SAE 3 /* Simultaneous Authentication of Equals (SAE) */ /** ARP offload statistics */ -struct whd_arp_stats_s { - uint32_t version; /**< WLAN version */ - uint32_t peerage; /**< Current peer age-out time */ - uint32_t arpoe; /**< Agent enabled state */ - uint32_t features_enabled; /**< ARP Feature Flags @ref CY_ARP_OL_AGENT_ENABLE, etc. */ - arp_ol_stats_t stats; /**< Current stats */ - uint32_t host_ip_list[ARP_MULTIHOMING_MAX]; /**< host_ip addresses in one call */ +struct whd_arp_stats_s +{ + uint32_t version; /**< WLAN version */ + uint32_t peerage; /**< Current peer age-out time */ + uint32_t arpoe; /**< Agent enabled state */ + uint32_t features_enabled; /**< ARP Feature Flags @ref CY_ARP_OL_AGENT_ENABLE, etc. */ + arp_ol_stats_t stats; /**< Current stats */ + uint32_t host_ip_list[ARP_MULTIHOMING_MAX]; /**< host_ip addresses in one call */ }; #pragma pack() @@ -3725,8 +4233,15 @@ struct whd_arp_stats_s { /* * TCP keepalive offload definitions */ -#define MAX_TKO_CONN 4 -#define IPV4_ADDR_LEN 4 /* IPV4 address length */ + +#define MAX_TLS_CONN 1 +#define MAX_TKO_CONN 4 +#define WL_TKO_AUTO_VER 1 +#define TKO_FILTER_SRC_IP 0x1 +#define TKO_FILTER_DST_IP 0x2 +#define TKO_FILTER_SRC_PORT 0x4 +#define TKO_FILTER_DST_PORT 0x8 +#define TKO_FILTER_ALL (TKO_FILTER_SRC_IP|TKO_FILTER_DST_IP|TKO_FILTER_SRC_PORT|TKO_FILTER_DST_PORT) /* Default TCP Keepalive retry parameters. */ #define TCP_KEEPALIVE_OFFLOAD_INTERVAL_SEC (20) @@ -3734,46 +4249,53 @@ struct whd_arp_stats_s { #define TCP_KEEPALIVE_OFFLOAD_RETRY_INTERVAL_SEC (3) /* common iovar struct */ -typedef struct wl_tko { - uint16_t subcmd_id; /* subcommand id */ - uint16_t len; /* total length of data[] */ - uint8_t data[1]; /* subcommand data */ +typedef struct wl_tko +{ + uint16_t subcmd_id; /* subcommand id */ + uint16_t len; /* total length of data[] */ + uint8_t data[1]; /* subcommand data */ } wl_tko_t; /* subcommand ids */ -#define WL_TKO_SUBCMD_MAX_TCP 0 /* max TCP connections supported */ -#define WL_TKO_SUBCMD_PARAM 1 /* configure offload common parameters */ -#define WL_TKO_SUBCMD_CONNECT 2 /* TCP connection info */ -#define WL_TKO_SUBCMD_ENABLE 3 /* enable/disable */ -#define WL_TKO_SUBCMD_STATUS 4 /* TCP connection status */ +#define WL_TKO_SUBCMD_MAX_TCP 0 /* max TCP connections supported */ +#define WL_TKO_SUBCMD_PARAM 1 /* configure offload common parameters */ +#define WL_TKO_SUBCMD_CONNECT 2 /* TCP connection info */ +#define WL_TKO_SUBCMD_ENABLE 3 /* enable/disable */ +#define WL_TKO_SUBCMD_STATUS 4 /* TCP connection status */ +#define WL_TKO_SUBCMD_AUTOENAB 6 /* TCP auto configurations */ +#define WL_TKO_SUBCMD_AUTOCONNECT 7 /* get TCP auto connect info */ +#define WL_TKO_SUBCMD_FILTER 8 /* auto TCP filter/wildcard configurations */ /* WL_TKO_SUBCMD_MAX_CONNECT subcommand data */ -typedef struct wl_tko_max_tcp { - uint8_t max; /* max TCP connections supported */ - uint8_t pad[3]; /* 4-byte struct alignment */ +typedef struct wl_tko_max_tcp +{ + uint8_t max; /* max TCP connections supported */ + uint8_t pad[3]; /* 4-byte struct alignment */ } wl_tko_max_tcp_t; /* WL_TKO_SUBCMD_PARAM subcommand data */ -typedef struct wl_tko_param { - uint16_t interval; /* keepalive tx interval (secs) */ - uint16_t retry_interval; /* keepalive retry interval (secs) */ - uint16_t retry_count; /* retry_count */ - uint8_t pad[2]; /* 4-byte struct alignment */ +typedef struct wl_tko_param +{ + uint16_t interval; /* keepalive tx interval (secs) */ + uint16_t retry_interval; /* keepalive retry interval (secs) */ + uint16_t retry_count; /* retry_count */ + uint8_t pad[2]; /* 4-byte struct alignment */ } wl_tko_param_t; /* WL_TKO_SUBCMD_CONNECT subcommand data * invoke with unique 'index' for each TCP connection */ -typedef struct wl_tko_connect { - uint8_t index; /* TCP connection index, 0 to max-1 */ - uint8_t ip_addr_type; /* 0 - IPv4, 1 - IPv6 */ - uint16_t local_port; /* local port */ - uint16_t remote_port; /* remote port */ - uint32_t local_seq; /* local sequence number */ - uint32_t remote_seq; /* remote sequence number */ - uint16_t request_len; /* TCP keepalive request packet length */ - uint16_t response_len; /* TCP keepalive response packet length */ - uint8_t data[1]; /* variable length field containing local/remote IPv4/IPv6, +typedef struct wl_tko_connect +{ + uint8_t index; /* TCP connection index, 0 to max-1 */ + uint8_t ip_addr_type; /* 0 - IPv4, 1 - IPv6 */ + uint16_t local_port; /* local port */ + uint16_t remote_port; /* remote port */ + uint32_t local_seq; /* local sequence number */ + uint32_t remote_seq; /* remote sequence number */ + uint16_t request_len; /* TCP keepalive request packet length */ + uint16_t response_len; /* TCP keepalive response packet length */ + uint8_t data[1]; /* variable length field containing local/remote IPv4/IPv6, * TCP keepalive request packet, TCP keepalive response packet * For IPv4, length is 4 * 2 + request_length + response_length * offset 0 - local IPv4 @@ -3789,31 +4311,35 @@ typedef struct wl_tko_connect { } wl_tko_connect_t; /* WL_TKO_SUBCMD_CONNECT subcommand data to GET configured info for specific index */ -typedef struct wl_tko_get_connect { - uint8_t index; /* TCP connection index, 0 to max-1 */ - uint8_t pad[3]; /* 4-byte struct alignment */ +typedef struct wl_tko_get_connect +{ + uint8_t index; /* TCP connection index, 0 to max-1 */ + uint8_t pad[3]; /* 4-byte struct alignment */ } wl_tko_get_connect_t; -typedef struct wl_tko_enable { - uint8_t enable; /* 1 - enable, 0 - disable */ - uint8_t pad[3]; /* 4-byte struct alignment */ +typedef struct wl_tko_enable +{ + uint8_t enable; /* 1 - enable, 0 - disable */ + uint8_t pad[3]; /* 4-byte struct alignment */ } wl_tko_enable_t; /* WL_TKO_SUBCMD_STATUS subcommand data */ /* must be invoked before tko is disabled else status is unavailable */ -typedef struct wl_tko_status { - uint8_t count; /* number of status entries (i.e. equals +typedef struct wl_tko_status +{ + uint8_t count; /* number of status entries (i.e. equals * max TCP connections supported) */ - uint8_t status[1]; /* variable length field contain status for + uint8_t status[1]; /* variable length field contain status for * each TCP connection index */ } wl_tko_status_t; /** Get/Set TKO intervals & retrys */ -struct whd_tko_retry { - uint16_t tko_interval; /**< How often to send (in seconds) */ - uint16_t tko_retry_count; /**< Max times to retry if original fails */ - uint16_t tko_retry_interval; /**< Wait time between retries (in seconds) */ +struct whd_tko_retry +{ + uint16_t tko_interval; /**< How often to send (in seconds) */ + uint16_t tko_retry_count; /**< Max times to retry if original fails */ + uint16_t tko_retry_interval; /**< Wait time between retries (in seconds) */ }; /** Status values used in conjunction with whd_tko_status_t */ @@ -3829,9 +4355,10 @@ typedef enum { } tko_status_t; /** Status of each TCP connection */ -struct whd_tko_status { - uint8_t count; /**< number of status entries */ - uint8_t status[MAX_TKO_CONN]; /**< each TCP status */ +struct whd_tko_status +{ + uint8_t count; /**< number of status entries */ + uint8_t status[MAX_TKO_CONN]; /**< each TCP status */ }; /** Struct to query FW for current TKO configuration */ @@ -3845,20 +4372,169 @@ struct whd_tko_connect { uint16_t request_len; /**< TCP keepalive request packet length */ uint16_t response_len; /**< TCP keepalive response packet length */ uint8_t data[1]; /**< variable length field containing local/remote IPv4/IPv6, - * TCP keepalive request packet, TCP keepalive response packet - * For IPv4, length is 4 * 2 + request_length + response_length - * offset 0 - local IPv4 - * offset 4 - remote IPv4 - * offset 8 - TCP keepalive request packet - * offset 8+request_length - TCP keepalive response packet - * For IPv6, length is 16 * 2 + request_length + response_length - * offset 0 - local IPv6 - * offset 16 - remote IPv6 - * offset 32 - TCP keepalive request packet - * offset 32+request_length - TCP keepalive response packet - */ + * TCP keepalive request packet, TCP keepalive response packet + * For IPv4, length is 4 * 2 + request_length + response_length + * offset 0 - local IPv4 + * offset 4 - remote IPv4 + * offset 8 - TCP keepalive request packet + * offset 8+request_length - TCP keepalive response packet + * For IPv6, length is 16 * 2 + request_length + response_length + * offset 0 - local IPv6 + * offset 16 - remote IPv6 + * offset 32 - TCP keepalive request packet + * offset 32+request_length - TCP keepalive response packet + */ +}; + +#define IPV4_ADDR_LEN 4 /* IPV4 address length */ +#define IPV6_ADDR_LEN 16 /* IPV6 address length */ + +/* IPV4 address */ +struct ipv4_addr { + uint8_t addr[IPV4_ADDR_LEN]; +}; + +/* IPV6 address */ +struct ipv6_addr { + uint8_t addr[IPV6_ADDR_LEN]; +}; + +typedef struct wl_tko_autoenab { + uint16_t version; /* auto tko command version */ + uint16_t length; /* The remaining len after */ + uint8_t enable; /* 0: disable, 1: enable */ + uint8_t pad[3]; /* 4-byte struct alignment */ +} wl_tko_autoenab_t; + +typedef struct wl_tko_autoconnect { + uint16_t version; + uint16_t length; + uint8_t index; + bool is_enabled; /* Is auto tko enabled or not */ + uint8_t filter; /* The tx packets field to be filtered */ + uint8_t ip_addr_type; /* ipv4 or ipv6, only valid when allocated is TRUE */ + bool allocated; /* This wildcard has been allocated */ + bool pkt_created; /* the ready packet for tx/rx are really created */ + uint8_t pad[2]; /* pad */ + uint8_t src_ip[IPV6_ADDR_LEN]; /* src ip for offload, ipv6/ipv4 shared */ + uint8_t dst_ip[IPV6_ADDR_LEN]; /* dst ip for offload, ipv6/ipv4 shared */ + uint16_t local_port; /* The local port for offload */ + uint16_t remote_port; /* The remote port for offload */ + uint32_t local_seq; /* The local seq got */ + uint32_t remote_seq; /* The remote seq got */ +} wl_tko_autoconnect_t; + +typedef struct wl_tko_filter { + uint16_t version; /* auto tko command version */ + uint16_t length; /* The remaining len after */ + uint16_t sport; /* 0: wild card, others as filter local port */ + uint16_t dport; /* 0: wild card, others as filter remote port */ + uint8_t ip_src[IPV6_ADDR_LEN]; /* {0}: wild card, others as filter src ip */ + uint8_t ip_dst[IPV6_ADDR_LEN]; /* {0}: wild card, others as filter dst ip */ +} wl_tko_filter_t; + +struct whd_tko_auto_filter { + uint16_t version; /* auto tko command version */ + uint16_t length; /* The remaining len after */ + uint16_t sport; /* 0: wild card, others as filter local port */ + uint16_t dport; /* 0: wild card, others as filter remote port */ + uint8_t ip_src[IPV6_ADDR_LEN]; /* {0}: wild card, others as filter src ip */ + uint8_t ip_dst[IPV6_ADDR_LEN]; /* {0}: wild card, others as filter dst ip */ +}; + +struct whd_tko_autoconnect +{ + uint16_t version; + uint16_t length; + uint8_t index; + bool is_enabled; /* Is auto tko enabled or not */ + uint8_t filter; /* The tx packets field to be filtered */ + uint8_t ip_addr_type; /* ipv4 or ipv6, only valid when allocated is TRUE */ + bool allocated; /* This wildcard has been allocated */ + bool pkt_created; /* the ready packet for tx/rx are really created */ + uint8_t pad[2]; /* pad */ + uint8_t src_ip[IPV6_ADDR_LEN]; /* src ip for offload, ipv6/ipv4 shared */ + uint8_t dst_ip[IPV6_ADDR_LEN]; /* dst ip for offload, ipv6/ipv4 shared */ + uint16_t local_port; /* The local port for offload */ + uint16_t remote_port; /* The remote port for offload */ + uint32_t local_seq; /* The local seq got */ + uint32_t remote_seq; /* The remote seq got */ +}; + +/* Versions of Offload config */ +#define WL_OL_CFG_VER_1 1 + +typedef enum wl_ol_cfg_id { + WL_OL_CFG_ID_PROF = 1, /* Offload Profile Update */ + WL_OL_CFG_ID_INET_V4, /* ADD/DEL IPv4 Address */ + WL_OL_CFG_ID_INET_V6, /* ADD/DEL IPv6 Address */ + WL_OL_CFG_ID_ACTIVATE, /* Activate/Deactivate Offload */ + /* Add new type before this line */ + WL_OL_CFG_ID_MAX /* Last Offload Config ID */ +} wl_ol_cfg_id_t; + +typedef enum wl_ol_prof_type { + WL_OL_PROF_TYPE_LOW_PWR = 1, /* Low Power Profile */ + WL_OL_PROF_TYPE_MID_PWR = 2, /* Mid Power Profile */ + WL_OL_PROF_TYPE_HIGH_PWR = 3, /* High Power Profile */ + /* Add new type before this line */ + WL_OL_PROF_MAX = 4 /* Last Offload Profile */ +} wl_ol_prof_type_t; + +/* Offload configuration */ +typedef struct wl_ol_cfg_v1 { + uint16_t ver; /* version of this structure */ + uint16_t len; /* length of structure in bytes */ + uint32_t id; /* Offload Config ID */ + + union { + struct { + uint32_t type; /* offload profile type */ + whd_bool_t reset; /* Remove profile configuration */ + uint8_t pad[3]; + } ol_profile; + struct { + struct ipv4_addr host_ipv4; + whd_bool_t del; /* 1:del 0:add host ipv4 address */ + uint8_t pad[3]; + } ol_inet_v4; + struct { + struct ipv6_addr host_ipv6; + uint8_t type; /* 0:unicast 1:anycast */ + whd_bool_t del; /* 1:del 0:add host ipv6 address */ + uint8_t pad[2]; + } ol_inet_v6; + struct { + whd_bool_t enable; /* enable/disable offload feature */ + uint8_t pad[3]; + } ol_activate; + } u; + + uint32_t offload_skip; /* Bitmap of offload to be skipped */ +} wl_ol_cfg_v1_t; + +struct secure_sess_info { + uint32_t tcp_seq; + uint32_t tcp_ack; + uint8_t read_seq[TLS_MAX_SEQUENCE_LENGTH]; + uint8_t write_seq[TLS_MAX_SEQUENCE_LENGTH]; }; +/* Offload Skip Bitmap */ +#define WL_OL_ARP (1 << 0) +#define WL_OL_ND (1 << 1) +#define WL_OL_BDO (1 << 2) +#define WL_OL_ICMP (1 << 3) +#define WL_OL_TKO (1 << 4) +#define WL_OL_DLTRO (1 << 5) +#define WL_OL_PNO (1 << 6) +#define WL_OL_KEEPALIVE (1 << 7) +#define WL_OL_GTKOE (1 << 8) +#define WL_OL_WOWLPF (1 << 9) + +#define OFFLOAD_FEATURE WL_OL_ARP | WL_OL_ND | WL_OL_BDO | WL_OL_ICMP | WL_OL_TKO | WL_OL_DLTRO | WL_OL_PNO | WL_OL_KEEPALIVE | WL_OL_GTKOE | WL_OL_WOWLPF + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wi-fi/whd/wifi_nvram_image.h b/wi-fi/whd/wifi_nvram_image.h index 30082f7d..2085df85 100644 --- a/wi-fi/whd/wifi_nvram_image.h +++ b/wi-fi/whd/wifi_nvram_image.h @@ -105,6 +105,127 @@ static const char sterling_lwb_wifi_nvram_image[] = "spurconfig=0x3\0" "\0\0"; + +/** + * Character array of NVRAM image + * Generated from brcmfmac4373-sa-switch_210528.txt + */ + +static const char sterling_lwb5plus_wifi_nvram_image[] = + "NVRAMRev=$Rev$\0" + "sromrev=11\0" + "vendid=0x14e4\0" + "devid=0x4418\0" + "manfid=0x2d0\0" + "prodid=0x070f\0" + "macaddr=00:A0:50:3c:c0:1d\0" + "nocrc=1\0" + "boardtype=0x83d\0" + "boardrev=0x1200\0" + "xtalfreq=37400\0" + "boardflags=0x00000001\0" + "boardflags2=0x00800000\0" + "boardflags3=0x48202100\0" + "ext_lpo_margin_frac=0\0" + "tempthresh=105\0" + "temps_hysteresis=20\0" + "temps_txduty_lowlimit=0\0" + "temps_period=1\0" + "phycal_tempdelta=15\0" + "rxgains2gelnagaina0=0\0" + "rxgains2gtrisoa0=0\0" + "rxgains2gtrelnabypa0=0\0" + "rxgains5gelnagaina0=0\0" + "rxgains5gtrisoa0=0\0" + "rxgains5gtrelnabypa0=0\0" + "pdgain5g=3\0" + "pdgain2g=3\0" + "antswitch=0x6\0" + "rxchain=1\0" + "txchain=1\0" + "aa2g=1\0" + "aa5g=1\0" + "tssipos5g=1\0" + "tssipos2g=1\0" + "femctrl=0\0" + "pa2ga0=-214,4762,-584\0" + "pa5ga0=-153,5528,-664,-153,5528,-664,-155,5563,-666,-167,5492,-66\0" + "pdoffsetcckma0=0xf\0" + "pdoffset2g40ma0=0xc\0" + "pdoffset40ma0=0xffff\0" + "pdoffset80ma0=0xeeee\0" + "extpagain5g=2\0" + "extpagain2g=2\0" + "AvVmid_c0=1,130,0,160,0,160,0,160,0,160\0" + "maxp2ga0=72\0" + "maxp5ga0=70,70,70,70\0" + "cckbw202gpo=0x1111\0" + "dot11agofdmhrbw202gpo=0x4422\0" + "ofdmlrbw202gpo=0x0022\0" + "mcsbw202gpo=0xAA666666\0" + "mcsbw402gpo=0xFFEEEEEE\0" + "mcsbw205glpo=0xDD662222\0" + "mcsbw205gmpo=0xDD662222\0" + "mcsbw205ghpo=0xDD662222\0" + "mcsbw405glpo=0xDDAAAAAA\0" + "mcsbw405gmpo=0xDDAAAAAA\0" + "mcsbw405ghpo=0xDDAAAAAA\0" + "mcsbw805glpo=0xEECCCCCC\0" + "mcsbw805gmpo=0xEECCCCCC\0" + "mcsbw805ghpo=0xEECCCCCC\0" + "ppr_hitemp_offset=70,10\0" + "cckbw202gpo_ht=0x0000\0" + "ofdmbw202gpo_ht=0x00000000\0" + "mcsbw202gpo_ht=0x22222222\0" + "ofdmbw205gpo_ht=0x22222222\0" + "mcsbw205gpo_ht=0x22222222\0" + "mcsbw405gpo_ht=0x22222222\0" + "mcsbw805gpo_ht=0x22222222\0" + "swctrlmap_2g=0x00001131,0x00001131,0x00001131,0x313131,0x1ff\0" + "swctrlmap_5g=0x00201131,0x40405171,0x00001131,0x313131,0x1ff\0" + "swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0" + "swctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x000\0" + "fem_table_init_val=0x1131,0x1131\0" + "nb_papdcalidx=0x280f\0" + "nb_txattn=0x0303\0" + "nb_rxattn=0x0303\0" + "nb_bbmult=0x3948\0" + "nb_eps_offset=0x01e601ea\0" + "papdmode=1\0" + "rssi_delta_2g_c0=-2,-2,-2,-2\0" + "rssi_delta_5gl_c0=-2,-2,-3,-3,-1,-1\0" + "rssi_delta_5gml_c0=-2,-2,-3,-3,-1,-1\0" + "rssi_delta_5gmu_c0=0,0,-1,-1,0,0\0" + "rssi_delta_5gh_c0=-1,-1,-2,-2,0,0\0" + "ATErcalmode=0\0" + "swdiv_gpio=0\0" + "swdiv_swctrl_en=2\0" + "swdiv_swctrl_ant0=0\0" + "swdiv_swctrl_ant1=1\0" + "swdiv_antmap2g_main=1\0" + "swdiv_antmap5g_main=1\0" + "swdiv_snrlim=290 \0" + "swdiv_thresh=2000 \0" + "swdiv_snrthresh=24 \0" + "swdiv_timeon=10\0" + "swdiv_timeoff=1\0" + "swdiv_snr2g20=232\0" + "swdiv_snr2g40=257\0" + "swdiv_snr5g20=296\0" + "swdiv_snr5g40=312\0" + "swdiv_snr5g80=296\0" + "swdiv_ap_dead_check=1 \0" + "swdiv_ap_div=1 \0" + "idac_main_mode=1\0" + "paldo3p3_voltage=4\0" + "xtal_ldo_ctl=1\0" + "e_grade=1\0" + "fdss_level_2g=4\0" + "fdss_level_5g=4\0" + "fdss_interp_en=1\0" + "muxenab=0x10\0" + "\0\0"; + #ifdef __cplusplus } /*extern "C" */ #endif